@burdenoff/microfe-theglobalfuel 2026.705.2 → 2026.705.4

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 (80) hide show
  1. package/dist/theglobalfuel/TheGlobalFuelRoot.js +54 -46
  2. package/dist/theglobalfuel/TheGlobalFuelRoot.js.map +1 -1
  3. package/dist/theglobalfuel/TheGlobalFuelRoutes.js +10 -6
  4. package/dist/theglobalfuel/TheGlobalFuelRoutes.js.map +1 -1
  5. package/dist/theglobalfuel/components/DataTable.js +126 -58
  6. package/dist/theglobalfuel/components/DataTable.js.map +1 -1
  7. package/dist/theglobalfuel/components/EmptyState.js +4 -4
  8. package/dist/theglobalfuel/components/EmptyState.js.map +1 -1
  9. package/dist/theglobalfuel/components/MetricsCard.js +2 -2
  10. package/dist/theglobalfuel/components/MetricsCard.js.map +1 -1
  11. package/dist/theglobalfuel/components/WorldMap.js +115 -0
  12. package/dist/theglobalfuel/components/WorldMap.js.map +1 -0
  13. package/dist/theglobalfuel/components/index.js +9 -0
  14. package/dist/theglobalfuel/components/viz/AllocationBar.js +68 -0
  15. package/dist/theglobalfuel/components/viz/AllocationBar.js.map +1 -0
  16. package/dist/theglobalfuel/components/viz/AreaChart.js +102 -0
  17. package/dist/theglobalfuel/components/viz/AreaChart.js.map +1 -0
  18. package/dist/theglobalfuel/components/viz/AvatarStack.js +2 -0
  19. package/dist/theglobalfuel/components/viz/BarChart.js +4 -0
  20. package/dist/theglobalfuel/components/viz/CertificateCard.js +4 -0
  21. package/dist/theglobalfuel/components/viz/DonutChart.js +109 -0
  22. package/dist/theglobalfuel/components/viz/DonutChart.js.map +1 -0
  23. package/dist/theglobalfuel/components/viz/HBarFunnel.js +3 -0
  24. package/dist/theglobalfuel/components/viz/Heatmap.js +3 -0
  25. package/dist/theglobalfuel/components/viz/KanbanBoard.js +2 -0
  26. package/dist/theglobalfuel/components/viz/LineChart.js +4 -0
  27. package/dist/theglobalfuel/components/viz/OrgTree.js +2 -0
  28. package/dist/theglobalfuel/components/viz/PathSteps.js +68 -0
  29. package/dist/theglobalfuel/components/viz/PathSteps.js.map +1 -0
  30. package/dist/theglobalfuel/components/viz/ProgressRing.js +6 -0
  31. package/dist/theglobalfuel/components/viz/ProgressRing.js.map +1 -0
  32. package/dist/theglobalfuel/components/viz/RatingStars.js +3 -0
  33. package/dist/theglobalfuel/components/viz/SegmentedTabs.js +3 -0
  34. package/dist/theglobalfuel/components/viz/SkillBar.js +3 -0
  35. package/dist/theglobalfuel/components/viz/Sparkline.js +74 -0
  36. package/dist/theglobalfuel/components/viz/Sparkline.js.map +1 -0
  37. package/dist/theglobalfuel/components/viz/StatCard.js +3 -0
  38. package/dist/theglobalfuel/components/viz/StepProgress.js +64 -0
  39. package/dist/theglobalfuel/components/viz/StepProgress.js.map +1 -0
  40. package/dist/theglobalfuel/components/viz/Timeline.js +66 -0
  41. package/dist/theglobalfuel/components/viz/Timeline.js.map +1 -0
  42. package/dist/theglobalfuel/components/viz/index.js +23 -0
  43. package/dist/theglobalfuel/components/viz/lib/Avatar.js +1 -0
  44. package/dist/theglobalfuel/components/viz/lib/CartesianFrame.js +119 -0
  45. package/dist/theglobalfuel/components/viz/lib/CartesianFrame.js.map +1 -0
  46. package/dist/theglobalfuel/components/viz/lib/ResponsiveSvg.js +35 -0
  47. package/dist/theglobalfuel/components/viz/lib/ResponsiveSvg.js.map +1 -0
  48. package/dist/theglobalfuel/components/viz/lib/format.js +17 -0
  49. package/dist/theglobalfuel/components/viz/lib/format.js.map +1 -0
  50. package/dist/theglobalfuel/components/viz/lib/geometry.js +61 -0
  51. package/dist/theglobalfuel/components/viz/lib/geometry.js.map +1 -0
  52. package/dist/theglobalfuel/components/viz/lib/hooks.js +39 -0
  53. package/dist/theglobalfuel/components/viz/lib/hooks.js.map +1 -0
  54. package/dist/theglobalfuel/components/viz/lib/palette.js +27 -0
  55. package/dist/theglobalfuel/components/viz/lib/palette.js.map +1 -0
  56. package/dist/theglobalfuel/hooks/useCursorPager.js +6 -15
  57. package/dist/theglobalfuel/hooks/useCursorPager.js.map +1 -1
  58. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js +431 -316
  59. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js.map +1 -1
  60. package/dist/theglobalfuel/pages/assets/AssetsPage.js +99 -99
  61. package/dist/theglobalfuel/pages/assets/AssetsPage.js.map +1 -1
  62. package/dist/theglobalfuel/pages/compliance/CompliancePage.js +250 -250
  63. package/dist/theglobalfuel/pages/compliance/CompliancePage.js.map +1 -1
  64. package/dist/theglobalfuel/pages/contracts/ContractsPage.js +2 -2
  65. package/dist/theglobalfuel/pages/contracts/ContractsPage.js.map +1 -1
  66. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js +525 -227
  67. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js.map +1 -1
  68. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js +255 -206
  69. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js.map +1 -1
  70. package/dist/theglobalfuel/pages/inventory/InventoryPage.js +60 -60
  71. package/dist/theglobalfuel/pages/inventory/InventoryPage.js.map +1 -1
  72. package/dist/theglobalfuel/pages/production/ProductionPage.js +2 -2
  73. package/dist/theglobalfuel/pages/production/ProductionPage.js.map +1 -1
  74. package/dist/theglobalfuel/pages/provenance/ProvenancePage.js +465 -0
  75. package/dist/theglobalfuel/pages/provenance/ProvenancePage.js.map +1 -0
  76. package/dist/theglobalfuel/pages/reserves/ReservesPage.js +152 -152
  77. package/dist/theglobalfuel/pages/reserves/ReservesPage.js.map +1 -1
  78. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js +356 -227
  79. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js.map +1 -1
  80. package/package.json +1 -1
