updates on the astryx desing

This commit is contained in:
2026-08-14 16:09:14 +05:30
parent d3dd687a8d
commit a46212f291
106 changed files with 10244 additions and 24738 deletions

View File

@@ -1,6 +1,7 @@
import axios from 'axios';
import { OpenToast } from 'components/third-party/OpenToast';
import logger from 'utils/logger';
import { parseDoormileTimestamp } from 'utils/doormileTimestamp';
import {
getMilers,
getMiler,
@@ -518,7 +519,20 @@ export const notifyRider = async (
// deliveries.js itself doesn't need a full rewrite — same compatibility-shim
// approach as fetchAllRiders' `{details}` wrapper.
export const fetchDeliveries = async ({ pageParam = 1, queryKey }) => {
const [, , , , , , rowsPerPage] = queryKey;
// Every caller builds the key as
// [name, appId, userid, status, startdate, enddate, rowsPerPage, …]
// (Dispatch.js, deliveries.js, reports/ordersDetails.js,
// reports/profitability.js — all four verified). Only rowsPerPage used to be
// read here, which meant startdate/enddate were accepted and then ignored:
// changing the date on the Dispatch page rebuilt the query key and refetched,
// but issued an identical request, so the row set — and every batch count
// derived from it — was byte-identical for today, yesterday and last week.
//
// GET /admin/bookings takes only pageno/pagesize (doormileApi.js; no date
// parameter is documented in express-console-api.md and guessing one risks a
// silent 400 or, worse, a silently-ignored filter), so the range is applied
// client-side below, after the rows are normalised.
const [, , , , startdate, enddate, rowsPerPage] = queryKey;
// Unlike the 3 joins below (customers/milers/tenants — each individually
// guarded so a failed join just degrades a display field, not the whole
// page), a failed bookings call is the one thing this function can't
@@ -632,8 +646,30 @@ export const fetchDeliveries = async ({ pageParam = 1, queryKey }) => {
};
});
// Apply the requested date range to the booking's CREATION day. This has to
// agree with what the batch bucketing reads (Dispatch.js's
// BATCH_TIME_FIELD / deliveries.js's BATCH_TIME_KEYS, both `orderdate`) —
// filtering on one field while bucketing on another is how you get a row
// that is counted for the day but belongs to no batch in it.
//
// parseDoormileTimestamp, not bare dayjs(): some Doormile timestamps carry a
// false trailing Z, and near midnight an unstripped one shifts the row +5:30
// into the next calendar day, dropping it from the selected date.
//
// A missing/blank bound means "unbounded on that side", which preserves the
// old behaviour for any caller that doesn't pass real dates.
const inRange = (row) => {
if (!startdate && !enddate) return true;
const t = parseDoormileTimestamp(row.orderdate);
if (!t.isValid()) return false;
const day = t.format('YYYY-MM-DD');
if (startdate && day < String(startdate)) return false;
if (enddate && day > String(enddate)) return false;
return true;
};
return {
rows,
rows: rows.filter(inRange),
// Whether to fetch another page must be based on the RAW bookings page
// (bookings.length), not the post-filter `rows.length` — most bookings on
// any given page are still pending, not dispatched, so the filtered count
@@ -764,12 +800,21 @@ export const getallridersummary = async () => {
// A miler has no `status` field — availabilitystatus is the real one
// (confirmed live: Available/Assigned/On_Pickup/Offline/Blocked).
// "Active" here means not Offline and not Blocked, matching riders.js's
// own tab filter.
// own tab filter. `available`/`onDelivery` are a KPI-card-friendly
// breakdown of that same "active" bucket — Available is free/idle,
// On Delivery covers both Assigned (accepted, not yet picked up) and
// On_Pickup (en route) — computed separately so an unrecognised status
// value still falls into "active" (unchanged behaviour) without also
// silently inflating one of the two new buckets.
const active = milers.filter((m) => !['offline', 'blocked'].includes(String(m.availabilitystatus || '').toLowerCase())).length;
return { total: milers.length, active, inactive: milers.length - active };
const available = milers.filter((m) => String(m.availabilitystatus || '').toLowerCase() === 'available').length;
const onDelivery = milers.filter((m) =>
['assigned', 'on_pickup'].includes(String(m.availabilitystatus || '').toLowerCase())
).length;
return { total: milers.length, active, inactive: milers.length - active, available, onDelivery };
} catch (err) {
OpenToast(err.response?.data?.message || err.message || 'Failed to load rider summary', 'error', 2000);
return { total: 0, active: 0, inactive: 0 };
return { total: 0, active: 0, inactive: 0, available: 0, onDelivery: 0 };
}
};