@burdenoff/microfe-theglobalfuel 2026.1031.1 → 2026.1101.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 (69) hide show
  1. package/dist/theglobalfuel/components/PageLayout.js +2 -2
  2. package/dist/theglobalfuel/components/PageLayout.js.map +1 -1
  3. package/dist/theglobalfuel/components/RecordProductionSheet.d.ts +13 -0
  4. package/dist/theglobalfuel/components/RecordProductionSheet.d.ts.map +1 -0
  5. package/dist/theglobalfuel/components/RecordProductionSheet.js +244 -0
  6. package/dist/theglobalfuel/components/RecordProductionSheet.js.map +1 -0
  7. package/dist/theglobalfuel/components/mobile/CommodityThumb.d.ts +13 -0
  8. package/dist/theglobalfuel/components/mobile/CommodityThumb.d.ts.map +1 -0
  9. package/dist/theglobalfuel/components/mobile/CommodityThumb.js +30 -0
  10. package/dist/theglobalfuel/components/mobile/CommodityThumb.js.map +1 -0
  11. package/dist/theglobalfuel/components/mobile/MobileAssetList.d.ts +11 -0
  12. package/dist/theglobalfuel/components/mobile/MobileAssetList.d.ts.map +1 -0
  13. package/dist/theglobalfuel/components/mobile/MobileAssetList.js +102 -0
  14. package/dist/theglobalfuel/components/mobile/MobileAssetList.js.map +1 -0
  15. package/dist/theglobalfuel/components/mobile/MobileChip.d.ts +10 -0
  16. package/dist/theglobalfuel/components/mobile/MobileChip.d.ts.map +1 -0
  17. package/dist/theglobalfuel/components/mobile/MobileChip.js +14 -0
  18. package/dist/theglobalfuel/components/mobile/MobileChip.js.map +1 -0
  19. package/dist/theglobalfuel/components/mobile/MobileContractList.d.ts +10 -0
  20. package/dist/theglobalfuel/components/mobile/MobileContractList.d.ts.map +1 -0
  21. package/dist/theglobalfuel/components/mobile/MobileContractList.js +89 -0
  22. package/dist/theglobalfuel/components/mobile/MobileContractList.js.map +1 -0
  23. package/dist/theglobalfuel/components/mobile/MobileKpiTile.d.ts +14 -0
  24. package/dist/theglobalfuel/components/mobile/MobileKpiTile.d.ts.map +1 -0
  25. package/dist/theglobalfuel/components/mobile/MobileKpiTile.js +34 -0
  26. package/dist/theglobalfuel/components/mobile/MobileKpiTile.js.map +1 -0
  27. package/dist/theglobalfuel/hooks/index.d.ts +1 -0
  28. package/dist/theglobalfuel/hooks/index.d.ts.map +1 -1
  29. package/dist/theglobalfuel/hooks/index.js +1 -0
  30. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts +13 -2
  31. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts.map +1 -1
  32. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js +272 -247
  33. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js.map +1 -1
  34. package/dist/theglobalfuel/hooks/useTheIsMobile.d.ts +11 -0
  35. package/dist/theglobalfuel/hooks/useTheIsMobile.d.ts.map +1 -0
  36. package/dist/theglobalfuel/hooks/useTheIsMobile.js +10 -0
  37. package/dist/theglobalfuel/hooks/useTheIsMobile.js.map +1 -0
  38. package/dist/theglobalfuel/pages/assets/AssetsPage.d.ts.map +1 -1
  39. package/dist/theglobalfuel/pages/assets/AssetsPage.js +268 -249
  40. package/dist/theglobalfuel/pages/assets/AssetsPage.js.map +1 -1
  41. package/dist/theglobalfuel/pages/contracts/ContractsPage.d.ts.map +1 -1
  42. package/dist/theglobalfuel/pages/contracts/ContractsPage.js +237 -229
  43. package/dist/theglobalfuel/pages/contracts/ContractsPage.js.map +1 -1
  44. package/dist/theglobalfuel/pages/dashboard/DashboardPage.d.ts.map +1 -1
  45. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js +291 -272
  46. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js.map +1 -1
  47. package/dist/theglobalfuel/pages/mobile/DashboardMobileOverview.d.ts +33 -0
  48. package/dist/theglobalfuel/pages/mobile/DashboardMobileOverview.d.ts.map +1 -0
  49. package/dist/theglobalfuel/pages/mobile/DashboardMobileOverview.js +188 -0
  50. package/dist/theglobalfuel/pages/mobile/DashboardMobileOverview.js.map +1 -0
  51. package/dist/theglobalfuel/pages/production/ProductionPage.d.ts.map +1 -1
  52. package/dist/theglobalfuel/pages/production/ProductionPage.js +84 -325
  53. package/dist/theglobalfuel/pages/production/ProductionPage.js.map +1 -1
  54. package/dist/theglobalfuel/utils/index.d.ts +2 -0
  55. package/dist/theglobalfuel/utils/index.d.ts.map +1 -1
  56. package/dist/theglobalfuel/utils/index.js +2 -0
  57. package/dist/theglobalfuel/utils/mobile.d.ts +35 -0
  58. package/dist/theglobalfuel/utils/mobile.d.ts.map +1 -0
  59. package/dist/theglobalfuel/utils/mobile.js +57 -0
  60. package/dist/theglobalfuel/utils/mobile.js.map +1 -0
  61. package/dist/theglobalfuel/utils/paging.d.ts +19 -0
  62. package/dist/theglobalfuel/utils/paging.d.ts.map +1 -0
  63. package/dist/theglobalfuel/utils/paging.js +18 -0
  64. package/dist/theglobalfuel/utils/paging.js.map +1 -0
  65. package/dist/theglobalfuel/utils/productionForm.d.ts +51 -0
  66. package/dist/theglobalfuel/utils/productionForm.d.ts.map +1 -0
  67. package/dist/theglobalfuel/utils/productionForm.js +83 -0
  68. package/dist/theglobalfuel/utils/productionForm.js.map +1 -0
  69. package/package.json +1 -1
