@burdenoff/microfe-movethewheels 2026.1010.2 → 2026.1011.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.
Files changed (38) hide show
  1. package/dist/MoveTheWheelsRoot.js +12 -1
  2. package/dist/MoveTheWheelsRoutes.js +57 -49
  3. package/dist/generated/shipment-status-authority-operations.d.ts +4473 -0
  4. package/dist/generated/tracking-quality-operations.d.ts +4302 -0
  5. package/dist/hooks/useEpod.js +85 -77
  6. package/dist/hooks/useShipmentStatusAuthority.js +127 -0
  7. package/dist/hooks/useTracking.js +15 -14
  8. package/dist/hooks/useTrackingEventQuality.js +60 -0
  9. package/dist/movethewheels/hooks/useEpod.d.ts +23 -0
  10. package/dist/movethewheels/hooks/useShipmentStatusAuthority.d.ts +23 -0
  11. package/dist/movethewheels/hooks/useTrackingEventQuality.d.ts +18 -0
  12. package/dist/movethewheels/pages/ShipmentStatusAuthorityPage.d.ts +1 -0
  13. package/dist/movethewheels/pages/TrackingEventQualityPage.d.ts +1 -0
  14. package/dist/movethewheels/utils/shipmentStatusDraft.d.ts +45 -0
  15. package/dist/node_modules/lucide-react/dist/esm/icons/radio-tower.js +36 -0
  16. package/dist/pages/DeliveryCapturePage.js +181 -116
  17. package/dist/pages/ShipmentStatusAuthorityPage.js +563 -0
  18. package/dist/pages/TrackingEventQualityPage.js +224 -0
  19. package/dist/src/generated/shipment-status-authority-operations.js +86 -0
  20. package/dist/src/generated/tracking-quality-operations.js +44 -0
  21. package/dist/utils/shipmentStatusDraft.js +41 -0
  22. package/package.json +16 -7
  23. package/patches/README.md +25 -0
  24. package/patches/braces@3.0.3.patch +87 -0
  25. package/src/generated/shipment-status-authority-operations.ts +5503 -0
  26. package/src/generated/tracking-quality-operations.ts +5323 -0
  27. package/src/movethewheels/MoveTheWheelsRoot.tsx +14 -0
  28. package/src/movethewheels/MoveTheWheelsRoutes.tsx +4 -0
  29. package/src/movethewheels/hooks/useEpod.ts +47 -12
  30. package/src/movethewheels/hooks/useShipmentStatusAuthority.ts +179 -0
  31. package/src/movethewheels/hooks/useTracking.ts +27 -12
  32. package/src/movethewheels/hooks/useTrackingEventQuality.ts +110 -0
  33. package/src/movethewheels/pages/DeliveryCapturePage.tsx +113 -6
  34. package/src/movethewheels/pages/ShipmentStatusAuthorityPage.tsx +639 -0
  35. package/src/movethewheels/pages/TrackingEventQualityPage.tsx +250 -0
  36. package/src/movethewheels/utils/shipmentStatusDraft.ts +118 -0
  37. package/src/operations/shipment-status-authority/status.graphql +80 -0
  38. package/src/operations/tracking-quality/quality.graphql +15 -0
@@ -1,24 +1,26 @@
1
1
  import { useMoveTheWheels as e } from "../providers/MoveTheWheelsProvider.js";
2
2
  import { executeGraphQL as t } from "../utils/graphqlClient.js";
3
- import { useCallback as n, useEffect as r, useMemo as i, useState as a } from "react";
3
+ import { useShipmentStatusCommand as n } from "./useShipmentStatusAuthority.js";
4
+ import { useCallback as r, useEffect as i, useMemo as a, useState as o } from "react";
5
+ import { parse as s } from "graphql";
4
6
  //#region src/movethewheels/hooks/useEpod.ts
5
- var o = "\n id\n deliveryJobId\n shipmentId\n recipientName\n signatureType\n signatureData\n photoFileIds\n latitude\n longitude\n locationAccuracy\n deliveredAt\n capturedByDriverId\n notes\n", s = `
7
+ var c = "\n id\n deliveryJobId\n shipmentId\n recipientName\n signatureType\n signatureData\n photoFileIds\n latitude\n longitude\n locationAccuracy\n deliveredAt\n capturedByDriverId\n notes\n", l = `
6
8
  query GetEpod($deliveryJobId: ID!) {
7
9
  epod(deliveryJobId: $deliveryJobId) {
8
- ${o}
10
+ ${c}
9
11
  }
10
12
  }
