"use client"; import Link from "next/link"; import { useEffect, useId, useRef, useState } from "react"; import type { Product } from "@/lib/data"; import { formatPrice } from "@/lib/format"; import { IconSearch } from "./Icons"; import { Media } from "./Media"; type Props = { className?: string; onNavigate?: () => void; }; export function SearchBox({ className = "", onNavigate }: Props) { const listId = useId(); const root = useRef(null); const [query, setQuery] = useState(""); const [items, setItems] = useState([]); const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); useEffect(() => { const term = query.trim(); if (term.length < 2) { setItems([]); setLoading(false); setOpen(false); return; } const controller = new AbortController(); const timer = window.setTimeout(async () => { setLoading(true); try { const response = await fetch(`/api/search?q=${encodeURIComponent(term)}`, { signal: controller.signal }); const data = (await response.json()) as { items?: Product[] }; setItems(data.items ?? []); setOpen(true); } catch (error) { if ((error as { name?: string }).name !== "AbortError") { setItems([]); setOpen(true); } } finally { setLoading(false); } }, 160); return () => { window.clearTimeout(timer); controller.abort(); }; }, [query]); useEffect(() => { const onPointer = (event: MouseEvent) => { if (!root.current?.contains(event.target as Node)) setOpen(false); }; document.addEventListener("mousedown", onPointer); return () => document.removeEventListener("mousedown", onPointer); }, []); return (
setQuery(event.target.value)} onFocus={() => { if (query.trim().length >= 2) setOpen(true); }} onKeyDown={(event) => { if (event.key === "Escape") setOpen(false); }} placeholder="جستجو ..." autoComplete="off" role="combobox" aria-expanded={open} aria-controls={listId} className="w-full min-w-0 flex-1 bg-transparent py-2.5 text-sm outline-none placeholder:text-zinc-400" />
{open && (
{loading && !items.length ? (

در حال جستجو...

) : items.length ? (
    {items.map((product) => { const unavailable = product.stock === 0 || product.price === 0; return (
  • {product.name}

    {unavailable ? (

    ناموجود

    ) : (

    {formatPrice(product.price)} تومان

    )}
  • ); })}
) : (

نتیجه‌ای پیدا نشد.

)} مشاهده همه نتایج
)}
); }