feat: widget icons, dark theme tables, breadcrumb removal, bookkeeping rework, personal equipment pages, PDF/order improvements

This commit is contained in:
Matthias Hochmeister
2026-04-14 10:35:40 +02:00
parent 4c4fb01e68
commit 4fbea8af81
41 changed files with 679 additions and 659 deletions

View File

@@ -439,10 +439,6 @@ function MitgliedDetail() {
<PageHeader
title={displayName}
backTo="/mitglieder"
breadcrumbs={[
{ label: 'Mitglieder', href: '/mitglieder' },
{ label: displayName },
]}
/>
{/* Header card */}
@@ -820,7 +816,7 @@ function MitgliedDetail() {
</Card>
</Grid>
{/* Uniform sizing */}
{/* Uniform sizing + Personal equipment (merged) */}
<Grid item xs={12} md={6}>
<Card>
<CardHeader
@@ -858,48 +854,43 @@ function MitgliedDetail() {
<FieldRow label="Schuhgröße" value={profile?.schuhgroesse ?? null} />
</>
)}
{(hasPermission('persoenliche_ausruestung:view') || hasPermission('persoenliche_ausruestung:view_all')) && (
<>
<Divider sx={{ my: 1.5 }} />
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 1 }}>
Persönliche Ausrüstung
</Typography>
{personalEquipmentLoading ? (
<CircularProgress size={24} />
) : personalEquipment.length === 0 ? (
<Typography color="text.secondary" variant="body2">
Keine persönlichen Gegenstände erfasst
</Typography>
) : (
personalEquipment.map((item) => (
<Box key={item.id} sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', py: 0.75, borderBottom: '1px solid', borderColor: 'divider' }}>
<Box>
<Typography variant="body2" fontWeight={500}>{item.bezeichnung}</Typography>
{item.kategorie && (
<Typography variant="caption" color="text.secondary">{item.kategorie}</Typography>
)}
</Box>
<Chip
label={ZUSTAND_LABELS[item.zustand]}
color={ZUSTAND_COLORS[item.zustand]}
size="small"
variant="outlined"
/>
</Box>
))
)}
</>
)}
</CardContent>
</Card>
</Grid>
{/* Personal equipment */}
{(hasPermission('persoenliche_ausruestung:view') || hasPermission('persoenliche_ausruestung:view_all')) && (
<Grid item xs={12} md={6}>
<Card>
<CardHeader
avatar={<SecurityIcon color="primary" />}
title="Persönliche Ausrüstung"
/>
<CardContent>
{personalEquipmentLoading ? (
<CircularProgress size={24} />
) : personalEquipment.length === 0 ? (
<Typography color="text.secondary" variant="body2">
Keine persönlichen Gegenstände erfasst
</Typography>
) : (
personalEquipment.map((item) => (
<Box key={item.id} sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', py: 0.75, borderBottom: '1px solid', borderColor: 'divider' }}>
<Box>
<Typography variant="body2" fontWeight={500}>{item.bezeichnung}</Typography>
{item.kategorie && (
<Typography variant="caption" color="text.secondary">{item.kategorie}</Typography>
)}
</Box>
<Chip
label={ZUSTAND_LABELS[item.zustand]}
color={ZUSTAND_COLORS[item.zustand]}
size="small"
variant="outlined"
/>
</Box>
))
)}
</CardContent>
</Card>
</Grid>
)}
{/* Driving licenses */}
<Grid item xs={12} md={6}>
<Card>