aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/(app)/settings/delete/+page@(app).svelte
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-11-04 14:29:35 -0700
committerAdam Soltys <[email protected]>2026-11-04 14:38:48 -0700
commita5ff626228b35ef587f6b9493998184e3e8354fe (patch)
treef15d2726fbd391bbd3c4a3a1ca2826ff6c6ac2bd /src/routes/(app)/settings/delete/+page@(app).svelte
parent976473a781f1bcda7ba02fee9db122e163243e2b (diff)
downloadcoinos-ui-a5ff626228b35ef587f6b9493998184e3e8354fe.tar.gz
coinos-ui-a5ff626228b35ef587f6b9493998184e3e8354fe.zip
settings: let users delete their accountHEADmaster
A Delete account entry on the security tab leads to /settings/delete, which warns what's lost, asks for the username (and PIN when set) and calls the server's POST /delete, then logs out. The page resets to the (app) layout so its form isn't nested in the settings save form. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/routes/(app)/settings/delete/+page@(app).svelte')
-rw-r--r--src/routes/(app)/settings/delete/+page@(app).svelte82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/routes/(app)/settings/delete/+page@(app).svelte b/src/routes/(app)/settings/delete/+page@(app).svelte
new file mode 100644
index 00000000..e19a6604
--- /dev/null
+++ b/src/routes/(app)/settings/delete/+page@(app).svelte
@@ -0,0 +1,82 @@
+<script>
+ // Rendered outside the settings layout (+page@(app)) so this form isn't
+ // nested inside the settings save form.
+ import { enhance } from "$app/forms";
+ import { t } from "$lib/translations";
+
+ let { data, form } = $props();
+ let { user } = $derived(data);
+
+ let confirm = $state(form?.confirm || "");
+ let working = $state(false);
+ let matches = $derived(
+ confirm.trim().toLowerCase() === user.username.toLowerCase(),
+ );
+</script>
+
+<div class="container px-4 max-w-xl mx-auto space-y-5 mt-10">
+ <h1 class="text-3xl font-bold text-center">
+ {$t("user.settings.deleteAccount")}
+ </h1>
+
+ <div class="rounded-2xl border-2 border-error p-4 space-y-3">
+ <p class="flex gap-2">
+ <iconify-icon
+ noobserver
+ icon="ph:warning-bold"
+ width="24"
+ class="text-error shrink-0"
+ ></iconify-icon>
+ <span>{$t("user.settings.deleteAccountWarning")}</span>
+ </p>
+ <p class="text-secondary">{$t("user.settings.deleteAccountBalance")}</p>
+ </div>
+
+ {#if form?.error}<p class="text-error">{form.error}</p>{/if}
+
+ <form
+ method="POST"
+ class="space-y-3"
+ use:enhance={() => {
+ working = true;
+ return async ({ update }) => {
+ await update({ reset: false });
+ working = false;
+ };
+ }}
+ >
+ <label class="block space-y-1">
+ <span class="font-bold">{$t("user.settings.deleteAccountConfirm")}</span>
+ <input
+ class="input input-bordered w-full"
+ name="confirm"
+ autocomplete="off"
+ autocapitalize="off"
+ spellcheck="false"
+ placeholder={user.username}
+ bind:value={confirm}
+ />
+ </label>
+
+ {#if user.haspin}
+ <input
+ class="input input-bordered w-full"
+ type="password"
+ inputmode="numeric"
+ name="pin"
+ placeholder={$t("user.settings.securityPIN")}
+ />
+ {/if}
+
+ <button
+ class="btn btn-error w-full rounded-2xl"
+ disabled={!matches || working}
+ >
+ <iconify-icon noobserver icon="ph:trash-bold" width="24"></iconify-icon>
+ {$t("user.settings.deleteAccountButton")}
+ </button>
+ <a href="/settings/security" class="btn w-full rounded-2xl">
+ {$t("payments.cancel")}
+ </a>
+ </form>
+</div>