add some basic search functionality
This commit is contained in:
@ -1,17 +1,19 @@
|
||||
"use client";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useState, useEffect } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import styles from "./header.module.scss";
|
||||
import { Logo, LogoIcon } from "@/components/general/Logo";
|
||||
import Icon from "../general/Icon";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { getSearchPath } from "@/lib/common";
|
||||
|
||||
export const Header = () => {
|
||||
const { ref: observer, inView: isInView } = useInView({
|
||||
triggerOnce: false,
|
||||
initialInView: true,
|
||||
});
|
||||
const { replace } = useRouter();
|
||||
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
function toggleMenu() {
|
||||
@ -42,6 +44,17 @@ export const Header = () => {
|
||||
undefined
|
||||
);
|
||||
|
||||
const handleSearch = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key != "Enter") {
|
||||
return;
|
||||
}
|
||||
const query = e.currentTarget.value;
|
||||
if (query) {
|
||||
setShowMenu(false);
|
||||
replace(getSearchPath(query));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<header
|
||||
@ -144,7 +157,7 @@ export const Header = () => {
|
||||
<li className={styles.search}>
|
||||
<label>
|
||||
<p>Søk</p>
|
||||
<input type="text" />
|
||||
<input type="text" onKeyDown={handleSearch} />
|
||||
</label>
|
||||
</li>
|
||||
<li className={styles.galtinn}>
|
||||
|
74
web/src/components/search/SearchContainer.tsx
Normal file
74
web/src/components/search/SearchContainer.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
"use client";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import { PageHeader } from "../general/PageHeader";
|
||||
import { useSearchParams, usePathname, useRouter } from "next/navigation";
|
||||
import { getSearchPath } from "@/lib/common";
|
||||
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>
|
||||
<PageHeader heading="Søk" />
|
||||
<input
|
||||
name="query"
|
||||
type="text"
|
||||
autoFocus
|
||||
defaultValue={query ?? ""}
|
||||
onChange={(e) => {
|
||||
onQueryChange(e.target.value);
|
||||
}}
|
||||
/>
|
||||
{query && <SearchResults results={results} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function capitalizeFirstLetter(s: string) {
|
||||
return s.charAt(0).toUpperCase() + s.slice(1);
|
||||
}
|
||||
|
||||
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>Ingen resultater 😔</div>;
|
||||
}
|
||||
const supportedResults = results.filter(
|
||||
(result: any) =>
|
||||
!!result?.id && Object.keys(PAGE_TYPES).includes(result.__typename)
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
{supportedResults.map((result: any) => {
|
||||
let resultType = PAGE_TYPES[result.__typename] ?? "";
|
||||
if (result.__typename === "AssociationPage") {
|
||||
resultType = capitalizeFirstLetter(result?.associationType);
|
||||
}
|
||||
return (
|
||||
<div key={result.id}>
|
||||
<span>{resultType}</span>
|
||||
<span>{result.title}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user