@burdenoff/microfe-movethewheels 2026.1101.4 → 2026.1102.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 (47) hide show
  1. package/dist/components/CustomerDeliveryUpdatesFields.js +57 -0
  2. package/dist/components/CustomerNotificationSettingsCard.js +368 -0
  3. package/dist/components/freight-cost/FreightCommercialFactEditor.js +46 -46
  4. package/dist/components/freight-cost/FreightCommercialHistory.js +7 -7
  5. package/dist/components/freight-cost/FreightDraftForm.js +20 -20
  6. package/dist/components/freight-invoice/InvoiceReviewPanel.js +255 -0
  7. package/dist/components/freight-invoice/InvoiceReviewQueue.js +93 -0
  8. package/dist/generated/freight-invoice-operations.d.ts +461 -0
  9. package/dist/generated/tracking-quality-operations.d.ts +275 -0
  10. package/dist/hooks/useCustomers.js +9 -3
  11. package/dist/hooks/useInvoiceComparisonRecovery.js +26 -26
  12. package/dist/hooks/useInvoiceReviewPermissions.js +14 -0
  13. package/dist/movethewheels/components/CustomerDeliveryUpdatesFields.d.ts +12 -0
  14. package/dist/movethewheels/components/CustomerNotificationSettingsCard.d.ts +3 -0
  15. package/dist/movethewheels/components/freight-invoice/InvoiceReviewPanel.d.ts +11 -0
  16. package/dist/movethewheels/components/freight-invoice/InvoiceReviewQueue.d.ts +22 -0
  17. package/dist/movethewheels/hooks/useInvoiceReviewPermissions.d.ts +5 -0
  18. package/dist/movethewheels/pages/FinancePage.d.ts +3 -1
  19. package/dist/movethewheels/types/index.d.ts +4 -0
  20. package/dist/movethewheels/utils/customerNotifications.d.ts +66 -0
  21. package/dist/movethewheels/utils/invoiceReview.d.ts +26 -0
  22. package/dist/node_modules/lucide-react/dist/esm/icons/bell-ring.js +22 -0
  23. package/dist/pages/CustomerDetailsPage.js +279 -231
  24. package/dist/pages/FinancePage.js +109 -67
  25. package/dist/pages/FreightEstimatePage.js +89 -89
  26. package/dist/pages/FreightInvoicePage.js +138 -120
  27. package/dist/pages/SettingsPage.js +242 -238
  28. package/dist/src/generated/freight-invoice-operations.js +2100 -1
  29. package/dist/utils/customerNotifications.js +83 -0
  30. package/dist/utils/invoiceReview.js +84 -0
  31. package/package.json +4 -3
  32. package/src/generated/freight-invoice-operations.ts +245 -1
  33. package/src/generated/tracking-quality-operations.ts +304 -0
  34. package/src/movethewheels/components/CustomerDeliveryUpdatesFields.tsx +67 -0
  35. package/src/movethewheels/components/CustomerNotificationSettingsCard.tsx +465 -0
  36. package/src/movethewheels/components/freight-invoice/InvoiceReviewPanel.tsx +319 -0
  37. package/src/movethewheels/components/freight-invoice/InvoiceReviewQueue.tsx +96 -0
  38. package/src/movethewheels/hooks/useCustomers.ts +17 -0
  39. package/src/movethewheels/hooks/useInvoiceReviewPermissions.ts +25 -0
  40. package/src/movethewheels/pages/CustomerDetailsPage.tsx +39 -0
  41. package/src/movethewheels/pages/FinancePage.tsx +34 -2
  42. package/src/movethewheels/pages/FreightInvoicePage.tsx +44 -3
  43. package/src/movethewheels/pages/SettingsPage.tsx +221 -208
  44. package/src/movethewheels/types/index.ts +4 -0
  45. package/src/movethewheels/utils/customerNotifications.ts +209 -0
  46. package/src/movethewheels/utils/invoiceReview.ts +146 -0
  47. package/src/operations/freight-invoice/review.graphql +26 -0
