"use client"; import { useState, useRef, useEffect } from "react"; import Link from "next/link"; type SearchResult = { id: number; title: string; slug: string; coverUrl: string; }; export function SearchBar() { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const ref = useRef(null); const debounceRef = useRef>(null); useEffect(() => { function handleClickOutside(e: MouseEvent) { if (ref.current && !ref.current.contains(e.target as Node)) { setOpen(false); } } document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, []); function handleSearch(value: string) { setQuery(value); if (debounceRef.current) clearTimeout(debounceRef.current); if (value.trim().length < 2) { setResults([]); setOpen(false); return; } setLoading(true); debounceRef.current = setTimeout(async () => { try { const res = await fetch( `/api/search?q=${encodeURIComponent(value.trim())}` ); const data = await res.json(); setResults(data); setOpen(true); } catch { setResults([]); } finally { setLoading(false); } }, 300); } return (
handleSearch(e.target.value)} onFocus={() => results.length > 0 && setOpen(true)} placeholder="Search manga..." className="w-full pl-10 pr-4 py-2 text-sm bg-surface border border-border rounded-xl focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent placeholder:text-muted transition-colors" suppressHydrationWarning /> {loading && (
)}
{open && results.length > 0 && (
{results.map((manga) => ( { setOpen(false); setQuery(""); }} className="flex items-center gap-3 px-4 py-3 hover:bg-surface-hover transition-colors" > {manga.title} {manga.title} ))}
)} {open && query.trim().length >= 2 && results.length === 0 && !loading && (

No results found

)}
); }