diff --git a/frontend/src/pages/Atemschutz.tsx b/frontend/src/pages/Atemschutz.tsx
index fbbc034..a4643ad 100644
--- a/frontend/src/pages/Atemschutz.tsx
+++ b/frontend/src/pages/Atemschutz.tsx
@@ -183,20 +183,25 @@ function Atemschutz() {
try {
setLoading(true);
setError(null);
- const [traegerData, statsData, membersData] = await Promise.all([
- atemschutzApi.getAll(),
- atemschutzApi.getStats(),
- membersService.getMembers({ pageSize: 500 }),
- ]);
- setTraeger(traegerData);
- setStats(statsData);
- setMembers(membersData.items);
+ if (canViewAll) {
+ const [traegerData, statsData, membersData] = await Promise.all([
+ atemschutzApi.getAll(),
+ atemschutzApi.getStats(),
+ membersService.getMembers({ pageSize: 500 }),
+ ]);
+ setTraeger(traegerData);
+ setStats(statsData);
+ setMembers(membersData.items);
+ } else {
+ const traegerData = await atemschutzApi.getAll();
+ setTraeger(traegerData);
+ }
} catch {
setError('Atemschutzdaten konnten nicht geladen werden. Bitte versuchen Sie es erneut.');
} finally {
setLoading(false);
}
- }, []);
+ }, [canViewAll]);
useEffect(() => {
fetchData();
@@ -361,6 +366,11 @@ function Atemschutz() {
Atemschutzverwaltung
+ {!loading && !canViewAll && (
+
+ Dein persönlicher Atemschutz-Status
+
+ )}
{!loading && stats && canViewAll && (
@@ -471,7 +481,7 @@ function Atemschutz() {
Untersuchung gültig bis
Leistungstest gültig bis
Status
- Aktionen
+ {canWrite && Aktionen}
@@ -549,31 +559,29 @@ function Atemschutz() {
variant="filled"
/>
-
- {canWrite && (
-
-
-
- )}
- {canWrite && (
-
-
-
- )}
-
+ {canWrite && (
+
+
+
+
+
+
+
+
+ )}
);
})}
diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx
index fe20683..bce7f99 100644
--- a/frontend/src/pages/Dashboard.tsx
+++ b/frontend/src/pages/Dashboard.tsx
@@ -33,7 +33,7 @@ function Dashboard() {
void;
onTrainingClick: (id: string) => void;
onEventEdit: (ev: VeranstaltungListItem) => void;
+ onEventDelete: (id: string) => void;
}
function DayPopover({
anchorEl, day, trainingForDay, eventsForDay,
- canWriteEvents, onClose, onTrainingClick, onEventEdit,
+ canWriteEvents, onClose, onTrainingClick, onEventEdit, onEventDelete,
}: DayPopoverProps) {
if (!day) return null;
const hasContent = trainingForDay.length > 0 || eventsForDay.length > 0;
@@ -589,6 +591,15 @@ function DayPopover({
)}
+ {canWriteEvents && (
+ { onEventDelete(ev.id); onClose(); }}
+ >
+
+
+ )}
))}
@@ -610,11 +621,12 @@ interface CombinedListViewProps {
onTrainingClick: (id: string) => void;
onEventEdit: (ev: VeranstaltungListItem) => void;
onEventCancel: (id: string) => void;
+ onEventDelete: (id: string) => void;
}
function CombinedListView({
trainingEvents, veranstaltungen, selectedKategorie,
- canWriteEvents, onTrainingClick, onEventEdit, onEventCancel,
+ canWriteEvents, onTrainingClick, onEventEdit, onEventCancel, onEventDelete,
}: CombinedListViewProps) {
type ListEntry =
| { kind: 'training'; item: UebungListItem }
@@ -742,6 +754,18 @@ function CombinedListView({
)}
+ {!isTraining && canWriteEvents && (
+
+ onEventDelete(item.id)}
+ title="Endgültig löschen"
+ >
+
+
+
+ )}
);
@@ -1141,6 +1165,8 @@ export default function Kalender() {
const [cancelEventId, setCancelEventId] = useState(null);
const [cancelEventGrund, setCancelEventGrund] = useState('');
const [cancelEventLoading, setCancelEventLoading] = useState(false);
+ const [deleteEventId, setDeleteEventId] = useState(null);
+ const [deleteEventLoading, setDeleteEventLoading] = useState(false);
// ── Bookings tab state ───────────────────────────────────────────────────────
const [currentWeekStart, setCurrentWeekStart] = useState(() =>
@@ -1326,6 +1352,21 @@ export default function Kalender() {
}
};
+ const handleDeleteEvent = async () => {
+ if (!deleteEventId) return;
+ setDeleteEventLoading(true);
+ try {
+ await eventsApi.deleteEvent(deleteEventId);
+ notification.showSuccess('Veranstaltung wurde endgültig gelöscht');
+ setDeleteEventId(null);
+ loadCalendarData();
+ } catch (e: unknown) {
+ notification.showError((e as any)?.message || 'Fehler beim Löschen');
+ } finally {
+ setDeleteEventLoading(false);
+ }
+ };
+
// ── Booking helpers ──────────────────────────────────────────────────────────
const getBookingsForCell = (vehicleId: string, day: Date): FahrzeugBuchungListItem[] =>
@@ -1642,6 +1683,7 @@ export default function Kalender() {
setCancelEventId(id);
setCancelEventGrund('');
}}
+ onEventDelete={(id) => setDeleteEventId(id)}
/>
)}
@@ -1673,6 +1715,7 @@ export default function Kalender() {
setVeranstEditing(ev);
setVeranstFormOpen(true);
}}
+ onEventDelete={(id) => setDeleteEventId(id)}
/>
{/* Veranstaltung Form Dialog */}
@@ -1720,6 +1763,34 @@ export default function Kalender() {
+ {/* Endgültig löschen Dialog */}
+
+
{/* iCal Event subscription dialog */}