diff --git a/src/pages/nearle/dispatch/Dispatch.js b/src/pages/nearle/dispatch/Dispatch.js
index 791f9ec..774b763 100644
--- a/src/pages/nearle/dispatch/Dispatch.js
+++ b/src/pages/nearle/dispatch/Dispatch.js
@@ -785,11 +785,7 @@ const Dispatch = ({
selectedRiderId,
onRiderSelect,
// Highlight a single marker (e.g. on table-row hover). Adds a `.pulse` class to that cmark.
- pulseOrderId,
- // Optional. When provided, focused-rider order cards render a small "change rider"
- // icon in their header. Receiving callsite owns the rider-picker dialog. Standalone
- // /dispatch usage leaves this undefined so the icon never appears there.
- onChangeRider
+ pulseOrderId
}) => {
// Default to "By Zone" when the caller passes pre-zoned data (AI preview); fall back to
// "By Rider" for the standalone live page where zones are synthesized but riders are primary.
@@ -4131,19 +4127,6 @@ const Dispatch = ({
);
})()}
- {onChangeRider && (
-
- )}
diff --git a/src/pages/nearle/dispatch/Preview.js b/src/pages/nearle/dispatch/Preview.js
index 0f3999a..c372f8f 100644
--- a/src/pages/nearle/dispatch/Preview.js
+++ b/src/pages/nearle/dispatch/Preview.js
@@ -1,35 +1,28 @@
import React, { useEffect, useMemo, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import {
- Autocomplete,
Backdrop,
Box,
Button,
Card,
Chip,
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
IconButton,
Stack,
Tab,
Tabs,
- TextField,
Tooltip,
Typography
} from '@mui/material';
-import { useMutation, useQuery } from '@tanstack/react-query';
+import { useMutation } from '@tanstack/react-query';
import dayjs from 'dayjs';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import { HiOutlineArrowLeft } from 'react-icons/hi';
import { IoReload } from 'react-icons/io5';
-import { MdTwoWheeler, MdSwapHoriz } from 'react-icons/md';
+import { MdTwoWheeler } from 'react-icons/md';
import {
createAutomationDeliveries,
createOptimisationDeliveries,
- fetchRidersList,
finalCreatedeliveries,
notifyRider,
reconcileSteps
@@ -117,78 +110,6 @@ const flattenRiders = (riders) => {
return out;
};
-// Move one order from oldRiderId -> newRiderId inside dispatchPreviewData.
-// Mutates both the zones[].riders[].orders[] tree (so the Dispatch tab
-// renders the change) AND the flat details[] list (so Assign Orders picks
-// it up). Returns a NEW preview object (immutable update).
-const moveOrderInPreviewData = (preview, { orderId, newRiderId, newRiderName }) => {
- if (!preview) return preview;
- const next = JSON.parse(JSON.stringify(preview));
-
- // 1) Update flat details list
- if (Array.isArray(next.details)) {
- next.details = next.details.map((o) =>
- String(o.orderid) === String(orderId)
- ? { ...o, rider_id: newRiderId, userid: newRiderId, rider_name: newRiderName, rider: newRiderName }
- : o
- );
- }
-
- // 2) Move within zones[].riders[].orders[]
- if (Array.isArray(next.zones)) {
- let movedOrder = null;
- let homeZoneIdx = -1;
-
- for (let zi = 0; zi < next.zones.length && !movedOrder; zi++) {
- const zone = next.zones[zi];
- if (!Array.isArray(zone.riders)) continue;
- for (let ri = 0; ri < zone.riders.length && !movedOrder; ri++) {
- const r = zone.riders[ri];
- if (!Array.isArray(r.orders)) continue;
- const oi = r.orders.findIndex((o) => String(o.orderid) === String(orderId));
- if (oi !== -1) {
- movedOrder = r.orders[oi];
- r.orders.splice(oi, 1);
- homeZoneIdx = zi;
- }
- }
- }
-
- if (movedOrder) {
- const updated = {
- ...movedOrder,
- rider_id: newRiderId,
- userid: newRiderId,
- rider_name: newRiderName,
- rider: newRiderName
- };
- let placed = false;
- for (const zone of next.zones) {
- if (!Array.isArray(zone.riders)) continue;
- const target = zone.riders.find(
- (r) => String(r.rider_id ?? r.userid) === String(newRiderId)
- );
- if (target) {
- target.orders = target.orders || [];
- target.orders.push(updated);
- placed = true;
- break;
- }
- }
- if (!placed && homeZoneIdx >= 0) {
- next.zones[homeZoneIdx].riders.push({
- rider_id: newRiderId,
- userid: newRiderId,
- rider_name: newRiderName,
- orders: [updated]
- });
- }
- }
- }
-
- return next;
-};
-
// Merge a reconcile-API response { riders:[{rider_id, orders}] } back into
// dispatchPreviewData. Replaces each rider's orders[] in zones (preserving
// zone containment), then rebuilds the flat details list from the new tree.
@@ -319,12 +240,6 @@ const Preview = () => {
// server-side step re-ordering only needs to see what actually changed.
const [dirtyRiderIds, setDirtyRiderIds] = useState(() => new Set());
- // Change-rider dialog state
- const [changeDialogOpen, setChangeDialogOpen] = useState(false);
- const [selectedOrder, setSelectedOrder] = useState(null);
- const [selectedOldRiderId, setSelectedOldRiderId] = useState(null);
- const [selectedNewRider, setSelectedNewRider] = useState(null);
-
const aiMode = stateData.aiMode ?? 1;
const selectedMode = stateData.selectedMode || null;
const deliveryData = stateData.deliveryData || [];
@@ -341,16 +256,8 @@ const Preview = () => {
return 0;
}, [stateData.appId]);
- const { data: ridersList } = useQuery({
- queryKey: ['ridersList', appId],
- queryFn: fetchRidersList,
- enabled: !!appId,
- staleTime: 5 * 60 * 1000
- });
-
// Derived: rider list for the Reconcile tab. Recomputes whenever the cache
- // (dispatchPreviewData) changes — so Change Rider / Reconcile both reflect
- // here without a separate state.
+ // (dispatchPreviewData) changes — so Reconcile reflects here without a separate state.
const reconcileRiders = useMemo(() => extractRiders(dispatchPreviewData), [dispatchPreviewData]);
// Derived: flat orders list used for the Assign Orders payload + CSV export.
@@ -508,47 +415,6 @@ const Preview = () => {
});
};
- const openChangeRider = (oldRider, order) => {
- const oldId =
- oldRider?.rider_id ?? oldRider?.id ?? order?.rider_id ?? order?.userid ?? null;
- setSelectedOldRiderId(oldId);
- setSelectedOrder(order);
- setSelectedNewRider(null);
- setChangeDialogOpen(true);
- };
-
- const confirmChangeRider = () => {
- if (!selectedNewRider || !selectedOrder) return;
- // Backend expects an int — coerce at the boundary so a string from the
- // riders API doesn't propagate into the Assign Orders payload.
- const newRiderId = Number(selectedNewRider.userid);
- const newRiderName =
- selectedNewRider.label ||
- `${selectedNewRider.firstname || ''} ${selectedNewRider.lastname || ''}`.trim() ||
- `Rider ${newRiderId}`;
-
- setDispatchPreviewData((prev) =>
- moveOrderInPreviewData(prev, {
- orderId: selectedOrder.orderid,
- oldRiderId: selectedOldRiderId,
- newRiderId,
- newRiderName
- })
- );
- // Both riders' step sequences are now potentially stale: the old rider
- // lost a stop, the new rider gained one. Mark both as dirty so the next
- // Reconcile sends exactly these two.
- setDirtyRiderIds((prev) => {
- const next = new Set(prev);
- if (selectedOldRiderId != null) next.add(String(selectedOldRiderId));
- if (newRiderId != null && Number.isFinite(newRiderId)) next.add(String(newRiderId));
- return next;
- });
- setHasReconciled(false);
- setChangeDialogOpen(false);
- OpenToast('Rider changed — click Reconcile to verify steps', 'info', 2500);
- };
-
return (
{
{dispatchPreviewData && (
openChangeRider(focusedRider, order)}
/>
)}
-
);
};