diff --git a/client/src/pages/weekly-guards.tsx b/client/src/pages/weekly-guards.tsx index 924fd5b..5a7d62c 100644 --- a/client/src/pages/weekly-guards.tsx +++ b/client/src/pages/weekly-guards.tsx @@ -3,9 +3,12 @@ import { useQuery } from "@tanstack/react-query"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Button } from "@/components/ui/button"; -import { Calendar as CalendarIcon, ChevronLeft, ChevronRight, Users } from "lucide-react"; +import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"; +import { Badge } from "@/components/ui/badge"; +import { Calendar as CalendarIcon, ChevronLeft, ChevronRight, Users, Clock, MapPin, Navigation, ExternalLink } from "lucide-react"; import { format, parseISO, addDays, startOfWeek, addWeeks } from "date-fns"; import { it } from "date-fns/locale"; +import { Link } from "wouter"; type AbsenceType = "sick_leave" | "vacation" | "personal_leave" | "injury"; @@ -52,11 +55,19 @@ const ABSENCE_LABELS: Record = { injury: "Infortunio", }; +type DialogData = { + type: "fixed" | "mobile"; + guardName: string; + date: string; + data: any; +} | null; + export default function WeeklyGuards() { const [selectedLocation, setSelectedLocation] = useState("roccapiemonte"); const [currentWeekStart, setCurrentWeekStart] = useState(() => startOfWeek(new Date(), { weekStartsOn: 1 }) // Inizia lunedì ); + const [dialogData, setDialogData] = useState(null); const { data: scheduleData, isLoading } = useQuery({ queryKey: ["/api/weekly-guards-schedule", selectedLocation, format(currentWeekStart, "yyyy-MM-dd")], @@ -131,17 +142,18 @@ export default function WeeklyGuards() { setCurrentWeekStart(prev => addWeeks(prev, 1)); }; - const handleCellClick = (activity: ReturnType) => { - if (!activity) return; + const handleCellClick = (guardData: GuardScheduleData, activity: ReturnType, date: Date) => { + if (!activity || activity.type === "absence") return; - if (activity.type === "fixed") { - // TODO: Aprire dialog turno fisso - console.log("Open fixed shift dialog:", activity.data); - } else if (activity.type === "mobile") { - // TODO: Aprire dialog turno mobile - console.log("Open mobile shift dialog:", activity.data); - } - // Se absence, non fare nulla + const guardName = `${guardData.guard.lastName} ${guardData.guard.firstName}`; + const dateStr = format(date, "EEEE dd MMMM yyyy", { locale: it }); + + setDialogData({ + type: activity.type, + guardName, + date: dateStr, + data: activity.data, + }); }; return ( @@ -282,7 +294,7 @@ export default function WeeklyGuards() { variant="outline" size="sm" className="w-full h-auto text-xs px-2 py-1.5 whitespace-normal hover-elevate" - onClick={() => handleCellClick(activity)} + onClick={() => handleCellClick(guardData, activity, day)} data-testid={`button-shift-${guardData.guard.id}-${dayIndex}`} > {activity.label} @@ -310,6 +322,109 @@ export default function WeeklyGuards() { )} + + {/* Dialog Dettaglio Turno */} + setDialogData(null)}> + + + + {dialogData?.type === "fixed" ? ( + <> + + Turno Fisso - {dialogData.guardName} + + ) : ( + <> + + Turno Mobile - {dialogData.guardName} + + )} + + + {dialogData?.date} + + + + {dialogData && ( +
+ {dialogData.type === "fixed" ? ( + // Dettagli turno fisso +
+
+
+ Sito + {dialogData.data.siteName} +
+
+ Orario +
+ + {format(new Date(dialogData.data.plannedStartTime), "HH:mm")} - {format(new Date(dialogData.data.plannedEndTime), "HH:mm")} +
+
+
+ Durata + + {Math.round((new Date(dialogData.data.plannedEndTime).getTime() - new Date(dialogData.data.plannedStartTime).getTime()) / (1000 * 60 * 60))}h + +
+
+ +
+

+ Per modificare questo turno, vai alla pagina Planning Fissi +

+
+
+ ) : ( + // Dettagli turno mobile +
+
+
+ Tipo + Pattuglia +
+
+ Orario +
+ + {dialogData.data.startTime} - {dialogData.data.endTime} +
+
+
+ +
+

+ Per visualizzare il percorso completo e modificare il turno, vai alla pagina Planning Mobile +

+
+
+ )} +
+ )} + + + + {dialogData?.type === "fixed" ? ( + + + + ) : ( + + + + )} + +
+
); }