@@ -6,7 +6,7 @@ var a = ({ title: a, description: o, actions: s, children: c, className: l, titl
6
6
  className: e("flex flex-col h-full", l),
7
7
  "data-tour": f,
8
8
  children: [/* @__PURE__ */ n("div", {
9
- className: e("relative flex flex-col gap-3 px-6 py-4 border-b border-border-seam sm:flex-row sm:items-center sm:justify-between sm:gap-4", d ? "overflow-hidden bg-gloss-card" : "bg-bg-surface"),
9
+ className: e("relative flex flex-col gap-3 px-4 py-4 sm:px-6 border-b border-border-seam sm:flex-row sm:items-center sm:justify-between sm:gap-4", d ? "overflow-hidden bg-gloss-card" : "bg-bg-surface"),
10
10
  children: [
11
11
  d && /* @__PURE__ */ t(r, { intensity: "subtle" }),
12
12
  /* @__PURE__ */ n("div", {
@@ -29,7 +29,7 @@ var a = ({ title: a, description: o, actions: s, children: c, className: l, titl
29
29
  })
30
30
  ]
31
31
  }), /* @__PURE__ */ t("div", {
32
- className: "flex-1 overflow-auto p-6",
32
+ className: "flex-1 overflow-auto p-4 sm:p-6",
33
33
  children: c
34
34
  })]
35
35
  });
@@ -1 +1 @@
1
- {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/theglobalfuel/components/PageLayout.tsx"],"sourcesContent":["/**\n * Page Layout Component\n * @module theglobalfuel/components\n *\n * Boff UI 2.0 page wrapper. Supports a living-glass {@link AuroraBackground}\n * hero backdrop and a gradient hero title for the MFE's primary page.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { AuroraBackground, GradientText } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\n\ninterface PageLayoutProps {\n title: ReactNode;\n description?: string;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n /** Render the title as a gradient hero heading (reserve for the ONE primary page). */\n titleGradient?: boolean;\n /** Drop a subtle living-glass aurora behind the header (primary page only). */\n aurora?: boolean;\n /** Tour anchor id applied to the page wrapper for guided tours. */\n dataTour?: string;\n}\n\nexport const PageLayout: FC<PageLayoutProps> = ({\n title,\n description,\n actions,\n children,\n className,\n titleGradient = false,\n aurora = false,\n dataTour,\n}) => {\n return (\n <div className={cn('flex flex-col h-full', className)} data-tour={dataTour}>\n <div\n className={cn(\n 'relative flex flex-col gap-3 px-6 py-4 border-b border-border-seam sm:flex-row sm:items-center sm:justify-between sm:gap-4',\n aurora ? 'overflow-hidden bg-gloss-card' : 'bg-bg-surface'\n )}\n >\n {aurora && <AuroraBackground intensity=\"subtle\" />}\n <div className=\"min-w-0\">\n {titleGradient && typeof title === 'string' ? (\n <GradientText as=\"h1\" className=\"text-2xl font-semibold tracking-tight\">\n {title}\n </GradientText>\n ) : (\n <h1 className=\"text-2xl font-semibold text-text-primary\">{title}</h1>\n )}\n {description && <p className=\"mt-1 text-sm text-text-secondary\">{description}</p>}\n </div>\n {actions && (\n <div className=\"flex flex-wrap items-center gap-3 shrink-0 max-sm:w-full\">{actions}</div>\n )}\n </div>\n\n <div className=\"flex-1 overflow-auto p-6\">{children}</div>\n </div>\n );\n};\n"],"mappings":";;;;AA0BA,IAAa,KAAmC,EAC9C,UACA,gBACA,YACA,aACA,cACA,mBAAgB,IAChB,YAAS,IACT,kBAGE,kBAAC,OAAD;CAAK,WAAW,EAAG,wBAAwB,EAAU;CAAE,aAAW;WAAlE,CACE,kBAAC,OAAD;EACE,WAAW,EACT,8HACA,IAAS,kCAAkC,gBAC5C;YAJH;GAMG,KAAU,kBAAC,GAAD,EAAkB,WAAU,UAAW,CAAA;GAClD,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,KAAiB,OAAO,KAAU,WACjC,kBAAC,GAAD;KAAc,IAAG;KAAK,WAAU;eAC7B;KACY,CAAA,GAEf,kBAAC,MAAD;KAAI,WAAU;eAA4C;KAAW,CAAA,EAEtE,KAAe,kBAAC,KAAD;KAAG,WAAU;eAAoC;KAAgB,CAAA,CAC7E;;GACL,KACC,kBAAC,OAAD;IAAK,WAAU;cAA4D;IAAc,CAAA;GAEvF;KAEN,kBAAC,OAAD;EAAK,WAAU;EAA4B;EAAe,CAAA,CACtD"}
1
+ {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/theglobalfuel/components/PageLayout.tsx"],"sourcesContent":["/**\n * Page Layout Component\n * @module theglobalfuel/components\n *\n * Boff UI 2.0 page wrapper. Supports a living-glass {@link AuroraBackground}\n * hero backdrop and a gradient hero title for the MFE's primary page.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { AuroraBackground, GradientText } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\n\ninterface PageLayoutProps {\n title: ReactNode;\n description?: string;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n /** Render the title as a gradient hero heading (reserve for the ONE primary page). */\n titleGradient?: boolean;\n /** Drop a subtle living-glass aurora behind the header (primary page only). */\n aurora?: boolean;\n /** Tour anchor id applied to the page wrapper for guided tours. */\n dataTour?: string;\n}\n\nexport const PageLayout: FC<PageLayoutProps> = ({\n title,\n description,\n actions,\n children,\n className,\n titleGradient = false,\n aurora = false,\n dataTour,\n}) => {\n return (\n <div className={cn('flex flex-col h-full', className)} data-tour={dataTour}>\n <div\n className={cn(\n 'relative flex flex-col gap-3 px-4 py-4 sm:px-6 border-b border-border-seam sm:flex-row sm:items-center sm:justify-between sm:gap-4',\n aurora ? 'overflow-hidden bg-gloss-card' : 'bg-bg-surface'\n )}\n >\n {aurora && <AuroraBackground intensity=\"subtle\" />}\n <div className=\"min-w-0\">\n {titleGradient && typeof title === 'string' ? (\n <GradientText as=\"h1\" className=\"text-2xl font-semibold tracking-tight\">\n {title}\n </GradientText>\n ) : (\n <h1 className=\"text-2xl font-semibold text-text-primary\">{title}</h1>\n )}\n {description && <p className=\"mt-1 text-sm text-text-secondary\">{description}</p>}\n </div>\n {actions && (\n <div className=\"flex flex-wrap items-center gap-3 shrink-0 max-sm:w-full\">{actions}</div>\n )}\n </div>\n\n <div className=\"flex-1 overflow-auto p-4 sm:p-6\">{children}</div>\n </div>\n );\n};\n"],"mappings":";;;;AA0BA,IAAa,KAAmC,EAC9C,UACA,gBACA,YACA,aACA,cACA,mBAAgB,IAChB,YAAS,IACT,kBAGE,kBAAC,OAAD;CAAK,WAAW,EAAG,wBAAwB,EAAU;CAAE,aAAW;WAAlE,CACE,kBAAC,OAAD;EACE,WAAW,EACT,sIACA,IAAS,kCAAkC,gBAC5C;YAJH;GAMG,KAAU,kBAAC,GAAD,EAAkB,WAAU,UAAW,CAAA;GAClD,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,KAAiB,OAAO,KAAU,WACjC,kBAAC,GAAD;KAAc,IAAG;KAAK,WAAU;eAC7B;KACY,CAAA,GAEf,kBAAC,MAAD;KAAI,WAAU;eAA4C;KAAW,CAAA,EAEtE,KAAe,kBAAC,KAAD;KAAG,WAAU;eAAoC;KAAgB,CAAA,CAC7E;;GACL,KACC,kBAAC,OAAD;IAAK,WAAU;cAA4D;IAAc,CAAA;GAEvF;KAEN,kBAAC,OAAD;EAAK,WAAU;EAAmC;EAAe,CAAA,CAC7D"}
@@ -0,0 +1,13 @@
1
+ import { TheProductionRecord } from '../types';
2
+
3
+ interface RecordProductionSheetProps {
4
+ open: boolean;
5
+ onOpenChange: (open: boolean) => void;
6
+ /** Pre-select an asset (e.g. when opened from an asset card). */
7
+ defaultAssetId?: string;
8
+ /** Called after a record is saved. */
9
+ onRecorded?: (record: TheProductionRecord) => void;
10
+ }
11
+ export declare function RecordProductionSheet({ open, onOpenChange, defaultAssetId, onRecorded, }: RecordProductionSheetProps): import("react").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=RecordProductionSheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordProductionSheet.d.ts","sourceRoot":"","sources":["../../../src/theglobalfuel/components/RecordProductionSheet.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA8BH,OAAO,KAAK,EAAE,mBAAmB,EAAW,MAAM,UAAU,CAAC;AAE7D,UAAU,0BAA0B;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACpD;AAKD,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,YAAY,EACZ,cAAc,EACd,UAAU,GACX,EAAE,0BAA0B,+BAsO5B"}
@@ -0,0 +1,244 @@
1
+ import { formatEnumLabel as e } from "../utils/formatters.js";
2
+ import { useTheAsset as t, useTheAssets as n, useTheRecordProduction as r } from "../hooks/useTheGlobalFuelApi.js";
3
+ import { useNotify as i } from "../hooks/useNotify.js";
4
+ import "../hooks/index.js";
5
+ import { PRODUCTION_UNITS as a, autoUnitForAsset as o, buildRecordProductionInput as s, emptyRecordProductionForm as c, withSelectedAssetOption as l } from "../utils/productionForm.js";
6
+ import { useState as u } from "react";
7
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
+ import { Button as p, Input as m, Label as h, ResponsiveDialog as g, ResponsiveDialogContent as _, ResponsiveDialogDescription as v, ResponsiveDialogFooter as y, ResponsiveDialogHeader as b, ResponsiveDialogTitle as x, Select as S, SelectContent as C, SelectItem as w, SelectTrigger as T, SelectValue as E, Textarea as D } from "@burdenoff/fe-libs/ui";
9
+ //#region src/theglobalfuel/components/RecordProductionSheet.tsx
10
+ var O = { pagination: { limit: 100 } };
11
+ function k({ open: k, onOpenChange: A, defaultAssetId: j, onRecorded: M }) {
12
+ let N = i(), P = n(O), F = r(), I = P.data?.items ?? [], [L, R] = u(() => c(j)), [z, B] = u(!1), [V, H] = u(null), U = k ? `open:${j ?? ""}` : "closed", [W, G] = u(U);
13
+ U !== W && (G(U), k && (R(c(j ?? "")), B(!1), H(null)));
14
+ let K = I.find((e) => e.id === L.assetId), q = t(k && L.assetId && !K ? L.assetId : void 0), J = K ?? q.data ?? null, Y = l(I, J), X = o(J, L.unit, z) ?? L.unit, Z = () => A(!1), Q = async () => {
15
+ let e = s({
16
+ ...L,
17
+ unit: X
18
+ });
19
+ if (!e.ok) {
20
+ H(e.error), N.error(e.error);
21
+ return;
22
+ }
23
+ H(null);
24
+ try {
25
+ let t = await F.mutateAsync(e.input);
26
+ N.success("Production recorded"), M?.(t), Z();
27
+ } catch (e) {
28
+ H(e instanceof Error ? e.message : "Failed to record production."), N.fromError(e);
29
+ }
30
+ };
31
+ return /* @__PURE__ */ d(g, {
32
+ open: k,
33
+ onOpenChange: A,
34
+ children: /* @__PURE__ */ f(_, {
35
+ "data-testid": "record-production-sheet",
36
+ children: [/* @__PURE__ */ f(b, { children: [/* @__PURE__ */ d(x, { children: "Record production" }), /* @__PURE__ */ d(v, { children: "Log the volume produced by an asset over a reporting period." })] }), /* @__PURE__ */ f("form", {
37
+ onSubmit: (e) => {
38
+ e.preventDefault(), Q();
39
+ },
40
+ children: [/* @__PURE__ */ f("div", {
41
+ className: "grid gap-4 py-2",
42
+ children: [
43
+ /* @__PURE__ */ f("div", {
44
+ className: "grid gap-1.5",
45
+ children: [/* @__PURE__ */ d(h, {
46
+ htmlFor: "prAsset",
47
+ children: "Asset *"
48
+ }), /* @__PURE__ */ f(S, {
49
+ value: L.assetId,
50
+ onValueChange: (e) => R({
51
+ ...L,
52
+ assetId: e
53
+ }),
54
+ children: [/* @__PURE__ */ d(T, {
55
+ id: "prAsset",
56
+ className: "h-11 md:h-10",
57
+ children: /* @__PURE__ */ d(E, { placeholder: "Select an asset" })
58
+ }), /* @__PURE__ */ d(C, { children: Y.map((e) => /* @__PURE__ */ d(w, {
59
+ value: e.id,
60
+ children: e.name
61
+ }, e.id)) })]
62
+ })]
63
+ }),
64
+ /* @__PURE__ */ f("div", {
65
+ className: "grid grid-cols-2 gap-2",
66
+ children: [/* @__PURE__ */ f("div", {
67
+ className: "grid gap-1.5",
68
+ children: [/* @__PURE__ */ d(h, {
69
+ htmlFor: "prStart",
70
+ children: "Period start *"
71
+ }), /* @__PURE__ */ d(m, {
72
+ id: "prStart",
73
+ type: "date",
74
+ className: "h-11 md:h-10",
75
+ value: L.periodStart,
76
+ onChange: (e) => R({
77
+ ...L,
78
+ periodStart: e.target.value
79
+ })
80
+ })]
81
+ }), /* @__PURE__ */ f("div", {
82
+ className: "grid gap-1.5",
83
+ children: [/* @__PURE__ */ d(h, {
84
+ htmlFor: "prEnd",
85
+ children: "Period end *"
86
+ }), /* @__PURE__ */ d(m, {
87
+ id: "prEnd",
88
+ type: "date",
89
+ className: "h-11 md:h-10",
90
+ value: L.periodEnd,
91
+ onChange: (e) => R({
92
+ ...L,
93
+ periodEnd: e.target.value
94
+ })
95
+ })]
96
+ })]
97
+ }),
98
+ /* @__PURE__ */ f("div", {
99
+ className: "grid grid-cols-[minmax(0,1fr)_8rem] gap-2 md:grid-cols-2",
100
+ children: [/* @__PURE__ */ f("div", {
101
+ className: "grid gap-1.5",
102
+ children: [/* @__PURE__ */ d(h, {
103
+ htmlFor: "prVolume",
104
+ children: "Volume *"
105
+ }), /* @__PURE__ */ d(m, {
106
+ id: "prVolume",
107
+ type: "number",
108
+ inputMode: "decimal",
109
+ min: "0",
110
+ step: "any",
111
+ className: "h-11 text-lg tabular-nums md:h-10 md:text-sm",
112
+ value: L.volume,
113
+ onChange: (e) => R({
114
+ ...L,
115
+ volume: e.target.value
116
+ }),
117
+ placeholder: "12500"
118
+ })]
119
+ }), /* @__PURE__ */ f("div", {
120
+ className: "grid gap-1.5",
121
+ children: [/* @__PURE__ */ d(h, {
122
+ htmlFor: "prUnit",
123
+ children: "Unit"
124
+ }), /* @__PURE__ */ f(S, {
125
+ value: X,
126
+ onValueChange: (e) => {
127
+ B(!0), R({
128
+ ...L,
129
+ unit: e
130
+ });
131
+ },
132
+ children: [/* @__PURE__ */ d(T, {
133
+ id: "prUnit",
134
+ className: "h-11 md:h-10",
135
+ children: /* @__PURE__ */ d(E, {})
136
+ }), /* @__PURE__ */ d(C, { children: a.map((t) => /* @__PURE__ */ d(w, {
137
+ value: t,
138
+ children: e(t)
139
+ }, t)) })]
140
+ })]
141
+ })]
142
+ }),
143
+ /* @__PURE__ */ f("div", {
144
+ className: "grid grid-cols-2 gap-2",
145
+ children: [/* @__PURE__ */ f("div", {
146
+ className: "grid gap-1.5",
147
+ children: [/* @__PURE__ */ d(h, {
148
+ htmlFor: "prGrade",
149
+ children: "Grade"
150
+ }), /* @__PURE__ */ d(m, {
151
+ id: "prGrade",
152
+ type: "number",
153
+ inputMode: "decimal",
154
+ step: "any",
155
+ className: "h-11 md:h-10",
156
+ value: L.grade,
157
+ onChange: (e) => R({
158
+ ...L,
159
+ grade: e.target.value
160
+ }),
161
+ placeholder: "Quality"
162
+ })]
163
+ }), /* @__PURE__ */ f("div", {
164
+ className: "grid gap-1.5",
165
+ children: [/* @__PURE__ */ d(h, {
166
+ htmlFor: "prDowntime",
167
+ children: "Downtime (hours)"
168
+ }), /* @__PURE__ */ d(m, {
169
+ id: "prDowntime",
170
+ type: "number",
171
+ inputMode: "decimal",
172
+ min: "0",
173
+ step: "any",
174
+ className: "h-11 md:h-10",
175
+ value: L.downtimeHours,
176
+ onChange: (e) => R({
177
+ ...L,
178
+ downtimeHours: e.target.value
179
+ }),
180
+ placeholder: "0"
181
+ })]
182
+ })]
183
+ }),
184
+ /* @__PURE__ */ f("div", {
185
+ className: "grid gap-1.5",
186
+ children: [/* @__PURE__ */ d(h, {
187
+ htmlFor: "prSource",
188
+ children: "Source"
189
+ }), /* @__PURE__ */ d(m, {
190
+ id: "prSource",
191
+ className: "h-11 md:h-10",
192
+ value: L.source,
193
+ onChange: (e) => R({
194
+ ...L,
195
+ source: e.target.value
196
+ }),
197
+ placeholder: "SCADA, Manual, Meter…"
198
+ })]
199
+ }),
200
+ /* @__PURE__ */ f("div", {
201
+ className: "grid gap-1.5",
202
+ children: [/* @__PURE__ */ d(h, {
203
+ htmlFor: "prNotes",
204
+ children: "Notes"
205
+ }), /* @__PURE__ */ d(D, {
206
+ id: "prNotes",
207
+ rows: 2,
208
+ value: L.notes,
209
+ onChange: (e) => R({
210
+ ...L,
211
+ notes: e.target.value
212
+ }),
213
+ placeholder: "Optional context about this period."
214
+ })]
215
+ }),
216
+ V && /* @__PURE__ */ d("p", {
217
+ role: "alert",
218
+ className: "text-sm text-status-error-text",
219
+ children: V
220
+ })
221
+ ]
222
+ }), /* @__PURE__ */ f(y, {
223
+ className: "max-md:flex-col-reverse max-md:gap-2",
224
+ children: [/* @__PURE__ */ d(p, {
225
+ type: "button",
226
+ variant: "outline",
227
+ className: "max-md:h-11",
228
+ onClick: Z,
229
+ children: "Cancel"
230
+ }), /* @__PURE__ */ d(p, {
231
+ type: "submit",
232
+ className: "max-md:h-11",
233
+ disabled: F.isPending,
234
+ children: F.isPending ? "Recording…" : "Record production"
235
+ })]
236
+ })]
237
+ })]
238
+ })
239
+ });
240
+ }
241
+ //#endregion
242
+ export { k as RecordProductionSheet };
243
+
244
+ //# sourceMappingURL=RecordProductionSheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordProductionSheet.js","names":[],"sources":["../../../src/theglobalfuel/components/RecordProductionSheet.tsx"],"sourcesContent":["/**\n * RecordProductionSheet — the \"Record production\" form (BOFF-3956).\n * @module theglobalfuel/components\n *\n * One form for every entry point (Production page, mobile dashboard, mobile\n * asset cards). Built on fe-libs `ResponsiveDialog`, so it is a centred modal on\n * tablet/desktop and a bottom sheet with a drag handle on phones (mock 21). On\n * phones the fields stack in a single column with full-width, thumb-sized\n * actions. Writes `theRecordProduction`; validation is the shared pure\n * `buildRecordProductionInput` so all entry points enforce identical rules.\n */\n\nimport { useState } from 'react';\nimport {\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { useTheAsset, useTheAssets, useTheRecordProduction, useNotify } from '../hooks';\nimport { formatEnumLabel } from '../utils/formatters';\nimport {\n PRODUCTION_UNITS,\n autoUnitForAsset,\n buildRecordProductionInput,\n emptyRecordProductionForm,\n withSelectedAssetOption,\n type RecordProductionFormState,\n} from '../utils/productionForm';\nimport type { TheProductionRecord, TheUnit } from '../types';\n\ninterface RecordProductionSheetProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Pre-select an asset (e.g. when opened from an asset card). */\n defaultAssetId?: string;\n /** Called after a record is saved. */\n onRecorded?: (record: TheProductionRecord) => void;\n}\n\n/** Asset picker page — same query key as the Production page, so it is shared from cache. */\nconst ASSET_PICKER_PAGE = { pagination: { limit: 100 } } as const;\n\nexport function RecordProductionSheet({\n open,\n onOpenChange,\n defaultAssetId,\n onRecorded,\n}: RecordProductionSheetProps) {\n const notify = useNotify();\n const assetsQuery = useTheAssets(ASSET_PICKER_PAGE);\n const recordProduction = useTheRecordProduction();\n const pickerAssets = assetsQuery.data?.items ?? [];\n\n const [form, setForm] = useState<RecordProductionFormState>(() =>\n emptyRecordProductionForm(defaultAssetId)\n );\n const [unitChosenByUser, setUnitChosenByUser] = useState(false);\n const [formError, setFormError] = useState<string | null>(null);\n\n // Every time the sheet opens it starts from a clean form for the requested\n // asset. Re-seeding is done while rendering (React's \"adjust state on prop\n // change\" pattern) rather than in an effect, so the first painted frame\n // already shows the fresh form.\n const seedKey = open ? `open:${defaultAssetId ?? ''}` : 'closed';\n const [prevSeedKey, setPrevSeedKey] = useState(seedKey);\n if (seedKey !== prevSeedKey) {\n setPrevSeedKey(seedKey);\n if (open) {\n setForm(emptyRecordProductionForm(defaultAssetId ?? ''));\n setUnitChosenByUser(false);\n setFormError(null);\n }\n }\n\n // The picker shows one page of assets. An asset selected from a card or deep\n // link may sit outside it, so it is resolved by id; the query only runs\n // while the selection is missing from the page.\n const pickedFromPage = pickerAssets.find((a) => a.id === form.assetId);\n const selectedById = useTheAsset(\n open && form.assetId && !pickedFromPage ? form.assetId : undefined\n );\n const selectedAsset = pickedFromPage ?? selectedById.data ?? null;\n const assetOptions = withSelectedAssetOption(pickerAssets, selectedAsset);\n\n // The unit defaults to the selected asset's capacity unit until the user picks\n // one. It is derived on every render rather than written into state, so it\n // also applies when the asset only resolves after the sheet opened, and the\n // value shown is always the value submitted.\n const autoUnit = autoUnitForAsset(selectedAsset, form.unit, unitChosenByUser);\n const effectiveUnit: TheUnit = autoUnit ?? form.unit;\n\n const close = () => onOpenChange(false);\n\n const handleRecord = async () => {\n const result = buildRecordProductionInput({ ...form, unit: effectiveUnit });\n if (!result.ok) {\n setFormError(result.error);\n notify.error(result.error);\n return;\n }\n setFormError(null);\n try {\n const record = await recordProduction.mutateAsync(result.input);\n notify.success('Production recorded');\n onRecorded?.(record);\n close();\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to record production.');\n notify.fromError(err);\n }\n };\n\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent data-testid=\"record-production-sheet\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Record production</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Log the volume produced by an asset over a reporting period.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n void handleRecord();\n }}\n >\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"prAsset\">Asset *</Label>\n <Select value={form.assetId} onValueChange={(v) => setForm({ ...form, assetId: v })}>\n <SelectTrigger id=\"prAsset\" className=\"h-11 md:h-10\">\n <SelectValue placeholder=\"Select an asset\" />\n </SelectTrigger>\n <SelectContent>\n {assetOptions.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"prStart\">Period start *</Label>\n <Input\n id=\"prStart\"\n type=\"date\"\n className=\"h-11 md:h-10\"\n value={form.periodStart}\n onChange={(e) => setForm({ ...form, periodStart: e.target.value })}\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"prEnd\">Period end *</Label>\n <Input\n id=\"prEnd\"\n type=\"date\"\n className=\"h-11 md:h-10\"\n value={form.periodEnd}\n onChange={(e) => setForm({ ...form, periodEnd: e.target.value })}\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-[minmax(0,1fr)_8rem] gap-2 md:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"prVolume\">Volume *</Label>\n <Input\n id=\"prVolume\"\n type=\"number\"\n inputMode=\"decimal\"\n min=\"0\"\n step=\"any\"\n className=\"h-11 text-lg tabular-nums md:h-10 md:text-sm\"\n value={form.volume}\n onChange={(e) => setForm({ ...form, volume: e.target.value })}\n placeholder=\"12500\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"prUnit\">Unit</Label>\n <Select\n value={effectiveUnit}\n onValueChange={(v) => {\n setUnitChosenByUser(true);\n setForm({ ...form, unit: v as TheUnit });\n }}\n >\n <SelectTrigger id=\"prUnit\" className=\"h-11 md:h-10\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {PRODUCTION_UNITS.map((u) => (\n <SelectItem key={u} value={u}>\n {formatEnumLabel(u)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"prGrade\">Grade</Label>\n <Input\n id=\"prGrade\"\n type=\"number\"\n inputMode=\"decimal\"\n step=\"any\"\n className=\"h-11 md:h-10\"\n value={form.grade}\n onChange={(e) => setForm({ ...form, grade: e.target.value })}\n placeholder=\"Quality\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"prDowntime\">Downtime (hours)</Label>\n <Input\n id=\"prDowntime\"\n type=\"number\"\n inputMode=\"decimal\"\n min=\"0\"\n step=\"any\"\n className=\"h-11 md:h-10\"\n value={form.downtimeHours}\n onChange={(e) => setForm({ ...form, downtimeHours: e.target.value })}\n placeholder=\"0\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"prSource\">Source</Label>\n <Input\n id=\"prSource\"\n className=\"h-11 md:h-10\"\n value={form.source}\n onChange={(e) => setForm({ ...form, source: e.target.value })}\n placeholder=\"SCADA, Manual, Meter…\"\n />\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"prNotes\">Notes</Label>\n <Textarea\n id=\"prNotes\"\n rows={2}\n value={form.notes}\n onChange={(e) => setForm({ ...form, notes: e.target.value })}\n placeholder=\"Optional context about this period.\"\n />\n </div>\n\n {formError && (\n <p role=\"alert\" className=\"text-sm text-status-error-text\">\n {formError}\n </p>\n )}\n </div>\n\n <ResponsiveDialogFooter className=\"max-md:flex-col-reverse max-md:gap-2\">\n <Button type=\"button\" variant=\"outline\" className=\"max-md:h-11\" onClick={close}>\n Cancel\n </Button>\n <Button type=\"submit\" className=\"max-md:h-11\" disabled={recordProduction.isPending}>\n {recordProduction.isPending ? 'Recording…' : 'Record production'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { FC } from 'react';
2
+ import { LucideIcon } from 'lucide-react';
3
+ import { TheCommodityType } from '../../types';
4
+
5
+ export declare const COMMODITY_ICON: Record<TheCommodityType, LucideIcon>;
6
+ interface CommodityThumbProps {
7
+ commodity: TheCommodityType;
8
+ size?: 'sm' | 'lg';
9
+ className?: string;
10
+ }
11
+ export declare const CommodityThumb: FC<CommodityThumbProps>;
12
+ export {};
13
+ //# sourceMappingURL=CommodityThumb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommodityThumb.d.ts","sourceRoot":"","sources":["../../../../src/theglobalfuel/components/mobile/CommodityThumb.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAcL,KAAK,UAAU,EAChB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,gBAAgB,EAAE,UAAU,CAc/D,CAAC;AAEF,UAAU,mBAAmB;IAC3B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAclD,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { cn as e } from "../../utils/cn.js";
2
+ import { Atom as t, BatteryCharging as n, CircuitBoard as r, Coins as i, Flame as a, Fuel as o, Gem as s, Layers as c, Leaf as l, Mountain as u, Pickaxe as d, Snowflake as f, Zap as p } from "lucide-react";
3
+ import { jsx as m } from "react/jsx-runtime";
4
+ //#region src/theglobalfuel/components/mobile/CommodityThumb.tsx
5
+ var h = {
6
+ CRUDE_OIL: o,
7
+ NATURAL_GAS: a,
8
+ LNG: f,
9
+ COAL: u,
10
+ ELECTRICITY: p,
11
+ HYDROGEN: t,
12
+ BIOFUEL: l,
13
+ IRON_ORE: d,
14
+ COPPER: r,
15
+ BAUXITE: c,
16
+ GOLD: i,
17
+ LITHIUM: n,
18
+ RARE_EARTH: s
19
+ }, g = ({ commodity: t, size: n = "lg", className: r }) => {
20
+ let i = h[t] ?? o;
21
+ return /* @__PURE__ */ m("span", {
22
+ "aria-hidden": "true",
23
+ className: e("grid shrink-0 place-items-center rounded-xl bg-bg-sunken text-text-secondary", n === "lg" ? "size-14" : "size-9", r),
24
+ children: /* @__PURE__ */ m(i, { className: n === "lg" ? "h-6 w-6" : "h-4 w-4" })
25
+ });
26
+ };
27
+ //#endregion
28
+ export { g as CommodityThumb };
29
+
30
+ //# sourceMappingURL=CommodityThumb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommodityThumb.js","names":[],"sources":["../../../../src/theglobalfuel/components/mobile/CommodityThumb.tsx"],"sourcesContent":["/**\n * CommodityThumb — square asset thumbnail for the phone layouts (BOFF-3956).\n * @module theglobalfuel/components/mobile\n *\n * Mock 21 shows a photo per asset. `TheAsset` carries no image today, so the\n * thumbnail is a commodity glyph on a sunken tile: it still lets an operator\n * tell an oil field from a copper mine at a glance, and it never shows a\n * fabricated photo.\n */\n\nimport type { FC } from 'react';\nimport {\n Atom,\n BatteryCharging,\n CircuitBoard,\n Coins,\n Flame,\n Fuel,\n Gem,\n Layers,\n Leaf,\n Mountain,\n Pickaxe,\n Snowflake,\n Zap,\n type LucideIcon,\n} from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport type { TheCommodityType } from '../../types';\n\nexport const COMMODITY_ICON: Record<TheCommodityType, LucideIcon> = {\n CRUDE_OIL: Fuel,\n NATURAL_GAS: Flame,\n LNG: Snowflake,\n COAL: Mountain,\n ELECTRICITY: Zap,\n HYDROGEN: Atom,\n BIOFUEL: Leaf,\n IRON_ORE: Pickaxe,\n COPPER: CircuitBoard,\n BAUXITE: Layers,\n GOLD: Coins,\n LITHIUM: BatteryCharging,\n RARE_EARTH: Gem,\n};\n\ninterface CommodityThumbProps {\n commodity: TheCommodityType;\n size?: 'sm' | 'lg';\n className?: string;\n}\n\nexport const CommodityThumb: FC<CommodityThumbProps> = ({ commodity, size = 'lg', className }) => {\n const Icon = COMMODITY_ICON[commodity] ?? Fuel;\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\n 'grid shrink-0 place-items-center rounded-xl bg-bg-sunken text-text-secondary',\n size === 'lg' ? 'size-14' : 'size-9',\n className\n )}\n >\n <Icon className={size === 'lg' ? 'h-6 w-6' : 'h-4 w-4'} />\n </span>\n );\n};\n"],"mappings":";;;;AA8BA,IAAa,IAAuD;CAClE,WAAW;CACX,aAAa;CACb,KAAK;CACL,MAAM;CACN,aAAa;CACb,UAAU;CACV,SAAS;CACT,UAAU;CACV,QAAQ;CACR,SAAS;CACT,MAAM;CACN,SAAS;CACT,YAAY;CACb,EAQY,KAA2C,EAAE,cAAW,UAAO,MAAM,mBAAgB;CAChG,IAAM,IAAO,EAAe,MAAc;AAC1C,QACE,kBAAC,QAAD;EACE,eAAY;EACZ,WAAW,EACT,gFACA,MAAS,OAAO,YAAY,UAC5B,EACD;YAED,kBAAC,GAAD,EAAM,WAAW,MAAS,OAAO,YAAY,WAAa,CAAA;EACrD,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { FC } from 'react';
2
+ import { TheAsset } from '../../types';
3
+
4
+ interface MobileAssetListProps {
5
+ rows: readonly TheAsset[];
6
+ onOpen: (asset: TheAsset) => void;
7
+ onRecordProduction: (asset: TheAsset) => void;
8
+ }
9
+ export declare const MobileAssetList: FC<MobileAssetListProps>;
10
+ export {};
11
+ //# sourceMappingURL=MobileAssetList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MobileAssetList.d.ts","sourceRoot":"","sources":["../../../../src/theglobalfuel/components/mobile/MobileAssetList.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAmBhC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAiE5C,UAAU,oBAAoB;IAC5B,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC1B,MAAM,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IAClC,kBAAkB,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC/C;AAED,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CA8EpD,CAAC"}
@@ -0,0 +1,102 @@
1
+ import { formatEnumLabel as e, formatVolume as t } from "../../utils/formatters.js";
2
+ import { StatusBadge as n } from "../StatusBadge.js";
3
+ import { useTheAssetProductionHistory as r, useTheProductionRecords as i, useTheReserveEstimates as a } from "../../hooks/useTheGlobalFuelApi.js";
4
+ import { latestDailyProductionByAsset as o, latestReserveByAsset as s } from "../../utils/mobile.js";
5
+ import "../../hooks/index.js";
6
+ import { CommodityThumb as c } from "./CommodityThumb.js";
7
+ import { MobileChip as l } from "./MobileChip.js";
8
+ import { useMemo as u } from "react";
9
+ import { ChevronRight as d, MapPin as f, Plus as p } from "lucide-react";
10
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
11
+ import { Button as g } from "@burdenoff/fe-libs/ui";
12
+ //#region src/theglobalfuel/components/mobile/MobileAssetList.tsx
13
+ var _ = { pagination: { limit: 200 } }, v = { limit: 200 }, y = { limit: 1 }, b = ({ assetId: e, sharedDaily: n, sharedReserve: i, productionTruncated: c, reservesTruncated: l }) => {
14
+ let u = r(e, { enabled: c }), d = a(e, "PROVED", y, { enabled: !i && l }), f = u.data ? o(u.data.items).get(e) : void 0, p = u.data ? f : n, g = i ?? s(d.data?.items ?? []).get(e);
15
+ return /* @__PURE__ */ h("dl", {
16
+ className: "grid min-w-0 flex-1 grid-cols-2 gap-3 text-xs",
17
+ children: [/* @__PURE__ */ h("div", {
18
+ className: "min-w-0",
19
+ children: [/* @__PURE__ */ m("dt", {
20
+ className: "text-text-tertiary",
21
+ children: "Daily production"
22
+ }), /* @__PURE__ */ m("dd", {
23
+ className: "truncate font-medium tabular-nums text-text-primary",
24
+ children: p ? `${t(p.perDay, p.unit)}/day` : "—"
25
+ })]
26
+ }), /* @__PURE__ */ h("div", {
27
+ className: "min-w-0",
28
+ children: [/* @__PURE__ */ m("dt", {
29
+ className: "text-text-tertiary",
30
+ children: "Reserves (1P)"
31
+ }), /* @__PURE__ */ m("dd", {
32
+ className: "truncate font-medium tabular-nums text-text-primary",
33
+ children: g ? t(g.recoverable, g.unit) : "—"
34
+ })]
35
+ })]
36
+ });
37
+ }, x = ({ rows: t, onOpen: r, onRecordProduction: y }) => {
38
+ let x = i(_), S = a(void 0, "PROVED", v), C = u(() => o(x.data?.items ?? []), [x.data]), w = u(() => s(S.data?.items ?? []), [S.data]), T = x.data?.pageInfo.hasMore === !0, E = S.data?.pageInfo.hasMore === !0;
39
+ return /* @__PURE__ */ m("ul", {
40
+ className: "flex flex-col gap-3",
41
+ "data-testid": "theglobalfuel-mobile-assets",
42
+ children: t.map((t) => /* @__PURE__ */ h("li", {
43
+ className: "rounded-2xl border border-border-seam bg-bg-surface shadow-sm",
44
+ "data-testid": "theglobalfuel-mobile-asset-card",
45
+ children: [/* @__PURE__ */ h("button", {
46
+ type: "button",
47
+ onClick: () => r(t),
48
+ "aria-label": `Open ${t.name}`,
49
+ className: "flex w-full items-start gap-3 rounded-t-2xl p-4 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--color-focus-ring)]",
50
+ children: [
51
+ /* @__PURE__ */ m(c, { commodity: t.commodity }),
52
+ /* @__PURE__ */ h("div", {
53
+ className: "min-w-0 flex-1",
54
+ children: [/* @__PURE__ */ h("div", {
55
+ className: "flex items-start justify-between gap-2",
56
+ children: [/* @__PURE__ */ h("div", {
57
+ className: "min-w-0",
58
+ children: [/* @__PURE__ */ m("p", {
59
+ className: "truncate font-semibold text-text-primary",
60
+ children: t.name
61
+ }), t.code && /* @__PURE__ */ m("p", {
62
+ className: "truncate text-xs text-text-tertiary",
63
+ children: t.code
64
+ })]
65
+ }), /* @__PURE__ */ m(n, {
66
+ status: t.status,
67
+ className: "shrink-0"
68
+ })]
69
+ }), /* @__PURE__ */ h("div", {
70
+ className: "mt-2 flex flex-wrap gap-1.5",
71
+ children: [/* @__PURE__ */ m(l, { children: e(t.commodity) }), t.location && /* @__PURE__ */ m(l, {
72
+ icon: /* @__PURE__ */ m(f, { className: "h-3 w-3 shrink-0" }),
73
+ children: t.location
74
+ })]
75
+ })]
76
+ }),
77
+ /* @__PURE__ */ m(d, { className: "mt-1 h-4 w-4 shrink-0 text-text-tertiary" })
78
+ ]
79
+ }), /* @__PURE__ */ h("div", {
80
+ className: "flex items-end justify-between gap-3 border-t border-border-seam px-4 py-3",
81
+ children: [/* @__PURE__ */ m(b, {
82
+ assetId: t.id,
83
+ sharedDaily: C.get(t.id),
84
+ sharedReserve: w.get(t.id),
85
+ productionTruncated: T,
86
+ reservesTruncated: E
87
+ }), /* @__PURE__ */ h(g, {
88
+ size: "sm",
89
+ variant: "outline",
90
+ className: "h-9 shrink-0",
91
+ onClick: () => y(t),
92
+ "aria-label": `Record production for ${t.name}`,
93
+ children: [/* @__PURE__ */ m(p, { className: "mr-1 h-3.5 w-3.5" }), " Record"]
94
+ })]
95
+ })]
96
+ }, t.id))
97
+ });
98
+ };
99
+ //#endregion
100
+ export { x as MobileAssetList };
101
+
102
+ //# sourceMappingURL=MobileAssetList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MobileAssetList.js","names":[],"sources":["../../../../src/theglobalfuel/components/mobile/MobileAssetList.tsx"],"sourcesContent":["/**\n * MobileAssetList — the phone assets list from mock 21 (BOFF-3956).\n * @module theglobalfuel/components/mobile\n *\n * One card per asset: commodity thumbnail, name + code, commodity / location\n * chips, latest daily production, booked PROVED reserves and lifecycle status,\n * plus a one-tap \"Record\" action that opens the record-production sheet for\n * that asset. Production and reserves come first from the same workspace-wide\n * list queries (and React Query cache keys) the dashboard uses. Those are one\n * page each. When the production page is truncated (`hasMore`), each card\n * reads its own asset's production history; when the reserves page is\n * truncated, a card whose asset is missing from it reads its own latest\n * estimate. A busy workspace therefore never shows a blank or stale figure for\n * an asset that has data.\n */\n\nimport type { FC } from 'react';\nimport { useMemo } from 'react';\nimport { ChevronRight, MapPin, Plus } from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { StatusBadge } from '../StatusBadge';\nimport { CommodityThumb } from './CommodityThumb';\nimport { MobileChip } from './MobileChip';\nimport {\n useTheAssetProductionHistory,\n useTheProductionRecords,\n useTheReserveEstimates,\n} from '../../hooks';\nimport { formatEnumLabel, formatVolume } from '../../utils/formatters';\nimport {\n latestDailyProductionByAsset,\n latestReserveByAsset,\n type DailyProduction,\n type LatestReserve,\n} from '../../utils/mobile';\nimport type { TheAsset } from '../../types';\n\n/** Same page sizes/keys as the dashboard so the phone list reads from cache. */\nconst PRODUCTION_PAGE = { pagination: { limit: 200 } } as const;\nconst RESERVES_PAGE = { limit: 200 } as const;\n/**\n * Per-asset reserves fallback: reserves are listed newest `asOfDate` first, so\n * one row is the latest. Production has no such order (it is listed by\n * `periodStart` while the card shows the latest `periodEnd`), so its fallback\n * reads the asset's full history via `useTheAssetProductionHistory`.\n */\nconst ASSET_RESERVES_PAGE = { limit: 1 } as const;\n\ninterface AssetFiguresProps {\n assetId: string;\n sharedDaily: DailyProduction | undefined;\n sharedReserve: LatestReserve | undefined;\n /** True when the shared production page may not hold this asset's latest record. */\n productionTruncated: boolean;\n /** True when the shared page may have left this asset's reserves out. */\n reservesTruncated: boolean;\n}\n\nconst AssetFigures: FC<AssetFiguresProps> = ({\n assetId,\n sharedDaily,\n sharedReserve,\n productionTruncated,\n reservesTruncated,\n}) => {\n // The shared production page is ordered by periodStart, so once it is\n // truncated even an asset that appears in it may have a later-ending record\n // off the page: read that asset's own history and prefer it once loaded.\n const ownProduction = useTheAssetProductionHistory(assetId, {\n enabled: productionTruncated,\n });\n // Reserves are listed newest asOfDate first workspace-wide, so an asset that\n // appears on the shared page already shows its latest estimate.\n const ownReserves = useTheReserveEstimates(assetId, 'PROVED', ASSET_RESERVES_PAGE, {\n enabled: !sharedReserve && reservesTruncated,\n });\n const ownDaily = ownProduction.data\n ? latestDailyProductionByAsset(ownProduction.data.items).get(assetId)\n : undefined;\n const daily = ownProduction.data ? ownDaily : sharedDaily;\n const reserve = sharedReserve ?? latestReserveByAsset(ownReserves.data?.items ?? []).get(assetId);\n\n return (\n <dl className=\"grid min-w-0 flex-1 grid-cols-2 gap-3 text-xs\">\n <div className=\"min-w-0\">\n <dt className=\"text-text-tertiary\">Daily production</dt>\n <dd className=\"truncate font-medium tabular-nums text-text-primary\">\n {daily ? `${formatVolume(daily.perDay, daily.unit)}/day` : '—'}\n </dd>\n </div>\n <div className=\"min-w-0\">\n <dt className=\"text-text-tertiary\">Reserves (1P)</dt>\n <dd className=\"truncate font-medium tabular-nums text-text-primary\">\n {reserve ? formatVolume(reserve.recoverable, reserve.unit) : '—'}\n </dd>\n </div>\n </dl>\n );\n};\n\ninterface MobileAssetListProps {\n rows: readonly TheAsset[];\n onOpen: (asset: TheAsset) => void;\n onRecordProduction: (asset: TheAsset) => void;\n}\n\nexport const MobileAssetList: FC<MobileAssetListProps> = ({ rows, onOpen, onRecordProduction }) => {\n const production = useTheProductionRecords(PRODUCTION_PAGE);\n const reserves = useTheReserveEstimates(undefined, 'PROVED', RESERVES_PAGE);\n\n const dailyByAsset = useMemo(\n () => latestDailyProductionByAsset(production.data?.items ?? []),\n [production.data]\n );\n const reserveByAsset = useMemo(\n () => latestReserveByAsset(reserves.data?.items ?? []),\n [reserves.data]\n );\n\n // Only fall back per asset once the shared page has loaded and reported\n // that it did not include everything.\n const productionTruncated = production.data?.pageInfo.hasMore === true;\n const reservesTruncated = reserves.data?.pageInfo.hasMore === true;\n\n return (\n <ul className=\"flex flex-col gap-3\" data-testid=\"theglobalfuel-mobile-assets\">\n {rows.map((asset) => {\n return (\n <li\n key={asset.id}\n className=\"rounded-2xl border border-border-seam bg-bg-surface shadow-sm\"\n data-testid=\"theglobalfuel-mobile-asset-card\"\n >\n <button\n type=\"button\"\n onClick={() => onOpen(asset)}\n aria-label={`Open ${asset.name}`}\n className=\"flex w-full items-start gap-3 rounded-t-2xl p-4 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <CommodityThumb commodity={asset.commodity} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <p className=\"truncate font-semibold text-text-primary\">{asset.name}</p>\n {asset.code && (\n <p className=\"truncate text-xs text-text-tertiary\">{asset.code}</p>\n )}\n </div>\n <StatusBadge status={asset.status} className=\"shrink-0\" />\n </div>\n <div className=\"mt-2 flex flex-wrap gap-1.5\">\n <MobileChip>{formatEnumLabel(asset.commodity)}</MobileChip>\n {asset.location && (\n <MobileChip icon={<MapPin className=\"h-3 w-3 shrink-0\" />}>\n {asset.location}\n </MobileChip>\n )}\n </div>\n </div>\n <ChevronRight className=\"mt-1 h-4 w-4 shrink-0 text-text-tertiary\" />\n </button>\n <div className=\"flex items-end justify-between gap-3 border-t border-border-seam px-4 py-3\">\n <AssetFigures\n assetId={asset.id}\n sharedDaily={dailyByAsset.get(asset.id)}\n sharedReserve={reserveByAsset.get(asset.id)}\n productionTruncated={productionTruncated}\n reservesTruncated={reservesTruncated}\n />\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-9 shrink-0\"\n onClick={() => onRecordProduction(asset)}\n aria-label={`Record production for ${asset.name}`}\n >\n <Plus className=\"mr-1 h-3.5 w-3.5\" /> Record\n </Button>\n </div>\n </li>\n );\n })}\n </ul>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAsCA,IAAM,IAAkB,EAAE,YAAY,EAAE,OAAO,KAAK,EAAE,EAChD,IAAgB,EAAE,OAAO,KAAK,EAO9B,IAAsB,EAAE,OAAO,GAAG,EAYlC,KAAuC,EAC3C,YACA,gBACA,kBACA,wBACA,2BACI;CAIJ,IAAM,IAAgB,EAA6B,GAAS,EAC1D,SAAS,GACV,CAAC,EAGI,IAAc,EAAuB,GAAS,UAAU,GAAqB,EACjF,SAAS,CAAC,KAAiB,GAC5B,CAAC,EACI,IAAW,EAAc,OAC3B,EAA6B,EAAc,KAAK,MAAM,CAAC,IAAI,EAAQ,GACnE,KAAA,GACE,IAAQ,EAAc,OAAO,IAAW,GACxC,IAAU,KAAiB,EAAqB,EAAY,MAAM,SAAS,EAAE,CAAC,CAAC,IAAI,EAAQ;AAEjG,QACE,kBAAC,MAAD;EAAI,WAAU;YAAd,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,MAAD;IAAI,WAAU;cAAqB;IAAqB,CAAA,EACxD,kBAAC,MAAD;IAAI,WAAU;cACX,IAAQ,GAAG,EAAa,EAAM,QAAQ,EAAM,KAAK,CAAC,QAAQ;IACxD,CAAA,CACD;MACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,MAAD;IAAI,WAAU;cAAqB;IAAkB,CAAA,EACrD,kBAAC,MAAD;IAAI,WAAU;cACX,IAAU,EAAa,EAAQ,aAAa,EAAQ,KAAK,GAAG;IAC1D,CAAA,CACD;KACH;;GAUI,KAA6C,EAAE,SAAM,WAAQ,4BAAyB;CACjG,IAAM,IAAa,EAAwB,EAAgB,EACrD,IAAW,EAAuB,KAAA,GAAW,UAAU,EAAc,EAErE,IAAe,QACb,EAA6B,EAAW,MAAM,SAAS,EAAE,CAAC,EAChE,CAAC,EAAW,KAAK,CAClB,EACK,IAAiB,QACf,EAAqB,EAAS,MAAM,SAAS,EAAE,CAAC,EACtD,CAAC,EAAS,KAAK,CAChB,EAIK,IAAsB,EAAW,MAAM,SAAS,YAAY,IAC5D,IAAoB,EAAS,MAAM,SAAS,YAAY;AAE9D,QACE,kBAAC,MAAD;EAAI,WAAU;EAAsB,eAAY;YAC7C,EAAK,KAAK,MAEP,kBAAC,MAAD;GAEE,WAAU;GACV,eAAY;aAHd,CAKE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAO,EAAM;IAC5B,cAAY,QAAQ,EAAM;IAC1B,WAAU;cAJZ;KAME,kBAAC,GAAD,EAAgB,WAAW,EAAM,WAAa,CAAA;KAC9C,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBAA4C,EAAM;SAAS,CAAA,EACvE,EAAM,QACL,kBAAC,KAAD;SAAG,WAAU;mBAAuC,EAAM;SAAS,CAAA,CAEjE;WACN,kBAAC,GAAD;QAAa,QAAQ,EAAM;QAAQ,WAAU;QAAa,CAAA,CACtD;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAA,UAAa,EAAgB,EAAM,UAAU,EAAc,CAAA,EAC1D,EAAM,YACL,kBAAC,GAAD;QAAY,MAAM,kBAAC,GAAD,EAAQ,WAAU,oBAAqB,CAAA;kBACtD,EAAM;QACI,CAAA,CAEX;SACF;;KACN,kBAAC,GAAD,EAAc,WAAU,4CAA6C,CAAA;KAC9D;OACT,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KACE,SAAS,EAAM;KACf,aAAa,EAAa,IAAI,EAAM,GAAG;KACvC,eAAe,EAAe,IAAI,EAAM,GAAG;KACtB;KACF;KACnB,CAAA,EACF,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,WAAU;KACV,eAAe,EAAmB,EAAM;KACxC,cAAY,yBAAyB,EAAM;eAL7C,CAOE,kBAAC,GAAD,EAAM,WAAU,oBAAqB,CAAA,EAAA,UAC9B;OACL;MACH;KAlDE,EAAM,GAkDR,CAEP;EACC,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { FC, ReactNode } from 'react';
2
+
3
+ interface MobileChipProps {
4
+ icon?: ReactNode;
5
+ children: ReactNode;
6
+ className?: string;
7
+ }
8
+ export declare const MobileChip: FC<MobileChipProps>;
9
+ export {};
10
+ //# sourceMappingURL=MobileChip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MobileChip.d.ts","sourceRoot":"","sources":["../../../../src/theglobalfuel/components/mobile/MobileChip.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG3C,UAAU,eAAe;IACvB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAU1C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { cn as e } from "../../utils/cn.js";
2
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ //#region src/theglobalfuel/components/mobile/MobileChip.tsx
4
+ var r = ({ icon: r, children: i, className: a }) => /* @__PURE__ */ n("span", {
5
+ className: e("inline-flex max-w-full items-center gap-1 rounded-full border border-border-seam bg-bg-surface px-2 py-0.5 text-xs text-text-secondary", a),
6
+ children: [r, /* @__PURE__ */ t("span", {
7
+ className: "truncate",
8
+ children: i
9
+ })]
10
+ });
11
+ //#endregion
12
+ export { r as MobileChip };
13
+
14
+ //# sourceMappingURL=MobileChip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MobileChip.js","names":[],"sources":["../../../../src/theglobalfuel/components/mobile/MobileChip.tsx"],"sourcesContent":["/**\n * MobileChip — compact metadata chip (commodity, location, side) for the phone\n * cards in mock 21 (BOFF-3956).\n * @module theglobalfuel/components/mobile\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { cn } from '../../utils/cn';\n\ninterface MobileChipProps {\n icon?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\nexport const MobileChip: FC<MobileChipProps> = ({ icon, children, className }) => (\n <span\n className={cn(\n 'inline-flex max-w-full items-center gap-1 rounded-full border border-border-seam bg-bg-surface px-2 py-0.5 text-xs text-text-secondary',\n className\n )}\n >\n {icon}\n <span className=\"truncate\">{children}</span>\n </span>\n);\n"],"mappings":";;;AAeA,IAAa,KAAmC,EAAE,SAAM,aAAU,mBAChE,kBAAC,QAAD;CACE,WAAW,EACT,0IACA,EACD;WAJH,CAMG,GACD,kBAAC,QAAD;EAAM,WAAU;EAAY;EAAgB,CAAA,CACvC"}
@@ -0,0 +1,10 @@
1
+ import { FC } from 'react';
2
+ import { TheOfftakeContract } from '../../types';
3
+
4
+ interface MobileContractListProps {
5
+ rows: readonly TheOfftakeContract[];
6
+ onOpen: (contract: TheOfftakeContract) => void;
7
+ }
8
+ export declare const MobileContractList: FC<MobileContractListProps>;
9
+ export {};
10
+ //# sourceMappingURL=MobileContractList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MobileContractList.d.ts","sourceRoot":"","sources":["../../../../src/theglobalfuel/components/mobile/MobileContractList.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAQhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,UAAU,uBAAuB;IAC/B,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpC,MAAM,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;CAChD;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CA2C1D,CAAC"}