new features
This commit is contained in:
@@ -61,6 +61,7 @@ import {
|
||||
AusruestungStatusLabel,
|
||||
UpdateAusruestungStatusPayload,
|
||||
CreateAusruestungWartungslogPayload,
|
||||
UpdateAusruestungWartungslogPayload,
|
||||
} from '../types/equipment.types';
|
||||
import { usePermissions } from '../hooks/usePermissions';
|
||||
import { useNotification } from '../contexts/NotificationContext';
|
||||
@@ -422,6 +423,7 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [saveError, setSaveError] = useState<string | null>(null);
|
||||
const [editingEntry, setEditingEntry] = useState<AusruestungWartungslog | null>(null);
|
||||
|
||||
const emptyForm: CreateAusruestungWartungslogPayload = {
|
||||
datum: '',
|
||||
@@ -430,10 +432,33 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
|
||||
ergebnis: undefined,
|
||||
kosten: undefined,
|
||||
pruefende_stelle: undefined,
|
||||
naechste_pruefung_am: undefined,
|
||||
};
|
||||
|
||||
const [form, setForm] = useState<CreateAusruestungWartungslogPayload>(emptyForm);
|
||||
|
||||
const openAddDialog = () => {
|
||||
setEditingEntry(null);
|
||||
setForm(emptyForm);
|
||||
setSaveError(null);
|
||||
setDialogOpen(true);
|
||||
};
|
||||
|
||||
const openEditDialog = (entry: AusruestungWartungslog) => {
|
||||
setEditingEntry(entry);
|
||||
setForm({
|
||||
datum: entry.datum ? new Date(entry.datum).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }) : '',
|
||||
art: entry.art,
|
||||
beschreibung: entry.beschreibung,
|
||||
ergebnis: entry.ergebnis ?? undefined,
|
||||
kosten: entry.kosten ?? undefined,
|
||||
pruefende_stelle: entry.pruefende_stelle ?? undefined,
|
||||
naechste_pruefung_am: undefined,
|
||||
});
|
||||
setSaveError(null);
|
||||
setDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!form.datum || !form.art || !form.beschreibung.trim()) {
|
||||
setSaveError('Datum, Art und Beschreibung sind erforderlich.');
|
||||
@@ -442,14 +467,33 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
|
||||
try {
|
||||
setSaving(true);
|
||||
setSaveError(null);
|
||||
await equipmentApi.addWartungslog(equipmentId, {
|
||||
...form,
|
||||
datum: fromGermanDate(form.datum) || form.datum,
|
||||
pruefende_stelle: form.pruefende_stelle || undefined,
|
||||
ergebnis: form.ergebnis || undefined,
|
||||
});
|
||||
const datumIso = fromGermanDate(form.datum) || form.datum;
|
||||
const naechstePruefungIso = form.naechste_pruefung_am
|
||||
? (fromGermanDate(form.naechste_pruefung_am) || form.naechste_pruefung_am)
|
||||
: undefined;
|
||||
|
||||
if (editingEntry) {
|
||||
const payload: UpdateAusruestungWartungslogPayload = {
|
||||
datum: datumIso,
|
||||
art: form.art,
|
||||
beschreibung: form.beschreibung,
|
||||
ergebnis: form.ergebnis || null,
|
||||
pruefende_stelle: form.pruefende_stelle || null,
|
||||
naechste_pruefung_am: naechstePruefungIso || null,
|
||||
};
|
||||
await equipmentApi.updateWartungslog(equipmentId, editingEntry.id, payload);
|
||||
} else {
|
||||
await equipmentApi.addWartungslog(equipmentId, {
|
||||
...form,
|
||||
datum: datumIso,
|
||||
pruefende_stelle: form.pruefende_stelle || undefined,
|
||||
ergebnis: form.ergebnis || undefined,
|
||||
naechste_pruefung_am: naechstePruefungIso,
|
||||
});
|
||||
}
|
||||
setDialogOpen(false);
|
||||
setForm(emptyForm);
|
||||
setEditingEntry(null);
|
||||
onAdded();
|
||||
} catch {
|
||||
setSaveError('Wartungseintrag konnte nicht gespeichert werden.');
|
||||
@@ -463,6 +507,8 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
|
||||
(a, b) => new Date(b.datum).getTime() - new Date(a.datum).getTime()
|
||||
);
|
||||
|
||||
const showNaechstePruefung = form.ergebnis === 'bestanden';
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{sorted.length === 0 ? (
|
||||
@@ -496,13 +542,19 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
|
||||
)}
|
||||
</Box>
|
||||
<Typography variant="body2">{entry.beschreibung}</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mt: 0.25 }}>
|
||||
{[
|
||||
entry.kosten != null && `${Number(entry.kosten).toFixed(2)} EUR`,
|
||||
entry.pruefende_stelle && entry.pruefende_stelle,
|
||||
].filter(Boolean).join(' · ')}
|
||||
</Typography>
|
||||
{entry.pruefende_stelle && (
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mt: 0.25 }}>
|
||||
{entry.pruefende_stelle}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
{canWrite && (
|
||||
<Tooltip title="Bearbeiten">
|
||||
<IconButton size="small" onClick={() => openEditDialog(entry)}>
|
||||
<Edit fontSize="small" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
@@ -513,14 +565,14 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
|
||||
<ChatAwareFab
|
||||
size="small"
|
||||
aria-label="Wartung eintragen"
|
||||
onClick={() => { setForm(emptyForm); setSaveError(null); setDialogOpen(true); }}
|
||||
onClick={openAddDialog}
|
||||
>
|
||||
<Add />
|
||||
</ChatAwareFab>
|
||||
)}
|
||||
|
||||
<Dialog open={dialogOpen} onClose={() => setDialogOpen(false)} maxWidth="sm" fullWidth>
|
||||
<DialogTitle>Wartung / Prüfung eintragen</DialogTitle>
|
||||
<DialogTitle>{editingEntry ? 'Wartungseintrag bearbeiten' : 'Wartung / Prüfung eintragen'}</DialogTitle>
|
||||
<DialogContent>
|
||||
{saveError && <Alert severity="error" sx={{ mb: 2 }}>{saveError}</Alert>}
|
||||
<Grid container spacing={2} sx={{ mt: 0.5 }}>
|
||||
@@ -585,21 +637,6 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
|
||||
</FormControl>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<TextField
|
||||
label="Kosten (EUR)"
|
||||
type="number"
|
||||
fullWidth
|
||||
value={form.kosten ?? ''}
|
||||
onChange={(e) =>
|
||||
setForm((f) => ({
|
||||
...f,
|
||||
kosten: e.target.value ? Number(e.target.value) : undefined,
|
||||
}))
|
||||
}
|
||||
inputProps={{ min: 0, step: 0.01 }}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TextField
|
||||
label="Prüfende Stelle"
|
||||
fullWidth
|
||||
@@ -608,6 +645,19 @@ const WartungTab: React.FC<WartungTabProps> = ({ equipmentId, wartungslog, onAdd
|
||||
placeholder="Name der prüfenden Stelle oder Person"
|
||||
/>
|
||||
</Grid>
|
||||
{showNaechstePruefung && (
|
||||
<Grid item xs={12} sm={6}>
|
||||
<TextField
|
||||
label="Nächste Prüfung fällig am"
|
||||
fullWidth
|
||||
placeholder="TT.MM.JJJJ"
|
||||
value={form.naechste_pruefung_am ?? ''}
|
||||
onChange={(e) => setForm((f) => ({ ...f, naechste_pruefung_am: e.target.value }))}
|
||||
InputLabelProps={{ shrink: true }}
|
||||
helperText="Wird als nächster Prüftermin übernommen"
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
|
||||
Reference in New Issue
Block a user