diff --git a/frontend/src/components/budget/RecurringItemDialog.tsx b/frontend/src/components/budget/RecurringItemDialog.tsx index 55ee2cc..16d725a 100644 --- a/frontend/src/components/budget/RecurringItemDialog.tsx +++ b/frontend/src/components/budget/RecurringItemDialog.tsx @@ -25,6 +25,7 @@ import { } from '@/components/ui/select'; import { Textarea } from '@/components/ui/textarea'; import { Plus, Trash2 } from 'lucide-react'; +import ConfirmDialog from '@/components/ConfirmDialog'; const TYPE_OPTIONS: { value: RecurringItemType; label: string }[] = [ { value: 'INCOME', label: 'Ingreso' }, @@ -73,11 +74,13 @@ export default function RecurringItemDialog({ const snapshot = () => JSON.stringify([name, amount, itemType, frequency, dayOfMonth, monthOfYear, overrides, notes]); + const [confirmDiscard, setConfirmDiscard] = useState(false); + const handleOpenChange = (next: boolean) => { if (!next && !saving && snapshot() !== baseline) { // Closing with unsaved edits — confirm before discarding (UX-06). - const discard = window.confirm('Hay cambios sin guardar. ¿Descartarlos?'); - if (!discard) return; + setConfirmDiscard(true); + return; } onOpenChange(next); }; @@ -338,6 +341,19 @@ export default function RecurringItemDialog({ + + {confirmDiscard && ( + { + setConfirmDiscard(false); + onOpenChange(false); + }} + onCancel={() => setConfirmDiscard(false)} + /> + )} ); } diff --git a/frontend/src/components/budget/RecurringItemsManager.tsx b/frontend/src/components/budget/RecurringItemsManager.tsx index cedef57..4dd178d 100644 --- a/frontend/src/components/budget/RecurringItemsManager.tsx +++ b/frontend/src/components/budget/RecurringItemsManager.tsx @@ -8,6 +8,7 @@ import { import { formatAmount } from '@/lib/format'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; +import { Card, CardContent } from '@/components/ui/card'; import { DataTable } from '@/components/ui/data-table'; import { DataTableColumnHeader } from '@/components/ui/data-table-column-header'; import { Pencil, Plus, Trash2 } from 'lucide-react'; @@ -153,14 +154,18 @@ export default function RecurringItemsManager({ - + + + + + { if (!effectivePlan) return; - const confirmed = window.confirm( - 'Se eliminarán las cuotas y la compra volverá a contar como un solo cargo. ¿Continuar?', - ); - if (!confirmed) return; + setConfirmUnconvert(false); setSaving(true); try { await deleteInstallmentPlan(effectivePlan.id); @@ -248,7 +247,7 @@ export default function ConvertToInstallmentsDialog({