updates on the queries page and dispatch page section
This commit is contained in:
@@ -305,10 +305,36 @@ export const fetchAppLocations = async () => {
|
||||
try {
|
||||
const hubs = await getHubs();
|
||||
const seen = new Map();
|
||||
// Each city also carries a map centre, so Control X can move the map
|
||||
// there when the operator switches city and there are no orders yet to
|
||||
// zoom to. It is the MEDIAN of the city's hub coordinates, not the mean:
|
||||
// one mis-filed hub (a Chennai hub tagged as Coimbatore, say) would drag a
|
||||
// mean tens of km off, while the median ignores it. Hubs with no
|
||||
// coordinates (0,0 / missing) are left out.
|
||||
const points = new Map();
|
||||
(hubs || []).forEach((hub) => {
|
||||
if (hub.applocationid != null && !seen.has(hub.applocationid)) {
|
||||
if (hub.applocationid == null) return;
|
||||
if (!seen.has(hub.applocationid)) {
|
||||
seen.set(hub.applocationid, { applocationid: hub.applocationid, locationname: hub.city || hub.hubname });
|
||||
}
|
||||
const lat = Number(hub.latitude);
|
||||
const lng = Number(hub.longitude);
|
||||
if (Number.isFinite(lat) && Number.isFinite(lng) && lat !== 0 && lng !== 0) {
|
||||
const list = points.get(hub.applocationid) || [];
|
||||
list.push([lat, lng]);
|
||||
points.set(hub.applocationid, list);
|
||||
}
|
||||
});
|
||||
const median = (values) => {
|
||||
const v = [...values].sort((a, b) => a - b);
|
||||
const mid = Math.floor(v.length / 2);
|
||||
return v.length % 2 ? v[mid] : (v[mid - 1] + v[mid]) / 2;
|
||||
};
|
||||
points.forEach((list, id) => {
|
||||
const loc = seen.get(id);
|
||||
if (loc && list.length) {
|
||||
Object.assign(loc, { latitude: median(list.map((p) => p[0])), longitude: median(list.map((p) => p[1])) });
|
||||
}
|
||||
});
|
||||
const allLocations = [...seen.values()];
|
||||
|
||||
|
||||
@@ -564,8 +564,10 @@ const getStableRiderColor = (id) => {
|
||||
// call sites in this file are Leaflet divIcon HTML strings, which need a raw
|
||||
// hex — normal JSX should render <StatusBadge> instead.
|
||||
|
||||
const MapController = ({ focusedItem, viewMode, orders, kitchens, locationKey }) => {
|
||||
const MapController = ({ focusedItem, viewMode, orders, kitchens, locationKey, locationCenter }) => {
|
||||
const map = useMap();
|
||||
// Which city the map was last moved to by the no-data fallback below.
|
||||
const lastCenteredLocRef = useRef(null);
|
||||
// Last fit signature. We only call fitBounds when this changes — otherwise
|
||||
// every parent render (data refetch, sidebar tick, etc.) would refit the
|
||||
// map and snap it back mid-drag, which felt like the map was un-draggable.
|
||||
@@ -620,7 +622,28 @@ const MapController = ({ focusedItem, viewMode, orders, kitchens, locationKey })
|
||||
return `${loc}m|${viewMode || ''}|${kPairs.length}|${kSig}`;
|
||||
}, [focusedItem, viewMode, orders, kitchens, locationKey]);
|
||||
|
||||
// City the fit key last belonged to. Switching city must forget the last
|
||||
// fit: otherwise Coimbatore → Bangalore → Coimbatore produces the SAME
|
||||
// Coimbatore fit key as before, the early-return below treats it as
|
||||
// "already fitted", and the map stays parked on Bangalore.
|
||||
const lastFitLocRef = useRef(locationKey);
|
||||
|
||||
useEffect(() => {
|
||||
if (lastFitLocRef.current !== locationKey) {
|
||||
lastFitLocRef.current = locationKey;
|
||||
lastFitKeyRef.current = '';
|
||||
// Move to the new city IMMEDIATELY. Waiting for its data meant the map
|
||||
// sat on the previous city for the 5–8s the new orders took to load,
|
||||
// which read as "the dropdown didn't do anything". Skip fitting on this
|
||||
// pass — whatever orders/kitchens are on hand still belong to the OLD
|
||||
// city — and let the new city's data refit onto its orders when it
|
||||
// arrives (the fit key changes then).
|
||||
if (!focusedItem && locationCenter) {
|
||||
lastCenteredLocRef.current = locationKey;
|
||||
map.flyTo(locationCenter, 12, { duration: 0.8 });
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (lastFitKeyRef.current === fitKey) return;
|
||||
|
||||
let pts = [];
|
||||
@@ -675,7 +698,17 @@ const MapController = ({ focusedItem, viewMode, orders, kitchens, locationKey })
|
||||
// bug that left Nagercoil (and every non-Coimbatore hub) stuck on the
|
||||
// Coimbatore default during the brief window between picking the hub
|
||||
// and its data arriving.
|
||||
}, [fitKey, focusedItem, viewMode, orders, kitchens, map]);
|
||||
//
|
||||
// But a city with NO orders for the day never produces data to fit to,
|
||||
// so picking Bangalore left the map sitting on Coimbatore indefinitely.
|
||||
// Fall back to the selected city's own centre (its hubs' average) — the
|
||||
// selected city, never a hard-coded default — once per city switch. The
|
||||
// fit key stays unlocked, so orders arriving later still refit onto them.
|
||||
if (focusedItem || locationKey == null || !locationCenter) return;
|
||||
if (lastCenteredLocRef.current === locationKey) return;
|
||||
lastCenteredLocRef.current = locationKey;
|
||||
map.flyTo(locationCenter, 12, { duration: 0.8 });
|
||||
}, [fitKey, focusedItem, viewMode, orders, kitchens, map, locationKey, locationCenter]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -1283,6 +1316,14 @@ const Dispatch = ({
|
||||
return match?.locationname || null;
|
||||
}, [appLocations, selectedAppLocationId]);
|
||||
|
||||
// The selected city's map centre (average of its hubs), used by
|
||||
// MapController when there's nothing on the map to zoom to.
|
||||
const locationCenter = useMemo(() => {
|
||||
if (!appLocations) return null;
|
||||
const match = appLocations.find((l) => String(l.applocationid) === String(selectedAppLocationId));
|
||||
return Number.isFinite(match?.latitude) && Number.isFinite(match?.longitude) ? [match.latitude, match.longitude] : null;
|
||||
}, [appLocations, selectedAppLocationId]);
|
||||
|
||||
const handleLocationPick = (id) => {
|
||||
logger.info('Switching hub/location ID:', id);
|
||||
setSelectedAppLocationId(Number(id));
|
||||
@@ -5430,6 +5471,7 @@ const Dispatch = ({
|
||||
orders={allViewOrders}
|
||||
kitchens={kitchens}
|
||||
locationKey={selectedAppLocationId}
|
||||
locationCenter={locationCenter}
|
||||
extraPoints={allViewLivePoints}
|
||||
/>
|
||||
{kitchens
|
||||
|
||||
Reference in New Issue
Block a user