SPB Git
1.5 KB · 16 lines tsx
1"use client";2import { useEffect, useState } from "react";3import { useRouter } from "next/navigation";4import { Plus } from "lucide-react";5export function CompareSearch({ current }: { current: string[] }) {6  const router = useRouter(); const [q, setQ] = useState(""); const [hits, setHits] = useState<{ slug: string; name: string; kind: string }[]>([]);7  useEffect(() => { if (q.length < 2) { setHits([]); return; } const t = setTimeout(() => fetch(`/api/suggest?q=${encodeURIComponent(q)}`).then((r) => r.json()).then((h) => setHits(h.filter((x: any) => x.kind === "tool" && !current.includes(x.slug)))).catch(() => {}), 150); return () => clearTimeout(t); }, [q, current]);8  return (9    <div className="relative">10      <label className="sr-only" htmlFor="cmp-add">Add a tool to compare</label>11      <div className="flex items-center gap-1 rounded-full border border-dashed border-line-2 px-3 py-1"><Plus className="h-3.5 w-3.5 text-fg-3" aria-hidden /><input id="cmp-add" value={q} onChange={(e) => setQ(e.target.value)} placeholder="Add a tool…" className="w-36 bg-transparent text-sm outline-none placeholder:text-fg-3" /></div>12      {hits.length > 0 && <ul role="listbox" className="absolute z-20 mt-1 w-64 rounded-xl border border-line bg-bg-2 p-1 shadow-lift">{hits.map((h) => <li key={h.slug}><button type="button" onClick={() => { router.push(`/compare?tools=${[...current, h.slug].join(",")}`); setQ(""); setHits([]); }} className="w-full rounded-lg px-3 py-1.5 text-left text-sm hover:bg-bg-3">{h.name}</button></li>)}</ul>}13    </div>14  );15}16
Files · main
Menu

Theme