@burdenoff/microfe-movethewheels 2026.510.105

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.
Files changed (208) hide show
  1. package/README.md +82 -0
  2. package/dist/AIAssistantPage-hD0VYJdH.js +210 -0
  3. package/dist/AnalyticsPage-DHTHCUtr.js +201 -0
  4. package/dist/CreateOrderPage-Cprg4Y9V.js +471 -0
  5. package/dist/CustomerDetailsPage-DNDEw7IW.js +239 -0
  6. package/dist/CustomersPage-CDjjeCEL.js +119 -0
  7. package/dist/DashboardPage-8iTPXRAG.js +374 -0
  8. package/dist/DataTable-CRIKfdIN.js +239 -0
  9. package/dist/DriverDetailsPage-CRyRCno7.js +297 -0
  10. package/dist/DriversPage-16O8fVmf.js +127 -0
  11. package/dist/FinancePage-BYUxK5dR.js +154 -0
  12. package/dist/FleetPage-CHYETCWT.js +293 -0
  13. package/dist/ImportExportPage-C3MKKxfc.js +232 -0
  14. package/dist/InventoryPage--822AxZM.js +223 -0
  15. package/dist/LiveTrackingPage-Dp3rTJDr.js +332 -0
  16. package/dist/MarketplacePage-DjEqudfM.js +192 -0
  17. package/dist/MetricCard-GTbxAk1a.js +135 -0
  18. package/dist/OrderDetailsPage-BIuYG0ub.js +398 -0
  19. package/dist/OrdersListPage-CW5V0Uvh.js +257 -0
  20. package/dist/PageLayout-B7b0vl0R.js +1894 -0
  21. package/dist/ProductDetailsPage-Q3X7AT-7.js +168 -0
  22. package/dist/ProductsPage-CUj9JpnW.js +131 -0
  23. package/dist/ReportsPage-DblO5CdJ.js +227 -0
  24. package/dist/RouteDetailsPage-CLctgk6A.js +240 -0
  25. package/dist/RoutesPage-8hrv6RWT.js +116 -0
  26. package/dist/SettingsPage-BJ5BQeqn.js +247 -0
  27. package/dist/StatusBadge-BrrwraIA.js +206 -0
  28. package/dist/TrackingPage-BGqHDh-w.js +322 -0
  29. package/dist/VehicleDetailsPage-XnDH4iQR.js +194 -0
  30. package/dist/VehiclesPage-Cs4XxHkA.js +127 -0
  31. package/dist/WarehouseDetailsPage-GemdMvr_.js +215 -0
  32. package/dist/WarehousesPage-QTiuDuXy.js +121 -0
  33. package/dist/arrow-left-6CiLhqVp.js +11 -0
  34. package/dist/box-BunB_4UH.js +18 -0
  35. package/dist/chart-column-DWwVEVQ-.js +22 -0
  36. package/dist/chevron-right-DhZVf20o.js +8 -0
  37. package/dist/circle-alert-D5f6RZxt.js +26 -0
  38. package/dist/circle-check-big-D-JMHcTe.js +11 -0
  39. package/dist/clock-CvwBKbQP.js +13 -0
  40. package/dist/dev/main.d.ts +1 -0
  41. package/dist/dollar-sign-CP9qeU5d.js +14 -0
  42. package/dist/download-CIuG04pJ.js +21 -0
  43. package/dist/file-text-Dd_thxkn.js +26 -0
  44. package/dist/filter-DyRMX9CU.js +8 -0
  45. package/dist/formatters-_vJlC-47.js +50 -0
  46. package/dist/generated/global-operations.d.ts +1 -0
  47. package/dist/generated/global-types.d.ts +20715 -0
  48. package/dist/generated/wspace-operations.d.ts +3704 -0
  49. package/dist/generated/wspace-types.d.ts +53362 -0
  50. package/dist/graphqlClient-CdJyR_ed.js +55 -0
  51. package/dist/index.d.ts +4 -0
  52. package/dist/index.js +772 -0
  53. package/dist/map-BqH1cBJi.js +18 -0
  54. package/dist/map-pin-CFBOmh-A.js +13 -0
  55. package/dist/movethewheels/MoveTheWheelsRoot.d.ts +25 -0
  56. package/dist/movethewheels/MoveTheWheelsRoutes.d.ts +7 -0
  57. package/dist/movethewheels/components/DataTable.d.ts +32 -0
  58. package/dist/movethewheels/components/MetricCard.d.ts +43 -0
  59. package/dist/movethewheels/components/PageLayout.d.ts +68 -0
  60. package/dist/movethewheels/components/StatusBadge.d.ts +49 -0
  61. package/dist/movethewheels/components/index.d.ts +10 -0
  62. package/dist/movethewheels/components/ui.d.ts +22 -0
  63. package/dist/movethewheels/constants/index.d.ts +24 -0
  64. package/dist/movethewheels/constants/mockData.d.ts +33 -0
  65. package/dist/movethewheels/hooks/index.d.ts +12 -0
  66. package/dist/movethewheels/hooks/useAnalytics.d.ts +118 -0
  67. package/dist/movethewheels/hooks/useCustomers.d.ts +37 -0
  68. package/dist/movethewheels/hooks/useFleet.d.ts +71 -0
  69. package/dist/movethewheels/hooks/useInventory.d.ts +60 -0
  70. package/dist/movethewheels/hooks/useOrders.d.ts +47 -0
  71. package/dist/movethewheels/hooks/useRoutes.d.ts +41 -0
  72. package/dist/movethewheels/hooks/useTracking.d.ts +69 -0
  73. package/dist/movethewheels/index.d.ts +30 -0
  74. package/dist/movethewheels/pages/AIAssistantPage.d.ts +4 -0
  75. package/dist/movethewheels/pages/AnalyticsPage.d.ts +4 -0
  76. package/dist/movethewheels/pages/CreateOrderPage.d.ts +6 -0
  77. package/dist/movethewheels/pages/CustomerDetailsPage.d.ts +4 -0
  78. package/dist/movethewheels/pages/CustomersPage.d.ts +4 -0
  79. package/dist/movethewheels/pages/DashboardPage.d.ts +6 -0
  80. package/dist/movethewheels/pages/DriverDetailsPage.d.ts +4 -0
  81. package/dist/movethewheels/pages/DriversPage.d.ts +4 -0
  82. package/dist/movethewheels/pages/FinancePage.d.ts +4 -0
  83. package/dist/movethewheels/pages/FleetPage.d.ts +6 -0
  84. package/dist/movethewheels/pages/ImportExportPage.d.ts +4 -0
  85. package/dist/movethewheels/pages/InventoryPage.d.ts +4 -0
  86. package/dist/movethewheels/pages/LiveTrackingPage.d.ts +6 -0
  87. package/dist/movethewheels/pages/MarketplacePage.d.ts +4 -0
  88. package/dist/movethewheels/pages/OrderDetailsPage.d.ts +6 -0
  89. package/dist/movethewheels/pages/OrdersListPage.d.ts +6 -0
  90. package/dist/movethewheels/pages/ProductDetailsPage.d.ts +4 -0
  91. package/dist/movethewheels/pages/ProductsPage.d.ts +4 -0
  92. package/dist/movethewheels/pages/ReportsPage.d.ts +4 -0
  93. package/dist/movethewheels/pages/RouteDetailsPage.d.ts +4 -0
  94. package/dist/movethewheels/pages/RoutesPage.d.ts +4 -0
  95. package/dist/movethewheels/pages/SettingsPage.d.ts +4 -0
  96. package/dist/movethewheels/pages/TrackingPage.d.ts +6 -0
  97. package/dist/movethewheels/pages/VehicleDetailsPage.d.ts +4 -0
  98. package/dist/movethewheels/pages/VehiclesPage.d.ts +4 -0
  99. package/dist/movethewheels/pages/WarehouseDetailsPage.d.ts +4 -0
  100. package/dist/movethewheels/pages/WarehousesPage.d.ts +4 -0
  101. package/dist/movethewheels/providers/MoveTheWheelsProvider.d.ts +16 -0
  102. package/dist/movethewheels/store/movethewheelsStore.d.ts +73 -0
  103. package/dist/movethewheels/types/index.d.ts +655 -0
  104. package/dist/movethewheels/utils/cn.d.ts +6 -0
  105. package/dist/movethewheels/utils/formatters.d.ts +60 -0
  106. package/dist/movethewheels/utils/graphqlClient.d.ts +11 -0
  107. package/dist/movethewheels/utils/index.d.ts +7 -0
  108. package/dist/movethewheels/utils/navigation.d.ts +23 -0
  109. package/dist/navigation-BgnOfsVd.js +6 -0
  110. package/dist/navigation-C2fY_aS9.js +8 -0
  111. package/dist/package-DVZbDRcV.js +22 -0
  112. package/dist/phone-KdwpVmC4.js +18 -0
  113. package/dist/plus-Bl7uX6Ji.js +11 -0
  114. package/dist/refresh-cw-BYjl3K-8.js +22 -0
  115. package/dist/route-Ce_poKFi.js +51 -0
  116. package/dist/save-C-qDVat-.js +18 -0
  117. package/dist/search-5pdn5eOO.js +13 -0
  118. package/dist/settings-C4kIDsYg.js +28 -0
  119. package/dist/square-pen-BwQ67vLE.js +11 -0
  120. package/dist/star-BlVsC3Ad.js +8 -0
  121. package/dist/store-DTmQT5M0.js +26 -0
  122. package/dist/trending-up-C1faflCI.js +11 -0
  123. package/dist/triangle-alert-CUoVAA4L.js +18 -0
  124. package/dist/truck-BmDAzu05.js +30 -0
  125. package/dist/useAnalytics-ph7eTIK6.js +297 -0
  126. package/dist/useCustomers-bS3a4ytk.js +186 -0
  127. package/dist/useFleet-BdETplNE.js +398 -0
  128. package/dist/useInventory-Dwn18FPz.js +323 -0
  129. package/dist/useOrders-D_3_hGMp.js +324 -0
  130. package/dist/useRoutes-v4aBaS-E.js +224 -0
  131. package/dist/useTracking-De2KIUNu.js +261 -0
  132. package/dist/user-BplzDrLP.js +13 -0
  133. package/dist/users-i-igmsP4.js +24 -0
  134. package/dist/warehouse-DewG0PXh.js +25 -0
  135. package/dist/wrench-CoSDEIC7.js +31 -0
  136. package/package.json +107 -0
  137. package/src/dev/main.tsx +110 -0
  138. package/src/dev/styles.css +139 -0
  139. package/src/generated/global-operations.ts +2 -0
  140. package/src/generated/global-types.ts +24048 -0
  141. package/src/generated/wspace-operations.ts +3734 -0
  142. package/src/generated/wspace-types.ts +60715 -0
  143. package/src/index.ts +4 -0
  144. package/src/movethewheels/MoveTheWheelsRoot.tsx +258 -0
  145. package/src/movethewheels/MoveTheWheelsRoutes.tsx +119 -0
  146. package/src/movethewheels/components/DataTable.tsx +367 -0
  147. package/src/movethewheels/components/MetricCard.tsx +180 -0
  148. package/src/movethewheels/components/PageLayout.tsx +234 -0
  149. package/src/movethewheels/components/StatusBadge.tsx +243 -0
  150. package/src/movethewheels/components/index.ts +26 -0
  151. package/src/movethewheels/components/ui.tsx +124 -0
  152. package/src/movethewheels/constants/index.ts +65 -0
  153. package/src/movethewheels/constants/mockData.ts +1342 -0
  154. package/src/movethewheels/hooks/index.ts +55 -0
  155. package/src/movethewheels/hooks/useAnalytics.ts +476 -0
  156. package/src/movethewheels/hooks/useCustomers.ts +359 -0
  157. package/src/movethewheels/hooks/useFleet.ts +778 -0
  158. package/src/movethewheels/hooks/useInventory.ts +632 -0
  159. package/src/movethewheels/hooks/useOrders.ts +703 -0
  160. package/src/movethewheels/hooks/useRoutes.ts +453 -0
  161. package/src/movethewheels/hooks/useTracking.ts +505 -0
  162. package/src/movethewheels/index.ts +68 -0
  163. package/src/movethewheels/pages/AIAssistantPage.tsx +160 -0
  164. package/src/movethewheels/pages/AnalyticsPage.tsx +190 -0
  165. package/src/movethewheels/pages/CreateOrderPage.tsx +454 -0
  166. package/src/movethewheels/pages/CustomerDetailsPage.tsx +207 -0
  167. package/src/movethewheels/pages/CustomersPage.tsx +115 -0
  168. package/src/movethewheels/pages/DashboardPage.tsx +414 -0
  169. package/src/movethewheels/pages/DriverDetailsPage.tsx +261 -0
  170. package/src/movethewheels/pages/DriversPage.tsx +118 -0
  171. package/src/movethewheels/pages/FinancePage.tsx +141 -0
  172. package/src/movethewheels/pages/FleetPage.tsx +289 -0
  173. package/src/movethewheels/pages/ImportExportPage.tsx +165 -0
  174. package/src/movethewheels/pages/InventoryPage.tsx +212 -0
  175. package/src/movethewheels/pages/LiveTrackingPage.tsx +325 -0
  176. package/src/movethewheels/pages/MarketplacePage.tsx +235 -0
  177. package/src/movethewheels/pages/OrderDetailsPage.tsx +387 -0
  178. package/src/movethewheels/pages/OrdersListPage.tsx +241 -0
  179. package/src/movethewheels/pages/ProductDetailsPage.tsx +155 -0
  180. package/src/movethewheels/pages/ProductsPage.tsx +124 -0
  181. package/src/movethewheels/pages/ReportsPage.tsx +164 -0
  182. package/src/movethewheels/pages/RouteDetailsPage.tsx +245 -0
  183. package/src/movethewheels/pages/RoutesPage.tsx +104 -0
  184. package/src/movethewheels/pages/SettingsPage.tsx +242 -0
  185. package/src/movethewheels/pages/TrackingPage.tsx +419 -0
  186. package/src/movethewheels/pages/VehicleDetailsPage.tsx +218 -0
  187. package/src/movethewheels/pages/VehiclesPage.tsx +124 -0
  188. package/src/movethewheels/pages/WarehouseDetailsPage.tsx +216 -0
  189. package/src/movethewheels/pages/WarehousesPage.tsx +122 -0
  190. package/src/movethewheels/providers/MoveTheWheelsProvider.tsx +66 -0
  191. package/src/movethewheels/store/movethewheelsStore.ts +136 -0
  192. package/src/movethewheels/types/index.ts +744 -0
  193. package/src/movethewheels/utils/cn.ts +9 -0
  194. package/src/movethewheels/utils/formatters.ts +215 -0
  195. package/src/movethewheels/utils/graphqlClient.ts +63 -0
  196. package/src/movethewheels/utils/index.ts +8 -0
  197. package/src/movethewheels/utils/navigation.ts +70 -0
  198. package/src/operations/global/.gitkeep +0 -0
  199. package/src/operations/wspace/movethewheels/fragments/core.graphql +191 -0
  200. package/src/operations/wspace/movethewheels/mutations/entities.graphql +87 -0
  201. package/src/operations/wspace/movethewheels/mutations/logistics.graphql +86 -0
  202. package/src/operations/wspace/movethewheels/mutations/marketplace-reports.graphql +81 -0
  203. package/src/operations/wspace/movethewheels/mutations/orders.graphql +21 -0
  204. package/src/operations/wspace/movethewheels/queries/dashboard.graphql +61 -0
  205. package/src/operations/wspace/movethewheels/queries/entities.graphql +83 -0
  206. package/src/operations/wspace/movethewheels/queries/logistics.graphql +84 -0
  207. package/src/operations/wspace/movethewheels/queries/marketplace-reports.graphql +40 -0
  208. package/src/operations/wspace/movethewheels/queries/orders.graphql +43 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Vehicles Page - List of all vehicles
