"use client"; import { useEffect, useRef, useState } from "react"; import Link from "next/link"; import Image from "next/image"; import type { SearchResult } from "../api/search/route"; const DEBOUNCE_MS = 250; export function SearchButton() { const [open, setOpen] = useState(false); useEffect(() => { if (!open) return; function onKeyDown(e: KeyboardEvent) { if (e.key === "Escape") setOpen(false); } document.addEventListener("keydown", onKeyDown); document.body.style.overflow = "hidden"; return () => { document.removeEventListener("keydown", onKeyDown); document.body.style.overflow = ""; }; }, [open]); return ( <> {open && setOpen(false)} />} ); } function SearchOverlay({ onClose }: { onClose: () => void }) { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const inputRef = useRef(null); const debounceRef = useRef | null>(null); useEffect(() => { inputRef.current?.focus(); }, []); useEffect(() => { if (debounceRef.current) clearTimeout(debounceRef.current); if (query.trim().length < 2) { setResults([]); setLoading(false); return; } setLoading(true); debounceRef.current = setTimeout(async () => { const res = await fetch(`/api/search?q=${encodeURIComponent(query.trim())}`, { cache: "no-store" }); const data: { results?: SearchResult[] } = await res.json().catch(() => ({ results: [] })); setResults(data.results ?? []); setLoading(false); }, DEBOUNCE_MS); return () => { if (debounceRef.current) clearTimeout(debounceRef.current); }; }, [query]); const products = results.filter((r) => r.type === "product"); const posts = results.filter((r) => r.type === "post"); return (
e.stopPropagation()}>
setQuery(e.target.value)} placeholder="Produkte, Blogbeiträge…" className="flex-1 min-w-0 bg-transparent outline-none text-h4 text-text-primary placeholder:text-text-muted" />
{loading &&

Suche…

} {!loading && query.trim().length >= 2 && results.length === 0 && (

Keine Treffer für „{query}“.

)} {products.length > 0 && (

Produkte

{products.map((r) => ( ))}
)} {posts.length > 0 && (

Blog

{posts.map((r) => ( ))}
)}
); } function SearchResultRow({ result, onClose }: { result: SearchResult; onClose: () => void }) { return (
{result.thumbnail && }
{result.title} ); }