diff --git a/src/renderer/components/organization/helpers.tsx b/src/renderer/components/organization/helpers.tsx index 07ef10ee..ceb9191d 100644 --- a/src/renderer/components/organization/helpers.tsx +++ b/src/renderer/components/organization/helpers.tsx @@ -1,44 +1,13 @@ -import { Heartbeat, Lightning, Trash, XCircle } from "@phosphor-icons/react"; +import { Heartbeat, Lightning } from "@phosphor-icons/react"; import type { AgentRecord } from "@shared/types"; -import { ActionButton, Select } from "../ui"; -import { formatMoney, formatTime } from "../../lib/formatters"; +import { ActionButton, BudgetBar, InlineConfirmDelete, Select } from "../ui"; +import { formatTime } from "../../lib/formatters"; import { unwrap } from "../../lib/desktop"; -export function BudgetBar({ spent, budget }: { spent: number; budget: number }) { - const pct = budget > 0 ? Math.min((spent / budget) * 100, 100) : 0; - const overBudget = spent > budget && budget > 0; - return ( -
-
-
-
- - {formatMoney(spent)} / {formatMoney(budget)} - -
- ); -} - -export function ConfirmDelete({ - entityLabel, - onConfirm, - onCancel, -}: { - entityLabel: string; - onConfirm: () => void; - onCancel: () => void; -}) { - return ( -
- Delete {entityLabel}? - - -
- ); -} +// Re-exports kept so existing importers continue to work while BudgetBar and +// the inline-delete confirmation live in the shared UI library. +export { BudgetBar }; +export const ConfirmDelete = InlineConfirmDelete; const HEARTBEAT_INTERVALS = [ { value: "30", label: "30 seconds" }, diff --git a/src/renderer/components/ui/BudgetBar.tsx b/src/renderer/components/ui/BudgetBar.tsx new file mode 100644 index 00000000..7b2a2bd0 --- /dev/null +++ b/src/renderer/components/ui/BudgetBar.tsx @@ -0,0 +1,19 @@ +import { formatMoney } from "../../lib/formatters"; + +export function BudgetBar({ spent, budget }: { spent: number; budget: number }) { + const pct = budget > 0 ? Math.min((spent / budget) * 100, 100) : 0; + const overBudget = spent > budget && budget > 0; + return ( +
+
+
+
+ + {formatMoney(spent)} / {formatMoney(budget)} + +
+ ); +} diff --git a/src/renderer/components/ui/feedback.tsx b/src/renderer/components/ui/feedback.tsx index 113042b8..b31a70b5 100644 --- a/src/renderer/components/ui/feedback.tsx +++ b/src/renderer/components/ui/feedback.tsx @@ -1,5 +1,6 @@ import { useEffect, type ReactNode } from "react"; import { AnimatePresence, motion } from "framer-motion"; +import { Trash, XCircle } from "@phosphor-icons/react"; import { ActionButton } from "./primitives"; import { useFocusTrap } from "./hooks"; @@ -137,6 +138,28 @@ export function ConfirmDialog({ open, title, message, errorMessage, onConfirm, o ); } +/* ------------------------------------------------------------------ */ +/* InlineConfirmDelete */ +/* ------------------------------------------------------------------ */ + +export function InlineConfirmDelete({ + entityLabel, + onConfirm, + onCancel, +}: { + entityLabel: string; + onConfirm: () => void; + onCancel: () => void; +}) { + return ( +
+ Delete {entityLabel}? + + +
+ ); +} + /* ------------------------------------------------------------------ */ /* EmptyState */ /* ------------------------------------------------------------------ */ diff --git a/src/renderer/components/ui/index.ts b/src/renderer/components/ui/index.ts index 4b4cd11e..85dc9e85 100644 --- a/src/renderer/components/ui/index.ts +++ b/src/renderer/components/ui/index.ts @@ -1,5 +1,6 @@ export { Badge, SectionButton, Panel, Field, Input, TextArea, Select, ActionButton, Spinner, Eyebrow, Card } from "./primitives"; -export { StatusPill, InlineNotice, ConfirmDialog, EmptyState } from "./feedback"; +export { StatusPill, InlineNotice, ConfirmDialog, InlineConfirmDelete, EmptyState } from "./feedback"; +export { BudgetBar } from "./BudgetBar"; export { Modal, ListFrame, ListRow } from "./layout"; export { useFocusTrap, useReducedMotion, ErrorBoundary } from "./hooks"; export { AttentionRow } from "./AttentionRow";