import type { Goal } from "@paperclipai/shared"; import { Link } from "@/lib/router"; import { StatusBadge } from "./StatusBadge"; import { ChevronRight } from "lucide-react"; import { cn } from "../lib/utils"; import { useState } from "react"; interface GoalTreeProps { goals: Goal[]; goalLink?: (goal: Goal) => string; onSelect?: (goal: Goal) => void; } interface GoalNodeProps { goal: Goal; children: Goal[]; allGoals: Goal[]; depth: number; goalLink?: (goal: Goal) => string; onSelect?: (goal: Goal) => void; } function GoalNode({ goal, children, allGoals, depth, goalLink, onSelect }: GoalNodeProps) { const [expanded, setExpanded] = useState(true); const hasChildren = children.length > 0; const link = goalLink?.(goal); const inner = ( <> {hasChildren ? ( ) : ( )} {goal.level} {goal.title} ); const classes = cn( "flex items-center gap-2 px-3 py-1.5 text-sm transition-colors cursor-pointer hover:bg-accent/50", ); return (
{link ? ( {inner} ) : (
onSelect?.(goal)} > {inner}
)} {hasChildren && expanded && (
{children.map((child) => ( g.parentId === child.id)} allGoals={allGoals} depth={depth + 1} goalLink={goalLink} onSelect={onSelect} /> ))}
)}
); } export function GoalTree({ goals, goalLink, onSelect }: GoalTreeProps) { const goalIds = new Set(goals.map((g) => g.id)); const roots = goals.filter((g) => !g.parentId || !goalIds.has(g.parentId)); if (goals.length === 0) { return

No goals.

; } return (
{roots.map((goal) => ( g.parentId === goal.id)} allGoals={goals} depth={0} goalLink={goalLink} onSelect={onSelect} /> ))}
); }