Skip to content

feat(account): Account Settings page (/account/settings) — closes #74#81

Merged
ismetcahangirov merged 2 commits into
mainfrom
feat/account-settings-page
Jul 9, 2026
Merged

feat(account): Account Settings page (/account/settings) — closes #74#81
ismetcahangirov merged 2 commits into
mainfrom
feat/account-settings-page

Conversation

@ismetcahangirov

Copy link
Copy Markdown
Owner

Summary

Builds the customer Settings page at /{locale}/account/settings under the shared account/ shell, fixing the header dropdown "Ayarlar / Settings" which previously 404'd. Consolidates the old /profile UI into a proper sectioned settings page and removes the duplicated profile logic.

Closes #74.

What's included

Sectioned page (AccountSettingsClient) with four cards, each extracted into a reusable component:

  1. Profile (ProfileSection) — avatar upload (useUpdateAvatar), name/email edit (useUpdateProfile), role + verified badges, member-since.
  2. Security (SecuritySection) — change-password form (useUpdatePassword) with client-side match validation and "min 8 chars" hint. Google-only accounts see a clear notice instead of a form.
  3. Addresses — embeds the existing AddressListClient (full CRUD) via a new backward-compatible embedded prop (renders as a card with an h2; standalone /profile/addresses is unchanged).
  4. Preferences (PreferencesSection) — language (LanguageSwitcher) + theme (ThemeToggle), client-only.

Consolidation

  • Profile/password/avatar logic moved out of ProfilePageClient (deleted) into the section components — no duplicated logic.
  • /profile now redirects to /account/settings.

Backend (small addition)

  • GET /auth/me now returns a computed hasPassword boolean (Google-only accounts have none) so the UI can hide the password form. The password hash is never exposed. Regression tests added to auth.test.ts.

i18n — new keys added to all three messages/{az,en,ru}.json under the profile namespace.

Acceptance criteria

  • Header dropdown "Ayarlar" opens a working page (no 404) at /{locale}/account/settings.
  • Update profile (name/email/avatar), change password, and manage addresses from this page.
  • Language + theme toggles (reused, persist via next-intl / next-themes).
  • Google-only accounts get a clear message instead of a broken password form.
  • Unauthenticated → /login (via the account layout.tsx ProtectedRoute); page is noindex.
  • az / en / ru + dark mode correct; no duplicated profile logic.
  • lint, client test, and next build pass with new tests.

Out of scope (follow-up)

  • Danger zone / delete account — requires a new DELETE /users/me endpoint. Omitted per the issue's "optional/follow-up" note; recommend a separate backend task.
  • Phone field — the User model has no phone column, so it's omitted (as the issue instructed).

Testing

  • Unit (vitest): new suites for ProfileSection, SecuritySection, PreferencesSection, and AccountSettingsClient (loading / error / loaded / Google-only). Full suite green: 388 tests. next lint clean, next build succeeds.
  • Backend: tsc --noEmit + eslint clean. hasPassword verified live via curl against a local server (returns true for a password account, hash not present). Jest regression tests added (run in CI's dedicated test DB — the local suite is intentionally not run since its global setup wipes whatever DB it connects to).
  • E2E (Playwright, local backend + frontend): logged in as the seeded customer and verified the page renders all four sections, the password form reveals, the header dropdown "Ayarlar" link opens the page, and /profile redirects to /account/settings.

Note: on a hard page reload the in-memory access token (window.__accessToken) is gone, so the page briefly shows the loading skeleton while the axios interceptor refreshes the token — existing app behaviour, not specific to this page.

🤖 Generated with Claude Code

…ings

Build the sectioned account Settings page at /{locale}/account/settings under
the shared account shell, fixing the header dropdown "Ayarlar" 404.

- Profile / Security / Addresses / Preferences sections as reusable components;
  profile, password and avatar logic moved out of the old ProfilePageClient
  (removed) so there is no duplicated profile logic.
- Redirect /profile -> /account/settings.
- Embed AddressListClient via a new backward-compatible `embedded` prop (card +
  h2 heading); the standalone /profile/addresses page is unchanged.
- Security hides the change-password form for Google-only accounts; expose a
  computed `hasPassword` on GET /auth/me (never leaking the hash) to drive it.
- Preferences reuse LanguageSwitcher + ThemeToggle (client-only, no API).
- i18n keys added to az/en/ru; vitest coverage for every section + composition
  and a backend regression test for hasPassword.

Danger zone / delete-account omitted (needs a new DELETE /users/me) — follow-up.

Closes #74

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
api-shopflow Ready Ready Preview, Comment Jul 9, 2026 10:38am
shopflow Ready Ready Preview, Comment Jul 9, 2026 10:38am

The new settings sections left the change/cancel handlers and mutation
onSuccess callbacks unexercised, dropping global function coverage to 79.94%
(< 80% CI gate). Add tests for the password/profile success + cancel paths and
avatar upload success. Global functions coverage now 81.8%.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ismetcahangirov
ismetcahangirov merged commit 8e71371 into main Jul 9, 2026
9 checks passed
@ismetcahangirov
ismetcahangirov deleted the feat/account-settings-page branch July 9, 2026 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(account): Account Settings page (/account/settings)

2 participants