web: fix search debounce and client/server boundary

This commit is contained in:
2026-05-25 23:16:52 +02:00
parent 433c88c921
commit b5c9188488
3 changed files with 67 additions and 65 deletions
+57
View File
@@ -0,0 +1,57 @@
"use client";
import { useEffect, useRef, useState, useTransition, type ReactNode } from "react";
import { useDebouncedCallback } from "use-debounce";
import { useRouter } from "next/navigation";
import { PageHeader } from "../general/PageHeader";
import { getSearchPath } from "@/lib/common";
import styles from "./searchContainer.module.scss";
import { Icon } from "../general/Icon";
export function SearchShell({
initialQuery,
children,
}: {
initialQuery: string;
children: ReactNode;
}) {
const { replace } = useRouter();
const [inputValue, setInputValue] = useState(initialQuery);
const [, startTransition] = useTransition();
const lastPushedRef = useRef(initialQuery);
const pushQuery = useDebouncedCallback((next: string) => {
lastPushedRef.current = next;
startTransition(() => {
replace(getSearchPath(next));
});
}, 300);
useEffect(() => {
if (initialQuery !== lastPushedRef.current) {
lastPushedRef.current = initialQuery;
setInputValue(initialQuery);
}
}, [initialQuery]);
return (
<div className={styles.searchContainer}>
<PageHeader heading="Søk" />
<div className={styles.searchField}>
<input
name="query"
type="text"
autoFocus
value={inputValue}
onChange={(e) => {
setInputValue(e.target.value);
pushQuery(e.target.value);
}}
/>
<div className={styles.searchIcon}>
<Icon type="search" />
</div>
</div>
{children}
</div>
);
}