@burdenoff/microfe-movethewheels 2026.1101.1 → 2026.1101.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/EpodCaptureForm.js +256 -0
- package/dist/generated/wspace-types.d.ts +9012 -132
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useDriverDay.js +153 -0
- package/dist/hooks/useOrders.js +1 -1
- package/dist/index.js +27 -26
- package/dist/movethewheels/components/EpodCaptureForm.d.ts +12 -0
- package/dist/movethewheels/hooks/index.d.ts +1 -0
- package/dist/movethewheels/hooks/useDriverDay.d.ts +53 -0
- package/dist/movethewheels/utils/driverNavigation.d.ts +31 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/calendar-days.js +50 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/wifi-off.js +34 -0
- package/dist/pages/DeliveryCapturePage.js +450 -321
- package/dist/utils/driverNavigation.js +51 -0
- package/dist/utils/formatters.js +18 -9
- package/package.json +3 -2
- package/src/generated/wspace-types.ts +10266 -142
- package/src/movethewheels/components/EpodCaptureForm.tsx +343 -0
- package/src/movethewheels/hooks/index.ts +9 -0
- package/src/movethewheels/hooks/useDriverDay.ts +289 -0
- package/src/movethewheels/pages/DeliveryCapturePage.tsx +478 -392
- package/src/movethewheels/utils/driverNavigation.ts +103 -0
|
@@ -1,347 +1,476 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
1
|
+
import { ArrowLeft as e } from "../node_modules/lucide-react/dist/esm/icons/arrow-left.js";
|
|
2
|
+
import { CalendarDays as t } from "../node_modules/lucide-react/dist/esm/icons/calendar-days.js";
|
|
3
|
+
import { ChevronLeft as n } from "../node_modules/lucide-react/dist/esm/icons/chevron-left.js";
|
|
4
|
+
import { ChevronRight as r } from "../node_modules/lucide-react/dist/esm/icons/chevron-right.js";
|
|
5
|
+
import { CircleCheck as i } from "../node_modules/lucide-react/dist/esm/icons/circle-check.js";
|
|
6
|
+
import { Clock as a } from "../node_modules/lucide-react/dist/esm/icons/clock.js";
|
|
7
|
+
import { Navigation as o } from "../node_modules/lucide-react/dist/esm/icons/navigation.js";
|
|
8
|
+
import { Package as s } from "../node_modules/lucide-react/dist/esm/icons/package.js";
|
|
9
|
+
import { Phone as c } from "../node_modules/lucide-react/dist/esm/icons/phone.js";
|
|
10
|
+
import { RefreshCw as l } from "../node_modules/lucide-react/dist/esm/icons/refresh-cw.js";
|
|
11
|
+
import { Route as u } from "../node_modules/lucide-react/dist/esm/icons/route.js";
|
|
12
|
+
import { TriangleAlert as d } from "../node_modules/lucide-react/dist/esm/icons/triangle-alert.js";
|
|
13
|
+
import { Truck as ee } from "../node_modules/lucide-react/dist/esm/icons/truck.js";
|
|
14
|
+
import { WifiOff as te } from "../node_modules/lucide-react/dist/esm/icons/wifi-off.js";
|
|
15
|
+
import { useMoveTheWheels as ne } from "../providers/MoveTheWheelsProvider.js";
|
|
16
|
+
import { formatAddress as f, formatDate as p, formatTime as m } from "../utils/formatters.js";
|
|
17
|
+
import { mapOrderPriority as h } from "../hooks/useOrders.js";
|
|
18
|
+
import { localDateString as g, phoneHref as _, routeNavigationUrl as v, shiftLocalDate as y, stopNavigationUrl as b } from "../utils/driverNavigation.js";
|
|
19
|
+
import { useMyDeliveryDay as re, useOnlineStatus as x } from "../hooks/useDriverDay.js";
|
|
20
|
+
import { Badge as S, Button as C, Card as w, CardContent as T, Input as ie, Progress as ae } from "../components/ui.js";
|
|
17
21
|
import { PageLayout as E } from "../components/PageLayout.js";
|
|
18
|
-
import { PriorityBadge as D
|
|
19
|
-
import { FormError as
|
|
20
|
-
import { Notice as
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import { Fragment as te, jsx as L, jsxs as R } from "react/jsx-runtime";
|
|
22
|
+
import { PriorityBadge as D } from "../components/StatusBadge.js";
|
|
23
|
+
import { FormError as O } from "../components/FormError.js";
|
|
24
|
+
import { Notice as k, useNotice as A } from "../components/Notice.js";
|
|
25
|
+
import { EpodCaptureForm as oe } from "../components/EpodCaptureForm.js";
|
|
26
|
+
import { useEffect as se, useMemo as j, useRef as M, useState as N } from "react";
|
|
27
|
+
import { Fragment as P, jsx as F, jsxs as I } from "react/jsx-runtime";
|
|
25
28
|
//#region src/movethewheels/pages/DeliveryCapturePage.tsx
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
var L = {
|
|
30
|
+
COMPLETED: "Delivered",
|
|
31
|
+
EN_ROUTE: "En route",
|
|
32
|
+
UPCOMING: "Upcoming",
|
|
33
|
+
FAILED: "Not delivered"
|
|
34
|
+
}, R = {
|
|
35
|
+
COMPLETED: "secondary",
|
|
36
|
+
EN_ROUTE: "default",
|
|
37
|
+
UPCOMING: "outline",
|
|
38
|
+
FAILED: "destructive"
|
|
39
|
+
};
|
|
40
|
+
function z(e) {
|
|
41
|
+
return e.state === "COMPLETED" || e.state === "FAILED";
|
|
42
|
+
}
|
|
43
|
+
function B(e) {
|
|
44
|
+
return {
|
|
45
|
+
id: e.jobId,
|
|
46
|
+
deliveryJobNumber: e.deliveryJobNumber,
|
|
47
|
+
status: e.status,
|
|
48
|
+
priority: e.priority,
|
|
49
|
+
deliveryAddress: e.deliveryAddress,
|
|
50
|
+
scheduledDelivery: e.scheduledDelivery,
|
|
51
|
+
customerName: e.customerName,
|
|
52
|
+
customerPhone: e.customerPhone
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function V(e) {
|
|
56
|
+
e && window.open(e, "_blank", "noopener,noreferrer");
|
|
57
|
+
}
|
|
58
|
+
function H({ state: e }) {
|
|
59
|
+
return /* @__PURE__ */ F(S, {
|
|
60
|
+
variant: R[e],
|
|
61
|
+
children: L[e]
|
|
37
62
|
});
|
|
38
63
|
}
|
|
39
|
-
function
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
let n = G.trim();
|
|
51
|
-
if (!n) {
|
|
52
|
-
Q("Recipient name is required.");
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
let r = K === "typed" ? J.trim() : W.current?.toDataUrl() ?? null;
|
|
56
|
-
if (!r) {
|
|
57
|
-
Q(K === "typed" ? "Type the recipient full name as their signature." : "A signature is required.");
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
z.current = !0, V(!0);
|
|
61
|
-
try {
|
|
62
|
-
let i;
|
|
63
|
-
if (Y) if (j.current?.file === Y) i = [j.current.id];
|
|
64
|
-
else {
|
|
65
|
-
let e = await ae(Y);
|
|
66
|
-
j.current = {
|
|
67
|
-
file: Y,
|
|
68
|
-
id: e.fileId
|
|
69
|
-
}, i = [e.fileId];
|
|
70
|
-
}
|
|
71
|
-
if (!B.current) return;
|
|
72
|
-
let a = await ne();
|
|
73
|
-
if (!B.current) return;
|
|
74
|
-
let o = await u({
|
|
75
|
-
expectedShipmentId: D.data.myEpodShipmentStatus?.id ?? null,
|
|
76
|
-
expectedShipmentStatusRevision: D.data.myEpodShipmentStatus?.statusRevision,
|
|
77
|
-
completionAttestation: O,
|
|
78
|
-
deliveryJobId: e.id,
|
|
79
|
-
recipientName: n,
|
|
80
|
-
signatureType: K,
|
|
81
|
-
signatureData: r,
|
|
82
|
-
photoFileIds: i,
|
|
83
|
-
latitude: a?.coords.latitude,
|
|
84
|
-
longitude: a?.coords.longitude,
|
|
85
|
-
locationAccuracy: a?.coords.accuracy,
|
|
86
|
-
notes: X.trim() || void 0
|
|
87
|
-
});
|
|
88
|
-
if (!B.current) return;
|
|
89
|
-
t(o.deliveryJobId);
|
|
90
|
-
} catch {
|
|
91
|
-
A(!1), ie(_ + 1);
|
|
92
|
-
} finally {
|
|
93
|
-
z.current = !1, V(!1);
|
|
94
|
-
}
|
|
95
|
-
}, $ = d || oe || re;
|
|
96
|
-
return /* @__PURE__ */ R(y, { children: [/* @__PURE__ */ L(x, { children: /* @__PURE__ */ R(S, {
|
|
97
|
-
className: "flex items-center gap-2",
|
|
98
|
-
children: [
|
|
99
|
-
/* @__PURE__ */ L(s, { size: 18 }),
|
|
100
|
-
" Capture delivery for ",
|
|
101
|
-
e.deliveryJobNumber
|
|
102
|
-
]
|
|
103
|
-
}) }), /* @__PURE__ */ R(b, {
|
|
104
|
-
className: "space-y-4",
|
|
64
|
+
function U({ stop: e }) {
|
|
65
|
+
let t = z(e);
|
|
66
|
+
return /* @__PURE__ */ F("span", {
|
|
67
|
+
"aria-hidden": "true",
|
|
68
|
+
className: `flex h-8 w-8 shrink-0 items-center justify-center rounded-full border text-sm font-semibold ${e.state === "EN_ROUTE" ? "border-primary bg-primary text-primary-foreground" : t ? "border-border bg-surface-secondary text-text-secondary" : "border-border bg-surface text-text-primary"}`,
|
|
69
|
+
children: e.state === "COMPLETED" ? /* @__PURE__ */ F(i, { size: 16 }) : e.sequence
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function W({ stop: e, onOpen: t, onCapture: n, offline: r }) {
|
|
73
|
+
return /* @__PURE__ */ F(w, { children: /* @__PURE__ */ I(T, {
|
|
74
|
+
className: "flex items-start gap-3 py-4",
|
|
105
75
|
children: [
|
|
106
|
-
/* @__PURE__ */
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
className: "space-y-2",
|
|
113
|
-
children: [
|
|
114
|
-
/* @__PURE__ */ R("p", { children: [
|
|
115
|
-
"Recorded shipment:",
|
|
116
|
-
" ",
|
|
117
|
-
D.data?.myEpodShipmentStatus ? `${D.data.myEpodShipmentStatus.status.toLowerCase().replaceAll("_", " ")} · revision ${D.data.myEpodShipmentStatus.statusRevision}` : D.data ? "No linked shipment" : "Loading current record"
|
|
118
|
-
] }),
|
|
119
|
-
D.error && /* @__PURE__ */ L("p", {
|
|
120
|
-
role: "alert",
|
|
121
|
-
children: D.error
|
|
122
|
-
}),
|
|
123
|
-
/* @__PURE__ */ L(v, {
|
|
124
|
-
variant: "outline",
|
|
125
|
-
disabled: D.loading || $,
|
|
126
|
-
onClick: () => {
|
|
127
|
-
A(!1), E((e) => e + 1);
|
|
128
|
-
},
|
|
129
|
-
children: "Refresh linked status"
|
|
130
|
-
}),
|
|
131
|
-
/* @__PURE__ */ R("label", {
|
|
132
|
-
className: "flex items-start gap-2",
|
|
133
|
-
children: [/* @__PURE__ */ L("input", {
|
|
134
|
-
type: "checkbox",
|
|
135
|
-
checked: O,
|
|
136
|
-
disabled: D.loading || !!D.error || $ || _ < H || p?.kind === "UNKNOWN",
|
|
137
|
-
onChange: (e) => A(e.target.checked)
|
|
138
|
-
}), "I reviewed the recorded linked status and attest to this delivery completion."]
|
|
139
|
-
}),
|
|
140
|
-
/* @__PURE__ */ L("p", { children: "This records an assigned driver's attestation; it does not independently verify physical freight movement." }),
|
|
141
|
-
p && /* @__PURE__ */ L("p", {
|
|
142
|
-
role: "status",
|
|
143
|
-
children: p.message
|
|
144
|
-
})
|
|
145
|
-
]
|
|
146
|
-
}),
|
|
147
|
-
/* @__PURE__ */ R("div", {
|
|
148
|
-
className: "space-y-1.5",
|
|
149
|
-
children: [/* @__PURE__ */ L(w, {
|
|
150
|
-
htmlFor: "epod-recipient-name",
|
|
151
|
-
children: "Recipient name"
|
|
152
|
-
}), /* @__PURE__ */ L(C, {
|
|
153
|
-
id: "epod-recipient-name",
|
|
154
|
-
value: G,
|
|
155
|
-
onChange: (e) => se(e.target.value),
|
|
156
|
-
placeholder: "Who received the delivery?"
|
|
157
|
-
})]
|
|
158
|
-
}),
|
|
159
|
-
/* @__PURE__ */ R("div", {
|
|
160
|
-
className: "space-y-1.5",
|
|
76
|
+
/* @__PURE__ */ F(U, { stop: e }),
|
|
77
|
+
/* @__PURE__ */ I("button", {
|
|
78
|
+
type: "button",
|
|
79
|
+
onClick: t,
|
|
80
|
+
"aria-label": `Stop ${e.sequence}, ${e.deliveryJobNumber}, open details`,
|
|
81
|
+
className: "min-w-0 flex-1 text-left",
|
|
161
82
|
children: [
|
|
162
|
-
/* @__PURE__ */
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
onClick: () => q("typed"),
|
|
176
|
-
children: [/* @__PURE__ */ L(c, { size: 14 }), " Type name instead"]
|
|
177
|
-
})]
|
|
83
|
+
/* @__PURE__ */ I("div", {
|
|
84
|
+
className: "flex flex-wrap items-center gap-1.5",
|
|
85
|
+
children: [
|
|
86
|
+
/* @__PURE__ */ I("span", {
|
|
87
|
+
className: "font-medium",
|
|
88
|
+
children: ["Stop ", e.sequence]
|
|
89
|
+
}),
|
|
90
|
+
/* @__PURE__ */ F(H, { state: e.state }),
|
|
91
|
+
e.overdue && /* @__PURE__ */ F(S, {
|
|
92
|
+
variant: "destructive",
|
|
93
|
+
children: "Overdue"
|
|
94
|
+
})
|
|
95
|
+
]
|
|
178
96
|
}),
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
placeholder: "Type full name as signature"
|
|
183
|
-
})
|
|
184
|
-
]
|
|
185
|
-
}),
|
|
186
|
-
/* @__PURE__ */ R("div", {
|
|
187
|
-
className: "space-y-1.5",
|
|
188
|
-
children: [
|
|
189
|
-
/* @__PURE__ */ L(w, {
|
|
190
|
-
htmlFor: "epod-photo",
|
|
191
|
-
children: "Delivery photo (optional)"
|
|
97
|
+
e.deliveryAddress && /* @__PURE__ */ F("p", {
|
|
98
|
+
className: "mt-1 text-sm text-text-secondary",
|
|
99
|
+
children: f(e.deliveryAddress)
|
|
192
100
|
}),
|
|
193
|
-
/* @__PURE__ */
|
|
194
|
-
className: "flex items-center gap-
|
|
195
|
-
children: [
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
101
|
+
/* @__PURE__ */ I("p", {
|
|
102
|
+
className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-text-secondary",
|
|
103
|
+
children: [
|
|
104
|
+
e.scheduledDelivery && /* @__PURE__ */ I("span", {
|
|
105
|
+
className: "flex items-center gap-1",
|
|
106
|
+
children: [
|
|
107
|
+
/* @__PURE__ */ F(a, { size: 12 }),
|
|
108
|
+
" ",
|
|
109
|
+
m(e.scheduledDelivery)
|
|
110
|
+
]
|
|
111
|
+
}),
|
|
112
|
+
/* @__PURE__ */ I("span", {
|
|
113
|
+
className: "flex items-center gap-1",
|
|
114
|
+
children: [
|
|
115
|
+
/* @__PURE__ */ F(s, { size: 12 }),
|
|
116
|
+
" ",
|
|
117
|
+
e.deliveryJobNumber
|
|
118
|
+
]
|
|
119
|
+
}),
|
|
120
|
+
e.routeName && /* @__PURE__ */ I("span", {
|
|
121
|
+
className: "flex items-center gap-1",
|
|
122
|
+
children: [
|
|
123
|
+
/* @__PURE__ */ F(u, { size: 12 }),
|
|
124
|
+
" ",
|
|
125
|
+
e.routeName
|
|
126
|
+
]
|
|
127
|
+
})
|
|
128
|
+
]
|
|
210
129
|
})
|
|
211
130
|
]
|
|
212
131
|
}),
|
|
213
|
-
/* @__PURE__ */
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
id: "epod-notes",
|
|
220
|
-
value: X,
|
|
221
|
-
onChange: (e) => ue(e.target.value),
|
|
222
|
-
placeholder: "e.g. Left with front desk, gate code used, etc.",
|
|
223
|
-
rows: 2
|
|
224
|
-
})]
|
|
225
|
-
}),
|
|
226
|
-
/* @__PURE__ */ R("p", {
|
|
227
|
-
className: "flex items-center gap-1.5 text-xs text-text-secondary",
|
|
228
|
-
children: [/* @__PURE__ */ L(i, { size: 12 }), " Device GPS is captured automatically when permitted by the browser."]
|
|
229
|
-
}),
|
|
230
|
-
Z && /* @__PURE__ */ L(k, { message: Z }),
|
|
231
|
-
f && /* @__PURE__ */ L(k, { message: f.message }),
|
|
232
|
-
U && /* @__PURE__ */ L(k, { message: U.message }),
|
|
233
|
-
/* @__PURE__ */ R("div", {
|
|
234
|
-
className: "flex gap-2 justify-end",
|
|
235
|
-
children: [/* @__PURE__ */ L(v, {
|
|
236
|
-
type: "button",
|
|
237
|
-
variant: "outline",
|
|
238
|
-
onClick: a,
|
|
239
|
-
disabled: $,
|
|
240
|
-
children: "Cancel"
|
|
241
|
-
}), /* @__PURE__ */ L(v, {
|
|
242
|
-
type: "button",
|
|
243
|
-
onClick: () => void de(),
|
|
244
|
-
disabled: $ || D.loading || !!D.error || !D.data || _ < H || !O || p?.kind === "UNKNOWN",
|
|
245
|
-
children: $ ? /* @__PURE__ */ R(te, { children: [/* @__PURE__ */ L(r, {
|
|
246
|
-
size: 14,
|
|
247
|
-
className: "animate-spin"
|
|
248
|
-
}), " Submitting…"] }) : /* @__PURE__ */ R(te, { children: [/* @__PURE__ */ L(n, { size: 14 }), " Confirm delivery"] })
|
|
249
|
-
})]
|
|
132
|
+
e.awaitingCapture && /* @__PURE__ */ F(C, {
|
|
133
|
+
type: "button",
|
|
134
|
+
size: "sm",
|
|
135
|
+
onClick: n,
|
|
136
|
+
disabled: r,
|
|
137
|
+
children: "Capture"
|
|
250
138
|
})
|
|
251
139
|
]
|
|
252
|
-
})
|
|
140
|
+
}) });
|
|
141
|
+
}
|
|
142
|
+
function G({ stop: t, onBack: n, onCapture: r, offline: a }) {
|
|
143
|
+
let s = b(t.deliveryAddress), l = _(t.customerPhone);
|
|
144
|
+
return /* @__PURE__ */ I("div", {
|
|
145
|
+
className: "space-y-4",
|
|
146
|
+
children: [/* @__PURE__ */ I(C, {
|
|
147
|
+
type: "button",
|
|
148
|
+
variant: "ghost",
|
|
149
|
+
size: "sm",
|
|
150
|
+
onClick: n,
|
|
151
|
+
children: [/* @__PURE__ */ F(e, { size: 16 }), " All stops"]
|
|
152
|
+
}), /* @__PURE__ */ F(w, { children: /* @__PURE__ */ I(T, {
|
|
153
|
+
className: "space-y-4 py-5",
|
|
154
|
+
children: [
|
|
155
|
+
/* @__PURE__ */ I("div", {
|
|
156
|
+
className: "flex flex-wrap items-center gap-2",
|
|
157
|
+
children: [
|
|
158
|
+
/* @__PURE__ */ F(U, { stop: t }),
|
|
159
|
+
/* @__PURE__ */ I("h2", {
|
|
160
|
+
className: "text-lg font-semibold",
|
|
161
|
+
children: ["Stop ", t.sequence]
|
|
162
|
+
}),
|
|
163
|
+
/* @__PURE__ */ F(H, { state: t.state }),
|
|
164
|
+
/* @__PURE__ */ F(D, {
|
|
165
|
+
priority: h(t.priority),
|
|
166
|
+
size: "sm"
|
|
167
|
+
}),
|
|
168
|
+
t.overdue && /* @__PURE__ */ F(S, {
|
|
169
|
+
variant: "destructive",
|
|
170
|
+
children: "Overdue"
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
}),
|
|
174
|
+
/* @__PURE__ */ I("dl", {
|
|
175
|
+
className: "grid gap-3 text-sm",
|
|
176
|
+
children: [
|
|
177
|
+
/* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("dt", {
|
|
178
|
+
className: "text-text-secondary",
|
|
179
|
+
children: "Deliver to"
|
|
180
|
+
}), /* @__PURE__ */ F("dd", {
|
|
181
|
+
className: "font-medium",
|
|
182
|
+
children: t.deliveryAddress ? f(t.deliveryAddress) : "No address on file"
|
|
183
|
+
})] }),
|
|
184
|
+
t.customerName && /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("dt", {
|
|
185
|
+
className: "text-text-secondary",
|
|
186
|
+
children: "Recipient"
|
|
187
|
+
}), /* @__PURE__ */ F("dd", {
|
|
188
|
+
className: "font-medium",
|
|
189
|
+
children: t.customerName
|
|
190
|
+
})] }),
|
|
191
|
+
/* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("dt", {
|
|
192
|
+
className: "text-text-secondary",
|
|
193
|
+
children: "Order"
|
|
194
|
+
}), /* @__PURE__ */ F("dd", {
|
|
195
|
+
className: "font-medium",
|
|
196
|
+
children: t.deliveryJobNumber
|
|
197
|
+
})] }),
|
|
198
|
+
t.scheduledDelivery && /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("dt", {
|
|
199
|
+
className: "text-text-secondary",
|
|
200
|
+
children: "Scheduled"
|
|
201
|
+
}), /* @__PURE__ */ F("dd", {
|
|
202
|
+
className: "font-medium",
|
|
203
|
+
children: p(t.scheduledDelivery, "full")
|
|
204
|
+
})] }),
|
|
205
|
+
t.routeName && /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("dt", {
|
|
206
|
+
className: "text-text-secondary",
|
|
207
|
+
children: "Route"
|
|
208
|
+
}), /* @__PURE__ */ F("dd", {
|
|
209
|
+
className: "font-medium",
|
|
210
|
+
children: t.routeName
|
|
211
|
+
})] }),
|
|
212
|
+
t.specialInstructions && /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("dt", {
|
|
213
|
+
className: "text-text-secondary",
|
|
214
|
+
children: "Delivery instructions"
|
|
215
|
+
}), /* @__PURE__ */ F("dd", {
|
|
216
|
+
className: "whitespace-pre-line",
|
|
217
|
+
children: t.specialInstructions
|
|
218
|
+
})] }),
|
|
219
|
+
t.deliveredAt && /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("dt", {
|
|
220
|
+
className: "text-text-secondary",
|
|
221
|
+
children: "Proof of delivery captured"
|
|
222
|
+
}), /* @__PURE__ */ F("dd", {
|
|
223
|
+
className: "font-medium",
|
|
224
|
+
children: p(t.deliveredAt, "full")
|
|
225
|
+
})] })
|
|
226
|
+
]
|
|
227
|
+
}),
|
|
228
|
+
/* @__PURE__ */ I("div", {
|
|
229
|
+
className: "grid gap-2 sm:grid-cols-2",
|
|
230
|
+
children: [/* @__PURE__ */ I(C, {
|
|
231
|
+
type: "button",
|
|
232
|
+
variant: "outline",
|
|
233
|
+
disabled: !s,
|
|
234
|
+
onClick: () => V(s),
|
|
235
|
+
children: [/* @__PURE__ */ F(o, { size: 16 }), " Navigate"]
|
|
236
|
+
}), /* @__PURE__ */ I(C, {
|
|
237
|
+
type: "button",
|
|
238
|
+
variant: "outline",
|
|
239
|
+
disabled: !l,
|
|
240
|
+
onClick: () => {
|
|
241
|
+
l && (window.location.href = l);
|
|
242
|
+
},
|
|
243
|
+
children: [/* @__PURE__ */ F(c, { size: 16 }), " Call recipient"]
|
|
244
|
+
})]
|
|
245
|
+
}),
|
|
246
|
+
t.awaitingCapture ? /* @__PURE__ */ I(C, {
|
|
247
|
+
type: "button",
|
|
248
|
+
className: "w-full",
|
|
249
|
+
onClick: r,
|
|
250
|
+
disabled: a,
|
|
251
|
+
children: [/* @__PURE__ */ F(i, { size: 16 }), " Capture proof of delivery"]
|
|
252
|
+
}) : t.state === "UPCOMING" ? /* @__PURE__ */ F("p", {
|
|
253
|
+
className: "text-sm text-text-secondary",
|
|
254
|
+
children: "Proof of delivery opens once dispatch marks this stop out for delivery."
|
|
255
|
+
}) : null
|
|
256
|
+
]
|
|
257
|
+
}) })]
|
|
258
|
+
});
|
|
253
259
|
}
|
|
254
|
-
function
|
|
255
|
-
let { workspaceId:
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
+
function K() {
|
|
261
|
+
let { workspaceId: e, tenantId: a, currentUser: o, apiGatewayUrl: s } = ne(), c = x(), m = !c, [h, _] = N(() => g(/* @__PURE__ */ new Date())), [b, S] = N("all"), [D, L] = N({ kind: "list" }), { day: R, isLoading: H, error: U, refetch: K, markCaptured: ce } = re(h), { message: le, notify: ue } = A(), q = g(/* @__PURE__ */ new Date()), J = M(!1);
|
|
262
|
+
se(() => {
|
|
263
|
+
c ? J.current && (J.current = !1, K()) : J.current = !0;
|
|
264
|
+
}, [c, K]);
|
|
265
|
+
let Y = j(() => R?.stops ?? [], [R]), X = j(() => Y.filter((e) => b === "all" ? !0 : b === "completed" ? z(e) : !z(e)), [Y, b]), Z = j(() => v(Y.filter((e) => !z(e)).map((e) => e.deliveryAddress)), [Y]), Q = D.kind === "list" ? null : Y.find((e) => e.jobId === D.jobId) ?? null, de = (e) => {
|
|
266
|
+
ce(e), ue("Proof of delivery captured — delivery marked complete."), L({ kind: "list" }), K();
|
|
267
|
+
}, $ = (e) => {
|
|
268
|
+
/^\d{4}-\d{2}-\d{2}$/.test(e) && (_(e), L({ kind: "list" }));
|
|
269
|
+
}, fe = R && R.totalStops > 0 ? R.completedStops / R.totalStops * 100 : 0;
|
|
270
|
+
return /* @__PURE__ */ F(E, {
|
|
260
271
|
title: "My Deliveries",
|
|
261
|
-
subtitle: "
|
|
262
|
-
icon: /* @__PURE__ */
|
|
263
|
-
|
|
272
|
+
subtitle: "Your stops for the day, in order — navigate, then capture proof of delivery",
|
|
273
|
+
icon: /* @__PURE__ */ F(ee, { size: 24 }),
|
|
274
|
+
maxWidth: "2xl",
|
|
275
|
+
children: /* @__PURE__ */ I("div", {
|
|
264
276
|
className: "space-y-4",
|
|
265
|
-
children: [
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
277
|
+
children: [
|
|
278
|
+
/* @__PURE__ */ F(k, { message: le }),
|
|
279
|
+
m && /* @__PURE__ */ I("div", {
|
|
280
|
+
role: "status",
|
|
281
|
+
className: "flex items-start gap-2 rounded-md border border-border bg-surface-secondary p-3 text-sm",
|
|
282
|
+
children: [/* @__PURE__ */ F(te, {
|
|
283
|
+
size: 16,
|
|
284
|
+
className: "mt-0.5 shrink-0"
|
|
285
|
+
}), /* @__PURE__ */ F("span", { children: "You are offline. Your last loaded stops stay available; reconnect to capture proof of delivery." })]
|
|
286
|
+
}),
|
|
287
|
+
Q && D.kind === "capture" && Q.awaitingCapture ? /* @__PURE__ */ F(oe, {
|
|
288
|
+
job: B(Q),
|
|
289
|
+
offline: m,
|
|
290
|
+
onCaptured: de,
|
|
291
|
+
onCancel: () => L({
|
|
292
|
+
kind: "stop",
|
|
293
|
+
jobId: Q.jobId
|
|
294
|
+
})
|
|
295
|
+
}, `${e}:${a}:${o?.id}:${s}:${Q.jobId}`) : Q ? /* @__PURE__ */ F(G, {
|
|
296
|
+
stop: Q,
|
|
297
|
+
offline: m,
|
|
298
|
+
onBack: () => L({ kind: "list" }),
|
|
299
|
+
onCapture: () => L({
|
|
300
|
+
kind: "capture",
|
|
301
|
+
jobId: Q.jobId
|
|
302
|
+
})
|
|
303
|
+
}) : /* @__PURE__ */ I(P, { children: [
|
|
304
|
+
/* @__PURE__ */ I("div", {
|
|
305
|
+
className: "flex flex-wrap items-center gap-2",
|
|
280
306
|
children: [
|
|
281
|
-
/* @__PURE__ */
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
307
|
+
/* @__PURE__ */ F(C, {
|
|
308
|
+
type: "button",
|
|
309
|
+
variant: "outline",
|
|
310
|
+
size: "sm",
|
|
311
|
+
"aria-label": "Previous day",
|
|
312
|
+
onClick: () => $(y(h, -1)),
|
|
313
|
+
children: /* @__PURE__ */ F(n, { size: 16 })
|
|
314
|
+
}),
|
|
315
|
+
/* @__PURE__ */ I(C, {
|
|
316
|
+
type: "button",
|
|
317
|
+
variant: h === q ? "default" : "outline",
|
|
318
|
+
size: "sm",
|
|
319
|
+
onClick: () => $(q),
|
|
320
|
+
children: [/* @__PURE__ */ F(t, { size: 16 }), " Today"]
|
|
288
321
|
}),
|
|
289
|
-
/* @__PURE__ */
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
priority: f(e.priority),
|
|
297
|
-
size: "sm"
|
|
298
|
-
})]
|
|
322
|
+
/* @__PURE__ */ F(C, {
|
|
323
|
+
type: "button",
|
|
324
|
+
variant: "outline",
|
|
325
|
+
size: "sm",
|
|
326
|
+
"aria-label": "Next day",
|
|
327
|
+
onClick: () => $(y(h, 1)),
|
|
328
|
+
children: /* @__PURE__ */ F(r, { size: 16 })
|
|
299
329
|
}),
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
330
|
+
/* @__PURE__ */ F(ie, {
|
|
331
|
+
type: "date",
|
|
332
|
+
"aria-label": "Delivery date",
|
|
333
|
+
value: h,
|
|
334
|
+
onChange: (e) => $(e.target.value),
|
|
335
|
+
className: "w-auto"
|
|
303
336
|
}),
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
337
|
+
/* @__PURE__ */ F(C, {
|
|
338
|
+
type: "button",
|
|
339
|
+
variant: "ghost",
|
|
340
|
+
size: "sm",
|
|
341
|
+
"aria-label": "Refresh stops",
|
|
342
|
+
disabled: H || m,
|
|
343
|
+
onClick: () => void K(),
|
|
344
|
+
children: /* @__PURE__ */ F(l, {
|
|
345
|
+
size: 16,
|
|
346
|
+
className: H ? "animate-spin" : void 0
|
|
347
|
+
})
|
|
307
348
|
})
|
|
308
349
|
]
|
|
309
|
-
}),
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
children: "
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
350
|
+
}),
|
|
351
|
+
U && /* @__PURE__ */ F(O, { message: U.message }),
|
|
352
|
+
H && !R ? /* @__PURE__ */ F("p", {
|
|
353
|
+
className: "py-8 text-center text-text-secondary",
|
|
354
|
+
children: "Loading your deliveries…"
|
|
355
|
+
}) : R && R.driverId === null ? /* @__PURE__ */ I("div", {
|
|
356
|
+
className: "py-12 text-center",
|
|
357
|
+
children: [/* @__PURE__ */ F(d, {
|
|
358
|
+
size: 40,
|
|
359
|
+
className: "mx-auto mb-3 text-text-secondary opacity-50"
|
|
360
|
+
}), /* @__PURE__ */ F("p", {
|
|
361
|
+
className: "text-text-secondary",
|
|
362
|
+
children: "Your account is not linked to a driver in this workspace. Ask your dispatcher to link your user on the driver profile."
|
|
363
|
+
})]
|
|
364
|
+
}) : R ? /* @__PURE__ */ I(P, { children: [
|
|
365
|
+
/* @__PURE__ */ F(w, { children: /* @__PURE__ */ I(T, {
|
|
366
|
+
className: "space-y-3 py-4",
|
|
367
|
+
children: [
|
|
368
|
+
/* @__PURE__ */ I("div", {
|
|
369
|
+
className: "flex flex-wrap items-baseline justify-between gap-2",
|
|
370
|
+
children: [/* @__PURE__ */ I("p", {
|
|
371
|
+
className: "font-medium",
|
|
372
|
+
children: [
|
|
373
|
+
R.completedStops,
|
|
374
|
+
" of ",
|
|
375
|
+
R.totalStops,
|
|
376
|
+
" stops done",
|
|
377
|
+
R.driverName ? ` · ${R.driverName}` : ""
|
|
378
|
+
]
|
|
379
|
+
}), /* @__PURE__ */ F("p", {
|
|
380
|
+
className: "text-sm text-text-secondary",
|
|
381
|
+
children: p(/* @__PURE__ */ new Date(`${h}T12:00:00`), "full")
|
|
382
|
+
})]
|
|
383
|
+
}),
|
|
384
|
+
/* @__PURE__ */ F(ae, {
|
|
385
|
+
value: fe,
|
|
386
|
+
"aria-label": "Stops completed"
|
|
387
|
+
}),
|
|
388
|
+
R.nextStop && /* @__PURE__ */ I("div", {
|
|
389
|
+
className: "rounded-md border border-border p-3",
|
|
390
|
+
children: [
|
|
391
|
+
/* @__PURE__ */ I("p", {
|
|
392
|
+
className: "text-xs uppercase tracking-wide text-text-secondary",
|
|
393
|
+
children: ["Next stop · Stop ", R.nextStop.sequence]
|
|
394
|
+
}),
|
|
395
|
+
/* @__PURE__ */ F("p", {
|
|
396
|
+
className: "mt-1 font-medium",
|
|
397
|
+
children: R.nextStop.deliveryAddress ? f(R.nextStop.deliveryAddress) : R.nextStop.deliveryJobNumber
|
|
398
|
+
}),
|
|
399
|
+
R.nextStop.customerName && /* @__PURE__ */ I("p", {
|
|
400
|
+
className: "text-sm text-text-secondary",
|
|
401
|
+
children: ["Recipient: ", R.nextStop.customerName]
|
|
402
|
+
}),
|
|
403
|
+
/* @__PURE__ */ I("div", {
|
|
404
|
+
className: "mt-3 grid gap-2 sm:grid-cols-2",
|
|
405
|
+
children: [/* @__PURE__ */ I(C, {
|
|
406
|
+
type: "button",
|
|
407
|
+
onClick: () => V(Z),
|
|
408
|
+
disabled: !Z,
|
|
409
|
+
children: [/* @__PURE__ */ F(u, { size: 16 }), " Start route"]
|
|
410
|
+
}), /* @__PURE__ */ I(C, {
|
|
411
|
+
type: "button",
|
|
412
|
+
variant: "outline",
|
|
413
|
+
onClick: () => {
|
|
414
|
+
let e = R.nextStop;
|
|
415
|
+
e && L({
|
|
416
|
+
kind: "stop",
|
|
417
|
+
jobId: e.jobId
|
|
418
|
+
});
|
|
419
|
+
},
|
|
420
|
+
children: ["Stop details ", /* @__PURE__ */ F(r, { size: 16 })]
|
|
421
|
+
})]
|
|
422
|
+
})
|
|
423
|
+
]
|
|
424
|
+
})
|
|
425
|
+
]
|
|
426
|
+
}) }),
|
|
427
|
+
/* @__PURE__ */ F("div", {
|
|
428
|
+
role: "tablist",
|
|
429
|
+
"aria-label": "Filter stops",
|
|
430
|
+
className: "flex gap-2",
|
|
431
|
+
children: [
|
|
432
|
+
["all", `All stops (${R.totalStops})`],
|
|
433
|
+
["remaining", `Remaining (${R.remainingStops})`],
|
|
434
|
+
["completed", `Done (${R.completedStops})`]
|
|
435
|
+
].map(([e, t]) => /* @__PURE__ */ F(C, {
|
|
436
|
+
type: "button",
|
|
437
|
+
role: "tab",
|
|
438
|
+
"aria-selected": b === e,
|
|
439
|
+
size: "sm",
|
|
440
|
+
variant: b === e ? "default" : "outline",
|
|
441
|
+
onClick: () => S(e),
|
|
442
|
+
children: t
|
|
443
|
+
}, e))
|
|
444
|
+
}),
|
|
445
|
+
X.length > 0 ? /* @__PURE__ */ F("div", {
|
|
446
|
+
className: "space-y-3",
|
|
447
|
+
children: X.map((e) => /* @__PURE__ */ F(W, {
|
|
448
|
+
stop: e,
|
|
449
|
+
offline: m,
|
|
450
|
+
onOpen: () => L({
|
|
451
|
+
kind: "stop",
|
|
452
|
+
jobId: e.jobId
|
|
453
|
+
}),
|
|
454
|
+
onCapture: () => L({
|
|
455
|
+
kind: "capture",
|
|
456
|
+
jobId: e.jobId
|
|
457
|
+
})
|
|
458
|
+
}, e.jobId))
|
|
459
|
+
}) : /* @__PURE__ */ I("div", {
|
|
460
|
+
className: "py-12 text-center",
|
|
461
|
+
children: [/* @__PURE__ */ F(i, {
|
|
462
|
+
size: 40,
|
|
463
|
+
className: "mx-auto mb-3 text-text-secondary opacity-50"
|
|
464
|
+
}), /* @__PURE__ */ F("p", {
|
|
465
|
+
className: "text-text-secondary",
|
|
466
|
+
children: R.totalStops === 0 ? "No deliveries scheduled for this day." : b === "completed" ? "No stops completed yet." : "All stops done for this day."
|
|
467
|
+
})]
|
|
468
|
+
})
|
|
469
|
+
] }) : null
|
|
470
|
+
] })
|
|
471
|
+
]
|
|
343
472
|
})
|
|
344
473
|
});
|
|
345
474
|
}
|
|
346
475
|
//#endregion
|
|
347
|
-
export {
|
|
476
|
+
export { K as default };
|