"use client" import * as React from "react" import { useRouter } from "@/lib/router-compat" import { Button } from "@/components/ui/button" import { Tip } from "@/components/ui/tip" import type { DedicatedSearchRecentsController } from "@/lib/dedicated-search-recents" export interface DedicatedSearchRecentsProps { recents: Pick searchParamsKey: string replacePath: string patchSearchParams: (current: URLSearchParams, submittedText: string) => URLSearchParams sectionTitle?: string clearLabel?: string } /** * Recent query rows — reads storage only after mount so SSR and first client paint match (no hydration drift). */ export function DedicatedSearchRecents({ recents, searchParamsKey, replacePath, patchSearchParams, sectionTitle = "Recently searched", clearLabel = "Clear", }: DedicatedSearchRecentsProps) { const router = useRouter() const [items, setItems] = React.useState([]) React.useEffect(() => { const sync = () => setItems(recents.read()) sync() window.addEventListener(recents.eventName, sync) window.addEventListener("storage", sync) return () => { window.removeEventListener(recents.eventName, sync) window.removeEventListener("storage", sync) } }, [recents]) const runQuery = React.useCallback( (q: string) => { recents.record(q) const next = patchSearchParams(new URLSearchParams(searchParamsKey), q) const qs = next.toString() router.replace(qs ? `${replacePath}?${qs}` : replacePath) }, [patchSearchParams, recents, replacePath, router, searchParamsKey], ) if (items.length === 0) { return null } const headingId = "dedicated-search-recents-heading" return (

{sectionTitle}

{items.map((q, i) => (