@burdenoff/microfe-theglobalfuel 2026.705.2 → 2026.705.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/theglobalfuel/TheGlobalFuelRoot.js +54 -46
  2. package/dist/theglobalfuel/TheGlobalFuelRoot.js.map +1 -1
  3. package/dist/theglobalfuel/TheGlobalFuelRoutes.js +10 -6
  4. package/dist/theglobalfuel/TheGlobalFuelRoutes.js.map +1 -1
  5. package/dist/theglobalfuel/components/DataTable.js +126 -58
  6. package/dist/theglobalfuel/components/DataTable.js.map +1 -1
  7. package/dist/theglobalfuel/components/EmptyState.js +4 -4
  8. package/dist/theglobalfuel/components/EmptyState.js.map +1 -1
  9. package/dist/theglobalfuel/components/MetricsCard.js +2 -2
  10. package/dist/theglobalfuel/components/MetricsCard.js.map +1 -1
  11. package/dist/theglobalfuel/components/WorldMap.js +115 -0
  12. package/dist/theglobalfuel/components/WorldMap.js.map +1 -0
  13. package/dist/theglobalfuel/components/index.js +9 -0
  14. package/dist/theglobalfuel/components/viz/AllocationBar.js +68 -0
  15. package/dist/theglobalfuel/components/viz/AllocationBar.js.map +1 -0
  16. package/dist/theglobalfuel/components/viz/AreaChart.js +102 -0
  17. package/dist/theglobalfuel/components/viz/AreaChart.js.map +1 -0
  18. package/dist/theglobalfuel/components/viz/AvatarStack.js +2 -0
  19. package/dist/theglobalfuel/components/viz/BarChart.js +4 -0
  20. package/dist/theglobalfuel/components/viz/CertificateCard.js +4 -0
  21. package/dist/theglobalfuel/components/viz/DonutChart.js +109 -0
  22. package/dist/theglobalfuel/components/viz/DonutChart.js.map +1 -0
  23. package/dist/theglobalfuel/components/viz/HBarFunnel.js +3 -0
  24. package/dist/theglobalfuel/components/viz/Heatmap.js +3 -0
  25. package/dist/theglobalfuel/components/viz/KanbanBoard.js +2 -0
  26. package/dist/theglobalfuel/components/viz/LineChart.js +4 -0
  27. package/dist/theglobalfuel/components/viz/OrgTree.js +2 -0
  28. package/dist/theglobalfuel/components/viz/PathSteps.js +68 -0
  29. package/dist/theglobalfuel/components/viz/PathSteps.js.map +1 -0
  30. package/dist/theglobalfuel/components/viz/ProgressRing.js +6 -0
  31. package/dist/theglobalfuel/components/viz/ProgressRing.js.map +1 -0
  32. package/dist/theglobalfuel/components/viz/RatingStars.js +3 -0
  33. package/dist/theglobalfuel/components/viz/SegmentedTabs.js +3 -0
  34. package/dist/theglobalfuel/components/viz/SkillBar.js +3 -0
  35. package/dist/theglobalfuel/components/viz/Sparkline.js +74 -0
  36. package/dist/theglobalfuel/components/viz/Sparkline.js.map +1 -0
  37. package/dist/theglobalfuel/components/viz/StatCard.js +3 -0
  38. package/dist/theglobalfuel/components/viz/StepProgress.js +64 -0
  39. package/dist/theglobalfuel/components/viz/StepProgress.js.map +1 -0
  40. package/dist/theglobalfuel/components/viz/Timeline.js +66 -0
  41. package/dist/theglobalfuel/components/viz/Timeline.js.map +1 -0
  42. package/dist/theglobalfuel/components/viz/index.js +23 -0
  43. package/dist/theglobalfuel/components/viz/lib/Avatar.js +1 -0
  44. package/dist/theglobalfuel/components/viz/lib/CartesianFrame.js +119 -0
  45. package/dist/theglobalfuel/components/viz/lib/CartesianFrame.js.map +1 -0
  46. package/dist/theglobalfuel/components/viz/lib/ResponsiveSvg.js +35 -0
  47. package/dist/theglobalfuel/components/viz/lib/ResponsiveSvg.js.map +1 -0
  48. package/dist/theglobalfuel/components/viz/lib/format.js +17 -0
  49. package/dist/theglobalfuel/components/viz/lib/format.js.map +1 -0
  50. package/dist/theglobalfuel/components/viz/lib/geometry.js +61 -0
  51. package/dist/theglobalfuel/components/viz/lib/geometry.js.map +1 -0
  52. package/dist/theglobalfuel/components/viz/lib/hooks.js +39 -0
  53. package/dist/theglobalfuel/components/viz/lib/hooks.js.map +1 -0
  54. package/dist/theglobalfuel/components/viz/lib/palette.js +27 -0
  55. package/dist/theglobalfuel/components/viz/lib/palette.js.map +1 -0
  56. package/dist/theglobalfuel/hooks/useCursorPager.js +6 -15
  57. package/dist/theglobalfuel/hooks/useCursorPager.js.map +1 -1
  58. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js +431 -316
  59. package/dist/theglobalfuel/pages/assets/AssetDetailPage.js.map +1 -1
  60. package/dist/theglobalfuel/pages/assets/AssetsPage.js +99 -99
  61. package/dist/theglobalfuel/pages/assets/AssetsPage.js.map +1 -1
  62. package/dist/theglobalfuel/pages/compliance/CompliancePage.js +250 -250
  63. package/dist/theglobalfuel/pages/compliance/CompliancePage.js.map +1 -1
  64. package/dist/theglobalfuel/pages/contracts/ContractsPage.js +2 -2
  65. package/dist/theglobalfuel/pages/contracts/ContractsPage.js.map +1 -1
  66. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js +525 -227
  67. package/dist/theglobalfuel/pages/dashboard/DashboardPage.js.map +1 -1
  68. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js +255 -206
  69. package/dist/theglobalfuel/pages/emissions/EmissionsPage.js.map +1 -1
  70. package/dist/theglobalfuel/pages/inventory/InventoryPage.js +60 -60
  71. package/dist/theglobalfuel/pages/inventory/InventoryPage.js.map +1 -1
  72. package/dist/theglobalfuel/pages/production/ProductionPage.js +2 -2
  73. package/dist/theglobalfuel/pages/production/ProductionPage.js.map +1 -1
  74. package/dist/theglobalfuel/pages/provenance/ProvenancePage.js +465 -0
  75. package/dist/theglobalfuel/pages/provenance/ProvenancePage.js.map +1 -0
  76. package/dist/theglobalfuel/pages/reserves/ReservesPage.js +152 -152
  77. package/dist/theglobalfuel/pages/reserves/ReservesPage.js.map +1 -1
  78. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js +356 -227
  79. package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js.map +1 -1
  80. package/package.json +1 -1
