"use client"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { Search, X } from "lucide-react"; import { FormEvent, useEffect, useState } from "react"; import { Input } from "@/components/ui/input"; import type { Product } from "@/lib/headless/types"; export function PredictiveSearch() { const router = useRouter(); const [query, setQuery] = useState(""); const [matches, setMatches] = useState([]); const [loading, setLoading] = useState(false); const normalized = query.trim(); useEffect(() => { if (normalized.length < 2) { setMatches([]); setLoading(false); return; } const controller = new AbortController(); setLoading(true); const timer = setTimeout(() => { fetch(`/api/search?q=${encodeURIComponent(normalized)}`, { signal: controller.signal, }) .then((response) => response.json()) .then((data: { products?: Product[] }) => { setMatches((data.products ?? []).slice(0, 6)); }) .catch((error) => { if ((error as Error).name !== "AbortError") setMatches([]); }) .finally(() => setLoading(false)); }, 250); return () => { clearTimeout(timer); controller.abort(); }; }, [normalized]); const submit = (event: FormEvent) => { event.preventDefault(); const value = query.trim(); if (!value) return; router.push(`/catalog?q=${encodeURIComponent(value)}`); setQuery(""); }; return (
setQuery(event.target.value)} placeholder="Busca juguetes, mochilas, personajes…" className="h-[48px] border-0 bg-transparent p-0 shadow-none focus-visible:ring-0" /> {query && }
{loading && normalized.length >= 2 && matches.length === 0 && (
Buscando…
)} {matches.length > 0 && (
{matches.map((product) => ( setQuery("")}>
{product.name}{product.category} · {product.collection}
))}
)}
); }