3.1 KiB
profile-account-section — <AccountSection>
Purpose
profile-account-section.tsx houses the delete-account tab renderer for <ProfilePage>. It is split out of profile-sections.tsx so each implementation file stays under the 300-line hard cap. The component renders an <Alert variant="destructive"> framing a danger-zone block; clicking the initial delete button reveals a confirmation pane with a password input and two CTAs (confirm-delete, cancel-delete). The parent page owns the visibility state via showDeleteConfirm and the three callbacks (onRequestDelete, onCancelDelete, onConfirmDelete).
Features
- Single-card destructive surface using the
react-ui<Alert variant="destructive">primitive. - Two-stage confirmation: initial "Delete Account" button → confirm pane with password re-entry + "Yes, Delete My Account" + "Cancel".
- The confirm button is disabled while
isLoadingis true OR the password field is empty. - Spinning loader (
<Loader2>) appears alongside the deleting copy while the call is in flight. - Errors at the
currentPasswordfield surface inline.
Usage: Basic
import { AccountSection } from "./profile-account-section.js";
<AccountSection
t={t}
formData={formData}
errors={errors}
isLoading={isLoading}
onChange={handleInputChange}
showDeleteConfirm={showDeleteConfirm}
onRequestDelete={() => setShowDeleteConfirm(true)}
onCancelDelete={handleCancelDelete}
onConfirmDelete={handleConfirmDelete}
/>;
Usage: Advanced
Hooking an analytics callback into the delete flow is handled at the parent page level via onDeleteAccount. From this component's perspective, the onConfirmDelete callback is the only one that triggers a network call:
async function handleConfirmDelete() {
if (!formData.currentPassword) {
setErrors({ currentPassword: t.errorPasswordRequiredForDelete });
return;
}
await deleteAccount(formData.currentPassword);
track("account.deleted");
navigate("/auth/login");
}
API Reference
AccountSectionProps extends SectionProps
| Field | Type | Description |
|---|---|---|
showDeleteConfirm |
boolean |
When true, the confirm pane is rendered. |
onRequestDelete |
() => void |
Invoked when the initial delete button is clicked. |
onCancelDelete |
() => void |
Invoked when the cancel button is clicked. |
onConfirmDelete |
() => Promise<void> |
Invoked when the confirm button is clicked. |
Implementation Notes
- The component reuses
formData.currentPasswordinstead of introducing adeletePasswordfield — the parent page resets that field on cancel. - The placeholder copy on the delete-password input is intentionally the
errorPasswordRequiredForDeletestring (also used as the inline error). This matches upstream UX: the placeholder explains the requirement, the error reinforces it after a failed submit. - The component does not render its own
<form>— the confirm button is a regular<Button>whoseonClicktriggers the delete. That keeps the password input out of the<form>element used by<PasswordSection>and prevents accidental form-submit collisions.