@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,261 @@
1
+ /**
2
+ * Driver Details Page
3
+ */
4
+
5
+ import { useParams } from 'react-router-dom';
6
+ import { Users, ArrowLeft, Star, DollarSign, Clock, FileText, Edit, MapPin } from 'lucide-react';
7
+ import { PageLayout, LoadingState, ErrorState } from '../components/PageLayout';
8
+ import { StatusBadge } from '../components/StatusBadge';
9
+ import {
10
+ Card,
11
+ CardContent,
12
+ CardHeader,
13
+ CardTitle,
14
+ Button,
15
+ Badge,
16
+ Progress,
17
+ } from '../components/ui';
18
+ import { useDriver } from '../hooks/useFleet';
19
+ import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
20
+ import { formatCurrency, formatDate } from '../utils/formatters';
21
+ import { joinPath } from '../utils/navigation';
22
+
23
+ export default function DriverDetailsPage() {
24
+ const { driverId } = useParams<{ driverId: string }>();
25
+ const { basePath, navigate } = useMoveTheWheels();
26
+ const { driver, isLoading, error, refetch } = useDriver(driverId);
27
+
28
+ const goBack = () => navigate?.(joinPath(basePath, 'fleet/drivers'));
29
+
30
+ if (isLoading) return <LoadingState message="Loading driver details..." />;
31
+ if (error || !driver) return <ErrorState title="Driver not found" onRetry={refetch} />;
32
+
33
+ return (
34
+ <PageLayout
35
+ title={driver.fullName}
36
+ subtitle={`Employee ID: ${driver.employeeId}`}
37
+ icon={<Users size={24} />}
38
+ headerActions={
39
+ <div className="flex gap-2">
40
+ <Button variant="outline" onClick={goBack}>
41
+ <ArrowLeft size={16} /> Back
42
+ </Button>
43
+ <Button>
44
+ <Edit size={16} /> Edit
45
+ </Button>
46
+ </div>
47
+ }
48
+ headerContent={
49
+ <div className="flex items-center gap-4">
50
+ <StatusBadge status={driver.status} type="driver" />
51
+ <div className="flex items-center gap-1">
52
+ <Star size={16} className="text-yellow-500 fill-yellow-500" />
53
+ <span className="font-medium">{driver.ratings.overall.toFixed(1)}</span>
54
+ <span className="text-muted-foreground">({driver.ratings.totalRatings} ratings)</span>
55
+ </div>
56
+ </div>
57
+ }
58
+ >
59
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
60
+ <div className="lg:col-span-2 space-y-6">
61
+ {/* Ratings */}
62
+ <Card>
63
+ <CardHeader>
64
+ <CardTitle className="flex items-center gap-2">
65
+ <Star size={18} /> Ratings
66
+ </CardTitle>
67
+ </CardHeader>
68
+ <CardContent>
69
+ <div className="grid grid-cols-2 md:grid-cols-3 gap-4">
70
+ {[
71
+ { label: 'Punctuality', value: driver.ratings.punctuality },
72
+ { label: 'Communication', value: driver.ratings.communication },
73
+ { label: 'Handling', value: driver.ratings.carefulHandling },
74
+ { label: 'Professionalism', value: driver.ratings.professionalism },
75
+ { label: 'On-Time Delivery', value: driver.ratings.onTimeDelivery },
76
+ ].map((rating) => (
77
+ <div key={rating.label}>
78
+ <p className="text-sm text-muted-foreground">{rating.label}</p>
79
+ <div className="flex items-center gap-2 mt-1">
80
+ <Progress value={rating.value * 20} className="flex-1 h-2" />
81
+ <span className="text-sm font-medium">{rating.value.toFixed(1)}</span>
82
+ </div>
83
+ </div>
84
+ ))}
85
+ </div>
86
+ </CardContent>
87
+ </Card>
88
+
89
+ {/* Working Hours */}
90
+ <Card>
91
+ <CardHeader>
92
+ <CardTitle className="flex items-center gap-2">
93
+ <Clock size={18} /> Working Hours
94
+ </CardTitle>
95
+ </CardHeader>
96
+ <CardContent>
97
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
98
+ <div>
99
+ <p className="text-sm text-muted-foreground">Shift</p>
100
+ <p className="font-medium">
101
+ {driver.workingHours.startTime} - {driver.workingHours.endTime}
102
+ </p>
103
+ </div>
104
+ <div>
105
+ <p className="text-sm text-muted-foreground">Working Days</p>
106
+ <p className="font-medium">{driver.workingHours.workingDays.length} days/week</p>
107
+ </div>
108
+ <div>
109
+ <p className="text-sm text-muted-foreground">Hours Today</p>
110
+ <p className="font-medium">
111
+ {driver.workingHours.currentHoursToday}h / {driver.workingHours.maxHoursPerDay}h
112
+ </p>
113
+ </div>
114
+ <div>
115
+ <p className="text-sm text-muted-foreground">Hours This Week</p>
116
+ <p className="font-medium">
117
+ {driver.workingHours.currentHoursThisWeek}h /{' '}
118
+ {driver.workingHours.maxHoursPerWeek}h
119
+ </p>
120
+ </div>
121
+ </div>
122
+ </CardContent>
123
+ </Card>
124
+
125
+ {/* Documents */}
126
+ <Card>
127
+ <CardHeader>
128
+ <CardTitle className="flex items-center gap-2">
129
+ <FileText size={18} /> Documents
130
+ </CardTitle>
131
+ </CardHeader>
132
+ <CardContent>
133
+ <div className="space-y-3">
134
+ <div className="flex items-center justify-between p-3 border rounded-lg">
135
+ <div>
136
+ <p className="font-medium">Driver's License</p>
137
+ <p className="text-sm text-muted-foreground">
138
+ {driver.licenseNumber} - {driver.licenseType}
139
+ </p>
140
+ <p className="text-sm text-muted-foreground">
141
+ Expires: {formatDate(driver.licenseExpiry)}
142
+ </p>
143
+ </div>
144
+ <Badge variant="default">Valid</Badge>
145
+ </div>
146
+ {driver.documents.map((doc) => (
147
+ <div
148
+ key={doc.id}
149
+ className="flex items-center justify-between p-3 border rounded-lg"
150
+ >
151
+ <div>
152
+ <p className="font-medium capitalize">{doc.type.replace('_', ' ')}</p>
153
+ <p className="text-sm text-muted-foreground">
154
+ Expires: {formatDate(doc.expiryDate)}
155
+ </p>
156
+ </div>
157
+ <Badge variant={doc.verified ? 'default' : 'secondary'}>
158
+ {doc.verified ? 'Verified' : 'Pending'}
159
+ </Badge>
160
+ </div>
161
+ ))}
162
+ </div>
163
+ </CardContent>
164
+ </Card>
165
+ </div>
166
+
167
+ <div className="space-y-6">
168
+ {/* Stats */}
169
+ <Card>
170
+ <CardHeader>
171
+ <CardTitle>Statistics</CardTitle>
172
+ </CardHeader>
173
+ <CardContent className="space-y-4">
174
+ <div>
175
+ <p className="text-sm text-muted-foreground">Total Deliveries</p>
176
+ <p className="text-2xl font-bold">{driver.completedOrders.toLocaleString()}</p>
177
+ </div>
178
+ <div>
179
+ <p className="text-sm text-muted-foreground">Today's Deliveries</p>
180
+ <p className="text-2xl font-bold">{driver.todayOrders}</p>
181
+ </div>
182
+ <div>
183
+ <p className="text-sm text-muted-foreground">Join Date</p>
184
+ <p className="font-medium">{formatDate(driver.joinDate)}</p>
185
+ </div>
186
+ </CardContent>
187
+ </Card>
188
+
189
+ {/* Earnings */}
190
+ <Card>
191
+ <CardHeader>
192
+ <CardTitle className="flex items-center gap-2">
193
+ <DollarSign size={18} /> Earnings
194
+ </CardTitle>
195
+ </CardHeader>
196
+ <CardContent className="space-y-3">
197
+ <div>
198
+ <p className="text-sm text-muted-foreground">Total Earnings</p>
199
+ <p className="text-2xl font-bold">
200
+ {formatCurrency(driver.earnings.totalEarnings)}
201
+ </p>
202
+ </div>
203
+ <div className="grid grid-cols-2 gap-3">
204
+ <div>
205
+ <p className="text-sm text-muted-foreground">This Week</p>
206
+ <p className="font-medium">{formatCurrency(driver.earnings.weeklyEarnings)}</p>
207
+ </div>
208
+ <div>
209
+ <p className="text-sm text-muted-foreground">This Month</p>
210
+ <p className="font-medium">{formatCurrency(driver.earnings.monthlyEarnings)}</p>
211
+ </div>
212
+ </div>
213
+ <div>
214
+ <p className="text-sm text-muted-foreground">Base Salary</p>
215
+ <p className="font-medium">{formatCurrency(driver.baseSalary)}/year</p>
216
+ </div>
217
+ </CardContent>
218
+ </Card>
219
+
220
+ {/* Location */}
221
+ {driver.currentLocation && (
222
+ <Card>
223
+ <CardHeader>
224
+ <CardTitle className="flex items-center gap-2">
225
+ <MapPin size={18} /> Current Location
226
+ </CardTitle>
227
+ </CardHeader>
228
+ <CardContent>
229
+ <p className="text-sm">
230
+ {driver.currentLocation.address || 'Location updating...'}
231
+ </p>
232
+ <p className="text-xs text-muted-foreground mt-1">
233
+ Updated {formatDate(driver.currentLocation.timestamp || new Date(), 'relative')}
234
+ </p>
235
+ </CardContent>
236
+ </Card>
237
+ )}
238
+
239
+ {/* Compliance */}
240
+ <Card>
241
+ <CardHeader>
242
+ <CardTitle>Compliance Status</CardTitle>
243
+ </CardHeader>
244
+ <CardContent className="space-y-2">
245
+ {Object.entries(driver.compliance)
246
+ .filter(([k]) => k !== 'lastUpdate')
247
+ .map(([key, value]) => (
248
+ <div key={key} className="flex items-center justify-between">
249
+ <span className="text-sm capitalize">{key.replace(/([A-Z])/g, ' $1')}</span>
250
+ <Badge variant={value ? 'default' : 'destructive'}>
251
+ {value ? 'Compliant' : 'Non-compliant'}
252
+ </Badge>
253
+ </div>
254
+ ))}
255
+ </CardContent>
256
+ </Card>
257
+ </div>
258
+ </div>
259
+ </PageLayout>
260
+ );
261
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Drivers Page - List of all drivers
3
+ */
4
+
5
+ import { Users, Plus, RefreshCw, Download, Star } from 'lucide-react';
6
+ import { PageLayout } from '../components/PageLayout';
7
+ import { DataTable, type Column } from '../components/DataTable';
8
+ import { StatusBadge } from '../components/StatusBadge';
9
+ import { Button, Avatar, AvatarFallback } from '../components/ui';
10
+ import { useDrivers } from '../hooks/useFleet';
11
+ import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
12
+ import { formatDate } from '../utils/formatters';
13
+ import { joinPath } from '../utils/navigation';
14
+ import type { Driver } from '../types';
15
+
16
+ export default function DriversPage() {
17
+ const { basePath, navigate } = useMoveTheWheels();
18
+ const { drivers, totalDrivers, isLoading, refetch } = useDrivers();
19
+
20
+ const goTo = (path: string) => navigate?.(joinPath(basePath, path));
21
+
22
+ const columns: Column<Driver>[] = [
23
+ {
24
+ id: 'driver',
25
+ header: 'Driver',
26
+ cell: (row) => (
27
+ <div className="flex items-center gap-3">
28
+ <Avatar>
29
+ <AvatarFallback>
30
+ {row.fullName
31
+ .split(' ')
32
+ .map((n) => n[0])
33
+ .join('')}
34
+ </AvatarFallback>
35
+ </Avatar>
36
+ <div>
37
+ <p className="font-medium">{row.fullName}</p>
38
+ <p className="text-sm text-muted-foreground">{row.employeeId}</p>
39
+ </div>
40
+ </div>
41
+ ),
42
+ },
43
+ {
44
+ id: 'status',
45
+ header: 'Status',
46
+ accessorKey: 'status',
47
+ sortable: true,
48
+ cell: (row) => <StatusBadge status={row.status} type="driver" />,
49
+ },
50
+ {
51
+ id: 'rating',
52
+ header: 'Rating',
53
+ cell: (row) => (
54
+ <div className="flex items-center gap-1">
55
+ <Star size={14} className="text-yellow-500 fill-yellow-500" />
56
+ <span className="font-medium">{row.ratings.overall.toFixed(1)}</span>
57
+ <span className="text-muted-foreground text-sm">({row.ratings.totalRatings})</span>
58
+ </div>
59
+ ),
60
+ },
61
+ {
62
+ id: 'deliveries',
63
+ header: 'Deliveries',
64
+ accessorKey: 'completedOrders',
65
+ sortable: true,
66
+ cell: (row) => <span className="font-medium">{row.completedOrders.toLocaleString()}</span>,
67
+ },
68
+ {
69
+ id: 'license',
70
+ header: 'License',
71
+ cell: (row) => (
72
+ <div className="text-sm">
73
+ <p>{row.licenseType}</p>
74
+ <p className="text-muted-foreground">Exp: {formatDate(row.licenseExpiry, 'short')}</p>
75
+ </div>
76
+ ),
77
+ },
78
+ {
79
+ id: 'joined',
80
+ header: 'Join Date',
81
+ accessorKey: 'joinDate',
82
+ sortable: true,
83
+ cell: (row) => formatDate(row.joinDate, 'short'),
84
+ },
85
+ ];
86
+
87
+ return (
88
+ <PageLayout
89
+ title="Drivers"
90
+ subtitle={`${totalDrivers} drivers`}
91
+ icon={<Users size={24} />}
92
+ headerActions={
93
+ <div className="flex gap-2">
94
+ <Button variant="outline" onClick={refetch}>
95
+ <RefreshCw size={16} /> Refresh
96
+ </Button>
97
+ <Button variant="outline">
98
+ <Download size={16} /> Export
99
+ </Button>
100
+ <Button>
101
+ <Plus size={16} /> Add Driver
102
+ </Button>
103
+ </div>
104
+ }
105
+ >
106
+ <DataTable
107
+ columns={columns}
108
+ data={drivers}
109
+ isLoading={isLoading}
110
+ searchable
111
+ searchPlaceholder="Search drivers..."
112
+ searchFields={['fullName', 'employeeId'] as (keyof Driver)[]}
113
+ onRowClick={(row) => goTo(`fleet/drivers/${row.id}`)}
114
+ getRowId={(row) => row.id}
115
+ />
116
+ </PageLayout>
117
+ );
118
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Finance Page
3
+ */
4
+
5
+ import { DollarSign, TrendingUp, CreditCard, FileText, Download } from 'lucide-react';
6
+ import { PageLayout } from '../components/PageLayout';
7
+ import { MetricCard, MetricGrid } from '../components/MetricCard';
8
+ import { Card, CardContent, CardHeader, CardTitle, Button } from '../components/ui';
9
+ import { useAnalytics } from '../hooks/useAnalytics';
10
+ import { useOrderStats } from '../hooks/useOrders';
11
+ import { formatCurrency } from '../utils/formatters';
12
+
13
+ export default function FinancePage() {
14
+ const { analytics } = useAnalytics();
15
+ const { stats } = useOrderStats();
16
+
17
+ const pendingPayments = stats.totalRevenue * 0.15; // Simulated
18
+ const completedPayments = stats.totalRevenue * 0.85;
19
+
20
+ return (
21
+ <PageLayout
22
+ title="Finance"
23
+ subtitle="Financial overview and reports"
24
+ icon={<DollarSign size={24} />}
25
+ headerActions={
26
+ <div className="flex gap-2">
27
+ <Button variant="outline">
28
+ <FileText size={16} /> Invoices
29
+ </Button>
30
+ <Button variant="outline">
31
+ <Download size={16} /> Export
32
+ </Button>
33
+ </div>
34
+ }
35
+ >
36
+ <MetricGrid columns={4}>
37
+ <MetricCard
38
+ label="Total Revenue"
39
+ value={formatCurrency(analytics.overview.totalRevenue)}
40
+ icon={<DollarSign size={20} />}
41
+ change="+12.5%"
42
+ changeType="positive"
43
+ trend="up"
44
+ />
45
+ <MetricCard
46
+ label="Completed"
47
+ value={formatCurrency(completedPayments)}
48
+ icon={<TrendingUp size={20} />}
49
+ changeType="positive"
50
+ />
51
+ <MetricCard
52
+ label="Pending"
53
+ value={formatCurrency(pendingPayments)}
54
+ icon={<CreditCard size={20} />}
55
+ changeType="neutral"
56
+ />
57
+ <MetricCard
58
+ label="Avg Order Value"
59
+ value={formatCurrency(stats.avgOrderValue)}
60
+ icon={<DollarSign size={20} />}
61
+ />
62
+ </MetricGrid>
63
+
64
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
65
+ <Card>
66
+ <CardHeader>
67
+ <CardTitle>Revenue by Month</CardTitle>
68
+ </CardHeader>
69
+ <CardContent>
70
+ <div className="space-y-4">
71
+ {analytics.trends.revenue.map((r) => (
72
+ <div
73
+ key={r.month}
74
+ className="flex items-center justify-between p-3 bg-muted/50 rounded-lg"
75
+ >
76
+ <span className="font-medium">{r.month} 2024</span>
77
+ <span className="text-lg font-bold">{formatCurrency(r.revenue)}</span>
78
+ </div>
79
+ ))}
80
+ </div>
81
+ </CardContent>
82
+ </Card>
83
+
84
+ <Card>
85
+ <CardHeader>
86
+ <CardTitle>Payment Status</CardTitle>
87
+ </CardHeader>
88
+ <CardContent>
89
+ <div className="space-y-4">
90
+ <div className="flex items-center justify-between p-4 bg-green-50 dark:bg-green-900/20 rounded-lg">
91
+ <div className="flex items-center gap-3">
92
+ <div className="w-10 h-10 rounded-full bg-green-100 dark:bg-green-800 flex items-center justify-center">
93
+ <TrendingUp size={20} className="text-green-600" />
94
+ </div>
95
+ <div>
96
+ <p className="font-medium">Paid</p>
97
+ <p className="text-sm text-muted-foreground">
98
+ {stats.byStatus.delivered} orders
99
+ </p>
100
+ </div>
101
+ </div>
102
+ <span className="text-xl font-bold text-green-600">
103
+ {formatCurrency(completedPayments)}
104
+ </span>
105
+ </div>
106
+ <div className="flex items-center justify-between p-4 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg">
107
+ <div className="flex items-center gap-3">
108
+ <div className="w-10 h-10 rounded-full bg-yellow-100 dark:bg-yellow-800 flex items-center justify-center">
109
+ <CreditCard size={20} className="text-yellow-600" />
110
+ </div>
111
+ <div>
112
+ <p className="font-medium">Pending</p>
113
+ <p className="text-sm text-muted-foreground">
114
+ {stats.byStatus.pending + stats.byStatus.in_transit} orders
115
+ </p>
116
+ </div>
117
+ </div>
118
+ <span className="text-xl font-bold text-yellow-600">
119
+ {formatCurrency(pendingPayments)}
120
+ </span>
121
+ </div>
122
+ </div>
123
+ </CardContent>
124
+ </Card>
125
+ </div>
126
+
127
+ <Card>
128
+ <CardHeader>
129
+ <CardTitle>Recent Transactions</CardTitle>
130
+ </CardHeader>
131
+ <CardContent>
132
+ <div className="text-center py-8 text-muted-foreground">
133
+ <FileText size={48} className="mx-auto mb-4 opacity-50" />
134
+ <p>Transaction history would be displayed here</p>
135
+ <p className="text-sm">Integration with payment gateway required</p>
136
+ </div>
137
+ </CardContent>
138
+ </Card>
139
+ </PageLayout>
140
+ );
141
+ }