11
- `, c = "\n query MyPendingEpodDeliveryJobs($pagination: PaginationInput) {\n myPendingEpodDeliveryJobs(pagination: $pagination) {\n id\n deliveryJobNumber\n status\n priority\n deliveryAddress\n scheduledDelivery\n customer {\n name\n phone\n }\n }\n myPendingEpodDeliveryJobsCount\n }\n", l = `
13
+ `, u = "\n query MyPendingEpodDeliveryJobs($pagination: PaginationInput) {\n myPendingEpodDeliveryJobs(pagination: $pagination) {\n id\n deliveryJobNumber\n status\n priority\n deliveryAddress\n scheduledDelivery\n customer {\n name\n phone\n }\n }\n myPendingEpodDeliveryJobsCount\n }\n", d = s(`
12
14
  mutation CaptureEpod($input: CaptureEpodInput!) {
13
15
  captureEpod(input: $input) {
14
- ${o}
16
+ ${c}
15
17
  }
16
18
  }
17
- `, u = "\n mutation EpodInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }\n", d = "\n mutation EpodCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n }\n }\n", f = "\n query EpodFileUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n", p = 21600;
18
- function m(e) {
19
+ `), f = "\n mutation EpodInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }\n", p = "\n mutation EpodCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n }\n }\n", m = "\n query EpodFileUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n", h = 21600;
20
+ function g(e) {
19
21
  return e === "typed" ? "TYPED" : "DRAWN";
20
22
  }
