feat: responsive widgets, atemschutz permission UX, event hard-delete
- fix dashboard grid: use auto-fill instead of auto-fit for equal-width widgets - atemschutz: skip stats/members API calls for non-privileged users, hide empty Aktionen column, add personal status subtitle - kalender: add permanent delete option for events with confirmation dialog Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -183,20 +183,25 @@ function Atemschutz() {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const [traegerData, statsData, membersData] = await Promise.all([
|
||||
atemschutzApi.getAll(),
|
||||
atemschutzApi.getStats(),
|
||||
membersService.getMembers({ pageSize: 500 }),
|
||||
]);
|
||||
setTraeger(traegerData);
|
||||
setStats(statsData);
|
||||
setMembers(membersData.items);
|
||||
if (canViewAll) {
|
||||
const [traegerData, statsData, membersData] = await Promise.all([
|
||||
atemschutzApi.getAll(),
|
||||
atemschutzApi.getStats(),
|
||||
membersService.getMembers({ pageSize: 500 }),
|
||||
]);
|
||||
setTraeger(traegerData);
|
||||
setStats(statsData);
|
||||
setMembers(membersData.items);
|
||||
} else {
|
||||
const traegerData = await atemschutzApi.getAll();
|
||||
setTraeger(traegerData);
|
||||
}
|
||||
} catch {
|
||||
setError('Atemschutzdaten konnten nicht geladen werden. Bitte versuchen Sie es erneut.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
}, [canViewAll]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
@@ -361,6 +366,11 @@ function Atemschutz() {
|
||||
<Typography variant="h4" gutterBottom sx={{ mb: 0 }}>
|
||||
Atemschutzverwaltung
|
||||
</Typography>
|
||||
{!loading && !canViewAll && (
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
|
||||
Dein persönlicher Atemschutz-Status
|
||||
</Typography>
|
||||
)}
|
||||
{!loading && stats && canViewAll && (
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, mt: 0.5 }}>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
@@ -471,7 +481,7 @@ function Atemschutz() {
|
||||
<TableCell>Untersuchung gültig bis</TableCell>
|
||||
<TableCell>Leistungstest gültig bis</TableCell>
|
||||
<TableCell align="center">Status</TableCell>
|
||||
<TableCell align="right">Aktionen</TableCell>
|
||||
{canWrite && <TableCell align="right">Aktionen</TableCell>}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
@@ -549,31 +559,29 @@ function Atemschutz() {
|
||||
variant="filled"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell align="right">
|
||||
{canWrite && (
|
||||
<Tooltip title="Bearbeiten">
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => handleOpenEdit(item)}
|
||||
sx={{ minWidth: 'auto', mr: 0.5 }}
|
||||
>
|
||||
<Edit fontSize="small" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
{canWrite && (
|
||||
<Tooltip title="Löschen">
|
||||
<Button
|
||||
size="small"
|
||||
color="error"
|
||||
onClick={() => setDeleteId(item.id)}
|
||||
sx={{ minWidth: 'auto' }}
|
||||
>
|
||||
<Delete fontSize="small" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</TableCell>
|
||||
{canWrite && (
|
||||
<TableCell align="right">
|
||||
<Tooltip title="Bearbeiten">
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => handleOpenEdit(item)}
|
||||
sx={{ minWidth: 'auto', mr: 0.5 }}
|
||||
>
|
||||
<Edit fontSize="small" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title="Löschen">
|
||||
<Button
|
||||
size="small"
|
||||
color="error"
|
||||
onClick={() => setDeleteId(item.id)}
|
||||
sx={{ minWidth: 'auto' }}
|
||||
>
|
||||
<Delete fontSize="small" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user