"use client"; import { SweepButton } from "@/components/Buttons"; import { HexAvatar } from "@/components/HexAvatar"; import { useEffect, useRef, useState } from "react"; import type { DiscoverCategory } from "@/lib/discover"; import { fetchDiscover } from "@/lib/discover-client"; import type { ExpertResult } from "@/lib/experts-search"; import { fetchExperts } from "@/lib/experts-search-client"; export type SearchStatus = "idle" | "loading" | "ready" | "error"; export interface ExpertSearchViewProps { query: string; onQuery: (q: string) => void; categories: DiscoverCategory[]; activeCategory: string | null; onCategory: (name: string | null) => void; status: SearchStatus; results: ExpertResult[]; } export function ExpertSearchView(p: ExpertSearchViewProps) { return ( Find experts e.preventDefault()}> Search experts p.onQuery(e.target.value)} /> {p.categories.length > 0 ? ( {p.categories.map((c) => ( p.onCategory(p.activeCategory === c.name ? null : c.name)} /> ))} ) : null} {p.status === "loading" ? Searching... : null} {p.status === "error" ? Search is unavailable. Try again. : null} {p.status === "ready" && p.results.length === 0 ? ( No experts found. ) : null} {p.status === "ready" && p.results.length > 0 ? ( {p.results.map((e) => ( {e.displayName || "Expert"} {e.byline ? {e.byline} : null} {e.rating !== null ? ( {e.rating.toFixed(1)} ) : null} ))} ) : null} ); } const DEBOUNCE_MS = 300; export function ExpertSearch() { const [query, setQuery] = useState(""); const [category, setCategory] = useState(null); const [categories, setCategories] = useState([]); const [status, setStatus] = useState("idle"); const [results, setResults] = useState([]); const seq = useRef(0); useEffect(() => { let live = true; fetchDiscover().then( (d) => { if (live) setCategories(d.categories); }, () => {}, ); return () => { live = false; }; }, []); useEffect(() => { const q = query.trim(); const mine = ++seq.current; if (!q && !category) { setStatus("idle"); setResults([]); return; } setStatus("loading"); const t = setTimeout(() => { fetchExperts(q ? { q } : { category: category ?? undefined }).then( (r) => { if (seq.current === mine) { setResults(r); setStatus("ready"); } }, () => { if (seq.current === mine) { setResults([]); setStatus("error"); } }, ); }, q ? DEBOUNCE_MS : 0); return () => clearTimeout(t); }, [query, category]); return ( ); }
Searching...
Search is unavailable. Try again.
No experts found.