21
- function h(e) {
23
+ function _(e) {
22
24
  return {
23
25
  id: e.id,
24
26
  deliveryJobId: e.deliveryJobId,
@@ -35,58 +37,58 @@ function h(e) {
35
37
  notes: e.notes ?? void 0
36
38
  };
37
39
  }
38
- function g() {
39
- let { apiGatewayUrl: t, authToken: n, workspaceToken: r, workspaceId: a, tenantId: o, currentUser: s } = e();
40
- return i(() => ({
40
+ function v() {
41
+ let { apiGatewayUrl: t, authToken: n, workspaceToken: r, workspaceId: i, tenantId: o, currentUser: s } = e();
42
+ return a(() => ({
41
43
  apiGatewayUrl: t,
42
44
  authToken: n,
43
45
  workspaceToken: r,
44
- workspaceId: a,
46
+ workspaceId: i,
45
47
  tenantId: o,
46
48
  actorId: s?.id
47
49
  }), [
48
50
  t,
49
51
  n,
50
52
  r,
51
- a,
53
+ i,
52
54
  o,
53
55
  s?.id
54
56
  ]);
55
57
  }
56
- function _(e) {
57
- let i = g(), [o, c] = a(null), [l, u] = a(!1), [d, f] = a(null), p = n(async () => {
58
+ function y(e) {
59
+ let n = v(), [a, s] = o(null), [c, u] = o(!1), [d, f] = o(null), p = r(async () => {
58
60
  if (!e) {
59
- c(null);
61
+ s(null);
60
62
  return;
61
63
  }
62
64
  u(!0), f(null);
63
65
  try {
64
- let n = await t(i, s, { deliveryJobId: e });
65
- c(n.epod ? h(n.epod) : null);
66
+ let r = await t(n, l, { deliveryJobId: e });
67
+ s(r.epod ? _(r.epod) : null);
66
68
  } catch (e) {
67
- f(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load proof of delivery")), c(null);
69
+ f(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load proof of delivery")), s(null);
68
70
  } finally {
69
71
  u(!1);
70
72
  }
71
- }, [e, i]);
72
- return r(() => {
73
+ }, [e, n]);
74
+ return i(() => {
73
75
  p();
74
76
  }, [p]), {
75
- epod: o,
76
- isLoading: l,
77
+ epod: a,
78
+ isLoading: c,
77
79
  error: d,
78
80
  refetch: p
79
81
  };
80
82
  }
81
- function v(e = {}) {
82
- let { limit: i = 20, offset: o = 0 } = e, s = g(), [l, u] = a([]), [d, f] = a(0), [p, m] = a(!1), [h, _] = a(!1), [v, y] = a(null), b = n(async () => {
83
- _(!0), y(null);
83
+ function b(e = {}) {
84
+ let { limit: n = 20, offset: a = 0 } = e, s = v(), [c, l] = o([]), [d, f] = o(0), [p, m] = o(!1), [h, g] = o(!1), [_, y] = o(null), b = r(async () => {
85
+ g(!0), y(null);
84
86
  try {
85
- let e = await t(s, c, { pagination: {
86
- limit: i,
87
- offset: o
87
+ let e = await t(s, u, { pagination: {
88
+ limit: n,
89
+ offset: a
88
90
  } });
89
- f(e.myPendingEpodDeliveryJobsCount ?? 0), m(o + e.myPendingEpodDeliveryJobs.length < e.myPendingEpodDeliveryJobsCount), u(e.myPendingEpodDeliveryJobs.map((e) => ({
91
+ f(e.myPendingEpodDeliveryJobsCount ?? 0), m(a + e.myPendingEpodDeliveryJobs.length < e.myPendingEpodDeliveryJobsCount), l(e.myPendingEpodDeliveryJobs.map((e) => ({
90
92
  id: e.id,
91
93
  deliveryJobNumber: e.deliveryJobNumber,
92
94
  status: e.status,
@@ -97,61 +99,67 @@ function v(e = {}) {
97
99
  customerPhone: e.customer?.phone ?? void 0
98
100
  })));
99
101
  } catch (e) {
100
- y(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load pending deliveries")), u([]);
102
+ y(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load pending deliveries")), l([]);
101
103
  } finally {
102
- _(!1);
104
+ g(!1);
103
105
  }
104
106
  }, [
105
107
  s,
106
- i,
107
- o
108
+ n,
109
+ a
108
110
  ]);
109
- return r(() => {
111
+ return i(() => {
110
112
  b();
111
113
  }, [b]), {
112
- jobs: l,
114
+ jobs: c,
113
115
  totalJobs: d,
114
116
  hasMore: p,
115
117
  isLoading: h,
116
- error: v,
118
+ error: _,
117
119
  refetch: b
118
120
  };
119
121
  }
120
- function y() {
121
- let e = g(), [r, i] = a(!1), [o, s] = a(null);
122
+ function x(e, t) {
123
+ return !!e && typeof e.id == "string" && e.id.trim().length > 0 && e.deliveryJobId === t.deliveryJobId && e.shipmentId === t.expectedShipmentId && e.recipientName === t.recipientName && e.signatureType === g(t.signatureType) && e.signatureData === t.signatureData && typeof e.capturedByDriverId == "string" && e.capturedByDriverId.trim().length > 0 && typeof e.deliveredAt == "string" && Number.isFinite(Date.parse(e.deliveredAt)) && Array.isArray(e.photoFileIds) && e.photoFileIds.length === (t.photoFileIds ?? []).length && e.photoFileIds.every((e, n) => e === (t.photoFileIds ?? [])[n]) && e.latitude === (t.latitude ?? null) && e.longitude === (t.longitude ?? null) && e.locationAccuracy === (t.locationAccuracy ?? null) && e.notes === (t.notes ?? null);
124
+ }
125
+ function S() {
126
+ let e = n(), [t, i] = o(null);
122
127
  return {
123
- captureEpod: n(async (n) => {
124
- i(!0), s(null);
128
+ captureEpod: r(async (t) => {
129
+ i(null);
125
130
  try {
126
- return h((await t(e, l, { input: {
127
- deliveryJobId: n.deliveryJobId,
128
- recipientName: n.recipientName,
129
- signatureType: m(n.signatureType),
130
- signatureData: n.signatureData,
131
- photoFileIds: n.photoFileIds,
132
- latitude: n.latitude,
133
- longitude: n.longitude,
134
- locationAccuracy: n.locationAccuracy,
135
- notes: n.notes
136
- } })).captureEpod);
131
+ let n = await e.run(d, { input: {
132
+ expectedShipmentStatusRevision: t.expectedShipmentStatusRevision,
133
+ completionAttestation: t.completionAttestation,
134
+ deliveryJobId: t.deliveryJobId,
135
+ recipientName: t.recipientName,
136
+ signatureType: g(t.signatureType),
137
+ signatureData: t.signatureData,
138
+ photoFileIds: t.photoFileIds,
139
+ latitude: t.latitude,
140
+ longitude: t.longitude,
141
+ locationAccuracy: t.locationAccuracy,
142
+ notes: t.notes
143
+ } }, (e) => x(e.captureEpod, t));
144
+ if (!n) throw Error("Capture was not acknowledged. Review the recorded status and the capture message before taking further action.");
145
+ return _(n.captureEpod);
137
146
  } catch (e) {
138
147
  let t = e instanceof Error ? e : /* @__PURE__ */ Error("Failed to capture proof of delivery");
139
- throw s(t), t;
140
- } finally {
141
- i(!1);
148
+ throw i(t), t;
142
149
  }
143
150
  }, [e]),
144
- isSubmitting: r,
145
- error: o
151
+ isSubmitting: e.busy,
152
+ error: t,
153
+ captureFeedback: e.feedback
146
154
  };
147
155
  }
148
- function b() {
149
- let e = g(), [r, i] = a(!1), [o, s] = a(0), [c, l] = a(null);
156
+ function C() {
157
+ let e = v(), [n, i] = o(!1), [a, s] = o(0), [c, l] = o(null);
150
158
  return {
151
- upload: n(async (n) => {
159
+ upload: r(async (n) => {
152
160
  i(!0), s(0), l(null);
153
161
  try {
154
- let r = n.name.lastIndexOf("."), i = r > -1 ? n.name.slice(r + 1) : "", a = n.type || "application/octet-stream", o = await t(e, u, { input: {
162
+ let r = n.name.lastIndexOf("."), i = r > -1 ? n.name.slice(r + 1) : "", a = n.type || "application/octet-stream", o = await t(e, f, { input: {
155
163
  fileName: n.name,
156
164
  extension: i,
157
165
  mimeType: a,
@@ -160,18 +168,18 @@ function b() {
160
168
  } }), { uploadUrl: c } = o.initiateUpload, l = o.initiateUpload.session.id;
161
169
  if (!c) throw Error("The file service did not return an upload URL.");
162
170
  s(50);
163
- let f = await fetch(c, {
171
+ let u = await fetch(c, {
164
172
  method: "PUT",
165
173
  headers: { "Content-Type": a },
166
174
  body: n
167
175
  });
168
- if (!f.ok) throw Error(`File storage rejected the upload (HTTP ${f.status}).`);
169
- let p = await t(e, d, { input: {
176
+ if (!u.ok) throw Error(`File storage rejected the upload (HTTP ${u.status}).`);
177
+ let d = await t(e, p, { input: {
170
178
  sessionId: l,
171
179
  fileSize: String(n.size)
172
180
  } });
173
181
  return s(100), {
174
- fileId: p.completeUpload.fileId,
182
+ fileId: d.completeUpload.fileId,
175
183
  fileName: n.name
176
184
  };
177
185
  } catch (e) {
@@ -181,35 +189,35 @@ function b() {
181
189
  i(!1);
182
190
  }
183
191
  }, [e]),
184
- isUploading: r,
185
- progress: o,
192
+ isUploading: n,
193
+ progress: a,
186
194
  error: c
187
195
  };
188
196
  }
189
- function x(e) {
190
- let n = g(), [i, o] = a(null), [s, c] = a(!1);
191
- return r(() => {
197
+ function w(e) {
198
+ let n = v(), [r, a] = o(null), [s, c] = o(!1);
199
+ return i(() => {
192
200
  if (!e) {
193
- o(null);
201
+ a(null);
194
202
  return;
195
203
  }
196
204
  let r = !1;
197
- return c(!0), t(n, f, {
205
+ return c(!0), t(n, m, {
198
206
  id: e,
199
- expiresIn: p
207
+ expiresIn: h
200
208
  }).then((e) => {
201
- r || o(e.getFileDownloadUrl ?? null);
209
+ r || a(e.getFileDownloadUrl ?? null);
202
210
  }).catch(() => {
203
- r || o(null);
211
+ r || a(null);
204
212
  }).finally(() => {
205
213
  r || c(!1);
206
214
  }), () => {
207
215
  r = !0;
208
216
  };
209
217
  }, [e, n]), {
210
- url: i,
218
+ url: r,
211
219
  isLoading: s
212
220
  };
213
221
  }
214
222
  //#endregion
215
- export { y as useCaptureEpod, _ as useEpod, b as useEpodPhotoUpload, x as useEpodPhotoUrl, v as useMyPendingEpodDeliveryJobs };
223
+ export { S as useCaptureEpod, y as useEpod, C as useEpodPhotoUpload, w as useEpodPhotoUrl, b as useMyPendingEpodDeliveryJobs };
@@ -0,0 +1,127 @@
1
+ import { useMoveTheWheels as e } from "../providers/MoveTheWheelsProvider.js";
2
+ import { useCallback as t, useEffect as n, useMemo as r, useRef as i, useState as a } from "react";
3
+ import { print as o } from "graphql";
4
+ import { clearGraphqlFetchResponseCache as s, graphqlFetch as c } from "@burdenoff/fe-libs/shared/graphql";
5
+ //#region src/movethewheels/hooks/useShipmentStatusAuthority.ts
6
+ var l = new Set([
7
+ "STATUS_REVISION_CONFLICT",
8
+ "BAD_USER_INPUT",
9
+ "FORBIDDEN",
10
+ "UNAUTHENTICATED",
11
+ "NOT_FOUND"
12
+ ]), u = class extends Error {
13
+ code;
14
+ constructor(e, t) {
15
+ super(e), this.code = t, this.name = "ShipmentStatusRequestError";
16
+ }
17
+ };
18
+ function d() {
19
+ let { apiGatewayUrl: n, authToken: i, workspaceToken: a, workspaceId: s, tenantId: l } = e(), d = r(() => ({
20
+ apiGatewayUrl: n,
21
+ authToken: i,
22
+ workspaceToken: a,
23
+ workspaceId: s,
24
+ tenantId: l
25
+ }), [
26
+ n,
27
+ i,
28
+ a,
29
+ s,
30
+ l
31
+ ]);
32
+ return t(async (e, t, n = !1, r) => {
33
+ let i = await c({
34
+ gateway: "workspace",
35
+ query: o(e),
36
+ variables: t,
37
+ baseUrl: d.apiGatewayUrl,
38
+ authToken: d.authToken,
39
+ workspaceToken: d.workspaceToken || !0,
40
+ workspaceId: d.workspaceId || !0,
41
+ tenantId: d.tenantId || !0,
42
+ organizationId: !0,
43
+ signal: r,
44
+ skipAuthRetry: n
45
+ });
46
+ if (i.errors?.length) {
47
+ let e = i.errors[0], t = i.data === null && i.errors.length === 1 && typeof e?.extensions?.code == "string" ? e.extensions.code : null;
48
+ throw new u(e?.message ?? "Unable to load the recorded status.", t);
49
+ }
50
+ if (i.data == null) throw new u("No acknowledgement was received.", null);
51
+ return i.data;
52
+ }, [d]);
53
+ }
54
+ function f(e, t, r = 0) {
55
+ let i = d(), o = JSON.stringify(t), [c, l] = a(null);
56
+ n(() => {
57
+ let t = new AbortController(), n = {
58
+ request: i,
59
+ key: o,
60
+ revision: r
61
+ };
62
+ if (l({
63
+ ...n,
64
+ data: null,
65
+ error: null,
66
+ loading: o !== "null"
67
+ }), o !== "null") return r > 0 && s(), i(e, JSON.parse(o), !1, t.signal).then((e) => {
68
+ t.signal.aborted || l({
69
+ ...n,
70
+ data: e,
71
+ error: null,
72
+ loading: !1
73
+ });
74
+ }).catch((e) => {
75
+ t.signal.aborted || l({
76
+ ...n,
77
+ data: null,
78
+ error: e instanceof Error ? e.message : "Unable to load recorded status.",
79
+ loading: !1
80
+ });
81
+ }), () => t.abort();
82
+ }, [
83
+ e,
84
+ i,
85
+ o,
86
+ r
87
+ ]);
88
+ let u = c?.request === i && c.key === o && c.revision === r;
89
+ return {
90
+ data: u ? c.data : null,
91
+ error: u ? c.error : null,
92
+ loading: u ? c.loading : o !== "null"
93
+ };
94
+ }
95
+ function p() {
96
+ let e = d(), t = i(!1), n = i(!1), [r, o] = a(!1), [s, c] = a(null), [f, p] = a(0);
97
+ return {
98
+ run: async (r, i, a) => {
99
+ if (t.current || n.current) return null;
100
+ t.current = !0, o(!0), c(null);
101
+ try {
102
+ let t = await e(r, i, !0);
103
+ if (!a(t)) throw new u("The returned acknowledgement does not identify this decision.", null);
104
+ return c({
105
+ kind: "APPLIED",
106
+ message: "Decision recorded. Review the refreshed status and history."
107
+ }), p((e) => e + 1), t;
108
+ } catch (e) {
109
+ let t = e instanceof u && e.code !== null && l.has(e.code);
110
+ return n.current = !t, c({
111
+ kind: t ? "REJECTED" : "UNKNOWN",
112
+ message: t ? `${e.message} Your input is preserved; refresh and review the recorded status before another action.` : "Acknowledgement is uncertain. Do not resend this action. Refresh the recorded status and review its decisions before beginning a separate new action."
113
+ }), null;
114
+ } finally {
115
+ t.current = !1, o(!1);
116
+ }
117
+ },
118
+ busy: r,
119
+ feedback: s,
120
+ revision: f,
121
+ beginSeparateAction: () => {
122
+ n.current = !1, c(null);
123
+ }
124
+ };
125
+ }
126
+ //#endregion
127
+ export { p as useShipmentStatusCommand, f as useShipmentStatusQuery };
@@ -4,7 +4,7 @@ import { mapOrder as n, useOrder as r } from "./useOrders.js";
4
4
  import { mapDriver as i, mapVehicle as a, useDriver as o, useDrivers as s, useVehicle as c, useVehicles as l } from "./useFleet.js";
5
5
  import { useCallback as u, useEffect as d, useMemo as f, useState as p } from "react";
6
6
  //#region src/movethewheels/hooks/useTracking.ts
7
- var m = "\n query ListShipments($filter: ShipmentFilterInput, $pagination: PaginationInput) {\n shipments(filter: $filter, pagination: $pagination) {\n id\n shipmentNumber\n deliveryJobId\n status\n trackingNumber\n estimatedDelivery\n }\n }\n", h = "\n query LookupDeliveryJob($id: ID!) {\n deliveryJob(id: $id) {\n id\n }\n }\n", g = "\n query LookupDeliveryJobs($filter: DeliveryJobFilterInput, $pagination: PaginationInput) {\n deliveryJobs(filter: $filter, pagination: $pagination) {\n id\n deliveryJobNumber\n trackingNumber\n }\n }\n", _ = "\n query GetDeliveryJobTracking($deliveryJobId: ID!, $pagination: PaginationInput) {\n deliveryJobTracking(deliveryJobId: $deliveryJobId, pagination: $pagination) {\n id\n shipmentId\n eventType\n location\n details\n timestamp\n }\n }\n", v = "\n query GetActiveDeliveries($pagination: PaginationInput) {\n activeDeliveries(pagination: $pagination) {\n id\n shipmentNumber\n deliveryJobId\n status\n estimatedDelivery\n trackingEvents(pagination: { limit: 1, offset: 0 }) {\n id\n shipmentId\n eventType\n location\n details\n timestamp\n }\n deliveryJob {\n id\n deliveryJobNumber\n customerId\n status\n priority\n pickupAddress\n deliveryAddress\n cargoItems\n pricing\n trackingNumber\n specialInstructions\n scheduledDelivery\n vehicleId\n driverId\n createdAt\n updatedAt\n customer {\n name\n email\n phone\n company\n }\n vehicle {\n id\n vehicleNumber\n type\n make\n model\n licensePlate\n ownershipType\n year\n capacity\n status\n currentLocation\n fuelLevel\n mileage\n lastServiceDate\n nextServiceDueDate\n nextServiceDueMileage\n createdAt\n }\n driver {\n id\n userId\n firstName\n lastName\n email\n phone\n employeeId\n licenseNumber\n licenseClass\n licenseExpiry\n status\n currentLocation\n rating\n vehicleId\n createdAt\n }\n }\n }\n }\n", y = "\n query GetTrackingAlerts {\n trackingAlerts {\n shipmentId\n shipmentNumber\n alertType\n message\n }\n }\n";
7
+ var m = "\n query ListShipments($filter: ShipmentFilterInput, $pagination: PaginationInput) {\n shipments(filter: $filter, pagination: $pagination) {\n id\n shipmentNumber\n deliveryJobId\n status\n trackingNumber\n estimatedDelivery\n }\n }\n", h = "\n query LookupDeliveryJob($id: ID!) {\n deliveryJob(id: $id) {\n id\n }\n }\n", g = "\n query LookupDeliveryJobs($filter: DeliveryJobFilterInput, $pagination: PaginationInput) {\n deliveryJobs(filter: $filter, pagination: $pagination) {\n id\n deliveryJobNumber\n trackingNumber\n }\n }\n", _ = "\n query GetDeliveryJobTracking($deliveryJobId: ID!, $pagination: PaginationInput) {\n shipments(filter: { deliveryJobId: $deliveryJobId }, pagination: { limit: 2, offset: 0 }) {\n id\n status\n }\n deliveryJobTracking(deliveryJobId: $deliveryJobId, pagination: $pagination) {\n id\n shipmentId\n eventType\n location\n details\n timestamp\n }\n }\n", v = "\n query GetActiveDeliveries($pagination: PaginationInput) {\n activeDeliveries(pagination: $pagination) {\n id\n shipmentNumber\n deliveryJobId\n status\n estimatedDelivery\n trackingEvents(pagination: { limit: 1, offset: 0 }) {\n id\n shipmentId\n eventType\n location\n details\n timestamp\n }\n deliveryJob {\n id\n deliveryJobNumber\n customerId\n status\n priority\n pickupAddress\n deliveryAddress\n cargoItems\n pricing\n trackingNumber\n specialInstructions\n scheduledDelivery\n vehicleId\n driverId\n createdAt\n updatedAt\n customer {\n name\n email\n phone\n company\n }\n vehicle {\n id\n vehicleNumber\n type\n make\n model\n licensePlate\n ownershipType\n year\n capacity\n status\n currentLocation\n fuelLevel\n mileage\n lastServiceDate\n nextServiceDueDate\n nextServiceDueMileage\n createdAt\n }\n driver {\n id\n userId\n firstName\n lastName\n email\n phone\n employeeId\n licenseNumber\n licenseClass\n licenseExpiry\n status\n currentLocation\n rating\n vehicleId\n createdAt\n }\n }\n }\n }\n", y = "\n query GetTrackingAlerts {\n trackingAlerts {\n shipmentId\n shipmentNumber\n alertType\n message\n }\n }\n";
8
8
  function b(e) {
9
9
  let t = e.location;
10
10
  if (!t) return null;
@@ -16,21 +16,21 @@ function b(e) {
16
16
  timestamp: new Date(e.timestamp)
17
17
  };
18
18
  }
19
- function x(e, t) {
20
- let n = e[0];
21
- if (!n) return null;
22
- let r = e.map(b).filter((e) => e !== null), i = r[0];
19
+ function x(e, t, n) {
20
+ let r = e[0];
21
+ if (!r) return null;
22
+ let i = e.map(b).filter((e) => e !== null), a = i[0];
23
23
  return {
24
- id: n.id,
24
+ id: r.id,
25
25
  entityId: t,
26
26
  entityType: "order",
27
- currentLocation: i,
28
- locationHistory: r,
29
- status: n.eventType.toLowerCase(),
27
+ currentLocation: a,
28
+ locationHistory: i,
29
+ status: n?.toLowerCase() ?? "unknown",
30
30
  estimatedArrival: void 0,
31
- nextCheckpoint: n.details ?? void 0,
31
+ nextCheckpoint: r.details ?? void 0,
32
32
  alerts: [],
33
- lastUpdated: new Date(n.timestamp)
33
+ lastUpdated: new Date(r.timestamp)
34
34
  };
35
35
  }
36
36
  function S() {
@@ -161,13 +161,14 @@ function D(e) {
161
161
  }
162
162
  D(!0), k(null);
163
163
  try {
164
- C(x([...(await t(n, _, {
164
+ let e = await t(n, _, {
165
165
  deliveryJobId: i,
166
166
  pagination: {
167
167
  limit: 50,
168
168
  offset: 0
169
169
  }
170
- })).deliveryJobTracking].sort((e, t) => Date.parse(t.timestamp) - Date.parse(e.timestamp)), i));
170
+ });
171
+ C(x([...e.deliveryJobTracking].sort((e, t) => Date.parse(t.timestamp) - Date.parse(e.timestamp)), i, e.shipments.length === 1 ? e.shipments[0]?.status : void 0));
171
172
  } catch (e) {
172
173
  k(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load order tracking"));
173
174
  } finally {
@@ -237,7 +238,7 @@ function A() {
237
238
  order: n(t),
238
239
  driver: t.driver ? i(t.driver) : null,
239
240
  vehicle: t.vehicle ? a(t.vehicle) : null,
240
- tracking: x(e.trackingEvents ?? [], t.id),
241
+ tracking: x(e.trackingEvents ?? [], t.id, e.status),
241
242
  estimatedArrival: e.estimatedDelivery ? new Date(e.estimatedDelivery) : void 0
242
243
  } : null;
243
244
  }).filter((e) => e !== null));
@@ -0,0 +1,60 @@
1
+ import "../src/generated/tracking-quality-operations.js";
2
+ //#region src/movethewheels/hooks/useTrackingEventQuality.ts
3
+ var e = new Set([
4
+ "ACCEPTED",
5
+ "DUPLICATE",
6
+ "CONFLICT",
7
+ "REJECTED"
8
+ ]), t = new Set([
9
+ "LEGACY_AUTHORITY",
10
+ "MANUAL_AUTHORITY",
11
+ "NON_DESIGNATED_SOURCE",
12
+ "UNKNOWN_SOURCE_TIME",
13
+ "OLDER_SOURCE_TIME",
14
+ "EQUAL_SOURCE_TIME",
15
+ "SOURCE_TIME_TOO_OLD",
16
+ "SOURCE_TIME_IN_FUTURE",
17
+ "UNMAPPED_EVENT_TYPE",
18
+ "UNRECEIPTED_EVIDENCE"
19
+ ]), n = new Set([
20
+ "KEY_CONFLICT",
21
+ "BUDGET_EXHAUSTED",
22
+ "INTEGRATION_UNAVAILABLE",
23
+ "SHIPMENT_UNAVAILABLE",
24
+ "UPDATE_REJECTED"
25
+ ]), r = (e, t) => typeof e == "string" && e.length <= t, i = (e, t) => e === null || r(e, t);
26
+ function a(a) {
27
+ if (!Array.isArray(a) || a.length > 5) return null;
28
+ let o = [];
29
+ for (let s of a) {
30
+ if (typeof s != "object" || !s || Array.isArray(s)) return null;
31
+ let a = s;
32
+ if (!Number.isInteger(a.index) || typeof a.index != "number" || a.index !== o.length || a.index < 0 || a.index > 4 || !i(a.externalEventId, 255) || !r(a.shipmentReference, 255) || !i(a.shipmentId, 255) || typeof a.status != "string" || !e.has(a.status) || a.status === "CONFLICT" && a.shipmentId !== null || !(a.errorCode === null || typeof a.errorCode == "string" && n.has(a.errorCode))) return null;
33
+ let c = null, l = a.projectionStatus, u = a.projectionDecisionId ?? null, d = a.projectionHeldReason ?? null;
34
+ if (l != null) {
35
+ if (a.status !== "ACCEPTED" && a.status !== "DUPLICATE") return null;
36
+ if (l === "LEGACY_NO_DECISION") {
37
+ if (a.status !== "DUPLICATE" || u !== null || d !== null) return null;
38
+ } else if (l === "APPLIED" || l === "HELD") {
39
+ if (!r(u, 255) || !u || (l === "APPLIED" ? d !== null : typeof d != "string" || !t.has(d))) return null;
40
+ } else return null;
41
+ c = {
42
+ status: l,
43
+ decisionId: u,
44
+ heldReason: d
45
+ };
46
+ } else if (u !== null || d !== null) return null;
47
+ o.push({
48
+ index: a.index,
49
+ externalEventId: a.externalEventId,
50
+ shipmentReference: a.shipmentReference,
51
+ shipmentId: a.shipmentId,
52
+ status: a.status,
53
+ errorCode: a.errorCode,
54
+ projection: c
55
+ });
56
+ }
57
+ return o;
58
+ }
59
+ //#endregion
60
+ export { a as trackingOutcomes };
@@ -1,5 +1,20 @@
1
1
  import { Order, ProofOfDelivery, SignatureType } from '../types';
2
2
 
3
+ export interface ApiProofOfDelivery {
4
+ id: string;
5
+ deliveryJobId: string;
6
+ shipmentId?: string | null;
7
+ recipientName: string;
8
+ signatureType: 'DRAWN' | 'TYPED';
9
+ signatureData: string;
10
+ photoFileIds?: string[] | null;
11
+ latitude?: number | null;
12
+ longitude?: number | null;
13
+ locationAccuracy?: number | null;
14
+ deliveredAt: string;
15
+ capturedByDriverId: string;
16
+ notes?: string | null;
17
+ }
3
18
  /** The shipper/customer-facing view: the completed ePOD record for a delivery job (or null if not yet captured). */
4
19
  export declare function useEpod(deliveryJobId: string | undefined): {
5
20
  epod: ProofOfDelivery | null;
@@ -30,6 +45,9 @@ export declare function useMyPendingEpodDeliveryJobs(options?: {
30
45
  refetch: () => Promise<void>;
31
46
  };
32
47
  export interface CaptureEpodArgs {
48
+ expectedShipmentId: string | null;
49
+ expectedShipmentStatusRevision?: number;
50
+ completionAttestation: boolean;
33
51
  deliveryJobId: string;
34
52
  recipientName: string;
35
53
  signatureType: SignatureType;
@@ -40,11 +58,16 @@ export interface CaptureEpodArgs {
40
58
  locationAccuracy?: number;
41
59
  notes?: string;
42
60
  }
61
+ export declare function epodAcknowledged(actual: ApiProofOfDelivery | null | undefined, expected: CaptureEpodArgs): boolean;
43
62
  /** Driver-facing capture mutation. Identity/ownership is enforced server-side — this never sends a driver id. */
44
63
  export declare function useCaptureEpod(): {
45
64
  captureEpod: (args: CaptureEpodArgs) => Promise<ProofOfDelivery>;
46
65
  isSubmitting: boolean;
47
66
  error: Error | null;
67
+ captureFeedback: {
68
+ kind: "APPLIED" | "REJECTED" | "UNKNOWN";
69
+ message: string;
70
+ } | null;
48
71
  };
49
72
  export interface UploadedEpodPhoto {
50
73
  fileId: string;
@@ -0,0 +1,23 @@
1
+ import { DocumentNode } from 'graphql';
2
+
3
+ export declare class ShipmentStatusRequestError extends Error {
4
+ readonly code: string | null;
5
+ constructor(message: string, code: string | null);
6
+ }
7
+ /** Normal shared gateway transport; mutation acknowledgements are never automatically retried. */
8
+ export declare function useShipmentStatusApi(): <T>(document: DocumentNode, variables: Record<string, unknown>, mutation?: boolean, signal?: AbortSignal) => Promise<T>;
9
+ export declare function useShipmentStatusQuery<T>(document: DocumentNode, variables: Record<string, unknown> | null, revision?: number): {
10
+ data: T | null;
11
+ error: string | null;
12
+ loading: boolean;
13
+ };
14
+ export declare function useShipmentStatusCommand(): {
15
+ run: <T>(document: DocumentNode, variables: Record<string, unknown>, acknowledged: (result: T) => boolean) => Promise<T | null>;
16
+ busy: boolean;
17
+ feedback: {
18
+ kind: "APPLIED" | "REJECTED" | "UNKNOWN";
19
+ message: string;
20
+ } | null;
21
+ revision: number;
22
+ beginSeparateAction: () => void;
23
+ };
@@ -0,0 +1,18 @@
1
+ import { TrackingQualityIntegrationsDocument, TrackingQualityDeliveriesDocument, TrackingQualityShipmentDocument } from '../../generated/tracking-quality-operations';
2
+
3
+ export { TrackingQualityIntegrationsDocument as QualityIntegrationsDocument, TrackingQualityDeliveriesDocument as QualityDeliveriesDocument, TrackingQualityShipmentDocument as QualityShipmentDocument, };
4
+ export interface TrackingUpdateOutcome {
5
+ index: number;
6
+ externalEventId: string | null;
7
+ shipmentReference: string;
8
+ shipmentId: string | null;
9
+ status: 'ACCEPTED' | 'DUPLICATE' | 'CONFLICT' | 'REJECTED';
10
+ errorCode: string | null;
11
+ projection: {
12
+ status: 'APPLIED' | 'HELD' | 'LEGACY_NO_DECISION';
13
+ decisionId: string | null;
14
+ heldReason: string | null;
15
+ } | null;
16
+ }
17
+ /** JSON scalar decoding fails closed; legacy delivery history has no outcomes. */
18
+ export declare function trackingOutcomes(value: unknown): TrackingUpdateOutcome[] | null;
@@ -0,0 +1 @@
1
+ export default function ShipmentStatusAuthorityPage(): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ export default function TrackingEventQualityPage(): import("react").JSX.Element;