@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,505 @@
1
+ import { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
3
+ import type { Location, Tracking, TrackingAlert } from '../types';
4
+ import { executeGraphQL } from '../utils/graphqlClient';
5
+ import { useDriver, useDrivers, useVehicle, useVehicles } from './useFleet';
6
+ import { useOrder, useOrders } from './useOrders';
7
+
8
+ interface UseTrackingOptions {
9
+ entityId?: string;
10
+ entityType?: 'order' | 'vehicle' | 'driver';
11
+ realtime?: boolean;
12
+ }
13
+
14
+ interface UseTrackingResult {
15
+ tracking: Tracking[];
16
+ isLoading: boolean;
17
+ error: Error | null;
18
+ refetch: () => void;
19
+ }
20
+
21
+ interface ApiTrackingEvent {
22
+ id: string;
23
+ shipmentId: string;
24
+ eventType: string;
25
+ location?: Record<string, unknown> | null;
26
+ details?: string | null;
27
+ timestamp: string;
28
+ }
29
+
30
+ interface ApiShipment {
31
+ id: string;
32
+ shipmentNumber: string;
33
+ orderId: string;
34
+ status: string;
35
+ estimatedDelivery?: string | null;
36
+ trackingEvents?: ApiTrackingEvent[];
37
+ }
38
+
39
+ const SHIPMENTS_QUERY = `
40
+ query ListShipments($filter: ShipmentFilterInput, $pagination: PaginationInput) {
41
+ shipments(filter: $filter, pagination: $pagination) {
42
+ id
43
+ shipmentNumber
44
+ orderId
45
+ status
46
+ estimatedDelivery
47
+ }
48
+ }
49
+ `;
50
+
51
+ const SHIPMENT_QUERY = `
52
+ query GetShipment($id: ID!) {
53
+ shipment(id: $id) {
54
+ id
55
+ shipmentNumber
56
+ orderId
57
+ status
58
+ estimatedDelivery
59
+ trackingEvents {
60
+ id
61
+ shipmentId
62
+ eventType
63
+ location
64
+ details
65
+ timestamp
66
+ }
67
+ }
68
+ }
69
+ `;
70
+
71
+ const ORDER_TRACKING_QUERY = `
72
+ query GetOrderTracking($orderId: ID!) {
73
+ orderTracking(orderId: $orderId) {
74
+ id
75
+ shipmentId
76
+ eventType
77
+ location
78
+ details
79
+ timestamp
80
+ }
81
+ }
82
+ `;
83
+
84
+ const ACTIVE_DELIVERIES_QUERY = `
85
+ query GetActiveDeliveries {
86
+ activeDeliveries {
87
+ id
88
+ shipmentNumber
89
+ orderId
90
+ status
91
+ estimatedDelivery
92
+ }
93
+ }
94
+ `;
95
+
96
+ const TRACKING_ALERTS_QUERY = `
97
+ query GetTrackingAlerts {
98
+ trackingAlerts {
99
+ shipmentId
100
+ shipmentNumber
101
+ alertType
102
+ message
103
+ }
104
+ }
105
+ `;
106
+
107
+ function mapTrackingEventToTracking(event: ApiTrackingEvent, entityId: string): Tracking {
108
+ const location = {
109
+ latitude: Number((event.location?.latitude as number | undefined) ?? 0),
110
+ longitude: Number((event.location?.longitude as number | undefined) ?? 0),
111
+ address: (event.location?.address as string | undefined) ?? undefined,
112
+ timestamp: new Date(event.timestamp),
113
+ };
114
+
115
+ return {
116
+ id: event.id,
117
+ entityId,
118
+ entityType: 'order',
119
+ currentLocation: location,
120
+ locationHistory: [location],
121
+ status: event.eventType.toLowerCase(),
122
+ estimatedArrival: undefined,
123
+ nextCheckpoint: event.details ?? undefined,
124
+ alerts: [],
125
+ lastUpdated: new Date(event.timestamp),
126
+ };
127
+ }
128
+
129
+ function useGraphqlOptions() {
130
+ const { apiGatewayUrl, authToken, workspaceToken, workspaceId, tenantId, currentUser } =
131
+ useMoveTheWheels();
132
+ return useMemo(
133
+ () => ({
134
+ apiGatewayUrl,
135
+ authToken,
136
+ workspaceToken,
137
+ workspaceId,
138
+ tenantId,
139
+ actorId: currentUser?.id,
140
+ }),
141
+ [apiGatewayUrl, authToken, workspaceToken, workspaceId, tenantId, currentUser?.id]
142
+ );
143
+ }
144
+
145
+ export function useTracking(options: UseTrackingOptions = {}): UseTrackingResult {
146
+ const { entityId, entityType } = options;
147
+ const graphQLOptions = useGraphqlOptions();
148
+ const [tracking, setTracking] = useState<Tracking[]>([]);
149
+ const [isLoading, setIsLoading] = useState(false);
150
+ const [error, setError] = useState<Error | null>(null);
151
+
152
+ const load = useCallback(async () => {
153
+ setIsLoading(true);
154
+ setError(null);
155
+ try {
156
+ const data = await executeGraphQL<{ shipments: ApiShipment[] }>(
157
+ graphQLOptions,
158
+ SHIPMENTS_QUERY,
159
+ {
160
+ pagination: { limit: 200, offset: 0 },
161
+ }
162
+ );
163
+
164
+ const mapped = data.shipments.map((shipment) => ({
165
+ id: shipment.id,
166
+ entityId: shipment.orderId,
167
+ entityType: 'order' as const,
168
+ currentLocation: {
169
+ latitude: 0,
170
+ longitude: 0,
171
+ timestamp: new Date(),
172
+ },
173
+ locationHistory: [],
174
+ status: shipment.status.toLowerCase(),
175
+ estimatedArrival: shipment.estimatedDelivery
176
+ ? new Date(shipment.estimatedDelivery)
177
+ : undefined,
178
+ nextCheckpoint: shipment.shipmentNumber,
179
+ alerts: [],
180
+ lastUpdated: new Date(),
181
+ }));
182
+
183
+ const filtered = mapped.filter((item) => {
184
+ if (entityId && item.entityId !== entityId) return false;
185
+ if (entityType && item.entityType !== entityType) return false;
186
+ return true;
187
+ });
188
+
189
+ setTracking(filtered);
190
+ } catch (fetchError) {
191
+ setError(
192
+ fetchError instanceof Error ? fetchError : new Error('Failed to load tracking data')
193
+ );
194
+ } finally {
195
+ setIsLoading(false);
196
+ }
197
+ }, [entityId, entityType, graphQLOptions]);
198
+
199
+ useEffect(() => {
200
+ void load();
201
+ }, [load]);
202
+
203
+ return {
204
+ tracking,
205
+ isLoading,
206
+ error,
207
+ refetch: () => void load(),
208
+ };
209
+ }
210
+
211
+ export function useOrderTracking(orderId: string | undefined) {
212
+ const graphQLOptions = useGraphqlOptions();
213
+ const { order } = useOrder(orderId);
214
+ const [tracking, setTracking] = useState<Tracking | null>(null);
215
+ const [isLoading, setIsLoading] = useState(false);
216
+ const [error, setError] = useState<Error | null>(null);
217
+
218
+ const load = useCallback(async () => {
219
+ if (!orderId) {
220
+ setTracking(null);
221
+ return;
222
+ }
223
+
224
+ setIsLoading(true);
225
+ setError(null);
226
+ try {
227
+ const data = await executeGraphQL<{ orderTracking: ApiTrackingEvent[] }>(
228
+ graphQLOptions,
229
+ ORDER_TRACKING_QUERY,
230
+ {
231
+ orderId,
232
+ }
233
+ );
234
+ const latest = data.orderTracking[data.orderTracking.length - 1];
235
+ setTracking(latest ? mapTrackingEventToTracking(latest, orderId) : null);
236
+ } catch (fetchError) {
237
+ setError(
238
+ fetchError instanceof Error ? fetchError : new Error('Failed to load order tracking')
239
+ );
240
+ } finally {
241
+ setIsLoading(false);
242
+ }
243
+ }, [graphQLOptions, orderId]);
244
+
245
+ useEffect(() => {
246
+ void load();
247
+ }, [load]);
248
+
249
+ return { tracking, order, isLoading, error, refetch: () => void load() };
250
+ }
251
+
252
+ export function useVehicleTracking(vehicleId: string | undefined) {
253
+ const { vehicle, isLoading, error, refetch } = useVehicle(vehicleId);
254
+
255
+ const tracking = useMemo((): Tracking | null => {
256
+ if (!vehicle || !vehicle.currentLocation) return null;
257
+ return {
258
+ id: `vehicle-track-${vehicle.id}`,
259
+ entityId: vehicle.id,
260
+ entityType: 'vehicle',
261
+ currentLocation: vehicle.currentLocation,
262
+ locationHistory: [vehicle.currentLocation],
263
+ status: vehicle.status,
264
+ lastUpdated: vehicle.currentLocation.timestamp ?? new Date(),
265
+ alerts: [],
266
+ };
267
+ }, [vehicle]);
268
+
269
+ return { tracking, vehicle, isLoading, error, refetch };
270
+ }
271
+
272
+ export function useDriverTracking(driverId: string | undefined) {
273
+ const { driver, isLoading, error, refetch } = useDriver(driverId);
274
+
275
+ const tracking = useMemo((): Tracking | null => {
276
+ if (!driver || !driver.currentLocation) return null;
277
+ return {
278
+ id: `driver-track-${driver.id}`,
279
+ entityId: driver.id,
280
+ entityType: 'driver',
281
+ currentLocation: driver.currentLocation,
282
+ locationHistory: [driver.currentLocation],
283
+ status: driver.status,
284
+ lastUpdated: driver.currentLocation.timestamp ?? new Date(),
285
+ alerts: [],
286
+ };
287
+ }, [driver]);
288
+
289
+ return { tracking, driver, isLoading, error, refetch };
290
+ }
291
+
292
+ export function useLiveTracking() {
293
+ const graphQLOptions = useGraphqlOptions();
294
+ const { orders } = useOrders();
295
+ const { vehicles } = useVehicles();
296
+ const { drivers } = useDrivers();
297
+ const [activeDeliveries, setActiveDeliveries] = useState<
298
+ Array<{
299
+ order: (typeof orders)[number];
300
+ driver: (typeof drivers)[number] | null;
301
+ vehicle: (typeof vehicles)[number] | null;
302
+ tracking: Tracking | null;
303
+ estimatedArrival: Date | undefined;
304
+ }>
305
+ >([]);
306
+ const [isLoading, setIsLoading] = useState(false);
307
+ const [error, setError] = useState<Error | null>(null);
308
+
309
+ const load = useCallback(async () => {
310
+ setIsLoading(true);
311
+ setError(null);
312
+ try {
313
+ const data = await executeGraphQL<{ activeDeliveries: ApiShipment[] }>(
314
+ graphQLOptions,
315
+ ACTIVE_DELIVERIES_QUERY
316
+ );
317
+
318
+ const list = await Promise.all(
319
+ data.activeDeliveries.map(async (shipment) => {
320
+ const shipmentData = await executeGraphQL<{ shipment: ApiShipment | null }>(
321
+ graphQLOptions,
322
+ SHIPMENT_QUERY,
323
+ {
324
+ id: shipment.id,
325
+ }
326
+ );
327
+
328
+ const shipmentEvents = shipmentData.shipment?.trackingEvents ?? [];
329
+ const latestEvent = shipmentEvents[shipmentEvents.length - 1];
330
+ const order = orders.find((item) => item.id === shipment.orderId);
331
+ if (!order) {
332
+ return null;
333
+ }
334
+
335
+ const driver = order.driverId
336
+ ? (drivers.find(
337
+ (item) => item.id === order.driverId || item.userId === order.driverId
338
+ ) ?? null)
339
+ : null;
340
+ const vehicle = order.vehicleId
341
+ ? (vehicles.find((item) => item.id === order.vehicleId) ?? null)
342
+ : null;
343
+
344
+ return {
345
+ order,
346
+ driver,
347
+ vehicle,
348
+ tracking: latestEvent
349
+ ? mapTrackingEventToTracking(latestEvent, shipment.orderId)
350
+ : null,
351
+ estimatedArrival: shipment.estimatedDelivery
352
+ ? new Date(shipment.estimatedDelivery)
353
+ : undefined,
354
+ };
355
+ })
356
+ );
357
+
358
+ setActiveDeliveries(
359
+ list.filter(
360
+ (
361
+ item
362
+ ): item is {
363
+ order: (typeof orders)[number];
364
+ driver: (typeof drivers)[number] | null;
365
+ vehicle: (typeof vehicles)[number] | null;
366
+ tracking: Tracking | null;
367
+ estimatedArrival: Date | undefined;
368
+ } => item !== null
369
+ )
370
+ );
371
+ } catch (fetchError) {
372
+ setError(
373
+ fetchError instanceof Error ? fetchError : new Error('Failed to load live tracking')
374
+ );
375
+ } finally {
376
+ setIsLoading(false);
377
+ }
378
+ }, [drivers, graphQLOptions, orders, vehicles]);
379
+
380
+ useEffect(() => {
381
+ void load();
382
+ }, [load]);
383
+
384
+ return { activeDeliveries, isLoading, error, refetch: () => void load() };
385
+ }
386
+
387
+ export function useTrackingAlerts() {
388
+ const graphQLOptions = useGraphqlOptions();
389
+ const [alerts, setAlerts] = useState<TrackingAlert[]>([]);
390
+ const [isLoading, setIsLoading] = useState(false);
391
+ const [error, setError] = useState<Error | null>(null);
392
+
393
+ const load = useCallback(async () => {
394
+ setIsLoading(true);
395
+ setError(null);
396
+ try {
397
+ const data = await executeGraphQL<{
398
+ trackingAlerts: Array<{
399
+ shipmentId: string;
400
+ shipmentNumber: string;
401
+ alertType: string;
402
+ message: string;
403
+ }>;
404
+ }>(graphQLOptions, TRACKING_ALERTS_QUERY);
405
+
406
+ setAlerts(
407
+ data.trackingAlerts.map((alert) => ({
408
+ id: `${alert.shipmentId}-${alert.alertType}`,
409
+ type: 'delay',
410
+ severity: 'medium',
411
+ message: `${alert.shipmentNumber}: ${alert.message}`,
412
+ timestamp: new Date(),
413
+ acknowledged: false,
414
+ }))
415
+ );
416
+ } catch (fetchError) {
417
+ setError(
418
+ fetchError instanceof Error ? fetchError : new Error('Failed to load tracking alerts')
419
+ );
420
+ } finally {
421
+ setIsLoading(false);
422
+ }
423
+ }, [graphQLOptions]);
424
+
425
+ useEffect(() => {
426
+ void load();
427
+ }, [load]);
428
+
429
+ const unacknowledgedAlerts = useMemo(() => alerts.filter((item) => !item.acknowledged), [alerts]);
430
+
431
+ const acknowledgeAlert = useCallback(async (alertId: string): Promise<void> => {
432
+ setAlerts((previous) =>
433
+ previous.map((item) => (item.id === alertId ? { ...item, acknowledged: true } : item))
434
+ );
435
+ }, []);
436
+
437
+ return {
438
+ alerts,
439
+ unacknowledgedAlerts,
440
+ acknowledgeAlert,
441
+ isLoading,
442
+ error,
443
+ refetch: () => void load(),
444
+ };
445
+ }
446
+
447
+ export function useGeofence(center: Location, radiusKm: number) {
448
+ const { vehicles } = useVehicles();
449
+ const { drivers } = useDrivers();
450
+
451
+ const entitiesInRange = useMemo(() => {
452
+ const inRange: Array<{
453
+ type: 'vehicle' | 'driver';
454
+ entity: VehicleOrDriver;
455
+ distance: number;
456
+ }> = [];
457
+
458
+ vehicles.forEach((vehicle) => {
459
+ if (!vehicle.currentLocation) return;
460
+ const distance = calculateDistance(
461
+ center.latitude,
462
+ center.longitude,
463
+ vehicle.currentLocation.latitude,
464
+ vehicle.currentLocation.longitude
465
+ );
466
+ if (distance <= radiusKm) {
467
+ inRange.push({ type: 'vehicle', entity: vehicle, distance });
468
+ }
469
+ });
470
+
471
+ drivers.forEach((driver) => {
472
+ if (!driver.currentLocation) return;
473
+ const distance = calculateDistance(
474
+ center.latitude,
475
+ center.longitude,
476
+ driver.currentLocation.latitude,
477
+ driver.currentLocation.longitude
478
+ );
479
+ if (distance <= radiusKm) {
480
+ inRange.push({ type: 'driver', entity: driver, distance });
481
+ }
482
+ });
483
+
484
+ return inRange.sort((first, second) => first.distance - second.distance);
485
+ }, [center.latitude, center.longitude, drivers, radiusKm, vehicles]);
486
+
487
+ return { entitiesInRange, isLoading: false, error: null };
488
+ }
489
+
490
+ type VehicleOrDriver = { id: string; currentLocation?: Location };
491
+
492
+ function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
493
+ const earthRadiusKm = 6371;
494
+ const dLat = toRadians(lat2 - lat1);
495
+ const dLon = toRadians(lon2 - lon1);
496
+ const a =
497
+ Math.sin(dLat / 2) * Math.sin(dLat / 2) +
498
+ Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
499
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
500
+ return earthRadiusKm * c;
501
+ }
502
+
503
+ function toRadians(degrees: number): number {
504
+ return degrees * (Math.PI / 180);
505
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * MoveTheWheels Microfrontend
3
+ *
4
+ * Provides a comprehensive logistics and supply chain management interface
5
+ * for orders, fleet, inventory, customers, and analytics.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { MoveTheWheelsRoot, type MoveTheWheelsRootProps } from '@burdenoff/microfe-movethewheels';
10
+ *
11
+ * function App() {
12
+ * const props: MoveTheWheelsRootProps = {
13
+ * basePath: '/movethewheels',
14
+ * navigate: (path) => router.push(path),
15
+ * currentUser: { id: '1', email: 'user@example.com' },
16
+ * workspaceId: 'ws-123',
17
+ * apiGatewayUrl: 'https://api.example.com',
18
+ * authToken: 'token',
19
+ * };
20
+ *
21
+ * return <MoveTheWheelsRoot {...props} />;
22
+ * }
23
+ * ```
24
+ */
25
+
26
+ export { MoveTheWheelsRoot } from './MoveTheWheelsRoot';
27
+ export type {
28
+ MoveTheWheelsRootProps,
29
+ MoveTheWheelsContextValue,
30
+ // Entity types
31
+ Order,
32
+ OrderItem,
33
+ OrderStatus,
34
+ OrderFilter,
35
+ Customer,
36
+ CustomerFilter,
37
+ Vehicle,
38
+ VehicleType,
39
+ VehicleStatus,
40
+ Driver,
41
+ DriverStatus,
42
+ Warehouse,
43
+ Inventory,
44
+ InventoryFilter,
45
+ Product,
46
+ Route,
47
+ Tracking,
48
+ Analytics,
49
+ ServiceProvider,
50
+ ServiceOffering,
51
+ Notification,
52
+ // Common types
53
+ Address,
54
+ Location,
55
+ Dimensions,
56
+ NavItem,
57
+ FooterItem,
58
+ User,
59
+ UserRole,
60
+ } from './types';
61
+ export { useMoveTheWheels, useMoveTheWheelsNavigate } from './providers/MoveTheWheelsProvider';
62
+ export { useMoveTheWheelsStore } from './store/movethewheelsStore';
63
+
64
+ // Re-export hooks
65
+ export * from './hooks';
66
+
67
+ // Re-export components
68
+ export * from './components';