b8934f531d
Three domain services (mirroring the patients/nurse template): services/geography (cached province→city→district lookups; Infinity staleTime + shared geographyKeys), services/addresses (address book CRUD + set-primary; single-primary invariant), and services/serviceAreas (coverage add/remove; areaExists dup-guard, districtId=null = whole city). Four tested composites in src/components/geography: CascadingRegionSelect (drives the cascade queries), AddressMapPicker (map-pin stand-in emitting real lat/lng), AddressForm, AddressCard. Screens: customer address book (/addresses, reached from the profile hub) and nurse coverage editor (/nurse/coverage, new sidebar tab, inline duplicate block + 409). Adds geo/address/coverage i18n namespaces (both locales), location/delete/coverage icons, ADDRESSES/NURSE_COVERAGE routes. Consumes the b4 geography-addresses contract; filed REQ-008 (accept the map pin on create/update) and REQ-009 (provinceId on CustomerAddressDto) for gaps. Gate: npm run check + npm run test:ci (129, +17) + npm run build all green. A 5-dimension adversarial review fixed 3 findings (map-marker RTL transform, page_size→pageSize pagination casing, coverage districts-scope dead-end on district-less cities). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
'use client';
|
|
import { FunctionComponent, PropsWithChildren, useMemo } from 'react';
|
|
import { useTranslations } from 'next-intl';
|
|
import { ROUTES } from '@/constants';
|
|
import { LinkToPage } from '@/utils';
|
|
import TopBarAndSideBarLayout from './TopBarAndSideBarLayout';
|
|
|
|
/**
|
|
* Nurse app shell — the "نمای پرستار" experience (verification, dashboard, EVV visits).
|
|
* Uses the shared TopBar + SideBar engine: a temporary drawer on mobile, persistent on
|
|
* desktop. Nav is role-scoped to the nurse routes.
|
|
* @layout NurseLayout
|
|
*/
|
|
const NurseLayout: FunctionComponent<PropsWithChildren> = ({ children }) => {
|
|
const t = useTranslations('nav');
|
|
const tShell = useTranslations('shell');
|
|
|
|
const sidebarItems: Array<LinkToPage> = useMemo(
|
|
() => [
|
|
{ title: t('dashboard'), path: ROUTES.NURSE, icon: 'dashboard' },
|
|
{ title: t('profile'), path: ROUTES.NURSE_PROFILE, icon: 'profile' },
|
|
{ title: t('coverage'), path: ROUTES.NURSE_COVERAGE, icon: 'coverage' },
|
|
{ title: t('bank'), path: ROUTES.NURSE_BANK, icon: 'bank' },
|
|
{ title: t('verification'), path: ROUTES.NURSE_VERIFICATION, icon: 'verification' },
|
|
{ title: t('visits'), path: ROUTES.NURSE_VISITS, icon: 'visits' },
|
|
],
|
|
[t]
|
|
);
|
|
|
|
return (
|
|
<TopBarAndSideBarLayout
|
|
sidebarItems={sidebarItems}
|
|
title={tShell('nurse_app')}
|
|
variant="sidebarPersistentOnDesktop"
|
|
>
|
|
{children}
|
|
</TopBarAndSideBarLayout>
|
|
);
|
|
};
|
|
|
|
export default NurseLayout;
|