import { useEffect, useState } from "react"; import type { BudgetPolicySummary } from "@paperclipai/shared"; import { AlertTriangle, PauseCircle, ShieldAlert, Wallet } from "lucide-react"; import { cn, formatCents } from "../lib/utils"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; function centsInputValue(value: number) { return (value / 100).toFixed(2); } function parseDollarInput(value: string) { const normalized = value.trim(); if (normalized.length === 0) return 0; const parsed = Number(normalized); if (!Number.isFinite(parsed) || parsed < 0) return null; return Math.round(parsed * 100); } function windowLabel(windowKind: BudgetPolicySummary["windowKind"]) { return windowKind === "lifetime" ? "Lifetime budget" : "Monthly UTC budget"; } function statusTone(status: BudgetPolicySummary["status"]) { if (status === "hard_stop") return "text-red-300 border-red-500/30 bg-red-500/10"; if (status === "warning") return "text-amber-200 border-amber-500/30 bg-amber-500/10"; return "text-emerald-200 border-emerald-500/30 bg-emerald-500/10"; } export function BudgetPolicyCard({ summary, onSave, isSaving, compact = false, }: { summary: BudgetPolicySummary; onSave?: (amountCents: number) => void; isSaving?: boolean; compact?: boolean; }) { const [draftBudget, setDraftBudget] = useState(centsInputValue(summary.amount)); useEffect(() => { setDraftBudget(centsInputValue(summary.amount)); }, [summary.amount]); const parsedDraft = parseDollarInput(draftBudget); const canSave = typeof parsedDraft === "number" && parsedDraft !== summary.amount && Boolean(onSave); const progress = summary.amount > 0 ? Math.min(100, summary.utilizationPercent) : 0; const StatusIcon = summary.status === "hard_stop" ? ShieldAlert : summary.status === "warning" ? AlertTriangle : Wallet; return (
{summary.scopeType}
{summary.scopeName} {windowLabel(summary.windowKind)}
{summary.paused ? "Paused" : summary.status === "warning" ? "Warning" : summary.status === "hard_stop" ? "Hard stop" : "Healthy"}
Observed
{formatCents(summary.observedAmount)}
{summary.amount > 0 ? `${summary.utilizationPercent}% of limit` : "No cap configured"}
Budget
{summary.amount > 0 ? formatCents(summary.amount) : "Disabled"}
Soft alert at {summary.warnPercent}%{summary.paused && summary.pauseReason ? ` ยท ${summary.pauseReason} pause` : ""}
Remaining {summary.amount > 0 ? formatCents(summary.remainingAmount) : "Unlimited"}
{summary.paused ? (
{summary.scopeType === "project" ? "Execution is paused for this project until the budget is raised or the incident is dismissed." : "Heartbeats are paused for this scope until the budget is raised or the incident is dismissed."}
) : null} {onSave ? (
setDraftBudget(event.target.value)} className="mt-2" inputMode="decimal" placeholder="0.00" />
{parsedDraft === null ? (

Enter a valid non-negative dollar amount.

) : null}
) : null} ); }