import { useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Calendar, MapPin, User, Car, Clock } from "lucide-react"; import { format, parseISO, isValid } from "date-fns"; import { it } from "date-fns/locale"; type Location = "roccapiemonte" | "milano" | "roma"; type MobileSite = { id: string; name: string; address: string; city: string; serviceTypeId: string; serviceTypeName: string; location: Location; latitude: number | null; longitude: number | null; }; type AvailableGuard = { id: string; firstName: string; lastName: string; badgeNumber: string; location: Location; weeklyHours: number; availableHours: number; }; export default function PlanningMobile() { const [selectedDate, setSelectedDate] = useState(format(new Date(), "yyyy-MM-dd")); const [selectedLocation, setSelectedLocation] = useState("roccapiemonte"); const [selectedGuardId, setSelectedGuardId] = useState(""); // Query siti mobile per location const { data: mobileSites, isLoading: sitesLoading } = useQuery({ queryKey: ["/api/planning-mobile/sites", selectedLocation], queryFn: async () => { const response = await fetch(`/api/planning-mobile/sites?location=${selectedLocation}`); if (!response.ok) { throw new Error("Failed to fetch mobile sites"); } return response.json(); }, enabled: !!selectedLocation, }); // Query guardie disponibili per location e data const { data: availableGuards, isLoading: guardsLoading } = useQuery({ queryKey: ["/api/planning-mobile/guards", selectedLocation, selectedDate], queryFn: async () => { const response = await fetch(`/api/planning-mobile/guards?location=${selectedLocation}&date=${selectedDate}`); if (!response.ok) { throw new Error("Failed to fetch available guards"); } return response.json(); }, enabled: !!selectedLocation && !!selectedDate, }); const locationLabels: Record = { roccapiemonte: "Roccapiemonte", milano: "Milano", roma: "Roma", }; const locationColors: Record = { roccapiemonte: "bg-blue-500", milano: "bg-green-500", roma: "bg-purple-500", }; return (
{/* Header */}

Planning Mobile

Pianificazione ronde, ispezioni e interventi notturni per servizi mobili

{/* Filtri */} Filtri Pianificazione Seleziona sede, data e guardia per iniziare
setSelectedDate(e.target.value)} data-testid="input-mobile-date" />
{/* Grid: Mappa + Siti */}
{/* Mappa Siti */} Mappa Siti Mobile {mobileSites?.length || 0} siti con servizi mobili in {locationLabels[selectedLocation]}

Integrazione mappa in sviluppo
(Leaflet/Google Maps)

{/* Lista Siti Mobile */} Siti con Servizi Mobili Ronde notturne, ispezioni, interventi programmati {sitesLoading ? (

Caricamento...

) : mobileSites && mobileSites.length > 0 ? ( mobileSites.map((site) => (

{site.name}

{site.address}, {site.city}

{locationLabels[site.location]}
{site.serviceTypeName}
)) ) : (

Nessun sito con servizi mobili in {locationLabels[selectedLocation]}

)}
{/* Guardie Disponibili */} Guardie Disponibili ({availableGuards?.length || 0}) Guardie con ore disponibili per {format(parseISO(selectedDate), "dd MMMM yyyy", { locale: it })}
{guardsLoading ? (

Caricamento...

) : availableGuards && availableGuards.length > 0 ? ( availableGuards.map((guard) => (
{guard.firstName} {guard.lastName}

#{guard.badgeNumber}

{locationLabels[guard.location]}
Ore settimanali: {guard.weeklyHours}h / 45h
Disponibili: {guard.availableHours}h
)) ) : (

Nessuna guardia disponibile per la data selezionata

)}
); }