@@ -0,0 +1,465 @@
1
+ import { useTheGlobalFuel as e } from "../../context/TheGlobalFuelContext.js";
2
+ import { cn as t } from "../../utils/cn.js";
3
+ import { PageLayout as n } from "../../components/PageLayout.js";
4
+ import { formatCoords as r, formatDate as i, formatEnumLabel as a, formatNumber as o, formatTonnesCo2e as ee, formatVolume as s } from "../../utils/formatters.js";
5
+ import { StatusBadge as c } from "../../components/StatusBadge.js";
6
+ import { ErrorView as l, LoadingView as u } from "../../components/StateViews.js";
7
+ import { EmptyState as te } from "../../components/EmptyState.js";
8
+ import { Timeline as ne } from "../../components/viz/Timeline.js";
9
+ import { StepProgress as re } from "../../components/viz/StepProgress.js";
10
+ import "../../context/index.js";
11
+ import { useTheAsset as ie, useTheAssets as ae, useTheComplianceCerts as oe, useTheContract as se, useTheContracts as ce, useTheEmissionRecords as le, useTheInventoryLots as ue } from "../../hooks/useTheGlobalFuelApi.js";
12
+ import "../../hooks/index.js";
13
+ import { FileLink as d } from "../../components/FileLink.js";
14
+ import { WorldMap as de } from "../../components/WorldMap.js";
15
+ import "../../components/index.js";
16
+ import { useMemo as f, useState as fe } from "react";
17
+ import { Boxes as p, CheckCircle2 as m, Factory as pe, Fuel as me, Gauge as h, Layers as he, Link2 as ge, MapPin as g, Route as _e, Shield as ve, ShieldCheck as _, Ship as ye } from "lucide-react";
18
+ import { Fragment as be, jsx as v, jsxs as y } from "react/jsx-runtime";
19
+ import { GlassCard as b, Select as xe, SelectContent as Se, SelectItem as Ce, SelectTrigger as we, SelectValue as Te } from "@burdenoff/fe-libs/ui";
20
+ //#region src/theglobalfuel/pages/provenance/ProvenancePage.tsx
21
+ var x = { limit: 200 };
22
+ function S(e) {
23
+ return (t, n) => {
24
+ let r = new Date(e(t) ?? t.createdAt).getTime();
25
+ return new Date(e(n) ?? n.createdAt).getTime() - r;
26
+ };
27
+ }
28
+ var C = {
29
+ done: "bg-status-success-bg-subtle text-status-success-text",
30
+ active: "bg-[var(--color-accent-soft)] text-accent",
31
+ todo: "bg-bg-sunken text-text-muted",
32
+ locked: "bg-bg-sunken text-text-muted"
33
+ }, w = {
34
+ done: "bg-status-success-bg-subtle text-status-success-text",
35
+ active: "bg-[var(--color-accent-soft)] text-accent",
36
+ todo: "bg-bg-sunken text-text-tertiary",
37
+ locked: "bg-bg-sunken text-text-tertiary"
38
+ }, T = {
39
+ done: "bg-status-success-text",
40
+ active: "bg-[var(--color-accent-primary)] motion-safe:animate-vc-glow-pulse",
41
+ todo: "bg-border-strong",
42
+ locked: "bg-border-strong"
43
+ };
44
+ function Ee({ node: e }) {
45
+ return /* @__PURE__ */ y(b, {
46
+ treatment: "glass",
47
+ className: t("relative flex h-full flex-col gap-3 p-5 transition-shadow", e.state === "done" && "shadow-[inset_0_2px_0_0_var(--color-status-success-text)]", e.state === "active" && "shadow-[inset_0_2px_0_0_var(--color-accent-primary)]"),
48
+ children: [
49
+ /* @__PURE__ */ y("div", {
50
+ className: "flex items-center justify-between",
51
+ children: [/* @__PURE__ */ v("span", {
52
+ className: t("flex size-7 items-center justify-center rounded-full text-xs font-semibold tabular-nums", C[e.state]),
53
+ children: e.step
54
+ }), /* @__PURE__ */ v("span", {
55
+ "aria-hidden": "true",
56
+ className: t("size-2 rounded-full", T[e.state])
57
+ })]
58
+ }),
59
+ /* @__PURE__ */ v("span", {
60
+ className: t("flex size-11 items-center justify-center rounded-xl [&_svg]:size-6", w[e.state]),
61
+ children: e.icon
62
+ }),
63
+ /* @__PURE__ */ y("div", {
64
+ className: "min-w-0",
65
+ children: [
66
+ /* @__PURE__ */ v("p", {
67
+ className: "text-xs font-medium uppercase tracking-wide text-text-tertiary",
68
+ children: e.label
69
+ }),
70
+ /* @__PURE__ */ v("p", {
71
+ className: t("mt-1 truncate text-base font-semibold", e.present ? "text-text-primary" : "text-text-muted"),
72
+ title: typeof e.primary == "string" ? e.primary : void 0,
73
+ children: e.present ? e.primary : "Pending"
74
+ }),
75
+ e.present && e.secondary && /* @__PURE__ */ v("p", {
76
+ className: "mt-0.5 line-clamp-2 text-xs text-text-secondary",
77
+ children: e.secondary
78
+ })
79
+ ]
80
+ }),
81
+ (e.badge || e.present && e.fileId) && /* @__PURE__ */ y("div", {
82
+ className: "mt-auto flex flex-wrap items-center gap-2 pt-1",
83
+ children: [e.badge, e.present && e.fileId && /* @__PURE__ */ v(d, { fileId: e.fileId })]
84
+ })
85
+ ]
86
+ });
87
+ }
88
+ function E({ icon: e, label: t, value: n, caption: r }) {
89
+ return /* @__PURE__ */ y("div", {
90
+ className: "flex items-start gap-3",
91
+ children: [/* @__PURE__ */ v("span", {
92
+ className: "mt-0.5 flex size-9 shrink-0 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent [&_svg]:size-4",
93
+ children: e
94
+ }), /* @__PURE__ */ y("div", {
95
+ className: "min-w-0",
96
+ children: [
97
+ /* @__PURE__ */ v("p", {
98
+ className: "text-xs font-medium uppercase tracking-wide text-text-tertiary",
99
+ children: t
100
+ }),
101
+ /* @__PURE__ */ v("p", {
102
+ className: "mt-0.5 truncate text-sm font-semibold text-text-primary",
103
+ children: n
104
+ }),
105
+ r && /* @__PURE__ */ v("p", {
106
+ className: "truncate text-xs text-text-tertiary",
107
+ children: r
108
+ })
109
+ ]
110
+ })]
111
+ });
112
+ }
113
+ function D() {
114
+ let { navigateTo: d } = e(), C = ae({ pagination: x }), w = f(() => C.data?.items ?? [], [C.data]), [T, D] = fe(""), O = T || w[0]?.id || "", k = ie(O || void 0), A = ue({ pagination: x }), j = le({
115
+ assetId: O || void 0,
116
+ pagination: x
117
+ }), M = oe(O || void 0, void 0, void 0, x), N = ce({
118
+ commodity: k.data?.commodity,
119
+ pagination: x
120
+ }), P = f(() => {
121
+ let e = [...N.data?.items ?? []].sort(S((e) => e.createdAt));
122
+ return (e.find((e) => e.deliveredVolume > 0 && e.side === "SELL") ?? e.find((e) => e.deliveredVolume > 0) ?? e.find((e) => e.side === "SELL") ?? e[0])?.id;
123
+ }, [N.data]), F = se(P), I = f(() => [...k.data?.productionRecords ?? []].sort(S((e) => e.periodEnd)), [k.data]), L = I[0], R = f(() => (A.data?.items ?? []).filter((e) => e.assetId === O).sort(S((e) => e.producedAt)), [A.data, O]), z = R[0], B = f(() => F.data?.shipments ?? [], [F.data]), V = f(() => [...B].filter((e) => e.status === "DELIVERED").sort(S((e) => e.deliveredAt))[0], [B]), H = f(() => V ?? [...B].sort(S((e) => e.departedAt ?? e.scheduledAt))[0], [V, B]), De = f(() => N.data?.items.find((e) => e.id === P), [N.data, P]), U = f(() => M.data?.items ?? [], [M.data]), W = f(() => U.find((e) => e.category === "CHAIN_OF_CUSTODY") ?? U.find((e) => e.status === "APPROVED") ?? U[0], [U]), G = W?.status === "APPROVED", Oe = f(() => j.data?.items ?? [], [j.data]), ke = Oe.reduce((e, t) => e + (t.co2eTonnes ?? 0), 0), Ae = Oe.filter((e) => e.verified).length, K = k.data, q = [
124
+ !!K,
125
+ I.length > 0,
126
+ R.length > 0,
127
+ !!H,
128
+ !!V,
129
+ G
130
+ ], je = q.filter(Boolean).length, Me = q.findIndex((e) => !e), J = Me === -1 ? q.length : Me, Y = G && !!V, X = (e) => q[e] ? "done" : e === J ? "active" : "todo", Ne = [
131
+ {
132
+ label: "Asset",
133
+ description: "Origin"
134
+ },
135
+ {
136
+ label: "Production",
137
+ description: "Extracted"
138
+ },
139
+ {
140
+ label: "Inventory",
141
+ description: "Lotted"
142
+ },
143
+ {
144
+ label: "Shipment",
145
+ description: "In transit"
146
+ },
147
+ {
148
+ label: "Delivered",
149
+ description: "Received"
150
+ },
151
+ {
152
+ label: "Certificate",
153
+ description: "Verified"
154
+ }
155
+ ], Z = H && (H.origin || H.destination) ? [H.origin, H.destination].filter(Boolean).join(" → ") : void 0, Pe = K ? [
156
+ {
157
+ step: 1,
158
+ icon: /* @__PURE__ */ v(g, {}),
159
+ label: "Asset",
160
+ primary: K.name,
161
+ secondary: K.location ?? r(K.latitude, K.longitude),
162
+ badge: /* @__PURE__ */ v(c, { status: K.status }),
163
+ state: X(0),
164
+ present: !0
165
+ },
166
+ {
167
+ step: 2,
168
+ icon: /* @__PURE__ */ v(h, {}),
169
+ label: "Production",
170
+ primary: L ? s(L.volume, L.unit) : "Not yet recorded",
171
+ secondary: L ? `${i(L.periodStart)} – ${i(L.periodEnd)}` : void 0,
172
+ state: X(1),
173
+ present: !!L
174
+ },
175
+ {
176
+ step: 3,
177
+ icon: /* @__PURE__ */ v(p, {}),
178
+ label: "Inventory lot",
179
+ primary: z ? z.lotCode : "No lot yet",
180
+ secondary: z ? s(z.quantity, z.unit) : void 0,
181
+ badge: z ? /* @__PURE__ */ v(c, { status: z.status }) : void 0,
182
+ state: X(2),
183
+ present: !!z
184
+ },
185
+ {
186
+ step: 4,
187
+ icon: /* @__PURE__ */ v(ye, {}),
188
+ label: "Shipment",
189
+ primary: H ? H.reference : "Not shipped",
190
+ secondary: H ? [a(H.mode), Z].filter(Boolean).join(" · ") : void 0,
191
+ badge: H ? /* @__PURE__ */ v(c, { status: H.status }) : void 0,
192
+ fileId: H?.document?.id,
193
+ state: X(3),
194
+ present: !!H
195
+ },
196
+ {
197
+ step: 5,
198
+ icon: /* @__PURE__ */ v(m, {}),
199
+ label: "Delivered",
200
+ primary: V ? s(V.volume, V.unit) : "Awaiting delivery",
201
+ secondary: V && [V.deliveredAt ? i(V.deliveredAt) : null, De ? `Contract ${De.reference}` : null].filter(Boolean).join(" · ") || void 0,
202
+ state: X(4),
203
+ present: !!V
204
+ },
205
+ {
206
+ step: 6,
207
+ icon: /* @__PURE__ */ v(_, {}),
208
+ label: "Certificate",
209
+ primary: W ? W.certNumber ?? W.title : "No certificate",
210
+ secondary: W ? a(W.category) : void 0,
211
+ badge: W ? /* @__PURE__ */ v(c, { status: W.status }) : void 0,
212
+ fileId: W?.evidence?.id,
213
+ state: X(5),
214
+ present: !!W
215
+ }
216
+ ] : [], Fe = f(() => {
217
+ if (!K) return [];
218
+ let e = [], t = (t, n) => {
219
+ if (!t) return;
220
+ let r = new Date(t).getTime();
221
+ Number.isNaN(r) || e.push({
222
+ date: t,
223
+ item: n
224
+ });
225
+ };
226
+ return t(K.commissionedAt ?? K.createdAt, {
227
+ title: "Asset registered",
228
+ meta: K.name,
229
+ tone: "accent",
230
+ icon: /* @__PURE__ */ v(g, { className: "h-3 w-3" })
231
+ }), L && t(L.periodEnd ?? L.createdAt, {
232
+ title: "Production recorded",
233
+ meta: s(L.volume, L.unit),
234
+ tone: "info",
235
+ icon: /* @__PURE__ */ v(h, { className: "h-3 w-3" })
236
+ }), z && t(z.producedAt ?? z.createdAt, {
237
+ title: "Inventory lot created",
238
+ meta: `${z.lotCode} · ${s(z.quantity, z.unit)}`,
239
+ tone: "info",
240
+ icon: /* @__PURE__ */ v(p, { className: "h-3 w-3" })
241
+ }), H && t(H.departedAt ?? H.scheduledAt ?? H.createdAt, {
242
+ title: H.departedAt ? "Shipment departed" : "Shipment scheduled",
243
+ meta: [H.reference, Z].filter(Boolean).join(" · "),
244
+ tone: "accent",
245
+ icon: /* @__PURE__ */ v(ye, { className: "h-3 w-3" })
246
+ }), V?.deliveredAt && t(V.deliveredAt, {
247
+ title: "Delivered",
248
+ meta: s(V.volume, V.unit),
249
+ tone: "success",
250
+ icon: /* @__PURE__ */ v(m, { className: "h-3 w-3" })
251
+ }), W && t(W.issuedAt ?? W.createdAt, {
252
+ title: G ? "Certificate approved" : "Certificate registered",
253
+ meta: W.certNumber ?? W.title,
254
+ tone: G ? "success" : "warning",
255
+ icon: /* @__PURE__ */ v(_, { className: "h-3 w-3" })
256
+ }), e.sort((e, t) => new Date(e.date).getTime() - new Date(t.date).getTime()).map(({ date: e, item: t }) => ({
257
+ ...t,
258
+ time: i(e)
259
+ }));
260
+ }, [
261
+ K,
262
+ L,
263
+ z,
264
+ H,
265
+ V,
266
+ W,
267
+ G,
268
+ Z
269
+ ]), Q = K && typeof K.latitude == "number" && typeof K.longitude == "number" ? {
270
+ lat: K.latitude,
271
+ lng: K.longitude,
272
+ label: K.name,
273
+ primary: !0
274
+ } : null, $ = "Pit to port to certificate — end-to-end traceability from origin to verified certificate.";
275
+ return C.isLoading && w.length === 0 ? /* @__PURE__ */ v(n, {
276
+ title: "Provenance",
277
+ description: $,
278
+ children: /* @__PURE__ */ v(u, { label: "Loading assets…" })
279
+ }) : C.isError ? /* @__PURE__ */ v(n, {
280
+ title: "Provenance",
281
+ description: $,
282
+ children: /* @__PURE__ */ v(l, {
283
+ message: "Couldn't load assets to trace.",
284
+ onRetry: () => C.refetch()
285
+ })
286
+ }) : w.length === 0 ? /* @__PURE__ */ v(n, {
287
+ title: "Provenance",
288
+ description: $,
289
+ children: /* @__PURE__ */ v(te, {
290
+ illustration: "empty-data",
291
+ icon: /* @__PURE__ */ v(ge, { className: "h-10 w-10" }),
292
+ title: "No assets to trace",
293
+ description: "Register a resource asset to build its end-to-end chain of custody.",
294
+ action: /* @__PURE__ */ v("button", {
295
+ type: "button",
296
+ onClick: () => d("assets"),
297
+ className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
298
+ children: "Go to assets"
299
+ })
300
+ })
301
+ }) : /* @__PURE__ */ y(n, {
302
+ title: "Provenance",
303
+ description: $,
304
+ children: [/* @__PURE__ */ y(b, {
305
+ treatment: "glass",
306
+ className: "flex flex-col gap-4 p-5 sm:flex-row sm:items-center sm:justify-between",
307
+ children: [/* @__PURE__ */ y("div", {
308
+ className: "flex min-w-0 flex-1 flex-col gap-1.5",
309
+ children: [/* @__PURE__ */ v("label", {
310
+ htmlFor: "provenance-asset",
311
+ className: "text-xs font-medium uppercase tracking-wide text-text-tertiary",
312
+ children: "Trace asset"
313
+ }), /* @__PURE__ */ y(xe, {
314
+ value: O,
315
+ onValueChange: D,
316
+ children: [/* @__PURE__ */ v(we, {
317
+ id: "provenance-asset",
318
+ className: "h-10 w-full sm:w-96",
319
+ "aria-label": "Select an asset to trace",
320
+ children: /* @__PURE__ */ v(Te, { placeholder: "Select an asset to trace" })
321
+ }), /* @__PURE__ */ v(Se, { children: w.map((e) => /* @__PURE__ */ y(Ce, {
322
+ value: e.id,
323
+ children: [
324
+ e.name,
325
+ " · ",
326
+ a(e.commodity)
327
+ ]
328
+ }, e.id)) })]
329
+ })]
330
+ }), /* @__PURE__ */ y("div", {
331
+ className: t("flex items-center gap-2 self-start rounded-full px-3.5 py-1.5 text-sm font-medium", Y ? "bg-status-success-bg-subtle text-status-success-text" : "bg-bg-sunken text-text-secondary"),
332
+ children: [v(Y ? _ : ve, { className: "h-4 w-4" }), Y ? "Chain of custody verified" : `Traceability in progress · ${je}/6`]
333
+ })]
334
+ }), k.isLoading ? /* @__PURE__ */ v("div", {
335
+ className: "mt-6",
336
+ children: /* @__PURE__ */ v(u, { label: "Assembling chain of custody…" })
337
+ }) : k.isError || !K ? /* @__PURE__ */ v("div", {
338
+ className: "mt-6",
339
+ children: /* @__PURE__ */ v(l, {
340
+ message: "Couldn't load this asset's provenance.",
341
+ onRetry: () => k.refetch()
342
+ })
343
+ }) : /* @__PURE__ */ y(be, { children: [
344
+ /* @__PURE__ */ v(b, {
345
+ treatment: "glass",
346
+ className: "mt-6 p-5",
347
+ children: /* @__PURE__ */ v(re, {
348
+ steps: Ne,
349
+ current: J
350
+ })
351
+ }),
352
+ /* @__PURE__ */ v("div", {
353
+ className: "mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6",
354
+ children: Pe.map((e) => /* @__PURE__ */ v(Ee, { node: e }, e.step))
355
+ }),
356
+ /* @__PURE__ */ y("div", {
357
+ className: "mt-6 grid grid-cols-1 gap-6 lg:grid-cols-3",
358
+ children: [/* @__PURE__ */ y(b, {
359
+ treatment: "glass",
360
+ className: "p-5 lg:col-span-2",
361
+ children: [/* @__PURE__ */ y("div", {
362
+ className: "mb-4 flex items-center gap-2.5",
363
+ children: [/* @__PURE__ */ v("span", {
364
+ className: "flex size-8 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent",
365
+ children: /* @__PURE__ */ v(_e, { className: "h-4 w-4" })
366
+ }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h2", {
367
+ className: "text-base font-semibold text-text-primary",
368
+ children: "Traceability timeline"
369
+ }), /* @__PURE__ */ v("p", {
370
+ className: "text-xs text-text-tertiary",
371
+ children: "Recorded custody events, oldest to newest."
372
+ })] })]
373
+ }), Fe.length > 0 ? /* @__PURE__ */ v(ne, { items: Fe }) : /* @__PURE__ */ v("div", {
374
+ className: "rounded-xl border border-dashed border-border-seam py-8 text-center text-sm text-text-secondary",
375
+ children: "No dated custody events yet."
376
+ })]
377
+ }), /* @__PURE__ */ y(b, {
378
+ treatment: "glass",
379
+ className: "flex flex-col gap-4 p-5",
380
+ children: [/* @__PURE__ */ y("div", {
381
+ className: "flex items-center gap-2.5",
382
+ children: [/* @__PURE__ */ v("span", {
383
+ className: "flex size-8 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent",
384
+ children: /* @__PURE__ */ v(g, { className: "h-4 w-4" })
385
+ }), /* @__PURE__ */ y("div", {
386
+ className: "min-w-0",
387
+ children: [/* @__PURE__ */ v("h2", {
388
+ className: "text-base font-semibold text-text-primary",
389
+ children: "Origin"
390
+ }), /* @__PURE__ */ v("p", {
391
+ className: "truncate text-xs text-text-tertiary",
392
+ children: K.location ?? a(K.kind)
393
+ })]
394
+ })]
395
+ }), Q ? /* @__PURE__ */ v(de, { points: [Q] }) : /* @__PURE__ */ v("div", {
396
+ className: "rounded-xl border border-dashed border-border-seam py-8 text-center text-sm text-text-secondary",
397
+ children: "No coordinates recorded for this asset."
398
+ })]
399
+ })]
400
+ }),
401
+ /* @__PURE__ */ y(b, {
402
+ treatment: "glass",
403
+ className: "mt-6 p-5",
404
+ children: [/* @__PURE__ */ v("h2", {
405
+ className: "mb-4 text-base font-semibold text-text-primary",
406
+ children: "Provenance summary"
407
+ }), /* @__PURE__ */ y("div", {
408
+ className: "grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6",
409
+ children: [
410
+ /* @__PURE__ */ v(E, {
411
+ icon: /* @__PURE__ */ v(me, {}),
412
+ label: "Commodity",
413
+ value: a(K.commodity),
414
+ caption: a(K.kind)
415
+ }),
416
+ /* @__PURE__ */ v(E, {
417
+ icon: /* @__PURE__ */ v(g, {}),
418
+ label: "Origin",
419
+ value: K.location ?? K.name,
420
+ caption: r(K.latitude, K.longitude)
421
+ }),
422
+ /* @__PURE__ */ v(E, {
423
+ icon: /* @__PURE__ */ v(h, {}),
424
+ label: "Production",
425
+ value: `${o(I.length)} records`,
426
+ caption: L ? `Latest ${s(L.volume, L.unit)}` : "None yet"
427
+ }),
428
+ /* @__PURE__ */ v(E, {
429
+ icon: /* @__PURE__ */ v(p, {}),
430
+ label: "Inventory",
431
+ value: `${o(R.length)} lots`,
432
+ caption: z ? z.lotCode : "None yet"
433
+ }),
434
+ /* @__PURE__ */ v(E, {
435
+ icon: /* @__PURE__ */ v(pe, {}),
436
+ label: "Emissions",
437
+ value: j.isError ? "—" : ee(ke),
438
+ caption: `${Ae} verified`
439
+ }),
440
+ /* @__PURE__ */ v(E, {
441
+ icon: /* @__PURE__ */ v(_, {}),
442
+ label: "Certificates",
443
+ value: `${o(U.length)} tracked`,
444
+ caption: G ? "Custody approved" : W ? "Under review" : "None yet"
445
+ })
446
+ ]
447
+ })]
448
+ }),
449
+ (K.reserveEstimates?.length ?? 0) > 0 && /* @__PURE__ */ y("p", {
450
+ className: "mt-4 flex items-center gap-1.5 text-xs text-text-tertiary",
451
+ children: [
452
+ /* @__PURE__ */ v(he, { className: "h-3.5 w-3.5" }),
453
+ o(K.reserveEstimates?.length ?? 0),
454
+ " reserve estimate",
455
+ (K.reserveEstimates?.length ?? 0) === 1 ? "" : "s",
456
+ " on record for this asset."
457
+ ]
458
+ })
459
+ ] })]
460
+ });
461
+ }
462
+ //#endregion
463
+ export { D as ProvenancePage };
464
+
465
+ //# sourceMappingURL=ProvenancePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProvenancePage.js","names":[],"sources":["../../../../src/theglobalfuel/pages/provenance/ProvenancePage.tsx"],"sourcesContent":["/**\n * Provenance — chain-of-custody traceability (pit → port → certificate).\n * @module theglobalfuel/pages/provenance\n *\n * The flagship end-to-end traceability view. The user picks a resource asset and\n * we assemble its custody chain entirely from REAL linked records:\n * Asset (registry) → Production → Inventory lot → Shipment (+ document) →\n * Delivered → Chain-of-custody certificate (+ evidence)\n *\n * Sources — all `the*` endpoints, no mock data:\n * - useTheAsset(id) → the asset + nested productionRecords/reserves\n * - useTheInventoryLots() → filtered client-side to lot.assetId === id\n * - useTheEmissionRecords() → attributed emissions for the summary\n * - useTheComplianceCerts(id) → CHAIN_OF_CUSTODY / evidence certs\n * - useTheContracts({commodity}) + useTheContract() → offtake + nested shipments\n *\n * The chain renders as a StepProgress flow + a row of rich node cards (each\n * carrying the real record and a FileLink for its document/evidence), a Timeline\n * of the real dated events, an origin map and a provenance summary. Every stage\n * degrades gracefully when its downstream record does not exist yet (pre-launch).\n */\n\nimport { useMemo, useState, type ReactNode } from 'react';\nimport {\n Link2,\n MapPin,\n Gauge,\n Boxes,\n Ship,\n CheckCircle2,\n ShieldCheck,\n Shield,\n Fuel,\n Factory,\n Route,\n Layers,\n} from 'lucide-react';\nimport {\n GlassCard,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n StatusBadge,\n LoadingView,\n ErrorView,\n EmptyState,\n FileLink,\n WorldMap,\n StepProgress,\n Timeline,\n type TimelineItem,\n type StepProgressStep,\n type PathStepState,\n} from '../../components';\nimport { useTheGlobalFuel } from '../../context';\nimport {\n useTheAssets,\n useTheAsset,\n useTheInventoryLots,\n useTheEmissionRecords,\n useTheComplianceCerts,\n useTheContracts,\n useTheContract,\n} from '../../hooks';\nimport { cn } from '../../utils/cn';\nimport {\n formatDate,\n formatVolume,\n formatEnumLabel,\n formatCoords,\n formatNumber,\n formatTonnesCo2e,\n} from '../../utils';\nimport type { TheProductionRecord, TheInventoryLot, TheShipment } from '../../types';\n\nconst PAGE: { limit: number } = { limit: 200 };\n\n/** Latest-first by an optional date field, falling back to createdAt. */\nfunction byDateDesc<T extends { createdAt: string }>(pick: (row: T) => string | null | undefined) {\n return (a: T, b: T): number => {\n const av = new Date(pick(a) ?? a.createdAt).getTime();\n const bv = new Date(pick(b) ?? b.createdAt).getTime();\n return bv - av;\n };\n}\n\n// ── Chain node card ──────────────────────────────────────────────────────────\n\ninterface ChainNodeVM {\n step: number;\n icon: ReactNode;\n label: string;\n /** Real primary value; shown muted as \"Pending\" when the artifact is absent. */\n primary: ReactNode;\n secondary?: ReactNode;\n badge?: ReactNode;\n fileId?: string | null;\n state: PathStepState;\n present: boolean;\n}\n\nconst NUMBER_STYLE: Record<PathStepState, string> = {\n done: 'bg-status-success-bg-subtle text-status-success-text',\n active: 'bg-[var(--color-accent-soft)] text-accent',\n todo: 'bg-bg-sunken text-text-muted',\n locked: 'bg-bg-sunken text-text-muted',\n};\n\nconst ICON_STYLE: Record<PathStepState, string> = {\n done: 'bg-status-success-bg-subtle text-status-success-text',\n active: 'bg-[var(--color-accent-soft)] text-accent',\n todo: 'bg-bg-sunken text-text-tertiary',\n locked: 'bg-bg-sunken text-text-tertiary',\n};\n\nconst DOT_STYLE: Record<PathStepState, string> = {\n done: 'bg-status-success-text',\n active: 'bg-[var(--color-accent-primary)] motion-safe:animate-vc-glow-pulse',\n todo: 'bg-border-strong',\n locked: 'bg-border-strong',\n};\n\nfunction ChainNodeCard({ node }: { node: ChainNodeVM }) {\n return (\n <GlassCard\n treatment=\"glass\"\n className={cn(\n 'relative flex h-full flex-col gap-3 p-5 transition-shadow',\n node.state === 'done' && 'shadow-[inset_0_2px_0_0_var(--color-status-success-text)]',\n node.state === 'active' && 'shadow-[inset_0_2px_0_0_var(--color-accent-primary)]'\n )}\n >\n <div className=\"flex items-center justify-between\">\n <span\n className={cn(\n 'flex size-7 items-center justify-center rounded-full text-xs font-semibold tabular-nums',\n NUMBER_STYLE[node.state]\n )}\n >\n {node.step}\n </span>\n <span aria-hidden=\"true\" className={cn('size-2 rounded-full', DOT_STYLE[node.state])} />\n </div>\n\n <span\n className={cn(\n 'flex size-11 items-center justify-center rounded-xl [&_svg]:size-6',\n ICON_STYLE[node.state]\n )}\n >\n {node.icon}\n </span>\n\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-tertiary\">\n {node.label}\n </p>\n <p\n className={cn(\n 'mt-1 truncate text-base font-semibold',\n node.present ? 'text-text-primary' : 'text-text-muted'\n )}\n title={typeof node.primary === 'string' ? node.primary : undefined}\n >\n {node.present ? node.primary : 'Pending'}\n </p>\n {node.present && node.secondary && (\n <p className=\"mt-0.5 line-clamp-2 text-xs text-text-secondary\">{node.secondary}</p>\n )}\n </div>\n\n {(node.badge || (node.present && node.fileId)) && (\n <div className=\"mt-auto flex flex-wrap items-center gap-2 pt-1\">\n {node.badge}\n {node.present && node.fileId && <FileLink fileId={node.fileId} />}\n </div>\n )}\n </GlassCard>\n );\n}\n\n// ── Summary cell ─────────────────────────────────────────────────────────────\n\nfunction SummaryCell({\n icon,\n label,\n value,\n caption,\n}: {\n icon: ReactNode;\n label: string;\n value: ReactNode;\n caption?: ReactNode;\n}) {\n return (\n <div className=\"flex items-start gap-3\">\n <span className=\"mt-0.5 flex size-9 shrink-0 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent [&_svg]:size-4\">\n {icon}\n </span>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-tertiary\">{label}</p>\n <p className=\"mt-0.5 truncate text-sm font-semibold text-text-primary\">{value}</p>\n {caption && <p className=\"truncate text-xs text-text-tertiary\">{caption}</p>}\n </div>\n </div>\n );\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function ProvenancePage() {\n const { navigateTo } = useTheGlobalFuel();\n\n const assets = useTheAssets({ pagination: PAGE });\n const assetRows = useMemo(() => assets.data?.items ?? [], [assets.data]);\n\n const [selectedAssetId, setSelectedAssetId] = useState<string>('');\n // Auto-focus the first asset (no effect needed) so the chain renders at once;\n // an explicit user selection always wins.\n const effectiveAssetId = selectedAssetId || assetRows[0]?.id || '';\n\n const asset = useTheAsset(effectiveAssetId || undefined);\n const inventory = useTheInventoryLots({ pagination: PAGE });\n const emissions = useTheEmissionRecords({\n assetId: effectiveAssetId || undefined,\n pagination: PAGE,\n });\n const compliance = useTheComplianceCerts(\n effectiveAssetId || undefined,\n undefined,\n undefined,\n PAGE\n );\n const contracts = useTheContracts({ commodity: asset.data?.commodity, pagination: PAGE });\n\n // Pick the contract most likely to carry a delivered shipment for this\n // commodity: prefer one that has already delivered volume (SELL first), else\n // the most recent. Its nested shipments give us the movement + delivery nodes.\n const pickedContractId = useMemo(() => {\n const rows = [...(contracts.data?.items ?? [])].sort(byDateDesc((c) => c.createdAt));\n const pick =\n rows.find((c) => c.deliveredVolume > 0 && c.side === 'SELL') ??\n rows.find((c) => c.deliveredVolume > 0) ??\n rows.find((c) => c.side === 'SELL') ??\n rows[0];\n return pick?.id;\n }, [contracts.data]);\n\n const contractDetail = useTheContract(pickedContractId);\n\n // ── Derive the chain from real linked records ──────────────────────────────\n const productionRecords = useMemo(\n () => [...(asset.data?.productionRecords ?? [])].sort(byDateDesc((r) => r.periodEnd)),\n [asset.data]\n );\n const latestProduction: TheProductionRecord | undefined = productionRecords[0];\n\n const assetLots = useMemo<TheInventoryLot[]>(\n () =>\n (inventory.data?.items ?? [])\n .filter((l) => l.assetId === effectiveAssetId)\n .sort(byDateDesc((l) => l.producedAt)),\n [inventory.data, effectiveAssetId]\n );\n const latestLot: TheInventoryLot | undefined = assetLots[0];\n\n const shipments = useMemo<TheShipment[]>(\n () => contractDetail.data?.shipments ?? [],\n [contractDetail.data]\n );\n const deliveredShipment = useMemo<TheShipment | undefined>(\n () =>\n [...shipments]\n .filter((s) => s.status === 'DELIVERED')\n .sort(byDateDesc((s) => s.deliveredAt))[0],\n [shipments]\n );\n const primaryShipment = useMemo<TheShipment | undefined>(\n () =>\n deliveredShipment ?? [...shipments].sort(byDateDesc((s) => s.departedAt ?? s.scheduledAt))[0],\n [deliveredShipment, shipments]\n );\n const pickedContract = useMemo(\n () => contracts.data?.items.find((c) => c.id === pickedContractId),\n [contracts.data, pickedContractId]\n );\n\n const certRows = useMemo(() => compliance.data?.items ?? [], [compliance.data]);\n const custodyCert = useMemo(\n () =>\n certRows.find((c) => c.category === 'CHAIN_OF_CUSTODY') ??\n certRows.find((c) => c.status === 'APPROVED') ??\n certRows[0],\n [certRows]\n );\n const certApproved = custodyCert?.status === 'APPROVED';\n\n const emissionRows = useMemo(() => emissions.data?.items ?? [], [emissions.data]);\n const totalTonnes = emissionRows.reduce((sum, e) => sum + (e.co2eTonnes ?? 0), 0);\n const verifiedEmissions = emissionRows.filter((e) => e.verified).length;\n\n const a = asset.data;\n\n // Stage completeness, in chain order.\n const completeFlags = [\n Boolean(a),\n productionRecords.length > 0,\n assetLots.length > 0,\n Boolean(primaryShipment),\n Boolean(deliveredShipment),\n certApproved,\n ];\n const completeCount = completeFlags.filter(Boolean).length;\n const firstIncomplete = completeFlags.findIndex((f) => !f);\n const current = firstIncomplete === -1 ? completeFlags.length : firstIncomplete;\n const verified = certApproved && Boolean(deliveredShipment);\n\n const stateFor = (i: number): PathStepState =>\n completeFlags[i] ? 'done' : i === current ? 'active' : 'todo';\n\n const progressSteps: StepProgressStep[] = [\n { label: 'Asset', description: 'Origin' },\n { label: 'Production', description: 'Extracted' },\n { label: 'Inventory', description: 'Lotted' },\n { label: 'Shipment', description: 'In transit' },\n { label: 'Delivered', description: 'Received' },\n { label: 'Certificate', description: 'Verified' },\n ];\n\n const shipmentRoute =\n primaryShipment && (primaryShipment.origin || primaryShipment.destination)\n ? [primaryShipment.origin, primaryShipment.destination].filter(Boolean).join(' → ')\n : undefined;\n\n const nodes: ChainNodeVM[] = a\n ? [\n {\n step: 1,\n icon: <MapPin />,\n label: 'Asset',\n primary: a.name,\n secondary: a.location ?? formatCoords(a.latitude, a.longitude),\n badge: <StatusBadge status={a.status} />,\n state: stateFor(0),\n present: true,\n },\n {\n step: 2,\n icon: <Gauge />,\n label: 'Production',\n primary: latestProduction\n ? formatVolume(latestProduction.volume, latestProduction.unit)\n : 'Not yet recorded',\n secondary: latestProduction\n ? `${formatDate(latestProduction.periodStart)} – ${formatDate(latestProduction.periodEnd)}`\n : undefined,\n state: stateFor(1),\n present: Boolean(latestProduction),\n },\n {\n step: 3,\n icon: <Boxes />,\n label: 'Inventory lot',\n primary: latestLot ? latestLot.lotCode : 'No lot yet',\n secondary: latestLot ? formatVolume(latestLot.quantity, latestLot.unit) : undefined,\n badge: latestLot ? <StatusBadge status={latestLot.status} /> : undefined,\n state: stateFor(2),\n present: Boolean(latestLot),\n },\n {\n step: 4,\n icon: <Ship />,\n label: 'Shipment',\n primary: primaryShipment ? primaryShipment.reference : 'Not shipped',\n secondary: primaryShipment\n ? [formatEnumLabel(primaryShipment.mode), shipmentRoute].filter(Boolean).join(' · ')\n : undefined,\n badge: primaryShipment ? <StatusBadge status={primaryShipment.status} /> : undefined,\n fileId: primaryShipment?.document?.id,\n state: stateFor(3),\n present: Boolean(primaryShipment),\n },\n {\n step: 5,\n icon: <CheckCircle2 />,\n label: 'Delivered',\n primary: deliveredShipment\n ? formatVolume(deliveredShipment.volume, deliveredShipment.unit)\n : 'Awaiting delivery',\n secondary: deliveredShipment\n ? [\n deliveredShipment.deliveredAt ? formatDate(deliveredShipment.deliveredAt) : null,\n pickedContract ? `Contract ${pickedContract.reference}` : null,\n ]\n .filter(Boolean)\n .join(' · ') || undefined\n : undefined,\n state: stateFor(4),\n present: Boolean(deliveredShipment),\n },\n {\n step: 6,\n icon: <ShieldCheck />,\n label: 'Certificate',\n primary: custodyCert ? (custodyCert.certNumber ?? custodyCert.title) : 'No certificate',\n secondary: custodyCert ? formatEnumLabel(custodyCert.category) : undefined,\n badge: custodyCert ? <StatusBadge status={custodyCert.status} /> : undefined,\n fileId: custodyCert?.evidence?.id,\n state: stateFor(5),\n present: Boolean(custodyCert),\n },\n ]\n : [];\n\n // ── Timeline (real dated events, ascending) ────────────────────────────────\n const timelineItems = useMemo<TimelineItem[]>(() => {\n if (!a) return [];\n const raw: { date: string; item: Omit<TimelineItem, 'time'> }[] = [];\n const push = (date: string | null | undefined, item: Omit<TimelineItem, 'time'>) => {\n if (!date) return;\n const t = new Date(date).getTime();\n if (Number.isNaN(t)) return;\n raw.push({ date, item });\n };\n\n push(a.commissionedAt ?? a.createdAt, {\n title: 'Asset registered',\n meta: a.name,\n tone: 'accent',\n icon: <MapPin className=\"h-3 w-3\" />,\n });\n if (latestProduction) {\n push(latestProduction.periodEnd ?? latestProduction.createdAt, {\n title: 'Production recorded',\n meta: formatVolume(latestProduction.volume, latestProduction.unit),\n tone: 'info',\n icon: <Gauge className=\"h-3 w-3\" />,\n });\n }\n if (latestLot) {\n push(latestLot.producedAt ?? latestLot.createdAt, {\n title: 'Inventory lot created',\n meta: `${latestLot.lotCode} · ${formatVolume(latestLot.quantity, latestLot.unit)}`,\n tone: 'info',\n icon: <Boxes className=\"h-3 w-3\" />,\n });\n }\n if (primaryShipment) {\n push(primaryShipment.departedAt ?? primaryShipment.scheduledAt ?? primaryShipment.createdAt, {\n title: primaryShipment.departedAt ? 'Shipment departed' : 'Shipment scheduled',\n meta: [primaryShipment.reference, shipmentRoute].filter(Boolean).join(' · '),\n tone: 'accent',\n icon: <Ship className=\"h-3 w-3\" />,\n });\n }\n if (deliveredShipment?.deliveredAt) {\n push(deliveredShipment.deliveredAt, {\n title: 'Delivered',\n meta: formatVolume(deliveredShipment.volume, deliveredShipment.unit),\n tone: 'success',\n icon: <CheckCircle2 className=\"h-3 w-3\" />,\n });\n }\n if (custodyCert) {\n push(custodyCert.issuedAt ?? custodyCert.createdAt, {\n title: certApproved ? 'Certificate approved' : 'Certificate registered',\n meta: custodyCert.certNumber ?? custodyCert.title,\n tone: certApproved ? 'success' : 'warning',\n icon: <ShieldCheck className=\"h-3 w-3\" />,\n });\n }\n\n return raw\n .sort((x, y) => new Date(x.date).getTime() - new Date(y.date).getTime())\n .map(({ date, item }) => ({ ...item, time: formatDate(date) }));\n }, [\n a,\n latestProduction,\n latestLot,\n primaryShipment,\n deliveredShipment,\n custodyCert,\n certApproved,\n shipmentRoute,\n ]);\n\n const originPoint =\n a && typeof a.latitude === 'number' && typeof a.longitude === 'number'\n ? { lat: a.latitude, lng: a.longitude, label: a.name, primary: true }\n : null;\n\n const description =\n 'Pit to port to certificate — end-to-end traceability from origin to verified certificate.';\n\n // ── Render ─────────────────────────────────────────────────────────────────\n if (assets.isLoading && assetRows.length === 0) {\n return (\n <PageLayout title=\"Provenance\" description={description}>\n <LoadingView label=\"Loading assets…\" />\n </PageLayout>\n );\n }\n if (assets.isError) {\n return (\n <PageLayout title=\"Provenance\" description={description}>\n <ErrorView message=\"Couldn't load assets to trace.\" onRetry={() => assets.refetch()} />\n </PageLayout>\n );\n }\n if (assetRows.length === 0) {\n return (\n <PageLayout title=\"Provenance\" description={description}>\n <EmptyState\n illustration=\"empty-data\"\n icon={<Link2 className=\"h-10 w-10\" />}\n title=\"No assets to trace\"\n description=\"Register a resource asset to build its end-to-end chain of custody.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('assets')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n Go to assets\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout title=\"Provenance\" description={description}>\n {/* Control bar: asset picker + trust state */}\n <GlassCard\n treatment=\"glass\"\n className=\"flex flex-col gap-4 p-5 sm:flex-row sm:items-center sm:justify-between\"\n >\n <div className=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n <label\n htmlFor=\"provenance-asset\"\n className=\"text-xs font-medium uppercase tracking-wide text-text-tertiary\"\n >\n Trace asset\n </label>\n <Select value={effectiveAssetId} onValueChange={setSelectedAssetId}>\n <SelectTrigger\n id=\"provenance-asset\"\n className=\"h-10 w-full sm:w-96\"\n aria-label=\"Select an asset to trace\"\n >\n <SelectValue placeholder=\"Select an asset to trace\" />\n </SelectTrigger>\n <SelectContent>\n {assetRows.map((row) => (\n <SelectItem key={row.id} value={row.id}>\n {row.name} · {formatEnumLabel(row.commodity)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div\n className={cn(\n 'flex items-center gap-2 self-start rounded-full px-3.5 py-1.5 text-sm font-medium',\n verified\n ? 'bg-status-success-bg-subtle text-status-success-text'\n : 'bg-bg-sunken text-text-secondary'\n )}\n >\n {verified ? <ShieldCheck className=\"h-4 w-4\" /> : <Shield className=\"h-4 w-4\" />}\n {verified ? 'Chain of custody verified' : `Traceability in progress · ${completeCount}/6`}\n </div>\n </GlassCard>\n\n {asset.isLoading ? (\n <div className=\"mt-6\">\n <LoadingView label=\"Assembling chain of custody…\" />\n </div>\n ) : asset.isError || !a ? (\n <div className=\"mt-6\">\n <ErrorView\n message=\"Couldn't load this asset's provenance.\"\n onRetry={() => asset.refetch()}\n />\n </div>\n ) : (\n <>\n {/* Flow ribbon */}\n <GlassCard treatment=\"glass\" className=\"mt-6 p-5\">\n <StepProgress steps={progressSteps} current={current} />\n </GlassCard>\n\n {/* Chain nodes */}\n <div className=\"mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6\">\n {nodes.map((node) => (\n <ChainNodeCard key={node.step} node={node} />\n ))}\n </div>\n\n {/* Timeline + origin */}\n <div className=\"mt-6 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n <GlassCard treatment=\"glass\" className=\"p-5 lg:col-span-2\">\n <div className=\"mb-4 flex items-center gap-2.5\">\n <span className=\"flex size-8 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent\">\n <Route className=\"h-4 w-4\" />\n </span>\n <div>\n <h2 className=\"text-base font-semibold text-text-primary\">\n Traceability timeline\n </h2>\n <p className=\"text-xs text-text-tertiary\">\n Recorded custody events, oldest to newest.\n </p>\n </div>\n </div>\n {timelineItems.length > 0 ? (\n <Timeline items={timelineItems} />\n ) : (\n <div className=\"rounded-xl border border-dashed border-border-seam py-8 text-center text-sm text-text-secondary\">\n No dated custody events yet.\n </div>\n )}\n </GlassCard>\n\n <GlassCard treatment=\"glass\" className=\"flex flex-col gap-4 p-5\">\n <div className=\"flex items-center gap-2.5\">\n <span className=\"flex size-8 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent\">\n <MapPin className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0\">\n <h2 className=\"text-base font-semibold text-text-primary\">Origin</h2>\n <p className=\"truncate text-xs text-text-tertiary\">\n {a.location ?? formatEnumLabel(a.kind)}\n </p>\n </div>\n </div>\n {originPoint ? (\n <WorldMap points={[originPoint]} />\n ) : (\n <div className=\"rounded-xl border border-dashed border-border-seam py-8 text-center text-sm text-text-secondary\">\n No coordinates recorded for this asset.\n </div>\n )}\n </GlassCard>\n </div>\n\n {/* Provenance summary */}\n <GlassCard treatment=\"glass\" className=\"mt-6 p-5\">\n <h2 className=\"mb-4 text-base font-semibold text-text-primary\">Provenance summary</h2>\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6\">\n <SummaryCell\n icon={<Fuel />}\n label=\"Commodity\"\n value={formatEnumLabel(a.commodity)}\n caption={formatEnumLabel(a.kind)}\n />\n <SummaryCell\n icon={<MapPin />}\n label=\"Origin\"\n value={a.location ?? a.name}\n caption={formatCoords(a.latitude, a.longitude)}\n />\n <SummaryCell\n icon={<Gauge />}\n label=\"Production\"\n value={`${formatNumber(productionRecords.length)} records`}\n caption={\n latestProduction\n ? `Latest ${formatVolume(latestProduction.volume, latestProduction.unit)}`\n : 'None yet'\n }\n />\n <SummaryCell\n icon={<Boxes />}\n label=\"Inventory\"\n value={`${formatNumber(assetLots.length)} lots`}\n caption={latestLot ? latestLot.lotCode : 'None yet'}\n />\n <SummaryCell\n icon={<Factory />}\n label=\"Emissions\"\n value={emissions.isError ? '—' : formatTonnesCo2e(totalTonnes)}\n caption={`${verifiedEmissions} verified`}\n />\n <SummaryCell\n icon={<ShieldCheck />}\n label=\"Certificates\"\n value={`${formatNumber(certRows.length)} tracked`}\n caption={\n certApproved ? 'Custody approved' : custodyCert ? 'Under review' : 'None yet'\n }\n />\n </div>\n </GlassCard>\n\n {/* Reserves footnote — surface proved reserves when present */}\n {(a.reserveEstimates?.length ?? 0) > 0 && (\n <p className=\"mt-4 flex items-center gap-1.5 text-xs text-text-tertiary\">\n <Layers className=\"h-3.5 w-3.5\" />\n {formatNumber(a.reserveEstimates?.length ?? 0)} reserve estimate\n {(a.reserveEstimates?.length ?? 0) === 1 ? '' : 's'} on record for this asset.\n </p>\n )}\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}