@burdenoff/microfe-theglobalfuel 2026.705.5 → 2026.709.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/README.md +3 -0
  2. package/dist/dev/main.d.ts +2 -0
  3. package/dist/dev/main.d.ts.map +1 -0
  4. package/dist/generated/global-operations.d.ts +2 -0
  5. package/dist/generated/global-operations.d.ts.map +1 -0
  6. package/dist/generated/global-types.d.ts +18199 -0
  7. package/dist/generated/global-types.d.ts.map +1 -0
  8. package/dist/generated/wspace-operations.d.ts +2 -0
  9. package/dist/generated/wspace-operations.d.ts.map +1 -0
  10. package/dist/generated/wspace-types.d.ts +43046 -0
  11. package/dist/generated/wspace-types.d.ts.map +1 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +3 -1
  15. package/dist/theglobalfuel/TheGlobalFuelRoot.d.ts +5 -0
  16. package/dist/theglobalfuel/TheGlobalFuelRoot.d.ts.map +1 -0
  17. package/dist/theglobalfuel/TheGlobalFuelRoot.js +106 -104
  18. package/dist/theglobalfuel/TheGlobalFuelRoot.js.map +1 -1
  19. package/dist/theglobalfuel/TheGlobalFuelRoutes.d.ts +4 -0
  20. package/dist/theglobalfuel/TheGlobalFuelRoutes.d.ts.map +1 -0
  21. package/dist/theglobalfuel/TheGlobalFuelRoutes.js +60 -38
  22. package/dist/theglobalfuel/TheGlobalFuelRoutes.js.map +1 -1
  23. package/dist/theglobalfuel/components/DataTable.d.ts +30 -0
  24. package/dist/theglobalfuel/components/DataTable.d.ts.map +1 -0
  25. package/dist/theglobalfuel/components/DataTable.js.map +1 -1
  26. package/dist/theglobalfuel/components/EmptyState.d.ts +18 -0
  27. package/dist/theglobalfuel/components/EmptyState.d.ts.map +1 -0
  28. package/dist/theglobalfuel/components/EvidenceUpload.d.ts +14 -0
  29. package/dist/theglobalfuel/components/EvidenceUpload.d.ts.map +1 -0
  30. package/dist/theglobalfuel/components/FileLink.d.ts +15 -0
  31. package/dist/theglobalfuel/components/FileLink.d.ts.map +1 -0
  32. package/dist/theglobalfuel/components/FilterTabs.d.ts +18 -0
  33. package/dist/theglobalfuel/components/FilterTabs.d.ts.map +1 -0
  34. package/dist/theglobalfuel/components/MetricsCard.d.ts +23 -0
  35. package/dist/theglobalfuel/components/MetricsCard.d.ts.map +1 -0
  36. package/dist/theglobalfuel/components/MiniBar.d.ts +16 -0
  37. package/dist/theglobalfuel/components/MiniBar.d.ts.map +1 -0
  38. package/dist/theglobalfuel/components/PageLayout.d.ts +18 -0
  39. package/dist/theglobalfuel/components/PageLayout.d.ts.map +1 -0
  40. package/dist/theglobalfuel/components/PageLayout.js +2 -1
  41. package/dist/theglobalfuel/components/PageLayout.js.map +1 -1
  42. package/dist/theglobalfuel/components/Pagination.d.ts +22 -0
  43. package/dist/theglobalfuel/components/Pagination.d.ts.map +1 -0
  44. package/dist/theglobalfuel/components/StateViews.d.ts +24 -0
  45. package/dist/theglobalfuel/components/StateViews.d.ts.map +1 -0
  46. package/dist/theglobalfuel/components/StatusBadge.d.ts +9 -0
  47. package/dist/theglobalfuel/components/StatusBadge.d.ts.map +1 -0
  48. package/dist/theglobalfuel/components/Tabs.d.ts +17 -0
  49. package/dist/theglobalfuel/components/Tabs.d.ts.map +1 -0
  50. package/dist/theglobalfuel/components/TheDiscussion.d.ts +18 -0
  51. package/dist/theglobalfuel/components/TheDiscussion.d.ts.map +1 -0
  52. package/dist/theglobalfuel/components/TheTags.d.ts +17 -0
  53. package/dist/theglobalfuel/components/TheTags.d.ts.map +1 -0
  54. package/dist/theglobalfuel/components/WorldMap.d.ts +18 -0
  55. package/dist/theglobalfuel/components/WorldMap.d.ts.map +1 -0
  56. package/dist/theglobalfuel/components/WorldMap.js.map +1 -1
  57. package/dist/theglobalfuel/components/index.d.ts +21 -0
  58. package/dist/theglobalfuel/components/index.d.ts.map +1 -0
  59. package/dist/theglobalfuel/components/viz/AllocationBar.d.ts +21 -0
  60. package/dist/theglobalfuel/components/viz/AllocationBar.d.ts.map +1 -0
  61. package/dist/theglobalfuel/components/viz/AreaChart.d.ts +18 -0
  62. package/dist/theglobalfuel/components/viz/AreaChart.d.ts.map +1 -0
  63. package/dist/theglobalfuel/components/viz/AvatarStack.d.ts +13 -0
  64. package/dist/theglobalfuel/components/viz/AvatarStack.d.ts.map +1 -0
  65. package/dist/theglobalfuel/components/viz/BarChart.d.ts +17 -0
  66. package/dist/theglobalfuel/components/viz/BarChart.d.ts.map +1 -0
  67. package/dist/theglobalfuel/components/viz/CertificateCard.d.ts +14 -0
  68. package/dist/theglobalfuel/components/viz/CertificateCard.d.ts.map +1 -0
  69. package/dist/theglobalfuel/components/viz/DonutChart.d.ts +20 -0
  70. package/dist/theglobalfuel/components/viz/DonutChart.d.ts.map +1 -0
  71. package/dist/theglobalfuel/components/viz/HBarFunnel.d.ts +17 -0
  72. package/dist/theglobalfuel/components/viz/HBarFunnel.d.ts.map +1 -0
  73. package/dist/theglobalfuel/components/viz/Heatmap.d.ts +26 -0
  74. package/dist/theglobalfuel/components/viz/Heatmap.d.ts.map +1 -0
  75. package/dist/theglobalfuel/components/viz/KanbanBoard.d.ts +17 -0
  76. package/dist/theglobalfuel/components/viz/KanbanBoard.d.ts.map +1 -0
  77. package/dist/theglobalfuel/components/viz/LineChart.d.ts +20 -0
  78. package/dist/theglobalfuel/components/viz/LineChart.d.ts.map +1 -0
  79. package/dist/theglobalfuel/components/viz/OrgTree.d.ts +14 -0
  80. package/dist/theglobalfuel/components/viz/OrgTree.d.ts.map +1 -0
  81. package/dist/theglobalfuel/components/viz/PathSteps.d.ts +17 -0
  82. package/dist/theglobalfuel/components/viz/PathSteps.d.ts.map +1 -0
  83. package/dist/theglobalfuel/components/viz/ProgressRing.d.ts +20 -0
  84. package/dist/theglobalfuel/components/viz/ProgressRing.d.ts.map +1 -0
  85. package/dist/theglobalfuel/components/viz/RatingStars.d.ts +14 -0
  86. package/dist/theglobalfuel/components/viz/RatingStars.d.ts.map +1 -0
  87. package/dist/theglobalfuel/components/viz/SegmentedTabs.d.ts +26 -0
  88. package/dist/theglobalfuel/components/viz/SegmentedTabs.d.ts.map +1 -0
  89. package/dist/theglobalfuel/components/viz/SkillBar.d.ts +17 -0
  90. package/dist/theglobalfuel/components/viz/SkillBar.d.ts.map +1 -0
  91. package/dist/theglobalfuel/components/viz/Sparkline.d.ts +16 -0
  92. package/dist/theglobalfuel/components/viz/Sparkline.d.ts.map +1 -0
  93. package/dist/theglobalfuel/components/viz/StatCard.d.ts +22 -0
  94. package/dist/theglobalfuel/components/viz/StatCard.d.ts.map +1 -0
  95. package/dist/theglobalfuel/components/viz/StepProgress.d.ts +17 -0
  96. package/dist/theglobalfuel/components/viz/StepProgress.d.ts.map +1 -0
  97. package/dist/theglobalfuel/components/viz/Timeline.d.ts +21 -0
  98. package/dist/theglobalfuel/components/viz/Timeline.d.ts.map +1 -0
  99. package/dist/theglobalfuel/components/viz/index.d.ts +35 -0
  100. package/dist/theglobalfuel/components/viz/index.d.ts.map +1 -0
  101. package/dist/theglobalfuel/components/viz/lib/Avatar.d.ts +15 -0
  102. package/dist/theglobalfuel/components/viz/lib/Avatar.d.ts.map +1 -0
  103. package/dist/theglobalfuel/components/viz/lib/CartesianFrame.d.ts +44 -0
  104. package/dist/theglobalfuel/components/viz/lib/CartesianFrame.d.ts.map +1 -0
  105. package/dist/theglobalfuel/components/viz/lib/ResponsiveSvg.d.ts +27 -0
  106. package/dist/theglobalfuel/components/viz/lib/ResponsiveSvg.d.ts.map +1 -0
  107. package/dist/theglobalfuel/components/viz/lib/format.d.ts +10 -0
  108. package/dist/theglobalfuel/components/viz/lib/format.d.ts.map +1 -0
  109. package/dist/theglobalfuel/components/viz/lib/geometry.d.ts +41 -0
  110. package/dist/theglobalfuel/components/viz/lib/geometry.d.ts.map +1 -0
  111. package/dist/theglobalfuel/components/viz/lib/hooks.d.ts +18 -0
  112. package/dist/theglobalfuel/components/viz/lib/hooks.d.ts.map +1 -0
  113. package/dist/theglobalfuel/components/viz/lib/palette.d.ts +31 -0
  114. package/dist/theglobalfuel/components/viz/lib/palette.d.ts.map +1 -0
  115. package/dist/theglobalfuel/components/viz/lib/types.d.ts +27 -0
  116. package/dist/theglobalfuel/components/viz/lib/types.d.ts.map +1 -0
  117. package/dist/theglobalfuel/context/TheGlobalFuelContext.d.ts +16 -0
  118. package/dist/theglobalfuel/context/TheGlobalFuelContext.d.ts.map +1 -0
  119. package/dist/theglobalfuel/context/index.d.ts +6 -0
  120. package/dist/theglobalfuel/context/index.d.ts.map +1 -0
  121. package/dist/theglobalfuel/hooks/index.d.ts +15 -0
  122. package/dist/theglobalfuel/hooks/index.d.ts.map +1 -0
  123. package/dist/theglobalfuel/hooks/index.js +4 -0
  124. package/dist/theglobalfuel/hooks/useCursorPager.d.ts +26 -0
  125. package/dist/theglobalfuel/hooks/useCursorPager.d.ts.map +1 -0
  126. package/dist/theglobalfuel/hooks/useNotify.d.ts +23 -0
  127. package/dist/theglobalfuel/hooks/useNotify.d.ts.map +1 -0
  128. package/dist/theglobalfuel/hooks/useTheAnalytics.d.ts +38 -0
  129. package/dist/theglobalfuel/hooks/useTheAnalytics.d.ts.map +1 -0
  130. package/dist/theglobalfuel/hooks/useTheAnalytics.js +46 -0
  131. package/dist/theglobalfuel/hooks/useTheAnalytics.js.map +1 -0
  132. package/dist/theglobalfuel/hooks/useTheComments.d.ts +36 -0
  133. package/dist/theglobalfuel/hooks/useTheComments.d.ts.map +1 -0
  134. package/dist/theglobalfuel/hooks/useTheFiles.d.ts +47 -0
  135. package/dist/theglobalfuel/hooks/useTheFiles.d.ts.map +1 -0
  136. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts +79 -0
  137. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts.map +1 -0
  138. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js +2 -9
  139. package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js.map +1 -1
  140. package/dist/theglobalfuel/hooks/useTheNativeControls.d.ts +20 -0
  141. package/dist/theglobalfuel/hooks/useTheNativeControls.d.ts.map +1 -0
  142. package/dist/theglobalfuel/hooks/useTheNativeControls.js +22 -0
  143. package/dist/theglobalfuel/hooks/useTheNativeControls.js.map +1 -0
  144. package/dist/theglobalfuel/hooks/useThePageView.d.ts +10 -0
  145. package/dist/theglobalfuel/hooks/useThePageView.d.ts.map +1 -0
  146. package/dist/theglobalfuel/hooks/useThePageView.js +13 -0
  147. package/dist/theglobalfuel/hooks/useThePageView.js.map +1 -0
  148. package/dist/theglobalfuel/hooks/useTheTags.d.ts +44 -0
  149. package/dist/theglobalfuel/hooks/useTheTags.d.ts.map +1 -0
  150. package/dist/theglobalfuel/hooks/useTheTranslation.d.ts +4 -0
  151. package/dist/theglobalfuel/hooks/useTheTranslation.d.ts.map +1 -0
  152. package/dist/theglobalfuel/hooks/useTheTranslation.js +12 -0
  153. package/dist/theglobalfuel/hooks/useTheTranslation.js.map +1 -0
  154. package/dist/theglobalfuel/index.d.ts +11 -0
  155. package/dist/theglobalfuel/index.d.ts.map +1 -0
  156. package/dist/theglobalfuel/index.js +2 -0
  157. package/dist/theglobalfuel/pages/assets/AssetDetailPage.d.ts +13 -0
  158. package/dist/theglobalfuel/pages/assets/AssetDetailPage.d.ts.map +1 -0
  159. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js +395 -353
  160. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js.map +1 -1
  161. package/dist/theglobalfuel/pages/assets/AssetsPage.d.ts +10 -0
  162. package/dist/theglobalfuel/pages/assets/AssetsPage.d.ts.map +1 -0
  163. package/dist/theglobalfuel/pages/assets/AssetsPage.js +152 -146
  164. package/dist/theglobalfuel/pages/assets/AssetsPage.js.map +1 -1
  165. package/dist/theglobalfuel/pages/compliance/CompliancePage.d.ts +11 -0
  166. package/dist/theglobalfuel/pages/compliance/CompliancePage.d.ts.map +1 -0
  167. package/dist/theglobalfuel/pages/compliance/CompliancePage.js +233 -229
  168. package/dist/theglobalfuel/pages/compliance/CompliancePage.js.map +1 -1
  169. package/dist/theglobalfuel/pages/contracts/ContractDetailPage.d.ts +9 -0
  170. package/dist/theglobalfuel/pages/contracts/ContractDetailPage.d.ts.map +1 -0
  171. package/dist/theglobalfuel/pages/contracts/ContractDetailPage.js +410 -389
  172. package/dist/theglobalfuel/pages/contracts/ContractDetailPage.js.map +1 -1
  173. package/dist/theglobalfuel/pages/contracts/ContractsPage.d.ts +8 -0
  174. package/dist/theglobalfuel/pages/contracts/ContractsPage.d.ts.map +1 -0
  175. package/dist/theglobalfuel/pages/contracts/ContractsPage.js +237 -231
  176. package/dist/theglobalfuel/pages/contracts/ContractsPage.js.map +1 -1
  177. package/dist/theglobalfuel/pages/dashboard/DashboardPage.d.ts +17 -0
  178. package/dist/theglobalfuel/pages/dashboard/DashboardPage.d.ts.map +1 -0
  179. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js +255 -250
  180. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js.map +1 -1
  181. package/dist/theglobalfuel/pages/emissions/EmissionsPage.d.ts +13 -0
  182. package/dist/theglobalfuel/pages/emissions/EmissionsPage.d.ts.map +1 -0
  183. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js +154 -150
  184. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js.map +1 -1
  185. package/dist/theglobalfuel/pages/inventory/InventoryPage.d.ts +11 -0
  186. package/dist/theglobalfuel/pages/inventory/InventoryPage.d.ts.map +1 -0
  187. package/dist/theglobalfuel/pages/inventory/InventoryPage.js +151 -147
  188. package/dist/theglobalfuel/pages/inventory/InventoryPage.js.map +1 -1
  189. package/dist/theglobalfuel/pages/production/ProductionPage.d.ts +11 -0
  190. package/dist/theglobalfuel/pages/production/ProductionPage.d.ts.map +1 -0
  191. package/dist/theglobalfuel/pages/production/ProductionPage.js +175 -171
  192. package/dist/theglobalfuel/pages/production/ProductionPage.js.map +1 -1
  193. package/dist/theglobalfuel/pages/provenance/ProvenancePage.d.ts +23 -0
  194. package/dist/theglobalfuel/pages/provenance/ProvenancePage.d.ts.map +1 -0
  195. package/dist/theglobalfuel/pages/provenance/ProvenancePage.js +153 -146
  196. package/dist/theglobalfuel/pages/provenance/ProvenancePage.js.map +1 -1
  197. package/dist/theglobalfuel/pages/reserves/ReservesPage.d.ts +10 -0
  198. package/dist/theglobalfuel/pages/reserves/ReservesPage.d.ts.map +1 -0
  199. package/dist/theglobalfuel/pages/reserves/ReservesPage.js +168 -164
  200. package/dist/theglobalfuel/pages/reserves/ReservesPage.js.map +1 -1
  201. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.d.ts +11 -0
  202. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.d.ts.map +1 -0
  203. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js +179 -175
  204. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js.map +1 -1
  205. package/dist/theglobalfuel/services/assistantApi.d.ts +25 -0
  206. package/dist/theglobalfuel/services/assistantApi.d.ts.map +1 -0
  207. package/dist/theglobalfuel/services/assistantApi.js +225 -0
  208. package/dist/theglobalfuel/services/assistantApi.js.map +1 -0
  209. package/dist/theglobalfuel/services/createSandboxAssistantTransport.d.ts +38 -0
  210. package/dist/theglobalfuel/services/createSandboxAssistantTransport.d.ts.map +1 -0
  211. package/dist/theglobalfuel/services/createSandboxAssistantTransport.js +120 -0
  212. package/dist/theglobalfuel/services/createSandboxAssistantTransport.js.map +1 -0
  213. package/dist/theglobalfuel/services/index.d.ts +7 -0
  214. package/dist/theglobalfuel/services/index.d.ts.map +1 -0
  215. package/dist/theglobalfuel/types/assistant.d.ts +65 -0
  216. package/dist/theglobalfuel/types/assistant.d.ts.map +1 -0
  217. package/dist/theglobalfuel/types/index.d.ts +376 -0
  218. package/dist/theglobalfuel/types/index.d.ts.map +1 -0
  219. package/dist/theglobalfuel/utils/cn.d.ts +4 -0
  220. package/dist/theglobalfuel/utils/cn.d.ts.map +1 -0
  221. package/dist/theglobalfuel/utils/formatters.d.ts +44 -0
  222. package/dist/theglobalfuel/utils/formatters.d.ts.map +1 -0
  223. package/dist/theglobalfuel/utils/i18n.d.ts +5 -0
  224. package/dist/theglobalfuel/utils/i18n.d.ts.map +1 -0
  225. package/dist/theglobalfuel/utils/i18n.js +15 -0
  226. package/dist/theglobalfuel/utils/i18n.js.map +1 -0
  227. package/dist/theglobalfuel/utils/index.d.ts +10 -0
  228. package/dist/theglobalfuel/utils/index.d.ts.map +1 -0
  229. package/dist/theglobalfuel/utils/navigation.d.ts +14 -0
  230. package/dist/theglobalfuel/utils/navigation.d.ts.map +1 -0
  231. package/dist/theglobalfuel/utils/pageContext.d.ts +26 -0
  232. package/dist/theglobalfuel/utils/pageContext.d.ts.map +1 -0
  233. package/dist/theglobalfuel/utils/pageContext.js +65 -0
  234. package/dist/theglobalfuel/utils/pageContext.js.map +1 -0
  235. package/dist/theglobalfuel/utils/transitions.d.ts +17 -0
  236. package/dist/theglobalfuel/utils/transitions.d.ts.map +1 -0
  237. package/package.json +5 -1
  238. package/dist/node_modules/clsx/dist/clsx.js +0 -18
  239. package/dist/node_modules/clsx/dist/clsx.js.map +0 -1
  240. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +0 -1716
  241. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"EmissionsPage.js","names":[],"sources":["../../../../src/theglobalfuel/pages/emissions/EmissionsPage.tsx"],"sourcesContent":["/**\n * Emissions — the ESG greenhouse-gas ledger.\n * @module theglobalfuel/pages/emissions\n *\n * Reads `theListEmissionRecords` (optionally filtered by GHG-Protocol scope and\n * by asset); writes `theRecordEmission` and `theVerifyEmission`. Asset names are\n * resolved from `theListAssets`. The header pairs a scope-breakdown donut with a\n * KPI strip — both computed from a broad, asset-scoped pull of the ledger (not\n * just the current table page), split by Scope 1 / 2 / 3. No mock data — every\n * number comes from the real `wspace-theglobalfuel-svc` contract.\n */\n\nimport { useMemo, useState, type ReactNode } from 'react';\nimport { Plus, Factory, Flame, Zap, Truck, Cloud, CheckCircle2, Circle } from 'lucide-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 { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { DataTable, type Column } from '../../components/DataTable';\nimport { FilterTabs, type FilterOption } from '../../components/FilterTabs';\nimport { MiniBar } from '../../components/MiniBar';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { Pagination } from '../../components/Pagination';\nimport { DonutChart, type Segment } from '../../components';\nimport {\n useTheAssets,\n useTheEmissionRecords,\n useTheRecordEmission,\n useTheVerifyEmission,\n useCursorPager,\n useNotify,\n} from '../../hooks';\nimport {\n formatDate,\n formatRelativeTime,\n formatPercent,\n formatTonnesCo2e,\n formatEnumLabel,\n toBackendDate,\n} from '../../utils/formatters';\nimport type { TheEmissionRecord, TheEmissionScope } from '../../types';\n\nconst SCOPES: TheEmissionScope[] = ['SCOPE_1', 'SCOPE_2', 'SCOPE_3'];\n\nconst SCOPE_FILTERS: FilterOption<TheEmissionScope | 'ALL'>[] = [\n { value: 'ALL', label: 'All scopes' },\n { value: 'SCOPE_1', label: 'Scope 1' },\n { value: 'SCOPE_2', label: 'Scope 2' },\n { value: 'SCOPE_3', label: 'Scope 3' },\n];\n\n/** MiniBar fill token per GHG scope — mirrors the StatusBadge scope palette. */\nconst SCOPE_BAR: Record<TheEmissionScope, string> = {\n SCOPE_1: 'bg-status-error-text',\n SCOPE_2: 'bg-status-warning-text',\n SCOPE_3: 'bg-accent',\n};\n\n/** Short legend label per scope for the breakdown donut. */\nconst SCOPE_LABEL: Record<TheEmissionScope, string> = {\n SCOPE_1: 'Scope 1',\n SCOPE_2: 'Scope 2',\n SCOPE_3: 'Scope 3',\n};\n\n/**\n * Tokenized donut-segment color per scope — aligned to the StatusBadge scope\n * palette (Scope 1 = danger, Scope 2 = warning, Scope 3 = info/blue). All are\n * semantic CSS variables, so the chart themes automatically.\n */\nconst SCOPE_DONUT_COLOR: Record<TheEmissionScope, string> = {\n SCOPE_1: 'var(--color-status-error-text)',\n SCOPE_2: 'var(--color-status-warning-text)',\n SCOPE_3: 'var(--color-accent-blue)',\n};\n\n/** Compact CO₂e for the donut center (e.g. 1.24M) — full figures live in the KPIs. */\nconst compactTonnes = (n: number): string =>\n new Intl.NumberFormat('en', { notation: 'compact', maximumFractionDigits: 1 }).format(n);\n\nconst PAGE_SIZE = 25;\n\nconst today = (): string => new Date().toISOString().slice(0, 10);\n\ninterface RecordFormState {\n assetId: string;\n scope: TheEmissionScope;\n co2eTonnes: string;\n periodStart: string;\n periodEnd: string;\n source: string;\n methodology: string;\n notes: string;\n}\n\nconst emptyForm = (): RecordFormState => ({\n assetId: '',\n scope: 'SCOPE_1',\n co2eTonnes: '',\n periodStart: today(),\n periodEnd: today(),\n source: '',\n methodology: '',\n notes: '',\n});\n\n/** KPI-card footer: this scope's share of the page total, tinted by scope. */\nconst renderScopeShare = (\n value: number,\n total: number,\n scope: TheEmissionScope\n): ReactNode => {\n if (total <= 0) return undefined;\n const pct = (value / total) * 100;\n return (\n <div className=\"space-y-2\">\n <MiniBar value={pct} barClassName={SCOPE_BAR[scope]} height={4} />\n <p className=\"text-xs tabular-nums text-text-tertiary\">{formatPercent(pct)} of total</p>\n </div>\n );\n};\n\nexport function EmissionsPage() {\n const notify = useNotify();\n const [scope, setScope] = useState<TheEmissionScope | 'ALL'>('ALL');\n const [assetId, setAssetId] = useState<string>('ALL');\n const pager = useCursorPager();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<RecordFormState>(emptyForm);\n const [formError, setFormError] = useState<string | null>(null);\n // Track the row whose verification is in flight, so only that row's Verify\n // button disables (verifyEmission.isPending is shared across all rows).\n const [verifyingId, setVerifyingId] = useState<string | null>(null);\n\n // Assets feed the filter Select, the create picker, and the id→name map.\n const assetsQuery = useTheAssets({ pagination: { limit: 100 } });\n const assetMap = useMemo<Record<string, string>>(() => {\n const map: Record<string, string> = {};\n for (const a of assetsQuery.data?.items ?? []) map[a.id] = a.name;\n return map;\n }, [assetsQuery.data]);\n const assetOptions = assetsQuery.data?.items ?? [];\n\n const { data, isLoading, isError, refetch } = useTheEmissionRecords({\n scope: scope === 'ALL' ? undefined : scope,\n assetId: assetId === 'ALL' ? undefined : assetId,\n pagination: { limit: PAGE_SIZE, offset: pager.page * PAGE_SIZE },\n });\n const recordEmission = useTheRecordEmission();\n const verifyEmission = useTheVerifyEmission();\n\n const rows = useMemo(() => data?.items ?? [], [data]);\n\n // Broad, scope-agnostic pull (respects the asset filter only) so the header\n // donut + KPI totals reflect the whole ledger — stable as the scope tabs and\n // pagination narrow the table below.\n const metricsQuery = useTheEmissionRecords({\n assetId: assetId === 'ALL' ? undefined : assetId,\n pagination: { limit: 200 },\n });\n const metricsRows = useMemo(() => metricsQuery.data?.items ?? [], [metricsQuery.data]);\n const metricsCount = metricsRows.length;\n\n // KPI + donut summary — CO₂e total plus per-scope breakdown across the ledger.\n const { total, byScope } = useMemo(() => {\n const byScope: Record<TheEmissionScope, number> = {\n SCOPE_1: 0,\n SCOPE_2: 0,\n SCOPE_3: 0,\n };\n let total = 0;\n for (const r of metricsRows) {\n total += r.co2eTonnes;\n byScope[r.scope] += r.co2eTonnes;\n }\n return { total, byScope };\n }, [metricsRows]);\n\n // Donut segments — one per scope that actually carries CO₂e.\n const scopeSegments = useMemo<Segment[]>(\n () =>\n SCOPES.filter((s) => byScope[s] > 0).map((s) => ({\n label: SCOPE_LABEL[s],\n value: byScope[s],\n color: SCOPE_DONUT_COLOR[s],\n })),\n [byScope]\n );\n\n const columns: Column<TheEmissionRecord>[] = [\n {\n key: 'scope',\n header: 'Scope',\n render: (r) => <StatusBadge status={r.scope} />,\n },\n {\n key: 'asset',\n header: 'Asset',\n render: (r) => (\n <span className=\"text-text-secondary\">\n {r.assetId ? (assetMap[r.assetId] ?? `${r.assetId.slice(0, 8)}…`) : '—'}\n </span>\n ),\n },\n {\n key: 'co2e',\n header: 'CO₂e',\n align: 'right',\n sortValue: (r) => r.co2eTonnes,\n render: (r) => (\n <span className=\"tabular-nums font-medium text-text-primary\">\n {formatTonnesCo2e(r.co2eTonnes)}\n </span>\n ),\n },\n {\n key: 'period',\n header: 'Period',\n hideOnMobile: true,\n sortValue: (r) => new Date(r.periodStart).getTime(),\n render: (r) => (\n <span className=\"text-text-secondary\">\n {formatDate(r.periodStart)} – {formatDate(r.periodEnd)}\n </span>\n ),\n },\n {\n key: 'source',\n header: 'Source',\n hideOnMobile: true,\n render: (r) => <span className=\"text-text-secondary\">{r.source ?? '—'}</span>,\n },\n {\n key: 'verified',\n header: 'Verified',\n render: (r) =>\n r.verified ? (\n <span className=\"inline-flex items-center gap-1.5 text-status-success-text\">\n <CheckCircle2 className=\"h-4 w-4\" />\n <span className=\"text-xs font-medium\">Verified</span>\n {r.verifiedAt && (\n <span className=\"text-xs font-normal tabular-nums text-text-tertiary\">\n {formatDate(r.verifiedAt)}\n </span>\n )}\n </span>\n ) : (\n <span className=\"inline-flex items-center gap-1.5 text-text-tertiary\">\n <Circle className=\"h-3.5 w-3.5\" />\n <span className=\"text-xs\">Unverified</span>\n </span>\n ),\n },\n {\n key: 'created',\n header: 'Logged',\n align: 'right',\n hideOnMobile: true,\n render: (r) => <span className=\"text-text-tertiary\">{formatRelativeTime(r.createdAt)}</span>,\n },\n {\n key: 'verify',\n header: '',\n align: 'right',\n render: (r) =>\n !r.verified ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n setVerifyingId(r.id);\n verifyEmission.mutate(r.id, {\n onSuccess: () => notify.success('Emission verified'),\n onError: (e) => notify.fromError(e),\n onSettled: () => setVerifyingId(null),\n });\n }}\n disabled={verifyingId === r.id}\n >\n {verifyingId === r.id ? 'Verifying…' : 'Verify'}\n </Button>\n ) : null,\n },\n ];\n\n const openDialog = () => {\n setForm(emptyForm());\n setFormError(null);\n setDialogOpen(true);\n };\n\n const handleRecord = async () => {\n const co2e = Number(form.co2eTonnes);\n if (!form.co2eTonnes || Number.isNaN(co2e) || co2e <= 0) {\n const message = 'CO₂e (tonnes) must be greater than zero.';\n setFormError(message);\n notify.error(message);\n return;\n }\n if (!form.periodStart || !form.periodEnd) {\n setFormError('Period start and end are required.');\n return;\n }\n const start = toBackendDate(form.periodStart);\n const end = toBackendDate(form.periodEnd);\n if (!start || !end) {\n setFormError('Period start and end are required.');\n return;\n }\n if (new Date(end).getTime() < new Date(start).getTime()) {\n setFormError('Period end must be on or after the period start.');\n return;\n }\n setFormError(null);\n try {\n await recordEmission.mutateAsync({\n assetId: form.assetId || null,\n scope: form.scope,\n co2eTonnes: co2e,\n periodStart: start,\n periodEnd: end,\n source: form.source.trim() || null,\n methodology: form.methodology.trim() || null,\n notes: form.notes.trim() || null,\n });\n notify.success('Emission recorded');\n setDialogOpen(false);\n setForm(emptyForm());\n } catch (err) {\n notify.fromError(err);\n setFormError(err instanceof Error ? err.message : 'Failed to record emission.');\n }\n };\n\n return (\n <PageLayout\n title=\"Emissions\"\n description=\"ESG greenhouse-gas ledger across every asset — GHG Protocol Scope 1 / 2 / 3, with third-party verification.\"\n actions={\n <Button onClick={openDialog}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record emission\n </Button>\n }\n >\n {/* Header — scope-breakdown donut beside the CO₂e KPI cards (both broad). */}\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <div className=\"flex flex-col rounded-[var(--radius-card)] border border-border-subtle bg-bg-surface p-5 shadow-elevation-1\">\n <div className=\"mb-1 flex items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold text-text-secondary\">Emissions by scope</h3>\n <Cloud className=\"h-4 w-4 shrink-0 text-text-muted\" aria-hidden=\"true\" />\n </div>\n {metricsQuery.isLoading ? (\n <p className=\"flex flex-1 items-center py-8 text-sm text-text-tertiary\">\n Loading breakdown…\n </p>\n ) : scopeSegments.length > 0 ? (\n <DonutChart\n className=\"mt-3\"\n segments={scopeSegments}\n size={148}\n thickness={0.32}\n centerLabel={compactTonnes(total)}\n centerCaption=\"t CO₂e\"\n valueFormatter={formatTonnesCo2e}\n />\n ) : (\n <p className=\"flex flex-1 items-center py-8 text-sm text-text-tertiary\">\n No emissions recorded yet.\n </p>\n )}\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:col-span-2\">\n <MetricsCard\n icon={<Factory className=\"h-5 w-5\" />}\n value={metricsCount > 0 ? formatTonnesCo2e(total) : '—'}\n label=\"Total CO₂e\"\n featured\n footer={\n <p className=\"text-xs tabular-nums text-text-tertiary\">\n {metricsCount} record{metricsCount === 1 ? '' : 's'} · Scope 1 · 2 · 3\n </p>\n }\n />\n <MetricsCard\n icon={<Flame className=\"h-5 w-5\" />}\n value={metricsCount > 0 ? formatTonnesCo2e(byScope.SCOPE_1) : '—'}\n label=\"Scope 1 · Direct\"\n footer={renderScopeShare(byScope.SCOPE_1, total, 'SCOPE_1')}\n />\n <MetricsCard\n icon={<Zap className=\"h-5 w-5\" />}\n value={metricsCount > 0 ? formatTonnesCo2e(byScope.SCOPE_2) : '—'}\n label=\"Scope 2 · Purchased energy\"\n footer={renderScopeShare(byScope.SCOPE_2, total, 'SCOPE_2')}\n />\n <MetricsCard\n icon={<Truck className=\"h-5 w-5\" />}\n value={metricsCount > 0 ? formatTonnesCo2e(byScope.SCOPE_3) : '—'}\n label=\"Scope 3 · Value chain\"\n footer={renderScopeShare(byScope.SCOPE_3, total, 'SCOPE_3')}\n />\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"mt-6 mb-5 flex flex-wrap items-center gap-3\">\n <FilterTabs\n options={SCOPE_FILTERS}\n value={scope}\n onChange={(v) => {\n setScope(v);\n pager.reset();\n }}\n />\n <Select\n value={assetId}\n onValueChange={(v) => {\n setAssetId(v);\n pager.reset();\n }}\n >\n <SelectTrigger className=\"w-56\" aria-label=\"Filter by asset\">\n <SelectValue placeholder=\"All assets\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">All assets</SelectItem>\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 {isLoading ? (\n <LoadingView label=\"Loading emission records…\" />\n ) : isError ? (\n <ErrorView message=\"Couldn't load emission records.\" onRetry={() => refetch()} />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Cloud className=\"h-10 w-10\" />}\n title=\"No emissions recorded\"\n description={\n scope === 'ALL' && assetId === 'ALL'\n ? 'Record a CO₂e figure to start building your Scope 1–3 emissions ledger.'\n : 'No emission records match these filters.'\n }\n action={\n <Button onClick={openDialog}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record emission\n </Button>\n }\n />\n ) : (\n <>\n <DataTable\n columns={columns}\n rows={rows}\n rowKey={(r) => r.id}\n defaultSort={{ key: 'period', dir: 'desc' }}\n />\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={data?.pageInfo?.hasMore ?? false}\n onPageChange={pager.onPageChange}\n />\n </>\n )}\n\n {/* Record emission dialog */}\n <ResponsiveDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n setDialogOpen(open);\n if (!open) {\n setForm(emptyForm());\n setFormError(null);\n }\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Record emission</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Log a CO₂e figure for a reporting period — optionally attributed to an asset.\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-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emScope\">Scope</Label>\n <Select\n value={form.scope}\n onValueChange={(v) => setForm({ ...form, scope: v as TheEmissionScope })}\n >\n <SelectTrigger id=\"emScope\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SCOPES.map((s) => (\n <SelectItem key={s} value={s}>\n {formatEnumLabel(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emCo2e\">CO₂e (tonnes) *</Label>\n <Input\n id=\"emCo2e\"\n type=\"number\"\n min=\"0\"\n step=\"any\"\n value={form.co2eTonnes}\n onChange={(e) => setForm({ ...form, co2eTonnes: e.target.value })}\n placeholder=\"1250\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emAsset\">Asset</Label>\n <Select\n value={form.assetId}\n onValueChange={(v) => setForm({ ...form, assetId: v })}\n >\n <SelectTrigger id=\"emAsset\">\n <SelectValue placeholder=\"Optional — org-wide if unset\" />\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 gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emStart\">Period start *</Label>\n <Input\n id=\"emStart\"\n type=\"date\"\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=\"emEnd\">Period end *</Label>\n <Input\n id=\"emEnd\"\n type=\"date\"\n value={form.periodEnd}\n onChange={(e) => setForm({ ...form, periodEnd: e.target.value })}\n />\n </div>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emSource\">Source</Label>\n <Input\n id=\"emSource\"\n value={form.source}\n onChange={(e) => setForm({ ...form, source: e.target.value })}\n placeholder=\"Flaring, grid electricity…\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emMethod\">Methodology</Label>\n <Input\n id=\"emMethod\"\n value={form.methodology}\n onChange={(e) => setForm({ ...form, methodology: e.target.value })}\n placeholder=\"GHG Protocol / IPCC / API\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emNotes\">Notes</Label>\n <Textarea\n id=\"emNotes\"\n rows={2}\n value={form.notes}\n onChange={(e) => setForm({ ...form, notes: e.target.value })}\n placeholder=\"Optional context about this figure.\"\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setDialogOpen(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={recordEmission.isPending}>\n {recordEmission.isPending ? 'Recording…' : 'Record emission'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EmissionsPage.js","names":[],"sources":["../../../../src/theglobalfuel/pages/emissions/EmissionsPage.tsx"],"sourcesContent":["/**\n * Emissions — the ESG greenhouse-gas ledger.\n * @module theglobalfuel/pages/emissions\n *\n * Reads `theListEmissionRecords` (optionally filtered by GHG-Protocol scope and\n * by asset); writes `theRecordEmission` and `theVerifyEmission`. Asset names are\n * resolved from `theListAssets`. The header pairs a scope-breakdown donut with a\n * KPI strip — both computed from a broad, asset-scoped pull of the ledger (not\n * just the current table page), split by Scope 1 / 2 / 3. No mock data — every\n * number comes from the real `wspace-theglobalfuel-svc` contract.\n */\n\nimport { useMemo, useState, type ReactNode } from 'react';\nimport { Plus, Factory, Flame, Zap, Truck, Cloud, CheckCircle2, Circle } from 'lucide-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 { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { DataTable, type Column } from '../../components/DataTable';\nimport { FilterTabs, type FilterOption } from '../../components/FilterTabs';\nimport { MiniBar } from '../../components/MiniBar';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { Pagination } from '../../components/Pagination';\nimport { DonutChart, type Segment } from '../../components';\nimport {\n useTheAssets,\n useTheEmissionRecords,\n useTheRecordEmission,\n useTheVerifyEmission,\n useCursorPager,\n useNotify,\n useThePageView,\n useTheTranslation,\n} from '../../hooks';\nimport {\n formatDate,\n formatRelativeTime,\n formatPercent,\n formatTonnesCo2e,\n formatEnumLabel,\n toBackendDate,\n} from '../../utils/formatters';\nimport type { TheEmissionRecord, TheEmissionScope } from '../../types';\n\nconst SCOPES: TheEmissionScope[] = ['SCOPE_1', 'SCOPE_2', 'SCOPE_3'];\n\nconst SCOPE_FILTERS: FilterOption<TheEmissionScope | 'ALL'>[] = [\n { value: 'ALL', label: 'All scopes' },\n { value: 'SCOPE_1', label: 'Scope 1' },\n { value: 'SCOPE_2', label: 'Scope 2' },\n { value: 'SCOPE_3', label: 'Scope 3' },\n];\n\n/** MiniBar fill token per GHG scope — mirrors the StatusBadge scope palette. */\nconst SCOPE_BAR: Record<TheEmissionScope, string> = {\n SCOPE_1: 'bg-status-error-text',\n SCOPE_2: 'bg-status-warning-text',\n SCOPE_3: 'bg-accent',\n};\n\n/** Short legend label per scope for the breakdown donut. */\nconst SCOPE_LABEL: Record<TheEmissionScope, string> = {\n SCOPE_1: 'Scope 1',\n SCOPE_2: 'Scope 2',\n SCOPE_3: 'Scope 3',\n};\n\n/**\n * Tokenized donut-segment color per scope — aligned to the StatusBadge scope\n * palette (Scope 1 = danger, Scope 2 = warning, Scope 3 = info/blue). All are\n * semantic CSS variables, so the chart themes automatically.\n */\nconst SCOPE_DONUT_COLOR: Record<TheEmissionScope, string> = {\n SCOPE_1: 'var(--color-status-error-text)',\n SCOPE_2: 'var(--color-status-warning-text)',\n SCOPE_3: 'var(--color-accent-blue)',\n};\n\n/** Compact CO₂e for the donut center (e.g. 1.24M) — full figures live in the KPIs. */\nconst compactTonnes = (n: number): string =>\n new Intl.NumberFormat('en', { notation: 'compact', maximumFractionDigits: 1 }).format(n);\n\nconst PAGE_SIZE = 25;\n\nconst today = (): string => new Date().toISOString().slice(0, 10);\n\ninterface RecordFormState {\n assetId: string;\n scope: TheEmissionScope;\n co2eTonnes: string;\n periodStart: string;\n periodEnd: string;\n source: string;\n methodology: string;\n notes: string;\n}\n\nconst emptyForm = (): RecordFormState => ({\n assetId: '',\n scope: 'SCOPE_1',\n co2eTonnes: '',\n periodStart: today(),\n periodEnd: today(),\n source: '',\n methodology: '',\n notes: '',\n});\n\n/** KPI-card footer: this scope's share of the page total, tinted by scope. */\nconst renderScopeShare = (value: number, total: number, scope: TheEmissionScope): ReactNode => {\n if (total <= 0) return undefined;\n const pct = (value / total) * 100;\n return (\n <div className=\"space-y-2\">\n <MiniBar value={pct} barClassName={SCOPE_BAR[scope]} height={4} />\n <p className=\"text-xs tabular-nums text-text-tertiary\">{formatPercent(pct)} of total</p>\n </div>\n );\n};\n\nexport function EmissionsPage() {\n useThePageView('emissions');\n const t = useTheTranslation();\n const notify = useNotify();\n const [scope, setScope] = useState<TheEmissionScope | 'ALL'>('ALL');\n const [assetId, setAssetId] = useState<string>('ALL');\n const pager = useCursorPager();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<RecordFormState>(emptyForm);\n const [formError, setFormError] = useState<string | null>(null);\n // Track the row whose verification is in flight, so only that row's Verify\n // button disables (verifyEmission.isPending is shared across all rows).\n const [verifyingId, setVerifyingId] = useState<string | null>(null);\n\n // Assets feed the filter Select, the create picker, and the id→name map.\n const assetsQuery = useTheAssets({ pagination: { limit: 100 } });\n const assetMap = useMemo<Record<string, string>>(() => {\n const map: Record<string, string> = {};\n for (const a of assetsQuery.data?.items ?? []) map[a.id] = a.name;\n return map;\n }, [assetsQuery.data]);\n const assetOptions = assetsQuery.data?.items ?? [];\n\n const { data, isLoading, isError, refetch } = useTheEmissionRecords({\n scope: scope === 'ALL' ? undefined : scope,\n assetId: assetId === 'ALL' ? undefined : assetId,\n pagination: { limit: PAGE_SIZE, offset: pager.page * PAGE_SIZE },\n });\n const recordEmission = useTheRecordEmission();\n const verifyEmission = useTheVerifyEmission();\n\n const rows = useMemo(() => data?.items ?? [], [data]);\n\n // Broad, scope-agnostic pull (respects the asset filter only) so the header\n // donut + KPI totals reflect the whole ledger — stable as the scope tabs and\n // pagination narrow the table below.\n const metricsQuery = useTheEmissionRecords({\n assetId: assetId === 'ALL' ? undefined : assetId,\n pagination: { limit: 200 },\n });\n const metricsRows = useMemo(() => metricsQuery.data?.items ?? [], [metricsQuery.data]);\n const metricsCount = metricsRows.length;\n\n // KPI + donut summary — CO₂e total plus per-scope breakdown across the ledger.\n const { total, byScope } = useMemo(() => {\n const byScope: Record<TheEmissionScope, number> = {\n SCOPE_1: 0,\n SCOPE_2: 0,\n SCOPE_3: 0,\n };\n let total = 0;\n for (const r of metricsRows) {\n total += r.co2eTonnes;\n byScope[r.scope] += r.co2eTonnes;\n }\n return { total, byScope };\n }, [metricsRows]);\n\n // Donut segments — one per scope that actually carries CO₂e.\n const scopeSegments = useMemo<Segment[]>(\n () =>\n SCOPES.filter((s) => byScope[s] > 0).map((s) => ({\n label: SCOPE_LABEL[s],\n value: byScope[s],\n color: SCOPE_DONUT_COLOR[s],\n })),\n [byScope]\n );\n\n const columns: Column<TheEmissionRecord>[] = [\n {\n key: 'scope',\n header: 'Scope',\n render: (r) => <StatusBadge status={r.scope} />,\n },\n {\n key: 'asset',\n header: 'Asset',\n render: (r) => (\n <span className=\"text-text-secondary\">\n {r.assetId ? (assetMap[r.assetId] ?? `${r.assetId.slice(0, 8)}…`) : '—'}\n </span>\n ),\n },\n {\n key: 'co2e',\n header: 'CO₂e',\n align: 'right',\n sortValue: (r) => r.co2eTonnes,\n render: (r) => (\n <span className=\"tabular-nums font-medium text-text-primary\">\n {formatTonnesCo2e(r.co2eTonnes)}\n </span>\n ),\n },\n {\n key: 'period',\n header: 'Period',\n hideOnMobile: true,\n sortValue: (r) => new Date(r.periodStart).getTime(),\n render: (r) => (\n <span className=\"text-text-secondary\">\n {formatDate(r.periodStart)} – {formatDate(r.periodEnd)}\n </span>\n ),\n },\n {\n key: 'source',\n header: 'Source',\n hideOnMobile: true,\n render: (r) => <span className=\"text-text-secondary\">{r.source ?? '—'}</span>,\n },\n {\n key: 'verified',\n header: 'Verified',\n render: (r) =>\n r.verified ? (\n <span className=\"inline-flex items-center gap-1.5 text-status-success-text\">\n <CheckCircle2 className=\"h-4 w-4\" />\n <span className=\"text-xs font-medium\">Verified</span>\n {r.verifiedAt && (\n <span className=\"text-xs font-normal tabular-nums text-text-tertiary\">\n {formatDate(r.verifiedAt)}\n </span>\n )}\n </span>\n ) : (\n <span className=\"inline-flex items-center gap-1.5 text-text-tertiary\">\n <Circle className=\"h-3.5 w-3.5\" />\n <span className=\"text-xs\">Unverified</span>\n </span>\n ),\n },\n {\n key: 'created',\n header: 'Logged',\n align: 'right',\n hideOnMobile: true,\n render: (r) => <span className=\"text-text-tertiary\">{formatRelativeTime(r.createdAt)}</span>,\n },\n {\n key: 'verify',\n header: '',\n align: 'right',\n render: (r) =>\n !r.verified ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n setVerifyingId(r.id);\n verifyEmission.mutate(r.id, {\n onSuccess: () => notify.success('Emission verified'),\n onError: (e) => notify.fromError(e),\n onSettled: () => setVerifyingId(null),\n });\n }}\n disabled={verifyingId === r.id}\n >\n {verifyingId === r.id ? 'Verifying…' : 'Verify'}\n </Button>\n ) : null,\n },\n ];\n\n const openDialog = () => {\n setForm(emptyForm());\n setFormError(null);\n setDialogOpen(true);\n };\n\n const handleRecord = async () => {\n const co2e = Number(form.co2eTonnes);\n if (!form.co2eTonnes || Number.isNaN(co2e) || co2e <= 0) {\n const message = 'CO₂e (tonnes) must be greater than zero.';\n setFormError(message);\n notify.error(message);\n return;\n }\n if (!form.periodStart || !form.periodEnd) {\n setFormError('Period start and end are required.');\n return;\n }\n const start = toBackendDate(form.periodStart);\n const end = toBackendDate(form.periodEnd);\n if (!start || !end) {\n setFormError('Period start and end are required.');\n return;\n }\n if (new Date(end).getTime() < new Date(start).getTime()) {\n setFormError('Period end must be on or after the period start.');\n return;\n }\n setFormError(null);\n try {\n await recordEmission.mutateAsync({\n assetId: form.assetId || null,\n scope: form.scope,\n co2eTonnes: co2e,\n periodStart: start,\n periodEnd: end,\n source: form.source.trim() || null,\n methodology: form.methodology.trim() || null,\n notes: form.notes.trim() || null,\n });\n notify.success('Emission recorded');\n setDialogOpen(false);\n setForm(emptyForm());\n } catch (err) {\n notify.fromError(err);\n setFormError(err instanceof Error ? err.message : 'Failed to record emission.');\n }\n };\n\n return (\n <PageLayout\n title={t('theglobalfuel.pages.emissions.title', 'Emissions')}\n description={t(\n 'theglobalfuel.pages.emissions.description',\n 'ESG greenhouse-gas ledger across every asset — GHG Protocol Scope 1 / 2 / 3, with third-party verification.'\n )}\n dataTour=\"theglobalfuel-emissions-page\"\n actions={\n <Button onClick={openDialog}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record emission\n </Button>\n }\n >\n {/* Header — scope-breakdown donut beside the CO₂e KPI cards (both broad). */}\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <div className=\"flex flex-col rounded-[var(--radius-card)] border border-border-subtle bg-bg-surface p-5 shadow-elevation-1\">\n <div className=\"mb-1 flex items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold text-text-secondary\">Emissions by scope</h3>\n <Cloud className=\"h-4 w-4 shrink-0 text-text-muted\" aria-hidden=\"true\" />\n </div>\n {metricsQuery.isLoading ? (\n <p className=\"flex flex-1 items-center py-8 text-sm text-text-tertiary\">\n Loading breakdown…\n </p>\n ) : scopeSegments.length > 0 ? (\n <DonutChart\n className=\"mt-3\"\n segments={scopeSegments}\n size={148}\n thickness={0.32}\n centerLabel={compactTonnes(total)}\n centerCaption=\"t CO₂e\"\n valueFormatter={formatTonnesCo2e}\n />\n ) : (\n <p className=\"flex flex-1 items-center py-8 text-sm text-text-tertiary\">\n No emissions recorded yet.\n </p>\n )}\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:col-span-2\">\n <MetricsCard\n icon={<Factory className=\"h-5 w-5\" />}\n value={metricsCount > 0 ? formatTonnesCo2e(total) : '—'}\n label=\"Total CO₂e\"\n featured\n footer={\n <p className=\"text-xs tabular-nums text-text-tertiary\">\n {metricsCount} record{metricsCount === 1 ? '' : 's'} · Scope 1 · 2 · 3\n </p>\n }\n />\n <MetricsCard\n icon={<Flame className=\"h-5 w-5\" />}\n value={metricsCount > 0 ? formatTonnesCo2e(byScope.SCOPE_1) : '—'}\n label=\"Scope 1 · Direct\"\n footer={renderScopeShare(byScope.SCOPE_1, total, 'SCOPE_1')}\n />\n <MetricsCard\n icon={<Zap className=\"h-5 w-5\" />}\n value={metricsCount > 0 ? formatTonnesCo2e(byScope.SCOPE_2) : '—'}\n label=\"Scope 2 · Purchased energy\"\n footer={renderScopeShare(byScope.SCOPE_2, total, 'SCOPE_2')}\n />\n <MetricsCard\n icon={<Truck className=\"h-5 w-5\" />}\n value={metricsCount > 0 ? formatTonnesCo2e(byScope.SCOPE_3) : '—'}\n label=\"Scope 3 · Value chain\"\n footer={renderScopeShare(byScope.SCOPE_3, total, 'SCOPE_3')}\n />\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"mt-6 mb-5 flex flex-wrap items-center gap-3\">\n <FilterTabs\n options={SCOPE_FILTERS}\n value={scope}\n onChange={(v) => {\n setScope(v);\n pager.reset();\n }}\n />\n <Select\n value={assetId}\n onValueChange={(v) => {\n setAssetId(v);\n pager.reset();\n }}\n >\n <SelectTrigger className=\"w-56\" aria-label=\"Filter by asset\">\n <SelectValue placeholder=\"All assets\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">All assets</SelectItem>\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 {isLoading ? (\n <LoadingView label=\"Loading emission records…\" />\n ) : isError ? (\n <ErrorView message=\"Couldn't load emission records.\" onRetry={() => refetch()} />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Cloud className=\"h-10 w-10\" />}\n title=\"No emissions recorded\"\n description={\n scope === 'ALL' && assetId === 'ALL'\n ? 'Record a CO₂e figure to start building your Scope 1–3 emissions ledger.'\n : 'No emission records match these filters.'\n }\n action={\n <Button onClick={openDialog}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record emission\n </Button>\n }\n />\n ) : (\n <>\n <DataTable\n columns={columns}\n rows={rows}\n rowKey={(r) => r.id}\n defaultSort={{ key: 'period', dir: 'desc' }}\n />\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={data?.pageInfo?.hasMore ?? false}\n onPageChange={pager.onPageChange}\n />\n </>\n )}\n\n {/* Record emission dialog */}\n <ResponsiveDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n setDialogOpen(open);\n if (!open) {\n setForm(emptyForm());\n setFormError(null);\n }\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Record emission</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Log a CO₂e figure for a reporting period — optionally attributed to an asset.\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-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emScope\">Scope</Label>\n <Select\n value={form.scope}\n onValueChange={(v) => setForm({ ...form, scope: v as TheEmissionScope })}\n >\n <SelectTrigger id=\"emScope\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SCOPES.map((s) => (\n <SelectItem key={s} value={s}>\n {formatEnumLabel(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emCo2e\">CO₂e (tonnes) *</Label>\n <Input\n id=\"emCo2e\"\n type=\"number\"\n min=\"0\"\n step=\"any\"\n value={form.co2eTonnes}\n onChange={(e) => setForm({ ...form, co2eTonnes: e.target.value })}\n placeholder=\"1250\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emAsset\">Asset</Label>\n <Select\n value={form.assetId}\n onValueChange={(v) => setForm({ ...form, assetId: v })}\n >\n <SelectTrigger id=\"emAsset\">\n <SelectValue placeholder=\"Optional — org-wide if unset\" />\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 gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emStart\">Period start *</Label>\n <Input\n id=\"emStart\"\n type=\"date\"\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=\"emEnd\">Period end *</Label>\n <Input\n id=\"emEnd\"\n type=\"date\"\n value={form.periodEnd}\n onChange={(e) => setForm({ ...form, periodEnd: e.target.value })}\n />\n </div>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emSource\">Source</Label>\n <Input\n id=\"emSource\"\n value={form.source}\n onChange={(e) => setForm({ ...form, source: e.target.value })}\n placeholder=\"Flaring, grid electricity…\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emMethod\">Methodology</Label>\n <Input\n id=\"emMethod\"\n value={form.methodology}\n onChange={(e) => setForm({ ...form, methodology: e.target.value })}\n placeholder=\"GHG Protocol / IPCC / API\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"emNotes\">Notes</Label>\n <Textarea\n id=\"emNotes\"\n rows={2}\n value={form.notes}\n onChange={(e) => setForm({ ...form, notes: e.target.value })}\n placeholder=\"Optional context about this figure.\"\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setDialogOpen(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={recordEmission.isPending}>\n {recordEmission.isPending ? 'Recording…' : 'Record emission'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Commodity inventory — list, filter, create lots & drive lot status.
3
+ * @module theglobalfuel/pages/inventory
4
+ *
5
+ * Reads `theListInventoryLots`; writes `theCreateInventoryLot` and
6
+ * `theSetInventoryLotStatus`. A KPI strip (lots on hand, available quantity &
7
+ * inventory value) is aggregated client-side from a broad lot query. No mock
8
+ * data — every number is derived from live `the*` responses.
9
+ */
10
+ export declare function InventoryPage(): import("react").JSX.Element;
11
+ //# sourceMappingURL=InventoryPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InventoryPage.d.ts","sourceRoot":"","sources":["../../../../src/theglobalfuel/pages/inventory/InventoryPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiHH,wBAAgB,aAAa,gCA8kB5B"}