@@ -1,8 +1,8 @@
1
1
  import { Button as e } from "../ui.js";
2
2
  import { ContainerEvidencePicker as t } from "../ContainerEvidencePicker.js";
3
- import { commercialCanonical as n, commercialCaptureInput as r } from "../../utils/freightCommercial.js";
4
- import { FreightCurrency as i, FreightSelect as a, FreightText as o } from "./FreightFields.js";
5
- import { freightInstant as s, freightLocalTime as c, newFreightFacts as l, newFreightLine as u } from "../../utils/freightDraft.js";
3
+ import { FreightCurrency as n, FreightSelect as r, FreightText as i } from "./FreightFields.js";
4
+ import { freightInstant as a, freightLocalTime as o, newFreightFacts as s, newFreightLine as c } from "../../utils/freightDraft.js";
5
+ import { commercialCanonical as l, commercialCaptureInput as u } from "../../utils/freightCommercial.js";
6
6
  import { FreightCommercialEditor as d } from "./FreightCommercialEditor.js";
7
7
  import { FreightLineEditor as f } from "./FreightLineEditor.js";
8
8
  import { FreightScopeEditor as p } from "./FreightScopeEditor.js";
@@ -12,7 +12,7 @@ import { useRef as g, useState as _ } from "react";
12
12
  import { jsx as v, jsxs as y } from "react/jsx-runtime";
13
13
  //#region src/movethewheels/components/freight-cost/FreightDraftForm.tsx
