updates on the ui design and desing updates
This commit is contained in:
95
src/themes/dt/status.js
Normal file
95
src/themes/dt/status.js
Normal file
@@ -0,0 +1,95 @@
|
||||
// ============================================================================
|
||||
// Canonical lifecycle-status registry.
|
||||
//
|
||||
// Five pages (deliveries, orders, ordersDetails, Tenants, and the dispatch
|
||||
// panels) each carried their own private `STATUS_META` map. They agreed on the
|
||||
// hexes but disagreed on everything else — orders.js keys off the raw
|
||||
// `GET /admin/bookings` enum (`pending_pickup`, `miler_assigned`, …) while
|
||||
// deliveries.js keys off api.js's generic `pending`/`accepted`/`delivered`
|
||||
// mapping, so the same order rendered under two different labels depending on
|
||||
// which page you were looking at.
|
||||
//
|
||||
// This module is the one place that knows what a status LOOKS like. It does
|
||||
// not know what a status MEANS to a given page — the pending/accepted bucket
|
||||
// rules stay in each page's query layer, because those genuinely differ (see
|
||||
// the long comment above orders.js's STATUS_TABS).
|
||||
//
|
||||
// Each entry carries four renderings of the same state so a page never has to
|
||||
// pick a colour by hand:
|
||||
// color — hex, for the surfaces that take a raw accent (StatCard,
|
||||
// AccentAvatar, chart series). Matches CLAUDE.md's status palette.
|
||||
// badge — Astryx <Badge variant>. Non-semantic tinted variants on purpose:
|
||||
// per Astryx's Badge guidance the solid semantic variants
|
||||
// (success/warning/error) are for states that demand attention, and
|
||||
// a table where every row shouts is a table where nothing does.
|
||||
// `cancelled` is the one state that keeps a loud variant.
|
||||
// dot — Astryx <StatusDot variant>, which only has five values, so
|
||||
// several lifecycle states collapse onto `accent` here.
|
||||
// icon — react-icons component (not an element) so callers size it.
|
||||
// ============================================================================
|
||||
import {
|
||||
MdHourglassEmpty,
|
||||
MdPersonPin,
|
||||
MdLocationOn,
|
||||
MdInventory2,
|
||||
MdRoute,
|
||||
MdSkipNext,
|
||||
MdCheckCircle,
|
||||
MdCancel,
|
||||
MdList,
|
||||
MdHelpOutline
|
||||
} from 'react-icons/md';
|
||||
|
||||
export const STATUS_META = {
|
||||
all: { label: 'All', color: '#000000', badge: 'neutral', dot: 'neutral', icon: MdList },
|
||||
pending: { label: 'Pending', color: '#f59e0b', badge: 'yellow', dot: 'warning', icon: MdHourglassEmpty },
|
||||
accepted: { label: 'Accepted', color: '#6366f1', badge: 'blue', dot: 'accent', icon: MdPersonPin },
|
||||
arrived: { label: 'Arrived', color: '#06b6d4', badge: 'cyan', dot: 'accent', icon: MdLocationOn },
|
||||
picked: { label: 'Picked', color: '#8b5cf6', badge: 'purple', dot: 'accent', icon: MdInventory2 },
|
||||
active: { label: 'Active', color: '#14b8a6', badge: 'teal', dot: 'success', icon: MdRoute },
|
||||
skipped: { label: 'Skipped', color: '#f97316', badge: 'orange', dot: 'warning', icon: MdSkipNext },
|
||||
delivered: { label: 'Delivered', color: '#10b981', badge: 'green', dot: 'success', icon: MdCheckCircle },
|
||||
cancelled: { label: 'Cancelled', color: '#ef4444', badge: 'error', dot: 'error', icon: MdCancel },
|
||||
inactive: { label: 'Inactive', color: '#ef4444', badge: 'red', dot: 'error', icon: MdCancel }
|
||||
};
|
||||
|
||||
// Raw backend enums that render as one of the states above. Kept separate from
|
||||
// STATUS_META so the canonical list stays readable and so a page can still ask
|
||||
// "is this a known alias?" rather than silently falling back.
|
||||
//
|
||||
// The booking enums come from `GET /admin/bookings` (confirmed live — see
|
||||
// orders.js). `converted_to_consignment` is deliberately `accepted` and not
|
||||
// `picked`: it fires when the rider marks pickup COMPLETE, but the operator
|
||||
// workflow on the Orders page treats everything before hand-off as assigned.
|
||||
export const STATUS_ALIASES = {
|
||||
pending_pickup: 'pending',
|
||||
pending_assignment: 'pending',
|
||||
miler_assigned: 'accepted',
|
||||
pickup_scheduled: 'accepted',
|
||||
converted_to_consignment: 'accepted',
|
||||
in_transit: 'active',
|
||||
intransit: 'active',
|
||||
completed: 'delivered',
|
||||
cancel: 'cancelled',
|
||||
canceled: 'cancelled'
|
||||
};
|
||||
|
||||
// Fallback for a status the backend invents that nobody has mapped yet. Renders
|
||||
// as a neutral badge with the raw string as its label, so an unknown state is
|
||||
// visible and debuggable rather than blank.
|
||||
const unknownStatus = (status) => ({
|
||||
label: String(status || 'Unknown'),
|
||||
color: '#94a3b8',
|
||||
badge: 'neutral',
|
||||
dot: 'neutral',
|
||||
icon: MdHelpOutline
|
||||
});
|
||||
|
||||
// Resolve any status string — canonical key, backend alias, or arbitrary
|
||||
// casing — to its visual meta. Always returns an object; never throws.
|
||||
export function getStatusMeta(status) {
|
||||
if (!status) return unknownStatus(status);
|
||||
const raw = String(status).trim();
|
||||
const key = raw.toLowerCase();
|
||||
return STATUS_META[key] || STATUS_META[STATUS_ALIASES[raw]] || STATUS_META[STATUS_ALIASES[key]] || unknownStatus(raw);
|
||||
}
|
||||
@@ -30,6 +30,12 @@ export const DT = {
|
||||
// Semantic status palette — lifecycle colours, deliberately distinct from the
|
||||
// brand (see root CLAUDE.md §6). Pages have historically inlined these hexes;
|
||||
// new code should reference STATUS so there is one place to change them.
|
||||
//
|
||||
// This map is the RAW HEX layer, for surfaces that take an arbitrary accent
|
||||
// (StatCard, AccentAvatar, chart series). To RENDER a status — a row badge or
|
||||
// a filter tab — use `themes/dt/status.js` instead: it resolves backend enums
|
||||
// and aliases, and carries the matching Astryx Badge/StatusDot variants and
|
||||
// icon alongside the hex. Reach for STATUS only when you need the bare colour.
|
||||
// This also replaces the `theme.palette.error/success/...` lookups that used
|
||||
// to pull the same colours out of the MUI theme.
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -57,6 +63,26 @@ export const soft = (c) => a(c, '18'); // soft chip / avatar bg
|
||||
export const ring = (c) => a(c, '26'); // focus ring color
|
||||
export const edge = (c) => a(c, '55'); // resting border
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ⛔ LEGACY — MUI-ONLY. Everything from here to the end of this file emits MUI
|
||||
// `sx` objects and cannot be used by an Astryx page.
|
||||
//
|
||||
// They stay only because the pages still awaiting conversion import them
|
||||
// (`pillFieldSx` ×3 files, `tableScrollSx` ×4, `tableHeadSx` ×3,
|
||||
// `tableRowSx` ×3). They are deleted along with the MUI dependency once the
|
||||
// last page converts — do NOT add a new call site.
|
||||
//
|
||||
// Astryx equivalents:
|
||||
// pillFieldSx → nothing. Field chrome comes from the theme
|
||||
// (`themes/astryx.js` → components['text-input']), so every
|
||||
// input matches without a per-call-site helper.
|
||||
// tableScrollSx → <TableScroll> from themes/dt/primitives (also supplies
|
||||
// the sticky header MUI's TableContainer used to provide).
|
||||
// tableHeadSx → <Table density dividers hasHover> — header casing and
|
||||
// row rules are the component's own chrome.
|
||||
// tableRowSx → same; `hasHover` covers the hover tint.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Pill input sx — used by every filter Autocomplete/TextField on a page.
|
||||
// Neutral, corporate filter field: white surface, hairline border, brand
|
||||
// focus ring. Width is driven by parent flex/grid so this helper stays
|
||||
|
||||
Reference in New Issue
Block a user