---
phase: 28-profile-and-logto-integration
plan: 02
subsystem: client
tags: [profile, account-management, ui]
key-files:
  created:
    - src/client/routes/profile.tsx
    - src/client/hooks/useAccount.ts
  modified:
    - src/client/routes/settings.tsx
metrics:
  tasks: 2/2
  commits: 1
  files-changed: 3
---

# Plan 28-02 Summary: Profile Page & Settings Separation

## What Was Built

1. **Profile page** (`src/client/routes/profile.tsx`) — Dedicated /profile route with four sections:
   - Profile Info: Reuses existing ProfileSection component (displayName, bio, avatar)
   - Account Info: Shows email from auth session with inline change form, member-since date
   - Security: Password change form (3 fields if has password, 2 if social-only), client-side validation
   - Danger Zone: Account deletion with typed "DELETE" confirmation, red-bordered card

2. **Account hooks** (`src/client/hooks/useAccount.ts`) — TanStack Query hooks: useHasPassword, useChangePassword, useChangeEmail, useDeleteAccount

3. **Settings separation** — Removed ProfileSection from /settings. Settings now only has weight unit, currency, import/export, and API keys.

## Commits

| # | Hash | Description |
|---|------|-------------|
| 1 | 2369251 | feat(28-02): create profile page with account management, separate from settings |

## Deviations

None — implemented as planned per UI-SPEC.md.

## Self-Check: PASSED

- [x] /profile route created with createFileRoute
- [x] ProfileSection reused without modifications
- [x] Email display with change button and inline form
- [x] Member-since date formatted with Intl.DateTimeFormat
- [x] Password form adapts to has-password/no-password state
- [x] Client-side validation: 8+ chars, uppercase, lowercase, number
- [x] Danger zone card uses border-red-200
- [x] Delete confirmation requires typed "DELETE"
- [x] Settings page no longer contains ProfileSection
- [x] Auth guard redirects unauthenticated users
- [x] Lint passes
