'use client'; import { useEffect, useRef, useState } from 'react'; import { MagnifyingGlassIcon } from '@heroicons/react/24/outline'; import { inputClass } from './ui'; export interface UserHit { id: string; name: string; email: string; role: string } /** Debounced search box with a result list; `search` decides who is eligible. */ export function UserSearch({ search, onPick, placeholder, noResults }: { search: (q: string) => Promise<{ users: UserHit[] }>; onPick: (u: UserHit) => void; placeholder: string; noResults: string; }) { const [q, setQ] = useState(''); const [hits, setHits] = useState([]); const [searched, setSearched] = useState(false); const seq = useRef(0); useEffect(() => { const term = q.trim(); if (term.length < 2) { setHits([]); setSearched(false); return; } const mine = ++seq.current; const timer = setTimeout(() => { search(term) .then((res) => { if (mine === seq.current) { setHits(res.users); setSearched(true); } }) .catch(() => { if (mine === seq.current) { setHits([]); setSearched(true); } }); }, 250); return () => clearTimeout(timer); }, [q, search]); return (
setQ(e.target.value)} placeholder={placeholder} />
{hits.length > 0 && ( )} {searched && hits.length === 0 &&

{noResults}

}
); }