import React, { useState } from "react"; import { cn } from "@/lib/utils"; import { formatCurrency, formatCurrencyAbbrev } from "@/lib/format-currency"; import { Button } from "./button"; import { Skeleton } from "./skeleton"; /** * Organism — full lender comparison table for the Borrowing Capacity page. * * Renders an optional title, a sticky column-header row, and a paginated list * of lender rows. Each row shows: Lender, Interest Rate, Comparison Rate, * Monthly Repayments, Total Cost, and Max Buying Power. * * Values are pre-formatted / typed — business logic stays in the app layer. * Pass `isLoading` to render a skeleton table in place of real rows. */ export interface InterestRateItem { /** Lender display name (e.g. "ANZ") */ lender: string; /** Interest rate percentage (e.g. 5.5 → displayed as "5.50%") */ interestRate: number; /** Comparison rate percentage (e.g. 5.75 → displayed as "5.75%") */ comparisonRate: number; /** Pre-formatted monthly repayment string (e.g. "$2,800" or "$2,800 – $3,100") */ monthlyRepayment: string; /** Total cost in AUD cents */ totalCost: number; /** Maximum buying power in AUD cents */ maxBuyingPower: number; } export interface InterestRateSectionProps { /** * Section heading shown above the table, e.g. * "Lender Options for cash towards $150,000" */ title?: string; /** Lender rows to display */ items?: InterestRateItem[]; /** Number of rows shown per page (default: 5) */ pageSize?: number; /** Replace rows with a skeleton loading state */ isLoading?: boolean; className?: string; } const COLUMN_HEADERS = [ "Lender", "Interest Rate", "Comparison Rate", "Monthly Repayments", "Total Cost", "Real Buying Power", ] as const; export function InterestRateSection({ title, items = [], pageSize = 5, isLoading = false, className, }: InterestRateSectionProps) { const [visibleCount, setVisibleCount] = useState(pageSize); const visibleItems = items.slice(0, visibleCount); const hasMore = visibleCount < items.length; const handleLoadMore = () => setVisibleCount((n) => n + pageSize); return (
{title && (

{title}

)} {/* Column headers */}
{COLUMN_HEADERS.map((col) => ( {col} ))}
{/* Rows */}
{isLoading ? Array.from({ length: pageSize }).map((_, i) => (
{Array.from({ length: 6 }).map((__, j) => ( ))}
)) : visibleItems.length > 0 ? visibleItems.map((item, i) => (
{/* Lender */}
{item.lender}
{/* Interest Rate */} {item.interestRate.toFixed(2)}% {/* Comparison Rate */} {item.comparisonRate.toFixed(2)}% {/* Monthly Repayments */} {item.monthlyRepayment} {/* Total Cost */} {formatCurrencyAbbrev(item.totalCost)} {/* Max Buying Power */} {formatCurrency(item.maxBuyingPower)}
)) : !isLoading && (

No lender options available for this scenario.

)}
{/* Load more */} {!isLoading && hasMore && (
)}
); }