@@ -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 KPI strip summarises the CO₂e captured on\n * the current page, split by Scope 1 / 2 / 3. No mock data — every number comes\n * 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 {\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\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, cursor: pager.cursor },\n });\n const recordEmission = useTheRecordEmission();\n const verifyEmission = useTheVerifyEmission();\n\n const rows = useMemo(() => data?.items ?? [], [data]);\n\n // KPI summary — page-scoped CO₂e, total plus per-scope breakdown.\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 rows) {\n total += r.co2eTonnes;\n byScope[r.scope] += r.co2eTonnes;\n }\n return { total, byScope };\n }, [rows]);\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 {/* KPI strip — page-scoped CO₂e, split by scope */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <MetricsCard\n icon={<Factory className=\"h-5 w-5\" />}\n value={rows.length > 0 ? formatTonnesCo2e(total) : '—'}\n label=\"CO₂e on this page\"\n featured\n footer={\n <p className=\"text-xs tabular-nums text-text-tertiary\">\n {rows.length} record{rows.length === 1 ? '' : 's'} · Scope 1 · 2 · 3\n </p>\n }\n />\n <MetricsCard\n icon={<Flame className=\"h-5 w-5\" />}\n value={rows.length > 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={rows.length > 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={rows.length > 0 ? formatTonnesCo2e(byScope.SCOPE_3) : '—'}\n label=\"Scope 3 · Value chain\"\n footer={renderScopeShare(byScope.SCOPE_3, total, 'SCOPE_3')}\n />\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={(target) => pager.onPageChange(target, data?.pageInfo?.cursor)}\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":";;;;;;;;;;;;;;;;;;;AAyDA,IAAM,IAA6B;CAAC;CAAW;CAAW;CAAU,EAE9D,IAA0D;CAC9D;EAAE,OAAO;EAAO,OAAO;EAAc;CACrC;EAAE,OAAO;EAAW,OAAO;EAAW;CACtC;EAAE,OAAO;EAAW,OAAO;EAAW;CACtC;EAAE,OAAO;EAAW,OAAO;EAAW;CACvC,EAGK,IAA8C;CAClD,SAAS;CACT,SAAS;CACT,SAAS;CACV,EAEK,IAAY,IAEZ,2BAAsB,IAAI,MAAM,EAAC,aAAa,CAAC,MAAM,GAAG,GAAG,EAa3D,WAAoC;CACxC,SAAS;CACT,OAAO;CACP,YAAY;CACZ,aAAa,GAAO;CACpB,WAAW,GAAO;CAClB,QAAQ;CACR,aAAa;CACb,OAAO;CACR,GAGK,KACJ,GACA,GACA,MACc;AACd,KAAI,KAAS,EAAG;CAChB,IAAM,IAAO,IAAQ,IAAS;AAC9B,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD;GAAS,OAAO;GAAK,cAAc,EAAU;GAAQ,QAAQ;GAAK,CAAA,EAClE,kBAAC,KAAD;GAAG,WAAU;aAAb,CAAwD,EAAc,EAAI,EAAC,YAAa;KACpF;;;AAIV,SAAgB,IAAgB;CAC9B,IAAM,IAAS,IAAW,EACpB,CAAC,GAAO,KAAY,EAAmC,MAAM,EAC7D,CAAC,GAAS,KAAc,EAAiB,MAAM,EAC/C,IAAQ,IAAgB,EACxB,CAAC,IAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,GAAM,KAAW,EAA0B,EAAU,EACtD,CAAC,GAAW,KAAgB,EAAwB,KAAK,EAGzD,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAG7D,IAAc,GAAa,EAAE,YAAY,EAAE,OAAO,KAAK,EAAE,CAAC,EAC1D,KAAW,QAAsC;EACrD,IAAM,IAA8B,EAAE;AACtC,OAAK,IAAM,KAAK,EAAY,MAAM,SAAS,EAAE,CAAE,GAAI,EAAE,MAAM,EAAE;AAC7D,SAAO;IACN,CAAC,EAAY,KAAK,CAAC,EAChB,IAAe,EAAY,MAAM,SAAS,EAAE,EAE5C,EAAE,SAAM,eAAW,aAAS,gBAAY,GAAsB;EAClE,OAAO,MAAU,QAAQ,KAAA,IAAY;EACrC,SAAS,MAAY,QAAQ,KAAA,IAAY;EACzC,YAAY;GAAE,OAAO;GAAW,QAAQ,EAAM;GAAQ;EACvD,CAAC,EACI,IAAiB,IAAsB,EACvC,KAAiB,IAAsB,EAEvC,IAAO,QAAc,GAAM,SAAS,EAAE,EAAE,CAAC,EAAK,CAAC,EAG/C,EAAE,UAAO,eAAY,QAAc;EACvC,IAAM,IAA4C;GAChD,SAAS;GACT,SAAS;GACT,SAAS;GACV,EACG,IAAQ;AACZ,OAAK,IAAM,KAAK,EAEd,CADA,KAAS,EAAE,YACX,EAAQ,EAAE,UAAU,EAAE;AAExB,SAAO;GAAE;GAAO;GAAS;IACxB,CAAC,EAAK,CAAC,EAEJ,KAAuC;EAC3C;GACE,KAAK;GACL,QAAQ;GACR,SAAS,MAAM,kBAAC,IAAD,EAAa,QAAQ,EAAE,OAAS,CAAA;GAChD;EACD;GACE,KAAK;GACL,QAAQ;GACR,SAAS,MACP,kBAAC,QAAD;IAAM,WAAU;cACb,EAAE,UAAW,GAAS,EAAE,YAAY,GAAG,EAAE,QAAQ,MAAM,GAAG,EAAE,CAAC,KAAM;IAC/D,CAAA;GAEV;EACD;GACE,KAAK;GACL,QAAQ;GACR,OAAO;GACP,YAAY,MAAM,EAAE;GACpB,SAAS,MACP,kBAAC,QAAD;IAAM,WAAU;cACb,EAAiB,EAAE,WAAW;IAC1B,CAAA;GAEV;EACD;GACE,KAAK;GACL,QAAQ;GACR,cAAc;GACd,YAAY,MAAM,IAAI,KAAK,EAAE,YAAY,CAAC,SAAS;GACnD,SAAS,MACP,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACG,EAAW,EAAE,YAAY;KAAC;KAAI,EAAW,EAAE,UAAU;KACjD;;GAEV;EACD;GACE,KAAK;GACL,QAAQ;GACR,cAAc;GACd,SAAS,MAAM,kBAAC,QAAD;IAAM,WAAU;cAAuB,EAAE,UAAU;IAAW,CAAA;GAC9E;EACD;GACE,KAAK;GACL,QAAQ;GACR,SAAS,MACP,EAAE,WACA,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACE,kBAAC,IAAD,EAAc,WAAU,WAAY,CAAA;KACpC,kBAAC,QAAD;MAAM,WAAU;gBAAsB;MAAe,CAAA;KACpD,EAAE,cACD,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAW,EAAE,WAAW;MACpB,CAAA;KAEJ;QAEP,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACE,kBAAC,GAAD,EAAQ,WAAU,eAAgB,CAAA,EAClC,kBAAC,QAAD;KAAM,WAAU;eAAU;KAAiB,CAAA,CACtC;;GAEZ;EACD;GACE,KAAK;GACL,QAAQ;GACR,OAAO;GACP,cAAc;GACd,SAAS,MAAM,kBAAC,QAAD;IAAM,WAAU;cAAsB,GAAmB,EAAE,UAAU;IAAQ,CAAA;GAC7F;EACD;GACE,KAAK;GACL,QAAQ;GACR,OAAO;GACP,SAAS,MACN,EAAE,WAgBC,OAfF,kBAAC,GAAD;IACE,MAAK;IACL,SAAQ;IACR,eAAe;AAEb,KADA,EAAe,EAAE,GAAG,EACpB,GAAe,OAAO,EAAE,IAAI;MAC1B,iBAAiB,EAAO,QAAQ,oBAAoB;MACpD,UAAU,MAAM,EAAO,UAAU,EAAE;MACnC,iBAAiB,EAAe,KAAK;MACtC,CAAC;;IAEJ,UAAU,MAAgB,EAAE;cAE3B,MAAgB,EAAE,KAAK,eAAe;IAChC,CAAA;GAEd;EACF,EAEK,UAAmB;AAGvB,EAFA,EAAQ,GAAW,CAAC,EACpB,EAAa,KAAK,EAClB,EAAc,GAAK;IAGf,KAAe,YAAY;EAC/B,IAAM,IAAO,OAAO,EAAK,WAAW;AACpC,MAAI,CAAC,EAAK,cAAc,OAAO,MAAM,EAAK,IAAI,KAAQ,GAAG;GACvD,IAAM,IAAU;AAEhB,GADA,EAAa,EAAQ,EACrB,EAAO,MAAM,EAAQ;AACrB;;AAEF,MAAI,CAAC,EAAK,eAAe,CAAC,EAAK,WAAW;AACxC,KAAa,qCAAqC;AAClD;;EAEF,IAAM,IAAQ,EAAc,EAAK,YAAY,EACvC,IAAM,EAAc,EAAK,UAAU;AACzC,MAAI,CAAC,KAAS,CAAC,GAAK;AAClB,KAAa,qCAAqC;AAClD;;AAEF,MAAI,IAAI,KAAK,EAAI,CAAC,SAAS,GAAG,IAAI,KAAK,EAAM,CAAC,SAAS,EAAE;AACvD,KAAa,mDAAmD;AAChE;;AAEF,IAAa,KAAK;AAClB,MAAI;AAaF,GAZA,MAAM,EAAe,YAAY;IAC/B,SAAS,EAAK,WAAW;IACzB,OAAO,EAAK;IACZ,YAAY;IACZ,aAAa;IACb,WAAW;IACX,QAAQ,EAAK,OAAO,MAAM,IAAI;IAC9B,aAAa,EAAK,YAAY,MAAM,IAAI;IACxC,OAAO,EAAK,MAAM,MAAM,IAAI;IAC7B,CAAC,EACF,EAAO,QAAQ,oBAAoB,EACnC,EAAc,GAAM,EACpB,EAAQ,GAAW,CAAC;WACb,GAAK;AAEZ,GADA,EAAO,UAAU,EAAI,EACrB,EAAa,aAAe,QAAQ,EAAI,UAAU,6BAA6B;;;AAInF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,GAAD;GAAQ,SAAS;aAAjB,CACE,kBAAC,GAAD,EAAM,WAAU,kBAAmB,CAAA,EAAA,mBAC5B;;YANb;GAUE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA;MACrC,OAAO,EAAK,SAAS,IAAI,EAAiB,EAAM,GAAG;MACnD,OAAM;MACN,UAAA;MACA,QACE,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAK;QAAO;QAAQ,EAAK,WAAW,IAAI,KAAK;QAAI;QAChD;;MAEN,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;MACnC,OAAO,EAAK,SAAS,IAAI,EAAiB,EAAQ,QAAQ,GAAG;MAC7D,OAAM;MACN,QAAQ,EAAiB,EAAQ,SAAS,GAAO,UAAU;MAC3D,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,IAAD,EAAK,WAAU,WAAY,CAAA;MACjC,OAAO,EAAK,SAAS,IAAI,EAAiB,EAAQ,QAAQ,GAAG;MAC7D,OAAM;MACN,QAAQ,EAAiB,EAAQ,SAAS,GAAO,UAAU;MAC3D,CAAA;KACF,kBAAC,GAAD;MACE,MAAM,kBAAC,IAAD,EAAO,WAAU,WAAY,CAAA;MACnC,OAAO,EAAK,SAAS,IAAI,EAAiB,EAAQ,QAAQ,GAAG;MAC7D,OAAM;MACN,QAAQ,EAAiB,EAAQ,SAAS,GAAO,UAAU;MAC3D,CAAA;KACE;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,IAAD;KACE,SAAS;KACT,OAAO;KACP,WAAW,MAAM;AAEf,MADA,EAAS,EAAE,EACX,EAAM,OAAO;;KAEf,CAAA,EACF,kBAAC,GAAD;KACE,OAAO;KACP,gBAAgB,MAAM;AAEpB,MADA,EAAW,EAAE,EACb,EAAM,OAAO;;eAJjB,CAOE,kBAAC,GAAD;MAAe,WAAU;MAAO,cAAW;gBACzC,kBAAC,GAAD,EAAa,aAAY,cAAe,CAAA;MAC1B,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,OAAM;gBAAM;MAAuB,CAAA,EAC9C,EAAa,KAAK,MACjB,kBAAC,GAAD;MAAuB,OAAO,EAAE;gBAC7B,EAAE;MACQ,EAFI,EAAE,GAEN,CACb,CACY,EAAA,CAAA,CACT;OACL;;GAEL,KACC,kBAAC,GAAD,EAAa,OAAM,6BAA8B,CAAA,GAC/C,KACF,kBAAC,GAAD;IAAW,SAAQ;IAAkC,eAAe,IAAS;IAAI,CAAA,GAC/E,EAAK,WAAW,IAClB,kBAAC,GAAD;IACE,cAAa;IACb,MAAM,kBAAC,GAAD,EAAO,WAAU,aAAc,CAAA;IACrC,OAAM;IACN,aACE,MAAU,SAAS,MAAY,QAC3B,4EACA;IAEN,QACE,kBAAC,GAAD;KAAQ,SAAS;eAAjB,CACE,kBAAC,GAAD,EAAM,WAAU,kBAAmB,CAAA,EAAA,mBAC5B;;IAEX,CAAA,GAEF,kBAAA,IAAA,EAAA,UAAA,CACE,kBAAC,GAAD;IACW;IACH;IACN,SAAS,MAAM,EAAE;IACjB,aAAa;KAAE,KAAK;KAAU,KAAK;KAAQ;IAC3C,CAAA,EACF,kBAAC,IAAD;IACE,MAAM,EAAM;IACZ,UAAU;IACV,WAAW,EAAK;IAChB,SAAS,GAAM,UAAU,WAAW;IACpC,eAAe,MAAW,EAAM,aAAa,GAAQ,GAAM,UAAU,OAAO;IAC5E,CAAA,CACD,EAAA,CAAA;GAIL,kBAAC,IAAD;IACE,MAAM;IACN,eAAe,MAAS;AAEtB,KADA,EAAc,EAAK,EACd,MACH,EAAQ,GAAW,CAAC,EACpB,EAAa,KAAK;;cAItB,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EAAA,UAAuB,mBAAuC,CAAA,EAC9D,kBAAC,IAAD,EAAA,UAA6B,iFAEC,CAAA,CACP,EAAA,CAAA,EAEzB,kBAAC,QAAD;KACE,WAAW,MAAM;AAEV,MADL,EAAE,gBAAgB,EACb,IAAc;;eAHvB,CAME,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACA,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;oBAAU;UAAa,CAAA,EACtC,kBAAC,GAAD;UACE,OAAO,EAAK;UACZ,gBAAgB,MAAM,EAAQ;WAAE,GAAG;WAAM,OAAO;WAAuB,CAAC;oBAF1E,CAIE,kBAAC,GAAD;WAAe,IAAG;qBAChB,kBAAC,GAAD,EAAe,CAAA;WACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,EAAO,KAAK,MACX,kBAAC,GAAD;WAAoB,OAAO;qBACxB,EAAgB,EAAE;WACR,EAFI,EAEJ,CACb,EACY,CAAA,CACT;YACL;YACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;oBAAS;UAAuB,CAAA,EAC/C,kBAAC,GAAD;UACE,IAAG;UACH,MAAK;UACL,KAAI;UACJ,MAAK;UACL,OAAO,EAAK;UACZ,WAAW,MAAM,EAAQ;WAAE,GAAG;WAAM,YAAY,EAAE,OAAO;WAAO,CAAC;UACjE,aAAY;UACZ,CAAA,CACE;WACF;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;mBAAU;SAAa,CAAA,EACtC,kBAAC,GAAD;SACE,OAAO,EAAK;SACZ,gBAAgB,MAAM,EAAQ;UAAE,GAAG;UAAM,SAAS;UAAG,CAAC;mBAFxD,CAIE,kBAAC,GAAD;UAAe,IAAG;oBAChB,kBAAC,GAAD,EAAa,aAAY,gCAAiC,CAAA;UAC5C,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,EAAa,KAAK,MACjB,kBAAC,GAAD;UAAuB,OAAO,EAAE;oBAC7B,EAAE;UACQ,EAFI,EAAE,GAEN,CACb,EACY,CAAA,CACT;WACL;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;oBAAU;UAAsB,CAAA,EAC/C,kBAAC,GAAD;UACE,IAAG;UACH,MAAK;UACL,OAAO,EAAK;UACZ,WAAW,MAAM,EAAQ;WAAE,GAAG;WAAM,aAAa,EAAE,OAAO;WAAO,CAAC;UAClE,CAAA,CACE;YACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;oBAAQ;UAAoB,CAAA,EAC3C,kBAAC,GAAD;UACE,IAAG;UACH,MAAK;UACL,OAAO,EAAK;UACZ,WAAW,MAAM,EAAQ;WAAE,GAAG;WAAM,WAAW,EAAE,OAAO;WAAO,CAAC;UAChE,CAAA,CACE;WACF;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;oBAAW;UAAc,CAAA,EACxC,kBAAC,GAAD;UACE,IAAG;UACH,OAAO,EAAK;UACZ,WAAW,MAAM,EAAQ;WAAE,GAAG;WAAM,QAAQ,EAAE,OAAO;WAAO,CAAC;UAC7D,aAAY;UACZ,CAAA,CACE;YACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;oBAAW;UAAmB,CAAA,EAC7C,kBAAC,GAAD;UACE,IAAG;UACH,OAAO,EAAK;UACZ,WAAW,MAAM,EAAQ;WAAE,GAAG;WAAM,aAAa,EAAE,OAAO;WAAO,CAAC;UAClE,aAAY;UACZ,CAAA,CACE;WACF;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;mBAAU;SAAa,CAAA,EACtC,kBAAC,GAAD;SACE,IAAG;SACH,MAAM;SACN,OAAO,EAAK;SACZ,WAAW,MAAM,EAAQ;UAAE,GAAG;UAAM,OAAO,EAAE,OAAO;UAAO,CAAC;SAC5D,aAAY;SACZ,CAAA,CACE;;OAEL,KAAa,kBAAC,KAAD;QAAG,WAAU;kBAAkC;QAAc,CAAA;OACrE;SAEN,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAQ,MAAK;MAAS,SAAQ;MAAU,eAAe,EAAc,GAAM;gBAAE;MAEpE,CAAA,EACT,kBAAC,GAAD;MAAQ,MAAK;MAAS,UAAU,EAAe;gBAC5C,EAAe,YAAY,eAAe;MACpC,CAAA,CACc,EAAA,CAAA,CACpB;OACiB,EAAA,CAAA;IACT,CAAA;GACR"}
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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"}
@@ -13,11 +13,11 @@ import { INVENTORY_TRANSITIONS as de, nextStatuses as fe } from "../../utils/tra
13
13
  import { FilterTabs as pe } from "../../components/FilterTabs.js";
