new features

This commit is contained in:
Matthias Hochmeister
2026-03-23 16:09:42 +01:00
parent e9a9478aac
commit 8c66492b27
40 changed files with 2016 additions and 117 deletions

View File

@@ -1339,11 +1339,20 @@ function VeranstaltungFormDialog({
anmeldung_erforderlich: editingEvent.anmeldung_erforderlich,
anmeldung_bis: null,
});
setWiederholungAktiv(false);
setWiederholungTyp('wöchentlich');
setWiederholungIntervall(1);
setWiederholungBis('');
setWiederholungWochentag(0);
// Populate recurrence fields if parent event has config (read-only display)
if (editingEvent.wiederholung) {
setWiederholungAktiv(true);
setWiederholungTyp(editingEvent.wiederholung.typ);
setWiederholungIntervall(editingEvent.wiederholung.intervall ?? 1);
setWiederholungBis(editingEvent.wiederholung.bis ?? '');
setWiederholungWochentag(editingEvent.wiederholung.wochentag ?? 0);
} else {
setWiederholungAktiv(false);
setWiederholungTyp('wöchentlich');
setWiederholungIntervall(1);
setWiederholungBis('');
setWiederholungWochentag(0);
}
} else {
const now = new Date();
now.setMinutes(0, 0, 0);
@@ -1358,6 +1367,29 @@ function VeranstaltungFormDialog({
}
}, [open, editingEvent]);
// Auto-correct: end date should never be before start date
useEffect(() => {
const von = new Date(form.datum_von);
const bis = new Date(form.datum_bis);
if (!isNaN(von.getTime()) && !isNaN(bis.getTime()) && bis < von) {
// Set datum_bis to datum_von (preserve time offset for non-ganztaegig)
if (form.ganztaegig) {
handleChange('datum_bis', von.toISOString());
} else {
const adjusted = new Date(von);
adjusted.setHours(adjusted.getHours() + 2);
handleChange('datum_bis', adjusted.toISOString());
}
}
// Also auto-correct wiederholungBis
if (wiederholungBis) {
const vonDateOnly = form.datum_von.slice(0, 10);
if (wiederholungBis < vonDateOnly) {
setWiederholungBis(vonDateOnly);
}
}
}, [form.datum_von]); // eslint-disable-line react-hooks/exhaustive-deps
const handleChange = (field: keyof CreateVeranstaltungInput, value: unknown) => {
if (field === 'kategorie_id' && !editingEvent) {
// Auto-fill zielgruppen / alle_gruppen from the selected category (only for new events)
@@ -1600,22 +1632,34 @@ function VeranstaltungFormDialog({
fullWidth
/>
)}
{/* Wiederholung (only for new events) */}
{!editingEvent && (
{/* Wiederholung */}
{(!editingEvent || (editingEvent && editingEvent.wiederholung)) && (
<>
<Divider />
<FormControlLabel
control={
<Switch
checked={wiederholungAktiv}
onChange={(e) => setWiederholungAktiv(e.target.checked)}
{editingEvent && editingEvent.wiederholung ? (
<>
<Typography variant="body2" color="text.secondary" sx={{ fontStyle: 'italic' }}>
Wiederholung kann nicht bearbeitet werden
</Typography>
<FormControlLabel
control={<Switch checked disabled />}
label="Wiederkehrende Veranstaltung"
/>
}
label="Wiederkehrende Veranstaltung"
/>
</>
) : (
<FormControlLabel
control={
<Switch
checked={wiederholungAktiv}
onChange={(e) => setWiederholungAktiv(e.target.checked)}
/>
}
label="Wiederkehrende Veranstaltung"
/>
)}
{wiederholungAktiv && (
<Stack spacing={2}>
<FormControl fullWidth size="small">
<FormControl fullWidth size="small" disabled={!!editingEvent}>
<InputLabel id="wiederholung-typ-label">Wiederholung</InputLabel>
<Select
labelId="wiederholung-typ-label"
@@ -1640,11 +1684,12 @@ function VeranstaltungFormDialog({
onChange={(e) => setWiederholungIntervall(Math.max(1, Math.min(52, parseInt(e.target.value) || 1)))}
inputProps={{ min: 1, max: 52 }}
fullWidth
disabled={!!editingEvent}
/>
)}
{(wiederholungTyp === 'monatlich_erster_wochentag' || wiederholungTyp === 'monatlich_letzter_wochentag') && (
<FormControl fullWidth size="small">
<FormControl fullWidth size="small" disabled={!!editingEvent}>
<InputLabel id="wiederholung-wochentag-label">Wochentag</InputLabel>
<Select
labelId="wiederholung-wochentag-label"
@@ -1667,6 +1712,7 @@ function VeranstaltungFormDialog({
onChange={(e) => setWiederholungBis(e.target.value)}
InputLabelProps={{ shrink: true }}
fullWidth
disabled={!!editingEvent}
helperText="Letztes Datum für Wiederholungen"
/>
</Stack>