"use client"; import { useState } from "react"; import { ChevronRight, ChevronDown, Circle, CheckCircle2, Clock } from "lucide-react"; import { cn } from "@/lib/utils"; export interface TreeNode { id: string; label: string; status?: "built" | "in_progress" | "missing"; children?: TreeNode[]; metadata?: { sessionsCount?: number; commitsCount?: number; cost?: number; }; } interface TreeViewProps { data: TreeNode[]; selectedId?: string | null; onSelect?: (node: TreeNode) => void; className?: string; } interface TreeNodeItemProps { node: TreeNode; level: number; selectedId?: string | null; onSelect?: (node: TreeNode) => void; } function TreeNodeItem({ node, level, selectedId, onSelect }: TreeNodeItemProps) { const [isExpanded, setIsExpanded] = useState(level === 0); // Auto-expand top level const hasChildren = node.children && node.children.length > 0; const isSelected = selectedId === node.id; const getStatusIcon = () => { if (!node.status) return null; switch (node.status) { case "built": return ; case "in_progress": return ; case "missing": return ; } }; const getStatusColor = () => { if (!node.status) return ""; switch (node.status) { case "built": return "bg-green-50 hover:bg-green-100 border-l-2 border-l-green-500"; case "in_progress": return "bg-blue-50 hover:bg-blue-100 border-l-2 border-l-blue-500"; case "missing": return "hover:bg-gray-100 border-l-2 border-l-transparent"; } }; return (
0 && "text-sm" )} style={{ paddingLeft: `${level * 12 + 8}px` }} onClick={() => { if (hasChildren) { setIsExpanded(!isExpanded); } if (onSelect) { onSelect(node); } }} > {hasChildren ? ( ) : (
{getStatusIcon()}
)} 1 && "text-muted-foreground" )}> {node.label} {node.metadata && (
{node.metadata.sessionsCount && node.metadata.sessionsCount > 0 && ( {node.metadata.sessionsCount}s )} {node.metadata.commitsCount && node.metadata.commitsCount > 0 && ( {node.metadata.commitsCount}c )}
)}
{hasChildren && isExpanded && (
{node.children!.map((child) => ( ))}
)}
); } export function TreeView({ data, selectedId, onSelect, className }: TreeViewProps) { return (
{data.map((node) => ( ))}
); }