"use client"; import * as React from "react"; import { useRouter } from "next/navigation"; import { Search, Loader2, Building2, Mail, Workflow, FileText } from "lucide-react"; import { useDebounce } from "@/hooks/use-debounce"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command"; import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; import { useApi } from "@/hooks/use-api"; interface SearchResult { type: 'business' | 'template' | 'workflow'; id: string; title: string; subtitle: string; url: string; } export function GlobalSearch() { const router = useRouter(); const [open, setOpen] = React.useState(false); const [query, setQuery] = React.useState(""); const debouncedQuery = useDebounce(query, 300); const [results, setResults] = React.useState([]); const { get, loading } = useApi<{ results: SearchResult[] }>(); React.useEffect(() => { const down = (e: KeyboardEvent) => { if (e.key === "k" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); setOpen((open) => !open); } }; document.addEventListener("keydown", down); return () => document.removeEventListener("keydown", down); }, []); React.useEffect(() => { if (!debouncedQuery || debouncedQuery.length < 2) { setResults([]); return; } const fetchResults = async () => { const data = await get(`/api/search?q=${encodeURIComponent(debouncedQuery)}`); if (data && data.results) { setResults(data.results); } }; fetchResults(); }, [debouncedQuery, get]); const handleSelect = (url: string) => { setOpen(false); router.push(url); }; const getIcon = (type: string) => { switch (type) { case 'business': return ; case 'template': return ; case 'workflow': return ; default: return ; } }; return ( <> Global Search {loading ? (
) : query.length > 0 && query.length < 2 ? (
Type at least 2 characters...
) : ( "No results found." )}
{results.length > 0 && ( {results.map((result) => ( handleSelect(result.url)} className="cursor-pointer" > {getIcon(result.type)} {result.title} {result.subtitle && ( - {result.subtitle} )} ))} )}
); }