84 lines
1.9 KiB
TypeScript
84 lines
1.9 KiB
TypeScript
import Fuse from "fuse.js";
|
|
import Head from "next/head";
|
|
import { useRouter } from "next/router";
|
|
import { useCallback, useMemo } from "react";
|
|
|
|
import { Filter } from "@/components/Filter/Filter";
|
|
import { ItemList } from "@/components/ItemList/ItemList";
|
|
import { getItems } from "@/lib/data";
|
|
import { formatTitle } from "@/lib/format";
|
|
import { CustomPage } from "@/pages/_app";
|
|
|
|
const Overview: CustomPage = () => {
|
|
const router = useRouter();
|
|
const ring = router.query.ring as string | undefined;
|
|
const query = (router.query.query as string) || "";
|
|
|
|
const onRingChange = useCallback(
|
|
(ring: string) => {
|
|
router.push({ query: { ...router.query, ring, query } });
|
|
},
|
|
[router, query],
|
|
);
|
|
|
|
const onQueryChange = useCallback(
|
|
(query: string) => {
|
|
router.replace({ query: { ...router.query, ring, query } });
|
|
},
|
|
[router, ring],
|
|
);
|
|
|
|
const { items, index } = useMemo(() => {
|
|
const items = getItems().filter((item) => !ring || item.ring === ring);
|
|
const index = new Fuse(items, {
|
|
threshold: 0.3,
|
|
includeScore: true,
|
|
keys: [
|
|
{
|
|
name: "title",
|
|
weight: 1.5,
|
|
},
|
|
{
|
|
name: "tags",
|
|
weight: 1,
|
|
},
|
|
{
|
|
name: "body",
|
|
weight: 0.9,
|
|
},
|
|
{
|
|
name: "revision.body",
|
|
weight: 0.7,
|
|
},
|
|
],
|
|
});
|
|
|
|
return { items, index };
|
|
}, [ring]);
|
|
|
|
const results = useMemo(() => {
|
|
if (!query) return items;
|
|
return index.search(query).map((result) => result.item);
|
|
}, [query, index, items]);
|
|
|
|
return (
|
|
<>
|
|
<Head>
|
|
<title>{formatTitle("Technologies Overview")}</title>
|
|
</Head>
|
|
|
|
<h1>Technologies Overview</h1>
|
|
<Filter
|
|
query={query}
|
|
ring={ring}
|
|
onRingChange={onRingChange}
|
|
onQueryChange={onQueryChange}
|
|
/>
|
|
|
|
<ItemList items={results} size="large" hideRing={!!ring} />
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Overview;
|