bug fixes

This commit is contained in:
Matthias Hochmeister
2026-03-03 11:45:08 +01:00
parent 3101f1a9c5
commit d91f757f34
12 changed files with 313 additions and 47 deletions

View File

@@ -79,6 +79,7 @@ import type {
VeranstaltungKategorie,
GroupInfo,
CreateVeranstaltungInput,
WiederholungConfig,
} from '../types/events.types';
import type {
FahrzeugBuchungListItem,
@@ -768,6 +769,11 @@ function VeranstaltungFormDialog({
const notification = useNotification();
const [loading, setLoading] = useState(false);
const [form, setForm] = useState<CreateVeranstaltungInput>({ ...EMPTY_VERANSTALTUNG_FORM });
const [wiederholungAktiv, setWiederholungAktiv] = useState(false);
const [wiederholungTyp, setWiederholungTyp] = useState<WiederholungConfig['typ']>('wöchentlich');
const [wiederholungIntervall, setWiederholungIntervall] = useState(1);
const [wiederholungBis, setWiederholungBis] = useState('');
const [wiederholungWochentag, setWiederholungWochentag] = useState(0);
useEffect(() => {
if (!open) return;
@@ -787,12 +793,22 @@ function VeranstaltungFormDialog({
anmeldung_erforderlich: editingEvent.anmeldung_erforderlich,
anmeldung_bis: null,
});
setWiederholungAktiv(false);
setWiederholungTyp('wöchentlich');
setWiederholungIntervall(1);
setWiederholungBis('');
setWiederholungWochentag(0);
} else {
const now = new Date();
now.setMinutes(0, 0, 0);
const later = new Date(now);
later.setHours(later.getHours() + 2);
setForm({ ...EMPTY_VERANSTALTUNG_FORM, datum_von: now.toISOString(), datum_bis: later.toISOString() });
setWiederholungAktiv(false);
setWiederholungTyp('wöchentlich');
setWiederholungIntervall(1);
setWiederholungBis('');
setWiederholungWochentag(0);
}
}, [open, editingEvent]);
@@ -816,12 +832,29 @@ function VeranstaltungFormDialog({
}
setLoading(true);
try {
const createPayload: CreateVeranstaltungInput = {
...form,
wiederholung: (!editingEvent && wiederholungAktiv && wiederholungBis)
? {
typ: wiederholungTyp,
bis: wiederholungBis,
intervall: wiederholungTyp === 'wöchentlich' ? wiederholungIntervall : undefined,
wochentag: (wiederholungTyp === 'monatlich_erster_wochentag' || wiederholungTyp === 'monatlich_letzter_wochentag')
? wiederholungWochentag
: undefined,
}
: null,
};
if (editingEvent) {
await eventsApi.updateEvent(editingEvent.id, form);
notification.showSuccess('Veranstaltung aktualisiert');
} else {
await eventsApi.createEvent(form);
notification.showSuccess('Veranstaltung erstellt');
await eventsApi.createEvent(createPayload);
notification.showSuccess(
wiederholungAktiv && wiederholungBis
? 'Veranstaltung und Wiederholungen erstellt'
: 'Veranstaltung erstellt'
);
}
onSaved();
onClose();
@@ -855,11 +888,14 @@ function VeranstaltungFormDialog({
fullWidth
/>
<FormControl fullWidth>
<InputLabel>Kategorie</InputLabel>
<InputLabel id="kategorie-select-label" shrink>Kategorie</InputLabel>
<Select
labelId="kategorie-select-label"
label="Kategorie"
value={form.kategorie_id ?? ''}
onChange={(e) => handleChange('kategorie_id', e.target.value || null)}
displayEmpty
notched
>
<MenuItem value=""><em>Keine Kategorie</em></MenuItem>
{kategorien.map((k) => (
@@ -975,6 +1011,79 @@ function VeranstaltungFormDialog({
fullWidth
/>
)}
{/* Wiederholung (only for new events) */}
{!editingEvent && (
<>
<Divider />
<FormControlLabel
control={
<Switch
checked={wiederholungAktiv}
onChange={(e) => setWiederholungAktiv(e.target.checked)}
/>
}
label="Wiederkehrende Veranstaltung"
/>
{wiederholungAktiv && (
<Stack spacing={2}>
<FormControl fullWidth size="small">
<InputLabel id="wiederholung-typ-label">Wiederholung</InputLabel>
<Select
labelId="wiederholung-typ-label"
label="Wiederholung"
value={wiederholungTyp}
onChange={(e) => setWiederholungTyp(e.target.value as WiederholungConfig['typ'])}
>
<MenuItem value="wöchentlich">Wöchentlich</MenuItem>
<MenuItem value="zweiwöchentlich">Vierzehntägig (alle 2 Wochen)</MenuItem>
<MenuItem value="monatlich_datum">Monatlich (gleicher Tag)</MenuItem>
<MenuItem value="monatlich_erster_wochentag">Monatlich (erster Wochentag)</MenuItem>
<MenuItem value="monatlich_letzter_wochentag">Monatlich (letzter Wochentag)</MenuItem>
</Select>
</FormControl>
{wiederholungTyp === 'wöchentlich' && (
<TextField
label="Intervall (Wochen)"
type="number"
size="small"
value={wiederholungIntervall}
onChange={(e) => setWiederholungIntervall(Math.max(1, Math.min(52, parseInt(e.target.value) || 1)))}
inputProps={{ min: 1, max: 52 }}
fullWidth
/>
)}
{(wiederholungTyp === 'monatlich_erster_wochentag' || wiederholungTyp === 'monatlich_letzter_wochentag') && (
<FormControl fullWidth size="small">
<InputLabel id="wiederholung-wochentag-label">Wochentag</InputLabel>
<Select
labelId="wiederholung-wochentag-label"
label="Wochentag"
value={wiederholungWochentag}
onChange={(e) => setWiederholungWochentag(Number(e.target.value))}
>
{['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'].map((d, i) => (
<MenuItem key={i} value={i}>{d}</MenuItem>
))}
</Select>
</FormControl>
)}
<TextField
label="Wiederholungen bis"
type="date"
size="small"
value={wiederholungBis}
onChange={(e) => setWiederholungBis(e.target.value)}
InputLabelProps={{ shrink: true }}
fullWidth
helperText="Letztes Datum für Wiederholungen"
/>
</Stack>
)}
</>
)}
</Stack>
</DialogContent>
<DialogActions>
@@ -1211,7 +1320,7 @@ export default function Kalender() {
setCancelEventGrund('');
loadCalendarData();
} catch (e: unknown) {
notification.showError(e instanceof Error ? e.message : 'Fehler beim Absagen');
notification.showError((e as any)?.message || 'Fehler beim Absagen');
} finally {
setCancelEventLoading(false);
}