From bd1e7316746880cdee1334dab83b833bd645a97e Mon Sep 17 00:00:00 2001 From: Zain Fathoni Date: Sat, 17 Jul 2021 12:27:46 +0800 Subject: [PATCH] Refactor useSearch to be more generic for reusability across pages --- lib/hooks/use-search.ts | 27 ++++++++++++++++ pages/provinces/[provinceSlug]/index.tsx | 40 ++++++++---------------- pages/provinces/index.tsx | 17 ++-------- 3 files changed, 43 insertions(+), 41 deletions(-) create mode 100644 lib/hooks/use-search.ts diff --git a/lib/hooks/use-search.ts b/lib/hooks/use-search.ts new file mode 100644 index 000000000..be90226f2 --- /dev/null +++ b/lib/hooks/use-search.ts @@ -0,0 +1,27 @@ +import { useState } from "react"; + +export function useSearch(items: T[], fieldNames: string[]) { + const [filteredItems, setFilteredItems] = useState(items); + const handleSubmitKeywords = (keywords: string) => { + const lowerKeywords = keywords.toLowerCase(); + setFilteredItems( + items.filter((item) => { + const filterBy = (fieldName: keyof T) => { + const selectedField = item[fieldName]; + + if (typeof selectedField === "string") { + return selectedField.toLowerCase().includes(lowerKeywords); + } else { + return false; + } + }; + + const filterFunctions = fieldNames.map((fieldName) => + filterBy(fieldName as keyof T) + ); + return filterFunctions.reduce((acc, curr) => acc || curr, false); + }) + ); + }; + return [filteredItems, handleSubmitKeywords] as const; +} diff --git a/pages/provinces/[provinceSlug]/index.tsx b/pages/provinces/[provinceSlug]/index.tsx index a7cd1a8c1..2aceabde8 100644 --- a/pages/provinces/[provinceSlug]/index.tsx +++ b/pages/provinces/[provinceSlug]/index.tsx @@ -1,7 +1,7 @@ import { GetStaticPaths, GetStaticProps } from "next"; -import { useState } from "react"; import { ContactList } from "../../../components/contact-list"; import { SearchForm } from "../../../components/search-form"; +import { useSearch } from "../../../lib/hooks/use-search"; import provinces, { Contact, getProvincesPaths, @@ -14,35 +14,21 @@ type ProvinceProps = { provinceSlug: string; }; -const useSearch = (items: Contact[]) => { - const [filteredItems, setFilteredItems] = useState(items); - const handleSubmitKeywords = (keywords: string) => { - const lowerKeywords = keywords.toLowerCase(); - setFilteredItems( - items.filter((item) => { - const filterBy = (fieldName: keyof Contact) => - item[fieldName]?.toLowerCase().includes(lowerKeywords) ?? false; - return ( - filterBy("kebutuhan") || - filterBy("penyedia") || - filterBy("lokasi") || - filterBy("alamat") || - filterBy("keterangan") || - filterBy("kontak") || - filterBy("tautan") || - filterBy("tambahan_informasi") || - filterBy("bentuk_verifikasi") - ); - }) - ); - }; - return [filteredItems, handleSubmitKeywords] as const; -}; - export default function ProvincePage(props: ProvinceProps) { const { province, provinceSlug } = props; const [filteredContacts, handleSubmitKeywords] = useSearch( - props.province.data + props.province.data, + [ + "kebutuhan", + "penyedia", + "lokasi", + "alamat", + "keterangan", + "kontak", + "tautan", + "tambahan_informasi", + "bentuk_verifikasi", + ] ); if (province) { diff --git a/pages/provinces/index.tsx b/pages/provinces/index.tsx index ae2e46a0f..2eb59ad14 100644 --- a/pages/provinces/index.tsx +++ b/pages/provinces/index.tsx @@ -2,28 +2,17 @@ import { GetStaticProps } from "next"; import provinces from "../../lib/provinces"; import { getInitial, getSlug } from "../../lib/string-utils"; import { SearchForm } from "../../components/search-form"; -import { useState } from "react"; import { ProvinceList, ProvinceListItem } from "../../components/province-list"; +import { useSearch } from "../../lib/hooks/use-search"; type ProvincesPageProps = { provincesList: ProvinceListItem[]; }; -const useSearch = (items: ProvinceListItem[]) => { - const [filteredItems, setFilteredItems] = useState(items); - const handleSubmitKeywords = (keywords: string) => { - setFilteredItems( - items.filter((item) => { - return item.name.toLowerCase().includes(keywords.toLowerCase()); - }) - ); - }; - return [filteredItems, handleSubmitKeywords] as const; -}; - export default function ProvincesPage(props: ProvincesPageProps) { const [filteredProvinces, handleSubmitKeywords] = useSearch( - props.provincesList + props.provincesList, + ["name"] ); return (