updats on the dispatch page
This commit is contained in:
@@ -75,22 +75,55 @@ export const statusColor = (map: Record<string, string>, status: string | undefi
|
||||
map[(status ?? '').trim().toLowerCase()] ?? 'var(--color-ink-3)';
|
||||
|
||||
/**
|
||||
* The status tabs, as the old console groups them.
|
||||
* The status tabs — one set per kind of row, because they are different ladders.
|
||||
*
|
||||
* Tabs rather than a dropdown: there are six, an operator switches between them
|
||||
* constantly during a shift, and a dropdown hides the counts. Each carries how
|
||||
* many rows it holds, which is half the reason to look.
|
||||
* ── Why not one shared set ──────────────────────────────────────────────────
|
||||
*
|
||||
* An order and a delivery move through different lifecycles, and a single strip
|
||||
* shown over both leaves half its tabs permanently at zero. Measured across
|
||||
* every tenant on 2026-09-10:
|
||||
*
|
||||
* orders delivered 4240 · pending 876 · cancelled 827 · created 788
|
||||
* deliveries delivered 1528 · pending 209 · cancelled 146 · picked 42 ·
|
||||
* rejected 30 · active 22 · skipped 11 · accepted 6 · arrived 3
|
||||
*
|
||||
* So an order is never "arrived" or "picked", and a delivery is never
|
||||
* "created". The previous six-tab set was shown over both and had the worse
|
||||
* problem: "processing" swallowed accepted, picked, active and arrived into one
|
||||
* bucket, so a dispatcher could not tell a rider who had reached the shop from
|
||||
* one already riding, and "cancelled" quietly included skipped.
|
||||
*
|
||||
* ── Every status has exactly one tab ────────────────────────────────────────
|
||||
*
|
||||
* `rejected` is on the delivery strip even though it is easy to forget: 30 live
|
||||
* rows carry it, and a status with no tab appears under "All" and under nothing
|
||||
* else, so an operator working through the tabs never sees those rows at all.
|
||||
* That is the failure this list is checked against.
|
||||
*/
|
||||
export const STATUS_TABS = [
|
||||
export const ORDER_STATUS_TABS = [
|
||||
{ key: 'all', label: 'All' },
|
||||
{ key: 'created', label: 'Created' },
|
||||
{ key: 'pending', label: 'Pending' },
|
||||
{ key: 'processing', label: 'Processing' },
|
||||
{ key: 'delivered', label: 'Delivered' },
|
||||
{ key: 'cancelled', label: 'Cancelled' },
|
||||
] as const;
|
||||
|
||||
export type StatusKey = (typeof STATUS_TABS)[number]['key'];
|
||||
export const DELIVERY_STATUS_TABS = [
|
||||
{ key: 'all', label: 'All' },
|
||||
{ key: 'pending', label: 'Pending' },
|
||||
{ key: 'accepted', label: 'Accepted' },
|
||||
{ key: 'arrived', label: 'Arrived' },
|
||||
{ key: 'picked', label: 'Picked' },
|
||||
{ key: 'active', label: 'Active' },
|
||||
{ key: 'skipped', label: 'Skipped' },
|
||||
{ key: 'rejected', label: 'Rejected' },
|
||||
{ key: 'delivered', label: 'Delivered' },
|
||||
{ key: 'cancelled', label: 'Cancelled' },
|
||||
] as const;
|
||||
|
||||
export type StatusKey =
|
||||
| (typeof ORDER_STATUS_TABS)[number]['key']
|
||||
| (typeof DELIVERY_STATUS_TABS)[number]['key'];
|
||||
|
||||
/**
|
||||
* Does a row belong under this tab?
|
||||
@@ -98,8 +131,10 @@ export type StatusKey = (typeof STATUS_TABS)[number]['key'];
|
||||
* Substring matching, lowercased. Fiesta stores status as free text and the
|
||||
* casing is inconsistent between writers, so an exact match is how a
|
||||
* "Delivered" row silently stops counting the day someone writes "delivered".
|
||||
* "processing" also catches confirmed, preparing and ready — everything between
|
||||
* accepted and out the door, which is what an operator means by the word.
|
||||
*
|
||||
* Each status now lands in exactly ONE tab. The order of these cases matters
|
||||
* where words overlap: `undelivered` must not count as delivered, and
|
||||
* `out for delivery` is a delivery in progress rather than a completed one.
|
||||
*/
|
||||
export function matchesStatus(key: StatusKey, status: string | undefined): boolean {
|
||||
if (key === 'all') return true;
|
||||
@@ -110,30 +145,32 @@ export function matchesStatus(key: StatusKey, status: string | undefined): boole
|
||||
return s.includes('created') || s.includes('new');
|
||||
case 'pending':
|
||||
return s.includes('pending');
|
||||
case 'processing':
|
||||
return (
|
||||
s.includes('process') ||
|
||||
s.includes('confirm') ||
|
||||
s.includes('prepar') ||
|
||||
s.includes('ready') ||
|
||||
s.includes('accept') ||
|
||||
s.includes('picked') ||
|
||||
s.includes('active') ||
|
||||
s.includes('arrived') ||
|
||||
s.includes('out for')
|
||||
);
|
||||
case 'accepted':
|
||||
// Not "accept" alone — that would also catch "unaccepted" if it appears.
|
||||
return s.includes('accepted');
|
||||
case 'arrived':
|
||||
return s.includes('arrived');
|
||||
case 'picked':
|
||||
return s.includes('picked') || s.includes('pickup');
|
||||
case 'active':
|
||||
// Everything between collecting and dropping: the platform writes
|
||||
// `active`, and `out for delivery` means the same thing.
|
||||
return s.includes('active') || s.includes('out for') || s.includes('transit');
|
||||
case 'skipped':
|
||||
// Its own status and its own tab. The rider reached the address and
|
||||
// nobody was in — which is not a cancellation, and used to be filed as
|
||||
// one.
|
||||
return s.includes('skip');
|
||||
case 'rejected':
|
||||
return s.includes('reject') || s.includes('declin');
|
||||
case 'delivered':
|
||||
return s.includes('deliver') && !s.includes('undeliver') && !s.includes('out for');
|
||||
case 'cancelled':
|
||||
// `skipped` lives here too. It is its own delivery status — the rider
|
||||
// reached the address and nobody was in — and it keeps its own orange
|
||||
// chip, but it has no tab of its own in this six-tab strip. Without this
|
||||
// line a skipped job appears under "All" and under nothing else, so an
|
||||
// operator working through the tabs never sees it.
|
||||
return s.includes('cancel') || s.includes('skip');
|
||||
return s.includes('cancel');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The money on an order row, in the order the old console reads it.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user