# Customer account & care-circle management (profile, patients, patient care record, addresses + map picker)
## Current state
The area lives under `client/src/app/[locale]/(private-routes)/(customer)/` inside `CustomerLayout` (slim TopBar + 5-tab BottomBar, content column capped at CONTENT_MAX_WIDTH). `profile/page.tsx` is a single flat form: first/last name, a preferred-language select, an emergency-contact section (name + `PhoneNumberField`), one save button, and an outlined Paper card linking to the address book. `patients/page.tsx` is a header + `PatientCard` list with add/edit via `PatientForm` reused in a `Dialog maxWidth="sm"`, soft-archive with a confirm dialog, a 2-row Skeleton loader, and a dashed-border empty state with icon + CTA. `patients/[id]/record/page.tsx` is the care-record viewer: shared `PatientHeader`, a family-ownership banner on `--bal-primary-soft`, four scrollable Tabs (داروها/روتین/سوابق/وظایف); the three editable tabs use a whole-list "edit mode" (every row becomes small TextFields, save-all), history is read-only `VisitNoteCard`s with text prev/next pagination; access is gated by `useRecordAccess` with a non-leaking access-denied card. `addresses/page.tsx` mirrors the patients page: `AddressCard` list (primary badge via `StatusChip status="verified"`), add/edit dialog hosting `AddressForm` = title + `CascadingRegionSelect` (province→city→district with loading adornments and an explicit "whole city" option) + `AddressMapPicker` + multiline address line + set-primary switch.
Styling is disciplined and token-driven: everything is `elevation={0}` Paper with `border: 1px solid divider, borderRadius: 2`, colors come from `--bal-*` CSS variables (both schemes), text uses `text.secondary`, and RTL is handled with logical properties (`textAlign:'start'`, `marginInlineStart:'auto'`) — `AddressMapPicker` even pins itself `dir="ltr"` with inline styles and a comment explaining the stylis-RTL transform hazard. The weak points are structural rather than cosmetic: the "map" is a coordinate-grid stand-in (no tiles/search/geocoding, raw lat/lng shown), query errors collapse into empty/blank states, long forms are crammed into non-fullscreen modals on a mobile-first shell, there is no avatar/photo concept anywhere in the customer identity system, and the Profile tab lacks basic account affordances (no sign-out anywhere in the customer shell, no phone display, no locale switch).
## Problems (16)
- **[high]** `client/src/app/[locale]/(private-routes)/(customer)/patients/page.tsx` — Query errors collapse into the empty state: a failed usePatients() leaves data undefined so the page shows 'هنوز بیماری ثبت نشده' with an add CTA — telling a family their care recipients don't exist and inviting duplicate re-entry. No isError branch or retry exists. Identical bug in addresses/page.tsx line 91.
- evidence: line 83: `const isEmpty = !isLoading && patients.length === 0;` — isError is never read from the query
- **[high]** `client/src/app/[locale]/(private-routes)/(customer)/profile/page.tsx` — Profile load error is silently swallowed: only isLoading is handled, so on a failed useCustomerProfile() the form renders blank (initial=null) and a save would overwrite server truth with empty fields. No isError state, no retry.
- evidence: lines 16-18: `const { data: profile, isLoading } = useCustomerProfile(); ... if (isLoading) return ;` then `initial={profile ?? null}`
- **[high]** `client/src/layout/CustomerLayout.tsx` — No sign-out affordance exists anywhere in the customer experience: CustomerLayout has only support/bell/dark-toggle chrome and the 5-tab BottomBar; logout lives only in SideBar.tsx, which the customer shell never renders, and the Profile tab (the natural home for it) has no account section, no phone-number display, and no sign-out. A logged-in customer literally cannot log out.
- evidence: CustomerLayout renders TopBar(startNode=support, endNode=bell+DarkModeToggleButton)+BottomBar only; grep for logout hits layout/components/SideBar.tsx but no (customer) file
- **[high]** `client/src/components/geography/AddressMapPicker.tsx` — The 'map pin picker' is a blank coordinate grid, not a map: no tiles, no address search, no geocode, no locate-me — a family user is asked to place a pin on a featureless 220px grid whose output feeds the later EVV proximity check, so a meaningless pin is near-guaranteed. It also surfaces raw latitude/longitude captions ('عرض: 35.71234') to consumers — developer-grade UI in the most trust-sensitive form of the account area.
- evidence: lines 30-34 doc: 'It is NOT a real map (no Neshan/Google tiles), only a bounded canvas'; lines 143-152 render `{latLabel}: {value.latitude.toFixed(5)}`
- **[medium]** `client/src/app/[locale]/(private-routes)/(customer)/addresses/page.tsx` — The long address form (title + 3 cascading selects + 220px map + multiline line + switch + actions) is hosted in a Dialog maxWidth='sm' that is not fullScreen on mobile — on the phone-first customer shell this yields a cramped double-scroll (DialogContent + keyboard) modal; additionally backdrop-click/onClose silently discards a half-completed form with no dirty-state guard. Same pattern for PatientForm in patients/page.tsx line 160.
- evidence: line 170: `