"use client"; import type { ReactNode } from "react"; import { CheckSquare, FileText, Folder, FolderKanban, LayoutDashboard, PenLine, } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { cn } from "@/lib/utils"; export type SearchResultItem = { id: string; type: string; title: string; status: string | null; parentId: string | null; workspaceId: string | null; descriptionSnippet: string | null; parentBreadcrumb: string | null; }; const TYPE_STYLES: Record< string, { Icon: typeof CheckSquare; className: string } > = { task: { Icon: CheckSquare, className: "text-teal-600 dark:text-teal-400 bg-teal-500/12 border-teal-500/25", }, document: { Icon: FileText, className: "text-sky-600 dark:text-sky-400 bg-sky-500/12 border-sky-500/25", }, project: { Icon: FolderKanban, className: "text-amber-600 dark:text-amber-400 bg-amber-500/12 border-amber-500/25", }, whiteboard: { Icon: PenLine, className: "text-violet-600 dark:text-violet-400 bg-violet-500/12 border-violet-500/25", }, group: { Icon: Folder, className: "text-orange-600 dark:text-orange-400 bg-orange-500/12 border-orange-500/25", }, workspace: { Icon: LayoutDashboard, className: "text-emerald-600 dark:text-emerald-400 bg-emerald-500/12 border-emerald-500/25", }, }; function escapeRegExp(s: string): string { return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } export function highlightText(text: string, query: string): ReactNode { const q = query.trim(); if (!q) return text; const re = new RegExp(`(${escapeRegExp(q)})`, "gi"); const parts = text.split(re); return parts.map((part, i) => { if (part.toLowerCase() === q.toLowerCase()) { return ( {part} ); } return {part}; }); } function formatStatus(status: string | null): string { if (!status) return ""; return status.replace(/_/g, " "); } export function SearchResultRow({ object, query, onClick, active, onMouseEnter, }: { object: SearchResultItem; query: string; onClick: () => void; active: boolean; onMouseEnter?: () => void; }) { const style = TYPE_STYLES[object.type] ?? { Icon: Folder, className: "text-muted-foreground bg-muted/80 border-border", }; const Icon = style.Icon; return ( ); }