import { useState, useMemo } from 'react'; import { Autocomplete, Box, Button, Chip, Container, MenuItem, Tab, Tabs, TextField, Typography, } from '@mui/material'; import { Add as AddIcon } from '@mui/icons-material'; import CheckroomIcon from '@mui/icons-material/Checkroom'; import { useQuery } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import DashboardLayout from '../components/dashboard/DashboardLayout'; import { personalEquipmentApi } from '../services/personalEquipment'; import { ausruestungsanfrageApi } from '../services/ausruestungsanfrage'; import { membersService } from '../services/members'; import { usePermissionContext } from '../contexts/PermissionContext'; import ChatAwareFab from '../components/shared/ChatAwareFab'; import { PageHeader } from '../components/templates'; import { KatalogTab } from '../components/shared/KatalogTab'; import { ZUSTAND_LABELS, ZUSTAND_COLORS, } from '../types/personalEquipment.types'; import type { PersoenlicheAusruestungZustand } from '../types/personalEquipment.types'; const ZUSTAND_OPTIONS = Object.entries(ZUSTAND_LABELS) as [PersoenlicheAusruestungZustand, string][]; function PersoenlicheAusruestungPage() { const navigate = useNavigate(); const { hasPermission } = usePermissionContext(); const canViewAll = hasPermission('persoenliche_ausruestung:view_all'); const canCreate = hasPermission('persoenliche_ausruestung:create'); const canApprove = hasPermission('ausruestungsanfrage:approve'); const [activeTab, setActiveTab] = useState(0); const [filterZustand, setFilterZustand] = useState(''); const [filterUser, setFilterUser] = useState(''); const [search, setSearch] = useState(''); // Data queries const { data: items, isLoading } = useQuery({ queryKey: ['persoenliche-ausruestung', 'all'], queryFn: () => canViewAll ? personalEquipmentApi.getAll() : personalEquipmentApi.getMy(), staleTime: 2 * 60 * 1000, }); const { data: membersList } = useQuery({ queryKey: ['members-list-compact'], queryFn: () => membersService.getMembers({ pageSize: 500 }), staleTime: 5 * 60 * 1000, enabled: canViewAll, }); const { data: unassignedPositions, isLoading: unassignedLoading } = useQuery({ queryKey: ['ausruestungsanfrage', 'nicht-zugewiesen'], queryFn: () => ausruestungsanfrageApi.getUnassignedPositions(), staleTime: 2 * 60 * 1000, enabled: canApprove && activeTab === 2, }); const memberOptions = useMemo(() => { return (membersList?.items ?? []).map((m) => ({ id: m.id, name: [m.given_name, m.family_name].filter(Boolean).join(' ') || m.email, })); }, [membersList]); // Filter logic const filtered = useMemo(() => { let result = items ?? []; if (filterZustand) { result = result.filter((i) => i.zustand === filterZustand); } if (filterUser) { result = result.filter((i) => i.user_id === filterUser); } if (search.trim()) { const s = search.toLowerCase(); result = result.filter((i) => i.bezeichnung.toLowerCase().includes(s) || (i.kategorie ?? '').toLowerCase().includes(s) || (i.user_display_name ?? i.benutzer_name ?? '').toLowerCase().includes(s) ); } return result; }, [items, filterZustand, filterUser, search]); return ( setActiveTab(v)} sx={{ mb: 3 }}> {canApprove && } {activeTab === 0 && ( <> {/* Filters */} setSearch(e.target.value)} sx={{ minWidth: 200 }} /> setFilterZustand(e.target.value)} sx={{ minWidth: 140 }} > Alle {ZUSTAND_OPTIONS.map(([key, label]) => ( {label} ))} {canViewAll && ( o.name} value={memberOptions.find((m) => m.id === filterUser) ?? null} onChange={(_e, v) => setFilterUser(v?.id ?? '')} renderInput={(params) => } sx={{ minWidth: 200 }} /> )} {filtered.length} {filtered.length === 1 ? 'Eintrag' : 'Einträge'} {/* Table */} Bezeichnung Kategorie {canViewAll && Benutzer} Größe Zustand Anschaffung {isLoading ? ( Lade Daten… ) : filtered.length === 0 ? ( Keine Einträge gefunden ) : ( filtered.map((item) => ( navigate(`/persoenliche-ausruestung/${item.id}`)}> {item.bezeichnung} {item.artikel_bezeichnung && ( {item.artikel_bezeichnung} )} {item.eigenschaften && item.eigenschaften.length > 0 && ( {item.eigenschaften.map((e) => ( ))} )} {item.kategorie ?? '—'} {canViewAll && ( {item.user_display_name ?? item.benutzer_name ?? '—'} )} {item.groesse ?? '—'} {item.anschaffung_datum ? new Date(item.anschaffung_datum).toLocaleDateString('de-AT') : '—'} )) )} )} {activeTab === 1 && } {activeTab === 2 && canApprove && ( Bezeichnung Anfrage Für wen Im Katalog Aktion {unassignedLoading ? ( Lade Daten… ) : !unassignedPositions || unassignedPositions.length === 0 ? ( Alle Positionen sind zugewiesen ) : ( unassignedPositions.map((pos) => ( {pos.bezeichnung} navigate(`/ausruestungsanfrage/${pos.anfrage_id}`)} > {pos.anfrage_bezeichnung || (pos.bestell_jahr && pos.bestell_nummer ? `${pos.bestell_jahr}/${String(pos.bestell_nummer).padStart(3, '0')}` : `#${pos.anfrage_id}`)} {pos.fuer_wen || '—'} )) )} )} {/* FAB */} {canCreate && activeTab === 0 && ( navigate('/persoenliche-ausruestung/neu')} aria-label="Persönliche Ausrüstung hinzufügen" > )} ); } export default PersoenlicheAusruestungPage;