@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
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { CircleCheck as e } from "../node_modules/lucide-react/dist/esm/icons/circle-check.js";
|
|
2
|
+
import { LoaderCircle as t } from "../node_modules/lucide-react/dist/esm/icons/loader-circle.js";
|
|
3
|
+
import { MapPin as n } from "../node_modules/lucide-react/dist/esm/icons/map-pin.js";
|
|
4
|
+
import { PenLine as r } from "../node_modules/lucide-react/dist/esm/icons/pen-line.js";
|
|
5
|
+
import { Truck as i } from "../node_modules/lucide-react/dist/esm/icons/truck.js";
|
|
6
|
+
import { Type as a } from "../node_modules/lucide-react/dist/esm/icons/type.js";
|
|
7
|
+
import { Upload as o } from "../node_modules/lucide-react/dist/esm/icons/upload.js";
|
|
8
|
+
import { formatAddress as ee } from "../utils/formatters.js";
|
|
9
|
+
import { useShipmentStatusQuery as te } from "../hooks/useShipmentStatusAuthority.js";
|
|
10
|
+
import { useCaptureEpod as ne, useEpodPhotoUpload as s } from "../hooks/useEpod.js";
|
|
11
|
+
import { Button as c, Card as l, CardContent as re, CardHeader as ie, CardTitle as ae, Input as u, Label as d, Textarea as f } from "./ui.js";
|
|
12
|
+
import { FormError as p } from "./FormError.js";
|
|
13
|
+
import { SignaturePad as m } from "./SignaturePad.js";
|
|
14
|
+
import { StatusAuthorityOwnedDeliveryDocument as h } from "../src/generated/shipment-status-authority-operations.js";
|
|
15
|
+
import { useEffect as oe, useRef as g, useState as _ } from "react";
|
|
16
|
+
import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
17
|
+
//#region src/movethewheels/components/EpodCaptureForm.tsx
|
|
18
|
+
function x() {
|
|
19
|
+
return new Promise((e) => {
|
|
20
|
+
if (!navigator.geolocation) {
|
|
21
|
+
e(null);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
navigator.geolocation.getCurrentPosition((t) => e(t), () => e(null), {
|
|
25
|
+
enableHighAccuracy: !0,
|
|
26
|
+
timeout: 8e3,
|
|
27
|
+
maximumAge: 3e4
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function S({ job: S, onCaptured: C, onCancel: w, offline: T = !1 }) {
|
|
32
|
+
let { captureEpod: E, isSubmitting: D, error: O, captureFeedback: k } = ne(), [A, se] = _(0), j = te(h, { deliveryJobId: S.id }, A), [M, N] = _(!1), P = g(null), F = g(!1), I = g(!0);
|
|
33
|
+
oe(() => (I.current = !0, () => {
|
|
34
|
+
I.current = !1;
|
|
35
|
+
}), []);
|
|
36
|
+
let [L, R] = _(!1), [z, B] = _(0), { upload: V, isUploading: H, error: U } = s(), W = g(null), [G, ce] = _(""), [K, q] = _("drawn"), [J, le] = _(""), [Y, ue] = _(null), [X, de] = _(""), [Z, Q] = _(null), fe = async () => {
|
|
37
|
+
if (F.current) return;
|
|
38
|
+
if (Q(null), T) {
|
|
39
|
+
Q("You are offline. Reconnect to confirm this delivery.");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (j.loading || j.error || !j.data || A < z || !M || k?.kind === "UNKNOWN") {
|
|
43
|
+
Q("Review the current linked shipment status and confirm completion before capture. Do not resend an uncertain capture.");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
let e = G.trim();
|
|
47
|
+
if (!e) {
|
|
48
|
+
Q("Recipient name is required.");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
let t = K === "typed" ? J.trim() : W.current?.toDataUrl() ?? null;
|
|
52
|
+
if (!t) {
|
|
53
|
+
Q(K === "typed" ? "Type the recipient full name as their signature." : "A signature is required.");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
F.current = !0, R(!0);
|
|
57
|
+
try {
|
|
58
|
+
let n;
|
|
59
|
+
if (Y) if (P.current?.file === Y) n = [P.current.id];
|
|
60
|
+
else {
|
|
61
|
+
let e = await V(Y);
|
|
62
|
+
P.current = {
|
|
63
|
+
file: Y,
|
|
64
|
+
id: e.fileId
|
|
65
|
+
}, n = [e.fileId];
|
|
66
|
+
}
|
|
67
|
+
if (!I.current) return;
|
|
68
|
+
let r = await x();
|
|
69
|
+
if (!I.current) return;
|
|
70
|
+
let i = await E({
|
|
71
|
+
expectedShipmentId: j.data.myEpodShipmentStatus?.id ?? null,
|
|
72
|
+
expectedShipmentStatusRevision: j.data.myEpodShipmentStatus?.statusRevision,
|
|
73
|
+
completionAttestation: M,
|
|
74
|
+
deliveryJobId: S.id,
|
|
75
|
+
recipientName: e,
|
|
76
|
+
signatureType: K,
|
|
77
|
+
signatureData: t,
|
|
78
|
+
photoFileIds: n,
|
|
79
|
+
latitude: r?.coords.latitude,
|
|
80
|
+
longitude: r?.coords.longitude,
|
|
81
|
+
locationAccuracy: r?.coords.accuracy,
|
|
82
|
+
notes: X.trim() || void 0
|
|
83
|
+
});
|
|
84
|
+
if (!I.current) return;
|
|
85
|
+
C(i.deliveryJobId);
|
|
86
|
+
} catch {
|
|
87
|
+
N(!1), B(A + 1);
|
|
88
|
+
} finally {
|
|
89
|
+
F.current = !1, R(!1);
|
|
90
|
+
}
|
|
91
|
+
}, $ = D || H || L;
|
|
92
|
+
return /* @__PURE__ */ b(l, { children: [/* @__PURE__ */ y(ie, { children: /* @__PURE__ */ b(ae, {
|
|
93
|
+
className: "flex items-center gap-2",
|
|
94
|
+
children: [
|
|
95
|
+
/* @__PURE__ */ y(i, { size: 18 }),
|
|
96
|
+
" Capture delivery for ",
|
|
97
|
+
S.deliveryJobNumber
|
|
98
|
+
]
|
|
99
|
+
}) }), /* @__PURE__ */ b(re, {
|
|
100
|
+
className: "space-y-4",
|
|
101
|
+
children: [
|
|
102
|
+
/* @__PURE__ */ b("div", {
|
|
103
|
+
className: "text-sm text-text-secondary space-y-1",
|
|
104
|
+
children: [S.customerName && /* @__PURE__ */ b("p", { children: ["Recipient on file: ", S.customerName] }), S.deliveryAddress && /* @__PURE__ */ y("p", { children: ee(S.deliveryAddress) })]
|
|
105
|
+
}),
|
|
106
|
+
/* @__PURE__ */ b("section", {
|
|
107
|
+
"aria-label": "Linked shipment status",
|
|
108
|
+
className: "space-y-2",
|
|
109
|
+
children: [
|
|
110
|
+
/* @__PURE__ */ b("p", { children: [
|
|
111
|
+
"Recorded shipment:",
|
|
112
|
+
" ",
|
|
113
|
+
j.data?.myEpodShipmentStatus ? `${j.data.myEpodShipmentStatus.status.toLowerCase().replaceAll("_", " ")} · revision ${j.data.myEpodShipmentStatus.statusRevision}` : j.data ? "No linked shipment" : "Loading current record"
|
|
114
|
+
] }),
|
|
115
|
+
j.error && /* @__PURE__ */ y("p", {
|
|
116
|
+
role: "alert",
|
|
117
|
+
children: j.error
|
|
118
|
+
}),
|
|
119
|
+
/* @__PURE__ */ y(c, {
|
|
120
|
+
variant: "outline",
|
|
121
|
+
disabled: j.loading || $,
|
|
122
|
+
onClick: () => {
|
|
123
|
+
N(!1), se((e) => e + 1);
|
|
124
|
+
},
|
|
125
|
+
children: "Refresh linked status"
|
|
126
|
+
}),
|
|
127
|
+
/* @__PURE__ */ b("label", {
|
|
128
|
+
className: "flex items-start gap-2",
|
|
129
|
+
children: [/* @__PURE__ */ y("input", {
|
|
130
|
+
type: "checkbox",
|
|
131
|
+
checked: M,
|
|
132
|
+
disabled: j.loading || !!j.error || $ || A < z || k?.kind === "UNKNOWN",
|
|
133
|
+
onChange: (e) => N(e.target.checked)
|
|
134
|
+
}), "I reviewed the recorded linked status and attest to this delivery completion."]
|
|
135
|
+
}),
|
|
136
|
+
/* @__PURE__ */ y("p", { children: "This records an assigned driver's attestation; it does not independently verify physical freight movement." }),
|
|
137
|
+
k && /* @__PURE__ */ y("p", {
|
|
138
|
+
role: "status",
|
|
139
|
+
children: k.message
|
|
140
|
+
})
|
|
141
|
+
]
|
|
142
|
+
}),
|
|
143
|
+
/* @__PURE__ */ b("div", {
|
|
144
|
+
className: "space-y-1.5",
|
|
145
|
+
children: [/* @__PURE__ */ y(d, {
|
|
146
|
+
htmlFor: "epod-recipient-name",
|
|
147
|
+
children: "Recipient name"
|
|
148
|
+
}), /* @__PURE__ */ y(u, {
|
|
149
|
+
id: "epod-recipient-name",
|
|
150
|
+
value: G,
|
|
151
|
+
onChange: (e) => ce(e.target.value),
|
|
152
|
+
placeholder: "Who received the delivery?"
|
|
153
|
+
})]
|
|
154
|
+
}),
|
|
155
|
+
/* @__PURE__ */ b("div", {
|
|
156
|
+
className: "space-y-1.5",
|
|
157
|
+
children: [
|
|
158
|
+
/* @__PURE__ */ y(d, { children: "Signature" }),
|
|
159
|
+
/* @__PURE__ */ b("div", {
|
|
160
|
+
className: "flex gap-2",
|
|
161
|
+
children: [/* @__PURE__ */ b(c, {
|
|
162
|
+
type: "button",
|
|
163
|
+
variant: K === "drawn" ? "default" : "outline",
|
|
164
|
+
size: "sm",
|
|
165
|
+
onClick: () => q("drawn"),
|
|
166
|
+
children: [/* @__PURE__ */ y(r, { size: 14 }), " Draw"]
|
|
167
|
+
}), /* @__PURE__ */ b(c, {
|
|
168
|
+
type: "button",
|
|
169
|
+
variant: K === "typed" ? "default" : "outline",
|
|
170
|
+
size: "sm",
|
|
171
|
+
onClick: () => q("typed"),
|
|
172
|
+
children: [/* @__PURE__ */ y(a, { size: 14 }), " Type name instead"]
|
|
173
|
+
})]
|
|
174
|
+
}),
|
|
175
|
+
K === "drawn" ? /* @__PURE__ */ y(m, { ref: W }) : /* @__PURE__ */ y(u, {
|
|
176
|
+
value: J,
|
|
177
|
+
onChange: (e) => le(e.target.value),
|
|
178
|
+
placeholder: "Type full name as signature"
|
|
179
|
+
})
|
|
180
|
+
]
|
|
181
|
+
}),
|
|
182
|
+
/* @__PURE__ */ b("div", {
|
|
183
|
+
className: "space-y-1.5",
|
|
184
|
+
children: [
|
|
185
|
+
/* @__PURE__ */ y(d, {
|
|
186
|
+
htmlFor: "epod-photo",
|
|
187
|
+
children: "Delivery photo (optional)"
|
|
188
|
+
}),
|
|
189
|
+
/* @__PURE__ */ b("div", {
|
|
190
|
+
className: "flex items-center gap-2",
|
|
191
|
+
children: [/* @__PURE__ */ y("input", {
|
|
192
|
+
id: "epod-photo",
|
|
193
|
+
type: "file",
|
|
194
|
+
accept: "image/*",
|
|
195
|
+
capture: "environment",
|
|
196
|
+
onChange: (e) => ue(e.target.files?.[0] ?? null),
|
|
197
|
+
className: "text-sm"
|
|
198
|
+
}), Y && /* @__PURE__ */ y(o, {
|
|
199
|
+
size: 14,
|
|
200
|
+
className: "text-text-secondary"
|
|
201
|
+
})]
|
|
202
|
+
}),
|
|
203
|
+
Y && /* @__PURE__ */ y("p", {
|
|
204
|
+
className: "text-xs text-text-secondary",
|
|
205
|
+
children: Y.name
|
|
206
|
+
})
|
|
207
|
+
]
|
|
208
|
+
}),
|
|
209
|
+
/* @__PURE__ */ b("div", {
|
|
210
|
+
className: "space-y-1.5",
|
|
211
|
+
children: [/* @__PURE__ */ y(d, {
|
|
212
|
+
htmlFor: "epod-notes",
|
|
213
|
+
children: "Notes (optional)"
|
|
214
|
+
}), /* @__PURE__ */ y(f, {
|
|
215
|
+
id: "epod-notes",
|
|
216
|
+
value: X,
|
|
217
|
+
onChange: (e) => de(e.target.value),
|
|
218
|
+
placeholder: "e.g. Left with front desk, gate code used, etc.",
|
|
219
|
+
rows: 2
|
|
220
|
+
})]
|
|
221
|
+
}),
|
|
222
|
+
/* @__PURE__ */ b("p", {
|
|
223
|
+
className: "flex items-center gap-1.5 text-xs text-text-secondary",
|
|
224
|
+
children: [/* @__PURE__ */ y(n, { size: 12 }), " Device GPS is captured automatically when permitted by the browser."]
|
|
225
|
+
}),
|
|
226
|
+
T && /* @__PURE__ */ y("p", {
|
|
227
|
+
role: "alert",
|
|
228
|
+
className: "text-sm text-text-secondary",
|
|
229
|
+
children: "You are offline. Your entries stay on this screen; reconnect to confirm the delivery."
|
|
230
|
+
}),
|
|
231
|
+
Z && /* @__PURE__ */ y(p, { message: Z }),
|
|
232
|
+
O && /* @__PURE__ */ y(p, { message: O.message }),
|
|
233
|
+
U && /* @__PURE__ */ y(p, { message: U.message }),
|
|
234
|
+
/* @__PURE__ */ b("div", {
|
|
235
|
+
className: "flex gap-2 justify-end",
|
|
236
|
+
children: [/* @__PURE__ */ y(c, {
|
|
237
|
+
type: "button",
|
|
238
|
+
variant: "outline",
|
|
239
|
+
onClick: w,
|
|
240
|
+
disabled: $,
|
|
241
|
+
children: "Cancel"
|
|
242
|
+
}), /* @__PURE__ */ y(c, {
|
|
243
|
+
type: "button",
|
|
244
|
+
onClick: () => void fe(),
|
|
245
|
+
disabled: $ || T || j.loading || !!j.error || !j.data || A < z || !M || k?.kind === "UNKNOWN",
|
|
246
|
+
children: $ ? /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ y(t, {
|
|
247
|
+
size: 14,
|
|
248
|
+
className: "animate-spin"
|
|
249
|
+
}), " Submitting…"] }) : /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ y(e, { size: 14 }), " Confirm delivery"] })
|
|
250
|
+
})]
|
|
251
|
+
})
|
|
252
|
+
]
|
|
253
|
+
})] });
|
|
254
|
+
}
|
|
255
|
+
//#endregion
|
|
256
|
+
export { S as EpodCaptureForm };
|