99 lines
3.7 KiB
TypeScript
99 lines
3.7 KiB
TypeScript
'use client';
|
|
import { Stack, Typography } from '@mui/material';
|
|
import { useLocale, useTranslations } from 'next-intl';
|
|
import { AccentCard, AppLink, NavHubList, PageHeader, StatusChip, TrustBadge } from '@/components';
|
|
import type { NavHubItem } from '@/components';
|
|
import { ROUTES } from '@/constants';
|
|
import { useMyVariants } from '@/services/catalog';
|
|
import { useServiceAreas } from '@/services/serviceAreas';
|
|
import { useNurseProfile } from '@/services/profiles';
|
|
import { useVerificationStatus } from '@/services/verification';
|
|
import { ownBadgeState } from '@/services/verification/types';
|
|
|
|
/**
|
|
* «حرفهٔ من» group root — the page the bottom-nav tab lands on. It answers the question the
|
|
* sidebar section never could ("is my listing actually live, and what's missing?") before handing
|
|
* off to the four screens that fix it. Every number here is read off a query that already answers
|
|
* it; nothing is derived optimistically, and a count is simply omitted until its query resolves.
|
|
*/
|
|
export default function NursePracticeScreen() {
|
|
const t = useTranslations('hub');
|
|
const locale = useLocale();
|
|
const tn = useTranslations('nav');
|
|
const { data: verification } = useVerificationStatus();
|
|
const { data: profile } = useNurseProfile();
|
|
const { data: variants } = useMyVariants();
|
|
const { data: areas } = useServiceAreas();
|
|
|
|
const activeVariants = variants?.items.filter((variant) => variant.isActive).length;
|
|
const isAccepting = profile?.isAcceptingBookings;
|
|
|
|
const items: Array<NavHubItem> = [
|
|
{
|
|
title: tn('profile'),
|
|
subtitle: t('practice_profile_sub'),
|
|
icon: 'account',
|
|
path: ROUTES.NURSE_PROFILE,
|
|
},
|
|
{
|
|
title: tn('services'),
|
|
subtitle: t('practice_services_sub'),
|
|
icon: 'services',
|
|
path: ROUTES.NURSE_SERVICES,
|
|
meta: activeVariants === undefined ? undefined : <MetaCount value={activeVariants} />,
|
|
},
|
|
{
|
|
title: tn('coverage'),
|
|
subtitle: t('practice_coverage_sub'),
|
|
icon: 'coverage',
|
|
path: ROUTES.NURSE_COVERAGE,
|
|
meta: areas === undefined ? undefined : <MetaCount value={areas.total} />,
|
|
},
|
|
{
|
|
title: tn('verification'),
|
|
subtitle: t('practice_verification_sub'),
|
|
icon: 'verification',
|
|
path: ROUTES.NURSE_VERIFICATION,
|
|
},
|
|
];
|
|
|
|
return (
|
|
<Stack sx={{ gap: 2 }}>
|
|
<PageHeader title={tn('group_profession')} subtitle={t('practice_subtitle')} />
|
|
|
|
<AccentCard tone={isAccepting ? 'success' : 'warning'}>
|
|
<Stack sx={{ gap: 1.25 }}>
|
|
<Stack direction="row" sx={{ gap: 1, alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap' }}>
|
|
<Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
|
|
{t('practice_status_title')}
|
|
</Typography>
|
|
<TrustBadge state={ownBadgeState(verification)} />
|
|
</Stack>
|
|
{isAccepting === undefined ? null : (
|
|
<Stack direction="row" sx={{ gap: 1, alignItems: 'center', flexWrap: 'wrap' }}>
|
|
<StatusChip
|
|
status={isAccepting ? 'active' : 'neutral'}
|
|
label={isAccepting ? t('practice_accepting_on') : t('practice_accepting_off')}
|
|
/>
|
|
<AppLink to={`/${locale}${ROUTES.NURSE_SERVICES}`} variant="caption">
|
|
{t('practice_accepting_manage')}
|
|
</AppLink>
|
|
</Stack>
|
|
)}
|
|
</Stack>
|
|
</AccentCard>
|
|
|
|
<NavHubList items={items} />
|
|
</Stack>
|
|
);
|
|
}
|
|
|
|
/** A count read straight off a resolved query — never a placeholder while one is in flight. */
|
|
function MetaCount({ value }: { value: number }) {
|
|
return (
|
|
<Typography variant="body2" sx={{ color: 'text.secondary', fontVariantNumeric: 'tabular-nums' }}>
|
|
{value}
|
|
</Typography>
|
|
);
|
|
}
|