@burdenoff/microfe-theglobalfuel 2026.716.1 → 2026.720.1

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 (67) hide show
  1. package/dist/theglobalfuel/TheGlobalFuelRoutes.d.ts.map +1 -1
  2. package/dist/theglobalfuel/TheGlobalFuelRoutes.js +34 -22
  3. package/dist/theglobalfuel/TheGlobalFuelRoutes.js.map +1 -1
  4. package/dist/theglobalfuel/components/DataTable.js +1 -1
  5. package/dist/theglobalfuel/components/DataTable.js.map +1 -1
  6. package/dist/theglobalfuel/components/MiniBar.d.ts.map +1 -1
  7. package/dist/theglobalfuel/components/MiniBar.js +1 -1
  8. package/dist/theglobalfuel/components/MiniBar.js.map +1 -1
  9. package/dist/theglobalfuel/components/Tabs.js +1 -1
  10. package/dist/theglobalfuel/components/Tabs.js.map +1 -1
  11. package/dist/theglobalfuel/components/index.js +2 -0
  12. package/dist/theglobalfuel/components/viz/BarChart.js +83 -4
  13. package/dist/theglobalfuel/components/viz/BarChart.js.map +1 -0
  14. package/dist/theglobalfuel/components/viz/StatCard.js +60 -3
  15. package/dist/theglobalfuel/components/viz/StatCard.js.map +1 -0
  16. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts +10 -1
  17. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts.map +1 -1
  18. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js +1 -1
  19. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js.map +1 -1
  20. package/dist/theglobalfuel/pages/alerts/AlertsPage.d.ts +16 -0
  21. package/dist/theglobalfuel/pages/alerts/AlertsPage.d.ts.map +1 -0
  22. package/dist/theglobalfuel/pages/alerts/AlertsPage.js +295 -0
  23. package/dist/theglobalfuel/pages/alerts/AlertsPage.js.map +1 -0
  24. package/dist/theglobalfuel/pages/analytics/AnalyticsPage.d.ts +13 -0
  25. package/dist/theglobalfuel/pages/analytics/AnalyticsPage.d.ts.map +1 -0
  26. package/dist/theglobalfuel/pages/analytics/AnalyticsPage.js +358 -0
  27. package/dist/theglobalfuel/pages/analytics/AnalyticsPage.js.map +1 -0
  28. package/dist/theglobalfuel/pages/assets/AssetDetailPage.d.ts.map +1 -1
  29. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js +386 -342
  30. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js.map +1 -1
  31. package/dist/theglobalfuel/pages/assets/AssetsPage.d.ts.map +1 -1
  32. package/dist/theglobalfuel/pages/assets/AssetsPage.js +277 -199
  33. package/dist/theglobalfuel/pages/assets/AssetsPage.js.map +1 -1
  34. package/dist/theglobalfuel/pages/contracts/ContractsPage.js +1 -1
  35. package/dist/theglobalfuel/pages/contracts/ContractsPage.js.map +1 -1
  36. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js +6 -6
  37. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js.map +1 -1
  38. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js +1 -1
  39. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js.map +1 -1
  40. package/dist/theglobalfuel/pages/inventory/InventoryPage.js +1 -1
  41. package/dist/theglobalfuel/pages/inventory/InventoryPage.js.map +1 -1
  42. package/dist/theglobalfuel/pages/provenance/ProvenancePage.d.ts.map +1 -1
  43. package/dist/theglobalfuel/pages/provenance/ProvenancePage.js +372 -216
  44. package/dist/theglobalfuel/pages/provenance/ProvenancePage.js.map +1 -1
  45. package/dist/theglobalfuel/pages/reports/ReportsPage.d.ts +16 -0
  46. package/dist/theglobalfuel/pages/reports/ReportsPage.d.ts.map +1 -0
  47. package/dist/theglobalfuel/pages/reports/ReportsPage.js +578 -0
  48. package/dist/theglobalfuel/pages/reports/ReportsPage.js.map +1 -0
  49. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.d.ts.map +1 -1
  50. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js +43 -12
  51. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js.map +1 -1
  52. package/dist/theglobalfuel/types/index.d.ts +37 -0
  53. package/dist/theglobalfuel/types/index.d.ts.map +1 -1
  54. package/dist/theglobalfuel/utils/csv.d.ts +16 -0
  55. package/dist/theglobalfuel/utils/csv.d.ts.map +1 -0
  56. package/dist/theglobalfuel/utils/csv.js +14 -0
  57. package/dist/theglobalfuel/utils/csv.js.map +1 -0
  58. package/dist/theglobalfuel/utils/index.d.ts +2 -0
  59. package/dist/theglobalfuel/utils/index.d.ts.map +1 -1
  60. package/dist/theglobalfuel/utils/pageContext.d.ts.map +1 -1
  61. package/dist/theglobalfuel/utils/pageContext.js +32 -0
  62. package/dist/theglobalfuel/utils/pageContext.js.map +1 -1
  63. package/dist/theglobalfuel/utils/provenance.d.ts +135 -0
  64. package/dist/theglobalfuel/utils/provenance.d.ts.map +1 -0
  65. package/dist/theglobalfuel/utils/provenance.js +57 -0
  66. package/dist/theglobalfuel/utils/provenance.js.map +1 -0
  67. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TheGlobalFuelRoutes.d.ts","sourceRoot":"","sources":["../../src/theglobalfuel/TheGlobalFuelRoutes.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAkC,MAAM,OAAO,CAAC;AAuEhE,eAAO,MAAM,mBAAmB,EAAE,EA8DjC,CAAC"}
