frontend phase 4: catalog browse (Home A5) & nurse service builder (B7)
Light up the two faces of the configurable service catalog over a new cached services/catalog domain (consumes the b5 contract; unlocks f6 search). - services/catalog: types/keys/constants/apis(client+mock+seam)/hooks/index + names.ts. Categories & option groups are session-cached reference data (Infinity staleTime, like geography); variant mutations invalidate myVariantsLists() and setQueryData the edited row. Mock-primary (USE_CATALOG_MOCK), one-line swap; mock reproduces the 400 missing-required and (nurse,category,option-set) 409 duplicate rules. - Customer Home (A5): greeting+avatar, search bar (navigates toward f6), data-driven category grid (loading/empty/error), patient nudge from the cached f2 query. Deferred /search placeholder stub. - Nurse Services & prices (B7) at /nurse/services: offerings list (active vs deactivated, edit, soft-deactivate w/ confirm, reactivate, no delete) and a 3-step variant builder (category -> required/optional options -> price+unit+ duration). Required-group gate; Toman->IRR digit-string at the field boundary (no float); live unit-aware estimated total (never from price alone); editable auto display_name; inline 409 duplicate warning; locked category edit form. - Shared, tested components: CategoryTile, PriceDisplay, VariantCard. Money util: tomanToRial + multiplyIrr (integer-safe) + tests. - i18n: catalog/services/search namespaces + home additions + nav.services (both locales, in sync). Icons, routes (SEARCH, NURSE_SERVICES), nurse nav. Gate: npm run check green; npm run test:ci green (147 tests, +18 across 4 suites); npm run build green with NEXT_PUBLIC_API_URL set. Docs: client/CLAUDE.md (Project Structure, caching note, namespaces), STATUS, for-backend REQ-010 (pagination param casing), phase report, mocks registry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
import type { PageParams } from '@/lib/api/types';
|
||||
|
||||
/**
|
||||
* React Query key factory for the catalog domain. Reference data (categories, a category's option
|
||||
* groups) is keyed so each is fetched **once** per session and served from cache across the Home
|
||||
* grid and the nurse builder. The nurse's own variant list invalidates on every mutation via the
|
||||
* `myVariantsLists()` prefix; a single edited variant is refreshed by `variant(id)`.
|
||||
*/
|
||||
export const catalogKeys = {
|
||||
all: ['catalog'] as const,
|
||||
|
||||
// Reference data — cached for the whole session, never invalidated by this phase.
|
||||
categories: () => [...catalogKeys.all, 'categories'] as const,
|
||||
categoryOptionGroups: (categoryId?: number | null) =>
|
||||
[...catalogKeys.all, 'option-groups', categoryId ?? null] as const,
|
||||
|
||||
// The nurse's offerings — mutable; mutations invalidate the `myVariantsLists()` prefix.
|
||||
variants: () => [...catalogKeys.all, 'variants'] as const,
|
||||
myVariantsLists: () => [...catalogKeys.variants(), 'mine'] as const,
|
||||
myVariants: (params?: PageParams) => [...catalogKeys.myVariantsLists(), params ?? {}] as const,
|
||||
variant: (id: number) => [...catalogKeys.variants(), 'detail', id] as const,
|
||||
};
|
||||
Reference in New Issue
Block a user