"use client"; import { useEffect, useRef, useState, useTransition } from "react"; import { usePathname, useRouter } from "next/navigation"; import { clsx } from "clsx"; /** * Suchfeld mit Typfilter. * * Die Anfrage steht in der URL — damit sind Treffer teilbar, der Zurück-Knopf * funktioniert und die Suche selbst bleibt eine Server-Komponente. Getippte * Eingaben werden kurz gesammelt, bevor die Adresse fortgeschrieben wird. */ export function SearchField({ initialQuery, filter, filters, }: { initialQuery: string; filter: string; filters: { key: string; label: string }[]; }) { const router = useRouter(); const pathname = usePathname(); const [value, setValue] = useState(initialQuery); const [pending, startTransition] = useTransition(); const first = useRef(true); useEffect(() => { // Beim ersten Rendern nichts tun — sonst ersetzt die Komponente die // gerade geladene URL durch eine identische. if (first.current) { first.current = false; return; } const timer = setTimeout(() => { const params = new URLSearchParams(); if (value.trim()) params.set("q", value.trim()); if (filter !== "alle") params.set("typ", filter); startTransition(() => { router.replace(`${pathname}?${params.toString()}`, { scroll: false }); }); }, 350); return () => clearTimeout(timer); }, [value, filter, pathname, router]); function selectFilter(key: string) { const params = new URLSearchParams(); if (value.trim()) params.set("q", value.trim()); if (key !== "alle") params.set("typ", key); startTransition(() => { router.replace(`${pathname}?${params.toString()}`, { scroll: false }); }); } return (
setValue(event.target.value)} placeholder="Serie oder Film suchen …" aria-label="Suchbegriff" autoFocus className="fl-input pl-10 text-base" /> {pending && ( sucht … )}
{filters.map((item) => ( ))}
); } function SearchIcon() { return ( ); }