'use client'; import { useState, useEffect, useRef } from 'react'; import Link from 'next/link'; import { Search, X, Loader2, FileText } from 'lucide-react'; export default function SearchBox() { const [open, setOpen] = useState(false); const [q, setQ] = useState(''); const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const inputRef = useRef(null); const debounceRef = useRef(null); // открытие хоткеем / useEffect(() => { const onKey = (e) => { if (e.key === '/' && !['INPUT','TEXTAREA'].includes(document.activeElement?.tagName)) { e.preventDefault(); setOpen(true); } if (e.key === 'Escape') setOpen(false); }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, []); useEffect(() => { if (open) { setTimeout(() => inputRef.current?.focus(), 50); document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = ''; setQ(''); setResults([]); } }, [open]); // дебаунсовый поиск useEffect(() => { if (!open) return; if (debounceRef.current) clearTimeout(debounceRef.current); if (q.trim().length < 2) { setResults([]); setLoading(false); return; } setLoading(true); debounceRef.current = setTimeout(async () => { try { const r = await fetch(`/api/search?q=${encodeURIComponent(q.trim())}`); const data = await r.json(); setResults(Array.isArray(data) ? data : []); } catch { setResults([]); } setLoading(false); }, 250); }, [q, open]); return ( <> {open && (