import { useState } from 'react'; import { Plus } from 'lucide-react'; import { toast } from 'sonner'; import { api } from '@/api.js'; import { fmt, fmtDate } from '@/lib/utils'; import { METHOD_NONE, paymentSummary } from '@/lib/trackerUtils'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, } from '@/components/ui/select'; import PaymentModal from '@/components/tracker/PaymentModal'; import { PaymentProgress } from '@/components/tracker/PaymentProgress'; import { LowerThisMonthButton } from '@/components/tracker/LowerThisMonthButton'; export function PaymentLedgerDialog({ row, year, month, threshold, defaultPaymentDate, onClose, onSaved }) { const summary = paymentSummary(row, threshold); const [amount, setAmount] = useState(String(summary.remaining || summary.target || '')); const [date, setDate] = useState(defaultPaymentDate); const [method, setMethod] = useState(METHOD_NONE); const [notes, setNotes] = useState(''); const [busy, setBusy] = useState(false); const [editPayment, setEditPayment] = useState(null); const payments = [...(row.payments || [])].sort((a, b) => String(b.paid_date).localeCompare(String(a.paid_date))); async function handleAdd(e) { e.preventDefault(); const parsedAmount = parseFloat(amount); if (!Number.isFinite(parsedAmount) || parsedAmount <= 0) { toast.error('Enter a positive payment amount'); return; } if (!date) { toast.error('Choose a payment date'); return; } setBusy(true); try { await api.createPayment({ bill_id: row.id, amount: parsedAmount, paid_date: date, method: method === METHOD_NONE ? null : method, notes: notes || null, }); toast.success('Partial payment added'); onSaved?.(); onClose?.(); } catch (err) { toast.error(err.message || 'Failed to add payment'); } finally { setBusy(false); } } return ( <> { if (!value) onClose(); }}> {row.name} Payments {}} /> Payment History {payments.length > 0 ? ( {payments.map(payment => ( {fmt(payment.amount)} {fmtDate(payment.paid_date)} {payment.method ? ` · ${payment.method}` : ''} {payment.notes && ( {payment.notes} )} setEditPayment(payment)}> Edit ))} ) : ( No payments recorded for this month. )} Add Partial Payment Amount setAmount(e.target.value)} className="font-mono bg-background/70 border-border/60" /> Paid Date setDate(e.target.value)} className="font-mono bg-background/70 border-border/60" /> Method — Bank Transfer Card Autopay Check Cash Notes setNotes(e.target.value)} className="bg-background/70 border-border/60" /> {busy ? 'Adding...' : 'Add Payment'} {editPayment && ( setEditPayment(null)} onSave={() => { onSaved?.(); setEditPayment(null); }} /> )} > ); }
Payment History
{fmt(payment.amount)}
{fmtDate(payment.paid_date)} {payment.method ? ` · ${payment.method}` : ''}
{payment.notes}
No payments recorded for this month.
Add Partial Payment