From 69b34e824f93fde3a804870f540820a23f727769 Mon Sep 17 00:00:00 2001 From: Sonny Date: Wed, 17 May 2023 20:19:11 +0200 Subject: [PATCH] feat: add search modal filter with persistence --- src/components/SearchModal/SearchListItem.tsx | 1 - src/components/SearchModal/SearchModal.tsx | 44 ++++++++++++------- src/hooks/useLocalStorage.tsx | 30 +++++++++++++ src/utils/array.ts | 17 +++++++ 4 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 src/hooks/useLocalStorage.tsx create mode 100644 src/utils/array.ts diff --git a/src/components/SearchModal/SearchListItem.tsx b/src/components/SearchModal/SearchListItem.tsx index 2f4ea78..9f9e89f 100644 --- a/src/components/SearchModal/SearchListItem.tsx +++ b/src/components/SearchModal/SearchListItem.tsx @@ -28,7 +28,6 @@ export default function SearchListItem({ useEffect(() => { if (selected && !isHover) { - console.log(selected, ref.current); ref.current?.scrollIntoView({ behavior: "smooth", block: "center" }); } }, [isHover, selected]); diff --git a/src/components/SearchModal/SearchModal.tsx b/src/components/SearchModal/SearchModal.tsx index f682879..307289e 100644 --- a/src/components/SearchModal/SearchModal.tsx +++ b/src/components/SearchModal/SearchModal.tsx @@ -12,6 +12,7 @@ import SearchList from "./SearchList"; import * as Keys from "constants/keys"; import { GOOGLE_SEARCH_URL } from "constants/search-urls"; import { Category, SearchItem } from "types"; +import { useLocalStorage } from "hooks/useLocalStorage"; import styles from "./search.module.scss"; @@ -28,9 +29,14 @@ export default function SearchModal({ }) { const autoFocusRef = useAutoFocus(); - // TODO: peristance - const [canSearchLink, setCanSearchLink] = useState(true); - const [canSearchCategory, setCanSearchCategory] = useState(true); + const [canSearchLink, setCanSearchLink] = useLocalStorage( + "search-link", + true + ); + const [canSearchCategory, setCanSearchCategory] = useLocalStorage( + "search-category", + false + ); const [search, setSearch] = useState(""); const [cursor, setCursor] = useState(0); @@ -41,12 +47,15 @@ export default function SearchModal({ () => search.length === 0 ? [] - : items.filter((item) => - item.name - .toLocaleLowerCase() - .includes(search.toLocaleLowerCase().trim()) + : items.filter( + (item) => + ((item.type === "category" && canSearchCategory) || + (item.type === "link" && canSearchLink)) && + item.name + .toLocaleLowerCase() + .includes(search.toLocaleLowerCase().trim()) ), - [items, search] + [canSearchCategory, canSearchLink, items, search] ); useHotkeys(Keys.ARROW_UP, () => setCursor((cursor) => (cursor -= 1)), { @@ -65,6 +74,14 @@ export default function SearchModal({ setSearch(value); setCursor(0); }, []); + const handleCanSearchLink = (checked: boolean) => { + setCanSearchLink(checked); + setCursor(0); + }; + const handleCanSearchCategory = (checked: boolean) => { + setCanSearchCategory(checked); + setCursor(0); + }; const handleSubmit = useCallback( (event: FormEvent) => { @@ -108,18 +125,13 @@ export default function SearchModal({ {search.length > 0 && ( ({ - id: item.id, - name: item.name, - url: item.url, - type: item.type, - }))} + items={itemsCompletion} noItem={} cursor={cursor} setCursor={setCursor} diff --git a/src/hooks/useLocalStorage.tsx b/src/hooks/useLocalStorage.tsx new file mode 100644 index 0000000..dc4f8ee --- /dev/null +++ b/src/hooks/useLocalStorage.tsx @@ -0,0 +1,30 @@ +import { useState } from "react"; + +export function useLocalStorage(key: string, initialValue: any) { + const [storedValue, setStoredValue] = useState(() => { + if (typeof window === "undefined") { + return initialValue; + } + try { + const item = window.localStorage.getItem(key); + return item ? JSON.parse(item) : initialValue; + } catch (error) { + console.log(error); + return initialValue; + } + }); + + const setValue = (value: any) => { + try { + const valueToStore = + value instanceof Function ? value(storedValue) : value; + setStoredValue(valueToStore); + if (typeof window !== "undefined") { + window.localStorage.setItem(key, JSON.stringify(valueToStore)); + } + } catch (error) { + console.log(error); + } + }; + return [storedValue, setValue]; +} diff --git a/src/utils/array.ts b/src/utils/array.ts new file mode 100644 index 0000000..1097729 --- /dev/null +++ b/src/utils/array.ts @@ -0,0 +1,17 @@ +export function groupItemBy(array: any[], property: string) { + const hash = {}; + const props = property.split("."); + + for (const item of array) { + const key = props.reduce((acc, prop) => acc && acc[prop], item); + const hashKey = key !== undefined ? key : "catégories"; + + if (!hash[hashKey]) { + hash[hashKey] = []; + } + + hash[hashKey].push(item); + } + + return hash; +}