diff --git a/libs/react/containers/src/questions/question-search/question-search.tsx b/libs/react/containers/src/questions/question-search/question-search.tsx index 14911701e..4a6cbb097 100644 --- a/libs/react/containers/src/questions/question-search/question-search.tsx +++ b/libs/react/containers/src/questions/question-search/question-search.tsx @@ -74,38 +74,36 @@ export const QuestionSearch = container( placeholder="search Questions..." /> - - - - - } - filters={ - <> - - - - - + + } + /> ; + +const defaultSearchConfig: z.infer = { + mode: "all", + status: "all", +}; + +const searchPersistence = { + "cf-test-search-atpl": createUsePersistenceHook( + "cf-test-search-atpl", + ), + "cf-test-search-type": createUsePersistenceHook( + "cf-test-search-type", + ), + "cf-test-search-prep": createUsePersistenceHook( + "cf-test-search-prep", + ), +}; + +const resolver = zodResolver(searchConfigSchema); + +export const useSearchConfig = ( + questionBank: QuestionBankName, +): [SearchConfig, UseFormReturn] => { + const key = `cf-test-search-${questionBank}` as const; + const useSearchPersistence = searchPersistence[key]; + const { persistedData, setPersistedData } = useSearchPersistence(); + const defaultValues = persistedData ?? defaultSearchConfig; + const form = useForm({ defaultValues, resolver }); + const mode = form.watch("mode"); + const status = form.watch("status"); + + useEffect(() => { + setPersistedData({ mode, status }); + }, [mode, status, setPersistedData]); + + return [{ mode, status }, form]; +}; diff --git a/libs/react/containers/src/tests/test-search/test-search.tsx b/libs/react/containers/src/tests/test-search/test-search.tsx index 08a516dbe..323d3286f 100644 --- a/libs/react/containers/src/tests/test-search/test-search.tsx +++ b/libs/react/containers/src/tests/test-search/test-search.tsx @@ -1,3 +1,4 @@ +import { FormProvider } from "react-hook-form"; import { default as DeleteIcon } from "@mui/icons-material/DeleteOutlineOutlined"; import { default as PlayIcon } from "@mui/icons-material/PlayArrowOutlined"; import { default as EyeIcon } from "@mui/icons-material/VisibilityOutlined"; @@ -8,14 +9,22 @@ import { IconButton, Link, ListItemContent, + Select, + Option, Stack, Tooltip, Typography, + selectClasses, } from "@mui/joy"; import { processTest } from "@chair-flight/core/app"; -import { SearchList } from "@chair-flight/react/components"; +import { + HookFormSelect, + SearchFilters, + SearchList, +} from "@chair-flight/react/components"; import { container } from "../../wraper/container"; import { useTestProgress } from "../hooks/use-test-progress"; +import { useSearchConfig } from "./test-search-config-schema"; import type { QuestionBankName } from "@chair-flight/base/types"; type Props = { @@ -24,18 +33,62 @@ type Props = { export const TestSearch = container( ({ questionBank, sx, component = "section" }) => { + const [{ mode, status }, form] = useSearchConfig(questionBank); + const tests = useTestProgress((s) => s.tests); const deleteTest = useTestProgress((s) => s.deleteTest); + const testsAsList = Object.values(tests) .sort((a, b) => b.createdAtEpochMs - a.createdAtEpochMs) - .filter((test) => test.questionBank === questionBank) + .filter((test) => { + if (test.questionBank !== questionBank) return false; + if (status !== "all" && status !== test.status) return false; + if (mode !== "all" && mode !== test.mode) return false; + return true; + }) .map((test) => ({ ...test, ...processTest(test) })); + const numberOfFilters = Number(mode !== "all") + Number(status !== "all"); + return ( - + + + + + + + + + + + + + + } + fallback={ + <> + + + } + /> +