import React, { useEffect, useState } from 'react'; import { Alert, AlertTitle, Box, CircularProgress, Link, Typography, } from '@mui/material'; import { Link as RouterLink } from 'react-router-dom'; import { equipmentApi } from '../../services/equipment'; import { AusruestungStatusLabel, AusruestungStatus, } from '../../types/equipment.types'; import type { EquipmentStats, AusruestungListItem, } from '../../types/equipment.types'; function formatDate(iso: string): string { return new Date(iso).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', }); } interface EquipmentAlertsProps { daysAhead?: number; hideWhenEmpty?: boolean; } interface AlertGroup { key: string; severity: 'error' | 'warning'; title: string; content: React.ReactNode; } const EquipmentAlerts: React.FC = ({ daysAhead = 30, hideWhenEmpty = true, }) => { const [stats, setStats] = useState(null); const [alerts, setAlerts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let mounted = true; const fetchData = async () => { try { setLoading(true); setError(null); const [statsData, alertsData] = await Promise.all([ equipmentApi.getStats(), equipmentApi.getAlerts(daysAhead), ]); if (mounted) { setStats(statsData); setAlerts(alertsData); } } catch { if (mounted) setError('Ausrüstungshinweise konnten nicht geladen werden.'); } finally { if (mounted) setLoading(false); } }; fetchData(); return () => { mounted = false; }; }, [daysAhead]); if (loading) { return ( Ausrüstungsstatus wird geprüft... ); } if (error) { return {error}; } if (!stats) return null; // Separate alerts into overdue vs. upcoming inspections const overdueItems = alerts.filter( (a) => a.pruefung_tage_bis_faelligkeit !== null && a.pruefung_tage_bis_faelligkeit < 0 ); const upcomingItems = alerts.filter( (a) => a.pruefung_tage_bis_faelligkeit !== null && a.pruefung_tage_bis_faelligkeit >= 0 ); // Build alert groups based on stats const groups: AlertGroup[] = []; // 1. Overdue inspections if (stats.inspectionsOverdue > 0 && overdueItems.length > 0) { groups.push({ key: 'overdue', severity: 'error', title: `Überfällige Prüfungen (${stats.inspectionsOverdue})`, content: ( {overdueItems.map((item) => { const tage = Math.abs(item.pruefung_tage_bis_faelligkeit!); const tageText = `seit ${tage} Tag${tage === 1 ? '' : 'en'} überfällig`; return ( {item.bezeichnung} {item.kategorie_kurzname ? ` (${item.kategorie_kurzname})` : ''} {' — '} {tageText} {item.naechste_pruefung_am ? ` (${formatDate(item.naechste_pruefung_am)})` : ''} ); })} ), }); } // 2. Important equipment not ready (affects vehicle readiness) if (stats.wichtigNichtBereit > 0) { groups.push({ key: 'wichtig', severity: 'error', title: `Wichtige Ausrüstung nicht einsatzbereit (${stats.wichtigNichtBereit})`, content: ( {stats.wichtigNichtBereit} wichtige{stats.wichtigNichtBereit === 1 ? 's' : ''} {' '}Ausrüstungsteil{stats.wichtigNichtBereit === 1 ? '' : 'e'} nicht einsatzbereit — Fahrzeugbereitschaft kann beeinträchtigt sein. ), }); } // 3. Damaged equipment if (stats.beschaedigt > 0) { groups.push({ key: 'beschaedigt', severity: 'error', title: `${AusruestungStatusLabel[AusruestungStatus.Beschaedigt]} (${stats.beschaedigt})`, content: ( {stats.beschaedigt} Ausrüstungsteil{stats.beschaedigt === 1 ? '' : 'e'}{' '} {stats.beschaedigt === 1 ? 'ist' : 'sind'} als{' '} {AusruestungStatusLabel[AusruestungStatus.Beschaedigt].toLowerCase()} gemeldet. ), }); } // 4. Upcoming inspections if (stats.inspectionsDue > 0 && upcomingItems.length > 0) { groups.push({ key: 'upcoming', severity: 'warning', title: `Prüfungen fällig in den nächsten ${daysAhead} Tagen (${stats.inspectionsDue})`, content: ( {upcomingItems.map((item) => { const tage = item.pruefung_tage_bis_faelligkeit!; const tageText = tage === 0 ? 'heute fällig' : `fällig in ${tage} Tag${tage === 1 ? '' : 'en'}`; return ( {item.bezeichnung} {item.kategorie_kurzname ? ` (${item.kategorie_kurzname})` : ''} {' — '} {tageText} {item.naechste_pruefung_am ? ` (${formatDate(item.naechste_pruefung_am)})` : ''} ); })} ), }); } // 5. In maintenance if (stats.inWartung > 0) { groups.push({ key: 'wartung', severity: 'warning', title: `${AusruestungStatusLabel[AusruestungStatus.InWartung]} (${stats.inWartung})`, content: ( {stats.inWartung} Ausrüstungsteil{stats.inWartung === 1 ? '' : 'e'}{' '} {stats.inWartung === 1 ? 'befindet' : 'befinden'} sich derzeit in Wartung. ), }); } // Nothing to show if (groups.length === 0) { if (hideWhenEmpty) return null; return ( Alle Ausrüstung ist einsatzbereit. Keine Auffälligkeiten in den nächsten{' '} {daysAhead} Tagen. ); } return ( {groups.map(({ key, severity, title, content }) => ( {title} {content} ))} ); }; export default EquipmentAlerts;