85 lines
2.2 KiB
TypeScript
85 lines
2.2 KiB
TypeScript
'use client';
|
|
|
|
import * as React from 'react';
|
|
import { Alert, AlertTitle, Collapse, Typography } from '@mui/material';
|
|
import { Box } from '@mui/system';
|
|
import { Warning as WarningIcon } from '@phosphor-icons/react/dist/ssr/Warning';
|
|
|
|
interface PropsError {
|
|
message: string;
|
|
code?: string | number;
|
|
details?: string;
|
|
severity?: 'error' | 'warning' | 'info' | 'success';
|
|
}
|
|
|
|
// RULES: Sample of function
|
|
function formatErrorMessage(message: string, code?: string | number): string {
|
|
return code ? `[${code}] ${message}` : message;
|
|
}
|
|
|
|
// RULES: sample of inner component
|
|
function ErrorDetails({ details }: { details: string }): React.JSX.Element {
|
|
const [expanded, setExpanded] = React.useState<boolean>(false);
|
|
|
|
return (
|
|
<Box>
|
|
<Typography
|
|
variant="body2"
|
|
sx={{
|
|
cursor: 'pointer',
|
|
textDecoration: 'underline',
|
|
mt: 1,
|
|
}}
|
|
onClick={() => {
|
|
setExpanded(!expanded);
|
|
}}
|
|
>
|
|
{expanded ? 'Hide Details' : 'Show Details'}
|
|
</Typography>
|
|
|
|
<Collapse in={expanded}>
|
|
<Box sx={{ mt: 1, p: 1, bgcolor: 'background.paper' }}>
|
|
<Typography variant="body2" component="pre" sx={{ whiteSpace: 'pre-wrap' }}>
|
|
{details}
|
|
</Typography>
|
|
</Box>
|
|
</Collapse>
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
// RULES: naming should be in Pascal case
|
|
// RULES: sample of main component
|
|
function ErrorDisplay({ message, code, details, severity = 'error' }: PropsError): React.JSX.Element {
|
|
const [formattedMessage, setFormattedMessage] = React.useState<string>('');
|
|
|
|
React.useEffect(() => {
|
|
setFormattedMessage(formatErrorMessage(message, code));
|
|
}, [message, code]);
|
|
|
|
return (
|
|
<Box sx={{ p: 2, maxWidth: 800, width: '100%' }}>
|
|
<Alert
|
|
severity={severity}
|
|
icon={<WarningIcon weight="fill" />}
|
|
sx={{
|
|
'& .MuiAlert-message': {
|
|
width: '100%',
|
|
},
|
|
}}
|
|
>
|
|
<AlertTitle>{code ? `Error ${code}` : 'Error'}</AlertTitle>
|
|
|
|
<Typography variant="body1" gutterBottom>
|
|
{formattedMessage}
|
|
</Typography>
|
|
|
|
{details && <ErrorDetails details={details} />}
|
|
</Alert>
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
// RULES: component should be exported
|
|
export default ErrorDisplay;
|