feat(frontend): implement unified design system with 17 reusable template components, skeleton loading states, and golden-ratio-based layouts
This commit is contained in:
@@ -27,7 +27,6 @@ import {
|
||||
AccessTime,
|
||||
DirectionsCar,
|
||||
People,
|
||||
LocationOn,
|
||||
Description,
|
||||
PictureAsPdf,
|
||||
} from '@mui/icons-material';
|
||||
@@ -44,6 +43,7 @@ import {
|
||||
} from '../services/incidents';
|
||||
import { useNotification } from '../contexts/NotificationContext';
|
||||
import { usePermissionContext } from '../contexts/PermissionContext';
|
||||
import { PageHeader } from '../components/templates';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// COLOUR MAPS
|
||||
@@ -280,94 +280,75 @@ function EinsatzDetail() {
|
||||
return (
|
||||
<DashboardLayout>
|
||||
<Container maxWidth="lg">
|
||||
{/* Back + Actions */}
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
|
||||
<Button
|
||||
startIcon={<ArrowBack />}
|
||||
onClick={() => navigate('/einsaetze')}
|
||||
variant="text"
|
||||
>
|
||||
Zurück
|
||||
</Button>
|
||||
<Stack direction="row" spacing={1}>
|
||||
<Tooltip title="PDF exportieren (Vorschau)">
|
||||
<Button
|
||||
<PageHeader
|
||||
title={`Einsatz ${einsatz.einsatz_nr}`}
|
||||
subtitle={address || undefined}
|
||||
backTo="/einsaetze"
|
||||
actions={
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<Chip
|
||||
icon={<LocalFireDepartment />}
|
||||
label={EINSATZ_ART_LABELS[einsatz.einsatz_art]}
|
||||
color={ART_CHIP_COLOR[einsatz.einsatz_art]}
|
||||
sx={{ fontWeight: 600 }}
|
||||
/>
|
||||
<Chip
|
||||
label={EINSATZ_STATUS_LABELS[einsatz.status]}
|
||||
color={STATUS_CHIP_COLOR[einsatz.status]}
|
||||
variant="outlined"
|
||||
startIcon={<PictureAsPdf />}
|
||||
onClick={handleExportPdf}
|
||||
size="small"
|
||||
>
|
||||
PDF Export
|
||||
</Button>
|
||||
</Tooltip>
|
||||
{canWrite && !editing ? (
|
||||
<Button
|
||||
variant="contained"
|
||||
startIcon={<Edit />}
|
||||
onClick={() => setEditing(true)}
|
||||
size="small"
|
||||
>
|
||||
Bearbeiten
|
||||
</Button>
|
||||
) : canWrite && editing ? (
|
||||
<>
|
||||
/>
|
||||
<Tooltip title="PDF exportieren (Vorschau)">
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<Cancel />}
|
||||
onClick={handleCancelEdit}
|
||||
startIcon={<PictureAsPdf />}
|
||||
onClick={handleExportPdf}
|
||||
size="small"
|
||||
disabled={saving}
|
||||
>
|
||||
Abbrechen
|
||||
PDF Export
|
||||
</Button>
|
||||
</Tooltip>
|
||||
{canWrite && !editing ? (
|
||||
<Button
|
||||
variant="contained"
|
||||
color="success"
|
||||
startIcon={<Save />}
|
||||
onClick={handleSaveBericht}
|
||||
startIcon={<Edit />}
|
||||
onClick={() => setEditing(true)}
|
||||
size="small"
|
||||
disabled={saving}
|
||||
>
|
||||
{saving ? 'Speichere...' : 'Speichern'}
|
||||
Bearbeiten
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
</Stack>
|
||||
</Box>
|
||||
) : canWrite && editing ? (
|
||||
<>
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<Cancel />}
|
||||
onClick={handleCancelEdit}
|
||||
size="small"
|
||||
disabled={saving}
|
||||
>
|
||||
Abbrechen
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="success"
|
||||
startIcon={<Save />}
|
||||
onClick={handleSaveBericht}
|
||||
size="small"
|
||||
disabled={saving}
|
||||
>
|
||||
{saving ? 'Speichere...' : 'Speichern'}
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
</Stack>
|
||||
}
|
||||
/>
|
||||
|
||||
{/* HEADER */}
|
||||
<Box sx={{ mb: 3 }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, flexWrap: 'wrap', mb: 1 }}>
|
||||
<Chip
|
||||
icon={<LocalFireDepartment />}
|
||||
label={EINSATZ_ART_LABELS[einsatz.einsatz_art]}
|
||||
color={ART_CHIP_COLOR[einsatz.einsatz_art]}
|
||||
sx={{ fontWeight: 600 }}
|
||||
/>
|
||||
<Chip
|
||||
label={EINSATZ_STATUS_LABELS[einsatz.status]}
|
||||
color={STATUS_CHIP_COLOR[einsatz.status]}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
/>
|
||||
{einsatz.einsatz_stichwort && (
|
||||
<Typography variant="h6" color="text.secondary">
|
||||
{einsatz.einsatz_stichwort}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
<Typography variant="h4" fontWeight={700}>
|
||||
Einsatz {einsatz.einsatz_nr}
|
||||
{einsatz.einsatz_stichwort && (
|
||||
<Typography variant="h6" color="text.secondary" sx={{ mb: 2, mt: -2 }}>
|
||||
{einsatz.einsatz_stichwort}
|
||||
</Typography>
|
||||
{address && (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, mt: 0.5 }}>
|
||||
<LocationOn fontSize="small" color="action" />
|
||||
<Typography variant="body1" color="text.secondary">
|
||||
{address}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Grid container spacing={3}>
|
||||
{/* LEFT COLUMN: Timeline + Vehicles */}
|
||||
|
||||
Reference in New Issue
Block a user