diff --git a/client/components/BillModal.jsx b/client/components/BillModal.jsx index 5cba163..54d9c64 100644 --- a/client/components/BillModal.jsx +++ b/client/components/BillModal.jsx @@ -1,5 +1,5 @@ import { useActionState, useEffect, useState } from 'react'; -import { Copy, Layers, Link2, Link2Off, Loader2, Pencil, Plus, RefreshCw, Trash2 } from 'lucide-react'; +import { Copy, Layers, Link2, Link2Off, Loader2, RefreshCw } from 'lucide-react'; import { formatCentsUSD, validateNonNegativeMoney } from '@/lib/money'; import { toast } from 'sonner'; import { Button } from '@/components/ui/button'; @@ -21,6 +21,7 @@ import { cn, fmt, fmtDate, todayStr } from '@/lib/utils'; import BillMerchantRules from '@/components/BillMerchantRules'; import DebtDetailsSection from '@/components/bill-modal/DebtDetailsSection'; import AutopayTrustIndicator from '@/components/bill-modal/AutopayTrustIndicator'; +import PaymentHistoryList from '@/components/bill-modal/PaymentHistoryList'; import { BILLING_SCHEDULE_OPTIONS, billingCycleForSchedule, @@ -76,36 +77,6 @@ function transactionTitle(tx) { return tx?.payee || tx?.description || tx?.memo || 'Transaction'; } -function isTransactionLinkedPayment(payment) { - return payment?.payment_source === 'transaction_match' || payment?.transaction_id != null; -} - -function isHistoryOnlyPayment(payment) { - return !!payment?.accounting_excluded; -} - -function paymentSourceLabel(source) { - const labels = { - manual: 'Manual', - file_import: 'File import', - provider_sync: 'Sync', - transaction_match: 'Transaction', - auto_match: 'SimpleFIN', - }; - return labels[source] || source || 'Manual'; -} - -function paymentSourceTone(source) { - const tones = { - manual: 'border-emerald-500/25 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400', - file_import: 'border-sky-500/25 bg-sky-500/10 text-sky-600 dark:text-sky-400', - provider_sync: 'border-violet-500/25 bg-violet-500/10 text-violet-600 dark:text-violet-400', - transaction_match: 'border-primary/25 bg-primary/10 text-primary', - auto_match: 'border-violet-500/25 bg-violet-500/10 text-violet-600 dark:text-violet-400', - }; - return tones[source] || tones.manual; -} - function isDebtCat(categories, catId) { if (!catId || catId === CAT_NONE) return false; const cat = categories.find(c => String(c.id) === catId); @@ -968,86 +939,14 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa {!isNew && (
Payment history
-{payments.length} recorded
-No payments yet
-Use the form below to record the first payment.
-{fmt(payment.amount)}
- - {paymentSourceLabel(payment.payment_source)} - - {historyOnly && ( - - History only - - )} -- {fmtDate(payment.paid_date)} · {payment.method || (payment.payment_source === 'transaction_match' ? 'Synced' : 'manual')} -
- {payment.notes && ( -{payment.notes}
- )} -Payment history
+{payments.length} recorded
+No payments yet
+Use the form below to record the first payment.
+{fmt(payment.amount)}
+ + {paymentSourceLabel(payment.payment_source)} + + {historyOnly && ( + + History only + + )} ++ {fmtDate(payment.paid_date)} · {payment.method || (payment.payment_source === 'transaction_match' ? 'Synced' : 'manual')} +
+ {payment.notes && ( +{payment.notes}
+ )} +