diff --git a/frontend/src/components/ActiveFilters.tsx b/frontend/src/components/ActiveFilters.tsx index f0667f2b..f98b4524 100644 --- a/frontend/src/components/ActiveFilters.tsx +++ b/frontend/src/components/ActiveFilters.tsx @@ -3,11 +3,11 @@ import { Filter } from "react-feather"; import { useFilteredConsultants } from "@/hooks/useFilteredConsultants"; export default function ActiveFilters() { - const { filteredDepartments, currentSearch, filteredYears } = + const { filteredDepartments, searchFilter, filteredYears } = useFilteredConsultants(); const filterTextComponents: string[] = []; - if (currentSearch != "") filterTextComponents.push(` "${currentSearch}"`); + if (searchFilter != "") filterTextComponents.push(` "${searchFilter}"`); if (filteredDepartments.length > 0) filterTextComponents.push( diff --git a/frontend/src/hooks/useFilteredConsultants.ts b/frontend/src/hooks/useFilteredConsultants.ts index c962a8ba..0d3e8fee 100644 --- a/frontend/src/hooks/useFilteredConsultants.ts +++ b/frontend/src/hooks/useFilteredConsultants.ts @@ -6,29 +6,48 @@ import { useCallback, useContext, useEffect, useState } from "react"; import { FilteredContext } from "@/components/FilteredConsultantProvider"; import { yearRanges } from "@/components/ExperienceFilter"; +interface UpdateFilterParams { + search?: string; + departments?: string; + years?: string; +} + export function useFilteredConsultants() { const { departments, consultants } = useContext(FilteredContext); const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); - const currentSearch = searchParams.get("search") || ""; - const currentDepartmentFilter = searchParams.get("depFilter") || ""; - const currentYearFilter = searchParams.get("yearFilter") || ""; + + const searchFilter = searchParams.get("search") || ""; + const departmentFilter = searchParams.get("depFilter") || ""; + const yearFilter = searchParams.get("yearFilter") || ""; const [activeNameSearch, setActiveNameSearch] = - useState(currentSearch); + useState(searchFilter); const [lastSearchKeyStrokeTime, setLastSearchKeyStrokeTime] = useState(); + const updateRoute = useCallback( + (updateParams: UpdateFilterParams) => { + // If not defined, defaults to current value: + const { search = searchFilter } = updateParams; + const { departments = departmentFilter } = updateParams; + const { years = yearFilter } = updateParams; + + router.push( + `${pathname}?search=${search}&depFilter=${departments}&yearFilter=${years}`, + ); + }, + [departmentFilter, pathname, router, searchFilter, yearFilter], + ); + useEffect(() => { let nameSearchDebounceTimer = setTimeout(() => { if ( lastSearchKeyStrokeTime && Date.now() - lastSearchKeyStrokeTime > 250 ) { - router.push( - `${pathname}?search=${activeNameSearch}&depFilter=${currentDepartmentFilter}&yearFilter=${currentYearFilter}`, - ); + updateRoute({ search: activeNameSearch }); } }, 250); @@ -44,23 +63,24 @@ export function useFilteredConsultants() { searchParams, router, pathname, - currentDepartmentFilter, - currentYearFilter, + departmentFilter, + yearFilter, + updateRoute, ]); - const filteredDepartments = currentDepartmentFilter + const filteredDepartments = departmentFilter .split(",") .map((id) => departments.find((d) => d.id === id)) .filter((dept) => dept !== undefined) as Department[]; - const filteredYears = currentYearFilter + const filteredYears = yearFilter .split(",") .map((urlString) => yearRanges.find((y) => y.urlString === urlString)) .filter((year) => year !== undefined) as YearRange[]; const filteredConsultants = filterConsultants( - currentSearch, - currentDepartmentFilter, + searchFilter, + departmentFilter, filteredYears, consultants, ); @@ -72,47 +92,27 @@ export function useFilteredConsultants() { const toggleDepartmentFilter = useCallback( (d: Department) => { - const newDepartmentFilter = filterString(currentDepartmentFilter, d.id); - router.push( - `${pathname}?search=${currentSearch}&depFilter=${newDepartmentFilter}&yearFilter=${currentYearFilter}`, + const newDepartmentFilter = toggleFilterFromString( + departmentFilter, + d.id, ); + updateRoute({ departments: newDepartmentFilter }); }, - [ - currentDepartmentFilter, - router, - pathname, - currentSearch, - currentYearFilter, - ], + [departmentFilter, updateRoute], ); const clearDepartmentFilter = useCallback(() => { - router.push( - `${pathname}?search=${currentSearch}&depFilter=&yearFilter=${currentYearFilter}`, - ); - }, [currentSearch, currentYearFilter, pathname, router]); + updateRoute({ departments: "" }); + }, [updateRoute]); const toggleYearFilter = useCallback( (y: YearRange) => { - const newYearFilter = filterString(currentYearFilter, y.urlString); - - router.push( - `${pathname}?search=${currentSearch}&depFilter=${currentDepartmentFilter}&yearFilter=${newYearFilter}`, - ); + const newYearFilter = toggleFilterFromString(yearFilter, y.urlString); + updateRoute({ years: newYearFilter }); }, - [ - currentDepartmentFilter, - currentSearch, - currentYearFilter, - pathname, - router, - ], + [updateRoute, yearFilter], ); - const clearAll = useCallback(() => { - router.push(`${pathname}?search=&depFilter=&yearFilter=`); - }, [pathname, router]); - useEffect(() => { function handleDepartmentHotkey(keyCode: string) { departments @@ -139,7 +139,7 @@ export function useFilteredConsultants() { return () => { document.removeEventListener("keydown", keyDownHandler); }; - }, [clearAll, clearDepartmentFilter, departments, toggleDepartmentFilter]); + }, [clearDepartmentFilter, departments, toggleDepartmentFilter]); return { consultants, @@ -148,21 +148,20 @@ export function useFilteredConsultants() { filteredDepartments, filteredYears, currentNameSearch: activeNameSearch, - currentSearch, + searchFilter, setNameSearch, toggleDepartmentFilter, toggleYearFilter, clearDepartmentFilter, - clearAll, }; } -function filterString(existingFilters: string, sortByString: string) { - const filters = existingFilters.split(","); - const filterIndex = filters.indexOf(sortByString); +function toggleFilterFromString(stringFilter: string, id: string) { + const filters = stringFilter.split(","); + const filterIndex = filters.indexOf(id); const newFilters = [...filters]; if (filterIndex === -1) { - newFilters.push(sortByString); + newFilters.push(id); } else { newFilters.splice(filterIndex, 1); }