import { useState, useMemo, useEffect } from 'react'; import { Box, Tab, Tabs, Typography, Grid, Chip, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, TextField, MenuItem, } from '@mui/material'; import { Add as AddIcon } from '@mui/icons-material'; import { useQuery } from '@tanstack/react-query'; import { useSearchParams, useNavigate } from 'react-router-dom'; import DashboardLayout from '../components/dashboard/DashboardLayout'; import ChatAwareFab from '../components/shared/ChatAwareFab'; import { usePermissionContext } from '../contexts/PermissionContext'; import { ausruestungsanfrageApi } from '../services/ausruestungsanfrage'; import { KatalogTab } from '../components/shared/KatalogTab'; import { AUSRUESTUNG_STATUS_LABELS, AUSRUESTUNG_STATUS_COLORS } from '../types/ausruestungsanfrage.types'; import type { AusruestungAnfrageStatus, AusruestungAnfrage, AusruestungOverview, } from '../types/ausruestungsanfrage.types'; // ─── Helpers ───────────────────────────────────────────────────────────────── function formatOrderId(r: AusruestungAnfrage): string { if (r.bestell_jahr && r.bestell_nummer) { return `${r.bestell_jahr}/${String(r.bestell_nummer).padStart(3, '0')}`; } return `#${r.id}`; } const ACTIVE_STATUSES: AusruestungAnfrageStatus[] = ['offen', 'genehmigt', 'bestellt']; // ─── My Requests Tab ──────────────────────────────────────────────────────── function MeineAnfragenTab() { const { hasPermission } = usePermissionContext(); const navigate = useNavigate(); const canCreate = hasPermission('ausruestungsanfrage:create_request'); const [statusFilter, setStatusFilter] = useState(ACTIVE_STATUSES); const { data: requests = [], isLoading } = useQuery({ queryKey: ['ausruestungsanfrage', 'myRequests'], queryFn: () => ausruestungsanfrageApi.getMyRequests(), }); const filteredRequests = useMemo(() => { if (statusFilter.length === 0) return requests; return requests.filter(r => statusFilter.includes(r.status)); }, [requests, statusFilter]); const handleStatusFilterChange = (value: string) => { if (value === 'all') { setStatusFilter([]); } else if (value === 'active') { setStatusFilter(ACTIVE_STATUSES); } else { setStatusFilter([value as AusruestungAnfrageStatus]); } }; const currentFilterValue = useMemo(() => { if (statusFilter.length === 0) return 'all'; if (statusFilter.length === ACTIVE_STATUSES.length && ACTIVE_STATUSES.every(s => statusFilter.includes(s))) return 'active'; return statusFilter[0] || 'all'; }, [statusFilter]); if (isLoading) return Lade Anfragen...; return ( handleStatusFilterChange(e.target.value)} sx={{ minWidth: 200 }} > Aktive Anfragen Alle {(Object.keys(AUSRUESTUNG_STATUS_LABELS) as AusruestungAnfrageStatus[]).map(s => ( {AUSRUESTUNG_STATUS_LABELS[s]} ))} {filteredRequests.length === 0 ? ( Keine Anfragen vorhanden. ) : ( Anfrage ID Bezeichnung Status Im Haus Positionen Geliefert Erstellt am {filteredRequests.map(r => ( navigate('/ausruestungsanfrage/' + r.id)}> {formatOrderId(r)} {r.bezeichnung || '-'} {r.im_haus ? : null} {r.positionen_count ?? r.items_count ?? '-'} {r.positionen_count != null && r.positionen_count > 0 ? `${r.geliefert_count ?? 0}/${r.positionen_count}` : '-'} {new Date(r.erstellt_am).toLocaleDateString('de-AT')} ))}
)} {canCreate && ( navigate('/ausruestungsanfrage/neu')} aria-label="Neue Anfrage erstellen"> )}
); } // ─── Admin All Requests Tab (merged with overview) ────────────────────────── function AlleAnfragenTab() { const navigate = useNavigate(); const [statusFilter, setStatusFilter] = useState('alle'); const { data: requests = [], isLoading: requestsLoading, isError: requestsError } = useQuery({ queryKey: ['ausruestungsanfrage', 'allRequests', statusFilter], queryFn: () => ausruestungsanfrageApi.getRequests(statusFilter !== 'alle' ? { status: statusFilter } : undefined), }); const { data: overview } = useQuery({ queryKey: ['ausruestungsanfrage', 'overview-cards'], queryFn: () => ausruestungsanfrageApi.getOverview(), }); return ( {overview?.pending_count ?? '-'} Offene {overview?.approved_count ?? '-'} Genehmigte {overview?.unhandled_count ?? '-'} Neue (unbearbeitet) {overview?.total_items ?? '-'} Gesamt Artikel setStatusFilter(e.target.value)} sx={{ minWidth: 200, mb: 2 }} > Alle {(Object.keys(AUSRUESTUNG_STATUS_LABELS) as AusruestungAnfrageStatus[]).map(s => ( {AUSRUESTUNG_STATUS_LABELS[s]} ))} {requestsLoading ? ( Lade Anfragen... ) : requestsError ? ( Fehler beim Laden der Anfragen. ) : requests.length === 0 ? ( Keine Anfragen vorhanden. ) : ( Anfrage ID Bezeichnung Anfrage für Status Im Haus Positionen Geliefert Erstellt am {requests.map(r => ( navigate('/ausruestungsanfrage/' + r.id)}> {formatOrderId(r)} {r.bezeichnung || '-'} {r.fuer_benutzer_name || r.anfrager_name || r.anfrager_id} {r.im_haus ? : null} {r.positionen_count ?? r.items_count ?? '-'} {r.positionen_count != null && r.positionen_count > 0 ? `${r.geliefert_count ?? 0}/${r.positionen_count}` : '-'} {new Date(r.erstellt_am).toLocaleDateString('de-AT')} ))}
)}
); } // ─── Main Page ────────────────────────────────────────────────────────────── export default function Ausruestungsanfrage() { const [searchParams, setSearchParams] = useSearchParams(); const { hasPermission } = usePermissionContext(); const canView = hasPermission('ausruestungsanfrage:view'); const canCreate = hasPermission('ausruestungsanfrage:create_request'); const canApprove = hasPermission('ausruestungsanfrage:approve'); const tabCount = (canCreate ? 1 : 0) + (canApprove ? 1 : 0) + (canView ? 1 : 0); const [activeTab, setActiveTab] = useState(() => { const t = Number(searchParams.get('tab')); return t >= 0 && t < tabCount ? t : 0; }); useEffect(() => { const t = Number(searchParams.get('tab')); if (t >= 0 && t < tabCount) setActiveTab(t); }, [searchParams, tabCount]); const handleTabChange = (_: React.SyntheticEvent, val: number) => { setActiveTab(val); setSearchParams({ tab: String(val) }, { replace: true }); }; const tabIndex = useMemo(() => { const map: Record = {}; let next = 0; if (canCreate) { map.meine = next; next++; } if (canApprove) { map.alle = next; next++; } if (canView) { map.katalog = next; next++; } return map; }, [canCreate, canApprove, canView]); if (!canView && !canCreate && !canApprove) { return ( Keine Berechtigung. ); } return ( Interne Bestellungen {canCreate && } {canApprove && } {canView && } {canCreate && activeTab === tabIndex.meine && } {canApprove && activeTab === tabIndex.alle && } {canView && activeTab === tabIndex.katalog && } ); }