diff --git a/frontend/Front.jsx b/frontend/Front.jsx index 4320953..53f56d5 100644 --- a/frontend/Front.jsx +++ b/frontend/Front.jsx @@ -429,9 +429,22 @@ export default function PickupDeliveryUI() { if (!deliveryRequestSet) return null; if (selectedCourierId === null) return deliveryRequestSet; - const targetId = String(selectedCourierId); const assignments = effectiveAssignments || {}; + if (selectedCourierId === 'unassigned') { + const filteredDemands = (deliveryRequestSet.demands || []).filter((demand) => { + const assignedCourierId = assignments[demand.id]; + return assignedCourierId === null || assignedCourierId === undefined; + }); + + return { + ...deliveryRequestSet, + demands: filteredDemands, + }; + } + + const targetId = String(selectedCourierId); + const filteredDemands = (deliveryRequestSet.demands || []).filter((demand) => { const assignedCourierId = assignments[demand.id]; if (assignedCourierId === null || assignedCourierId === undefined) { @@ -574,11 +587,14 @@ export default function PickupDeliveryUI() { try { setIsCalculatingTour(true); + const currentAssignment = demandAssignments?.[demandId]; + const contextCourier = + selectedCourierId === 'unassigned' ? null : selectedCourierId; await apiService.updateCourierAssignment({ demandId, newCourierId: targetCourierId !== null && targetCourierId !== undefined ? String(targetCourierId) : null, - oldCourierId: (demandAssignments?.[demandId] ?? selectedCourierId ?? null) !== null - ? String(demandAssignments?.[demandId] ?? selectedCourierId) + oldCourierId: (currentAssignment ?? contextCourier ?? null) !== null + ? String(currentAssignment ?? contextCourier) : null, deliveryIndex: null, }); @@ -1267,7 +1283,7 @@ export default function PickupDeliveryUI() { setSelectedCourierId(tour?.courierId || null)} + onTourSelect={(tour) => setSelectedCourierId(tour?.courierId ?? null)} demandAssignments={effectiveAssignments} unassignedDemands={effectiveUnassignedDemands} onReassignDemand={handleReassignDemand} diff --git a/frontend/src/components/Icon.jsx b/frontend/src/components/Icon.jsx index 6add0ca..7c860a0 100644 --- a/frontend/src/components/Icon.jsx +++ b/frontend/src/components/Icon.jsx @@ -38,6 +38,8 @@ const iconMap = { warning: faTriangleExclamation, success: faCircleCheck, error: faCircleXmark, + na: faCircleXmark, + 'x-circle': faCircleXmark, info: faCircleInfo, rocket: faRocket, box: faBox, diff --git a/frontend/src/components/TourTabs.jsx b/frontend/src/components/TourTabs.jsx index c985a82..b3a1bb3 100644 --- a/frontend/src/components/TourTabs.jsx +++ b/frontend/src/components/TourTabs.jsx @@ -66,6 +66,8 @@ export default function TourTabs({ if (onTourSelect) { if (courierId === null) { onTourSelect(null); // Vue globale : afficher tous les tours + } else if (courierId === 'unassigned') { + onTourSelect({ courierId: 'unassigned' }); } else { const selectedTour = displayTours.find(t => t.courierId === courierId); onTourSelect(selectedTour); @@ -142,6 +144,19 @@ export default function TourTabs({ return Array.from(union.values()); }, [allDemands, demandAssignments, unassignedDemands]); + const hasUnassigned = derivedUnassigned.length > 0; + + // Si l'onglet N/A est sélectionné mais qu'il n'y a plus de demandes non assignées, + // revenir automatiquement à la vue globale pour éviter un onglet vide. + useEffect(() => { + if (selectedCourierId === 'unassigned' && !hasUnassigned) { + setSelectedCourierId(null); + if (onTourSelect) { + onTourSelect(null); + } + } + }, [selectedCourierId, hasUnassigned, onTourSelect]); + const demandsForCourier = (courierId) => allDemands.filter((d) => (demandAssignments?.[d.id] ?? null) === courierId); @@ -184,9 +199,12 @@ export default function TourTabs({ setShowAssignModal(false); }; - const handleRemove = async (demand) => { + const handleRemove = async (demandOrId) => { if (!onRemoveDemand) return; - await onRemoveDemand(demand.id); + const demandId = + demandOrId && typeof demandOrId === 'object' ? demandOrId.id : demandOrId; + if (!demandId) return; + await onRemoveDemand(demandId); }; return ( @@ -234,6 +252,22 @@ export default function TourTabs({ Vue globale + {/* Onglet Non assignées (affiché uniquement s'il existe des demandes non assignées) */} + {hasUnassigned && ( + + )} {/* Onglets par coursier */} {displayTours.map(tour => ( @@ -278,6 +312,22 @@ export default function TourTabs({ /> )} + ) : selectedCourierId === 'unassigned' && hasUnassigned ? ( +
+
+ +

Demandes non assignées

+
+ +
) : (