import { useState, useMemo } from 'react'; import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TableSortLabel, Paper, TextField, Chip, Typography, CircularProgress, } from '@mui/material'; import { useQuery } from '@tanstack/react-query'; import { adminApi } from '../../services/admin'; import type { UserOverview } from '../../types/admin.types'; type SortKey = 'name' | 'email' | 'role' | 'is_active' | 'last_login_at'; type SortDir = 'asc' | 'desc'; function formatRelativeTime(dateStr: string | null): string { if (!dateStr) return 'Nie'; const date = new Date(dateStr); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffMins = Math.floor(diffMs / 60000); if (diffMins < 1) return 'Gerade eben'; if (diffMins < 60) return `vor ${diffMins}m`; const diffHours = Math.floor(diffMins / 60); if (diffHours < 24) return `vor ${diffHours}h`; const diffDays = Math.floor(diffHours / 24); return `vor ${diffDays}d`; } function UserOverviewTab() { const [search, setSearch] = useState(''); const [sortKey, setSortKey] = useState('name'); const [sortDir, setSortDir] = useState('asc'); const { data: users, isLoading, isError } = useQuery({ queryKey: ['admin', 'users'], queryFn: adminApi.getUsers, }); const handleSort = (key: SortKey) => { if (sortKey === key) { setSortDir(sortDir === 'asc' ? 'desc' : 'asc'); } else { setSortKey(key); setSortDir('asc'); } }; const filtered = useMemo(() => { if (!users) return []; const q = search.toLowerCase(); let result = users.filter( (u) => u.name?.toLowerCase().includes(q) || u.email?.toLowerCase().includes(q) ); result.sort((a, b) => { const valA = a[sortKey]; const valB = b[sortKey]; let cmp = 0; if (valA == null && valB == null) cmp = 0; else if (valA == null) cmp = -1; else if (valB == null) cmp = 1; else if (typeof valA === 'string' && typeof valB === 'string') { cmp = valA.localeCompare(valB); } else if (typeof valA === 'boolean' && typeof valB === 'boolean') { cmp = valA === valB ? 0 : valA ? 1 : -1; } return sortDir === 'asc' ? cmp : -cmp; }); return result; }, [users, search, sortKey, sortDir]); if (isLoading) { return ; } if (isError) { return ( Benutzerdaten konnten nicht geladen werden. Bitte versuchen Sie es später erneut. ); } return ( Benutzer ({filtered.length}) setSearch(e.target.value)} sx={{ minWidth: 280 }} /> handleSort('name')}> Name handleSort('email')}> E-Mail handleSort('role')}> Rolle Gruppen handleSort('is_active')}> Status handleSort('last_login_at')}> Letzter Login {filtered.map((user: UserOverview) => ( {user.name} {user.email} {(user.groups ?? []).map((g) => ( ))} {formatRelativeTime(user.last_login_at)} ))}
); } export default UserOverviewTab;