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 )}
-