diff --git a/apps/shopify-app/app/features/delivery/route-detail-map.js b/apps/shopify-app/app/features/delivery/route-detail-map.js index 2cb7f63..ef97ae4 100644 --- a/apps/shopify-app/app/features/delivery/route-detail-map.js +++ b/apps/shopify-app/app/features/delivery/route-detail-map.js @@ -874,7 +874,7 @@ function buildRouteDetailMarkerFeatureCollection(departureLocation, routeStops, }, properties: { featureType: "routeStop", - isCompleted: Boolean(stop.isTrackingCompleted || isRouteStopCompleted(stop)), + isCompleted: Boolean(stop.isTrackingCompleted), orderId: stop.orderId ?? "", pinImage: getRouteDetailStopPinImageId(stop, stopColor), sortKey: stop.isPolygonSelected ? 3000 : 1000 - stop.stop, diff --git a/apps/shopify-app/app/routes/app.routes.$routeId.jsx b/apps/shopify-app/app/routes/app.routes.$routeId.jsx index 3d09953..d3e145f 100644 --- a/apps/shopify-app/app/routes/app.routes.$routeId.jsx +++ b/apps/shopify-app/app/routes/app.routes.$routeId.jsx @@ -2948,19 +2948,10 @@ export default function RouteDetailPage() { () => new Set(isPolygonTargetPickerOpen ? polygonSelectedOrderIds : polygonCandidateOrderIds), [isPolygonTargetPickerOpen, polygonCandidateOrderIds, polygonSelectedOrderIds], ); - const completedTrackingStopIds = useMemo(() => { - const completedStopIds = new Set(routeTrackingProgress?.completedStopIds ?? []); - for (const routeRow of timelineRouteRows) { - for (const stop of routeRow.stops) { - if ([stop.status, stop.deliveryStatus, stop.deliveryStopStatus] - .some((status) => ["COMPLETED", "DELIVERED", "FULFILLED"].includes(String(status ?? "").toUpperCase()))) { - if (stop.id) completedStopIds.add(stop.id); - if (stop.deliveryStopId) completedStopIds.add(stop.deliveryStopId); - } - } - } - return completedStopIds; - }, [routeTrackingProgress?.completedStopIds, timelineRouteRows]); + const completedTrackingStopIds = useMemo( + () => new Set(routeTrackingProgress?.completedStopIds ?? []), + [routeTrackingProgress?.completedStopIds], + ); const routeStopColorById = useMemo(() => new Map(timelineRouteRows.flatMap((routeRow) => ( routeRow.stops.flatMap((stop) => { return [ @@ -5597,7 +5588,9 @@ export default function RouteDetailPage() { > {row.stop} {row.order} {getLiveTrackingStopStatus(row, routeTrackingProgress)} diff --git a/apps/shopify-app/tests/route-detail-map-behavior.test.mjs b/apps/shopify-app/tests/route-detail-map-behavior.test.mjs index 4840f9d..786a0c7 100644 --- a/apps/shopify-app/tests/route-detail-map-behavior.test.mjs +++ b/apps/shopify-app/tests/route-detail-map-behavior.test.mjs @@ -98,6 +98,24 @@ test("Tracking completion preserves the route-colored marker and exposes badge s assert.equal(markerData.features[0].properties.pinImage, "route-detail-stop-pin-006fbb-3"); }); +test("persisted delivery status does not create a Tracking completion badge", () => { + const markerData = buildRouteDetailMarkerFeatureCollection(null, [{ + coordinates: [126.927, 37.512], + deliveryStopId: "stop-4", + hasCoordinates: true, + id: "order-4", + isTrackingCompleted: false, + preserveRouteColor: true, + routeColor: "#006fbb", + status: "DELIVERED", + stop: 4, + }], [], "#e11900", new Map()); + + assert.equal(markerData.features.length, 1); + assert.equal(markerData.features[0].properties.isCompleted, false); + assert.equal(markerData.features[0].properties.pinImage, "route-detail-stop-pin-006fbb-4"); +}); + test("Tracking planned route remains a solid, visible reference under dashed GPS", () => { const fake = createFakeMap(); const routeGeometry = { diff --git a/apps/shopify-app/tests/route-tracking-live.test.mjs b/apps/shopify-app/tests/route-tracking-live.test.mjs index 68850ef..a22ea41 100644 --- a/apps/shopify-app/tests/route-tracking-live.test.mjs +++ b/apps/shopify-app/tests/route-tracking-live.test.mjs @@ -132,14 +132,17 @@ test("live tracking updates MapLibre sources instead of rebuilding the child map assert.match(routeMapSource, /ROUTE_DETAIL_COMPLETED_STOP_COLOR/); assert.match(routeMapSource, /const ROUTE_DETAIL_STOP_COMPLETION_BADGE_LAYER_ID/); assert.match(routeMapSource, /const ROUTE_DETAIL_STOP_COMPLETION_CHECK_LAYER_ID/); - assert.match(routeMapSource, /isCompleted: Boolean\(stop\.isTrackingCompleted \|\| isRouteStopCompleted\(stop\)\)/); + assert.match(routeMapSource, /isCompleted: Boolean\(stop\.isTrackingCompleted\)/); + assert.doesNotMatch(routeMapSource, /isCompleted: Boolean\(stop\.isTrackingCompleted \|\| isRouteStopCompleted\(stop\)\)/); assert.match(routeMapSource, /"circle-translate": \[-10, -28\]/); assert.match(routeMapSource, /"text-translate": \[-10, -28\]/); assert.match(routeMapSource, /"text-field": "✓"/); assert.doesNotMatch(routeMapSource, /const stopOpacity = isTrackingView \? 0\.42 : 1/); - assert.match(routeDetailSource, /completedTrackingStopIds/); + assert.match(routeDetailSource, /const completedTrackingStopIds = useMemo\(\s*\(\) => new Set\(routeTrackingProgress\?\.completedStopIds \?\? \[\]\)/); + assert.doesNotMatch(routeDetailSource, /completedStopIds\.add\(stop\.(?:id|deliveryStopId)\)/); assert.match(routeDetailSource, /isTrackingCompleted: completedTrackingStopIds\.has\(stop\.id\)/); assert.match(routeDetailSource, /preserveRouteColor: isTrackingMapView/); + assert.match(routeDetailSource, /background: completedTrackingStopIds\.has\(row\.id\)[\s\S]*ROUTE_DETAIL_COMPLETED_STOP_COLOR[\s\S]*routeStopColorById\.get\(row\.id\) \?\? routeLineColor/); assert.match(routeDetailSource, /if \(!isTrackingMapView \|\| !isMapReady \|\| !routeMapRef\.current\) return undefined/); assert.match(routeDetailSource, /syncRouteDetailLiveTracking\(routeMapRef\.current, displayedRouteTrackingSnapshot, routeMapStops\)/); assert.match(routeDetailSource, /map\.on\("click", ROUTE_DETAIL_TRACKING_ARRIVAL_CIRCLE_LAYER_ID, handleArrivalMarkerClick\)/);