refinement phase 2
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
'use client';
|
||||
import { FunctionComponent } from 'react';
|
||||
import { CircularProgress, Stack, Typography } from '@mui/material';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
import { AppButton } from '@/components';
|
||||
import AppIcon from '@/components/common/AppIcon';
|
||||
import BrandMark from './BrandMark';
|
||||
|
||||
interface AuthAccountErrorProps {
|
||||
onRetry: () => void;
|
||||
isRetrying: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shown by `RoleGuard` when `/me` fails on a private route (e.g. the API is unreachable). Surfacing an
|
||||
* explicit "couldn't load your account" recovery is the deliberate alternative to silently defaulting to
|
||||
* the customer shell — a transient error must never downgrade a nurse/admin to the family app.
|
||||
* @component AuthAccountError
|
||||
*/
|
||||
const AuthAccountError: FunctionComponent<AuthAccountErrorProps> = ({ onRetry, isRetrying }) => {
|
||||
const t = useTranslations('auth');
|
||||
return (
|
||||
<Stack
|
||||
sx={{ alignItems: 'center', justifyContent: 'center', minHeight: '70vh', gap: 2, px: 2, textAlign: 'center' }}
|
||||
>
|
||||
<BrandMark />
|
||||
<AppIcon icon="warning" size={40} color="var(--bal-warning)" />
|
||||
<Typography variant="h6" component="h1">
|
||||
{t('account_error_title')}
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: 'text.secondary', maxWidth: 360 }}>
|
||||
{t('account_error_body')}
|
||||
</Typography>
|
||||
<AppButton
|
||||
color="primary"
|
||||
variant="contained"
|
||||
onClick={onRetry}
|
||||
disabled={isRetrying}
|
||||
startIcon={isRetrying ? <CircularProgress size={18} color="inherit" /> : undefined}
|
||||
>
|
||||
{t('account_error_retry')}
|
||||
</AppButton>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default AuthAccountError;
|
||||
Reference in New Issue
Block a user