diff --git a/frontend/mockdata/mockData.ts b/frontend/mockdata/mockData.ts index 2f39ff86..1fb378ba 100644 --- a/frontend/mockdata/mockData.ts +++ b/frontend/mockdata/mockData.ts @@ -32,6 +32,7 @@ export const MockConsultants: Consultant[] = [ }, ], yearsOfExperience: 23, + isOccupied: true, }, ]; diff --git a/frontend/src/components/AvailabilityFilter.tsx b/frontend/src/components/AvailabilityFilter.tsx new file mode 100644 index 00000000..ecfddf76 --- /dev/null +++ b/frontend/src/components/AvailabilityFilter.tsx @@ -0,0 +1,21 @@ +"use client"; +import FilterButton from "./FilterButton"; +import { useFilteredConsultants } from "@/hooks/useFilteredConsultants"; + +export default function AvailabilityFilter() { + const { availabilityFilterOn, toggleAvailabilityFilter } = + useFilteredConsultants(); + + return ( +
+

Status

+
+ toggleAvailabilityFilter(!availabilityFilterOn)} + checked={availabilityFilterOn} + /> +
+
+ ); +} diff --git a/frontend/src/components/StaffingSidebar.tsx b/frontend/src/components/StaffingSidebar.tsx index e9f8527b..6e0c294c 100644 --- a/frontend/src/components/StaffingSidebar.tsx +++ b/frontend/src/components/StaffingSidebar.tsx @@ -1,6 +1,7 @@ "use client"; import { useState } from "react"; import DepartmentFilter from "./DepartmentFilter"; +import AvailabilityFilter from "./AvailabilityFilter"; import SearchBarComponent from "./SearchBarComponent"; import { ArrowLeft, Filter } from "react-feather"; import ExperienceFilter from "./ExperienceFilter"; @@ -22,6 +23,7 @@ export default function StaffingSidebar() { + diff --git a/frontend/src/hooks/useFilteredConsultants.ts b/frontend/src/hooks/useFilteredConsultants.ts index da496cd1..8130c505 100644 --- a/frontend/src/hooks/useFilteredConsultants.ts +++ b/frontend/src/hooks/useFilteredConsultants.ts @@ -13,6 +13,7 @@ interface UpdateFilterParams { departments?: string; years?: string; week?: Week; + availability?: Boolean; } export function useFilteredConsultants() { @@ -24,6 +25,7 @@ export function useFilteredConsultants() { const searchFilter = searchParams.get("search") || ""; const departmentFilter = searchParams.get("depFilter") || ""; const yearFilter = searchParams.get("yearFilter") || ""; + const availabilityFilter = searchParams.get("availabilityFilter") || ""; const selectedWeek = stringToWeek( searchParams.get("selectedWeek") || undefined, ); @@ -40,11 +42,12 @@ export function useFilteredConsultants() { const { departments = departmentFilter } = updateParams; const { years = yearFilter } = updateParams; const { week = selectedWeek } = updateParams; + const { availability = availabilityFilter } = updateParams; router.push( `${pathname}?search=${search}&depFilter=${departments}&yearFilter=${years}${ week ? `&selectedWeek=${weekToString(week)}` : "" - }`, + }&availabilityFilter=${availability}`, ); }, [ @@ -54,6 +57,7 @@ export function useFilteredConsultants() { searchFilter, selectedWeek, yearFilter, + availabilityFilter, ], ); @@ -87,7 +91,7 @@ export function useFilteredConsultants() { function resetSelectedWeek() { router.push( - `${pathname}?search=${searchFilter}&depFilter=${departmentFilter}&yearFilter=${yearFilter}`, + `${pathname}?search=${searchFilter}&depFilter=${departmentFilter}&yearFilter=${yearFilter}&availabilityFilter=${availabilityFilter}`, ); } @@ -119,11 +123,14 @@ export function useFilteredConsultants() { .map((urlString) => yearRanges.find((y) => y.urlString === urlString)) .filter((year) => year !== undefined) as YearRange[]; + const availabilityFilterOn = availabilityFilter === "true"; + const filteredConsultants = filterConsultants( searchFilter, departmentFilter, filteredYears, consultants, + availabilityFilterOn, ); function setNameSearch(newSearch: string) { @@ -147,6 +154,13 @@ export function useFilteredConsultants() { [updateRoute, yearFilter], ); + const toggleAvailabilityFilter = useCallback( + (availabelFilterOn: Boolean) => { + updateRoute({ availability: availabelFilterOn }); + }, + [updateRoute], + ); + useEffect(() => { function handleDepartmentHotkey(keyCode: string) { departments @@ -181,11 +195,13 @@ export function useFilteredConsultants() { departments, filteredDepartments, filteredYears, + availabilityFilterOn, currentNameSearch: activeNameSearch, searchFilter, setNameSearch, toggleDepartmentFilter, toggleYearFilter, + toggleAvailabilityFilter, selectedWeek, incrementSelectedWeek, decrementSelectedWeek, @@ -236,6 +252,7 @@ function filterConsultants( departmentFilter: string, yearFilter: YearRange[], consultants: Consultant[], + availabilityFilterOn: Boolean, ) { let newFilteredConsultants = consultants; if (search && search.length > 0) { @@ -255,6 +272,11 @@ function filterConsultants( inYearRanges(consultant, yearFilter), ); } + if (availabilityFilterOn) { + newFilteredConsultants = newFilteredConsultants.filter( + (consultant) => !consultant.isOccupied, + ); + } return newFilteredConsultants; } diff --git a/frontend/src/types.ts b/frontend/src/types.ts index c6b8c5f7..55eea176 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -37,6 +37,7 @@ export type Consultant = { department: string; yearsOfExperience: number; bookings?: BookedHoursPerWeek[] | null; + isOccupied: Boolean; }; export type Department = {