@burdenoff/microfe-movethewheels 2026.1030.1 → 2026.1031.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.
@@ -1,170 +1,176 @@
1
1
  import { Coffee as e } from "../node_modules/lucide-react/dist/esm/icons/coffee.js";
2
2
  import { Download as t } from "../node_modules/lucide-react/dist/esm/icons/download.js";
3
- import { Filter as n } from "../node_modules/lucide-react/dist/esm/icons/filter.js";
4
- import { Plus as r } from "../node_modules/lucide-react/dist/esm/icons/plus.js";
5
- import { RefreshCw as ee } from "../node_modules/lucide-react/dist/esm/icons/refresh-cw.js";
6
- import { Star as i } from "../node_modules/lucide-react/dist/esm/icons/star.js";
7
- import { Truck as a } from "../node_modules/lucide-react/dist/esm/icons/truck.js";
8
- import { UserCheck as o } from "../node_modules/lucide-react/dist/esm/icons/user-check.js";
9
- import { UserMinus as s } from "../node_modules/lucide-react/dist/esm/icons/user-minus.js";
10
- import { Users as c } from "../node_modules/lucide-react/dist/esm/icons/users.js";
11
- import { joinPath as l } from "../utils/navigation.js";
12
- import { useMoveTheWheels as u } from "../providers/MoveTheWheelsProvider.js";
13
- import { useDriverStatusCounts as d, useDrivers as f, useFleetStats as p, useVehicles as te } from "../hooks/useFleet.js";
14
- import { Avatar as ne, AvatarFallback as re, Button as ie, Card as m, CardContent as h, Select as g, SelectContent as _, SelectItem as v, SelectTrigger as y, SelectValue as b } from "../components/ui.js";
15
- import { PageLayout as ae } from "../components/PageLayout.js";
16
- import { MetricCard as x, MetricGrid as S } from "../components/MetricCard.js";
17
- import { DRIVER_STATUS_LABELS as C } from "../constants/index.js";
18
- import { StatusBadge as w } from "../components/StatusBadge.js";
19
- import { DataTable as T } from "../components/DataTable.js";
20
- import { formatDate as E } from "../utils/formatters.js";
21
- import { useDebouncedValue as oe } from "../hooks/useDebouncedValue.js";
22
- import { useMemo as D, useState as O } from "react";
23
- import { jsx as k, jsxs as A } from "react/jsx-runtime";
24
- import { CTAOverflowMenu as j, PagePurpose as M } from "@burdenoff/fe-libs/ui";
3
+ import { Filter as ee } from "../node_modules/lucide-react/dist/esm/icons/filter.js";
4
+ import { Plus as te } from "../node_modules/lucide-react/dist/esm/icons/plus.js";
5
+ import { RefreshCw as n } from "../node_modules/lucide-react/dist/esm/icons/refresh-cw.js";
6
+ import { Star as r } from "../node_modules/lucide-react/dist/esm/icons/star.js";
7
+ import { Truck as ne } from "../node_modules/lucide-react/dist/esm/icons/truck.js";
8
+ import { UserCheck as re } from "../node_modules/lucide-react/dist/esm/icons/user-check.js";
9
+ import { UserMinus as ie } from "../node_modules/lucide-react/dist/esm/icons/user-minus.js";
10
+ import { Users as i } from "../node_modules/lucide-react/dist/esm/icons/users.js";
11
+ import { joinPath as ae } from "../utils/navigation.js";
12
+ import { useMoveTheWheels as oe } from "../providers/MoveTheWheelsProvider.js";
13
+ import { useDriverStatusCounts as a, useDrivers as o, useFleetStats as s, useVehicles as c } from "../hooks/useFleet.js";
14
+ import { Avatar as l, AvatarFallback as u, Button as d, Card as f, CardContent as p, Select as m, SelectContent as h, SelectItem as g, SelectTrigger as _, SelectValue as v } from "../components/ui.js";
15
+ import { PageLayout as se } from "../components/PageLayout.js";
16
+ import { MetricCard as y, MetricGrid as ce } from "../components/MetricCard.js";
17
+ import { DRIVER_STATUS_LABELS as b } from "../constants/index.js";
18
+ import { StatusBadge as le } from "../components/StatusBadge.js";
19
+ import { DataTable as ue } from "../components/DataTable.js";
20
+ import { formatDate as x } from "../utils/formatters.js";
21
+ import { useDebouncedValue as de } from "../hooks/useDebouncedValue.js";
22
+ import { useEntityExport as fe } from "../hooks/useEntityExport.js";
23
+ import { ExportStatusBanner as S } from "../components/ExportStatusBanner.js";
24
+ import { useMemo as C, useState as w } from "react";
25
+ import { jsx as T, jsxs as E } from "react/jsx-runtime";
26
+ import { CTAOverflowMenu as D, PagePurpose as O } from "@burdenoff/fe-libs/ui";
25
27
  //#region src/movethewheels/pages/DriversPage.tsx
