@burdenoff/microfe-theglobalfuel 2026.704.1 → 2026.705.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.
- package/dist/node_modules/{.bun/clsx@2.1.1/node_modules/clsx → clsx}/dist/clsx.js +1 -1
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/{.bun/tailwind-merge@3.5.0/node_modules/tailwind-merge → tailwind-merge}/dist/bundle-mjs.js +212 -170
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/dist/theglobalfuel/components/DataTable.js +37 -27
- package/dist/theglobalfuel/components/DataTable.js.map +1 -1
- package/dist/theglobalfuel/hooks/index.js +1 -0
- package/dist/theglobalfuel/hooks/useNotify.js +19 -0
- package/dist/theglobalfuel/hooks/useNotify.js.map +1 -0
- package/dist/theglobalfuel/hooks/useTheFiles.js +4 -1
- package/dist/theglobalfuel/hooks/useTheFiles.js.map +1 -1
- package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js +59 -31
- package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.js.map +1 -1
- package/dist/theglobalfuel/pages/assets/AssetDetailPage.js +367 -321
- package/dist/theglobalfuel/pages/assets/AssetDetailPage.js.map +1 -1
- package/dist/theglobalfuel/pages/assets/AssetsPage.js +66 -54
- package/dist/theglobalfuel/pages/assets/AssetsPage.js.map +1 -1
- package/dist/theglobalfuel/pages/compliance/CompliancePage.js +346 -182
- package/dist/theglobalfuel/pages/compliance/CompliancePage.js.map +1 -1
- package/dist/theglobalfuel/pages/contracts/ContractDetailPage.js +418 -390
- package/dist/theglobalfuel/pages/contracts/ContractDetailPage.js.map +1 -1
- package/dist/theglobalfuel/pages/contracts/ContractsPage.js +238 -230
- package/dist/theglobalfuel/pages/contracts/ContractsPage.js.map +1 -1
- package/dist/theglobalfuel/pages/dashboard/DashboardPage.js +5 -3
- package/dist/theglobalfuel/pages/dashboard/DashboardPage.js.map +1 -1
- package/dist/theglobalfuel/pages/emissions/EmissionsPage.js +201 -177
- package/dist/theglobalfuel/pages/emissions/EmissionsPage.js.map +1 -1
- package/dist/theglobalfuel/pages/inventory/InventoryPage.js +271 -238
- package/dist/theglobalfuel/pages/inventory/InventoryPage.js.map +1 -1
- package/dist/theglobalfuel/pages/production/ProductionPage.js +185 -177
- package/dist/theglobalfuel/pages/production/ProductionPage.js.map +1 -1
- package/dist/theglobalfuel/pages/reserves/ReservesPage.js +160 -138
- package/dist/theglobalfuel/pages/reserves/ReservesPage.js.map +1 -1
- package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js +250 -198
- package/dist/theglobalfuel/pages/shipments/ShipmentsPage.js.map +1 -1
- package/dist/theglobalfuel/utils/cn.js +2 -2
- package/dist/theglobalfuel/utils/formatters.js +6 -1
- package/dist/theglobalfuel/utils/formatters.js.map +1 -1
- package/dist/theglobalfuel/utils/transitions.js +70 -0
- package/dist/theglobalfuel/utils/transitions.js.map +1 -0
- package/package.json +1 -1
- package/dist/dev/main.d.ts +0 -2
- package/dist/dev/main.d.ts.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js.map +0 -1
- package/dist/node_modules/.bun/tailwind-merge@3.5.0/node_modules/tailwind-merge/dist/bundle-mjs.js.map +0 -1
- package/dist/theglobalfuel/TheGlobalFuelRoot.d.ts +0 -5
- package/dist/theglobalfuel/TheGlobalFuelRoot.d.ts.map +0 -1
- package/dist/theglobalfuel/TheGlobalFuelRoutes.d.ts +0 -4
- package/dist/theglobalfuel/TheGlobalFuelRoutes.d.ts.map +0 -1
- package/dist/theglobalfuel/components/DataTable.d.ts +0 -28
- package/dist/theglobalfuel/components/DataTable.d.ts.map +0 -1
- package/dist/theglobalfuel/components/EmptyState.d.ts +0 -18
- package/dist/theglobalfuel/components/EmptyState.d.ts.map +0 -1
- package/dist/theglobalfuel/components/EvidenceUpload.d.ts +0 -14
- package/dist/theglobalfuel/components/EvidenceUpload.d.ts.map +0 -1
- package/dist/theglobalfuel/components/FileLink.d.ts +0 -15
- package/dist/theglobalfuel/components/FileLink.d.ts.map +0 -1
- package/dist/theglobalfuel/components/FilterTabs.d.ts +0 -18
- package/dist/theglobalfuel/components/FilterTabs.d.ts.map +0 -1
- package/dist/theglobalfuel/components/MetricsCard.d.ts +0 -23
- package/dist/theglobalfuel/components/MetricsCard.d.ts.map +0 -1
- package/dist/theglobalfuel/components/MiniBar.d.ts +0 -16
- package/dist/theglobalfuel/components/MiniBar.d.ts.map +0 -1
- package/dist/theglobalfuel/components/PageLayout.d.ts +0 -16
- package/dist/theglobalfuel/components/PageLayout.d.ts.map +0 -1
- package/dist/theglobalfuel/components/Pagination.d.ts +0 -22
- package/dist/theglobalfuel/components/Pagination.d.ts.map +0 -1
- package/dist/theglobalfuel/components/StateViews.d.ts +0 -24
- package/dist/theglobalfuel/components/StateViews.d.ts.map +0 -1
- package/dist/theglobalfuel/components/StatusBadge.d.ts +0 -9
- package/dist/theglobalfuel/components/StatusBadge.d.ts.map +0 -1
- package/dist/theglobalfuel/components/Tabs.d.ts +0 -17
- package/dist/theglobalfuel/components/Tabs.d.ts.map +0 -1
- package/dist/theglobalfuel/components/TheDiscussion.d.ts +0 -18
- package/dist/theglobalfuel/components/TheDiscussion.d.ts.map +0 -1
- package/dist/theglobalfuel/components/TheTags.d.ts +0 -17
- package/dist/theglobalfuel/components/TheTags.d.ts.map +0 -1
- package/dist/theglobalfuel/components/index.d.ts +0 -19
- package/dist/theglobalfuel/components/index.d.ts.map +0 -1
- package/dist/theglobalfuel/context/TheGlobalFuelContext.d.ts +0 -16
- package/dist/theglobalfuel/context/TheGlobalFuelContext.d.ts.map +0 -1
- package/dist/theglobalfuel/context/index.d.ts +0 -6
- package/dist/theglobalfuel/context/index.d.ts.map +0 -1
- package/dist/theglobalfuel/hooks/index.d.ts +0 -10
- package/dist/theglobalfuel/hooks/index.d.ts.map +0 -1
- package/dist/theglobalfuel/hooks/useCursorPager.d.ts +0 -33
- package/dist/theglobalfuel/hooks/useCursorPager.d.ts.map +0 -1
- package/dist/theglobalfuel/hooks/useTheComments.d.ts +0 -36
- package/dist/theglobalfuel/hooks/useTheComments.d.ts.map +0 -1
- package/dist/theglobalfuel/hooks/useTheFiles.d.ts +0 -47
- package/dist/theglobalfuel/hooks/useTheFiles.d.ts.map +0 -1
- package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts +0 -75
- package/dist/theglobalfuel/hooks/useTheGlobalFuelApi.d.ts.map +0 -1
- package/dist/theglobalfuel/hooks/useTheTags.d.ts +0 -44
- package/dist/theglobalfuel/hooks/useTheTags.d.ts.map +0 -1
- package/dist/theglobalfuel/index.d.ts +0 -9
- package/dist/theglobalfuel/index.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/assets/AssetDetailPage.d.ts +0 -13
- package/dist/theglobalfuel/pages/assets/AssetDetailPage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/assets/AssetsPage.d.ts +0 -10
- package/dist/theglobalfuel/pages/assets/AssetsPage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/compliance/CompliancePage.d.ts +0 -11
- package/dist/theglobalfuel/pages/compliance/CompliancePage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/contracts/ContractDetailPage.d.ts +0 -9
- package/dist/theglobalfuel/pages/contracts/ContractDetailPage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/contracts/ContractsPage.d.ts +0 -8
- package/dist/theglobalfuel/pages/contracts/ContractsPage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/dashboard/DashboardPage.d.ts +0 -13
- package/dist/theglobalfuel/pages/dashboard/DashboardPage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/emissions/EmissionsPage.d.ts +0 -12
- package/dist/theglobalfuel/pages/emissions/EmissionsPage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/inventory/InventoryPage.d.ts +0 -11
- package/dist/theglobalfuel/pages/inventory/InventoryPage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/production/ProductionPage.d.ts +0 -11
- package/dist/theglobalfuel/pages/production/ProductionPage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/reserves/ReservesPage.d.ts +0 -10
- package/dist/theglobalfuel/pages/reserves/ReservesPage.d.ts.map +0 -1
- package/dist/theglobalfuel/pages/shipments/ShipmentsPage.d.ts +0 -10
- package/dist/theglobalfuel/pages/shipments/ShipmentsPage.d.ts.map +0 -1
- package/dist/theglobalfuel/types/index.d.ts +0 -376
- package/dist/theglobalfuel/types/index.d.ts.map +0 -1
- package/dist/theglobalfuel/utils/cn.d.ts +0 -4
- package/dist/theglobalfuel/utils/cn.d.ts.map +0 -1
- package/dist/theglobalfuel/utils/formatters.d.ts +0 -36
- package/dist/theglobalfuel/utils/formatters.d.ts.map +0 -1
- package/dist/theglobalfuel/utils/i18n.d.ts +0 -6
- package/dist/theglobalfuel/utils/i18n.d.ts.map +0 -1
- package/dist/theglobalfuel/utils/index.d.ts +0 -9
- package/dist/theglobalfuel/utils/index.d.ts.map +0 -1
- package/dist/theglobalfuel/utils/navigation.d.ts +0 -14
- package/dist/theglobalfuel/utils/navigation.d.ts.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 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} from '../../hooks';\nimport {\n formatDate,\n formatRelativeTime,\n formatPercent,\n formatTonnesCo2e,\n formatEnumLabel,\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 [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\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 </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={() => verifyEmission.mutate(r.id)}\n disabled={verifyEmission.isPending}\n >\n 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 if (!form.co2eTonnes) {\n setFormError('CO₂e (tonnes) is required.');\n return;\n }\n if (!form.periodStart || !form.periodEnd) {\n setFormError('Period start and end are required.');\n return;\n }\n if (new Date(form.periodEnd).getTime() < new Date(form.periodStart).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: Number(form.co2eTonnes),\n periodStart: new Date(form.periodStart).toISOString(),\n periodEnd: new Date(form.periodEnd).toISOString(),\n source: form.source.trim() || null,\n methodology: form.methodology.trim() || null,\n notes: form.notes.trim() || null,\n });\n setDialogOpen(false);\n setForm(emptyForm());\n } catch (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\">\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 <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 variant=\"outline\" onClick={() => setDialogOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleRecord} disabled={recordEmission.isPending}>\n {recordEmission.isPending ? 'Recording…' : 'Record emission'}\n </Button>\n </ResponsiveDialogFooter>\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 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":"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"}
|