14
14
  import { Pagination as me } from "../../components/Pagination.js";
15
15
  import { useMemo as l, useState as u } from "react";
16
- import { Boxes as d, Coins as f, Layers as he, Plus as p, Warehouse as ge } from "lucide-react";
17
- import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
18
- import { Button as _, Input as v, Label as y, ResponsiveDialog as _e, ResponsiveDialogContent as ve, ResponsiveDialogDescription as ye, ResponsiveDialogFooter as b, ResponsiveDialogHeader as x, ResponsiveDialogTitle as S, Select as C, SelectContent as w, SelectItem as T, SelectTrigger as E, SelectValue as D, Textarea as O } from "@burdenoff/fe-libs/ui";
16
+ import { Boxes as d, Coins as f, Layers as p, Plus as m, Warehouse as he } from "lucide-react";
17
+ import { Fragment as ge, jsx as h, jsxs as g } from "react/jsx-runtime";
18
+ import { Button as _, Input as v, Label as y, ResponsiveDialog as _e, ResponsiveDialogContent as ve, ResponsiveDialogDescription as ye, ResponsiveDialogFooter as be, 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";
19
19
  //#region src/theglobalfuel/pages/inventory/InventoryPage.tsx
20
- var k = [
20
+ var O = [
21
21
  {
22
22
  value: "ALL",
23
23
  label: "All"
@@ -42,7 +42,7 @@ var k = [
42
42
  value: "WRITTEN_OFF",
43
43
  label: "Written off"
44
44
  }
45
- ], A = "__none__", j = [
45
+ ], k = "__none__", A = [
46
46
  "CRUDE_OIL",
47
47
  "NATURAL_GAS",
48
48
  "LNG",
@@ -56,7 +56,7 @@ var k = [
56
56
  "GOLD",
57
57
  "LITHIUM",
58
58
  "RARE_EARTH"
59
- ], M = [
59
+ ], j = [
60
60
  "BARRELS",
61
61
  "CUBIC_METERS",
62
62
  "TONNES",
@@ -64,7 +64,7 @@ var k = [
64
64
  "MWH",
65
65
  "GJ",
66
66
  "MCF"
67
- ], N = 25, P = (e) => e.quantity * e.unitValue, F = {
67
+ ], M = 25, N = (e) => e.quantity * e.unitValue, P = {
68
68
  lotCode: "",
69
69
  commodity: "CRUDE_OIL",
70
70
  assetId: "",
@@ -77,13 +77,13 @@ var k = [
77
77
  producedAt: "",
78
78
  notes: ""
79
79
  };
80
- function I() {
81
- let [I, be] = u("ALL"), [L, xe] = u("ALL"), R = le(), [Se, z] = u(!1), [B, V] = u(F), [H, U] = u(null), [Ce, W] = u(null), G = ue(), { data: K, isLoading: we, isError: Te, refetch: Ee } = c({
82
- status: I === "ALL" ? void 0 : I,
83
- commodity: L === "ALL" ? void 0 : L,
80
+ function F() {
81
+ let [F, xe] = u("ALL"), [I, L] = u("ALL"), R = le(), [Se, z] = u(!1), [B, V] = u(P), [H, U] = u(null), [Ce, W] = u(null), G = ue(), { data: K, isLoading: we, isError: Te, refetch: Ee } = c({
82
+ status: F === "ALL" ? void 0 : F,
83
+ commodity: I === "ALL" ? void 0 : I,
84
84
  pagination: {
85
- limit: N,
86
- cursor: R.cursor
85
+ limit: M,
86
+ offset: R.page * M
87
87
  }
88
88
  }), q = c({ pagination: { limit: 200 } }), J = oe({ pagination: { limit: 200 } }), Y = se(), De = ce(), X = l(() => K?.items ?? [], [K]), Z = l(() => {
89
89
  let e = {};
@@ -97,7 +97,7 @@ function I() {
97
97
  let a = /* @__PURE__ */ new Map();
98
98
  for (let e of t) {
99
99
  let t = e.currency || "USD";
100
- a.set(t, (a.get(t) ?? 0) + P(e));
100
+ a.set(t, (a.get(t) ?? 0) + N(e));
101
101
  }
102
102
  let o = "USD", s = 0;
103
103
  for (let [e, t] of a) t > s && (s = t, o = e);
@@ -187,10 +187,10 @@ function I() {
187
187
  header: "Value",
188
188
  align: "right",
189
189
  hideOnMobile: !0,
190
- sortValue: (e) => P(e),
190
+ sortValue: (e) => N(e),
191
191
  render: (e) => /* @__PURE__ */ h("span", {
192
192
  className: "tabular-nums text-text-secondary",
193
- children: i(P(e), e.currency)
193
+ children: i(N(e), e.currency)
194
194
  })
195
195
  },
196
196
  {
@@ -210,7 +210,7 @@ function I() {
210
210
  align: "right",
211
211
  render: (e) => {
212
212
  let t = fe(de, e.status), n = t.length === 0, i = Ce === e.id;
213
- return /* @__PURE__ */ g(C, {
213
+ return /* @__PURE__ */ g(S, {
214
214
  value: e.status,
215
215
  disabled: n || i,
216
216
  onValueChange: (t) => {
@@ -223,15 +223,15 @@ function I() {
223
223
  onSettled: () => W(null)
224
224
  });
225
225
  },
226
- children: [/* @__PURE__ */ h(E, {
226
+ children: [/* @__PURE__ */ h(T, {
227
227
  className: "h-8 w-36",
228
228
  "aria-label": `Change status for lot ${e.lotCode}`,
229
- children: /* @__PURE__ */ h(D, {})
230
- }), /* @__PURE__ */ g(w, { children: [/* @__PURE__ */ h(T, {
229
+ children: /* @__PURE__ */ h(E, {})
230
+ }), /* @__PURE__ */ g(C, { children: [/* @__PURE__ */ h(w, {
231
231
  value: e.status,
232
232
  disabled: !0,
233
233
  children: r(e.status)
234
- }), t.map((e) => /* @__PURE__ */ h(T, {
234
+ }), t.map((e) => /* @__PURE__ */ h(w, {
235
235
  value: e,
236
236
  children: r(e)
237
237
  }, e))] })]
@@ -239,7 +239,7 @@ function I() {
239
239
  }
240
240
  }
241
241
  ], $ = () => {
242
- V(F), U(null);
242
+ V(P), U(null);
243
243
  }, ke = async () => {
244
244
  if (!B.lotCode.trim()) {
245
245
  U("Lot code is required.");
@@ -301,14 +301,14 @@ function I() {
301
301
  description: "Commodity inventory lots — on-hand quantity, grade, location & book value across the portfolio.",
302
302
  actions: /* @__PURE__ */ g(_, {
303
303
  onClick: () => z(!0),
304
- children: [/* @__PURE__ */ h(p, { className: "mr-1.5 h-4 w-4" }), " New lot"]
304
+ children: [/* @__PURE__ */ h(m, { className: "mr-1.5 h-4 w-4" }), " New lot"]
305
305
  }),
306
306
  children: [
307
307
  /* @__PURE__ */ g("div", {
308
308
  className: "mb-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
309
309
  children: [
310
310
  /* @__PURE__ */ h(t, {
311
- icon: /* @__PURE__ */ h(ge, { className: "h-5 w-5" }),
311
+ icon: /* @__PURE__ */ h(he, { className: "h-5 w-5" }),
312
312
  value: q.data ? a(Q.totalLots) : "—",
313
313
  label: "Inventory lots",
314
314
  featured: !0,
@@ -318,7 +318,7 @@ function I() {
318
318
  }) : void 0
319
319
  }),
320
320
  /* @__PURE__ */ h(t, {
321
- icon: /* @__PURE__ */ h(he, { className: "h-5 w-5" }),
321
+ icon: /* @__PURE__ */ h(p, { className: "h-5 w-5" }),
322
322
  value: q.data ? s(Q.topUnitQty, Q.topUnit) : "—",
323
323
  label: "On-hand quantity",
324
324
  accent: "success",
@@ -335,24 +335,24 @@ function I() {
335
335
  /* @__PURE__ */ g("div", {
336
336
  className: "mb-5 flex flex-wrap items-center gap-3",
337
337
  children: [/* @__PURE__ */ h(pe, {
338
- options: k,
339
- value: I,
338
+ options: O,
339
+ value: F,
340
340
  onChange: (e) => {
341
- be(e), R.reset();
341
+ xe(e), R.reset();
342
342
  }
343
- }), /* @__PURE__ */ g(C, {
344
- value: L,
343
+ }), /* @__PURE__ */ g(S, {
344
+ value: I,
345
345
  onValueChange: (e) => {
346
- xe(e), R.reset();
346
+ L(e), R.reset();
347
347
  },
348
- children: [/* @__PURE__ */ h(E, {
348
+ children: [/* @__PURE__ */ h(T, {
349
349
  className: "w-48",
350
350
  "aria-label": "Filter by commodity",
351
- children: /* @__PURE__ */ h(D, { placeholder: "All commodities" })
352
- }), /* @__PURE__ */ g(w, { children: [/* @__PURE__ */ h(T, {
351
+ children: /* @__PURE__ */ h(E, { placeholder: "All commodities" })
352
+ }), /* @__PURE__ */ g(C, { children: [/* @__PURE__ */ h(w, {
353
353
  value: "ALL",
354
354
  children: "All commodities"
355
- }), j.map((e) => /* @__PURE__ */ h(T, {
355
+ }), A.map((e) => /* @__PURE__ */ h(w, {
356
356
  value: e,
357
357
  children: r(e)
358
358
  }, e))] })]
@@ -365,28 +365,28 @@ function I() {
365
365
  illustration: "empty-data",
366
366
  icon: /* @__PURE__ */ h(d, { className: "h-10 w-10" }),
367
367
  title: "No inventory lots yet",
368
- description: I === "ALL" && L === "ALL" ? "Create your first inventory lot to track on-hand commodity quantity, grade and value." : "No lots match these filters.",
368
+ description: F === "ALL" && I === "ALL" ? "Create your first inventory lot to track on-hand commodity quantity, grade and value." : "No lots match these filters.",
369
369
  action: /* @__PURE__ */ g(_, {
370
370
  onClick: () => z(!0),
371
- children: [/* @__PURE__ */ h(p, { className: "mr-1.5 h-4 w-4" }), " New lot"]
371
+ children: [/* @__PURE__ */ h(m, { className: "mr-1.5 h-4 w-4" }), " New lot"]
372
372
  })
373
- }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(ne, {
373
+ }) : /* @__PURE__ */ g(ge, { children: [/* @__PURE__ */ h(ne, {
374
374
  columns: Oe,
375
375
  rows: X,
376
376
  rowKey: (e) => e.id
377
377
  }), /* @__PURE__ */ h(me, {
378
378
  page: R.page,
379
- pageSize: N,
379
+ pageSize: M,
380
380
  itemCount: X.length,
381
381
  hasMore: K?.pageInfo?.hasMore ?? !1,
382
- onPageChange: (e) => R.onPageChange(e, K?.pageInfo?.cursor)
382
+ onPageChange: R.onPageChange
383
383
  })] }),
384
384
  /* @__PURE__ */ h(_e, {
385
385
  open: Se,
386
386
  onOpenChange: (e) => {
387
387
  z(e), e || $();
388
388
  },
389
- children: /* @__PURE__ */ g(ve, { children: [/* @__PURE__ */ g(x, { children: [/* @__PURE__ */ h(S, { children: "New inventory lot" }), /* @__PURE__ */ h(ye, { children: "Register an on-hand quantity of a commodity — optionally attributed to a producing asset." })] }), /* @__PURE__ */ g("form", {
389
+ children: /* @__PURE__ */ g(ve, { children: [/* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(x, { children: "New inventory lot" }), /* @__PURE__ */ h(ye, { children: "Register an on-hand quantity of a commodity — optionally attributed to a producing asset." })] }), /* @__PURE__ */ g("form", {
390
390
  onSubmit: (e) => {
391
391
  e.preventDefault(), ke();
392
392
  },
@@ -414,16 +414,16 @@ function I() {
414
414
  children: [/* @__PURE__ */ h(y, {
415
415
  htmlFor: "commodity",
416
416
  children: "Commodity *"
417
- }), /* @__PURE__ */ g(C, {
417
+ }), /* @__PURE__ */ g(S, {
418
418
  value: B.commodity,
419
419
  onValueChange: (e) => V({
420
420
  ...B,
421
421
  commodity: e
422
422
  }),
423
- children: [/* @__PURE__ */ h(E, {
423
+ children: [/* @__PURE__ */ h(T, {
424
424
  id: "commodity",
425
- children: /* @__PURE__ */ h(D, {})
426
- }), /* @__PURE__ */ h(w, { children: j.map((e) => /* @__PURE__ */ h(T, {
425
+ children: /* @__PURE__ */ h(E, {})
426
+ }), /* @__PURE__ */ h(C, { children: A.map((e) => /* @__PURE__ */ h(w, {
427
427
  value: e,
428
428
  children: r(e)
429
429
  }, e)) })]
@@ -435,19 +435,19 @@ function I() {
435
435
  children: [/* @__PURE__ */ h(y, {
436
436
  htmlFor: "assetId",
437
437
  children: "Produced by asset"
438
- }), /* @__PURE__ */ g(C, {
439
- value: B.assetId || A,
438
+ }), /* @__PURE__ */ g(S, {
439
+ value: B.assetId || k,
440
440
  onValueChange: (e) => V({
441
441
  ...B,
442
- assetId: e === A ? "" : e
442
+ assetId: e === k ? "" : e
443
443
  }),
444
- children: [/* @__PURE__ */ h(E, {
444
+ children: [/* @__PURE__ */ h(T, {
445
445
  id: "assetId",
446
- children: /* @__PURE__ */ h(D, { placeholder: "Optional — link to a producing asset" })
447
- }), /* @__PURE__ */ g(w, { children: [/* @__PURE__ */ h(T, {
448
- value: A,
446
+ children: /* @__PURE__ */ h(E, { placeholder: "Optional — link to a producing asset" })
447
+ }), /* @__PURE__ */ g(C, { children: [/* @__PURE__ */ h(w, {
448
+ value: k,
449
449
  children: "None"
450
- }), Object.entries(Z).map(([e, t]) => /* @__PURE__ */ h(T, {
450
+ }), Object.entries(Z).map(([e, t]) => /* @__PURE__ */ h(w, {
451
451
  value: e,
452
452
  children: t
453
453
  }, e))] })]
@@ -479,16 +479,16 @@ function I() {
479
479
  children: [/* @__PURE__ */ h(y, {
480
480
  htmlFor: "unit",
481
481
  children: "Unit"
482
- }), /* @__PURE__ */ g(C, {
482
+ }), /* @__PURE__ */ g(S, {
483
483
  value: B.unit,
484
484
  onValueChange: (e) => V({
485
485
  ...B,
486
486
  unit: e
487
487
  }),
488
- children: [/* @__PURE__ */ h(E, {
488
+ children: [/* @__PURE__ */ h(T, {
489
489
  id: "unit",
490
- children: /* @__PURE__ */ h(D, {})
491
- }), /* @__PURE__ */ h(w, { children: M.map((e) => /* @__PURE__ */ h(T, {
490
+ children: /* @__PURE__ */ h(E, {})
491
+ }), /* @__PURE__ */ h(C, { children: j.map((e) => /* @__PURE__ */ h(w, {
492
492
  value: e,
493
493
  children: o(e)
494
494
  }, e)) })]
@@ -586,7 +586,7 @@ function I() {
586
586
  children: [/* @__PURE__ */ h(y, {
587
587
  htmlFor: "notes",
588
588
  children: "Notes"
589
- }), /* @__PURE__ */ h(O, {
589
+ }), /* @__PURE__ */ h(D, {
590
590
  id: "notes",
591
591
  rows: 2,
592
592
  value: B.notes,
@@ -602,7 +602,7 @@ function I() {
602
602
  children: H
603
603
  })
604
604
  ]
605
- }), /* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(_, {
605
+ }), /* @__PURE__ */ g(be, { children: [/* @__PURE__ */ h(_, {
606
606
  type: "button",
607
607
  variant: "outline",
608
608
  onClick: () => {
@@ -620,6 +620,6 @@ function I() {
620
620
  });
621
621
  }
622
622
  //#endregion
623
- export { I as InventoryPage };
623
+ export { F as InventoryPage };
624
624
 
625
625
  //# sourceMappingURL=InventoryPage.js.map