1
+ {"version":3,"file":"TheGlobalFuelRoutes.d.ts","sourceRoot":"","sources":["../../src/theglobalfuel/TheGlobalFuelRoutes.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAkC,MAAM,OAAO,CAAC;AAkFhE,eAAO,MAAM,mBAAmB,EAAE,EAoEjC,CAAC"}
@@ -6,11 +6,11 @@ import { Navigate as a, Route as o, Routes as s, useLocation as c } from "react-
6
6
  import { jsx as l, jsxs as u } from "react/jsx-runtime";
7
7
  import { Spinner as d } from "@burdenoff/fe-libs/ui";
8
8
  //#region src/theglobalfuel/TheGlobalFuelRoutes.tsx
9
- var f = r(() => import("./pages/assets/AssetsPage.js").then((e) => ({ default: e.AssetsPage }))), p = r(() => import("./pages/assets/AssetDetailPage.js").then((e) => ({ default: e.AssetDetailPage }))), m = r(() => import("./pages/production/ProductionPage.js").then((e) => ({ default: e.ProductionPage }))), h = r(() => import("./pages/reserves/ReservesPage.js").then((e) => ({ default: e.ReservesPage }))), g = r(() => import("./pages/contracts/ContractsPage.js").then((e) => ({ default: e.ContractsPage }))), _ = r(() => import("./pages/contracts/ContractDetailPage.js").then((e) => ({ default: e.ContractDetailPage }))), v = r(() => import("./pages/shipments/ShipmentsPage.js").then((e) => ({ default: e.ShipmentsPage }))), y = r(() => import("./pages/inventory/InventoryPage.js").then((e) => ({ default: e.InventoryPage }))), b = r(() => import("./pages/emissions/EmissionsPage.js").then((e) => ({ default: e.EmissionsPage }))), x = r(() => import("./pages/compliance/CompliancePage.js").then((e) => ({ default: e.CompliancePage }))), S = r(() => import("./pages/provenance/ProvenancePage.js").then((e) => ({ default: e.ProvenancePage }))), C = () => /* @__PURE__ */ l("div", {
9
+ var f = r(() => import("./pages/assets/AssetsPage.js").then((e) => ({ default: e.AssetsPage }))), p = r(() => import("./pages/assets/AssetDetailPage.js").then((e) => ({ default: e.AssetDetailPage }))), m = r(() => import("./pages/production/ProductionPage.js").then((e) => ({ default: e.ProductionPage }))), h = r(() => import("./pages/reserves/ReservesPage.js").then((e) => ({ default: e.ReservesPage }))), g = r(() => import("./pages/contracts/ContractsPage.js").then((e) => ({ default: e.ContractsPage }))), _ = r(() => import("./pages/contracts/ContractDetailPage.js").then((e) => ({ default: e.ContractDetailPage }))), v = r(() => import("./pages/shipments/ShipmentsPage.js").then((e) => ({ default: e.ShipmentsPage }))), y = r(() => import("./pages/inventory/InventoryPage.js").then((e) => ({ default: e.InventoryPage }))), b = r(() => import("./pages/emissions/EmissionsPage.js").then((e) => ({ default: e.EmissionsPage }))), x = r(() => import("./pages/compliance/CompliancePage.js").then((e) => ({ default: e.CompliancePage }))), S = r(() => import("./pages/provenance/ProvenancePage.js").then((e) => ({ default: e.ProvenancePage }))), C = r(() => import("./pages/analytics/AnalyticsPage.js").then((e) => ({ default: e.AnalyticsPage }))), w = r(() => import("./pages/reports/ReportsPage.js").then((e) => ({ default: e.ReportsPage }))), T = r(() => import("./pages/alerts/AlertsPage.js").then((e) => ({ default: e.AlertsPage }))), E = () => /* @__PURE__ */ l("div", {
10
10
  className: "flex min-h-[400px] items-center justify-center",
11
11
  children: /* @__PURE__ */ l(d, { size: "lg" })
12
12
  });
13
- function w() {
13
+ function D() {
14
14
  return /* @__PURE__ */ u("div", {
15
15
  className: "flex min-h-[400px] flex-col items-center justify-center gap-3 text-center p-6",
16
16
  children: [/* @__PURE__ */ l("p", {
@@ -22,73 +22,85 @@ function w() {
22
22
  })]
23
23
  });
24
24
  }
25
- function T(e, t) {
25
+ function O(e, t) {
26
26
  return /* @__PURE__ */ l(i, {
27
27
  flag: e,
28
28
  defaultValue: !0,
29
- fallback: /* @__PURE__ */ l(w, {}),
29
+ fallback: /* @__PURE__ */ l(D, {}),
30
30
  children: t
31
31
  });
32
32
  }
33
- var E = () => {
34
- let { basePath: r, isStandalone: i } = e(), d = c(), w = r === "/" ? "" : (r ?? "").replace(/\/$/, "");
35
- return w && !i && !(d.pathname === w || d.pathname.startsWith(w + "/")) ? null : /* @__PURE__ */ l("div", {
33
+ var k = () => {
34
+ let { basePath: r, isStandalone: i } = e(), d = c(), D = r === "/" ? "" : (r ?? "").replace(/\/$/, "");
35
+ return D && !i && !(d.pathname === D || d.pathname.startsWith(D + "/")) ? null : /* @__PURE__ */ l("div", {
36
36
  className: "flex min-h-full flex-col",
37
37
  children: /* @__PURE__ */ l(n, {
38
- fallback: /* @__PURE__ */ l(C, {}),
38
+ fallback: /* @__PURE__ */ l(E, {}),
39
39
  children: /* @__PURE__ */ u(s, { children: [
40
40
  /* @__PURE__ */ l(o, {
41
41
  index: !0,
42
- element: T("theglobalfuel.dashboard", /* @__PURE__ */ l(t, {}))
42
+ element: O("theglobalfuel.dashboard", /* @__PURE__ */ l(t, {}))
43
43
  }),
44
44
  /* @__PURE__ */ l(o, {
45
45
  path: "assets",
46
- element: T("theglobalfuel.assets", /* @__PURE__ */ l(f, {}))
46
+ element: O("theglobalfuel.assets", /* @__PURE__ */ l(f, {}))
47
47
  }),
48
48
  /* @__PURE__ */ l(o, {
49
49
  path: "assets/:id",
50
- element: T("theglobalfuel.assets", /* @__PURE__ */ l(p, {}))
50
+ element: O("theglobalfuel.assets", /* @__PURE__ */ l(p, {}))
51
51
  }),
52
52
  /* @__PURE__ */ l(o, {
53
53
  path: "production",
54
- element: T("theglobalfuel.production", /* @__PURE__ */ l(m, {}))
54
+ element: O("theglobalfuel.production", /* @__PURE__ */ l(m, {}))
55
55
  }),
56
56
  /* @__PURE__ */ l(o, {
57
57
  path: "reserves",
58
- element: T("theglobalfuel.reserves", /* @__PURE__ */ l(h, {}))
58
+ element: O("theglobalfuel.reserves", /* @__PURE__ */ l(h, {}))
59
59
  }),
60
60
  /* @__PURE__ */ l(o, {
61
61
  path: "contracts",
62
- element: T("theglobalfuel.contracts", /* @__PURE__ */ l(g, {}))
62
+ element: O("theglobalfuel.contracts", /* @__PURE__ */ l(g, {}))
63
63
  }),
64
64
  /* @__PURE__ */ l(o, {
65
65
  path: "contracts/:id",
66
- element: T("theglobalfuel.contracts", /* @__PURE__ */ l(_, {}))
66
+ element: O("theglobalfuel.contracts", /* @__PURE__ */ l(_, {}))
67
67
  }),
68
68
  /* @__PURE__ */ l(o, {
69
69
  path: "shipments",
70
- element: T("theglobalfuel.shipments", /* @__PURE__ */ l(v, {}))
70
+ element: O("theglobalfuel.shipments", /* @__PURE__ */ l(v, {}))
71
71
  }),
72
72
  /* @__PURE__ */ l(o, {
73
73
  path: "inventory",
74
- element: T("theglobalfuel.inventory", /* @__PURE__ */ l(y, {}))
74
+ element: O("theglobalfuel.inventory", /* @__PURE__ */ l(y, {}))
75
75
  }),
76
76
  /* @__PURE__ */ l(o, {
77
77
  path: "emissions",
78
- element: T("theglobalfuel.emissions", /* @__PURE__ */ l(b, {}))
78
+ element: O("theglobalfuel.emissions", /* @__PURE__ */ l(b, {}))
79
79
  }),
80
80
  /* @__PURE__ */ l(o, {
81
81
  path: "compliance",
82
- element: T("theglobalfuel.compliance", /* @__PURE__ */ l(x, {}))
82
+ element: O("theglobalfuel.compliance", /* @__PURE__ */ l(x, {}))
83
83
  }),
84
84
  /* @__PURE__ */ l(o, {
85
85
  path: "provenance",
86
- element: T("theglobalfuel.provenance", /* @__PURE__ */ l(S, {}))
86
+ element: O("theglobalfuel.provenance", /* @__PURE__ */ l(S, {}))
87
+ }),
88
+ /* @__PURE__ */ l(o, {
89
+ path: "analytics",
90
+ element: O("theglobalfuel.analytics", /* @__PURE__ */ l(C, {}))
91
+ }),
92
+ /* @__PURE__ */ l(o, {
93
+ path: "reports",
94
+ element: O("theglobalfuel.reports", /* @__PURE__ */ l(w, {}))
95
+ }),
96
+ /* @__PURE__ */ l(o, {
97
+ path: "alerts",
98
+ element: O("theglobalfuel.alerts", /* @__PURE__ */ l(T, {}))
87
99
  }),
88
100
  /* @__PURE__ */ l(o, {
89
101
  path: "*",
90
102
  element: /* @__PURE__ */ l(a, {
91
- to: w || "/",
103
+ to: D || "/",
92
104
  replace: !0
93
105
  })
94
106
  })
@@ -97,6 +109,6 @@ var E = () => {
97
109
  });
98
110
  };
99
111
  //#endregion
100
- export { E as TheGlobalFuelRoutes };
112
+ export { k as TheGlobalFuelRoutes };
101
113
 
102
114
  //# sourceMappingURL=TheGlobalFuelRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TheGlobalFuelRoutes.js","names":[],"sources":["../../src/theglobalfuel/TheGlobalFuelRoutes.tsx"],"sourcesContent":["/**\n * TheGlobalFuel Routes\n * @module theglobalfuel\n *\n * Domain routes. The dashboard is eager-loaded (primary landing); all other\n * pages are lazy-loaded. Every route maps to a real `the*` backend capability.\n */\n\nimport { type FC, lazy, Suspense, type ReactNode } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router-dom';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useTheGlobalFuel } from './context/TheGlobalFuelContext';\n\n// Eager — primary landing\nimport { DashboardPage } from './pages/dashboard/DashboardPage';\n\n// Registry — Assets, Production, Reserves\nconst AssetsPage = lazy(() =>\n import('./pages/assets/AssetsPage').then((m) => ({ default: m.AssetsPage }))\n);\nconst AssetDetailPage = lazy(() =>\n import('./pages/assets/AssetDetailPage').then((m) => ({ default: m.AssetDetailPage }))\n);\nconst ProductionPage = lazy(() =>\n import('./pages/production/ProductionPage').then((m) => ({ default: m.ProductionPage }))\n);\nconst ReservesPage = lazy(() =>\n import('./pages/reserves/ReservesPage').then((m) => ({ default: m.ReservesPage }))\n);\n\n// Commerce — Offtake Contracts, Shipments, Inventory\nconst ContractsPage = lazy(() =>\n import('./pages/contracts/ContractsPage').then((m) => ({ default: m.ContractsPage }))\n);\nconst ContractDetailPage = lazy(() =>\n import('./pages/contracts/ContractDetailPage').then((m) => ({ default: m.ContractDetailPage }))\n);\nconst ShipmentsPage = lazy(() =>\n import('./pages/shipments/ShipmentsPage').then((m) => ({ default: m.ShipmentsPage }))\n);\nconst InventoryPage = lazy(() =>\n import('./pages/inventory/InventoryPage').then((m) => ({ default: m.InventoryPage }))\n);\n\n// Sustainability — Emissions, Compliance\nconst EmissionsPage = lazy(() =>\n import('./pages/emissions/EmissionsPage').then((m) => ({ default: m.EmissionsPage }))\n);\nconst CompliancePage = lazy(() =>\n import('./pages/compliance/CompliancePage').then((m) => ({ default: m.CompliancePage }))\n);\nconst ProvenancePage = lazy(() =>\n import('./pages/provenance/ProvenancePage').then((m) => ({ default: m.ProvenancePage }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n);\n\nfunction FeatureDisabledFallback() {\n return (\n <div className=\"flex min-h-[400px] flex-col items-center justify-center gap-3 text-center p-6\">\n <p className=\"text-sm font-medium text-text-secondary\">This feature is not available.</p>\n <p className=\"text-xs text-text-tertiary\">Ask your workspace admin to enable it.</p>\n </div>\n );\n}\n\nfunction gated(flag: string, element: ReactNode): React.ReactElement {\n return (\n <FeatureGate flag={flag} defaultValue={true} fallback={<FeatureDisabledFallback />}>\n {element}\n </FeatureGate>\n );\n}\n\nexport const TheGlobalFuelRoutes: FC = () => {\n const { basePath, isStandalone } = useTheGlobalFuel();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n // Guard: only render if the current path matches basePath (integrated mode).\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={gated('theglobalfuel.dashboard', <DashboardPage />)} />\n\n <Route path=\"assets\" element={gated('theglobalfuel.assets', <AssetsPage />)} />\n <Route path=\"assets/:id\" element={gated('theglobalfuel.assets', <AssetDetailPage />)} />\n\n <Route\n path=\"production\"\n element={gated('theglobalfuel.production', <ProductionPage />)}\n />\n\n <Route path=\"reserves\" element={gated('theglobalfuel.reserves', <ReservesPage />)} />\n\n <Route path=\"contracts\" element={gated('theglobalfuel.contracts', <ContractsPage />)} />\n <Route\n path=\"contracts/:id\"\n element={gated('theglobalfuel.contracts', <ContractDetailPage />)}\n />\n\n <Route path=\"shipments\" element={gated('theglobalfuel.shipments', <ShipmentsPage />)} />\n\n <Route path=\"inventory\" element={gated('theglobalfuel.inventory', <InventoryPage />)} />\n\n <Route path=\"emissions\" element={gated('theglobalfuel.emissions', <EmissionsPage />)} />\n\n <Route\n path=\"compliance\"\n element={gated('theglobalfuel.compliance', <CompliancePage />)}\n />\n\n <Route\n path=\"provenance\"\n element={gated('theglobalfuel.provenance', <ProvenancePage />)}\n />\n\n {/* Unknown subpaths (e.g. /theglobalfuel/dashboard, stale bookmarks) canonicalize\n to the product root (the dashboard index). An absolute target avoids the\n self-referential `to=\"\"` loop that renders blank inside the nested Routes. */}\n <Route path=\"*\" element={<Navigate to={normalizedBasePath || '/'} replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"TheGlobalFuelRoutes.js","names":[],"sources":["../../src/theglobalfuel/TheGlobalFuelRoutes.tsx"],"sourcesContent":["/**\n * TheGlobalFuel Routes\n * @module theglobalfuel\n *\n * Domain routes. The dashboard is eager-loaded (primary landing); all other\n * pages are lazy-loaded. Every route maps to a real `the*` backend capability.\n */\n\nimport { type FC, lazy, Suspense, type ReactNode } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router-dom';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useTheGlobalFuel } from './context/TheGlobalFuelContext';\n\n// Eager — primary landing\nimport { DashboardPage } from './pages/dashboard/DashboardPage';\n\n// Registry — Assets, Production, Reserves\nconst AssetsPage = lazy(() =>\n import('./pages/assets/AssetsPage').then((m) => ({ default: m.AssetsPage }))\n);\nconst AssetDetailPage = lazy(() =>\n import('./pages/assets/AssetDetailPage').then((m) => ({ default: m.AssetDetailPage }))\n);\nconst ProductionPage = lazy(() =>\n import('./pages/production/ProductionPage').then((m) => ({ default: m.ProductionPage }))\n);\nconst ReservesPage = lazy(() =>\n import('./pages/reserves/ReservesPage').then((m) => ({ default: m.ReservesPage }))\n);\n\n// Commerce — Offtake Contracts, Shipments, Inventory\nconst ContractsPage = lazy(() =>\n import('./pages/contracts/ContractsPage').then((m) => ({ default: m.ContractsPage }))\n);\nconst ContractDetailPage = lazy(() =>\n import('./pages/contracts/ContractDetailPage').then((m) => ({ default: m.ContractDetailPage }))\n);\nconst ShipmentsPage = lazy(() =>\n import('./pages/shipments/ShipmentsPage').then((m) => ({ default: m.ShipmentsPage }))\n);\nconst InventoryPage = lazy(() =>\n import('./pages/inventory/InventoryPage').then((m) => ({ default: m.InventoryPage }))\n);\n\n// Sustainability — Emissions, Compliance\nconst EmissionsPage = lazy(() =>\n import('./pages/emissions/EmissionsPage').then((m) => ({ default: m.EmissionsPage }))\n);\nconst CompliancePage = lazy(() =>\n import('./pages/compliance/CompliancePage').then((m) => ({ default: m.CompliancePage }))\n);\nconst ProvenancePage = lazy(() =>\n import('./pages/provenance/ProvenancePage').then((m) => ({ default: m.ProvenancePage }))\n);\n\n// Cross-cutting operator surfaces — analytics, report extracts and exceptions.\nconst AnalyticsPage = lazy(() =>\n import('./pages/analytics/AnalyticsPage').then((m) => ({ default: m.AnalyticsPage }))\n);\nconst ReportsPage = lazy(() =>\n import('./pages/reports/ReportsPage').then((m) => ({ default: m.ReportsPage }))\n);\nconst AlertsPage = lazy(() =>\n import('./pages/alerts/AlertsPage').then((m) => ({ default: m.AlertsPage }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n);\n\nfunction FeatureDisabledFallback() {\n return (\n <div className=\"flex min-h-[400px] flex-col items-center justify-center gap-3 text-center p-6\">\n <p className=\"text-sm font-medium text-text-secondary\">This feature is not available.</p>\n <p className=\"text-xs text-text-tertiary\">Ask your workspace admin to enable it.</p>\n </div>\n );\n}\n\nfunction gated(flag: string, element: ReactNode): React.ReactElement {\n return (\n <FeatureGate flag={flag} defaultValue={true} fallback={<FeatureDisabledFallback />}>\n {element}\n </FeatureGate>\n );\n}\n\nexport const TheGlobalFuelRoutes: FC = () => {\n const { basePath, isStandalone } = useTheGlobalFuel();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n // Guard: only render if the current path matches basePath (integrated mode).\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={gated('theglobalfuel.dashboard', <DashboardPage />)} />\n\n <Route path=\"assets\" element={gated('theglobalfuel.assets', <AssetsPage />)} />\n <Route path=\"assets/:id\" element={gated('theglobalfuel.assets', <AssetDetailPage />)} />\n\n <Route\n path=\"production\"\n element={gated('theglobalfuel.production', <ProductionPage />)}\n />\n\n <Route path=\"reserves\" element={gated('theglobalfuel.reserves', <ReservesPage />)} />\n\n <Route path=\"contracts\" element={gated('theglobalfuel.contracts', <ContractsPage />)} />\n <Route\n path=\"contracts/:id\"\n element={gated('theglobalfuel.contracts', <ContractDetailPage />)}\n />\n\n <Route path=\"shipments\" element={gated('theglobalfuel.shipments', <ShipmentsPage />)} />\n\n <Route path=\"inventory\" element={gated('theglobalfuel.inventory', <InventoryPage />)} />\n\n <Route path=\"emissions\" element={gated('theglobalfuel.emissions', <EmissionsPage />)} />\n\n <Route\n path=\"compliance\"\n element={gated('theglobalfuel.compliance', <CompliancePage />)}\n />\n\n <Route\n path=\"provenance\"\n element={gated('theglobalfuel.provenance', <ProvenancePage />)}\n />\n\n <Route path=\"analytics\" element={gated('theglobalfuel.analytics', <AnalyticsPage />)} />\n\n <Route path=\"reports\" element={gated('theglobalfuel.reports', <ReportsPage />)} />\n\n <Route path=\"alerts\" element={gated('theglobalfuel.alerts', <AlertsPage />)} />\n\n {/* Unknown subpaths (e.g. /theglobalfuel/dashboard, stale bookmarks) canonicalize\n to the product root (the dashboard index). An absolute target avoids the\n self-referential `to=\"\"` loop that renders blank inside the nested Routes. */}\n <Route path=\"*\" element={<Navigate to={normalizedBasePath || '/'} replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -66,7 +66,7 @@ function p({ columns: p, rows: m, rowKey: h, onRowClick: g, rowLabel: _, classNa
66
66
  className: e("px-4 py-3 font-medium text-text-secondary whitespace-nowrap", f[t.align ?? "left"], t.hideOnMobile && "hidden md:table-cell", n && "cursor-pointer select-none hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]"),
67
67
  children: /* @__PURE__ */ l("span", {
68
68
  className: e("inline-flex items-center gap-1", t.align === "right" && "flex-row-reverse"),
69
- children: [t.header, n && (r ? b?.dir === "asc" ? /* @__PURE__ */ c(o, { className: "h-3.5 w-3.5 text-accent" }) : /* @__PURE__ */ c(i, { className: "h-3.5 w-3.5 text-accent" }) : /* @__PURE__ */ c(s, { className: "h-3.5 w-3.5 opacity-40" }))]
69
+ children: [t.header, n && (r ? b?.dir === "asc" ? /* @__PURE__ */ c(o, { className: "h-3.5 w-3.5 text-action-primary-bg" }) : /* @__PURE__ */ c(i, { className: "h-3.5 w-3.5 text-action-primary-bg" }) : /* @__PURE__ */ c(s, { className: "h-3.5 w-3.5 opacity-40" }))]
70
70
  })
71
71
  }, t.key);
72
72
  })
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.js","names":[],"sources":["../../../src/theglobalfuel/components/DataTable.tsx"],"sourcesContent":["/**\n * DataTable — a lightweight, semantic-token table for list pages.\n * @module theglobalfuel/components\n *\n * Deliberately minimal (no external table lib). Columns declare a header, a\n * render fn, optional alignment, and optionally a `sortValue` to make the column\n * click-sortable.\n *\n * Responsive strategy:\n * - At `md` and up it renders a horizontally-scrollable table wrapped in a\n * GlassCard (the classic desktop layout).\n * - Below `md` it renders each row as a native-feeling, stacked \"card\": the\n * first column becomes the card's headline (with a chevron affordance when\n * the row is clickable) and the remaining columns render as label→value\n * pairs. Sort + click behavior carry over, so every list page is usable on\n * mobile with zero page-level changes.\n */\n\nimport { useId, useMemo, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport { ChevronUp, ChevronDown, ChevronsUpDown, ChevronRight } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\n\nexport interface Column<T> {\n key: string;\n header: ReactNode;\n render: (row: T) => ReactNode;\n align?: 'left' | 'right' | 'center';\n className?: string;\n /** Hide below the `md` breakpoint for a mobile-friendly layout. */\n hideOnMobile?: boolean;\n /** Provide to make this column click-sortable (returns a comparable value). */\n sortValue?: (row: T) => string | number;\n}\n\ninterface DataTableProps<T> {\n columns: Column<T>[];\n rows: T[];\n rowKey: (row: T) => string;\n onRowClick?: (row: T) => void;\n /** Accessible label for a clickable row (e.g. `(a) => `Open ${a.name}``). */\n rowLabel?: (row: T) => string;\n className?: string;\n /** Default sort: a column key + direction. */\n defaultSort?: { key: string; dir: 'asc' | 'desc' };\n}\n\n/** Enter/Space activate — only when the event originates on the element itself\n * (not on an interactive descendant like a Select or Button inside a cell). */\nconst activateOnKey = (e: KeyboardEvent, fn: () => void) => {\n if (e.target !== e.currentTarget) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n fn();\n }\n};\n\nconst alignClass = {\n left: 'text-left',\n right: 'text-right',\n center: 'text-center',\n} as const;\n\ntype Sort = { key: string; dir: 'asc' | 'desc' };\n\nexport function DataTable<T>({\n columns,\n rows,\n rowKey,\n onRowClick,\n rowLabel,\n className,\n defaultSort,\n}: DataTableProps<T>) {\n const [sort, setSort] = useState<Sort | null>(defaultSort ?? null);\n const sortSelectId = useId();\n\n const sortedRows = useMemo(() => {\n if (!sort) return rows;\n const col = columns.find((c) => c.key === sort.key);\n if (!col?.sortValue) return rows;\n const dir = sort.dir === 'asc' ? 1 : -1;\n return [...rows].sort((a, b) => {\n const va = col.sortValue!(a);\n const vb = col.sortValue!(b);\n if (va < vb) return -1 * dir;\n if (va > vb) return 1 * dir;\n return 0;\n });\n }, [rows, sort, columns]);\n\n const toggleSort = (key: string) => {\n setSort((prev) =>\n prev?.key === key ? { key, dir: prev.dir === 'asc' ? 'desc' : 'asc' } : { key, dir: 'asc' }\n );\n };\n\n const flipDir = () =>\n setSort((prev) => (prev ? { key: prev.key, dir: prev.dir === 'asc' ? 'desc' : 'asc' } : prev));\n\n const sortableColumns = useMemo(() => columns.filter((c) => c.sortValue), [columns]);\n\n const rowInteractive = (row: T) =>\n onRowClick\n ? {\n role: 'button' as const,\n tabIndex: 0,\n 'aria-label': rowLabel?.(row),\n onClick: () => onRowClick(row),\n onKeyDown: (e: KeyboardEvent) => activateOnKey(e, () => onRowClick(row)),\n }\n : {};\n\n const [headCol, ...restCols] = columns;\n\n return (\n <div className={className}>\n {/* ── md and up: full table ─────────────────────────────────────── */}\n <GlassCard treatment=\"plain\" className=\"hidden overflow-hidden md:block\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full border-collapse text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam\">\n {columns.map((col) => {\n const sortable = Boolean(col.sortValue);\n const active = sort?.key === col.key;\n return (\n <th\n key={col.key}\n scope=\"col\"\n role={sortable ? 'button' : undefined}\n tabIndex={sortable ? 0 : undefined}\n onClick={sortable ? () => toggleSort(col.key) : undefined}\n onKeyDown={\n sortable ? (e) => activateOnKey(e, () => toggleSort(col.key)) : undefined\n }\n aria-sort={\n active ? (sort?.dir === 'asc' ? 'ascending' : 'descending') : undefined\n }\n className={cn(\n 'px-4 py-3 font-medium text-text-secondary whitespace-nowrap',\n alignClass[col.align ?? 'left'],\n col.hideOnMobile && 'hidden md:table-cell',\n sortable &&\n 'cursor-pointer select-none hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n <span\n className={cn(\n 'inline-flex items-center gap-1',\n col.align === 'right' && 'flex-row-reverse'\n )}\n >\n {col.header}\n {sortable &&\n (active ? (\n sort?.dir === 'asc' ? (\n <ChevronUp className=\"h-3.5 w-3.5 text-accent\" />\n ) : (\n <ChevronDown className=\"h-3.5 w-3.5 text-accent\" />\n )\n ) : (\n <ChevronsUpDown className=\"h-3.5 w-3.5 opacity-40\" />\n ))}\n </span>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {sortedRows.map((row) => (\n <tr\n key={rowKey(row)}\n {...rowInteractive(row)}\n className={cn(\n 'group border-b border-border-seam/60 last:border-0',\n onRowClick &&\n 'cursor-pointer transition-colors hover:bg-bg-sunken/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n {columns.map((col) => (\n <td\n key={col.key}\n className={cn(\n 'px-4 py-3 text-text-primary align-middle',\n alignClass[col.align ?? 'left'],\n col.hideOnMobile && 'hidden md:table-cell',\n col.className\n )}\n >\n {col.render(row)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </GlassCard>\n\n {/* ── below md: stacked cards ───────────────────────────────────── */}\n <div className=\"space-y-2.5 md:hidden\">\n {sortableColumns.length > 0 && (\n <div className=\"flex items-center justify-end gap-1.5 px-0.5\">\n <label htmlFor={sortSelectId} className=\"text-xs text-text-tertiary\">\n Sort\n </label>\n <select\n id={sortSelectId}\n value={sort?.key ?? ''}\n onChange={(e) =>\n setSort(e.target.value ? { key: e.target.value, dir: sort?.dir ?? 'asc' } : null)\n }\n className=\"rounded-md border border-border-subtle bg-bg-surface px-2 py-1 text-xs text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Default order</option>\n {sortableColumns.map((col) => (\n <option key={col.key} value={col.key}>\n {typeof col.header === 'string' ? col.header : col.key}\n </option>\n ))}\n </select>\n {sort && (\n <button\n type=\"button\"\n onClick={flipDir}\n aria-label={sort.dir === 'asc' ? 'Sort ascending' : 'Sort descending'}\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border-subtle bg-bg-surface text-text-secondary transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n {sort.dir === 'asc' ? (\n <ChevronUp className=\"h-4 w-4\" />\n ) : (\n <ChevronDown className=\"h-4 w-4\" />\n )}\n </button>\n )}\n </div>\n )}\n\n {sortedRows.map((row) => (\n <div\n key={rowKey(row)}\n {...rowInteractive(row)}\n className={cn(\n 'rounded-xl border border-border-subtle bg-bg-surface p-4',\n onRowClick &&\n 'cursor-pointer transition-colors hover:bg-bg-sunken/40 active:bg-bg-sunken/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n {headCol && (\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1\">{headCol.render(row)}</div>\n {onRowClick && (\n <ChevronRight\n className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\"\n aria-hidden\n />\n )}\n </div>\n )}\n {restCols.length > 0 && (\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-2.5 border-t border-border-subtle/70 pt-3\">\n {restCols.map((col) => (\n <div key={col.key} className=\"min-w-0\">\n <dt className=\"text-[11px] uppercase tracking-wide text-text-tertiary\">\n {col.header}\n </dt>\n <dd className=\"mt-0.5 text-sm text-text-primary break-words\">\n {col.render(row)}\n </dd>\n </div>\n ))}\n </dl>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DataTable.js","names":[],"sources":["../../../src/theglobalfuel/components/DataTable.tsx"],"sourcesContent":["/**\n * DataTable — a lightweight, semantic-token table for list pages.\n * @module theglobalfuel/components\n *\n * Deliberately minimal (no external table lib). Columns declare a header, a\n * render fn, optional alignment, and optionally a `sortValue` to make the column\n * click-sortable.\n *\n * Responsive strategy:\n * - At `md` and up it renders a horizontally-scrollable table wrapped in a\n * GlassCard (the classic desktop layout).\n * - Below `md` it renders each row as a native-feeling, stacked \"card\": the\n * first column becomes the card's headline (with a chevron affordance when\n * the row is clickable) and the remaining columns render as label→value\n * pairs. Sort + click behavior carry over, so every list page is usable on\n * mobile with zero page-level changes.\n */\n\nimport { useId, useMemo, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport { ChevronUp, ChevronDown, ChevronsUpDown, ChevronRight } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\n\nexport interface Column<T> {\n key: string;\n header: ReactNode;\n render: (row: T) => ReactNode;\n align?: 'left' | 'right' | 'center';\n className?: string;\n /** Hide below the `md` breakpoint for a mobile-friendly layout. */\n hideOnMobile?: boolean;\n /** Provide to make this column click-sortable (returns a comparable value). */\n sortValue?: (row: T) => string | number;\n}\n\ninterface DataTableProps<T> {\n columns: Column<T>[];\n rows: T[];\n rowKey: (row: T) => string;\n onRowClick?: (row: T) => void;\n /** Accessible label for a clickable row (e.g. `(a) => `Open ${a.name}``). */\n rowLabel?: (row: T) => string;\n className?: string;\n /** Default sort: a column key + direction. */\n defaultSort?: { key: string; dir: 'asc' | 'desc' };\n}\n\n/** Enter/Space activate — only when the event originates on the element itself\n * (not on an interactive descendant like a Select or Button inside a cell). */\nconst activateOnKey = (e: KeyboardEvent, fn: () => void) => {\n if (e.target !== e.currentTarget) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n fn();\n }\n};\n\nconst alignClass = {\n left: 'text-left',\n right: 'text-right',\n center: 'text-center',\n} as const;\n\ntype Sort = { key: string; dir: 'asc' | 'desc' };\n\nexport function DataTable<T>({\n columns,\n rows,\n rowKey,\n onRowClick,\n rowLabel,\n className,\n defaultSort,\n}: DataTableProps<T>) {\n const [sort, setSort] = useState<Sort | null>(defaultSort ?? null);\n const sortSelectId = useId();\n\n const sortedRows = useMemo(() => {\n if (!sort) return rows;\n const col = columns.find((c) => c.key === sort.key);\n if (!col?.sortValue) return rows;\n const dir = sort.dir === 'asc' ? 1 : -1;\n return [...rows].sort((a, b) => {\n const va = col.sortValue!(a);\n const vb = col.sortValue!(b);\n if (va < vb) return -1 * dir;\n if (va > vb) return 1 * dir;\n return 0;\n });\n }, [rows, sort, columns]);\n\n const toggleSort = (key: string) => {\n setSort((prev) =>\n prev?.key === key ? { key, dir: prev.dir === 'asc' ? 'desc' : 'asc' } : { key, dir: 'asc' }\n );\n };\n\n const flipDir = () =>\n setSort((prev) => (prev ? { key: prev.key, dir: prev.dir === 'asc' ? 'desc' : 'asc' } : prev));\n\n const sortableColumns = useMemo(() => columns.filter((c) => c.sortValue), [columns]);\n\n const rowInteractive = (row: T) =>\n onRowClick\n ? {\n role: 'button' as const,\n tabIndex: 0,\n 'aria-label': rowLabel?.(row),\n onClick: () => onRowClick(row),\n onKeyDown: (e: KeyboardEvent) => activateOnKey(e, () => onRowClick(row)),\n }\n : {};\n\n const [headCol, ...restCols] = columns;\n\n return (\n <div className={className}>\n {/* ── md and up: full table ─────────────────────────────────────── */}\n <GlassCard treatment=\"plain\" className=\"hidden overflow-hidden md:block\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full border-collapse text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam\">\n {columns.map((col) => {\n const sortable = Boolean(col.sortValue);\n const active = sort?.key === col.key;\n return (\n <th\n key={col.key}\n scope=\"col\"\n role={sortable ? 'button' : undefined}\n tabIndex={sortable ? 0 : undefined}\n onClick={sortable ? () => toggleSort(col.key) : undefined}\n onKeyDown={\n sortable ? (e) => activateOnKey(e, () => toggleSort(col.key)) : undefined\n }\n aria-sort={\n active ? (sort?.dir === 'asc' ? 'ascending' : 'descending') : undefined\n }\n className={cn(\n 'px-4 py-3 font-medium text-text-secondary whitespace-nowrap',\n alignClass[col.align ?? 'left'],\n col.hideOnMobile && 'hidden md:table-cell',\n sortable &&\n 'cursor-pointer select-none hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n <span\n className={cn(\n 'inline-flex items-center gap-1',\n col.align === 'right' && 'flex-row-reverse'\n )}\n >\n {col.header}\n {sortable &&\n (active ? (\n sort?.dir === 'asc' ? (\n <ChevronUp className=\"h-3.5 w-3.5 text-action-primary-bg\" />\n ) : (\n <ChevronDown className=\"h-3.5 w-3.5 text-action-primary-bg\" />\n )\n ) : (\n <ChevronsUpDown className=\"h-3.5 w-3.5 opacity-40\" />\n ))}\n </span>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {sortedRows.map((row) => (\n <tr\n key={rowKey(row)}\n {...rowInteractive(row)}\n className={cn(\n 'group border-b border-border-seam/60 last:border-0',\n onRowClick &&\n 'cursor-pointer transition-colors hover:bg-bg-sunken/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n {columns.map((col) => (\n <td\n key={col.key}\n className={cn(\n 'px-4 py-3 text-text-primary align-middle',\n alignClass[col.align ?? 'left'],\n col.hideOnMobile && 'hidden md:table-cell',\n col.className\n )}\n >\n {col.render(row)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </GlassCard>\n\n {/* ── below md: stacked cards ───────────────────────────────────── */}\n <div className=\"space-y-2.5 md:hidden\">\n {sortableColumns.length > 0 && (\n <div className=\"flex items-center justify-end gap-1.5 px-0.5\">\n <label htmlFor={sortSelectId} className=\"text-xs text-text-tertiary\">\n Sort\n </label>\n <select\n id={sortSelectId}\n value={sort?.key ?? ''}\n onChange={(e) =>\n setSort(e.target.value ? { key: e.target.value, dir: sort?.dir ?? 'asc' } : null)\n }\n className=\"rounded-md border border-border-subtle bg-bg-surface px-2 py-1 text-xs text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Default order</option>\n {sortableColumns.map((col) => (\n <option key={col.key} value={col.key}>\n {typeof col.header === 'string' ? col.header : col.key}\n </option>\n ))}\n </select>\n {sort && (\n <button\n type=\"button\"\n onClick={flipDir}\n aria-label={sort.dir === 'asc' ? 'Sort ascending' : 'Sort descending'}\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border-subtle bg-bg-surface text-text-secondary transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n {sort.dir === 'asc' ? (\n <ChevronUp className=\"h-4 w-4\" />\n ) : (\n <ChevronDown className=\"h-4 w-4\" />\n )}\n </button>\n )}\n </div>\n )}\n\n {sortedRows.map((row) => (\n <div\n key={rowKey(row)}\n {...rowInteractive(row)}\n className={cn(\n 'rounded-xl border border-border-subtle bg-bg-surface p-4',\n onRowClick &&\n 'cursor-pointer transition-colors hover:bg-bg-sunken/40 active:bg-bg-sunken/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n {headCol && (\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1\">{headCol.render(row)}</div>\n {onRowClick && (\n <ChevronRight\n className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\"\n aria-hidden\n />\n )}\n </div>\n )}\n {restCols.length > 0 && (\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-2.5 border-t border-border-subtle/70 pt-3\">\n {restCols.map((col) => (\n <div key={col.key} className=\"min-w-0\">\n <dt className=\"text-[11px] uppercase tracking-wide text-text-tertiary\">\n {col.header}\n </dt>\n <dd className=\"mt-0.5 text-sm text-text-primary break-words\">\n {col.render(row)}\n </dd>\n </div>\n ))}\n </dl>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MiniBar.d.ts","sourceRoot":"","sources":["../../../src/theglobalfuel/components/MiniBar.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,UAAU,YAAY;IACpB,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,SAAS,EACT,YAA0B,EAC1B,MAAU,GACX,EAAE,YAAY,+BAiBd"}
1
+ {"version":3,"file":"MiniBar.d.ts","sourceRoot":"","sources":["../../../src/theglobalfuel/components/MiniBar.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,UAAU,YAAY;IACpB,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,SAAS,EACT,YAAqC,EACrC,MAAU,GACX,EAAE,YAAY,+BAiBd"}
@@ -1,7 +1,7 @@
1
1
  import { cn as e } from "../utils/cn.js";
2
2
  import { jsx as t } from "react/jsx-runtime";
3
3
  //#region src/theglobalfuel/components/MiniBar.tsx
4
- function n({ value: n, className: r, barClassName: i = "bg-accent", height: a = 6 }) {
4
+ function n({ value: n, className: r, barClassName: i = "bg-action-primary-bg", height: a = 6 }) {
5
5
  let o = Math.max(0, Math.min(100, n));
6
6
  return /* @__PURE__ */ t("div", {
7
7
  className: e("w-full overflow-hidden rounded-full bg-bg-sunken", r),
@@ -1 +1 @@
1
- {"version":3,"file":"MiniBar.js","names":[],"sources":["../../../src/theglobalfuel/components/MiniBar.tsx"],"sourcesContent":["/**\n * MiniBar — a thin inline progress bar (target progress, completion, breach %).\n * @module theglobalfuel/components\n */\n\nimport { cn } from '../utils/cn';\n\ninterface MiniBarProps {\n /** 0–100. */\n value: number;\n className?: string;\n /** Bar fill token class (defaults to accent). */\n barClassName?: string;\n /** Height in px. */\n height?: number;\n}\n\nexport function MiniBar({\n value,\n className,\n barClassName = 'bg-accent',\n height = 6,\n}: MiniBarProps) {\n const clamped = Math.max(0, Math.min(100, value));\n return (\n <div\n className={cn('w-full overflow-hidden rounded-full bg-bg-sunken', className)}\n style={{ height }}\n role=\"progressbar\"\n aria-valuenow={Math.round(clamped)}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div\n className={cn('h-full rounded-full transition-[width] duration-700 ease-out', barClassName)}\n style={{ width: `${clamped}%` }}\n />\n </div>\n );\n}\n"],"mappings":";;;AAiBA,SAAgB,EAAQ,EACtB,UACA,cACA,kBAAe,aACf,YAAS,KACM;CACf,IAAM,IAAU,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,EAAM,CAAC;AACjD,QACE,kBAAC,OAAD;EACE,WAAW,EAAG,oDAAoD,EAAU;EAC5E,OAAO,EAAE,WAAQ;EACjB,MAAK;EACL,iBAAe,KAAK,MAAM,EAAQ;EAClC,iBAAe;EACf,iBAAe;YAEf,kBAAC,OAAD;GACE,WAAW,EAAG,gEAAgE,EAAa;GAC3F,OAAO,EAAE,OAAO,GAAG,EAAQ,IAAI;GAC/B,CAAA;EACE,CAAA"}
1
+ {"version":3,"file":"MiniBar.js","names":[],"sources":["../../../src/theglobalfuel/components/MiniBar.tsx"],"sourcesContent":["/**\n * MiniBar — a thin inline progress bar (target progress, completion, breach %).\n * @module theglobalfuel/components\n */\n\nimport { cn } from '../utils/cn';\n\ninterface MiniBarProps {\n /** 0–100. */\n value: number;\n className?: string;\n /** Bar fill token class (defaults to accent). */\n barClassName?: string;\n /** Height in px. */\n height?: number;\n}\n\nexport function MiniBar({\n value,\n className,\n barClassName = 'bg-action-primary-bg',\n height = 6,\n}: MiniBarProps) {\n const clamped = Math.max(0, Math.min(100, value));\n return (\n <div\n className={cn('w-full overflow-hidden rounded-full bg-bg-sunken', className)}\n style={{ height }}\n role=\"progressbar\"\n aria-valuenow={Math.round(clamped)}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div\n className={cn('h-full rounded-full transition-[width] duration-700 ease-out', barClassName)}\n style={{ width: `${clamped}%` }}\n />\n </div>\n );\n}\n"],"mappings":";;;AAiBA,SAAgB,EAAQ,EACtB,UACA,cACA,kBAAe,wBACf,YAAS,KACM;CACf,IAAM,IAAU,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,EAAM,CAAC;AACjD,QACE,kBAAC,OAAD;EACE,WAAW,EAAG,oDAAoD,EAAU;EAC5E,OAAO,EAAE,WAAQ;EACjB,MAAK;EACL,iBAAe,KAAK,MAAM,EAAQ;EAClC,iBAAe;EACf,iBAAe;YAEf,kBAAC,OAAD;GACE,WAAW,EAAG,gEAAgE,EAAa;GAC3F,OAAO,EAAE,OAAO,GAAG,EAAQ,IAAI;GAC/B,CAAA;EACE,CAAA"}
@@ -12,7 +12,7 @@ function r({ items: r, value: i, onChange: a, className: o }) {
12
12
  role: "tab",
13
13
  "aria-selected": o,
14
14
  onClick: () => a(r.value),
15
- className: e("relative -mb-px inline-flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-medium transition-colors", o ? "border-accent text-text-primary" : "border-transparent text-text-secondary hover:text-text-primary"),
15
+ className: e("relative -mb-px inline-flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-medium transition-colors", o ? "border-action-primary-bg text-text-primary" : "border-transparent text-text-secondary hover:text-text-primary"),
16
16
  children: [
17
17
  r.icon,
18
18
  r.label,
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.js","names":[],"sources":["../../../src/theglobalfuel/components/Tabs.tsx"],"sourcesContent":["/**\n * Tabs — a top-level segmented navigation control for multi-section pages\n * (Monitoring: Sensors/Measurements/Thresholds; Carbon: Ledger/Factors/Targets).\n * @module theglobalfuel/components\n *\n * Visually heavier than {@link FilterTabs} (underline-style page tabs vs a pill\n * filter). Purely presentational — the parent owns the active-tab state.\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn';\n\nexport interface TabItem<V extends string> {\n value: V;\n label: string;\n icon?: ReactNode;\n count?: number;\n}\n\ninterface TabsProps<V extends string> {\n items: TabItem<V>[];\n value: V;\n onChange: (value: V) => void;\n className?: string;\n}\n\nexport function Tabs<V extends string>({ items, value, onChange, className }: TabsProps<V>) {\n return (\n <div\n role=\"tablist\"\n className={cn('flex flex-wrap items-center gap-1 border-b border-border-seam', className)}\n >\n {items.map((item) => {\n const active = item.value === value;\n return (\n <button\n key={item.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => onChange(item.value)}\n className={cn(\n 'relative -mb-px inline-flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-medium transition-colors',\n active\n ? 'border-accent text-text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n )}\n >\n {item.icon}\n {item.label}\n {typeof item.count === 'number' && (\n <span\n className={cn(\n 'rounded-full px-1.5 py-0.5 text-xs tabular-nums',\n active\n ? 'bg-[var(--color-accent-soft)] text-text-primary'\n : 'bg-bg-sunken text-text-secondary'\n )}\n >\n {item.count}\n </span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;AA0BA,SAAgB,EAAuB,EAAE,UAAO,UAAO,aAAU,gBAA2B;AAC1F,QACE,kBAAC,OAAD;EACE,MAAK;EACL,WAAW,EAAG,iEAAiE,EAAU;YAExF,EAAM,KAAK,MAAS;GACnB,IAAM,IAAS,EAAK,UAAU;AAC9B,UACE,kBAAC,UAAD;IAEE,MAAK;IACL,MAAK;IACL,iBAAe;IACf,eAAe,EAAS,EAAK,MAAM;IACnC,WAAW,EACT,+GACA,IACI,oCACA,iEACL;cAXH;KAaG,EAAK;KACL,EAAK;KACL,OAAO,EAAK,SAAU,YACrB,kBAAC,QAAD;MACE,WAAW,EACT,mDACA,IACI,oDACA,mCACL;gBAEA,EAAK;MACD,CAAA;KAEF;MA1BF,EAAK,MA0BH;IAEX;EACE,CAAA"}
1
+ {"version":3,"file":"Tabs.js","names":[],"sources":["../../../src/theglobalfuel/components/Tabs.tsx"],"sourcesContent":["/**\n * Tabs — a top-level segmented navigation control for multi-section pages\n * (Monitoring: Sensors/Measurements/Thresholds; Carbon: Ledger/Factors/Targets).\n * @module theglobalfuel/components\n *\n * Visually heavier than {@link FilterTabs} (underline-style page tabs vs a pill\n * filter). Purely presentational — the parent owns the active-tab state.\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn';\n\nexport interface TabItem<V extends string> {\n value: V;\n label: string;\n icon?: ReactNode;\n count?: number;\n}\n\ninterface TabsProps<V extends string> {\n items: TabItem<V>[];\n value: V;\n onChange: (value: V) => void;\n className?: string;\n}\n\nexport function Tabs<V extends string>({ items, value, onChange, className }: TabsProps<V>) {\n return (\n <div\n role=\"tablist\"\n className={cn('flex flex-wrap items-center gap-1 border-b border-border-seam', className)}\n >\n {items.map((item) => {\n const active = item.value === value;\n return (\n <button\n key={item.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => onChange(item.value)}\n className={cn(\n 'relative -mb-px inline-flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-medium transition-colors',\n active\n ? 'border-action-primary-bg text-text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n )}\n >\n {item.icon}\n {item.label}\n {typeof item.count === 'number' && (\n <span\n className={cn(\n 'rounded-full px-1.5 py-0.5 text-xs tabular-nums',\n active\n ? 'bg-[var(--color-accent-soft)] text-text-primary'\n : 'bg-bg-sunken text-text-secondary'\n )}\n >\n {item.count}\n </span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;AA0BA,SAAgB,EAAuB,EAAE,UAAO,UAAO,aAAU,gBAA2B;AAC1F,QACE,kBAAC,OAAD;EACE,MAAK;EACL,WAAW,EAAG,iEAAiE,EAAU;YAExF,EAAM,KAAK,MAAS;GACnB,IAAM,IAAS,EAAK,UAAU;AAC9B,UACE,kBAAC,UAAD;IAEE,MAAK;IACL,MAAK;IACL,iBAAe;IACf,eAAe,EAAS,EAAK,MAAM;IACnC,WAAW,EACT,+GACA,IACI,+CACA,iEACL;cAXH;KAaG,EAAK;KACL,EAAK;KACL,OAAO,EAAK,SAAU,YACrB,kBAAC,QAAD;MACE,WAAW,EACT,mDACA,IACI,oDACA,mCACL;gBAEA,EAAK;MACD,CAAA;KAEF;MA1BF,EAAK,MA0BH;IAEX;EACE,CAAA"}
@@ -7,7 +7,9 @@ import "./StateViews.js";
7
7
  import "./EmptyState.js";
8
8
  import "./viz/Sparkline.js";
9
9
  import "./viz/AreaChart.js";
10
+ import "./viz/BarChart.js";
10
11
  import "./viz/DonutChart.js";
12
+ import "./viz/StatCard.js";
11
13
  import "./viz/Timeline.js";
12
14
  import "./viz/AllocationBar.js";
13
15
  import "./viz/StepProgress.js";
@@ -1,4 +1,83 @@
1
- import "./lib/palette.js";
2
- import "./lib/hooks.js";
3
- import "./lib/ResponsiveSvg.js";
4
- import "react/jsx-runtime";
1
+ import { chartPalette as e } from "./lib/palette.js";
2
+ import { useMounted as t, usePrefersReducedMotion as n } from "./lib/hooks.js";
3
+ import { ResponsiveSvg as r } from "./lib/ResponsiveSvg.js";
4
+ import { scaleLinear as i } from "./lib/geometry.js";
5
+ import { formatCompact as a } from "./lib/format.js";
6
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
+ //#region src/theglobalfuel/components/viz/BarChart.tsx
8
+ var c = {
9
+ top: 20,
10
+ bottom: 26,
11
+ left: 8,
12
+ right: 8
13
+ };
14
+ function l({ series: l, height: u = 220, valueFormatter: d = a, colorful: f = !1, hideValues: p = !1, title: m, className: h }) {
15
+ let g = t(), _ = n();
16
+ if (l.length === 0) return null;
17
+ let v = l.map((e) => e.value), y = Math.max(...v, 0) || 1, b = e(l.length);
18
+ return /* @__PURE__ */ o(r, {
19
+ height: u,
20
+ title: m ?? `Bar chart of ${l.length} categories`,
21
+ className: h,
22
+ desc: l.map((e) => `${e.label}: ${d(e.value)}`).join(", "),
23
+ children: ({ width: e }) => {
24
+ let t = c.left, n = e - c.right, r = c.top, a = u - c.bottom, m = a - r, h = (n - t) / l.length, v = Math.min(56, h * .62);
25
+ return /* @__PURE__ */ s("g", { children: [/* @__PURE__ */ o("line", {
26
+ x1: t,
27
+ x2: n,
28
+ y1: a,
29
+ y2: a,
30
+ stroke: "var(--color-chart-axis)",
31
+ strokeWidth: 1,
32
+ vectorEffect: "non-scaling-stroke",
33
+ opacity: .5
34
+ }), l.map((e, n) => {
35
+ let r = i(e.value, 0, y, 0, m), c = t + h * n + h / 2, l = c - v / 2, x = a - r, S = e.color ?? (f ? b[n] : "var(--color-accent-primary)");
36
+ return /* @__PURE__ */ s("g", { children: [
37
+ /* @__PURE__ */ o("title", { children: `${e.label}: ${d(e.value)}` }),
38
+ /* @__PURE__ */ o("rect", {
39
+ x: l,
40
+ y: x,
41
+ width: v,
42
+ height: Math.max(0, r),
43
+ rx: 4,
44
+ fill: S,
45
+ style: {
46
+ transformBox: "fill-box",
47
+ transformOrigin: "bottom",
48
+ transform: g || _ ? "scaleY(1)" : "scaleY(0)",
49
+ transition: _ ? void 0 : "transform 620ms cubic-bezier(0.22,1,0.36,1)",
50
+ transitionDelay: _ ? void 0 : `${n * 45}ms`
51
+ }
52
+ }),
53
+ p ? null : /* @__PURE__ */ o("text", {
54
+ x: c,
55
+ y: x - 6,
56
+ textAnchor: "middle",
57
+ fontSize: 10,
58
+ fontWeight: 600,
59
+ fill: "var(--color-text-secondary)",
60
+ style: {
61
+ opacity: g || _ ? 1 : 0,
62
+ transition: _ ? void 0 : "opacity 400ms ease",
63
+ transitionDelay: _ ? void 0 : `${n * 45 + 220}ms`
64
+ },
65
+ children: d(e.value)
66
+ }),
67
+ /* @__PURE__ */ o("text", {
68
+ x: c,
69
+ y: u - 8,
70
+ textAnchor: "middle",
71
+ fontSize: 10,
72
+ fill: "var(--color-chart-axis)",
73
+ children: e.label
74
+ })
75
+ ] }, `${e.label}-${n}`);
76
+ })] });
77
+ }
78
+ });
79
+ }
80
+ //#endregion
81
+ export { l as BarChart };
82
+
83
+ //# sourceMappingURL=BarChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BarChart.js","names":[],"sources":["../../../../src/theglobalfuel/components/viz/BarChart.tsx"],"sourcesContent":["import { ACCENT, chartPalette } from './lib/palette';\nimport { ResponsiveSvg } from './lib/ResponsiveSvg';\nimport { scaleLinear } from './lib/geometry';\nimport { formatCompact } from './lib/format';\nimport { useMounted, usePrefersReducedMotion } from './lib/hooks';\nimport type { Segment } from './lib/types';\n\nexport interface BarChartProps {\n /** Bars to render. A `color` on a datum overrides the palette. */\n series: Segment[];\n height?: number;\n valueFormatter?: (value: number) => string;\n /** Color each bar from the categorical palette instead of a single accent. */\n colorful?: boolean;\n /** Hide the value label above each bar. */\n hideValues?: boolean;\n title?: string;\n className?: string;\n}\n\nconst PAD = { top: 20, bottom: 26, left: 8, right: 8 };\n\n/** Vertical bar chart with value labels and an animated grow-in. */\nexport function BarChart({\n series,\n height = 220,\n valueFormatter = formatCompact,\n colorful = false,\n hideValues = false,\n title,\n className,\n}: BarChartProps) {\n const mounted = useMounted();\n const reduced = usePrefersReducedMotion();\n\n if (series.length === 0) {\n return null;\n }\n\n const values = series.map((s) => s.value);\n const max = Math.max(...values, 0) || 1;\n const palette = chartPalette(series.length);\n const chartTitle = title ?? `Bar chart of ${series.length} categories`;\n\n return (\n <ResponsiveSvg\n height={height}\n title={chartTitle}\n className={className}\n desc={series.map((s) => `${s.label}: ${valueFormatter(s.value)}`).join(', ')}\n >\n {({ width }) => {\n const plotLeft = PAD.left;\n const plotRight = width - PAD.right;\n const plotTop = PAD.top;\n const plotBottom = height - PAD.bottom;\n const plotH = plotBottom - plotTop;\n const slot = (plotRight - plotLeft) / series.length;\n const barWidth = Math.min(56, slot * 0.62);\n return (\n <g>\n <line\n x1={plotLeft}\n x2={plotRight}\n y1={plotBottom}\n y2={plotBottom}\n stroke=\"var(--color-chart-axis)\"\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n opacity={0.5}\n />\n {series.map((datum, i) => {\n const barH = scaleLinear(datum.value, 0, max, 0, plotH);\n const cx = plotLeft + slot * i + slot / 2;\n const x = cx - barWidth / 2;\n const y = plotBottom - barH;\n const color = datum.color ?? (colorful ? palette[i] : ACCENT);\n return (\n <g key={`${datum.label}-${i}`}>\n <title>{`${datum.label}: ${valueFormatter(datum.value)}`}</title>\n <rect\n x={x}\n y={y}\n width={barWidth}\n height={Math.max(0, barH)}\n rx={4}\n fill={color}\n style={{\n transformBox: 'fill-box',\n transformOrigin: 'bottom',\n transform: mounted || reduced ? 'scaleY(1)' : 'scaleY(0)',\n transition: reduced\n ? undefined\n : 'transform 620ms cubic-bezier(0.22,1,0.36,1)',\n transitionDelay: reduced ? undefined : `${i * 45}ms`,\n }}\n />\n {hideValues ? null : (\n <text\n x={cx}\n y={y - 6}\n textAnchor=\"middle\"\n fontSize={10}\n fontWeight={600}\n fill=\"var(--color-text-secondary)\"\n style={{\n opacity: mounted || reduced ? 1 : 0,\n transition: reduced ? undefined : 'opacity 400ms ease',\n transitionDelay: reduced ? undefined : `${i * 45 + 220}ms`,\n }}\n >\n {valueFormatter(datum.value)}\n </text>\n )}\n <text\n x={cx}\n y={height - 8}\n textAnchor=\"middle\"\n fontSize={10}\n fill=\"var(--color-chart-axis)\"\n >\n {datum.label}\n </text>\n </g>\n );\n })}\n </g>\n );\n }}\n </ResponsiveSvg>\n );\n}\n"],"mappings":";;;;;;;AAoBA,IAAM,IAAM;CAAE,KAAK;CAAI,QAAQ;CAAI,MAAM;CAAG,OAAO;CAAG;AAGtD,SAAgB,EAAS,EACvB,WACA,YAAS,KACT,oBAAiB,GACjB,cAAW,IACX,gBAAa,IACb,UACA,gBACgB;CAChB,IAAM,IAAU,GAAY,EACtB,IAAU,GAAyB;AAEzC,KAAI,EAAO,WAAW,EACpB,QAAO;CAGT,IAAM,IAAS,EAAO,KAAK,MAAM,EAAE,MAAM,EACnC,IAAM,KAAK,IAAI,GAAG,GAAQ,EAAE,IAAI,GAChC,IAAU,EAAa,EAAO,OAAO;AAG3C,QACE,kBAAC,GAAD;EACU;EACR,OALe,KAAS,gBAAgB,EAAO,OAAO;EAM3C;EACX,MAAM,EAAO,KAAK,MAAM,GAAG,EAAE,MAAM,IAAI,EAAe,EAAE,MAAM,GAAG,CAAC,KAAK,KAAK;aAE1E,EAAE,eAAY;GACd,IAAM,IAAW,EAAI,MACf,IAAY,IAAQ,EAAI,OACxB,IAAU,EAAI,KACd,IAAa,IAAS,EAAI,QAC1B,IAAQ,IAAa,GACrB,KAAQ,IAAY,KAAY,EAAO,QACvC,IAAW,KAAK,IAAI,IAAI,IAAO,IAAK;AAC1C,UACE,kBAAC,KAAD,EAAA,UAAA,CACE,kBAAC,QAAD;IACE,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,QAAO;IACP,aAAa;IACb,cAAa;IACb,SAAS;IACT,CAAA,EACD,EAAO,KAAK,GAAO,MAAM;IACxB,IAAM,IAAO,EAAY,EAAM,OAAO,GAAG,GAAK,GAAG,EAAM,EACjD,IAAK,IAAW,IAAO,IAAI,IAAO,GAClC,IAAI,IAAK,IAAW,GACpB,IAAI,IAAa,GACjB,IAAQ,EAAM,UAAU,IAAW,EAAQ,KAAA;AACjD,WACE,kBAAC,KAAD,EAAA,UAAA;KACE,kBAAC,SAAD,EAAA,UAAQ,GAAG,EAAM,MAAM,IAAI,EAAe,EAAM,MAAM,IAAW,CAAA;KACjE,kBAAC,QAAD;MACK;MACA;MACH,OAAO;MACP,QAAQ,KAAK,IAAI,GAAG,EAAK;MACzB,IAAI;MACJ,MAAM;MACN,OAAO;OACL,cAAc;OACd,iBAAiB;OACjB,WAAW,KAAW,IAAU,cAAc;OAC9C,YAAY,IACR,KAAA,IACA;OACJ,iBAAiB,IAAU,KAAA,IAAY,GAAG,IAAI,GAAG;OAClD;MACD,CAAA;KACD,IAAa,OACZ,kBAAC,QAAD;MACE,GAAG;MACH,GAAG,IAAI;MACP,YAAW;MACX,UAAU;MACV,YAAY;MACZ,MAAK;MACL,OAAO;OACL,SAAS,KAAW,IAAU,IAAI;OAClC,YAAY,IAAU,KAAA,IAAY;OAClC,iBAAiB,IAAU,KAAA,IAAY,GAAG,IAAI,KAAK,IAAI;OACxD;gBAEA,EAAe,EAAM,MAAM;MACvB,CAAA;KAET,kBAAC,QAAD;MACE,GAAG;MACH,GAAG,IAAS;MACZ,YAAW;MACX,UAAU;MACV,MAAK;gBAEJ,EAAM;MACF,CAAA;KACL,EAAA,EA7CI,GAAG,EAAM,MAAM,GAAG,IA6CtB;KAEN,CACA,EAAA,CAAA;;EAGM,CAAA"}
@@ -1,3 +1,60 @@
1
- import "./Sparkline.js";
2
- import "lucide-react";
3
- import "react/jsx-runtime";
1
+ import { cn as e } from "../../utils/cn.js";
2
+ import { Sparkline as t } from "./Sparkline.js";
3
+ import { ArrowDownRight as n, ArrowUpRight as r } from "lucide-react";
4
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
+ //#region src/theglobalfuel/components/viz/StatCard.tsx
6
+ function o({ label: o, value: s, delta: c, deltaSuffix: l = "%", deltaLabel: u, invertDelta: d = !1, icon: f, sparkline: p, sparklineVariant: m = "area", className: h }) {
7
+ let g = typeof c == "number", _ = d ? (c ?? 0) < 0 : (c ?? 0) > 0, v = (c ?? 0) === 0, y = (c ?? 0) > 0, b = v ? "text-text-muted" : _ ? "text-status-success-text" : "text-status-error-text";
8
+ return /* @__PURE__ */ a("div", {
9
+ className: e("flex flex-col gap-3 rounded-[var(--radius-card)] border border-border-subtle bg-bg-surface p-5 shadow-elevation-1 transition-shadow duration-200 hover:shadow-elevation-2", h),
10
+ children: [
11
+ /* @__PURE__ */ a("div", {
12
+ className: "flex items-start justify-between gap-2",
13
+ children: [/* @__PURE__ */ i("span", {
14
+ className: "text-sm font-medium text-text-secondary",
15
+ children: o
16
+ }), f ? /* @__PURE__ */ i("span", {
17
+ className: "text-text-muted",
18
+ children: f
19
+ }) : null]
20
+ }),
21
+ /* @__PURE__ */ i("div", {
22
+ className: "flex items-end justify-between gap-3",
23
+ children: /* @__PURE__ */ i("span", {
24
+ className: "text-3xl font-semibold leading-none tracking-tight tabular-nums text-text-primary",
25
+ children: s
26
+ })
27
+ }),
28
+ g ? /* @__PURE__ */ a("div", {
29
+ className: "flex items-center gap-1.5 text-sm",
30
+ children: [/* @__PURE__ */ a("span", {
31
+ className: e("inline-flex items-center gap-0.5 font-medium tabular-nums", b),
32
+ children: [
33
+ v ? null : i(y ? r : n, {
34
+ "aria-hidden": "true",
35
+ className: "h-4 w-4"
36
+ }),
37
+ y ? "+" : "",
38
+ c,
39
+ l
40
+ ]
41
+ }), u ? /* @__PURE__ */ i("span", {
42
+ className: "text-text-muted",
43
+ children: u
44
+ }) : null]
45
+ }) : null,
46
+ p && p.length > 1 ? /* @__PURE__ */ i("div", {
47
+ className: "mt-1",
48
+ children: /* @__PURE__ */ i(t, {
49
+ data: p,
50
+ variant: m,
51
+ label: `${o} trend`
52
+ })
53
+ }) : null
54
+ ]
55
+ });
56
+ }
57
+ //#endregion
58
+ export { o as StatCard };
59
+
60
+ //# sourceMappingURL=StatCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatCard.js","names":[],"sources":["../../../../src/theglobalfuel/components/viz/StatCard.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { ArrowDownRight, ArrowUpRight } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Sparkline } from './Sparkline';\n\nexport interface StatCardProps {\n label: string;\n value: ReactNode;\n /** Signed change; positive renders success (unless `invertDelta`). */\n delta?: number;\n /** Unit appended to the delta (default \"%\"). */\n deltaSuffix?: string;\n /** Context line under the delta, e.g. \"vs last month\". */\n deltaLabel?: string;\n /** When true (attrition, cost) a negative delta is the good outcome. */\n invertDelta?: boolean;\n icon?: ReactNode;\n /** Optional trend to render as a footer sparkline. */\n sparkline?: number[];\n sparklineVariant?: 'line' | 'area';\n className?: string;\n}\n\n/** KPI tile: label, big tabular value, optional signed delta and sparkline. */\nexport function StatCard({\n label,\n value,\n delta,\n deltaSuffix = '%',\n deltaLabel,\n invertDelta = false,\n icon,\n sparkline,\n sparklineVariant = 'area',\n className,\n}: StatCardProps) {\n const hasDelta = typeof delta === 'number';\n const positiveIsGood = invertDelta ? (delta ?? 0) < 0 : (delta ?? 0) > 0;\n const isNeutral = (delta ?? 0) === 0;\n const rising = (delta ?? 0) > 0;\n\n const toneClass = isNeutral\n ? 'text-text-muted'\n : positiveIsGood\n ? 'text-status-success-text'\n : 'text-status-error-text';\n\n return (\n <div\n className={cn(\n 'flex flex-col gap-3 rounded-[var(--radius-card)] border border-border-subtle bg-bg-surface p-5 shadow-elevation-1 transition-shadow duration-200 hover:shadow-elevation-2',\n className\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"text-sm font-medium text-text-secondary\">{label}</span>\n {icon ? <span className=\"text-text-muted\">{icon}</span> : null}\n </div>\n <div className=\"flex items-end justify-between gap-3\">\n <span className=\"text-3xl font-semibold leading-none tracking-tight tabular-nums text-text-primary\">\n {value}\n </span>\n </div>\n {hasDelta ? (\n <div className=\"flex items-center gap-1.5 text-sm\">\n <span\n className={cn('inline-flex items-center gap-0.5 font-medium tabular-nums', toneClass)}\n >\n {isNeutral ? null : rising ? (\n <ArrowUpRight aria-hidden=\"true\" className=\"h-4 w-4\" />\n ) : (\n <ArrowDownRight aria-hidden=\"true\" className=\"h-4 w-4\" />\n )}\n {rising ? '+' : ''}\n {delta}\n {deltaSuffix}\n </span>\n {deltaLabel ? <span className=\"text-text-muted\">{deltaLabel}</span> : null}\n </div>\n ) : null}\n {sparkline && sparkline.length > 1 ? (\n <div className=\"mt-1\">\n <Sparkline data={sparkline} variant={sparklineVariant} label={`${label} trend`} />\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;;AAwBA,SAAgB,EAAS,EACvB,UACA,UACA,UACA,iBAAc,KACd,eACA,iBAAc,IACd,SACA,cACA,sBAAmB,QACnB,gBACgB;CAChB,IAAM,IAAW,OAAO,KAAU,UAC5B,IAAiB,KAAe,KAAS,KAAK,KAAK,KAAS,KAAK,GACjE,KAAa,KAAS,OAAO,GAC7B,KAAU,KAAS,KAAK,GAExB,IAAY,IACd,oBACA,IACE,6BACA;AAEN,QACE,kBAAC,OAAD;EACE,WAAW,EACT,6KACA,EACD;YAJH;GAME,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eAA2C;KAAa,CAAA,EACvE,IAAO,kBAAC,QAAD;KAAM,WAAU;eAAmB;KAAY,CAAA,GAAG,KACtD;;GACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,QAAD;KAAM,WAAU;eACb;KACI,CAAA;IACH,CAAA;GACL,IACC,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KACE,WAAW,EAAG,6DAA6D,EAAU;eADvF;MAGG,IAAY,OACX,EADkB,IACjB,IAEA,GAFD;OAAc,eAAY;OAAO,WAAU;OAAY,CAEE;MAE1D,IAAS,MAAM;MACf;MACA;MACI;QACN,IAAa,kBAAC,QAAD;KAAM,WAAU;eAAmB;KAAkB,CAAA,GAAG,KAClE;QACJ;GACH,KAAa,EAAU,SAAS,IAC/B,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KAAW,MAAM;KAAW,SAAS;KAAkB,OAAO,GAAG,EAAM;KAAW,CAAA;IAC9E,CAAA,GACJ;GACA"}
@@ -1,4 +1,4 @@
1
- import { TheConnection, TheAsset, TheAssetKind, TheAssetStatus, TheCommodityType, TheProductionRecord, TheReserveEstimate, TheReserveCategory, TheOfftakeContract, TheContractSide, TheContractStatus, TheShipment, TheShipmentStatus, TheInventoryLot, TheInventoryStatus, TheEmissionRecord, TheEmissionScope, TheComplianceCert, TheComplianceCategory, TheComplianceStatus, TheCreateAssetInput, TheUpdateAssetInput, TheRecordProductionInput, TheCreateReserveEstimateInput, TheCreateOfftakeContractInput, TheUpdateOfftakeContractInput, TheCreateShipmentInput, TheCreateInventoryLotInput, TheRecordEmissionInput, TheCreateComplianceCertInput, PaginationInput } from '../types';
1
+ import { TheConnection, TheAsset, TheAssetKind, TheAssetStatus, TheCommodityType, TheProductionRecord, TheReserveEstimate, TheReserveCategory, TheOfftakeContract, TheContractSide, TheContractStatus, TheShipment, TheShipmentStatus, TheInventoryLot, TheInventoryStatus, TheEmissionRecord, TheEmissionScope, TheComplianceCert, TheComplianceCategory, TheComplianceStatus, TheCreateAssetInput, TheUpdateAssetInput, TheRecordProductionInput, TheCreateReserveEstimateInput, TheCreateOfftakeContractInput, TheUpdateOfftakeContractInput, TheCreateShipmentInput, TheUpdateShipmentInput, TheCreateInventoryLotInput, TheRecordEmissionInput, TheCreateComplianceCertInput, PaginationInput } from '../types';
2
2
 
3
3
  export interface AssetFilters {
4
4
  commodity?: TheCommodityType;
@@ -49,6 +49,15 @@ export declare const useTheTransitionShipment: () => import('@tanstack/react-que
49
49
  status: TheShipmentStatus;
50
50
  }, unknown>;
51
51
  export declare const useTheScheduleShipment: () => import('@tanstack/react-query').UseMutationResult<TheShipment, Error, TheCreateShipmentInput, unknown>;
52
+ /**
53
+ * Update the logistics metadata of an existing shipment (carrier, tracking
54
+ * number, route, schedule, document, notes). Status/volume are not editable
55
+ * here — use the transition/deliver mutations for those.
56
+ */
57
+ export declare const useTheUpdateShipment: () => import('@tanstack/react-query').UseMutationResult<TheShipment, Error, {
58
+ id: string;
59
+ input: TheUpdateShipmentInput;
60
+ }, unknown>;
52
61
  export declare const useTheDeliverShipment: () => import('@tanstack/react-query').UseMutationResult<TheShipment, Error, string, unknown>;
53
62
  export interface InventoryFilters {
54
63
  commodity?: TheCommodityType;
@@ -1 +1 @@
1
- {"version":3,"file":"useTheGlobalFuelApi.d.ts","sourceRoot":"","sources":["../../../src/theglobalfuel/hooks/useTheGlobalFuelApi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useTheGlobalFuelApi.d.ts","sourceRoot":"","sources":["../../../src/theglobalfuel/hooks/useTheGlobalFuelApi.ts"],"names":[],"mappings":"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"}
@@ -41,7 +41,7 @@ var a = () => {
41
41
  "compliance",
42
42
  e
43
43
  ]
44
- }, c = { limit: 50 }, l = "\n id workspaceId name code kind commodity status location latitude longitude\n capacityPerDay capacityUnit workingInterestPct operatorLeadId\n commissionedAt decommissionedAt tags createdAt updatedAt\n", u = "\n id workspaceId assetId periodStart periodEnd volume unit grade downtimeHours\n notes createdAt updatedAt\n", d = "\n id workspaceId assetId category asOfDate recoverable recoveryFactor unit\n methodology notes createdAt updatedAt\n", f = "\n id workspaceId reference counterparty commodity side status pricingBasis\n pricePerUnit priceIndex currency contractedVolume deliveredVolume unit\n deliveryLocation startDate endDate signedAt notes tags createdAt updatedAt\n", p = "\n id workspaceId contractId reference mode status carrier origin destination\n volume unit scheduledAt departedAt deliveredAt document { id } notes\n createdAt updatedAt\n", m = "\n id workspaceId lotCode commodity assetId quantity unit grade status location\n unitValue currency producedAt notes createdAt updatedAt\n", h = "\n id workspaceId assetId scope co2eTonnes periodStart periodEnd source\n methodology verified verifiedAt notes createdAt updatedAt\n", g = "\n id workspaceId title category status assetId authority certNumber ownerId\n issuedAt expiresAt evidence { id } notes tags createdAt updatedAt\n", _ = (t = {}) => {
44
+ }, c = { limit: 50 }, l = "\n id workspaceId name code kind commodity status location latitude longitude\n capacityPerDay capacityUnit workingInterestPct operatorLeadId\n commissionedAt decommissionedAt discoveryAt area reservoirType waterDepth\n tags createdAt updatedAt\n", u = "\n id workspaceId assetId periodStart periodEnd volume unit grade downtimeHours\n source notes createdAt updatedAt\n", d = "\n id workspaceId assetId category asOfDate recoverable recoveryFactor unit\n methodology notes createdAt updatedAt\n", f = "\n id workspaceId reference counterparty commodity side status pricingBasis\n pricePerUnit priceIndex currency contractedVolume deliveredVolume unit\n deliveryLocation startDate endDate signedAt notes tags createdAt updatedAt\n", p = "\n id workspaceId contractId reference mode status carrier trackingId origin destination\n volume unit scheduledAt departedAt deliveredAt document { id } notes\n createdAt updatedAt\n", m = "\n id workspaceId lotCode commodity assetId quantity unit grade status location\n unitValue currency producedAt notes createdAt updatedAt\n", h = "\n id workspaceId assetId scope co2eTonnes periodStart periodEnd source\n methodology verified verifiedAt notes createdAt updatedAt\n", g = "\n id workspaceId title category status assetId authority certNumber ownerId\n issuedAt expiresAt evidence { id } notes tags createdAt updatedAt\n", _ = (t = {}) => {
45
45
  let { apiGatewayUrl: r } = e();
46
46
  return n({
47
47
  queryKey: [...s.assets, t],