14
14
  function b({ disabled: b, shipmentId: x, onPreview: S, onSave: C }) {
15
- let [w, T] = _(null), [E, D] = _(l), [O, k] = _([]), [A, j] = _(null), [M, N] = _(null), [P, F] = _(!1), I = g(!1), L = JSON.stringify(E), R = A?.body === L ? A.value : null, z = (e) => D({
15
+ let [w, T] = _(null), [E, D] = _(s), [O, k] = _([]), [A, j] = _(null), [M, N] = _(null), [P, F] = _(!1), I = g(!1), L = JSON.stringify(E), R = A?.body === L ? A.value : null, z = (e) => D({
16
16
  ...E,
17
17
  ...e
18
18
  }), B = async () => {
@@ -40,8 +40,8 @@ function b({ disabled: b, shipmentId: x, onPreview: S, onSave: C }) {
40
40
  }
41
41
  N(null);
42
42
  try {
43
- if (w && w.reviewed !== n(w.selectedLegs)) throw Error("Explicitly review the commercial leg selection before saving.");
44
- let e = w ? r(w.facts, w.selectedLegs, O) : void 0;
43
+ if (w && w.reviewed !== l(w.selectedLegs)) throw Error("Explicitly review the commercial leg selection before saving.");
44
+ let e = w ? u(w.facts, w.selectedLegs, O) : void 0;
45
45
  C(structuredClone(E), structuredClone(O), e).catch((e) => N(e instanceof Error ? e.message : "Unable to save this cost record."));
46
46
  } catch (e) {
47
47
  N(e instanceof Error ? e.message : "Review commercial facts before saving.");
@@ -59,13 +59,13 @@ function b({ disabled: b, shipmentId: x, onPreview: S, onSave: C }) {
59
59
  /* @__PURE__ */ y("div", {
60
60
  className: "grid gap-3 md:grid-cols-2",
61
61
  children: [
62
- /* @__PURE__ */ v(o, {
62
+ /* @__PURE__ */ v(i, {
63
63
  label: "Estimate title",
64
64
  value: E.title,
65
65
  required: !0,
66
66
  onChange: (e) => z({ title: e })
67
67
  }),
68
- /* @__PURE__ */ y(a, {
68
+ /* @__PURE__ */ y(r, {
69
69
  label: "Record type",
70
70
  value: E.kind,
71
71
  onChange: (e) => {
@@ -79,13 +79,13 @@ function b({ disabled: b, shipmentId: x, onPreview: S, onSave: C }) {
79
79
  children: "Reported quote"
80
80
  })]
81
81
  }),
82
- /* @__PURE__ */ v(o, {
82
+ /* @__PURE__ */ v(i, {
83
83
  label: "Commercial source",
84
84
  value: E.sourceReference,
85
85
  required: !0,
86
86
  onChange: (e) => z({ sourceReference: e })
87
87
  }),
88
- /* @__PURE__ */ v(o, {
88
+ /* @__PURE__ */ v(i, {
89
89
  label: "Source version",
90
90
  value: E.sourceRevision,
91
91
  required: !0,
@@ -93,7 +93,7 @@ function b({ disabled: b, shipmentId: x, onPreview: S, onSave: C }) {
93
93
  })
94
94
  ]
95
95
  }),
96
- /* @__PURE__ */ v(o, {
96
+ /* @__PURE__ */ v(i, {
97
97
  label: "Shipment and services covered by this source",
98
98
  value: E.commercialScope,
99
99
  required: !0,
@@ -107,13 +107,13 @@ function b({ disabled: b, shipmentId: x, onPreview: S, onSave: C }) {
107
107
  ". They are recorded as exact UTC instants."
108
108
  ]
109
109
  }),
110
- /* @__PURE__ */ v(o, {
110
+ /* @__PURE__ */ v(i, {
111
111
  label: "Price applies at",
112
112
  type: "datetime-local",
113
- value: c(E.pricingAt),
113
+ value: o(E.pricingAt),
114
114
  required: !0,
115
115
  onChange: (e) => {
116
- e && z({ pricingAt: s(e) });
116
+ e && z({ pricingAt: a(e) });
117
117
  }
118
118
  }),
119
119
  /* @__PURE__ */ y("section", {
@@ -137,7 +137,7 @@ function b({ disabled: b, shipmentId: x, onPreview: S, onSave: C }) {
137
137
  type: "button",
138
138
  variant: "outline",
139
139
  disabled: E.lines.length >= 100,
140
- onClick: () => z({ lines: [...E.lines, u()] }),
140
+ onClick: () => z({ lines: [...E.lines, c()] }),
141
141
  children: "Add cost item"
142
142
  })
143
143
  ]
@@ -162,14 +162,14 @@ function b({ disabled: b, shipmentId: x, onPreview: S, onSave: C }) {
162
162
  "quotedAt",
163
163
  "validFrom",
164
164
  "validUntil"
165
- ].map((e) => /* @__PURE__ */ v(o, {
165
+ ].map((e) => /* @__PURE__ */ v(i, {
166
166
  label: e === "quotedAt" ? "Quote received at" : e === "validFrom" ? "Quote valid from" : "Quote valid until",
167
167
  type: "datetime-local",
168
- value: E[e] ? c(E[e]) : "",
169
- onChange: (t) => z({ [e]: t ? s(t) : null })
168
+ value: E[e] ? o(E[e]) : "",
169
+ onChange: (t) => z({ [e]: t ? a(t) : null })
170
170
  }, e))]
171
171
  }),
172
- /* @__PURE__ */ y(a, {
172
+ /* @__PURE__ */ y(r, {
173
173
  label: "Reporting total",
174
174
  value: E.reportingCurrency ? "RECORDED" : "UNKNOWN",
175
175
  onChange: (e) => z({ reportingCurrency: e === "RECORDED" ? {
@@ -184,7 +184,7 @@ function b({ disabled: b, shipmentId: x, onPreview: S, onSave: C }) {
184
184
  children: "Use a recorded currency convention"
185
185
  })]
186
186
  }),
187
- E.reportingCurrency && /* @__PURE__ */ v(i, {
187
+ E.reportingCurrency && /* @__PURE__ */ v(n, {
188
188
  label: "Reporting currency convention",
189
189
  value: E.reportingCurrency,
190
190
  onChange: (e) => z({ reportingCurrency: e })
@@ -0,0 +1,255 @@
1
+ import { Button as e } from "../ui.js";
2
+ import { useConditionApi as t, useConditionQuery as n } from "../../hooks/useContainerCondition.js";
3
+ import { ReuseState as r, reuseCard as i } from "../ReuseControls.js";
4
+ import { FreightSelect as a } from "../freight-cost/FreightFields.js";
5
+ import { DecideInvoiceReviewDocument as o, HandOffInvoiceSettlementDocument as s, InvoiceReviewExactDocument as c, RecordInvoiceSupplierResponseDocument as l, ResolveInvoiceDisputeDocument as u } from "../../src/generated/freight-invoice-operations.js";
6
+ import { invoiceMoney as d } from "../../utils/invoiceComparison.js";
7
+ import { DRAFT_PROBLEM_LABELS as f, REVIEW_EVENT_LABELS as p, REVIEW_STATUS_LABELS as m, authorNotice as h, availableReviewActions as g, decisionInput as _, handOffInput as v, isDraftProblem as y, resolutionInput as b, supplierResponseInput as x } from "../../utils/invoiceReview.js";
8
+ import { useState as S } from "react";
9
+ import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
10
+ //#region src/movethewheels/components/freight-invoice/InvoiceReviewPanel.tsx
11
+ var E = "mt-1 min-h-24 w-full rounded border p-2";
12
+ function D({ record: e, permissions: t, onChanged: a }) {
13
+ let [o, s] = S(0), l = n(c, t.canRead ? {
14
+ shipmentId: e.shipmentId,
15
+ comparisonId: e.id
16
+ } : null, o);
17
+ if (!t.canRead) return /* @__PURE__ */ T("section", {
18
+ className: i,
19
+ "aria-label": "Invoice review",
20
+ children: [/* @__PURE__ */ w("h2", {
21
+ className: "text-lg font-semibold",
22
+ children: "Invoice review"
23
+ }), /* @__PURE__ */ w("p", { children: "Freight invoice read permission is required to see the review status of this invoice." })]
24
+ });
25
+ let u = l.data?.mtwFreightInvoiceReview;
26
+ return /* @__PURE__ */ T("section", {
27
+ className: i,
28
+ "aria-label": "Invoice review",
29
+ children: [
30
+ /* @__PURE__ */ w("h2", {
31
+ className: "text-lg font-semibold",
32
+ children: "Invoice review"
33
+ }),
34
+ /* @__PURE__ */ w(r, {
35
+ loading: l.loading,
36
+ error: l.error
37
+ }),
38
+ u && /* @__PURE__ */ w(O, {
39
+ review: u,
40
+ lines: e.facts.rows,
41
+ permissions: t,
42
+ onRecorded: () => {
43
+ s((e) => e + 1), a?.();
44
+ }
45
+ }, `${u.comparisonId}:${u.sequence}`)
46
+ ]
47
+ });
48
+ }
49
+ function O({ review: e, lines: t, permissions: n, onRecorded: r }) {
50
+ let i = g(e, n), a = h(e), o = (e) => t.find((t) => t.id === e)?.description ?? e;
51
+ return /* @__PURE__ */ T("div", {
52
+ className: "space-y-4",
53
+ children: [
54
+ /* @__PURE__ */ T("p", {
55
+ className: "font-medium",
56
+ role: "status",
57
+ children: ["Status: ", m[e.status]]
58
+ }),
59
+ /* @__PURE__ */ T("p", { children: [
60
+ "Revision ",
61
+ e.revision,
62
+ " of ",
63
+ e.latestRevision,
64
+ ". Known invoice amount",
65
+ " ",
66
+ d(e.knownInvoiceAmountMinor, e.currency),
67
+ e.invoiceAmountComplete ? "" : " (some reported amounts are unknown and are not counted as zero)",
68
+ "."
69
+ ] }),
70
+ e.status === "SUPERSEDED" && /* @__PURE__ */ T("p", { children: ["A newer correction replaces this revision; review continues on the latest revision.", e.resolvedByCorrection && " Its open dispute was resolved by that correction."] }),
71
+ e.settlementReference && /* @__PURE__ */ T("p", { children: [
72
+ "Handed to platform Billing for settlement under reference",
73
+ " ",
74
+ /* @__PURE__ */ w("span", {
75
+ className: "break-all font-mono",
76
+ children: e.settlementReference
77
+ }),
78
+ ". This revision can no longer be corrected."
79
+ ] }),
80
+ a && /* @__PURE__ */ w("p", { children: a }),
81
+ e.events.length > 0 && /* @__PURE__ */ w("ol", {
82
+ className: "space-y-2",
83
+ "aria-label": "Review history",
84
+ children: e.events.map((e) => /* @__PURE__ */ T("li", {
85
+ className: "rounded border p-3 text-sm",
86
+ children: [
87
+ /* @__PURE__ */ T("p", {
88
+ className: "font-medium",
89
+ children: [
90
+ e.sequence,
91
+ ". ",
92
+ p[e.kind],
93
+ " —",
94
+ " ",
95
+ m[e.statusAfter]
96
+ ]
97
+ }),
98
+ /* @__PURE__ */ T("p", { children: [
99
+ e.recordedAt,
100
+ " by ",
101
+ e.createdBy
102
+ ] }),
103
+ e.reason && /* @__PURE__ */ w("p", {
104
+ className: "whitespace-pre-wrap break-words",
105
+ children: e.reason
106
+ }),
107
+ e.disputedLineIds.length > 0 && /* @__PURE__ */ T("p", { children: ["Disputed lines: ", e.disputedLineIds.map(o).join(", ")] })
108
+ ]
109
+ }, e.id))
110
+ }),
111
+ i.length > 0 ? /* @__PURE__ */ w(A, {
112
+ review: e,
113
+ actions: i,
114
+ lines: t,
115
+ onRecorded: r
116
+ }) : e.status !== "SUPERSEDED" && e.status !== "SETTLEMENT_HANDED_OFF" && !a && /* @__PURE__ */ w("p", { children: "Your role cannot take the next review step on this invoice." })
117
+ ]
118
+ });
119
+ }
120
+ var k = {
121
+ DECIDE: "Accept or dispute",
122
+ RECORD_SUPPLIER_RESPONSE: "Record supplier response",
123
+ RESOLVE_DISPUTE: "Resolve dispute",
124
+ HAND_OFF_SETTLEMENT: "Hand off to Billing"
125
+ };
126
+ function A({ review: n, actions: r, lines: i, onRecorded: c }) {
127
+ let p = t(), [m, h] = S(r[0]), [g, D] = S("ACCEPTED"), [O, A] = S("ACCEPTED"), [j, M] = S(""), [N, P] = S([]), [F, I] = S(() => crypto.randomUUID()), [L, R] = S(!1), [z, B] = S(null), V = (e) => (t) => {
128
+ e(t), I(crypto.randomUUID()), B(null);
129
+ }, H = {
130
+ review: n,
131
+ idempotencyKey: F
132
+ }, U = async () => {
133
+ let e = m === "DECIDE" ? {
134
+ document: o,
135
+ input: _(H, g, j, N)
136
+ } : m === "RECORD_SUPPLIER_RESPONSE" ? {
137
+ document: l,
138
+ input: x(H, j)
139
+ } : m === "RESOLVE_DISPUTE" ? {
140
+ document: u,
141
+ input: b(H, O, j)
142
+ } : {
143
+ document: s,
144
+ input: v(H, j)
145
+ };
146
+ if (y(e.input)) {
147
+ B(f[e.input]);
148
+ return;
149
+ }
150
+ R(!0), B(null);
151
+ try {
152
+ await p(e.document, { input: e.input }), c();
153
+ } catch (e) {
154
+ B(e instanceof Error ? e.message : "The review step was not recorded.");
155
+ } finally {
156
+ R(!1);
157
+ }
158
+ };
159
+ return /* @__PURE__ */ T("form", {
160
+ className: "space-y-3 border-t pt-4",
161
+ "aria-label": "Next review step",
162
+ onSubmit: (e) => {
163
+ e.preventDefault(), U();
164
+ },
165
+ children: [
166
+ r.length > 1 && /* @__PURE__ */ w(a, {
167
+ label: "Review step",
168
+ value: m,
169
+ onChange: (e) => V(h)(e),
170
+ children: r.map((e) => /* @__PURE__ */ w("option", {
171
+ value: e,
172
+ children: k[e]
173
+ }, e))
174
+ }),
175
+ m === "DECIDE" && /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ T(a, {
176
+ label: "Decision",
177
+ value: g,
178
+ onChange: (e) => V(D)(e),
179
+ children: [
180
+ /* @__PURE__ */ w("option", {
181
+ value: "ACCEPTED",
182
+ children: "Accept"
183
+ }),
184
+ /* @__PURE__ */ w("option", {
185
+ value: "ACCEPTED_WITH_VARIANCE",
186
+ children: "Accept with variance"
187
+ }),
188
+ /* @__PURE__ */ w("option", {
189
+ value: "DISPUTED",
190
+ children: "Dispute"
191
+ })
192
+ ]
193
+ }), g === "DISPUTED" && /* @__PURE__ */ T("fieldset", {
194
+ className: "space-y-2",
195
+ children: [/* @__PURE__ */ w("legend", {
196
+ className: "text-sm font-medium",
197
+ children: "Disputed invoice lines"
198
+ }), i.map((e) => /* @__PURE__ */ T("label", {
199
+ className: "flex min-h-11 items-center gap-2 text-sm",
200
+ children: [
201
+ /* @__PURE__ */ w("input", {
202
+ type: "checkbox",
203
+ checked: N.includes(e.id),
204
+ onChange: (t) => V(P)(t.target.checked ? [...N, e.id] : N.filter((t) => t !== e.id))
205
+ }),
206
+ e.description,
207
+ " (",
208
+ d(e.amountMinor, e.currency),
209
+ ")"
210
+ ]
211
+ }, e.id))]
212
+ })] }),
213
+ m === "RESOLVE_DISPUTE" && /* @__PURE__ */ T(a, {
214
+ label: "Resolution",
215
+ value: O,
216
+ onChange: (e) => V(A)(e),
217
+ children: [/* @__PURE__ */ w("option", {
218
+ value: "ACCEPTED",
219
+ children: "Accept as invoiced"
220
+ }), /* @__PURE__ */ w("option", {
221
+ value: "ACCEPTED_WITH_VARIANCE",
222
+ children: "Accept with variance"
223
+ })]
224
+ }),
225
+ /* @__PURE__ */ T("label", {
226
+ className: "block text-sm",
227
+ children: [m === "RECORD_SUPPLIER_RESPONSE" ? "Supplier's response" : m === "HAND_OFF_SETTLEMENT" ? "Note for Billing (optional)" : "Reason", /* @__PURE__ */ w("textarea", {
228
+ className: E,
229
+ value: j,
230
+ maxLength: 1e3,
231
+ onChange: (e) => V(M)(e.target.value)
232
+ })]
233
+ }),
234
+ m === "RESOLVE_DISPUTE" && /* @__PURE__ */ w("p", {
235
+ className: "text-sm",
236
+ children: "A dispute can also close by recording a corrected invoice revision."
237
+ }),
238
+ m === "HAND_OFF_SETTLEMENT" && /* @__PURE__ */ w("p", {
239
+ className: "text-sm",
240
+ children: "Billing settles the invoice; MoveTheWheels keeps no payment ledger. After hand-off this revision can no longer be corrected."
241
+ }),
242
+ z && /* @__PURE__ */ w("p", {
243
+ role: "alert",
244
+ children: z
245
+ }),
246
+ /* @__PURE__ */ w(e, {
247
+ type: "submit",
248
+ disabled: L,
249
+ children: L ? "Recording…" : k[m]
250
+ })
251
+ ]
252
+ });
253
+ }
254
+ //#endregion
255
+ export { D as InvoiceReviewPanel };
@@ -0,0 +1,93 @@
1
+ import { Button as e } from "../ui.js";
2
+ import { useConditionQuery as t } from "../../hooks/useContainerCondition.js";
3
+ import { ReusePager as n, ReuseState as r, reuseCard as i } from "../ReuseControls.js";
4
+ import { FreightSelect as a } from "../freight-cost/FreightFields.js";
5
+ import { InvoiceReviewQueueDocument as o, InvoiceReviewSummaryDocument as s } from "../../src/generated/freight-invoice-operations.js";
6
+ import { invoiceMoney as c } from "../../utils/invoiceComparison.js";
7
+ import { REVIEW_QUEUE_STATUSES as l, REVIEW_STATUS_LABELS as u } from "../../utils/invoiceReview.js";
8
+ import { useState as d } from "react";
9
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
10
+ //#region src/movethewheels/components/freight-invoice/InvoiceReviewQueue.tsx
11
+ var m = 10;
12
+ function h({ revision: s, onOpen: h, locked: g = !1 }) {
13
+ let [_, v] = d("AWAITING_REVIEW"), [y, b] = d(0), x = t(o, {
14
+ status: _ || null,
15
+ pagination: {
16
+ limit: m,
17
+ offset: y
18
+ }
19
+ }, s), S = x.data?.mtwFreightInvoiceReviewPage;
20
+ return /* @__PURE__ */ p("section", {
21
+ className: i,
22
+ "aria-label": "Invoice review queue",
23
+ children: [
24
+ /* @__PURE__ */ f("h2", {
25
+ className: "text-lg font-semibold",
26
+ children: "Invoice review queue"
27
+ }),
28
+ /* @__PURE__ */ f("p", { children: "The latest revision of each recorded carrier invoice. Open one to review it." }),
29
+ g && /* @__PURE__ */ f("p", {
30
+ role: "status",
31
+ children: "Finish or cancel the invoice draft below before opening a review."
32
+ }),
33
+ /* @__PURE__ */ p(a, {
34
+ label: "Review status",
35
+ value: _,
36
+ onChange: (e) => {
37
+ v(e), b(0);
38
+ },
39
+ children: [/* @__PURE__ */ f("option", {
40
+ value: "",
41
+ children: "All statuses"
42
+ }), l.map((e) => /* @__PURE__ */ f("option", {
43
+ value: e,
44
+ children: u[e]
45
+ }, e))]
46
+ }),
47
+ /* @__PURE__ */ f(r, {
48
+ loading: x.loading,
49
+ error: x.error
50
+ }),
51
+ S && S.items.length === 0 && /* @__PURE__ */ f("p", { children: "No invoices with this review status." }),
52
+ /* @__PURE__ */ f("ul", {
53
+ className: "space-y-2",
54
+ children: S?.items.map((t) => /* @__PURE__ */ f("li", { children: /* @__PURE__ */ p(e, {
55
+ type: "button",
56
+ variant: "outline",
57
+ className: "h-auto w-full max-w-full justify-start whitespace-normal break-words text-left",
58
+ disabled: g,
59
+ onClick: () => h(t),
60
+ children: [
61
+ t.supplierLabel ?? t.supplierReference,
62
+ " / invoice ",
63
+ t.invoiceReference,
64
+ ", revision ",
65
+ t.revision,
66
+ " — ",
67
+ u[t.status],
68
+ " —",
69
+ " ",
70
+ c(t.knownInvoiceAmountMinor, t.currency),
71
+ t.invoiceAmountComplete ? "" : " known"
72
+ ]
73
+ }) }, t.comparisonId))
74
+ }),
75
+ /* @__PURE__ */ f(n, {
76
+ page: S,
77
+ busy: x.loading,
78
+ offset: y,
79
+ onChange: b
80
+ })
81
+ ]
82
+ });
83
+ }
84
+ function g(e) {
85
+ let n = t(s, e ? {} : null);
86
+ return {
87
+ summary: n.data?.mtwFreightInvoiceReviewSummary ?? null,
88
+ loading: n.loading,
89
+ error: n.error
90
+ };
91
+ }
92
+ //#endregion
93
+ export { h as InvoiceReviewQueue, g as useInvoiceReviewSummary };