Files
react-test/docs/data/material/getting-started/templates/crud-dashboard/components/EmployeeShow.tsx
how2ice 005cf56baf
Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
init project
2025-12-12 14:26:25 +09:00

223 lines
6.3 KiB
TypeScript

import * as React from 'react';
import Alert from '@mui/material/Alert';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import CircularProgress from '@mui/material/CircularProgress';
import Divider from '@mui/material/Divider';
import Grid from '@mui/material/Grid';
import Paper from '@mui/material/Paper';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import { useNavigate, useParams } from 'react-router';
import dayjs from 'dayjs';
import { useDialogs } from '../hooks/useDialogs/useDialogs';
import useNotifications from '../hooks/useNotifications/useNotifications';
import {
deleteOne as deleteEmployee,
getOne as getEmployee,
type Employee,
} from '../data/employees';
import PageContainer from './PageContainer';
export default function EmployeeShow() {
const { employeeId } = useParams();
const navigate = useNavigate();
const dialogs = useDialogs();
const notifications = useNotifications();
const [employee, setEmployee] = React.useState<Employee | null>(null);
const [isLoading, setIsLoading] = React.useState(true);
const [error, setError] = React.useState<Error | null>(null);
const loadData = React.useCallback(async () => {
setError(null);
setIsLoading(true);
try {
const showData = await getEmployee(Number(employeeId));
setEmployee(showData);
} catch (showDataError) {
setError(showDataError as Error);
}
setIsLoading(false);
}, [employeeId]);
React.useEffect(() => {
loadData();
}, [loadData]);
const handleEmployeeEdit = React.useCallback(() => {
navigate(`/employees/${employeeId}/edit`);
}, [navigate, employeeId]);
const handleEmployeeDelete = React.useCallback(async () => {
if (!employee) {
return;
}
const confirmed = await dialogs.confirm(
`Do you wish to delete ${employee.name}?`,
{
title: `Delete employee?`,
severity: 'error',
okText: 'Delete',
cancelText: 'Cancel',
},
);
if (confirmed) {
setIsLoading(true);
try {
await deleteEmployee(Number(employeeId));
navigate('/employees');
notifications.show('Employee deleted successfully.', {
severity: 'success',
autoHideDuration: 3000,
});
} catch (deleteError) {
notifications.show(
`Failed to delete employee. Reason:' ${(deleteError as Error).message}`,
{
severity: 'error',
autoHideDuration: 3000,
},
);
}
setIsLoading(false);
}
}, [employee, dialogs, employeeId, navigate, notifications]);
const handleBack = React.useCallback(() => {
navigate('/employees');
}, [navigate]);
const renderShow = React.useMemo(() => {
if (isLoading) {
return (
<Box
sx={{
flex: 1,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
m: 1,
}}
>
<CircularProgress />
</Box>
);
}
if (error) {
return (
<Box sx={{ flexGrow: 1 }}>
<Alert severity="error">{error.message}</Alert>
</Box>
);
}
return employee ? (
<Box sx={{ flexGrow: 1, width: '100%' }}>
<Grid container spacing={2} sx={{ width: '100%' }}>
<Grid size={{ xs: 12, sm: 6 }}>
<Paper sx={{ px: 2, py: 1 }}>
<Typography variant="overline">Name</Typography>
<Typography variant="body1" sx={{ mb: 1 }}>
{employee.name}
</Typography>
</Paper>
</Grid>
<Grid size={{ xs: 12, sm: 6 }}>
<Paper sx={{ px: 2, py: 1 }}>
<Typography variant="overline">Age</Typography>
<Typography variant="body1" sx={{ mb: 1 }}>
{employee.age}
</Typography>
</Paper>
</Grid>
<Grid size={{ xs: 12, sm: 6 }}>
<Paper sx={{ px: 2, py: 1 }}>
<Typography variant="overline">Join date</Typography>
<Typography variant="body1" sx={{ mb: 1 }}>
{dayjs(employee.joinDate).format('MMMM D, YYYY')}
</Typography>
</Paper>
</Grid>
<Grid size={{ xs: 12, sm: 6 }}>
<Paper sx={{ px: 2, py: 1 }}>
<Typography variant="overline">Department</Typography>
<Typography variant="body1" sx={{ mb: 1 }}>
{employee.role}
</Typography>
</Paper>
</Grid>
<Grid size={{ xs: 12, sm: 6 }}>
<Paper sx={{ px: 2, py: 1 }}>
<Typography variant="overline">Full-time</Typography>
<Typography variant="body1" sx={{ mb: 1 }}>
{employee.isFullTime ? 'Yes' : 'No'}
</Typography>
</Paper>
</Grid>
</Grid>
<Divider sx={{ my: 3 }} />
<Stack direction="row" spacing={2} justifyContent="space-between">
<Button
variant="contained"
startIcon={<ArrowBackIcon />}
onClick={handleBack}
>
Back
</Button>
<Stack direction="row" spacing={2}>
<Button
variant="contained"
startIcon={<EditIcon />}
onClick={handleEmployeeEdit}
>
Edit
</Button>
<Button
variant="contained"
color="error"
startIcon={<DeleteIcon />}
onClick={handleEmployeeDelete}
>
Delete
</Button>
</Stack>
</Stack>
</Box>
) : null;
}, [
isLoading,
error,
employee,
handleBack,
handleEmployeeEdit,
handleEmployeeDelete,
]);
const pageTitle = `Employee ${employeeId}`;
return (
<PageContainer
title={pageTitle}
breadcrumbs={[
{ title: 'Employees', path: '/employees' },
{ title: pageTitle },
]}
>
<Box sx={{ display: 'flex', flex: 1, width: '100%' }}>{renderShow}</Box>
</PageContainer>
);
}