import React from "react"; import { cn } from "@/lib/utils"; import { colorMixSwatch } from "@/lib/colors"; import { Button } from "./button"; import { EditableMoneyItem } from "./editable-money-item"; import { CalculatorInputItem } from "./calculator-input-item"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "./accordion"; /** * Right-panel organism for the Borrowing Capacity page. * * Composes: * - Collapsible income accordion with editable sub-items * - Expense rows (editable + read-only) separated by dividers * - Stacked proportional bar visualising income vs expenses * - Apply footer button * * All values are pre-formatted strings — business logic stays in the app layer. */ const INCOME_COLOR = "#39FD99"; const SURPLUS_COLOR = "#C65AFF"; const EXPENSES_COLOR = "#9B9EA1"; const DEBT_COLOR = "#162029"; // Distinct opacities let viewers distinguish HEM row from debt row sharing the same hue const HEM_FILL_OPACITY = 0.7; const DEBT_FILL_OPACITY = 0.8; export interface CalculatorIncomeItem { key: string; /** e.g. "Avg Income Per Month" */ label: string; /** Pre-formatted e.g. "$8,500" */ value: string; } export interface CalculatorSectionProps { // ── Income accordion ───────────────────────────────── /** Formatted total of all income sources, e.g. "$12,500" */ incomeTotalFormatted: string; /** Individual income line items shown when accordion is open */ incomeItems: CalculatorIncomeItem[]; /** Initial open/closed state of the accordion (uncontrolled after mount) */ defaultIncomeExpanded?: boolean; onIncomeExpandChange?: (open: boolean) => void; /** Called with the item key when a pencil button is clicked */ onIncomeItemEdit?: (key: string) => void; // ── Expense rows ────────────────────────────────────── currentExpensesValue: string; currentExpensesTooltip?: string; /** * Raw number — enables inline editing directly in the row. * Must be paired with `onCurrentExpensesChange`. */ currentExpenses?: number; onCurrentExpensesChange?: (value: number) => void; /** Fallback: called when pencil is clicked (no inline edit) */ onCurrentExpensesEdit?: () => void; optimisedEstimateValue: string; optimisedEstimateTooltip?: string; debtRepaymentsValue: string; /** * Raw number — enables inline editing directly in the row. * Must be paired with `onDebtRepaymentsChange`. */ debtRepayments?: number; onDebtRepaymentsChange?: (value: number) => void; /** Fallback: called when pencil is clicked (no inline edit) */ onDebtRepaymentsEdit?: () => void; surplusIncomeValue: string; // ── Bar proportions (0–100) ─────────────────────────── surplusPercent: number; currentExpensesPercent: number; debtRepaymentsPercent: number; // ── Footer ──────────────────────────────────────────── /** Enables the Save button */ hasChanges?: boolean; /** Shows loading state on the Save button */ isSaving?: boolean; onSave?: () => void; className?: string; } function RowDivider() { return
; } export function CalculatorSection({ incomeTotalFormatted, incomeItems, defaultIncomeExpanded = false, onIncomeExpandChange, onIncomeItemEdit, currentExpensesValue, currentExpensesTooltip, currentExpenses, onCurrentExpensesChange, onCurrentExpensesEdit, optimisedEstimateValue, optimisedEstimateTooltip, debtRepaymentsValue, debtRepayments, onDebtRepaymentsChange, onDebtRepaymentsEdit, surplusIncomeValue, surplusPercent, currentExpensesPercent, debtRepaymentsPercent, hasChanges = false, isSaving = false, onSave, className, }: CalculatorSectionProps) { const [accordionValue, setAccordionValue] = React.useStateCalculator Used