Files
neuf-www/web/src/components/search/SearchContainer.tsx
T
2025-08-08 14:40:16 +02:00

113 lines
3.0 KiB
TypeScript

"use client";
import { useDebouncedCallback } from "use-debounce";
import { PageHeader } from "../general/PageHeader";
import { useSearchParams, usePathname, useRouter } from "next/navigation";
import { getSearchPath } from "@/lib/common";
import styles from './searchContainer.module.scss';
import { Icon } from "../general/Icon";
import Link from "next/link";
export function SearchContainer({
query,
results,
}: {
query: string;
results: any;
}) {
const searchParams = useSearchParams();
const pathname = usePathname();
const { replace } = useRouter();
const onQueryChange = useDebouncedCallback((query) => {
replace(getSearchPath(query));
}, 500);
return (
<div className={styles.searchContainer}>
<PageHeader heading="Søk" />
<div className={styles.searchField}>
<input
name="query"
type="text"
autoFocus
defaultValue={query ?? ""}
onChange={(e) => {
onQueryChange(e.target.value);
}}
/>
<div className={styles.searchIcon}>
<Icon type="search" />
</div>
</div>
{query && <SearchResults results={results} />}
</div>
);
}
function capitalizeFirstLetter(s: string) {
return s.charAt(0).toUpperCase() + s.slice(1);
}
function linkTo(page: any): string | null {
if (page.__typename === "EventPage") {
return `/arrangementer/${page.slug}`;
}
if (page.__typename === "NewsPage") {
return `/aktuelt/${page.slug}`;
}
if (page.__typename === "AssociationPage") {
return `/foreninger/${page.slug}`;
}
if (page.__typename === "GenericPage") {
return `/{page.slug}`;
}
if (page.__typename === "VenuePage") {
return `/lokaler/${page.slug}`;
}
return null;
}
const PAGE_TYPES: Record<string, string> = {
NewsPage: "Nyhet",
EventPage: "Arrangement",
GenericPage: "Underside",
VenuePage: "Lokale",
AssociationPage: "Forening",
};
function SearchResults({ results }: { results: any }) {
if (!results.length) {
return <div className={styles.noResults}>Ingen resultater</div>;
}
const supportedResults = results.filter(
(result: any) =>
!!result?.id && Object.keys(PAGE_TYPES).includes(result.__typename)
);
return (
<div>
<p className={styles.resultsCounter}>{results.length} resultater</p>
{supportedResults.map((result: any) => {
let resultType = PAGE_TYPES[result.__typename] ?? "";
if (result.__typename === "AssociationPage") {
resultType = capitalizeFirstLetter(result?.associationType);
}
const link = linkTo(result);
const ResultItem = () => (
<div className={styles.resultItem}>
<span className={styles.suphead}>{resultType}</span>
<h2 className={styles.title}>{result.title}</h2>
</div>
);
if (link) {
return (
<Link key={result.id} href={link}>
<ResultItem />
</Link>
);
}
return <ResultItem key={result.id} />;
})}
</div>
);
}