diff --git a/apps/portal/src/components/resumes/browse/resumeConstants.ts b/apps/portal/src/components/resumes/browse/resumeConstants.ts index 6996538a..b8d85d6e 100644 --- a/apps/portal/src/components/resumes/browse/resumeConstants.ts +++ b/apps/portal/src/components/resumes/browse/resumeConstants.ts @@ -17,7 +17,13 @@ export const TOP_HITS = [ { href: '#', name: 'US Only' }, ]; -export const ROLES = [ +export type FilterOption = { + checked: boolean; + label: string; + value: string; +}; + +export const ROLE: Array = [ { checked: false, label: 'Full-Stack Engineer', @@ -30,7 +36,7 @@ export const ROLES = [ { checked: false, label: 'Android Engineer', value: 'Android Engineer' }, ]; -export const EXPERIENCE = [ +export const EXPERIENCE: Array = [ { checked: false, label: 'Freshman', value: 'Freshman' }, { checked: false, label: 'Sophomore', value: 'Sophomore' }, { checked: false, label: 'Junior', value: 'Junior' }, @@ -52,7 +58,7 @@ export const EXPERIENCE = [ }, ]; -export const LOCATION = [ +export const LOCATION: Array = [ { checked: false, label: 'Singapore', value: 'Singapore' }, { checked: false, label: 'United States', value: 'United States' }, { checked: false, label: 'India', value: 'India' }, diff --git a/apps/portal/src/pages/resumes/index.tsx b/apps/portal/src/pages/resumes/index.tsx index a65f3ca6..4dc3fe77 100644 --- a/apps/portal/src/pages/resumes/index.tsx +++ b/apps/portal/src/pages/resumes/index.tsx @@ -10,13 +10,14 @@ import { PlusIcon, } from '@heroicons/react/20/solid'; import { MagnifyingGlassIcon } from '@heroicons/react/24/outline'; -import { Tabs, TextInput } from '@tih/ui'; +import { CheckboxInput, CheckboxList, Tabs, TextInput } from '@tih/ui'; +import type { FilterOption } from '~/components/resumes/browse/resumeConstants'; import { BROWSE_TABS_VALUES, EXPERIENCE, LOCATION, - ROLES, + ROLE, SORT_OPTIONS, TOP_HITS, } from '~/components/resumes/browse/resumeConstants'; @@ -29,11 +30,19 @@ import { trpc } from '~/utils/trpc'; import type { Resume } from '~/types/resume'; -const filters = [ +type FilterId = 'experience' | 'location' | 'role'; +type Filter = { + id: FilterId; + name: string; + options: Array; +}; +type FilterState = Record>; + +const filters: Array = [ { - id: 'roles', - name: 'Roles', - options: ROLES, + id: 'role', + name: 'Role', + options: ROLE, }, { id: 'experience', @@ -47,11 +56,35 @@ const filters = [ }, ]; +const INITIAL_FILTER_STATE: FilterState = { + experience: Object.values(EXPERIENCE).map(({ value }) => value), + location: Object.values(LOCATION).map(({ value }) => value), + role: Object.values(ROLE).map(({ value }) => value), +}; + +const filterResumes = ( + resumes: Array, + searchValue: string, + userFilters: FilterState, +) => { + return resumes + .filter((resume) => + resume.title.toLowerCase().includes(searchValue.toLocaleLowerCase()), + ) + .filter( + ({ experience, location, role }) => + userFilters.role.includes(role) && + userFilters.experience.includes(experience) && + userFilters.location.includes(location), + ); +}; + export default function ResumeHomePage() { const { data: sessionData } = useSession(); const router = useRouter(); const [tabsValue, setTabsValue] = useState(BROWSE_TABS_VALUES.ALL); const [searchValue, setSearchValue] = useState(''); + const [userFilters, setUserFilters] = useState(INITIAL_FILTER_STATE); const [resumes, setResumes] = useState>([]); const [renderSignInButton, setRenderSignInButton] = useState(false); const [signInButtonText, setSignInButtonText] = useState(''); @@ -102,6 +135,26 @@ export default function ResumeHomePage() { } }; + const onFilterCheckboxChange = ( + isChecked: boolean, + filterSection: FilterId, + filterValue: string, + ) => { + if (isChecked) { + setUserFilters({ + ...userFilters, + [filterSection]: [...userFilters[filterSection], filterValue], + }); + } else { + setUserFilters({ + ...userFilters, + [filterSection]: userFilters[filterSection].filter( + (value) => value !== filterValue, + ), + }); + } + }; + return ( <> @@ -256,8 +309,8 @@ export default function ResumeHomePage() { - -
+ + {/*
{section.options.map((option, optionIdx) => (
console.log(value)} />
))} -
+
*/} + + {section.options.map((option) => ( +
+ + onFilterCheckboxChange( + isChecked, + section.id, + option.value, + ) + } + /> +
+ ))} +
)} @@ -296,7 +375,7 @@ export default function ResumeHomePage() { starredResumesQuery.isFetching || myResumesQuery.isFetching } - resumes={resumes} + resumes={filterResumes(resumes, searchValue, userFilters)} /> diff --git a/apps/portal/src/pages/resumes/submit.tsx b/apps/portal/src/pages/resumes/submit.tsx index b85852f0..79c1fc9b 100644 --- a/apps/portal/src/pages/resumes/submit.tsx +++ b/apps/portal/src/pages/resumes/submit.tsx @@ -11,7 +11,7 @@ import { Button, CheckboxInput, Select, TextArea, TextInput } from '@tih/ui'; import { EXPERIENCE, LOCATION, - ROLES, + ROLE, } from '~/components/resumes/browse/resumeConstants'; import { RESUME_STORAGE_KEY } from '~/constants/file-storage-keys'; @@ -152,7 +152,7 @@ export default function SubmitResumeForm() { {...register('role', { required: true })} disabled={isLoading} label="Role" - options={ROLES} + options={ROLE} required={true} onChange={(val) => setValue('role', val)} />