first commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# 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 `isLoading` is true OR the password field is empty.
|
||||
- Spinning loader (`<Loader2>`) appears alongside the deleting copy while the call is in flight.
|
||||
- Errors at the `currentPassword` field surface inline.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```tsx
|
||||
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:
|
||||
|
||||
```tsx
|
||||
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.currentPassword` instead of introducing a `deletePassword` field — the parent page resets that field on cancel.
|
||||
- The placeholder copy on the delete-password input is intentionally the `errorPasswordRequiredForDelete` string (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>` whose `onClick` triggers the delete. That keeps the password input out of the `<form>` element used by `<PasswordSection>` and prevents accidental form-submit collisions.
|
||||
Reference in New Issue
Block a user