From 227dd2b73f04e3ec914316e770b5ac0a4c0a25bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 4 Jun 2026 18:20:10 +0200 Subject: [PATCH] fix(settings): show a pending state on the danger-zone confirm buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The data-reset and account-delete confirmations fired their mutation from an uncontrolled AlertDialog, so the action dismissed the dialog the instant it was clicked and the only spinner lived on the now-hidden trigger. A user on a slow link saw no feedback and could re-open and re-submit a destructive, irreversible action. Drive both dialogs from controlled open state and add an in-dialog pending treatment to the confirm button — disabled, aria-busy, and a spinner — mirroring the bulk-delete confirmation in the medication intake history. The dialog now holds open while the request is in flight; the data-reset closes on success, the account-delete keeps its pending state through the post-delete redirect. --- src/components/settings/advanced-section.tsx | 60 +++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/src/components/settings/advanced-section.tsx b/src/components/settings/advanced-section.tsx index 279af5388..ef993b414 100644 --- a/src/components/settings/advanced-section.tsx +++ b/src/components/settings/advanced-section.tsx @@ -235,10 +235,12 @@ function DataResetCard() { const { t } = useTranslations(); const queryClient = useQueryClient(); const [deleting, setDeleting] = useState(false); + const [confirmOpen, setConfirmOpen] = useState(false); const [msg, setMsg] = useState(null); const [msgType, setMsgType] = useState<"success" | "error" | null>(null); async function handleDeleteAllData() { + if (deleting) return; setDeleting(true); setMsg(null); setMsgType(null); @@ -258,6 +260,7 @@ function DataResetCard() { await queryClient.invalidateQueries(); setMsg(t("settings.dangerZoneSuccess")); setMsgType("success"); + setConfirmOpen(false); } catch { setMsg(t("settings.dangerZoneDeleteFailed")); setMsgType("error"); @@ -285,7 +288,16 @@ function DataResetCard() { {t("settings.dangerZoneDescription")}

- + { + // Hold the dialog open while the destructive mutation is in + // flight so the in-dialog pending state stays visible and a + // stray backdrop tap can't dismiss it mid-request. + if (deleting) return; + setConfirmOpen(open); + }} + >