import React from "react"; import { TrendingUp, TrendingDown, Minus, Plus } from "lucide-react"; import { cn } from "@/lib/utils"; import { formatCurrencyAbbrev } from "@/lib/format-currency"; import { Button } from "./button"; // ─── BorrowCapacityItem ─────────────────────────────────────────────────────── /** * Displays a single borrowing capacity result field. * Shows a muted label, optional sub-label, and the formatted value below. * * Used inside scenario detail cards on the Borrowing Capacity page. */ export interface BorrowCapacityItemProps { /** Label above the value (e.g. "Purchase Price") */ title?: string; /** Optional secondary descriptor below the title */ subTitle?: string; /** Pre-formatted value string to display (e.g. "$500,000") */ value?: string; className?: string; } export function BorrowCapacityItem({ title, subTitle, value, className, }: BorrowCapacityItemProps) { if (!title && !value) { return
; } return (
{title && ( {title} )} {value && ( {value} )} {subTitle && ( {subTitle} )}
); } // ─── StatisticItem ──────────────────────────────────────────────────────────── /** * Shows a financial trend statistic over a lookback period. * Displays a heading ("Last N months"), the absolute dollar change, * and the percentage change with a direction icon. * * Trend colors: positive → primary, flat/negative → muted. * * Used in the statistics summary row of the Borrowing Capacity page. */ export interface StatisticItemProps { /** Number of months to look back (default: 3) */ loopBackMonths?: number; /** Absolute dollar amount of change */ amountChange?: number; /** Percentage change — positive = up, negative = down, 0 = flat */ amountChangePercentage?: number; className?: string; } export function StatisticItem({ loopBackMonths = 3, amountChange = 0, amountChangePercentage = 0, className, }: StatisticItemProps) { const isPositive = amountChangePercentage > 0; const isNegative = amountChangePercentage < 0; const TrendIcon = isPositive ? TrendingUp : isNegative ? TrendingDown : Minus; const trendClassName = isPositive ? "text-primary" : "text-muted-foreground"; const amountPrefix = isPositive ? "+" : isNegative ? "−" : ""; return (
Last {loopBackMonths} month{loopBackMonths !== 1 ? "s" : ""}
{amountPrefix} {formatCurrencyAbbrev(Math.abs(amountChange), 2)} {Math.abs(amountChangePercentage).toFixed(1)}%
); } // ─── LoanToValueRatio ───────────────────────────────────────────────────────── /** * Displays a Loan-to-Value Ratio (LVR) as a percentage with a color-coded * risk indicator and an optional equity/debt breakdown bar. * * Risk tiers: * ≤ 60% → green (safe) * 61–80% → warning (moderate) * > 80% → destructive (high) * * Used in the LVR settings panel of the Borrowing Capacity page. */ export interface LoanToValueRatioProps { /** LVR as a whole number percentage (0–100) */ lvr: number; /** Optional debt amount — shown below the bar when provided */ debtAmount?: number; /** Optional equity amount — shown below the bar when provided */ equityAmount?: number; className?: string; } // Thresholds match major Australian lender risk bands const LVR_TIER_STYLES = { safe: { text: "text-success", bar: "bg-success" }, moderate: { text: "text-warning", bar: "bg-warning" }, high: { text: "text-destructive", bar: "bg-destructive" }, } as const; export function LoanToValueRatio({ lvr, debtAmount, equityAmount, className, }: LoanToValueRatioProps) { const clamped = Math.min(100, Math.max(0, lvr)); const tier = clamped <= 60 ? "safe" : clamped <= 80 ? "moderate" : "high"; const { text: lvrTextColor, bar: lvrBarColor } = LVR_TIER_STYLES[tier]; return (
{clamped.toFixed(0)}% LVR
{/* Debt-vs-equity bar */}
{(debtAmount !== undefined || equityAmount !== undefined) && (
{debtAmount !== undefined && ( Debt {formatCurrencyAbbrev(debtAmount, 1)} )} {equityAmount !== undefined && ( Equity {formatCurrencyAbbrev(equityAmount, 1)} )}
)}
); } // ─── AddScenarioButton ──────────────────────────────────────────────────────── /** * A dashed-border CTA button for adding a new borrowing scenario. * Renders as a full-width ); }