26
- var N = [{
28
+ var k = [{
27
29
  value: "all",
28
30
  label: "All statuses"
29
- }, ...Object.entries(C).map(([e, t]) => ({
31
+ }, ...Object.entries(b).map(([e, t]) => ({
30
32
  value: e,
31
33
  label: t
32
34
  }))];
33
- function P() {
34
- let { basePath: C, navigate: P } = u(), [F, I] = O(0), [L, R] = O(25), [z, B] = O(""), V = oe(z), [H, U] = O("all"), [W, G] = O("all"), { drivers: K, totalDrivers: se, hasMore: ce, isLoading: le, error: ue, refetch: q } = f({
35
+ function A() {
36
+ let { basePath: b, navigate: A } = oe(), { state: j, isExporting: M, startExport: N, dismiss: P } = fe("drivers", "driver"), [F, I] = w(0), [L, pe] = w(25), [R, z] = w(""), B = de(R), [V, H] = w("all"), [U, W] = w("all"), { drivers: G, totalDrivers: me, hasMore: he, isLoading: ge, error: _e, refetch: K } = o({
35
37
  limit: L,
36
38
  offset: F * L,
37
- search: V || void 0,
38
- status: H === "all" ? void 0 : H,
39
- licenseClass: W === "all" ? void 0 : W
40
- }), { stats: J } = p(), { counts: Y } = d(), { vehicles: X } = te({ ids: D(() => Array.from(new Set(K.map((e) => e.assignedVehicle).filter(Boolean))), [K]) }), de = D(() => new Map(X.map((e) => [e.id, e.vehicleNumber])), [X]), Z = J.totalDrivers, fe = D(() => Array.from(new Set(K.map((e) => e.licenseType).filter(Boolean))).sort((e, t) => e.localeCompare(t)), [K]), Q = H !== "all" || W !== "all" || z.length > 0, $ = (e) => P?.(l(C, e));
41
- return /* @__PURE__ */ A(ae, {
39
+ search: B || void 0,
40
+ status: V === "all" ? void 0 : V,
41
+ licenseClass: U === "all" ? void 0 : U
42
+ }), { stats: q } = s(), { counts: J } = a(), { vehicles: Y } = c({ ids: C(() => Array.from(new Set(G.map((e) => e.assignedVehicle).filter(Boolean))), [G]) }), ve = C(() => new Map(Y.map((e) => [e.id, e.vehicleNumber])), [Y]), X = q.totalDrivers, Z = C(() => Array.from(new Set(G.map((e) => e.licenseType).filter(Boolean))).sort((e, t) => e.localeCompare(t)), [G]), Q = V !== "all" || U !== "all" || R.length > 0, $ = (e) => A?.(ae(b, e));
43
+ return /* @__PURE__ */ E(se, {
42
44
  title: "Drivers",
43
- subtitle: `${Z} drivers`,
44
- icon: /* @__PURE__ */ k(c, { size: 24 }),
45
- headerActions: /* @__PURE__ */ k(j, {
45
+ subtitle: `${X} drivers`,
46
+ icon: /* @__PURE__ */ T(i, { size: 24 }),
47
+ headerActions: /* @__PURE__ */ T(D, {
46
48
  primary: {
47
49
  label: "Add Driver",
48
- icon: /* @__PURE__ */ k(r, { size: 16 }),
50
+ icon: /* @__PURE__ */ T(te, { size: 16 }),
49
51
  onSelect: () => $("fleet/drivers/new")
50
52
  },
51
53
  actions: [{
52
54
  label: "Refresh",
53
- icon: /* @__PURE__ */ k(ee, { size: 16 }),
54
- onSelect: () => q()
55
+ icon: /* @__PURE__ */ T(n, { size: 16 }),
56
+ onSelect: () => K()
55
57
  }, {
56
- label: "Export",
57
- icon: /* @__PURE__ */ k(t, { size: 16 }),
58
- onSelect: () => $("import-export")
58
+ label: M ? "Exporting…" : "Export",
59
+ icon: /* @__PURE__ */ T(t, { size: 16 }),
60
+ onSelect: N
59
61
  }]
60
62
  }),
61
63
  children: [
62
- /* @__PURE__ */ k(M, {
63
- icon: /* @__PURE__ */ k(c, { size: 18 }),
64
+ /* @__PURE__ */ T(O, {
65
+ icon: /* @__PURE__ */ T(i, { size: 18 }),
64
66
  children: "Your delivery workforce. Track each driver's availability, rating, licence status, contact number and the vehicle they are on — open a driver to review their record before assigning them to an order or route."
65
67
  }),
66
- /* @__PURE__ */ A("div", { children: [/* @__PURE__ */ k("p", {
68
+ /* @__PURE__ */ T(S, {
69
+ state: j,
70
+ onDismiss: P
71
+ }),
72
+ /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("p", {
67
73
  className: "mb-3 text-sm font-medium text-text-secondary",
68
74
  children: "Workforce at a glance"
69
- }), /* @__PURE__ */ A(S, {
75
+ }), /* @__PURE__ */ E(ce, {
70
76
  columns: 4,
71
77
  children: [
72
- /* @__PURE__ */ k(x, {
78
+ /* @__PURE__ */ T(y, {
73
79
  label: "On duty",
74
- value: J.driversByStatus.available + J.driversByStatus.busy,
75
- icon: /* @__PURE__ */ k(o, { size: 20 }),
80
+ value: q.driversByStatus.available + q.driversByStatus.busy,
81
+ icon: /* @__PURE__ */ T(re, { size: 20 }),
76
82
  accent: "success",
77
83
  subtitle: "Available or delivering"
78
84
  }),
79
- /* @__PURE__ */ k(x, {
85
+ /* @__PURE__ */ T(y, {
80
86
  label: "On break",
81
- value: Y.onBreak,
82
- icon: /* @__PURE__ */ k(e, { size: 20 }),
87
+ value: J.onBreak,
88
+ icon: /* @__PURE__ */ T(e, { size: 20 }),
83
89
  accent: "warning",
84
90
  subtitle: "Back on shift shortly"
85
91
  }),
86
- /* @__PURE__ */ k(x, {
92
+ /* @__PURE__ */ T(y, {
87
93
  label: "Off duty",
88
- value: Y.offDuty,
89
- icon: /* @__PURE__ */ k(s, { size: 20 }),
94
+ value: J.offDuty,
95
+ icon: /* @__PURE__ */ T(ie, { size: 20 }),
90
96
  accent: "neutral",
91
- subtitle: Y.inactive > 0 ? `${Y.inactive} inactive` : void 0
97
+ subtitle: J.inactive > 0 ? `${J.inactive} inactive` : void 0
92
98
  }),
93
- /* @__PURE__ */ k(x, {
99
+ /* @__PURE__ */ T(y, {
94
100
  label: "Avg rating",
95
- value: J.avgDriverRating > 0 ? J.avgDriverRating.toFixed(1) : "—",
96
- icon: /* @__PURE__ */ k(i, { size: 20 }),
101
+ value: q.avgDriverRating > 0 ? q.avgDriverRating.toFixed(1) : "—",
102
+ icon: /* @__PURE__ */ T(r, { size: 20 }),
97
103
  accent: "brand",
98
- subtitle: `${Z} drivers`
104
+ subtitle: `${X} drivers`
99
105
  })
100
106
  ]
101
107
  })] }),
102
- /* @__PURE__ */ k(m, { children: /* @__PURE__ */ k(h, {
108
+ /* @__PURE__ */ T(f, { children: /* @__PURE__ */ T(p, {
103
109
  className: "p-4",
104
- children: /* @__PURE__ */ A("div", {
110
+ children: /* @__PURE__ */ E("div", {
105
111
  className: "flex flex-wrap items-center gap-4",
106
112
  children: [
107
- /* @__PURE__ */ A("div", {
113
+ /* @__PURE__ */ E("div", {
108
114
  className: "flex items-center gap-2",
109
- children: [/* @__PURE__ */ k(n, {
115
+ children: [/* @__PURE__ */ T(ee, {
110
116
  size: 16,
111
117
  className: "text-text-secondary"
112
- }), /* @__PURE__ */ k("span", {
118
+ }), /* @__PURE__ */ T("span", {
113
119
  className: "text-sm font-medium",
114
120
  children: "Filters:"
115
121
  })]
116
122
  }),
117
- /* @__PURE__ */ A(g, {
118
- value: H,
123
+ /* @__PURE__ */ E(m, {
124
+ value: V,
119
125
  onValueChange: (e) => {
120
- U(e), I(0);
126
+ H(e), I(0);
121
127
  },
122
- children: [/* @__PURE__ */ k(y, {
128
+ children: [/* @__PURE__ */ T(_, {
123
129
  className: "w-[180px]",
124
- children: /* @__PURE__ */ k(b, { placeholder: "Status" })
125
- }), /* @__PURE__ */ k(_, { children: N.map((e) => /* @__PURE__ */ k(v, {
130
+ children: /* @__PURE__ */ T(v, { placeholder: "Status" })
131
+ }), /* @__PURE__ */ T(h, { children: k.map((e) => /* @__PURE__ */ T(g, {
126
132
  value: e.value,
127
133
  children: e.label
128
134
  }, e.value)) })]
129
135
  }),
130
- /* @__PURE__ */ A(g, {
131
- value: W,
136
+ /* @__PURE__ */ E(m, {
137
+ value: U,
132
138
  onValueChange: (e) => {
133
- G(e), I(0);
139
+ W(e), I(0);
134
140
  },
135
- children: [/* @__PURE__ */ k(y, {
141
+ children: [/* @__PURE__ */ T(_, {
136
142
  className: "w-[180px]",
137
- children: /* @__PURE__ */ k(b, { placeholder: "License class" })
138
- }), /* @__PURE__ */ A(_, { children: [/* @__PURE__ */ k(v, {
143
+ children: /* @__PURE__ */ T(v, { placeholder: "License class" })
144
+ }), /* @__PURE__ */ E(h, { children: [/* @__PURE__ */ T(g, {
139
145
  value: "all",
140
146
  children: "All licence classes"
141
- }), fe.map((e) => /* @__PURE__ */ k(v, {
147
+ }), Z.map((e) => /* @__PURE__ */ T(g, {
142
148
  value: e,
143
149
  children: e
144
150
  }, e))] })]
145
151
  }),
146
- Q && /* @__PURE__ */ k(ie, {
152
+ Q && /* @__PURE__ */ T(d, {
147
153
  variant: "ghost",
148
154
  size: "sm",
149
155
  onClick: () => {
150
- U("all"), G("all"), B(""), I(0);
156
+ H("all"), W("all"), z(""), I(0);
151
157
  },
152
158
  children: "Clear filters"
153
159
  })
154
160
  ]
155
161
  })
156
162
  }) }),
157
- /* @__PURE__ */ k(T, {
163
+ /* @__PURE__ */ T(ue, {
158
164
  columns: [
159
165
  {
160
166
  id: "driver",
161
167
  header: "Driver",
162
- cell: (e) => /* @__PURE__ */ A("div", {
168
+ cell: (e) => /* @__PURE__ */ E("div", {
163
169
  className: "flex items-center gap-3",
164
- children: [/* @__PURE__ */ k(ne, { children: /* @__PURE__ */ k(re, { children: e.fullName.split(" ").map((e) => e[0]).join("") }) }), /* @__PURE__ */ A("div", { children: [/* @__PURE__ */ k("p", {
170
+ children: [/* @__PURE__ */ T(l, { children: /* @__PURE__ */ T(u, { children: e.fullName.split(" ").map((e) => e[0]).join("") }) }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("p", {
165
171
  className: "font-medium",
166
172
  children: e.fullName
167
- }), /* @__PURE__ */ k("p", {
173
+ }), /* @__PURE__ */ T("p", {
168
174
  className: "text-sm text-text-secondary",
169
175
  children: e.employeeId
170
176
  })] })]
@@ -175,7 +181,7 @@ function P() {
175
181
  header: "Status",
176
182
  accessorKey: "status",
177
183
  sortable: !0,
178
- cell: (e) => /* @__PURE__ */ k(w, {
184
+ cell: (e) => /* @__PURE__ */ T(le, {
179
185
  status: e.status,
180
186
  type: "driver"
181
187
  })
@@ -183,11 +189,11 @@ function P() {
183
189
  {
184
190
  id: "license",
185
191
  header: "License",
186
- cell: (e) => /* @__PURE__ */ A("div", {
192
+ cell: (e) => /* @__PURE__ */ E("div", {
187
193
  className: "text-sm",
188
- children: [/* @__PURE__ */ k("p", { children: e.licenseType }), /* @__PURE__ */ k("p", {
194
+ children: [/* @__PURE__ */ T("p", { children: e.licenseType }), /* @__PURE__ */ T("p", {
189
195
  className: "text-text-secondary",
190
- children: e.licenseExpiry ? `Exp: ${E(e.licenseExpiry, "short")}` : "Expiry not recorded"
196
+ children: e.licenseExpiry ? `Exp: ${x(e.licenseExpiry, "short")}` : "Expiry not recorded"
191
197
  })]
192
198
  })
193
199
  },
@@ -195,12 +201,12 @@ function P() {
195
201
  id: "phone",
196
202
  header: "Phone",
197
203
  accessorKey: "phone",
198
- cell: (e) => e.phone ? /* @__PURE__ */ k("a", {
204
+ cell: (e) => e.phone ? /* @__PURE__ */ T("a", {
199
205
  href: `tel:${e.phone}`,
200
206
  className: "text-sm hover:underline",
201
207
  onClick: (e) => e.stopPropagation(),
202
208
  children: e.phone
203
- }) : /* @__PURE__ */ k("span", {
209
+ }) : /* @__PURE__ */ T("span", {
204
210
  className: "text-sm text-text-secondary",
205
211
  children: "—"
206
212
  })
@@ -208,15 +214,15 @@ function P() {
208
214
  {
209
215
  id: "rating",
210
216
  header: "Rating",
211
- cell: (e) => e.rating === void 0 ? /* @__PURE__ */ k("span", {
217
+ cell: (e) => e.rating === void 0 ? /* @__PURE__ */ T("span", {
212
218
  className: "text-sm text-text-secondary",
213
219
  children: "Not rated"
214
- }) : /* @__PURE__ */ A("div", {
220
+ }) : /* @__PURE__ */ E("div", {
215
221
  className: "flex items-center gap-1",
216
- children: [/* @__PURE__ */ k(i, {
222
+ children: [/* @__PURE__ */ T(r, {
217
223
  size: 14,
218
224
  className: "text-status-warning-text fill-current"
219
- }), /* @__PURE__ */ k("span", {
225
+ }), /* @__PURE__ */ T("span", {
220
226
  className: "font-medium",
221
227
  children: e.rating.toFixed(1)
222
228
  })]
@@ -226,14 +232,14 @@ function P() {
226
232
  id: "vehicle",
227
233
  header: "Assigned vehicle",
228
234
  cell: (e) => {
229
- if (!e.assignedVehicle) return /* @__PURE__ */ k("span", {
235
+ if (!e.assignedVehicle) return /* @__PURE__ */ T("span", {
230
236
  className: "text-sm text-text-secondary",
231
237
  children: "Unassigned"
232
238
  });
233
- let t = de.get(e.assignedVehicle);
234
- return /* @__PURE__ */ A("span", {
239
+ let t = ve.get(e.assignedVehicle);
240
+ return /* @__PURE__ */ E("span", {
235
241
  className: "inline-flex items-center gap-1.5 text-sm font-medium",
236
- children: [/* @__PURE__ */ k(a, {
242
+ children: [/* @__PURE__ */ T(ne, {
237
243
  size: 14,
238
244
  className: "text-text-secondary"
239
245
  }), t ?? "Assigned"]
@@ -245,22 +251,22 @@ function P() {
245
251
  header: "Hire Date",
246
252
  accessorKey: "hireDate",
247
253
  sortable: !0,
248
- cell: (e) => e.hireDate ? E(e.hireDate, "short") : /* @__PURE__ */ k("span", {
254
+ cell: (e) => e.hireDate ? x(e.hireDate, "short") : /* @__PURE__ */ T("span", {
249
255
  className: "text-text-secondary",
250
256
  children: "Not recorded"
251
257
  })
252
258
  }
253
259
  ],
254
- data: K,
255
- isLoading: le,
256
- error: ue,
257
- onRetry: q,
260
+ data: G,
261
+ isLoading: ge,
262
+ error: _e,
263
+ onRetry: K,
258
264
  searchable: !0,
259
265
  searchPlaceholder: "Search drivers...",
260
266
  searchFields: ["fullName", "employeeId"],
261
- searchQuery: z,
267
+ searchQuery: R,
262
268
  onSearchQueryChange: (e) => {
263
- B(e), I(0);
269
+ z(e), I(0);
264
270
  },
265
271
  onRowClick: (e) => $(`fleet/drivers/${e.id}`),
266
272
  getRowId: (e) => e.id,
@@ -268,10 +274,10 @@ function P() {
268
274
  pageSize: L,
269
275
  onPageChange: I,
270
276
  onPageSizeChange: (e) => {
271
- R(e), I(0);
277
+ pe(e), I(0);
272
278
  },
273
- totalItems: se,
274
- hasNextPage: ce,
279
+ totalItems: me,
280
+ hasNextPage: he,
275
281
  emptyIllustration: "empty-people",
276
282
  emptyTitle: Q ? "No drivers match these filters" : "No drivers yet",
277
283
  emptyDescription: Q ? "Clear the status or licence-class filter to see the rest of the roster." : "Add drivers to start assigning deliveries and routes."
@@ -280,4 +286,4 @@ function P() {
280
286
  });
281
287
  }
282
288
  //#endregion
283
- export { P as default };
289
+ export { A as default };