import React, { useState, useEffect, useCallback } from 'react'; import { Undo2, ChevronDown, ChevronRight } from 'lucide-react'; import { toast } from 'sonner'; import { api } from '@/api'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; function fmtAmt(dollars) { if (dollars == null) return '—'; return `$${Number(dollars).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; } function fmtDate(iso) { if (!iso) return ''; const d = new Date(`${iso}T00:00:00`); return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }); } function payeeLabel(row) { return row.payee || row.description || `Transaction #${row.transaction_id}`; } export default function AutoMatchReview({ refreshKey }) { const [items, setItems] = useState([]); const [loading, setLoading] = useState(false); const [open, setOpen] = useState(true); const [undoing, setUndoing] = useState(null); const load = useCallback(async () => { setLoading(true); try { const rows = await api.recentAutoMatched(); setItems(Array.isArray(rows) ? rows : []); } catch { // Non-blocking — don't surface errors for a review panel } finally { setLoading(false); } }, []); useEffect(() => { load(); }, [load, refreshKey]); async function handleUndo(item) { setUndoing(item.id); try { await api.undoAutoMatch(item.id); setItems(prev => prev.filter(p => p.id !== item.id)); toast.success(`Undone — ${payeeLabel(item)} unlinked from "${item.bill_name}"`); } catch (err) { toast.error(err.message || 'Failed to undo auto-match'); } finally { setUndoing(null); } } if (!loading && items.length === 0) return null; return (
Loading…
) : items.map(item => ({fmtAmt(item.amount)} {' → '} {item.bill_name}
Payments auto-created from merchant rules in the last 7 days. Undo removes the payment and restores the bill balance.