import { CheckCircle2, XCircle, Clock } from "lucide-react"; import { Link } from "@/lib/router"; import { Badge } from "@/components/ui/badge"; import { Button, buttonVariants } from "@/components/ui/button"; import { Identity } from "./Identity"; import { approvalSubject, typeIcon, defaultTypeIcon, ApprovalPayloadRenderer, typeLabel, } from "./ApprovalPayload"; import { timeAgo } from "../lib/timeAgo"; import type { Approval, Agent } from "@paperclipai/shared"; import { cn } from "@/lib/utils"; function statusIcon(status: string) { if (status === "approved") return ; if (status === "rejected") return ; if (status === "revision_requested") return ; if (status === "pending") return ; return null; } export function ApprovalCard({ approval, requesterAgent, onApprove, onReject, onOpen, detailLink, isPending = false, pendingAction = null, }: { approval: Approval; requesterAgent: Agent | null; onApprove?: () => void; onReject?: () => void; onOpen?: () => void; detailLink?: string; isPending?: boolean; pendingAction?: "approve" | "reject" | null; }) { const payload = approval.payload as Record | null; const Icon = typeIcon[approval.type] ?? defaultTypeIcon; const kindLabel = typeLabel[approval.type] ?? approval.type; const subject = approvalSubject(payload); const showResolutionButtons = Boolean(onApprove && onReject) && approval.type !== "budget_override_required" && (approval.status === "pending" || approval.status === "revision_requested"); const hasFooter = showResolutionButtons || Boolean(detailLink || onOpen); return (
{kindLabel} {requesterAgent && (
Requested by
)}

{subject ?? kindLabel}

Approval request created {timeAgo(approval.createdAt)}

{statusIcon(approval.status)} {approval.status.replace(/_/g, " ")}
{approval.decisionNote && (
Decision note. {approval.decisionNote}
)} {hasFooter ? (
{showResolutionButtons && ( <> )}
{(detailLink || onOpen) ? ( detailLink ? ( View details ) : ( ) ) : null}
) : null}
); }