"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 (
);
}