83 lines
2.9 KiB
TypeScript
83 lines
2.9 KiB
TypeScript
'use client';
|
|
import { FunctionComponent } from 'react';
|
|
import { useLocale, useTranslations } from 'next-intl';
|
|
import { useSnackbar } from 'notistack';
|
|
import { Paper, Stack, Typography } from '@mui/material';
|
|
import { AppButton, AppIcon } from '@/components';
|
|
import { ROUTES } from '@/constants';
|
|
import { useVerificationStatus } from '@/services/verification';
|
|
import { isApproved } from '@/services/verification/types';
|
|
|
|
/**
|
|
* The go-live gate for the nurse's services (the f4 publish stub, wired to verification here). A nurse
|
|
* is **not bookable and cannot publish until verified**: when the aggregate isn't `approved` the publish
|
|
* CTA is **disabled** with a blocked-until-verified explanation that links to the B3 checklist; once
|
|
* approved it enables. Mirrors the server's guarded `is_verified` flip — the UI never implies a nurse is
|
|
* live before verification completes. Reads the shared `VerificationStatus` query (cached across the app).
|
|
*/
|
|
const PublishGate: FunctionComponent = () => {
|
|
const t = useTranslations('verification');
|
|
const locale = useLocale();
|
|
const { enqueueSnackbar } = useSnackbar();
|
|
const { data: status, isLoading } = useVerificationStatus();
|
|
|
|
if (isLoading) return null;
|
|
const approved = isApproved(status);
|
|
|
|
return (
|
|
<Paper
|
|
elevation={0}
|
|
sx={{
|
|
p: 2,
|
|
borderRadius: 2,
|
|
border: '1px solid',
|
|
borderColor: 'divider',
|
|
borderInlineStartWidth: 4,
|
|
borderInlineStartColor: approved ? 'var(--bal-success)' : 'var(--bal-warning)',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: 1,
|
|
}}
|
|
>
|
|
<Stack direction="row" sx={{ gap: 1.5, alignItems: 'flex-start' }}>
|
|
<AppIcon
|
|
icon={approved ? 'verified' : 'warning'}
|
|
size={24}
|
|
color={approved ? 'var(--bal-success)' : 'var(--bal-warning)'}
|
|
/>
|
|
<Stack sx={{ gap: 0.5, flexGrow: 1 }}>
|
|
<Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
|
|
{approved ? t('publish_ready_title') : t('publish_blocked_title')}
|
|
</Typography>
|
|
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
|
|
{approved ? t('publish_ready_body') : t('publish_blocked_body')}
|
|
</Typography>
|
|
</Stack>
|
|
</Stack>
|
|
|
|
<Stack direction="row" sx={{ gap: 1, flexWrap: 'wrap' }}>
|
|
<AppButton
|
|
color="primary"
|
|
variant="contained"
|
|
startIcon="publish"
|
|
disabled={!approved}
|
|
onClick={() => enqueueSnackbar(t('publish_done'), { variant: 'success' })}
|
|
>
|
|
{t('publish_cta')}
|
|
</AppButton>
|
|
{!approved ? (
|
|
<AppButton
|
|
variant="outlined"
|
|
color="primary"
|
|
to={`/${locale}${ROUTES.NURSE_VERIFICATION}`}
|
|
>
|
|
{t('publish_complete_verification')}
|
|
</AppButton>
|
|
) : null}
|
|
</Stack>
|
|
</Paper>
|
|
);
|
|
};
|
|
|
|
export default PublishGate;
|