"use client"; import { useEffect, useRef, useState } from "react"; import Link from "next/link"; import { getProducts } from "@/lib/api"; import type { ApiProduct } from "@/lib/types"; import { formatToman } from "@/lib/format"; import { productHref } from "@/lib/slug"; import { SearchIcon } from "./icons"; const MIN_QUERY_LENGTH = 3; const DEBOUNCE_MS = 350; export default function SearchBox({ placeholder = "جستجوی محصولات...", inputHeightClassName = "h-11", }: { placeholder?: string; inputHeightClassName?: string; }) { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const [open, setOpen] = useState(false); const containerRef = useRef(null); function handleQueryChange(value: string) { setQuery(value); if (value.trim().length < MIN_QUERY_LENGTH) { setResults([]); setOpen(false); setLoading(false); } else { setLoading(true); } } useEffect(() => { const term = query.trim(); if (term.length < MIN_QUERY_LENGTH) return; const handle = setTimeout(() => { getProducts({ name: term, pageSize: 6 }) .then((res) => { setResults(res.items); setOpen(true); }) .catch(() => setResults([])) .finally(() => setLoading(false)); }, DEBOUNCE_MS); return () => clearTimeout(handle); }, [query]); useEffect(() => { function onClickOutside(event: MouseEvent) { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setOpen(false); } } document.addEventListener("mousedown", onClickOutside); return () => document.removeEventListener("mousedown", onClickOutside); }, []); const term = query.trim(); const showDropdown = open && term.length >= MIN_QUERY_LENGTH; return (
handleQueryChange(e.target.value)} onFocus={() => term.length >= MIN_QUERY_LENGTH && setOpen(true)} placeholder={placeholder} className="flex-1 bg-transparent outline-none text-sm placeholder:text-body/70" />
{showDropdown && (
{loading &&

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

} {!loading && results.length === 0 && (

نتیجه‌ای یافت نشد

)} {!loading && results.map((product) => ( setOpen(false)} className="flex items-center gap-3 p-3 hover:bg-surface transition-colors border-b border-line last:border-0" >

{product.nameFa || product.title}

{product.store?.minPrice != null ? formatToman(product.store.minPrice) : "تماس بگیرید"}

))}
)}
); }