Skip to content

Commit

Permalink
feat: add instantsearch page
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinstadler committed Aug 20, 2024
1 parent 33e5f14 commit ed73597
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
58 changes: 55 additions & 3 deletions app/instantsearch/instantsearch.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
"use client";
import { Hits, SearchBox } from "react-instantsearch";
import { useTranslations } from "next-intl";
import { Configure, Hits, Pagination, RefinementList, SearchBox } from "react-instantsearch";
import { InstantSearchNext } from "react-instantsearch-nextjs";
import TypesenseInstantSearchAdapter, { type SearchClient } from "typesense-instantsearch-adapter";

import { ClickablePublicationThumbnail } from "@/components/publication-cover";
import type { Publication } from "@/types/model";

export function InstantSearch() {
const t = useTranslations("SearchPage");

const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
server: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Expand All @@ -29,11 +35,57 @@ export function InstantSearch() {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const searchClient = typesenseInstantsearchAdapter.searchClient as unknown as SearchClient;

function DefaultRefinementList({
attribute,
attributeName,
}: {
attribute: string;
attributeName: string;
}) {
return (
<RefinementList
attribute={attribute}
classNames={{
count: 'before:content-["("] after:content-[")"]',
labelText: "px-1",
}}
searchable={true}
searchablePlaceholder={`${t("filter")} ${attributeName}`}
showMore={true}
showMoreLimit={100}
/>
);
}

return (
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
<InstantSearchNext indexName="thomas-bernhard" searchClient={searchClient}>
<SearchBox />
<Hits />
<Configure hitsPerPage={12} />
<div>
<DefaultRefinementList attribute="language" attributeName="languages" />
<DefaultRefinementList attribute="contains.work.title" attributeName="works" />
<DefaultRefinementList attribute="contains.translators.name" attributeName="translators" />
</div>
<div>
<div className="flex place-content-between">
<SearchBox placeholder={t("filter_publications")} />
<Pagination
classNames={{
root: "float-right",
list: "flex gap-1",
noRefinementRoot: "hidden",
}}
/>
</div>
<Hits
classNames={{
list: "m-2 grid grid-cols-1 md:grid-cols-4",
}}
hitComponent={({ hit }) => {
return <ClickablePublicationThumbnail publication={hit as unknown as Publication} />;
}}
/>
</div>
</InstantSearchNext>
);
}
4 changes: 4 additions & 0 deletions components/app-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export function AppHeader(): ReactNode {
href: createHref({ pathname: "/translator" }),
label: t("links.translators"),
},
search: {
href: createHref({ pathname: "/instantsearch" }),
label: t("links.search"),
},
} satisfies Record<string, { href: LinkProps["href"]; label: string }>;

return (
Expand Down
1 change: 1 addition & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"home": "home",
"works": "explore works",
"languages": "languages",
"search": "search",
"translators": "translators"
},
"navigation-primary": "Primary"
Expand Down

0 comments on commit ed73597

Please sign in to comment.