import clsx from "clsx" import Link from "next/link" import { Fragment, useEffect, useMemo, useState } from "react" import { Configure, ConfigureProps, Index, Snippet, useHits, useInstantSearch, } from "react-instantsearch" import SearchNoResult from "../NoResults" import SearchHitGroupName from "./GroupName" import getBaseUrl from "../../../utils/get-base-url" import { useSearch } from "../../../providers/search" type Hierarchy = "lvl0" | "lvl1" | "lvl2" | "lvl3" | "lvl4" | "lvl5" export type HitType = { hierarchy: { lvl0: string | null lvl1: string | null lvl2: string | null lvl3: string | null lvl4: string | null lvl5: string | null } _tags: string[] url: string type?: "lvl1" | "lvl2" | "lvl3" | "lvl4" | "lvl5" | "content" content?: string __position: number __queryID?: string objectID: string } type GroupedHitType = { [k: string]: HitType[] } type SearchHitWrapperProps = { configureProps: ConfigureProps } type IndexResults = { [k: string]: boolean } const SearchHitsWrapper = ({ configureProps }: SearchHitWrapperProps) => { const { status } = useInstantSearch() const indices = useMemo( () => [ process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", ], [] ) const [hasNoResults, setHashNoResults] = useState({ [indices[0]]: false, [indices[1]]: false, }) const showNoResults = useMemo(() => { return Object.values(hasNoResults).every((value) => value === true) }, [hasNoResults]) const setNoResults = (index: string, value: boolean) => { setHashNoResults((prev: IndexResults) => ({ ...prev, [index]: value, })) } return (
{status !== "loading" && showNoResults && } {indices.map((indexName, index) => ( ))}
) } type SearchHitsProps = { indexName: string setNoResults: (index: string, value: boolean) => void } const SearchHits = ({ indexName, setNoResults }: SearchHitsProps) => { const { hits } = useHits() const { status } = useInstantSearch() const { setIsOpen } = useSearch() // group by lvl0 const grouped = useMemo(() => { const grouped: GroupedHitType = {} hits.forEach((hit) => { if (hit.hierarchy.lvl0) { if (!grouped[hit.hierarchy.lvl0]) { grouped[hit.hierarchy.lvl0] = [] } grouped[hit.hierarchy.lvl0].push(hit) } }) return grouped }, [hits]) useEffect(() => { if (status !== "loading" && status !== "stalled") { setNoResults(indexName, hits.length === 0) } }, [hits, status]) const getLastAvailableHeirarchy = (item: HitType) => { return ( Object.keys(item.hierarchy) .reverse() .find((key) => item.hierarchy[key as Hierarchy] !== null) || "" ) } const baseUrl = useMemo(() => getBaseUrl(), []) const checkIfInternal = (url: string): boolean => { const testRegex = new RegExp(`^${baseUrl}/api/(admin|store)`) return testRegex.test(url) } return (
{Object.keys(grouped).map((groupName, index) => ( {grouped[groupName].map((item, index) => (
{ const target = e.target as Element if (target.tagName.toLowerCase() === "div") { target.querySelector("a")?.click() } }} > {item.type !== "lvl1" && ( )} { if (checkIfInternal(item.url)) { e.preventDefault() window.location.href = item.url setIsOpen(false) } }} />
))}
))}
) } export default SearchHitsWrapper