ui phase 9
This commit is contained in:
+11
-9
@@ -154,11 +154,11 @@ client/
|
||||
│ │ │ │ ├── ScheduleStep.tsx # D4 تایید طرح و قرارداد — served repayment rows (InstallmentScheduleRow) + ownership note + contract-consent gate → useIssueBnplToken handoff
|
||||
│ │ │ │ ├── gateway/page.tsx # dev provider-handoff harness (TEST HARNESS; mock redirectUrl points here) → return; env-gated `notFound()` outside `development` (ui-phase-6 — was reachable in production builds)
|
||||
│ │ │ │ └── return/page.tsx # settle (useAcceptBnplSchedule) → invalidate → reused confirmation (?method=bnpl) / retry / card; the invalid-link CTA label now matches its destination (ui-phase-6 fix)
|
||||
│ │ │ ├── patients/page.tsx # /patients — E1 list/CRUD (add/edit dialog reusing PatientForm, soft-archive); tapping a PatientCard opens the E2 record (f13)
|
||||
│ │ │ ├── patients/[id]/record/page.tsx # /patients/[id]/record — f13 E2 care-record viewer (b14): reused PatientHeader + ownership banner + 4 tabs (داروها/روتین/سوابق/وظایف). Family-owned & patient-scoped — customer edits medications/routine/tasks (useUpdateCareRecord); سوابق = read-only nurse visit-note history (VisitNoteCard); access-denied is a first-class non-leaking state gated BEFORE any clinical fetch (services/patientRecords)
|
||||
│ │ │ ├── addresses/page.tsx # /addresses — F3 address book (cascading region dropdowns + map-pin picker, set-primary)
|
||||
│ │ │ ├── patients/page.tsx # /patients — the E1 «حلقهٔ مراقبت» (care-circle) list/CRUD, ui-phase-9 redesign: copy-level rename from «بیماران» (route/service/i18n key names unchanged), `FormDialogShell` (full-screen-on-mobile) replacing the `maxWidth="sm"` dialog, `PatientForm`'s `onDirtyChange` wired to its discard-confirm; error/empty/loading states unchanged (already fixed pre-phase-9); tapping a `PatientCard` (now a pressable surface with a chevron, not an invisible button) opens the E2 record (f13)
|
||||
│ │ │ ├── patients/[id]/record/page.tsx # /patients/[id]/record — f13 E2 care-record viewer (b14), ui-phase-9 rebuild: reused PatientHeader (now with an avatar) + ownership banner + 4 tabs (داروها/روتین/سوابق/وظایف). The whole-list free-text edit mode is gone — each medication/routine/task row opens a per-item responsive sheet (`Drawer anchor="bottom"` mobile / `Dialog` desktop, its own dirty-gated discard-confirm) with structured dose amount+unit/frequency-preset+time-of-day-chip fields (REQ-027 addendum); سوابق (read-only nurse visit-note history, VisitNoteCard) is now a Shamsi month-grouped timeline with a booking link + task-done summary when derivable; access-denied is a first-class non-leaking state gated BEFORE any clinical fetch (services/patientRecords) — preserved verbatim
|
||||
│ │ │ ├── addresses/page.tsx # /addresses — F3 address book, ui-phase-9 pass: `isError`→`ErrorState` (was silently absent), `FormDialogShell` replacing the cramped dialog, `AddressCard`'s new pin-quality cue (`hasPin`/pin_set/pin_missing)
|
||||
│ │ │ ├── wallet/ # /wallet — ui-phase-6 rebuilt into the customer money hub (page.tsx → WalletScreen.tsx: 4 Tabs, one shared `CONTENT_MAX_WIDTH`, no local width override): «پرداختها» (WalletPaymentHistory — card `usePaymentHistory` (REQ-047) + BNPL down-payment rows merged via the co-located `useWalletHistoryRows`), «اقساط» (WalletInstallments — the unchanged f11 D5 provider-reported outstanding balance + due list + early-pay hand-off, now section-only, no own heading/width), «استردادها» (WalletRefunds — `useMyRefunds`, REQ-048, one RefundStatusCard per refund), «رسیدها» (WalletReceipts — client-derived invoice deep-links off the same merged history rows, no endpoint)
|
||||
│ │ │ ├── profile/page.tsx # /profile — customer profile + emergency contact (no national-ID)
|
||||
│ │ │ ├── profile/page.tsx # /profile — ui-phase-9 rebuild into the customer's account hub (still the single route — sub-sections are `FormDialogShell` sheets, not sub-routes): `ProfileSummary` identity header (avatar/initials + name + server-masked phone), grouped tappable rows (اطلاعات شخصی/نشانیها/زبان/اعلانها/پشتیبانی/خروج — the زبان row owns the server-stored `preferredLanguage` and hosts the phase-2 `LocaleSwitcher`, never a second locale mechanism), an emergency-contact status card (tel:-only link when complete, a warm nudge otherwise), `ActorSwitcher` preserved; sign-out goes through `useLogout()` only. No national-ID.
|
||||
│ │ │ ├── support/tickets/ # /support/tickets — f14 "My Tickets" inbox (TicketInboxScreen role="customer") ↔ support/tickets/[id]/page.tsx thread (TicketThreadScreen); thin role-passing wrappers over @/components/messaging
|
||||
│ │ │ └── notifications/page.tsx # /notifications — f14 notification center (NotificationCenter role="customer"); the TopBar bell deep-links here
|
||||
│ │ ├── nurse/ # Nurse app (/nurse/…) — sidebar shell
|
||||
@@ -242,6 +242,8 @@ client/
|
||||
│ │ ├── StickyActionBar/ # ui-phase-4 — a `position:sticky` bottom-pinned action-bar shell for a scrolling screen's primary CTA (C1's live-count CTA, C3's booking CTA); composes with the shell's existing BottomBar safe-area padding rather than reimplementing `env(safe-area-inset-bottom)`
|
||||
│ │ ├── LocaleSwitcher/ # ui-2 fa/en toggle preserving the current route (`router.replace(pathname, {locale})` via `@/i18n/navigation`); sidebar footers, the customer profile hub, the public shell (tested)
|
||||
│ │ ├── Pager/ # ui-phase-7 — the shared prev/next "page X of Y" control (common namespace i18n) replacing the near-identical inline pagers hand-rolled per list screen (nurse inbox tabs, payout history/earnings) (tested)
|
||||
│ │ ├── InitialsAvatar/ # ui-phase-9 — warm auto-colored initials for a person with no photo: deterministic name-hash → one of 6 `--bal-avatar-*` token pairs (tokens.css, both scheme blocks); `aria-hidden` (decorative next to a visible name); used by `PatientHeader` and (via `ProfileSummary`'s new `initialsFallback` prop) the customer account hub (tested)
|
||||
│ │ ├── FormDialogShell/ # ui-phase-9 — full-screen-below-`sm` form dialog (app-bar header + close) with a dirty-gated discard-confirm on close/backdrop/escape; the shared primitive behind the patient/address add-edit dialogs (the hosted form reports `dirty` via an `onDirtyChange` prop) (tested)
|
||||
│ │ └── index.tsx # barrel — keep next-intl-importing primitives (Money) below the presentational ones so the poisoning risk stays visible in review
|
||||
│ ├── PlaceholderScreen/ # Empty-state scaffold for not-yet-built screens
|
||||
│ ├── OtpInput/ # OTP code input (auto-advance, paste, RTL-safe)
|
||||
@@ -251,8 +253,8 @@ client/
|
||||
│ ├── GenderToggle/ # Required male/female toggle (never defaulted) — drives same-gender matching; ui-phase-4 added an opt-in `allowAny` mode (discriminated-union props) adding a third «فرقی ندارد» option for C1's search facet — the default booking-context contract is unchanged
|
||||
│ ├── ConditionChips/ # Multi-select patient-condition chips (stable codes, translated labels)
|
||||
│ ├── RelationSelect/ # Single-select relation radio cards (parent/spouse/child/self)
|
||||
│ ├── PatientForm/ # A4 patient form (name/age/gender/conditions/relation) — reused create+edit
|
||||
│ ├── PatientCard/ # E1 patient summary card (composes the shared PatientHeader) + edit/archive actions + optional onOpen tap-to-open (→ f13 E2 record)
|
||||
│ ├── PatientForm/ # A4 patient form (first/last name, age/gender/conditions/relation) — reused create+edit; ui-phase-9 split the single full-name field into first/last (lastName falls back to firstName when blank — the wire requires it) and added an `onDirtyChange` prop for `FormDialogShell`'s discard-confirm
|
||||
│ ├── PatientCard/ # E1 care-circle summary card (composes the shared PatientHeader, now with its avatar) + edit/archive actions; ui-phase-9 replaced the invisible tap target with a pressable `ButtonBase` surface (hover/press + a trailing chevron) and added an optional `lastVisitLabel` teaser (never populated without a `patientId` on the cached bookings list — REQ-057)
|
||||
│ ├── BankStatusPanel/ # Nurse bank-account ownership state (pending/verified/mismatch), masked IBAN
|
||||
│ ├── CategoryTile/ # f4 tappable service-category tile (icon+label; `selected` state for the builder) — Home grid + builder step 1 (tested)
|
||||
│ ├── PriceDisplay/ # f4 price renderer: money-util Toman + i18n unit label + unit-aware estimated total (never a total from price alone) (tested)
|
||||
@@ -282,10 +284,10 @@ client/
|
||||
│ ├── RatingInput/ # f13 1–5 star input/display (custom, on AppIcon "star"; filled=var(--bal-warning), empty=var(--bal-divider)); interactive=radiogroup of radios, readOnly=static role="img"; used by the review form + review/my-review display (tested)
|
||||
│ ├── ReviewTagSelector/ # f13 multi-select review-tag chip group (selected=MUI palette primary, unselected=outlined); i18n-free (caller passes labelFor(code)); codes stay keyed off the stable vocabulary, never off the wire (tested)
|
||||
│ ├── VisitNoteCard/ # f13 one read-only nurse visit note: nurse name + Shamsi date + body + done/not-done task-result chips; presentational (caller formats the date); reused by the E2 سوابق tab + the nurse continuity view (tested)
|
||||
│ ├── PatientHeader/ # f13 patient identity block (name + relation chip + "age · gender" meta + condition chips) extracted from PatientCard so the E1 card and the E2 record viewer share one header; tolerates null relation / empty conditions (tested)
|
||||
│ ├── ProfileSummary/ # ui-2 the one identity card for chrome: avatar+name+masked phone+role label+optional TrustBadge, vertical (nurse sidebar) or `compact` horizontal chip (admin/partner TopBar); presentational — callers source data from useMe/profiles; replaces the starter UserInfo (tested)
|
||||
│ ├── PatientHeader/ # f13 patient identity block (avatar + name + relation chip + "age · gender" meta + condition chips) extracted from PatientCard so the E1 card and the E2 record viewer share one header; tolerates null relation / empty conditions; ui-phase-9 added an `InitialsAvatar` slot (tested)
|
||||
│ ├── ProfileSummary/ # ui-2 the one identity card for chrome: avatar+name+masked phone+role label+optional TrustBadge, vertical (nurse sidebar) or `compact` horizontal chip (admin/partner TopBar); presentational — callers source data from useMe/profiles; replaces the starter UserInfo; ui-phase-9 added `initialsFallback` (renders `InitialsAvatar` instead of MUI's generic silhouette when there's no `avatarUrl`) — the customer account hub's identity header (tested)
|
||||
│ ├── booking/ # f8 post-payment engagement composites (import from @/components/booking). BookingDetailView (both-roles smart container; ui-phase-5 hero: next-upcoming-session headline off the embedded sessions, a nurse-identity row, a client-only `.ics` add-to-calendar download (ics.ts, no backend seam), an EVV "پرستار در محل است" presence headline while checked in, role-conditioned EVV+gated care; ui-phase-7 added a standalone AddressCard below the hero — a `geo:`/Neshan-web map deep-link when the frozen snapshot carries lat/lng, a quiet nurse-only fallback note otherwise (REQ-051) — and a nurse-only in-visit «در حال ویزیت» banner promoting the check-out action), BookingStatusTimeline (server-truth 7-status timeline over the shared vertical StatusTimeline — the ui-phase-1 swap off StepperHeader), SessionList→SessionCard (per-session schedule/status/EVV CTA; ui-phase-5 aligned its card shell to SurfaceCard; ui-phase-7 made the EVV CTA the full-width hero action + an optional `serviceLabel` line, REQ-052), EvvStatusBanner (advisory in/out-of-range/no-gps), CareInstructionsCard (decrypted clinical read), CheckOutConfirmButton (ui-phase-7 — the shared check-out action + lightweight confirm dialog, used by both SessionCard and BookingDetailView's in-visit banner so "check-out ends the visit and starts the payout clock" always gets one confirm step), BookingMoneySummary (gross/commission/payout display-only); useEvvController (GPS-capture + check-in/out orchestration), format.ts + statusKind.ts + ics.ts helpers (kept internal — not in the barrel). Each composite tested; the BookingDetailView test proves the customer never fires the care query (two-stage-disclosure gate)
|
||||
│ ├── geography/ # F3 geo composites: CascadingRegionSelect, AddressMapPicker (map-pin stand-in), AddressForm, AddressCard (each tested)
|
||||
│ ├── geography/ # F3 geo composites: CascadingRegionSelect, AddressForm, AddressCard (ui-phase-9 added a pin-quality cue — hasPin/pinSetLabel/pinMissingLabel), and the map-pin picker boundary — `AddressMapPicker` now branches on `NESHAN_WEB_KEY` (`@/config`): real Neshan tiles via `NeshanMap` (Leaflet, dynamically imported `ssr:false`; search box + locate-me + draggable pin + reverse-geocoded preview via `services/geography/neshan.ts`'s direct third-party fetch client) when set, else the original bounded-canvas grid stand-in (kept, not deleted, for dev/CI/jsdom) — `{ latitude, longitude }` in/out is identical either way so `AddressForm` never changed (each tested; `NeshanMap` itself isn't unit-tested — jsdom+Leaflet integration — and is unreachable in tests since `NEXT_PUBLIC_NESHAN_KEY` is unset in CI)
|
||||
│ ├── messaging/ # f14 tickets composites (import from @/components/messaging). Screens shared by the customer+nurse pages (role decides chrome): TicketInboxScreen, TicketThreadScreen (+ TicketMessageList), ContactSupportDialog (new-ticket → shows referenceCode), MessageComposer (optimistic send, draft-preserving), BookingSupportEntry (page-local glue on f8 booking detail — reuses the cached booking + care query, no refetch). Pure/tested: MessageBubble (mine/theirs, RTL-mirrored, never any internal-note styling), TicketListCard (prominent referenceCode + unread indicator + null-safe link), EmergencyBanner (post-confirmation tel: playbook, no VoIP seam). Helpers: statusKind.ts, authorLabel.ts
|
||||
│ ├── notifications/ # f14 notification composites (import from @/components/notifications). NotificationBell (chrome container — subscribes to the polling count so only it re-renders) → NotificationBellView (pure, tested), NotificationRow (pure, tested: unread emphasis + server title/body), NotificationCenter (shared page body: unread-first, mark-read-on-open + mark-all, deep-links via notificationDeepLink). Helper: notificationIcon.ts
|
||||
│ └── auth/ # Auth-flow composites: LoginFlow, PhoneStep, OtpStep, RoleRouter, SelectRole, AuthCard, BrandMark, AuthSplash, RoleGuard (role-aware shell guard, tested), AuthAccountError (/me-failed recovery), useCountdown, useWebOtp (ui-phase-3 WebOTP autofill seam), AuthIllustration + TrustBullets (ui-phase-3 CSS/SVG login-hero treatment)
|
||||
|
||||
Reference in New Issue
Block a user