3.7 KiB
<ProfilePage> — three-tab profile-settings page
(no submodules)
Purpose
<ProfilePage> is the routing-aware profile-settings surface for an authenticated user. It renders three tabs — Profile (name + email), Password (current / new / confirm), and Account (danger zone / delete account) — over the Wave 1 useAuth() action surface (updateProfile, changePassword, deleteAccount). It applies useAuthGuard({ requireAuth: true }) so unauthenticated visitors are redirected to /auth/login, hydrates the profile form from useAuth().user, and exposes optional onSuccess and onDeleteAccount callbacks for downstream analytics. All copy flows through a translations?: Partial<AuthProfilePageStrings> prop defaulting to enGb.auth.profilePage.
The implementation is split into three files to honour the 300-line hard cap: profile.tsx (shell + state + actions), profile-sections.tsx (Profile and Password tab renderers), and profile-account-section.tsx (Account tab with delete-account confirmation flow). All three sit behind the same package entry point.
Features
- Three tabs via
@suaveplan/react-ui<Tabs>: profile / password / account. - Auth-guard: unauthenticated visitors redirected to
/auth/login. - Hydrates name + email from
useAuth().useron mount. - Calls
updateProfile,changePassword,deleteAccountfrom the matching tab. - Local validation on password change: required, ≥8 chars, must match.
- Delete-account confirmation flow with a password re-entry input.
- Three independent password-visibility toggles (current / new / confirm).
successMessageanderror.messagealerts surfaced inline.- Locale overrides via
translations.
Usage: Basic
import { Route, Routes } from "react-router-dom";
import { ProfilePage } from "@suaveplan/react-auth";
export function ProfileRoute() {
return (
<Routes>
<Route path="/profile" element={<ProfilePage />} />
</Routes>
);
}
Usage: Advanced
Hook into analytics:
import { ProfilePage } from "@suaveplan/react-auth";
export function MyProfile() {
return (
<ProfilePage
onSuccess={() => track("profile.update.success")}
onDeleteAccount={() => track("account.deleted")}
translations={{
title: "My Account",
subtitle: "Keep your details up to date.",
}}
/>
);
}
API Reference
ProfilePageProps
| Field | Type | Description |
|---|---|---|
onSuccess |
() => void |
Invoked after profile update or password change succeeds. |
onDeleteAccount |
() => void |
Invoked after deleteAccount resolves, before navigation. |
translations |
Partial<AuthProfilePageStrings> |
Locale overrides. |
ProfilePageFormData
{ name, email, currentPassword, newPassword, confirmPassword } — five strings.
ProfilePageSection
{ id, title, active, icon } — descriptor consumed by the <TabsList> render loop. id is one of "profile" | "password" | "account".
Implementation Notes
- The export is
<ProfilePage>; the upstreamProfilealias is preserved as a named re-export for back-compat. - The page does NOT navigate after
updateProfileorchangePasswordsucceed — it stays on the same route and surfaces a success alert above the tab bar. - The delete-account flow re-uses the
currentPasswordform field rather than a dedicated input, mirroring the upstream UX. clearMessages()is invoked on every input change so success / error banners disappear when the user starts editing again.onValueChangeon<Tabs>clears messages so banners from one tab do not bleed across tab changes.