From ca514e5f26349daf79e8fd9ec3295a1d3b5d9de8 Mon Sep 17 00:00:00 2001 From: null Date: Mon, 8 Jun 2026 16:33:48 -0500 Subject: [PATCH] fix(tracker): BillModal save/close race and pending badge logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use controlled Dialog state (setDialogOpen) instead of immediate onClose() to let Radix cleanup properly before unmount - Amber 'Pending' badge now only shows for bank-linked bills — unlinked bills skip the pending-cleared check and show 'Paid' directly - TrackerPage onSave no longer nullifies edit state before BillModal can animate closed (batch 0.37.4) --- client/components/BillModal.jsx | 12 ++++++++---- client/pages/TrackerPage.jsx | 2 +- services/trackerService.js | 5 ++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/client/components/BillModal.jsx b/client/components/BillModal.jsx index 4ad26ef..1aed291 100644 --- a/client/components/BillModal.jsx +++ b/client/components/BillModal.jsx @@ -190,6 +190,10 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa bill?.autopay_verified_at ? new Date(bill.autopay_verified_at) : null ); + // Controls the outer Dialog's open state so it closes via its own animation + // rather than being abruptly unmounted, which can leave Radix cleanup in a broken state. + const [dialogOpen, setDialogOpen] = useState(true); + // Deactivate dialog state const [deactivateOpen, setDeactivateOpen] = useState(false); const [deactivateReason, setDeactivateReason] = useState(''); @@ -594,7 +598,7 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa toast.success('Template saved'); } onSave(savedBill); - onClose(); + setDialogOpen(false); } catch (err) { toast.error(err.message); } @@ -608,7 +612,7 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa await api.updateBill(bill.id, payload); toast.success(bill.active ? 'Bill deactivated' : 'Bill reactivated'); onSave?.(); - onClose(); + setDialogOpen(false); } catch (err) { toast.error(err.message); } @@ -617,7 +621,7 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa const inp = 'bg-background/50 border-border/60 h-9 text-sm w-full'; return ( - { if (!v) onClose(); }}> + { if (!v) onClose(); }}> @@ -1422,7 +1426,7 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa )}
-