import { useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { useAuth } from "@/hooks/useAuth"; import { KPICard } from "@/components/kpi-card"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { StatusBadge } from "@/components/status-badge"; import { Users, Calendar, MapPin, AlertTriangle, Clock, CheckCircle, Building2 } from "lucide-react"; import { ShiftWithDetails, GuardWithCertifications, Site } from "@shared/schema"; import { formatDistanceToNow, format } from "date-fns"; import { it } from "date-fns/locale"; import { Skeleton } from "@/components/ui/skeleton"; export default function Dashboard() { const { user } = useAuth(); const [selectedLocation, setSelectedLocation] = useState("all"); const { data: shifts, isLoading: shiftsLoading } = useQuery({ queryKey: ["/api/shifts/active"], }); const { data: guards, isLoading: guardsLoading } = useQuery({ queryKey: ["/api/guards"], }); const { data: sites, isLoading: sitesLoading } = useQuery({ queryKey: ["/api/sites"], }); // Filter data by location const filteredGuards = selectedLocation === "all" ? guards : guards?.filter(g => g.location === selectedLocation); const filteredSites = selectedLocation === "all" ? sites : sites?.filter(s => s.location === selectedLocation); const filteredShifts = selectedLocation === "all" ? shifts : shifts?.filter(s => { const site = sites?.find(site => site.id === s.siteId); return site?.location === selectedLocation; }); // Calculate KPIs const activeShifts = filteredShifts?.filter(s => s.status === "active").length || 0; const totalGuards = filteredGuards?.length || 0; const activeSites = filteredSites?.filter(s => s.isActive).length || 0; // Expiring certifications (next 30 days) const expiringCerts = filteredGuards?.flatMap(g => g.certifications.filter(c => c.status === "expiring_soon") ).length || 0; const isLoading = shiftsLoading || guardsLoading || sitesLoading; const locationLabels: Record = { all: "Tutte le Sedi", roccapiemonte: "Roccapiemonte", milano: "Milano", roma: "Roma" }; return (

Dashboard Operativa

Benvenuto, {user?.firstName} {user?.lastName}

{/* KPI Cards */}
{isLoading ? ( <> ) : ( <> 0 ? "border-[hsl(25,90%,55%)]" : ""} data-testid="kpi-expiring-certs" /> )}
{/* Active Shifts */} Turni in Corso Servizi attualmente attivi {shiftsLoading ? (
) : filteredShifts && filteredShifts.length > 0 ? (
{filteredShifts.slice(0, 5).map((shift) => (

{shift.site.name}

{shift.assignments.length} guardie assegnate

{shift.status === "active" ? "Attivo" : "Pianificato"}
))}
) : (

Nessun turno attivo al momento

)}
{/* Alerts & Notifications */} Alert e Scadenze Certificazioni in scadenza prossimi 30 giorni {guardsLoading ? (
) : filteredGuards ? (
{filteredGuards .flatMap(guard => guard.certifications .filter(c => c.status === "expiring_soon" || c.status === "expired") .map(cert => ({ guard, cert })) ) .slice(0, 5) .map(({ guard, cert }) => (

{guard.user?.firstName} {guard.user?.lastName}

{cert.name} - Scade {format(new Date(cert.expiryDate), "dd/MM/yyyy")}

{cert.status === "expired" ? "Scaduto" : "In scadenza"}
))} {filteredGuards.flatMap(g => g.certifications.filter(c => c.status !== "valid")).length === 0 && (
Tutte le certificazioni sono valide
)}
) : null}
); }