3
+ */
4
+
5
+ import { Truck, Plus, RefreshCw, Download } from 'lucide-react';
6
+ import { PageLayout } from '../components/PageLayout';
7
+ import { DataTable, type Column } from '../components/DataTable';
8
+ import { StatusBadge, VehicleTypeBadge } from '../components/StatusBadge';
9
+ import { Button, Progress } from '../components/ui';
10
+ import { useVehicles } from '../hooks/useFleet';
11
+ import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
12
+ import { joinPath } from '../utils/navigation';
13
+ import type { Vehicle } from '../types';
14
+
15
+ export default function VehiclesPage() {
16
+ const { basePath, navigate } = useMoveTheWheels();
17
+ const { vehicles, totalVehicles, isLoading, refetch } = useVehicles();
18
+
19
+ const goTo = (path: string) => {
20
+ if (navigate) {
21
+ navigate(joinPath(basePath, path));
22
+ }
23
+ };
24
+
25
+ const columns: Column<Vehicle>[] = [
26
+ {
27
+ id: 'vehicleNumber',
28
+ header: 'Vehicle #',
29
+ accessorKey: 'vehicleNumber',
30
+ sortable: true,
31
+ cell: (row) => <span className="font-medium">{row.vehicleNumber}</span>,
32
+ },
33
+ {
34
+ id: 'type',
35
+ header: 'Type',
36
+ accessorKey: 'type',
37
+ cell: (row) => <VehicleTypeBadge type={row.type} />,
38
+ },
39
+ {
40
+ id: 'details',
41
+ header: 'Vehicle',
42
+ cell: (row) => (
43
+ <div>
44
+ <p className="font-medium">
45
+ {row.make} {row.model}
46
+ </p>
47
+ <p className="text-sm text-muted-foreground">{row.year}</p>
48
+ </div>
49
+ ),
50
+ },
51
+ {
52
+ id: 'status',
53
+ header: 'Status',
54
+ accessorKey: 'status',
55
+ sortable: true,
56
+ cell: (row) => <StatusBadge status={row.status} type="vehicle" />,
57
+ },
58
+ {
59
+ id: 'capacity',
60
+ header: 'Capacity',
61
+ cell: (row) => (
62
+ <div className="text-sm">
63
+ <p>{row.capacity.weight} kg</p>
64
+ <p className="text-muted-foreground">{row.capacity.volume} m³</p>
65
+ </div>
66
+ ),
67
+ },
68
+ {
69
+ id: 'fuel',
70
+ header: 'Fuel Level',
71
+ cell: (row) =>
72
+ row.fuelLevel !== undefined ? (
73
+ <div className="flex items-center gap-2">
74
+ <Progress value={row.fuelLevel} className="w-16 h-2" />
75
+ <span className="text-sm">{row.fuelLevel}%</span>
76
+ </div>
77
+ ) : (
78
+ '-'
79
+ ),
80
+ },
81
+ {
82
+ id: 'mileage',
83
+ header: 'Mileage',
84
+ accessorKey: 'mileage',
85
+ sortable: true,
86
+ cell: (row) => (row.mileage ? `${row.mileage.toLocaleString()} mi` : '-'),
87
+ },
88
+ ];
89
+
90
+ return (
91
+ <PageLayout
92
+ title="Vehicles"
93
+ subtitle={`${totalVehicles} vehicles in fleet`}
94
+ icon={<Truck size={24} />}
95
+ headerActions={
96
+ <div className="flex gap-2">
97
+ <Button variant="outline" onClick={refetch}>
98
+ <RefreshCw size={16} />
99
+ Refresh
100
+ </Button>
101
+ <Button variant="outline">
102
+ <Download size={16} />
103
+ Export
104
+ </Button>
105
+ <Button>
106
+ <Plus size={16} />
107
+ Add Vehicle
108
+ </Button>
109
+ </div>
110
+ }
111
+ >
112
+ <DataTable
113
+ columns={columns}
114
+ data={vehicles}
115
+ isLoading={isLoading}
116
+ searchable
117
+ searchPlaceholder="Search vehicles..."
118
+ searchFields={['vehicleNumber', 'make', 'model'] as (keyof Vehicle)[]}
119
+ onRowClick={(row) => goTo(`fleet/vehicles/${row.id}`)}
120
+ getRowId={(row) => row.id}
121
+ />
122
+ </PageLayout>
123
+ );
124
+ }
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Warehouse Details Page
3
+ */
4
+
5
+ import { useParams } from 'react-router-dom';
6
+ import { Warehouse, ArrowLeft, Edit, MapPin, Clock, Users, Box } from 'lucide-react';
7
+ import { PageLayout, LoadingState, ErrorState } from '../components/PageLayout';
8
+ import {
9
+ Card,
10
+ CardContent,
11
+ CardHeader,
12
+ CardTitle,
13
+ Button,
14
+ Badge,
15
+ Progress,
16
+ } from '../components/ui';
17
+ import { useWarehouse } from '../hooks/useInventory';
18
+ import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
19
+ import { formatAddress } from '../utils/formatters';
20
+ import { joinPath } from '../utils/navigation';
21
+
22
+ export default function WarehouseDetailsPage() {
23
+ const { warehouseId } = useParams<{ warehouseId: string }>();
24
+ const { basePath, navigate } = useMoveTheWheels();
25
+ const { warehouse, isLoading, error, refetch } = useWarehouse(warehouseId);
26
+
27
+ const goBack = () => navigate?.(joinPath(basePath, 'inventory/warehouses'));
28
+
29
+ if (isLoading) return <LoadingState message="Loading warehouse details..." />;
30
+ if (error || !warehouse) return <ErrorState title="Warehouse not found" onRetry={refetch} />;
31
+
32
+ const utilization = (warehouse.capacity.usedSpace / warehouse.capacity.totalSpace) * 100;
33
+
34
+ return (
35
+ <PageLayout
36
+ title={warehouse.name}
37
+ subtitle={`Code: ${warehouse.code}`}
38
+ icon={<Warehouse size={24} />}
39
+ headerActions={
40
+ <div className="flex gap-2">
41
+ <Button variant="outline" onClick={goBack}>
42
+ <ArrowLeft size={16} /> Back
43
+ </Button>
44
+ <Button>
45
+ <Edit size={16} /> Edit
46
+ </Button>
47
+ </div>
48
+ }
49
+ headerContent={
50
+ <div className="flex gap-2">
51
+ <Badge variant={warehouse.isActive ? 'default' : 'secondary'}>
52
+ {warehouse.isActive ? 'Active' : 'Inactive'}
53
+ </Badge>
54
+ <Badge variant="outline" className="capitalize">
55
+ {warehouse.type.replace('_', ' ')}
56
+ </Badge>
57
+ </div>
58
+ }
59
+ >
60
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
61
+ <div className="lg:col-span-2 space-y-6">
62
+ <Card>
63
+ <CardHeader>
64
+ <CardTitle className="flex items-center gap-2">
65
+ <Box size={18} /> Capacity
66
+ </CardTitle>
67
+ </CardHeader>
68
+ <CardContent>
69
+ <div className="space-y-4">
70
+ <div>
71
+ <div className="flex justify-between text-sm mb-2">
72
+ <span>Space Utilization</span>
73
+ <span>{utilization.toFixed(0)}%</span>
74
+ </div>
75
+ <Progress value={utilization} />
76
+ <p className="text-sm text-muted-foreground mt-1">
77
+ {warehouse.capacity.usedSpace.toLocaleString()} /{' '}
78
+ {warehouse.capacity.totalSpace.toLocaleString()} sq ft
79
+ </p>
80
+ </div>
81
+ <div className="grid grid-cols-2 gap-4">
82
+ <div>
83
+ <p className="text-sm text-muted-foreground">Pallets Used</p>
84
+ <p className="text-2xl font-bold">
85
+ {warehouse.capacity.usedPallets}
86
+ <span className="text-sm font-normal text-muted-foreground">
87
+ {' '}
88
+ / {warehouse.capacity.totalPallets}
89
+ </span>
90
+ </p>
91
+ </div>
92
+ </div>
93
+ </div>
94
+ </CardContent>
95
+ </Card>
96
+
97
+ <Card>
98
+ <CardHeader>
99
+ <CardTitle>Zones ({warehouse.zones.length})</CardTitle>
100
+ </CardHeader>
101
+ <CardContent>
102
+ <div className="space-y-3">
103
+ {warehouse.zones.map((zone) => (
104
+ <div
105
+ key={zone.id}
106
+ className="flex items-center justify-between p-3 border rounded-lg"
107
+ >
108
+ <div>
109
+ <p className="font-medium">{zone.name}</p>
110
+ <p className="text-sm text-muted-foreground capitalize">
111
+ {zone.type} - {zone.location}
112
+ </p>
113
+ </div>
114
+ <div className="text-right">
115
+ <Progress
116
+ value={(zone.currentOccupancy / zone.capacity) * 100}
117
+ className="w-24 h-2"
118
+ />
119
+ <p className="text-sm text-muted-foreground">
120
+ {zone.currentOccupancy} / {zone.capacity}
121
+ </p>
122
+ </div>
123
+ </div>
124
+ ))}
125
+ </div>
126
+ </CardContent>
127
+ </Card>
128
+
129
+ <Card>
130
+ <CardHeader>
131
+ <CardTitle className="flex items-center gap-2">
132
+ <Clock size={18} /> Operating Hours
133
+ </CardTitle>
134
+ </CardHeader>
135
+ <CardContent>
136
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
137
+ {Object.entries(warehouse.operatingHours).map(([day, hours]) => (
138
+ <div key={day}>
139
+ <p className="text-sm font-medium">{day}</p>
140
+ <p className="text-sm text-muted-foreground">
141
+ {hours ? `${hours.open} - ${hours.close}` : 'Closed'}
142
+ </p>
143
+ </div>
144
+ ))}
145
+ </div>
146
+ </CardContent>
147
+ </Card>
148
+ </div>
149
+
150
+ <div className="space-y-6">
151
+ <Card>
152
+ <CardHeader>
153
+ <CardTitle className="flex items-center gap-2">
154
+ <MapPin size={18} /> Location
155
+ </CardTitle>
156
+ </CardHeader>
157
+ <CardContent>
158
+ <p className="text-sm">{formatAddress(warehouse.address)}</p>
159
+ </CardContent>
160
+ </Card>
161
+
162
+ <Card>
163
+ <CardHeader>
164
+ <CardTitle>Metrics</CardTitle>
165
+ </CardHeader>
166
+ <CardContent className="space-y-3">
167
+ <div>
168
+ <p className="text-sm text-muted-foreground">Throughput</p>
169
+ <p className="text-2xl font-bold">
170
+ {warehouse.metrics.throughput}
171
+ <span className="text-sm font-normal"> orders/day</span>
172
+ </p>
173
+ </div>
174
+ <div>
175
+ <p className="text-sm text-muted-foreground">Accuracy</p>
176
+ <p className="text-2xl font-bold">{warehouse.metrics.accuracy}%</p>
177
+ </div>
178
+ <div>
179
+ <p className="text-sm text-muted-foreground">Productivity</p>
180
+ <p className="text-2xl font-bold">{warehouse.metrics.productivity}%</p>
181
+ </div>
182
+ <div>
183
+ <p className="text-sm text-muted-foreground">Orders Fulfilled</p>
184
+ <p className="text-2xl font-bold">
185
+ {warehouse.metrics.ordersFulfilled.toLocaleString()}
186
+ </p>
187
+ </div>
188
+ </CardContent>
189
+ </Card>
190
+
191
+ <Card>
192
+ <CardHeader>
193
+ <CardTitle className="flex items-center gap-2">
194
+ <Users size={18} /> Staff ({warehouse.staff.length})
195
+ </CardTitle>
196
+ </CardHeader>
197
+ <CardContent>
198
+ {warehouse.staff.length > 0 ? (
199
+ <div className="space-y-2">
200
+ {warehouse.staff.map((member, i) => (
201
+ <div key={i} className="flex items-center justify-between p-2 border rounded">
202
+ <span className="text-sm capitalize">{member.role}</span>
203
+ <Badge variant="outline">{member.shift}</Badge>
204
+ </div>
205
+ ))}
206
+ </div>
207
+ ) : (
208
+ <p className="text-muted-foreground">No staff assigned</p>
209
+ )}
210
+ </CardContent>
211
+ </Card>
212
+ </div>
213
+ </div>
214
+ </PageLayout>
215
+ );
216
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Warehouses Page
3
+ */
4
+
5
+ import { Warehouse, Plus, RefreshCw } from 'lucide-react';
6
+ import { PageLayout } from '../components/PageLayout';
7
+ import { DataTable, type Column } from '../components/DataTable';
8
+ import { Button, Badge, Progress } from '../components/ui';
9
+ import { useWarehouses } from '../hooks/useInventory';
10
+ import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
11
+ import { joinPath } from '../utils/navigation';
12
+ import type { Warehouse as WarehouseType } from '../types';
13
+
14
+ export default function WarehousesPage() {
15
+ const { basePath, navigate } = useMoveTheWheels();
16
+ const { warehouses, totalWarehouses, isLoading, refetch } = useWarehouses();
17
+
18
+ const goTo = (path: string) => navigate?.(joinPath(basePath, path));
19
+
20
+ const columns: Column<WarehouseType>[] = [
21
+ {
22
+ id: 'name',
23
+ header: 'Warehouse',
24
+ accessorKey: 'name',
25
+ sortable: true,
26
+ cell: (row) => (
27
+ <div>
28
+ <p className="font-medium">{row.name}</p>
29
+ <p className="text-sm text-muted-foreground">{row.code}</p>
30
+ </div>
31
+ ),
32
+ },
33
+ {
34
+ id: 'location',
35
+ header: 'Location',
36
+ cell: (row) => (
37
+ <div>
38
+ <p>
39
+ {row.address.city}, {row.address.state}
40
+ </p>
41
+ <p className="text-sm text-muted-foreground">{row.address.country}</p>
42
+ </div>
43
+ ),
44
+ },
45
+ {
46
+ id: 'type',
47
+ header: 'Type',
48
+ accessorKey: 'type',
49
+ cell: (row) => (
50
+ <Badge variant="outline" className="capitalize">
51
+ {row.type.replace('_', ' ')}
52
+ </Badge>
53
+ ),
54
+ },
55
+ {
56
+ id: 'utilization',
57
+ header: 'Utilization',
58
+ cell: (row) => {
59
+ const pct = (row.capacity.usedSpace / row.capacity.totalSpace) * 100;
60
+ return (
61
+ <div className="flex items-center gap-2">
62
+ <Progress value={pct} className="w-16 h-2" />
63
+ <span className="text-sm">{pct.toFixed(0)}%</span>
64
+ </div>
65
+ );
66
+ },
67
+ },
68
+ {
69
+ id: 'capacity',
70
+ header: 'Capacity',
71
+ cell: (row) => (
72
+ <div className="text-sm">
73
+ <p>
74
+ {row.capacity.usedSpace.toLocaleString()} / {row.capacity.totalSpace.toLocaleString()}{' '}
75
+ sq ft
76
+ </p>
77
+ <p className="text-muted-foreground">
78
+ {row.capacity.usedPallets} / {row.capacity.totalPallets} pallets
79
+ </p>
80
+ </div>
81
+ ),
82
+ },
83
+ {
84
+ id: 'status',
85
+ header: 'Status',
86
+ cell: (row) => (
87
+ <Badge variant={row.isActive ? 'default' : 'secondary'}>
88
+ {row.isActive ? 'Active' : 'Inactive'}
89
+ </Badge>
90
+ ),
91
+ },
92
+ ];
93
+
94
+ return (
95
+ <PageLayout
96
+ title="Warehouses"
97
+ subtitle={`${totalWarehouses} warehouses`}
98
+ icon={<Warehouse size={24} />}
99
+ headerActions={
100
+ <div className="flex gap-2">
101
+ <Button variant="outline" onClick={refetch}>
102
+ <RefreshCw size={16} /> Refresh
103
+ </Button>
104
+ <Button>
105
+ <Plus size={16} /> Add Warehouse
106
+ </Button>
107
+ </div>
108
+ }
109
+ >
110
+ <DataTable
111
+ columns={columns}
112
+ data={warehouses}
113
+ isLoading={isLoading}
114
+ searchable
115
+ searchPlaceholder="Search warehouses..."
116
+ searchFields={['name', 'code'] as (keyof WarehouseType)[]}
117
+ onRowClick={(row) => goTo(`inventory/warehouses/${row.id}`)}
118
+ getRowId={(row) => row.id}
119
+ />
120
+ </PageLayout>
121
+ );
122
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * MoveTheWheels Provider
3
+ *
4
+ * Provides context for the entire microfrontend including navigation,
5
+ * user info, workspace context, and API configuration.
6
+ */
7
+
8
+ import { createContext, useContext, useMemo, type FC, type PropsWithChildren } from 'react';
9
+ import { MemoryRouter } from 'react-router-dom';
10
+ import type { MoveTheWheelsRootProps, MoveTheWheelsContextValue } from '../types';
11
+
12
+ const MoveTheWheelsContext = createContext<MoveTheWheelsContextValue | null>(null);
13
+
14
+ export interface MoveTheWheelsProviderProps extends PropsWithChildren<MoveTheWheelsRootProps> {}
15
+
16
+ export const MoveTheWheelsProvider: FC<MoveTheWheelsProviderProps> = ({ children, ...props }) => {
17
+ const contextValue = useMemo<MoveTheWheelsContextValue>(
18
+ () => ({
19
+ ...props,
20
+ }),
21
+ [props]
22
+ );
23
+
24
+ if (props.basePath) {
25
+ return (
26
+ <MoveTheWheelsContext.Provider value={contextValue}>{children}</MoveTheWheelsContext.Provider>
27
+ );
28
+ }
29
+
30
+ return (
31
+ <MoveTheWheelsContext.Provider value={contextValue}>
32
+ <MemoryRouter>{children}</MemoryRouter>
33
+ </MoveTheWheelsContext.Provider>
34
+ );
35
+ };
36
+
37
+ /**
38
+ * Hook to access the MoveTheWheels context.
39
+ *
40
+ * @throws Error if used outside of MoveTheWheelsProvider
41
+ */
42
+ export function useMoveTheWheels(): MoveTheWheelsContextValue {
43
+ const context = useContext(MoveTheWheelsContext);
44
+ if (!context) {
45
+ throw new Error('useMoveTheWheels must be used within a MoveTheWheelsProvider');
46
+ }
47
+ return context;
48
+ }
49
+
50
+ /**
51
+ * Hook to get the navigate function from context.
52
+ */
53
+ export function useMoveTheWheelsNavigate(): (path: string) => void {
54
+ const { navigate, basePath } = useMoveTheWheels();
55
+
56
+ return (path: string) => {
57
+ // If path is absolute (starts with /), use it directly
58
+ // Otherwise, prepend basePath
59
+ if (path.startsWith('/')) {
60
+ navigate(path);
61
+ } else {
62
+ const cleanBase = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;
63
+ navigate(`${cleanBase}/${path}`);
64
+ }
65
+ };
66
+ }
@@ -0,0 +1,136 @@
1
+ /**
2
+ * MoveTheWheels Zustand Store
3
+ *
4
+ * Manages UI state for the microfrontend.
5
+ * Server/entity data comes from hooks with mock data (ready for GraphQL replacement).
6
+ */
7
+
8
+ import { create } from 'zustand';
9
+ import { devtools, persist } from 'zustand/middleware';
10
+ import { createProfileScopedStorage } from '@burdenoff/fe-libs/shared/utils';
11
+ import type { OrderFilter, FleetFilter, InventoryFilter, CustomerFilter } from '../types';
12
+
13
+ interface MoveTheWheelsState {
14
+ // View state
15
+ viewMode: 'grid' | 'list' | 'table';
16
+ sidebarCollapsed: boolean;
17
+
18
+ // Selection state
19
+ selectedOrderId: string | null;
20
+ selectedVehicleId: string | null;
21
+ selectedDriverId: string | null;
22
+ selectedCustomerId: string | null;
23
+ selectedWarehouseId: string | null;
24
+ selectedRouteId: string | null;
25
+
26
+ // Filters
27
+ orderFilters: OrderFilter;
28
+ fleetFilters: FleetFilter;
29
+ inventoryFilters: InventoryFilter;
30
+ customerFilters: CustomerFilter;
31
+
32
+ // Search
33
+ globalSearch: string;
34
+
35
+ // Actions
36
+ setViewMode: (mode: 'grid' | 'list' | 'table') => void;
37
+ setSidebarCollapsed: (collapsed: boolean) => void;
38
+ toggleSidebar: () => void;
39
+
40
+ setSelectedOrderId: (id: string | null) => void;
41
+ setSelectedVehicleId: (id: string | null) => void;
42
+ setSelectedDriverId: (id: string | null) => void;
43
+ setSelectedCustomerId: (id: string | null) => void;
44
+ setSelectedWarehouseId: (id: string | null) => void;
45
+ setSelectedRouteId: (id: string | null) => void;
46
+
47
+ setOrderFilters: (filters: Partial<OrderFilter>) => void;
48
+ setFleetFilters: (filters: Partial<FleetFilter>) => void;
49
+ setInventoryFilters: (filters: Partial<InventoryFilter>) => void;
50
+ setCustomerFilters: (filters: Partial<CustomerFilter>) => void;
51
+ clearAllFilters: () => void;
52
+
53
+ setGlobalSearch: (search: string) => void;
54
+
55
+ // Reset
56
+ reset: () => void;
57
+ }
58
+
59
+ const initialState = {
60
+ viewMode: 'table' as const,
61
+ sidebarCollapsed: false,
62
+ selectedOrderId: null,
63
+ selectedVehicleId: null,
64
+ selectedDriverId: null,
65
+ selectedCustomerId: null,
66
+ selectedWarehouseId: null,
67
+ selectedRouteId: null,
68
+ orderFilters: {},
69
+ fleetFilters: {},
70
+ inventoryFilters: {},
71
+ customerFilters: {},
72
+ globalSearch: '',
73
+ };
74
+
75
+ export const useMoveTheWheelsStore = create<MoveTheWheelsState>()(
76
+ devtools(
77
+ persist(
78
+ (set) => ({
79
+ ...initialState,
80
+
81
+ // View actions
82
+ setViewMode: (mode) => set({ viewMode: mode }),
83
+ setSidebarCollapsed: (collapsed) => set({ sidebarCollapsed: collapsed }),
84
+ toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),
85
+
86
+ // Selection actions
87
+ setSelectedOrderId: (id) => set({ selectedOrderId: id }),
88
+ setSelectedVehicleId: (id) => set({ selectedVehicleId: id }),
89
+ setSelectedDriverId: (id) => set({ selectedDriverId: id }),
90
+ setSelectedCustomerId: (id) => set({ selectedCustomerId: id }),
91
+ setSelectedWarehouseId: (id) => set({ selectedWarehouseId: id }),
92
+ setSelectedRouteId: (id) => set({ selectedRouteId: id }),
93
+
94
+ // Filter actions
95
+ setOrderFilters: (filters) =>
96
+ set((state) => ({
97
+ orderFilters: { ...state.orderFilters, ...filters },
98
+ })),
99
+ setFleetFilters: (filters) =>
100
+ set((state) => ({
101
+ fleetFilters: { ...state.fleetFilters, ...filters },
102
+ })),
103
+ setInventoryFilters: (filters) =>
104
+ set((state) => ({
105
+ inventoryFilters: { ...state.inventoryFilters, ...filters },
106
+ })),
107
+ setCustomerFilters: (filters) =>
108
+ set((state) => ({
109
+ customerFilters: { ...state.customerFilters, ...filters },
110
+ })),
111
+ clearAllFilters: () =>
112
+ set({
113
+ orderFilters: {},
114
+ fleetFilters: {},
115
+ inventoryFilters: {},
116
+ customerFilters: {},
117
+ }),
118
+
119
+ // Search
120
+ setGlobalSearch: (search) => set({ globalSearch: search }),
121
+
122
+ // Reset
123
+ reset: () => set(initialState),
124
+ }),
125
+ {
126
+ name: 'movethewheels-storage',
127
+ storage: createProfileScopedStorage(),
128
+ partialize: (state) => ({
129
+ viewMode: state.viewMode,
130
+ sidebarCollapsed: state.sidebarCollapsed,
131
+ }),
132
+ }
133
+ ),
134
+ { name: 'MoveTheWheelsStore' }
135
+ )
136
+ );