Update site management to use service types instead of shift types

Introduces the ability to select service types when creating or editing sites, replacing the previous shift type field. It fetches available active service types from the API and displays them in a dropdown.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: e5565357-90e1-419f-b9a8-6ee8394636df
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/6d543d2c-20b9-4ea6-93fe-70fe9b1d9f80/e5565357-90e1-419f-b9a8-6ee8394636df/AXEqh9q
This commit is contained in:
marco370 2025-10-23 10:25:43 +00:00
parent 9ee37d8ea1
commit a48577c9b8

View File

@ -1,6 +1,6 @@
import { useState } from "react"; import { useState } from "react";
import { useQuery, useMutation } from "@tanstack/react-query"; import { useQuery, useMutation } from "@tanstack/react-query";
import { Site, InsertSite, Customer } from "@shared/schema"; import { Site, InsertSite, Customer, ServiceType } from "@shared/schema";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
@ -18,13 +18,6 @@ import { StatusBadge } from "@/components/status-badge";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
const shiftTypeLabels: Record<string, string> = {
fixed_post: "Presidio Fisso",
patrol: "Pattugliamento",
night_inspection: "Ispettorato Notturno",
quick_response: "Pronto Intervento",
};
const locationLabels: Record<string, string> = { const locationLabels: Record<string, string> = {
roccapiemonte: "Roccapiemonte", roccapiemonte: "Roccapiemonte",
milano: "Milano", milano: "Milano",
@ -44,6 +37,10 @@ export default function Sites() {
queryKey: ["/api/customers"], queryKey: ["/api/customers"],
}); });
const { data: serviceTypes } = useQuery<ServiceType[]>({
queryKey: ["/api/service-types"],
});
const form = useForm<InsertSite>({ const form = useForm<InsertSite>({
resolver: zodResolver(insertSiteSchema), resolver: zodResolver(insertSiteSchema),
defaultValues: { defaultValues: {
@ -51,7 +48,7 @@ export default function Sites() {
address: "", address: "",
customerId: undefined, customerId: undefined,
location: "roccapiemonte", location: "roccapiemonte",
shiftType: "fixed_post", serviceTypeId: undefined,
minGuards: 1, minGuards: 1,
requiresArmed: false, requiresArmed: false,
requiresDriverLicense: false, requiresDriverLicense: false,
@ -71,7 +68,7 @@ export default function Sites() {
address: "", address: "",
customerId: undefined, customerId: undefined,
location: "roccapiemonte", location: "roccapiemonte",
shiftType: "fixed_post", serviceTypeId: undefined,
minGuards: 1, minGuards: 1,
requiresArmed: false, requiresArmed: false,
requiresDriverLicense: false, requiresDriverLicense: false,
@ -145,7 +142,7 @@ export default function Sites() {
address: site.address, address: site.address,
customerId: site.customerId ?? undefined, customerId: site.customerId ?? undefined,
location: site.location, location: site.location,
shiftType: site.shiftType, serviceTypeId: site.serviceTypeId ?? undefined,
minGuards: site.minGuards, minGuards: site.minGuards,
requiresArmed: site.requiresArmed, requiresArmed: site.requiresArmed,
requiresDriverLicense: site.requiresDriverLicense, requiresDriverLicense: site.requiresDriverLicense,
@ -345,21 +342,22 @@ export default function Sites() {
<FormField <FormField
control={form.control} control={form.control}
name="shiftType" name="serviceTypeId"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Tipologia Servizio</FormLabel> <FormLabel>Tipologia Servizio (opzionale)</FormLabel>
<Select onValueChange={field.onChange} value={field.value ?? undefined}> <Select onValueChange={field.onChange} value={field.value ?? undefined}>
<FormControl> <FormControl>
<SelectTrigger data-testid="select-shift-type"> <SelectTrigger data-testid="select-service-type">
<SelectValue placeholder="Seleziona tipo servizio" /> <SelectValue placeholder="Seleziona tipo servizio" />
</SelectTrigger> </SelectTrigger>
</FormControl> </FormControl>
<SelectContent> <SelectContent>
<SelectItem value="fixed_post">Presidio Fisso</SelectItem> {serviceTypes?.filter(st => st.isActive).map((serviceType) => (
<SelectItem value="patrol">Pattugliamento</SelectItem> <SelectItem key={serviceType.id} value={serviceType.id}>
<SelectItem value="night_inspection">Ispettorato Notturno</SelectItem> {serviceType.label}
<SelectItem value="quick_response">Pronto Intervento</SelectItem> </SelectItem>
))}
</SelectContent> </SelectContent>
</Select> </Select>
<FormMessage /> <FormMessage />
@ -631,21 +629,22 @@ export default function Sites() {
<FormField <FormField
control={editForm.control} control={editForm.control}
name="shiftType" name="serviceTypeId"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Tipologia Servizio</FormLabel> <FormLabel>Tipologia Servizio (opzionale)</FormLabel>
<Select onValueChange={field.onChange} value={field.value ?? undefined}> <Select onValueChange={field.onChange} value={field.value ?? undefined}>
<FormControl> <FormControl>
<SelectTrigger data-testid="select-edit-shift-type"> <SelectTrigger data-testid="select-edit-service-type">
<SelectValue placeholder="Seleziona tipo servizio" /> <SelectValue placeholder="Seleziona tipo servizio" />
</SelectTrigger> </SelectTrigger>
</FormControl> </FormControl>
<SelectContent> <SelectContent>
<SelectItem value="fixed_post">Presidio Fisso</SelectItem> {serviceTypes?.filter(st => st.isActive).map((serviceType) => (
<SelectItem value="patrol">Pattugliamento</SelectItem> <SelectItem key={serviceType.id} value={serviceType.id}>
<SelectItem value="night_inspection">Ispettorato Notturno</SelectItem> {serviceType.label}
<SelectItem value="quick_response">Pronto Intervento</SelectItem> </SelectItem>
))}
</SelectContent> </SelectContent>
</Select> </Select>
<FormMessage /> <FormMessage />
@ -824,9 +823,14 @@ export default function Sites() {
</CardHeader> </CardHeader>
<CardContent className="space-y-3"> <CardContent className="space-y-3">
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
<Badge variant="outline"> {site.serviceTypeId && serviceTypes && (() => {
{shiftTypeLabels[site.shiftType]} const serviceType = serviceTypes.find(st => st.id === site.serviceTypeId);
return serviceType ? (
<Badge variant="outline" data-testid={`badge-service-type-${site.id}`}>
{serviceType.label}
</Badge> </Badge>
) : null;
})()}
{(() => { {(() => {
const status = getContractStatus(site); const status = getContractStatus(site);
const statusInfo = contractStatusLabels[status]; const statusInfo = contractStatusLabels[status];