diff --git a/client/src/pages/SavTickets.tsx b/client/src/pages/SavTickets.tsx index b74b162..e631de6 100644 --- a/client/src/pages/SavTickets.tsx +++ b/client/src/pages/SavTickets.tsx @@ -190,6 +190,38 @@ export default function SavTickets() { }, }); + // Update ticket status/priority mutation + const updateTicketMutation = useMutation({ + mutationFn: async (data: { ticketId: number; status?: string; priority?: string; resolutionDescription?: string }) => { + const response = await apiRequest(`/api/sav/tickets/${data.ticketId}`, "PATCH", { + status: data.status, + priority: data.priority, + resolutionDescription: data.resolutionDescription, + }); + return response; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['/api/sav/tickets'] }); + queryClient.invalidateQueries({ queryKey: ['/api/sav/stats'] }); + if (selectedTicket) { + queryClient.invalidateQueries({ queryKey: [`/api/sav/tickets/${selectedTicket.id}`] }); + } + setTempStatus(""); + setTempPriority(""); + toast({ + title: "Ticket mis à jour", + description: "Le statut du ticket a été modifié avec succès.", + }); + }, + onError: (error: any) => { + toast({ + title: "Erreur", + description: error?.message || "Impossible de modifier le ticket.", + variant: "destructive", + }); + }, + }); + // Delete ticket mutation const deleteTicketMutation = useMutation({ mutationFn: async (ticketId: number) => { @@ -263,7 +295,7 @@ export default function SavTickets() { problemDescription: formData.problemDescription, priority: formData.priority as "faible" | "normale" | "haute" | "critique", status: "nouveau" as const, - createdBy: 1, // Will be set by the backend from session + createdBy: "1", // Will be set by the backend from session clientName: formData.clientName || undefined, clientPhone: formData.clientPhone || undefined, }; @@ -285,6 +317,20 @@ export default function SavTickets() { staleTime: 0, // Toujours récupérer les derniers commentaires }); + // Function to check if ticket has recent comments (last 24h) + const hasRecentComments = (ticket: SavTicketWithRelations) => { + if (!ticket.history || ticket.history.length === 0) return false; + + const oneDayAgo = new Date(); + oneDayAgo.setDate(oneDayAgo.getDate() - 1); + + return ticket.history.some(entry => + entry.action === 'comment' && + entry.createdAt && + new Date(entry.createdAt) > oneDayAgo + ); + }; + // Handle editing ticket const handleEditTicket = (ticket: SavTicketWithRelations) => { setSelectedTicket(ticket); @@ -370,160 +416,200 @@ export default function SavTickets() { -
- {/* Informations produit */} -
-

Informations produit

- -
- - setFormData({...formData, productGencode: e.target.value})} - placeholder="Code-barres du produit" - /> -
- -
- - setFormData({...formData, productReference: e.target.value})} - placeholder="Référence du produit" - /> -
- -
- - setFormData({...formData, productDesignation: e.target.value})} - placeholder="Nom/désignation du produit" - /> -
- -
- - -
- - {availableGroups.length > 1 && ( -
- - -
- )} - - {availableGroups.length === 1 && ( -
- -
- - {availableGroups[0].name} +
+ {/* Section Informations Produit */} + + + + + Informations Produit + + + Détails du produit concerné par le SAV + + + +
+
+ + setFormData({...formData, productGencode: e.target.value})} + placeholder="Code-barres du produit" + /> +
+ +
+ + setFormData({...formData, productReference: e.target.value})} + placeholder="Référence du produit" + />
- )} - - {availableGroups.length === 0 && ( +
- -
- Aucun magasin assigné. Contactez un administrateur. -
+ + setFormData({...formData, productDesignation: e.target.value})} + placeholder="Nom/désignation du produit" + />
- )} -
+ +
+
+ + +
+ + {availableGroups.length > 1 && ( +
+ + +
+ )} +
+ + {availableGroups.length === 1 && ( +
+ +
+ + {availableGroups[0].name} +
+
+ )} + + {availableGroups.length === 0 && ( +
+ +
+ Aucun magasin assigné. Contactez un administrateur. +
+
+ )} + + - {/* Informations problème et client */} -
-

Problème et client

- -
- - -
- -
- - -
- -
- -