@burdenoff/microfe-movethewheels 2026.804.1 → 2026.822.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/CarbonFootprintPanel.js +108 -0
- package/dist/components/UpcomingDemandPanel.js +184 -0
- package/dist/components/index.js +1 -0
- package/dist/generated/wspace-operations.d.ts +147 -0
- package/dist/generated/wspace-types.d.ts +63 -0
- package/dist/hooks/useAnalytics.js +45 -4
- package/dist/hooks/useDemandForecast.js +54 -0
- package/dist/index.js +29 -28
- package/dist/movethewheels/components/CarbonFootprintPanel.d.ts +7 -0
- package/dist/movethewheels/components/UpcomingDemandPanel.d.ts +13 -0
- package/dist/movethewheels/components/index.d.ts +1 -0
- package/dist/movethewheels/hooks/index.d.ts +1 -1
- package/dist/movethewheels/hooks/useAnalytics.d.ts +22 -0
- package/dist/movethewheels/hooks/useDemandForecast.d.ts +39 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/leaf.js +11 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/trending-down.js +11 -0
- package/dist/pages/AnalyticsPage.js +82 -69
- package/package.json +2 -2
- package/src/generated/wspace-operations.ts +177 -0
- package/src/generated/wspace-types.ts +74 -0
- package/src/movethewheels/components/CarbonFootprintPanel.tsx +133 -0
- package/src/movethewheels/components/UpcomingDemandPanel.tsx +237 -0
- package/src/movethewheels/components/index.ts +3 -0
- package/src/movethewheels/hooks/index.ts +2 -0
- package/src/movethewheels/hooks/useAnalytics.ts +86 -0
- package/src/movethewheels/hooks/useDemandForecast.ts +161 -0
- package/src/movethewheels/pages/AnalyticsPage.tsx +27 -0
- package/src/operations/wspace/movethewheels/queries/forecast.graphql +47 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useMoveTheWheels as e } from "../providers/MoveTheWheelsProvider.js";
|
|
2
|
+
import { executeGraphQL as t } from "../utils/graphqlClient.js";
|
|
3
|
+
import { useCallback as n, useEffect as r, useMemo as i, useState as a } from "react";
|
|
4
|
+
//#region src/movethewheels/hooks/useDemandForecast.ts
|
|
5
|
+
var o = "\n query GetMovethewheelsDemandForecast($weeks: Int!, $varianceLimit: Int!) {\n demandForecastByLane(weeks: $weeks) {\n scopeType\n scopeKey\n periodStart\n periodEnd\n predictedVolume\n predictedRevenue\n actualVolume\n actualRevenue\n confidence\n }\n demandForecastByCustomer(weeks: $weeks) {\n scopeType\n scopeKey\n periodStart\n periodEnd\n predictedVolume\n predictedRevenue\n actualVolume\n actualRevenue\n confidence\n }\n laneVariance: demandForecastVariance(scopeType: LANE, limit: $varianceLimit) {\n scopeType\n scopeKey\n periodStart\n periodEnd\n predictedVolume\n actualVolume\n volumeVariance\n predictedRevenue\n actualRevenue\n revenueVariance\n }\n customerVariance: demandForecastVariance(scopeType: CUSTOMER, limit: $varianceLimit) {\n scopeType\n scopeKey\n periodStart\n periodEnd\n predictedVolume\n actualVolume\n volumeVariance\n predictedRevenue\n actualRevenue\n revenueVariance\n }\n }\n";
|
|
6
|
+
function s(s = 4, c = 8) {
|
|
7
|
+
let { apiGatewayUrl: l, authToken: u, workspaceToken: d, workspaceId: f, tenantId: p, currentUser: m } = e(), [h, g] = a([]), [_, v] = a([]), [y, b] = a([]), [x, S] = a([]), [C, w] = a(!1), [T, E] = a(null), D = i(() => ({
|
|
8
|
+
apiGatewayUrl: l,
|
|
9
|
+
authToken: u,
|
|
10
|
+
workspaceToken: d,
|
|
11
|
+
workspaceId: f,
|
|
12
|
+
tenantId: p,
|
|
13
|
+
actorId: m?.id
|
|
14
|
+
}), [
|
|
15
|
+
l,
|
|
16
|
+
u,
|
|
17
|
+
d,
|
|
18
|
+
f,
|
|
19
|
+
p,
|
|
20
|
+
m?.id
|
|
21
|
+
]), O = n(async () => {
|
|
22
|
+
w(!0), E(null);
|
|
23
|
+
try {
|
|
24
|
+
let e = await t(D, o, {
|
|
25
|
+
weeks: s,
|
|
26
|
+
varianceLimit: c
|
|
27
|
+
});
|
|
28
|
+
g(e.demandForecastByLane ?? []), v(e.demandForecastByCustomer ?? []), b(e.laneVariance ?? []), S(e.customerVariance ?? []);
|
|
29
|
+
} catch (e) {
|
|
30
|
+
E(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load demand forecast"));
|
|
31
|
+
} finally {
|
|
32
|
+
w(!1);
|
|
33
|
+
}
|
|
34
|
+
}, [
|
|
35
|
+
D,
|
|
36
|
+
s,
|
|
37
|
+
c
|
|
38
|
+
]);
|
|
39
|
+
return r(() => {
|
|
40
|
+
O();
|
|
41
|
+
}, [O]), {
|
|
42
|
+
laneForecast: h,
|
|
43
|
+
customerForecast: _,
|
|
44
|
+
laneVariance: y,
|
|
45
|
+
customerVariance: x,
|
|
46
|
+
isLoading: C,
|
|
47
|
+
error: T,
|
|
48
|
+
refetch: n(() => {
|
|
49
|
+
O();
|
|
50
|
+
}, [O])
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { s as useDemandForecast };
|
package/dist/index.js
CHANGED
|
@@ -7,33 +7,34 @@ import { useDriver as c, useDrivers as l, useFleet as u, useFleetStats as d, use
|
|
|
7
7
|
import { useInventory as m, useInventoryStats as h, useProduct as g, useProducts as _, useWarehouse as v, useWarehouses as y } from "./hooks/useInventory.js";
|
|
8
8
|
import { useCustomer as b, useCustomerStats as x, useCustomers as S } from "./hooks/useCustomers.js";
|
|
9
9
|
import { useRoute as C, useRouteStats as w, useRoutes as T } from "./hooks/useRoutes.js";
|
|
10
|
-
import { useAnalytics as E, useDashboardMetrics as D,
|
|
11
|
-
import { useDriverTracking as
|
|
12
|
-
import { useReports as
|
|
13
|
-
import { useImportExport as
|
|
14
|
-
import { useModuleSettings as
|
|
15
|
-
import { useEntityDocuments as
|
|
16
|
-
import { useCaptureEpod as
|
|
10
|
+
import { useAnalytics as E, useDashboardMetrics as D, useEmissionsSummary as O, useFinanceMetrics as k, useFleetAnalytics as A, useOrderAnalytics as j, usePerformanceAnalytics as M, useRevenueAnalytics as N } from "./hooks/useAnalytics.js";
|
|
11
|
+
import { useDriverTracking as P, useGeofence as F, useLiveTracking as I, useOrderTracking as L, useTracking as R, useTrackingAlerts as z, useVehicleTracking as B } from "./hooks/useTracking.js";
|
|
12
|
+
import { useReports as V } from "./hooks/useReports.js";
|
|
13
|
+
import { useImportExport as H } from "./hooks/useImportExport.js";
|
|
14
|
+
import { useModuleSettings as U } from "./hooks/useSettings.js";
|
|
15
|
+
import { useEntityDocuments as W } from "./hooks/useEntityDocuments.js";
|
|
16
|
+
import { useCaptureEpod as G, useEpod as K, useEpodPhotoUpload as q, useEpodPhotoUrl as J, useMyPendingEpodDeliveryJobs as Y } from "./hooks/useEpod.js";
|
|
17
17
|
import "./hooks/index.js";
|
|
18
|
-
import { Avatar as
|
|
19
|
-
import { EmptyState as
|
|
20
|
-
import { chartTokens as
|
|
21
|
-
import { Sparkline as
|
|
22
|
-
import { MetricCard as
|
|
23
|
-
import { GlassPanel as
|
|
24
|
-
import { ChartEmpty as
|
|
25
|
-
import { TrendChart as
|
|
26
|
-
import { VolumeBar as
|
|
27
|
-
import { StatusDonut as
|
|
28
|
-
import { createCurrentIcon as
|
|
29
|
-
import { MapCanvas as
|
|
30
|
-
import { LogisticsMap as
|
|
31
|
-
import { RouteMap as
|
|
32
|
-
import { TrackingMap as
|
|
33
|
-
import { PaymentStatusBadge as
|
|
34
|
-
import { DataTable as
|
|
35
|
-
import { FormError as
|
|
36
|
-
import { Notice as
|
|
37
|
-
import { DocumentsCard as
|
|
18
|
+
import { Avatar as X, AvatarFallback as Z, AvatarImage as Q, Badge as $, Button as ee, Card as te, CardContent as ne, CardDescription as re, CardFooter as ie, CardHeader as ae, CardTitle as oe, Checkbox as se, Dialog as ce, DialogContent as le, DialogDescription as ue, DialogFooter as de, DialogHeader as fe, DialogTitle as pe, DialogTrigger as me, DropdownMenu as he, DropdownMenuContent as ge, DropdownMenuItem as _e, DropdownMenuSeparator as ve, DropdownMenuTrigger as ye, Input as be, Label as xe, Progress as Se, ScrollArea as Ce, Select as we, SelectContent as Te, SelectItem as Ee, SelectTrigger as De, SelectValue as Oe, Separator as ke, Skeleton as Ae, Switch as je, Table as Me, TableBody as Ne, TableCell as Pe, TableHead as Fe, TableHeader as Ie, TableRow as Le, Tabs as Re, TabsContent as ze, TabsList as Be, TabsTrigger as Ve, Textarea as He, Tooltip as Ue, TooltipContent as We, TooltipProvider as Ge, TooltipTrigger as Ke } from "./components/ui.js";
|
|
19
|
+
import { EmptyState as qe, ErrorState as Je, LoadingState as Ye, PageLayout as Xe, PageSection as Ze } from "./components/PageLayout.js";
|
|
20
|
+
import { chartTokens as Qe, seriesColor as $e } from "./components/charts/chartTokens.js";
|
|
21
|
+
import { Sparkline as et } from "./components/charts/Sparkline.js";
|
|
22
|
+
import { MetricCard as tt, MetricCardSkeleton as nt, MetricGrid as rt } from "./components/MetricCard.js";
|
|
23
|
+
import { GlassPanel as it } from "./components/GlassPanel.js";
|
|
24
|
+
import { ChartEmpty as at, ChartTooltip as ot } from "./components/charts/ChartShell.js";
|
|
25
|
+
import { TrendChart as st } from "./components/charts/TrendChart.js";
|
|
26
|
+
import { VolumeBar as ct } from "./components/charts/VolumeBar.js";
|
|
27
|
+
import { StatusDonut as lt } from "./components/charts/StatusDonut.js";
|
|
28
|
+
import { createCurrentIcon as ut, createPinIcon as dt, createStopIcon as ft, isRealCoord as pt } from "./components/maps/leaflet-setup.js";
|
|
29
|
+
import { MapCanvas as mt } from "./components/maps/MapCanvas.js";
|
|
30
|
+
import { LogisticsMap as ht } from "./components/maps/LogisticsMap.js";
|
|
31
|
+
import { RouteMap as gt } from "./components/maps/RouteMap.js";
|
|
32
|
+
import { TrackingMap as _t } from "./components/maps/TrackingMap.js";
|
|
33
|
+
import { PaymentStatusBadge as vt, PriorityBadge as yt, StatusBadge as bt, TypeBadge as xt, VehicleTypeBadge as St } from "./components/StatusBadge.js";
|
|
34
|
+
import { DataTable as Ct } from "./components/DataTable.js";
|
|
35
|
+
import { FormError as wt } from "./components/FormError.js";
|
|
36
|
+
import { Notice as Tt, useNotice as Et } from "./components/Notice.js";
|
|
37
|
+
import { DocumentsCard as Dt } from "./components/DocumentsCard.js";
|
|
38
|
+
import { CarbonFootprintPanel as Ot } from "./components/CarbonFootprintPanel.js";
|
|
38
39
|
import "./components/index.js";
|
|
39
|
-
export {
|
|
40
|
+
export { X as Avatar, Z as AvatarFallback, Q as AvatarImage, $ as Badge, ee as Button, Ot as CarbonFootprintPanel, te as Card, ne as CardContent, re as CardDescription, ie as CardFooter, ae as CardHeader, oe as CardTitle, at as ChartEmpty, ot as ChartTooltip, se as Checkbox, Ct as DataTable, ce as Dialog, le as DialogContent, ue as DialogDescription, de as DialogFooter, fe as DialogHeader, pe as DialogTitle, me as DialogTrigger, Dt as DocumentsCard, he as DropdownMenu, ge as DropdownMenuContent, _e as DropdownMenuItem, ve as DropdownMenuSeparator, ye as DropdownMenuTrigger, qe as EmptyState, Je as ErrorState, wt as FormError, it as GlassPanel, be as Input, xe as Label, Ye as LoadingState, ht as LogisticsMap, mt as MapCanvas, tt as MetricCard, nt as MetricCardSkeleton, rt as MetricGrid, n as MoveTheWheelsRoot, Tt as Notice, Xe as PageLayout, Ze as PageSection, vt as PaymentStatusBadge, yt as PriorityBadge, Se as Progress, gt as RouteMap, Ce as ScrollArea, we as Select, Te as SelectContent, Ee as SelectItem, De as SelectTrigger, Oe as SelectValue, ke as Separator, Ae as Skeleton, et as Sparkline, bt as StatusBadge, lt as StatusDonut, je as Switch, Me as Table, Ne as TableBody, Pe as TableCell, Fe as TableHead, Ie as TableHeader, Le as TableRow, Re as Tabs, ze as TabsContent, Be as TabsList, Ve as TabsTrigger, He as Textarea, Ue as Tooltip, We as TooltipContent, Ge as TooltipProvider, Ke as TooltipTrigger, _t as TrackingMap, st as TrendChart, xt as TypeBadge, St as VehicleTypeBadge, ct as VolumeBar, Qe as chartTokens, ut as createCurrentIcon, dt as createPinIcon, ft as createStopIcon, pt as isRealCoord, $e as seriesColor, E as useAnalytics, G as useCaptureEpod, b as useCustomer, x as useCustomerStats, S as useCustomers, D as useDashboardMetrics, c as useDriver, P as useDriverTracking, l as useDrivers, O as useEmissionsSummary, W as useEntityDocuments, K as useEpod, q as useEpodPhotoUpload, J as useEpodPhotoUrl, k as useFinanceMetrics, u as useFleet, A as useFleetAnalytics, d as useFleetStats, F as useGeofence, H as useImportExport, m as useInventory, h as useInventoryStats, I as useLiveTracking, U as useModuleSettings, e as useMoveTheWheels, t as useMoveTheWheelsNavigate, r as useMoveTheWheelsStore, Y as useMyPendingEpodDeliveryJobs, Et as useNotice, a as useOrder, j as useOrderAnalytics, o as useOrderStats, L as useOrderTracking, s as useOrders, M as usePerformanceAnalytics, g as useProduct, _ as useProducts, V as useReports, N as useRevenueAnalytics, C as useRoute, w as useRouteStats, T as useRoutes, i as useSandboxAssistantTransport, R as useTracking, z as useTrackingAlerts, f as useVehicle, B as useVehicleTracking, p as useVehicles, v as useWarehouse, y as useWarehouses };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ForecastPoint, ForecastVariance } from '../hooks/useDemandForecast';
|
|
2
|
+
|
|
3
|
+
interface UpcomingDemandPanelProps {
|
|
4
|
+
laneForecast: ForecastPoint[];
|
|
5
|
+
customerForecast: ForecastPoint[];
|
|
6
|
+
laneVariance: ForecastVariance[];
|
|
7
|
+
customerVariance: ForecastVariance[];
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
error: Error | null;
|
|
10
|
+
onRetry: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function UpcomingDemandPanel({ laneForecast, customerForecast, laneVariance, customerVariance, isLoading, error, onRetry, }: UpcomingDemandPanelProps): import("react").JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -8,7 +8,7 @@ export { useFleet, useVehicles, useVehicle, useDrivers, useDriver, useFleetStats
|
|
|
8
8
|
export { useInventory, useProducts, useProduct, useWarehouses, useWarehouse, useInventoryStats, } from './useInventory';
|
|
9
9
|
export { useCustomers, useCustomer, useCustomerStats } from './useCustomers';
|
|
10
10
|
export { useRoutes, useRoute, useRouteStats } from './useRoutes';
|
|
11
|
-
export { useAnalytics, useDashboardMetrics, useRevenueAnalytics, useOrderAnalytics, useFleetAnalytics, usePerformanceAnalytics, useFinanceMetrics, type FinanceMetrics, } from './useAnalytics';
|
|
11
|
+
export { useAnalytics, useDashboardMetrics, useRevenueAnalytics, useOrderAnalytics, useFleetAnalytics, usePerformanceAnalytics, useFinanceMetrics, type FinanceMetrics, useEmissionsSummary, type EmissionsSummary, } from './useAnalytics';
|
|
12
12
|
export { useTracking, useOrderTracking, useVehicleTracking, useDriverTracking, useLiveTracking, useTrackingAlerts, useGeofence, } from './useTracking';
|
|
13
13
|
export { useReports } from './useReports';
|
|
14
14
|
export { useImportExport } from './useImportExport';
|
|
@@ -133,4 +133,26 @@ export declare function usePerformanceAnalytics(): {
|
|
|
133
133
|
isLoading: boolean;
|
|
134
134
|
error: Error | null;
|
|
135
135
|
};
|
|
136
|
+
export interface EmissionsSummary {
|
|
137
|
+
totalCo2eKg: number;
|
|
138
|
+
totalDistanceKm: number;
|
|
139
|
+
averageCo2eKgPerKm: number;
|
|
140
|
+
byVehicle: Array<{
|
|
141
|
+
vehicleId: string | null;
|
|
142
|
+
vehicleNumber: string | null;
|
|
143
|
+
totalDistanceKm: number;
|
|
144
|
+
co2eKg: number;
|
|
145
|
+
}>;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Real emissions figures straight from Query.emissionsSummary (BOFF-4391).
|
|
149
|
+
* Returns totals, per-km intensity, and a per-vehicle breakdown sourced from
|
|
150
|
+
* cached route CO2e values and actual/estimated distances.
|
|
151
|
+
*/
|
|
152
|
+
export declare function useEmissionsSummary(): {
|
|
153
|
+
summary: EmissionsSummary;
|
|
154
|
+
isLoading: boolean;
|
|
155
|
+
error: Error | null;
|
|
156
|
+
refetch: () => void;
|
|
157
|
+
};
|
|
136
158
|
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Demand forecasting hook (BOFF-4393). Pulls next-N-week forecasts by lane
|
|
3
|
+
* and customer plus the recent closed-period variance. Read-side only — the
|
|
4
|
+
* admin console exposes `recalculateDemandForecasts` separately.
|
|
5
|
+
*/
|
|
6
|
+
export interface ForecastPoint {
|
|
7
|
+
scopeType: 'LANE' | 'CUSTOMER';
|
|
8
|
+
scopeKey: string;
|
|
9
|
+
periodStart: string;
|
|
10
|
+
periodEnd: string;
|
|
11
|
+
predictedVolume: number;
|
|
12
|
+
predictedRevenue: number;
|
|
13
|
+
actualVolume: number | null;
|
|
14
|
+
actualRevenue: number | null;
|
|
15
|
+
confidence: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ForecastVariance {
|
|
18
|
+
scopeType: 'LANE' | 'CUSTOMER';
|
|
19
|
+
scopeKey: string;
|
|
20
|
+
periodStart: string;
|
|
21
|
+
periodEnd: string;
|
|
22
|
+
predictedVolume: number;
|
|
23
|
+
actualVolume: number;
|
|
24
|
+
volumeVariance: number;
|
|
25
|
+
predictedRevenue: number;
|
|
26
|
+
actualRevenue: number;
|
|
27
|
+
revenueVariance: number;
|
|
28
|
+
}
|
|
29
|
+
interface UseDemandForecastResult {
|
|
30
|
+
laneForecast: ForecastPoint[];
|
|
31
|
+
customerForecast: ForecastPoint[];
|
|
32
|
+
laneVariance: ForecastVariance[];
|
|
33
|
+
customerVariance: ForecastVariance[];
|
|
34
|
+
isLoading: boolean;
|
|
35
|
+
error: Error | null;
|
|
36
|
+
refetch: () => void;
|
|
37
|
+
}
|
|
38
|
+
export declare function useDemandForecast(weeks?: number, varianceLimit?: number): UseDemandForecastResult;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createLucideIcon as e } from "../createLucideIcon.js";
|
|
2
|
+
//#region node_modules/lucide-react/dist/esm/icons/leaf.js
|
|
3
|
+
var t = e("Leaf", [["path", {
|
|
4
|
+
d: "M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z",
|
|
5
|
+
key: "nnexq3"
|
|
6
|
+
}], ["path", {
|
|
7
|
+
d: "M2 21c0-3 1.85-5.36 5.08-6C9.5 14.52 12 13 13 12",
|
|
8
|
+
key: "mt58a7"
|
|
9
|
+
}]]);
|
|
10
|
+
//#endregion
|
|
11
|
+
export { t as Leaf };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createLucideIcon as e } from "../createLucideIcon.js";
|
|
2
|
+
//#region node_modules/lucide-react/dist/esm/icons/trending-down.js
|
|
3
|
+
var t = e("TrendingDown", [["polyline", {
|
|
4
|
+
points: "22 17 13.5 8.5 8.5 13.5 2 7",
|
|
5
|
+
key: "1r2t7k"
|
|
6
|
+
}], ["polyline", {
|
|
7
|
+
points: "16 17 22 17 22 11",
|
|
8
|
+
key: "11uiuu"
|
|
9
|
+
}]]);
|
|
10
|
+
//#endregion
|
|
11
|
+
export { t as TrendingDown };
|
|
@@ -13,75 +13,78 @@ import { VolumeBar as b } from "../components/charts/VolumeBar.js";
|
|
|
13
13
|
import { StatusDonut as x } from "../components/charts/StatusDonut.js";
|
|
14
14
|
import "../components/charts/index.js";
|
|
15
15
|
import { formatCurrency as S } from "../utils/formatters.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
16
|
+
import { CarbonFootprintPanel as C } from "../components/CarbonFootprintPanel.js";
|
|
17
|
+
import { UpcomingDemandPanel as w } from "../components/UpcomingDemandPanel.js";
|
|
18
|
+
import { useDemandForecast as T } from "../hooks/useDemandForecast.js";
|
|
19
|
+
import { useMemo as E } from "react";
|
|
20
|
+
import { jsx as D, jsxs as O } from "react/jsx-runtime";
|
|
21
|
+
import { EmphasisPanel as k, PagePurpose as A } from "@burdenoff/fe-libs/ui";
|
|
19
22
|
//#region src/movethewheels/pages/AnalyticsPage.tsx
|
|
20
|
-
var
|
|
21
|
-
function
|
|
22
|
-
let { analytics:
|
|
23
|
+
var j = (e) => e.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
|
|
24
|
+
function M() {
|
|
25
|
+
let { analytics: M, isLoading: N, error: P, refetch: F } = o(), { orderData: I } = c(), { fleetData: L } = s(), { laneForecast: R, customerForecast: z, laneVariance: B, customerVariance: V, isLoading: H, error: U, refetch: W } = T(4, 8), G = E(() => M.trends.dailyOrders.map((e) => e.orders), [M.trends.dailyOrders]), K = E(() => M.trends.revenue.map((e) => ({
|
|
23
26
|
month: e.month,
|
|
24
27
|
revenue: e.revenue
|
|
25
|
-
})), [
|
|
26
|
-
name:
|
|
28
|
+
})), [M.trends.revenue]), q = E(() => I.byStatus.filter((e) => e.count > 0).map((e) => ({
|
|
29
|
+
name: j(e.status),
|
|
27
30
|
value: e.count
|
|
28
|
-
})), [
|
|
29
|
-
return /* @__PURE__ */
|
|
31
|
+
})), [I.byStatus]), J = q.reduce((e, t) => e + t.value, 0);
|
|
32
|
+
return /* @__PURE__ */ O(h, {
|
|
30
33
|
title: "Analytics",
|
|
31
34
|
subtitle: "Business performance and insights",
|
|
32
|
-
icon: /* @__PURE__ */
|
|
35
|
+
icon: /* @__PURE__ */ D(e, { size: 24 }),
|
|
33
36
|
children: [
|
|
34
|
-
/* @__PURE__ */
|
|
35
|
-
icon: /* @__PURE__ */
|
|
37
|
+
/* @__PURE__ */ D(A, {
|
|
38
|
+
icon: /* @__PURE__ */ D(e, { size: 18 }),
|
|
36
39
|
children: "See how the operation is really performing. Track order volume, revenue, on-time rate and customer satisfaction over time so you can spot trends, find bottlenecks, and decide where to invest — whether that's more vehicles, better routes, or new customers."
|
|
37
40
|
}),
|
|
38
|
-
|
|
41
|
+
P && !N ? /* @__PURE__ */ D(u, {
|
|
39
42
|
className: "border-status-error-border",
|
|
40
|
-
children: /* @__PURE__ */
|
|
43
|
+
children: /* @__PURE__ */ O(d, {
|
|
41
44
|
className: "p-6 text-center space-y-3",
|
|
42
45
|
children: [
|
|
43
|
-
/* @__PURE__ */
|
|
46
|
+
/* @__PURE__ */ D("p", {
|
|
44
47
|
className: "text-status-error-text font-medium",
|
|
45
48
|
children: "Couldn't load analytics"
|
|
46
49
|
}),
|
|
47
|
-
/* @__PURE__ */
|
|
50
|
+
/* @__PURE__ */ D("p", {
|
|
48
51
|
className: "text-sm text-text-secondary",
|
|
49
|
-
children:
|
|
52
|
+
children: P.message
|
|
50
53
|
}),
|
|
51
|
-
/* @__PURE__ */
|
|
54
|
+
/* @__PURE__ */ D(l, {
|
|
52
55
|
variant: "outline",
|
|
53
|
-
onClick:
|
|
56
|
+
onClick: F,
|
|
54
57
|
children: "Retry"
|
|
55
58
|
})
|
|
56
59
|
]
|
|
57
60
|
})
|
|
58
|
-
}) :
|
|
61
|
+
}) : N ? /* @__PURE__ */ D(v, {
|
|
59
62
|
columns: 4,
|
|
60
|
-
children: Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */
|
|
61
|
-
}) : /* @__PURE__ */
|
|
63
|
+
children: Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */ D(_, {}, t))
|
|
64
|
+
}) : /* @__PURE__ */ O(v, {
|
|
62
65
|
columns: 4,
|
|
63
66
|
children: [
|
|
64
|
-
/* @__PURE__ */
|
|
67
|
+
/* @__PURE__ */ D(g, {
|
|
65
68
|
label: "Order Volume",
|
|
66
|
-
value:
|
|
67
|
-
icon: /* @__PURE__ */
|
|
69
|
+
value: M.overview.totalOrders.toLocaleString(),
|
|
70
|
+
icon: /* @__PURE__ */ D(n, { size: 20 }),
|
|
68
71
|
accent: "brand",
|
|
69
|
-
sparklineData:
|
|
72
|
+
sparklineData: G.length >= 2 ? G : void 0
|
|
70
73
|
}),
|
|
71
|
-
/* @__PURE__ */
|
|
74
|
+
/* @__PURE__ */ D(g, {
|
|
72
75
|
treatment: "glass",
|
|
73
76
|
glow: !0,
|
|
74
77
|
label: "Revenue",
|
|
75
|
-
value: S(
|
|
76
|
-
icon: /* @__PURE__ */
|
|
78
|
+
value: S(M.overview.totalRevenue),
|
|
79
|
+
icon: /* @__PURE__ */ D(t, { size: 20 }),
|
|
77
80
|
accent: "success"
|
|
78
81
|
}),
|
|
79
|
-
/* @__PURE__ */
|
|
82
|
+
/* @__PURE__ */ D(g, {
|
|
80
83
|
label: "On-Time Delivery",
|
|
81
|
-
value: `${
|
|
82
|
-
icon: /* @__PURE__ */
|
|
84
|
+
value: `${M.overview.onTimeDeliveryRate.toFixed(1)}%`,
|
|
85
|
+
icon: /* @__PURE__ */ D(i, { size: 20 }),
|
|
83
86
|
accent: "blue",
|
|
84
|
-
delta:
|
|
87
|
+
delta: M.overview.onTimeDeliveryRate >= 90 ? {
|
|
85
88
|
value: "On target",
|
|
86
89
|
direction: "up"
|
|
87
90
|
} : {
|
|
@@ -89,19 +92,19 @@ function k() {
|
|
|
89
92
|
direction: "down"
|
|
90
93
|
}
|
|
91
94
|
}),
|
|
92
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ D(g, {
|
|
93
96
|
label: "Customer Satisfaction",
|
|
94
|
-
value:
|
|
95
|
-
icon: /* @__PURE__ */
|
|
97
|
+
value: M.overview.customerSatisfaction.toFixed(1),
|
|
98
|
+
icon: /* @__PURE__ */ D(r, { size: 20 }),
|
|
96
99
|
accent: "warning",
|
|
97
100
|
subtitle: "out of 5"
|
|
98
101
|
})
|
|
99
102
|
]
|
|
100
103
|
}),
|
|
101
|
-
/* @__PURE__ */
|
|
104
|
+
/* @__PURE__ */ O(u, { children: [/* @__PURE__ */ D(f, { children: /* @__PURE__ */ D(p, { children: "Order & delivery trend" }) }), /* @__PURE__ */ D(d, { children: /* @__PURE__ */ D(y, {
|
|
102
105
|
xKey: "date",
|
|
103
106
|
height: 300,
|
|
104
|
-
data:
|
|
107
|
+
data: M.trends.dailyOrders,
|
|
105
108
|
series: [{
|
|
106
109
|
dataKey: "orders",
|
|
107
110
|
name: "Orders"
|
|
@@ -111,89 +114,99 @@ function k() {
|
|
|
111
114
|
}],
|
|
112
115
|
emptyMessage: "No order trend recorded yet"
|
|
113
116
|
}) })] }),
|
|
114
|
-
/* @__PURE__ */
|
|
117
|
+
/* @__PURE__ */ D(w, {
|
|
118
|
+
laneForecast: R,
|
|
119
|
+
customerForecast: z,
|
|
120
|
+
laneVariance: B,
|
|
121
|
+
customerVariance: V,
|
|
122
|
+
isLoading: H,
|
|
123
|
+
error: U,
|
|
124
|
+
onRetry: W
|
|
125
|
+
}),
|
|
126
|
+
/* @__PURE__ */ O("div", {
|
|
115
127
|
className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
|
|
116
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ O(u, { children: [/* @__PURE__ */ D(f, { children: /* @__PURE__ */ D(p, { children: "Revenue by month" }) }), /* @__PURE__ */ D(d, { children: /* @__PURE__ */ D(b, {
|
|
117
129
|
xKey: "month",
|
|
118
130
|
height: 280,
|
|
119
131
|
showLegend: !1,
|
|
120
|
-
data:
|
|
132
|
+
data: K,
|
|
121
133
|
series: [{
|
|
122
134
|
dataKey: "revenue",
|
|
123
135
|
name: "Revenue"
|
|
124
136
|
}],
|
|
125
137
|
valueFormatter: (e) => S(Number(e)),
|
|
126
138
|
emptyMessage: "No revenue recorded yet"
|
|
127
|
-
}) })] }), /* @__PURE__ */
|
|
128
|
-
data:
|
|
139
|
+
}) })] }), /* @__PURE__ */ O(u, { children: [/* @__PURE__ */ D(f, { children: /* @__PURE__ */ D(p, { children: "Orders by status" }) }), /* @__PURE__ */ D(d, { children: /* @__PURE__ */ D(x, {
|
|
140
|
+
data: q,
|
|
129
141
|
height: 240,
|
|
130
|
-
centerLabel:
|
|
142
|
+
centerLabel: J.toLocaleString(),
|
|
131
143
|
centerSubLabel: "orders",
|
|
132
144
|
emptyMessage: "No orders to break down yet"
|
|
133
145
|
}) })] })]
|
|
134
146
|
}),
|
|
135
|
-
/* @__PURE__ */
|
|
147
|
+
/* @__PURE__ */ O("div", {
|
|
136
148
|
className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
|
|
137
|
-
children: [/* @__PURE__ */
|
|
149
|
+
children: [/* @__PURE__ */ O(u, { children: [/* @__PURE__ */ D(f, { children: /* @__PURE__ */ D(p, { children: "Fleet Performance" }) }), /* @__PURE__ */ O(d, {
|
|
138
150
|
className: "space-y-4",
|
|
139
|
-
children: [/* @__PURE__ */
|
|
151
|
+
children: [/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ O("div", {
|
|
140
152
|
className: "flex justify-between text-sm mb-1",
|
|
141
|
-
children: [/* @__PURE__ */
|
|
142
|
-
}), /* @__PURE__ */
|
|
153
|
+
children: [/* @__PURE__ */ D("span", { children: "Vehicle Utilization" }), /* @__PURE__ */ O("span", { children: [L.vehicleUtilization.toFixed(0), "%"] })]
|
|
154
|
+
}), /* @__PURE__ */ D(m, { value: L.vehicleUtilization })] }), L.vehiclesByType.length > 0 && /* @__PURE__ */ O("div", {
|
|
143
155
|
className: "pt-2",
|
|
144
|
-
children: [/* @__PURE__ */
|
|
156
|
+
children: [/* @__PURE__ */ D("p", {
|
|
145
157
|
className: "text-sm text-text-secondary mb-2",
|
|
146
158
|
children: "Vehicles by Type"
|
|
147
|
-
}),
|
|
159
|
+
}), L.vehiclesByType.map(({ type: e, count: t }) => /* @__PURE__ */ O("div", {
|
|
148
160
|
className: "flex justify-between text-sm py-1",
|
|
149
|
-
children: [/* @__PURE__ */
|
|
161
|
+
children: [/* @__PURE__ */ D("span", {
|
|
150
162
|
className: "capitalize",
|
|
151
163
|
children: e
|
|
152
|
-
}), /* @__PURE__ */
|
|
164
|
+
}), /* @__PURE__ */ D("span", {
|
|
153
165
|
className: "font-medium",
|
|
154
166
|
children: t
|
|
155
167
|
})]
|
|
156
168
|
}, e))]
|
|
157
169
|
})]
|
|
158
|
-
})] }), /* @__PURE__ */
|
|
170
|
+
})] }), /* @__PURE__ */ O(k, {
|
|
159
171
|
className: "space-y-4",
|
|
160
172
|
children: [
|
|
161
|
-
/* @__PURE__ */
|
|
173
|
+
/* @__PURE__ */ D("h2", {
|
|
162
174
|
className: "text-base font-semibold text-text-primary",
|
|
163
175
|
children: "Performance Metrics"
|
|
164
176
|
}),
|
|
165
|
-
/* @__PURE__ */
|
|
177
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("p", {
|
|
166
178
|
className: "text-sm text-text-secondary",
|
|
167
179
|
children: "On-Time Delivery"
|
|
168
|
-
}), /* @__PURE__ */
|
|
180
|
+
}), /* @__PURE__ */ O("p", {
|
|
169
181
|
className: "text-2xl font-bold",
|
|
170
|
-
children: [
|
|
182
|
+
children: [M.performance.onTimeDelivery.toFixed(1), "%"]
|
|
171
183
|
})] }),
|
|
172
|
-
/* @__PURE__ */
|
|
184
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("p", {
|
|
173
185
|
className: "text-sm text-text-secondary",
|
|
174
186
|
children: "Customer Satisfaction"
|
|
175
|
-
}), /* @__PURE__ */
|
|
187
|
+
}), /* @__PURE__ */ O("p", {
|
|
176
188
|
className: "text-2xl font-bold",
|
|
177
|
-
children: [
|
|
189
|
+
children: [M.overview.customerSatisfaction.toFixed(1), "/5"]
|
|
178
190
|
})] }),
|
|
179
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ O("div", {
|
|
180
192
|
className: "flex items-center gap-2",
|
|
181
|
-
children: [/* @__PURE__ */
|
|
193
|
+
children: [/* @__PURE__ */ D(a, {
|
|
182
194
|
size: 16,
|
|
183
195
|
className: "text-text-secondary"
|
|
184
|
-
}), /* @__PURE__ */
|
|
196
|
+
}), /* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("p", {
|
|
185
197
|
className: "text-sm text-text-secondary",
|
|
186
198
|
children: "Driver Ratings"
|
|
187
|
-
}), /* @__PURE__ */
|
|
199
|
+
}), /* @__PURE__ */ O("p", {
|
|
188
200
|
className: "text-2xl font-bold",
|
|
189
|
-
children: [
|
|
201
|
+
children: [M.performance.driverRatings.toFixed(1), "/5"]
|
|
190
202
|
})] })]
|
|
191
203
|
})
|
|
192
204
|
]
|
|
193
205
|
})]
|
|
194
|
-
})
|
|
206
|
+
}),
|
|
207
|
+
/* @__PURE__ */ D(C, {})
|
|
195
208
|
]
|
|
196
209
|
});
|
|
197
210
|
}
|
|
198
211
|
//#endregion
|
|
199
|
-
export {
|
|
212
|
+
export { M as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-movethewheels",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.822.1",
|
|
4
4
|
"description": "Burdenoff MoveTheWheels Microfrontend - Logistics & Supply Chain Management Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"zustand": "^5.0.0"
|
|
107
107
|
},
|
|
108
108
|
"publishConfig": {
|
|
109
|
-
"access": "
|
|
109
|
+
"access": "public"
|
|
110
110
|
},
|
|
111
111
|
"overrides": {
|
|
112
112
|
"lodash": ">=4.17.21",
|