"use client"; import { useState } from "react"; import { Check, ChevronDown, X, Link2, ListTodo, FileEdit, Tag, AlertTriangle } from "lucide-react"; import { Markdown } from "@/components/markdown"; import { Badge } from "@/components/ui/primitives"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; export interface ProposalView { idx: number; tool: string; kind: "page_edit" | "task" | "link" | "property"; scope: string; scopeGranted: boolean; rationale: string; status: "proposed" | "approved" | "rejected" | "applied" | "failed"; payload: any; error?: string; result?: any; decidedAt?: string; appliedAt?: string } const ICON = { page_edit: FileEdit, task: ListTodo, link: Link2, property: Tag } as const; const TONE: Record = { proposed: "accent", approved: "success", applied: "success", rejected: "neutral", failed: "danger" }; const title = (p: ProposalView) => p.kind === "page_edit" ? `${p.payload.mode === "append" ? "Append to" : "Replace body of"} “${p.payload.pageTitle}”` : p.kind === "task" ? `New task: ${p.payload.title}` : p.kind === "link" ? `Link “${p.payload.fromTitle}” → “${p.payload.toTitle}”` : `Set ${p.payload.key} on “${p.payload.pageTitle}”`; export function ProposalCard({ p, busy, onApprove, onReject }: { p: ProposalView; busy: boolean; onApprove: () => void; onReject: () => void }) { const [showCurrent, setShowCurrent] = useState(false); const Icon = ICON[p.kind]; return (
#{p.idx + 1} · {title(p)}
{p.status}{!p.scopeGranted && p.status === "proposed" && {p.scope} not granted}

Why: {p.rationale}

{p.kind === "page_edit" &&
{p.payload.mode === "replace" &&
{showCurrent &&
}
}
+ {p.payload.mode === "append" ? "appended" : "new body"}
} {p.kind === "task" &&
Priority
{p.payload.priority}
Due
{p.payload.dueAt ? p.payload.dueAt.slice(0, 10) : "—"}
Page
{p.payload.pageTitle ? {p.payload.pageTitle} : "—"}
{p.payload.project && <>
Project
{p.payload.project}
}
} {p.kind === "link" &&
{p.payload.fromTitle}—{p.payload.relation}→{p.payload.toTitle}{p.payload.confidence != null && confidence {(p.payload.confidence * 100).toFixed(0)}%}
} {p.kind === "property" &&
{p.payload.key}: {JSON.stringify(p.payload.previous)} → {JSON.stringify(p.payload.value)} {p.payload.pageTitle}
} {p.error &&
Failed: {p.error}
} {p.status === "applied" && p.result &&
Applied {p.appliedAt ? new Date(p.appliedAt).toLocaleString() : ""} · {JSON.stringify(p.result)}
}
{p.status === "proposed" &&
}
); }