@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":"DashboardPage.js","names":[],"sources":["../../../../src/theglobalfuel/pages/dashboard/DashboardPage.tsx"],"sourcesContent":["/**\n * Dashboard — TheGlobalFuel resources operating-system overview.\n * @module theglobalfuel/pages/dashboard\n *\n * The hero landing (eager-loaded). Every figure is aggregated client-side from\n * the real `the*` list endpoints — no mock data. KPIs summarise the registry\n * (Assets / Production), commerce (Contracts / Shipments / Inventory) and\n * sustainability (Emissions / Compliance) domains; distribution cards derive\n * bars straight from the fetched arrays; recent-activity tables link into the\n * relevant detail routes. Pre-launch empty states are handled gracefully.\n */\n\nimport { useMemo, type ReactNode } from 'react';\nimport {\n Layers,\n ScrollText,\n Ship,\n Factory,\n Boxes,\n ShieldCheck,\n ArrowRight,\n Fuel,\n GitBranch,\n Gauge,\n ClipboardList,\n} from 'lucide-react';\nimport { GlassCard, Spinner } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { MiniBar } from '../../components/MiniBar';\nimport { DataTable, type Column } from '../../components/DataTable';\nimport { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useTheGlobalFuel } from '../../context';\nimport {\n useTheAssets,\n useTheContracts,\n useTheShipments,\n useTheEmissionRecords,\n useTheInventoryLots,\n useTheComplianceCerts,\n useTheProductionRecords,\n} from '../../hooks';\nimport {\n formatNumber,\n formatPercent,\n formatDate,\n formatRelativeTime,\n formatEnumLabel,\n formatVolume,\n formatTonnesCo2e,\n isExpired,\n} from '../../utils/formatters';\nimport type {\n TheAssetStatus,\n TheEmissionScope,\n TheOfftakeContract,\n TheProductionRecord,\n} from '../../types';\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst EXPIRY_WINDOW_DAYS = 30;\n\n/** True when a cert expires within the next 30 days (but hasn't yet). */\nconst isExpiringSoon = (date: string | null | undefined): boolean => {\n if (!date) return false;\n const t = new Date(date).getTime();\n if (Number.isNaN(t)) return false;\n const diff = t - Date.now();\n return diff >= 0 && diff <= EXPIRY_WINDOW_DAYS * DAY_MS;\n};\n\n/** Asset lifecycle → MiniBar fill token (semantic, maturity-ordered). */\nconst ASSET_STATUS_BAR: Record<TheAssetStatus, string> = {\n EXPLORATION: 'bg-[var(--color-accent-indigo)]',\n APPRAISAL: 'bg-[var(--color-accent-blue)]',\n DEVELOPMENT: 'bg-[var(--color-accent-teal)]',\n PRODUCING: 'bg-status-success-text',\n SUSPENDED: 'bg-status-warning-text',\n DECOMMISSIONING: 'bg-status-error-text',\n RETIRED: 'bg-[var(--color-text-tertiary)]',\n};\n\n/** GHG scope → MiniBar fill token (Scope 1 direct · 2 energy · 3 value-chain). */\nconst SCOPE_BAR: Record<TheEmissionScope, string> = {\n SCOPE_1: 'bg-status-error-text',\n SCOPE_2: 'bg-status-warning-text',\n SCOPE_3: 'bg-[var(--color-accent-blue)]',\n};\n\nconst ALL_SCOPES: TheEmissionScope[] = ['SCOPE_1', 'SCOPE_2', 'SCOPE_3'];\n\n/** Group rows by a discriminator, sorted by descending count, with % of total. */\nfunction distribution<T>(\n rows: T[],\n keyOf: (row: T) => string\n): { key: string; count: number; pct: number }[] {\n const counts = new Map<string, number>();\n for (const row of rows) {\n const k = keyOf(row);\n counts.set(k, (counts.get(k) ?? 0) + 1);\n }\n const total = rows.length;\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([key, count]) => ({ key, count, pct: total ? (count / total) * 100 : 0 }));\n}\n\ninterface DistBar {\n key: string;\n label: ReactNode;\n /** Pre-formatted primary figure shown right of the bar. */\n value: string;\n /** 0–100 — drives the bar width + the muted percentage. */\n pct: number;\n barClassName: string;\n}\n\ninterface DistributionCardProps {\n title: string;\n description: string;\n icon: ReactNode;\n linkLabel: string;\n onLink: () => void;\n isLoading: boolean;\n isError: boolean;\n onRetry: () => void;\n emptyLabel: string;\n bars: DistBar[];\n footer?: ReactNode;\n}\n\n/** A titled glass card that renders a compact set of MiniBar distribution rows. */\nfunction DistributionCard({\n title,\n description,\n icon,\n linkLabel,\n onLink,\n isLoading,\n isError,\n onRetry,\n emptyLabel,\n bars,\n footer,\n}: DistributionCardProps) {\n return (\n <GlassCard treatment=\"glass\" className=\"flex flex-col p-5\">\n <div className=\"mb-4 flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span className=\"mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent\">\n {icon}\n </span>\n <div className=\"min-w-0\">\n <h2 className=\"text-base font-semibold text-text-primary\">{title}</h2>\n <p className=\"mt-0.5 text-xs text-text-tertiary\">{description}</p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onLink}\n className=\"inline-flex shrink-0 items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n {linkLabel} <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n\n {isLoading ? (\n <div className=\"flex items-center gap-2 py-8 text-sm text-text-secondary\">\n <Spinner size=\"sm\" /> Loading…\n </div>\n ) : isError ? (\n <div className=\"flex flex-col items-start gap-2 py-6\">\n <p className=\"text-sm text-status-error-text\">Couldn&apos;t load {title.toLowerCase()}.</p>\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"rounded-lg border border-border-seam px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken\"\n >\n Retry\n </button>\n </div>\n ) : bars.length === 0 ? (\n <div className=\"flex flex-1 flex-col items-center justify-center rounded-xl border border-dashed border-border-seam py-8 text-center\">\n <p className=\"text-sm text-text-secondary\">{emptyLabel}</p>\n </div>\n ) : (\n <div className=\"flex flex-1 flex-col justify-between gap-4\">\n <div className=\"space-y-3\">\n {bars.map((bar) => (\n <div key={bar.key} className=\"flex items-center gap-3\">\n <div className=\"w-24 shrink-0 truncate text-sm text-text-secondary sm:w-28\">\n {bar.label}\n </div>\n <MiniBar value={bar.pct} barClassName={bar.barClassName} className=\"flex-1\" height={8} />\n <span className=\"w-16 shrink-0 whitespace-nowrap text-right text-sm font-medium tabular-nums text-text-primary\">\n {bar.value}\n </span>\n <span className=\"hidden w-11 shrink-0 text-right text-xs tabular-nums text-text-tertiary sm:inline\">\n {formatPercent(bar.pct)}\n </span>\n </div>\n ))}\n </div>\n {footer && (\n <p className=\"border-t border-border-seam/70 pt-3 text-xs text-text-tertiary\">{footer}</p>\n )}\n </div>\n )}\n </GlassCard>\n );\n}\n\nexport function DashboardPage() {\n const { navigateTo, currentUser } = useTheGlobalFuel();\n\n // Real backend queries (limit 50 for connection lists — plenty for a summary).\n const assets = useTheAssets({ pagination: { limit: 50 } });\n const contracts = useTheContracts({ pagination: { limit: 50 } });\n const shipments = useTheShipments(undefined, 'IN_TRANSIT');\n const emissions = useTheEmissionRecords({ pagination: { limit: 50 } });\n const inventory = useTheInventoryLots({ pagination: { limit: 50 } });\n const compliance = useTheComplianceCerts();\n const production = useTheProductionRecords({ pagination: { limit: 12 } });\n\n const assetRows = useMemo(() => assets.data?.items ?? [], [assets.data]);\n const contractRows = useMemo(() => contracts.data?.items ?? [], [contracts.data]);\n const inTransitRows = useMemo(() => shipments.data?.items ?? [], [shipments.data]);\n const emissionRows = useMemo(() => emissions.data?.items ?? [], [emissions.data]);\n const inventoryRows = useMemo(() => inventory.data?.items ?? [], [inventory.data]);\n const certRows = useMemo(() => compliance.data?.items ?? [], [compliance.data]);\n const productionRows = useMemo(() => production.data?.items ?? [], [production.data]);\n\n // ── KPI aggregates ─────────────────────────────────────────────────────────\n const producingCount = assetRows.filter((a) => a.status === 'PRODUCING').length;\n const activeContracts = contractRows.filter((c) => c.status === 'ACTIVE').length;\n const totalTonnes = emissionRows.reduce((sum, e) => sum + (e.co2eTonnes ?? 0), 0);\n const verifiedEmissions = emissionRows.filter((e) => e.verified).length;\n const availableLots = inventoryRows.filter((l) => l.status === 'AVAILABLE').length;\n\n const pendingCerts = certRows.filter((c) => c.status === 'PENDING').length;\n const expiringCerts = certRows.filter(\n (c) => c.expiresAt != null && (isExpired(c.expiresAt) || isExpiringSoon(c.expiresAt))\n ).length;\n const attentionCerts = certRows.filter(\n (c) =>\n c.status === 'PENDING' ||\n (c.expiresAt != null && (isExpired(c.expiresAt) || isExpiringSoon(c.expiresAt)))\n ).length;\n\n const withPlus = (rows: unknown[], hasMore: boolean | undefined): string =>\n hasMore ? `${rows.length}+` : formatNumber(rows.length);\n\n // ── Distribution derivations ───────────────────────────────────────────────\n const commodityBars = useMemo<DistBar[]>(\n () =>\n distribution(assetRows, (a) => a.commodity).map((d) => ({\n key: d.key,\n label: <span className=\"truncate\">{formatEnumLabel(d.key)}</span>,\n value: formatNumber(d.count),\n pct: d.pct,\n barClassName: 'bg-[var(--color-accent-blue)]',\n })),\n [assetRows]\n );\n\n const lifecycleBars = useMemo<DistBar[]>(\n () =>\n distribution(assetRows, (a) => a.status).map((d) => ({\n key: d.key,\n label: <StatusBadge status={d.key} />,\n value: formatNumber(d.count),\n pct: d.pct,\n barClassName: ASSET_STATUS_BAR[d.key as TheAssetStatus] ?? 'bg-action-primary-bg',\n })),\n [assetRows]\n );\n\n const scopeBars = useMemo<DistBar[]>(() => {\n if (emissionRows.length === 0) return [];\n const totals: Record<TheEmissionScope, number> = { SCOPE_1: 0, SCOPE_2: 0, SCOPE_3: 0 };\n for (const e of emissionRows) totals[e.scope] = (totals[e.scope] ?? 0) + (e.co2eTonnes ?? 0);\n const grand = totals.SCOPE_1 + totals.SCOPE_2 + totals.SCOPE_3;\n return ALL_SCOPES.map((scope) => ({\n key: scope,\n label: <StatusBadge status={scope} />,\n value: `${formatNumber(totals[scope], { maximumFractionDigits: totals[scope] >= 100 ? 0 : 1 })} t`,\n pct: grand > 0 ? (totals[scope] / grand) * 100 : 0,\n barClassName: SCOPE_BAR[scope],\n }));\n }, [emissionRows]);\n\n // ── Recent activity ────────────────────────────────────────────────────────\n const assetName = useMemo(() => {\n const m = new Map<string, string>();\n for (const a of assetRows) m.set(a.id, a.name);\n return m;\n }, [assetRows]);\n\n const recentContracts = useMemo(\n () =>\n [...contractRows]\n .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())\n .slice(0, 6),\n [contractRows]\n );\n\n const recentProduction = useMemo(\n () =>\n [...productionRows]\n .sort((a, b) => new Date(b.periodEnd).getTime() - new Date(a.periodEnd).getTime())\n .slice(0, 6),\n [productionRows]\n );\n\n const contractColumns: Column<TheOfftakeContract>[] = [\n {\n key: 'reference',\n header: 'Reference',\n render: (c) => <span className=\"font-medium text-text-primary\">{c.reference}</span>,\n },\n {\n key: 'counterparty',\n header: 'Counterparty',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-secondary\">{c.counterparty}</span>,\n },\n {\n key: 'commodity',\n header: 'Commodity',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-secondary\">{formatEnumLabel(c.commodity)}</span>,\n },\n { key: 'side', header: 'Side', render: (c) => <StatusBadge status={c.side} /> },\n {\n key: 'volume',\n header: 'Volume',\n align: 'right',\n hideOnMobile: true,\n render: (c) => (\n <span className=\"tabular-nums text-text-secondary\">\n {formatVolume(c.contractedVolume, c.unit)}\n </span>\n ),\n },\n { key: 'status', header: 'Status', render: (c) => <StatusBadge status={c.status} /> },\n {\n key: 'created',\n header: 'Created',\n align: 'right',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-tertiary\">{formatRelativeTime(c.createdAt)}</span>,\n },\n ];\n\n const productionColumns: Column<TheProductionRecord>[] = [\n {\n key: 'asset',\n header: 'Asset',\n render: (p) => (\n <span className=\"font-medium text-text-primary\">\n {assetName.get(p.assetId) ?? 'Unknown asset'}\n </span>\n ),\n },\n {\n key: 'period',\n header: 'Period',\n hideOnMobile: true,\n render: (p) => (\n <span className=\"text-text-secondary\">\n {formatDate(p.periodStart)} – {formatDate(p.periodEnd)}\n </span>\n ),\n },\n {\n key: 'volume',\n header: 'Volume',\n align: 'right',\n render: (p) => (\n <span className=\"tabular-nums font-medium text-text-primary\">\n {formatVolume(p.volume, p.unit)}\n </span>\n ),\n },\n {\n key: 'downtime',\n header: 'Downtime',\n align: 'right',\n hideOnMobile: true,\n render: (p) => (\n <span className=\"tabular-nums text-text-secondary\">{formatNumber(p.downtimeHours)} h</span>\n ),\n },\n {\n key: 'logged',\n header: 'Logged',\n align: 'right',\n hideOnMobile: true,\n render: (p) => <span className=\"text-text-tertiary\">{formatRelativeTime(p.createdAt)}</span>,\n },\n ];\n\n const greetingName = currentUser?.firstName || currentUser?.name || 'there';\n const description = `Welcome back, ${greetingName} — your energy, mineral & commodity resource control room.`;\n\n // Full-page loader only while every primary domain is still loading its first page.\n const initialLoading =\n assets.isLoading &&\n contracts.isLoading &&\n emissions.isLoading &&\n inventory.isLoading &&\n compliance.isLoading;\n\n if (initialLoading) {\n return (\n <PageLayout title=\"TheGlobalFuel\" titleGradient aurora description={description}>\n <LoadingView label=\"Loading your resource portfolio…\" />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout title=\"TheGlobalFuel\" titleGradient aurora description={description}>\n {/* KPI grid */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6\">\n <MetricsCard\n icon={<Layers className=\"h-5 w-5\" />}\n value={withPlus(assetRows, assets.data?.pageInfo?.hasMore)}\n label=\"Resource assets\"\n featured\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={assetRows.length ? (producingCount / assetRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-status-success-text\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">{producingCount}</span> producing\n </p>\n </div>\n }\n />\n\n <MetricsCard\n icon={<ScrollText className=\"h-5 w-5\" />}\n value={withPlus(contractRows, contracts.data?.pageInfo?.hasMore)}\n label=\"Offtake contracts\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={contractRows.length ? (activeContracts / contractRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-action-primary-bg\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">{activeContracts}</span> active\n </p>\n </div>\n }\n />\n\n <MetricsCard\n icon={<Ship className=\"h-5 w-5\" />}\n value={shipments.isError ? '—' : formatNumber(inTransitRows.length)}\n label=\"Shipments in transit\"\n footer={\n <p className=\"text-xs text-text-tertiary\">\n {inTransitRows.length > 0 ? 'In motion across carriers' : 'No active movements'}\n </p>\n }\n />\n\n <MetricsCard\n icon={<Factory className=\"h-5 w-5\" />}\n value={emissions.isError ? '—' : formatTonnesCo2e(totalTonnes)}\n label=\"Emissions logged\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={emissionRows.length ? (verifiedEmissions / emissionRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-status-success-text\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">{verifiedEmissions}</span>{' '}\n verified\n </p>\n </div>\n }\n />\n\n <MetricsCard\n icon={<Boxes className=\"h-5 w-5\" />}\n value={inventory.isError ? '—' : formatNumber(availableLots)}\n label=\"Inventory available\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={inventoryRows.length ? (availableLots / inventoryRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-action-primary-bg\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">\n {withPlus(inventoryRows, inventory.data?.pageInfo?.hasMore)}\n </span>{' '}\n lots total\n </p>\n </div>\n }\n />\n\n <MetricsCard\n icon={<ShieldCheck className=\"h-5 w-5\" />}\n value={compliance.isError ? '—' : formatNumber(attentionCerts)}\n label=\"Certs need attention\"\n accent={attentionCerts > 0 ? 'warning' : certRows.length > 0 ? 'success' : undefined}\n footer={\n <p\n className={\n attentionCerts > 0\n ? 'text-xs font-medium text-status-warning-text'\n : 'text-xs text-text-tertiary'\n }\n >\n {certRows.length === 0\n ? 'No certifications tracked yet'\n : attentionCerts > 0\n ? `${pendingCerts} pending · ${expiringCerts} expiring`\n : 'All certifications current'}\n </p>\n }\n />\n </div>\n\n {/* Distribution cards — every bar derived from the fetched arrays */}\n <div className=\"mt-6 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n <DistributionCard\n title=\"Assets by commodity\"\n description=\"Portfolio mix across energy, mineral & metal streams.\"\n icon={<Fuel className=\"h-4 w-4\" />}\n linkLabel=\"Assets\"\n onLink={() => navigateTo('assets')}\n isLoading={assets.isLoading}\n isError={assets.isError}\n onRetry={() => assets.refetch()}\n emptyLabel=\"No assets registered yet.\"\n bars={commodityBars}\n footer={\n assetRows.length > 0\n ? `${withPlus(assetRows, assets.data?.pageInfo?.hasMore)} assets across ${commodityBars.length} ${commodityBars.length === 1 ? 'commodity' : 'commodities'}`\n : undefined\n }\n />\n\n <DistributionCard\n title=\"Assets by lifecycle\"\n description=\"Where the portfolio sits from exploration to retirement.\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n linkLabel=\"Assets\"\n onLink={() => navigateTo('assets')}\n isLoading={assets.isLoading}\n isError={assets.isError}\n onRetry={() => assets.refetch()}\n emptyLabel=\"No assets to profile yet.\"\n bars={lifecycleBars}\n footer={\n assetRows.length > 0\n ? `${producingCount} of ${withPlus(assetRows, assets.data?.pageInfo?.hasMore)} currently producing`\n : undefined\n }\n />\n\n <DistributionCard\n title=\"Emissions by scope\"\n description=\"GHG Protocol Scope 1 / 2 / 3 (tonnes CO₂e logged).\"\n icon={<Gauge className=\"h-4 w-4\" />}\n linkLabel=\"Emissions\"\n onLink={() => navigateTo('emissions')}\n isLoading={emissions.isLoading}\n isError={emissions.isError}\n onRetry={() => emissions.refetch()}\n emptyLabel=\"No emission records logged yet.\"\n bars={scopeBars}\n footer={\n emissionRows.length > 0\n ? `${formatTonnesCo2e(totalTonnes)} across ${withPlus(emissionRows, emissions.data?.pageInfo?.hasMore)} records`\n : undefined\n }\n />\n </div>\n\n {/* Recent offtake contracts */}\n <Section\n title=\"Recent offtake contracts\"\n description=\"Latest buy/sell agreements across your commodity book.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('contracts')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n All contracts <ArrowRight className=\"h-4 w-4\" />\n </button>\n }\n >\n {contracts.isLoading ? (\n <LoadingView label=\"Loading contracts…\" />\n ) : contracts.isError ? (\n <ErrorView message=\"Couldn't load contracts.\" onRetry={() => contracts.refetch()} />\n ) : recentContracts.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<ScrollText className=\"h-10 w-10\" />}\n title=\"No contracts yet\"\n description=\"Draft your first offtake contract to start tracking commodity trade.\"\n />\n ) : (\n <DataTable\n columns={contractColumns}\n rows={recentContracts}\n rowKey={(c) => c.id}\n onRowClick={(c) => navigateTo(`contracts/${c.id}`)}\n rowLabel={(c) => `Open contract ${c.reference}`}\n />\n )}\n </Section>\n\n {/* Recent production */}\n <Section\n title=\"Recent production\"\n description=\"Latest metered output captured against your producing assets.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('production')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n All production <ArrowRight className=\"h-4 w-4\" />\n </button>\n }\n >\n {production.isLoading ? (\n <LoadingView label=\"Loading production…\" />\n ) : production.isError ? (\n <ErrorView message=\"Couldn't load production records.\" onRetry={() => production.refetch()} />\n ) : recentProduction.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<ClipboardList className=\"h-10 w-10\" />}\n title=\"No production logged yet\"\n description=\"Record production against an asset to build its output history.\"\n />\n ) : (\n <DataTable\n columns={productionColumns}\n rows={recentProduction}\n rowKey={(p) => p.id}\n onRowClick={(p) => navigateTo(`assets/${p.assetId}`)}\n rowLabel={(p) => `Open ${assetName.get(p.assetId) ?? 'asset'}`}\n />\n )}\n </Section>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../../src/theglobalfuel/pages/dashboard/DashboardPage.tsx"],"sourcesContent":["/**\n * Dashboard — TheGlobalFuel resources operating-system overview.\n * @module theglobalfuel/pages/dashboard\n *\n * The hero landing (eager-loaded). Every figure is aggregated client-side from\n * the real `the*` list endpoints — no mock data. The page opens with the domain\n * KPI grid (registry / commerce / sustainability), then a rich analytics band:\n * - a PRODUCTION TREND area chart (metered output bucketed by month),\n * - a COMMODITY MIX donut (share of assets by commodity), and\n * - an EMISSIONS-BY-SCOPE donut (tonnes CO₂e per GHG scope);\n * a COMMODITY PORTFOLIO grid (one glass card per commodity present, with real\n * asset counts, summed capacity and a production sparkline); an ASSETS-BY-\n * LIFECYCLE distribution; and recent-activity tables. All charts derive from\n * the fetched arrays and degrade to pre-launch empty states.\n */\n\nimport { useMemo, type ReactNode } from 'react';\nimport {\n Layers,\n ScrollText,\n Ship,\n Factory,\n Boxes,\n ShieldCheck,\n ArrowRight,\n ArrowUpRight,\n Fuel,\n GitBranch,\n Gauge,\n Activity,\n ClipboardList,\n} from 'lucide-react';\nimport { GlassCard, Spinner } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { MiniBar } from '../../components/MiniBar';\nimport { DataTable, type Column } from '../../components/DataTable';\nimport { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport {\n AreaChart,\n DonutChart,\n Sparkline,\n chartPalette,\n type LabeledValue,\n type Segment,\n} from '../../components/viz';\nimport { cn } from '../../utils/cn';\nimport { useTheGlobalFuel } from '../../context';\nimport {\n useTheAssets,\n useTheContracts,\n useTheShipments,\n useTheEmissionRecords,\n useTheInventoryLots,\n useTheComplianceCerts,\n useTheProductionRecords,\n} from '../../hooks';\nimport {\n formatNumber,\n formatPercent,\n formatDate,\n formatRelativeTime,\n formatEnumLabel,\n formatVolume,\n formatTonnesCo2e,\n isExpired,\n} from '../../utils/formatters';\nimport type {\n TheAssetStatus,\n TheCommodityType,\n TheEmissionScope,\n TheOfftakeContract,\n TheProductionRecord,\n} from '../../types';\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst EXPIRY_WINDOW_DAYS = 30;\n\n/** True when a cert expires within the next 30 days (but hasn't yet). */\nconst isExpiringSoon = (date: string | null | undefined): boolean => {\n if (!date) return false;\n const t = new Date(date).getTime();\n if (Number.isNaN(t)) return false;\n const diff = t - Date.now();\n return diff >= 0 && diff <= EXPIRY_WINDOW_DAYS * DAY_MS;\n};\n\n/** Asset lifecycle → MiniBar fill token (semantic, maturity-ordered). */\nconst ASSET_STATUS_BAR: Record<TheAssetStatus, string> = {\n EXPLORATION: 'bg-[var(--color-accent-indigo)]',\n APPRAISAL: 'bg-[var(--color-accent-blue)]',\n DEVELOPMENT: 'bg-[var(--color-accent-teal)]',\n PRODUCING: 'bg-status-success-text',\n SUSPENDED: 'bg-status-warning-text',\n DECOMMISSIONING: 'bg-status-error-text',\n RETIRED: 'bg-[var(--color-text-tertiary)]',\n};\n\n/** GHG scope → donut segment color token (Scope 1 direct · 2 energy · 3 chain). */\nconst SCOPE_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\nconst ALL_SCOPES: TheEmissionScope[] = ['SCOPE_1', 'SCOPE_2', 'SCOPE_3'];\n\n// ── Month bucketing (UTC-stable, gap-free) ───────────────────────────────────\n\n/** UTC year-month key (e.g. \"2026-07\"). */\nconst monthKey = (d: Date): string =>\n `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}`;\n\nconst MONTH_FMT = new Intl.DateTimeFormat(undefined, {\n month: 'short',\n year: '2-digit',\n timeZone: 'UTC',\n});\n\nconst monthLabel = (year: number, month1: number): string =>\n MONTH_FMT.format(new Date(Date.UTC(year, month1 - 1, 1)));\n\n/** Sum `valueOf` into UTC-month buckets keyed by the `dateOf` field. */\nfunction bucketByMonth<T>(\n rows: readonly T[],\n dateOf: (row: T) => string | null | undefined,\n valueOf: (row: T) => number\n): Map<string, number> {\n const buckets = new Map<string, number>();\n for (const row of rows) {\n const raw = dateOf(row);\n if (!raw) continue;\n const d = new Date(raw);\n if (Number.isNaN(d.getTime())) continue;\n const key = monthKey(d);\n buckets.set(key, (buckets.get(key) ?? 0) + valueOf(row));\n }\n return buckets;\n}\n\n/**\n * Expand month buckets into a gap-free ordered series from the earliest to the\n * latest populated month (so a trend line stays continuous), then keep only the\n * most recent `maxMonths` so a stray old record can't blow out the axis.\n */\nfunction monthlySeries(buckets: Map<string, number>, maxMonths = 18): LabeledValue[] {\n const keys = [...buckets.keys()].sort();\n if (keys.length === 0) return [];\n const parse = (k: string): [number, number] => {\n const [y, m] = k.split('-');\n return [Number(y), Number(m)];\n };\n const [maxY, maxM] = parse(keys[keys.length - 1]);\n let [y, m] = parse(keys[0]);\n const series: LabeledValue[] = [];\n let guard = 0;\n while ((y < maxY || (y === maxY && m <= maxM)) && guard < 240) {\n series.push({\n label: monthLabel(y, m),\n value: buckets.get(`${y}-${String(m).padStart(2, '0')}`) ?? 0,\n });\n m += 1;\n if (m > 12) {\n m = 1;\n y += 1;\n }\n guard += 1;\n }\n return series.length > maxMonths ? series.slice(series.length - maxMonths) : series;\n}\n\n/** Group rows by a discriminator, sorted by descending count, with % of total. */\nfunction distribution<T>(\n rows: T[],\n keyOf: (row: T) => string\n): { key: string; count: number; pct: number }[] {\n const counts = new Map<string, number>();\n for (const row of rows) {\n const k = keyOf(row);\n counts.set(k, (counts.get(k) ?? 0) + 1);\n }\n const total = rows.length;\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([key, count]) => ({ key, count, pct: total ? (count / total) * 100 : 0 }));\n}\n\n// ── Distribution card (MiniBar rows) ─────────────────────────────────────────\n\ninterface DistBar {\n key: string;\n label: ReactNode;\n /** Pre-formatted primary figure shown right of the bar. */\n value: string;\n /** 0–100 — drives the bar width + the muted percentage. */\n pct: number;\n barClassName: string;\n}\n\ninterface DistributionCardProps {\n title: string;\n description: string;\n icon: ReactNode;\n linkLabel: string;\n onLink: () => void;\n isLoading: boolean;\n isError: boolean;\n onRetry: () => void;\n emptyLabel: string;\n bars: DistBar[];\n footer?: ReactNode;\n className?: string;\n}\n\n/** A titled glass card that renders a compact set of MiniBar distribution rows. */\nfunction DistributionCard({\n title,\n description,\n icon,\n linkLabel,\n onLink,\n isLoading,\n isError,\n onRetry,\n emptyLabel,\n bars,\n footer,\n className,\n}: DistributionCardProps) {\n return (\n <GlassCard treatment=\"glass\" className={cn('flex flex-col p-5', className)}>\n <div className=\"mb-4 flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span className=\"mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent\">\n {icon}\n </span>\n <div className=\"min-w-0\">\n <h2 className=\"text-base font-semibold text-text-primary\">{title}</h2>\n <p className=\"mt-0.5 text-xs text-text-tertiary\">{description}</p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onLink}\n className=\"inline-flex shrink-0 items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n {linkLabel} <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n\n {isLoading ? (\n <div className=\"flex items-center gap-2 py-8 text-sm text-text-secondary\">\n <Spinner size=\"sm\" /> Loading…\n </div>\n ) : isError ? (\n <div className=\"flex flex-col items-start gap-2 py-6\">\n <p className=\"text-sm text-status-error-text\">Couldn&apos;t load {title.toLowerCase()}.</p>\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"rounded-lg border border-border-seam px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken\"\n >\n Retry\n </button>\n </div>\n ) : bars.length === 0 ? (\n <div className=\"flex flex-1 flex-col items-center justify-center rounded-xl border border-dashed border-border-seam py-8 text-center\">\n <p className=\"text-sm text-text-secondary\">{emptyLabel}</p>\n </div>\n ) : (\n <div className=\"flex flex-1 flex-col justify-between gap-4\">\n <div className=\"space-y-3\">\n {bars.map((bar) => (\n <div key={bar.key} className=\"flex items-center gap-3\">\n <div className=\"w-24 shrink-0 truncate text-sm text-text-secondary sm:w-28\">\n {bar.label}\n </div>\n <MiniBar value={bar.pct} barClassName={bar.barClassName} className=\"flex-1\" height={8} />\n <span className=\"w-16 shrink-0 whitespace-nowrap text-right text-sm font-medium tabular-nums text-text-primary\">\n {bar.value}\n </span>\n <span className=\"hidden w-11 shrink-0 text-right text-xs tabular-nums text-text-tertiary sm:inline\">\n {formatPercent(bar.pct)}\n </span>\n </div>\n ))}\n </div>\n {footer && (\n <p className=\"border-t border-border-seam/70 pt-3 text-xs text-text-tertiary\">{footer}</p>\n )}\n </div>\n )}\n </GlassCard>\n );\n}\n\n// ── Chart card (titled glass panel for a chart body) ─────────────────────────\n\ninterface ChartCardProps {\n title: string;\n caption: string;\n icon: ReactNode;\n link?: { label: string; onClick: () => void };\n isLoading: boolean;\n isError: boolean;\n onRetry: () => void;\n isEmpty: boolean;\n emptyLabel: string;\n footer?: ReactNode;\n className?: string;\n children: ReactNode;\n}\n\n/** A titled glass card wrapping a viz-kit chart, with loading/error/empty states. */\nfunction ChartCard({\n title,\n caption,\n icon,\n link,\n isLoading,\n isError,\n onRetry,\n isEmpty,\n emptyLabel,\n footer,\n className,\n children,\n}: ChartCardProps) {\n return (\n <GlassCard treatment=\"glass\" className={cn('flex flex-col p-5', className)}>\n <div className=\"mb-4 flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span className=\"mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-accent\">\n {icon}\n </span>\n <div className=\"min-w-0\">\n <h2 className=\"text-base font-semibold text-text-primary\">{title}</h2>\n <p className=\"mt-0.5 text-xs text-text-tertiary\">{caption}</p>\n </div>\n </div>\n {link ? (\n <button\n type=\"button\"\n onClick={link.onClick}\n className=\"inline-flex shrink-0 items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n {link.label} <ArrowRight className=\"h-4 w-4\" />\n </button>\n ) : null}\n </div>\n\n {isLoading ? (\n <div className=\"flex flex-1 items-center gap-2 py-8 text-sm text-text-secondary\">\n <Spinner size=\"sm\" /> Loading…\n </div>\n ) : isError ? (\n <div className=\"flex flex-1 flex-col items-start gap-2 py-6\">\n <p className=\"text-sm text-status-error-text\">Couldn&apos;t load {title.toLowerCase()}.</p>\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"rounded-lg border border-border-seam px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken\"\n >\n Retry\n </button>\n </div>\n ) : isEmpty ? (\n <div className=\"flex flex-1 flex-col items-center justify-center rounded-xl border border-dashed border-border-seam py-10 text-center\">\n <p className=\"text-sm text-text-secondary\">{emptyLabel}</p>\n </div>\n ) : (\n <div className=\"flex flex-1 flex-col justify-between gap-4\">\n <div className=\"flex-1\">{children}</div>\n {footer ? (\n <p className=\"border-t border-border-seam/70 pt-3 text-xs text-text-tertiary\">{footer}</p>\n ) : null}\n </div>\n )}\n </GlassCard>\n );\n}\n\n// ── Commodity portfolio card ─────────────────────────────────────────────────\n\ninterface CommodityPortfolioEntry {\n key: TheCommodityType;\n name: string;\n /** Tokenized commodity color, shared with the commodity-mix donut. */\n color: string;\n assetCount: number;\n producing: number;\n capacity: number;\n /** Dominant `TheUnit` token across the commodity's assets. */\n unit: string;\n /** Monthly production volumes (oldest first) — empty when none logged. */\n spark: number[];\n}\n\nfunction CommodityCard({ card, onOpen }: { card: CommodityPortfolioEntry; onOpen: () => void }) {\n return (\n <GlassCard treatment=\"metric\" className=\"p-0\">\n <button\n type=\"button\"\n onClick={onOpen}\n aria-label={`Open ${card.name} assets`}\n className=\"flex w-full flex-col gap-4 rounded-[var(--radius-card)] p-5 text-left outline-none transition-transform duration-200 hover:-translate-y-0.5 focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-2.5\">\n <span\n aria-hidden=\"true\"\n className=\"size-2.5 shrink-0 rounded-full\"\n style={{ backgroundColor: card.color }}\n />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold text-text-primary\">{card.name}</p>\n <p className=\"text-xs text-text-tertiary\">\n {card.assetCount} {card.assetCount === 1 ? 'asset' : 'assets'}\n </p>\n </div>\n </div>\n <ArrowUpRight className=\"h-4 w-4 shrink-0 text-text-tertiary\" />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-[11px] uppercase tracking-wide text-text-tertiary\">Capacity/day</p>\n <p className=\"mt-0.5 truncate text-sm font-semibold tabular-nums text-text-primary\">\n {card.capacity > 0 ? formatVolume(card.capacity, card.unit) : '—'}\n </p>\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-[11px] uppercase tracking-wide text-text-tertiary\">Producing</p>\n <p className=\"mt-0.5 text-sm font-semibold tabular-nums text-text-primary\">\n {card.producing}{' '}\n <span className=\"text-xs font-normal text-text-tertiary\">of {card.assetCount}</span>\n </p>\n </div>\n </div>\n\n {card.spark.length >= 2 ? (\n <div>\n <Sparkline\n data={card.spark}\n variant=\"area\"\n height={40}\n label={`${card.name} monthly production`}\n />\n <p className=\"mt-1 text-[11px] text-text-tertiary\">Monthly output</p>\n </div>\n ) : (\n <p className=\"text-xs text-text-tertiary\">No production logged yet.</p>\n )}\n </button>\n </GlassCard>\n );\n}\n\nexport function DashboardPage() {\n const { navigateTo, currentUser } = useTheGlobalFuel();\n\n // Real backend queries. Aggregate domains fetch a generous page (200) so the\n // charts + portfolio reflect the whole book; commerce lists stay at 50.\n const assets = useTheAssets({ pagination: { limit: 200 } });\n const contracts = useTheContracts({ pagination: { limit: 50 } });\n const shipments = useTheShipments(undefined, 'IN_TRANSIT');\n const emissions = useTheEmissionRecords({ pagination: { limit: 200 } });\n const inventory = useTheInventoryLots({ pagination: { limit: 50 } });\n const compliance = useTheComplianceCerts();\n const production = useTheProductionRecords({ pagination: { limit: 200 } });\n\n const assetRows = useMemo(() => assets.data?.items ?? [], [assets.data]);\n const contractRows = useMemo(() => contracts.data?.items ?? [], [contracts.data]);\n const inTransitRows = useMemo(() => shipments.data?.items ?? [], [shipments.data]);\n const emissionRows = useMemo(() => emissions.data?.items ?? [], [emissions.data]);\n const inventoryRows = useMemo(() => inventory.data?.items ?? [], [inventory.data]);\n const certRows = useMemo(() => compliance.data?.items ?? [], [compliance.data]);\n const productionRows = useMemo(() => production.data?.items ?? [], [production.data]);\n\n // ── KPI aggregates ─────────────────────────────────────────────────────────\n const producingCount = assetRows.filter((a) => a.status === 'PRODUCING').length;\n const activeContracts = contractRows.filter((c) => c.status === 'ACTIVE').length;\n const totalTonnes = emissionRows.reduce((sum, e) => sum + (e.co2eTonnes ?? 0), 0);\n const verifiedEmissions = emissionRows.filter((e) => e.verified).length;\n const availableLots = inventoryRows.filter((l) => l.status === 'AVAILABLE').length;\n const totalProductionVolume = productionRows.reduce((sum, p) => sum + (p.volume ?? 0), 0);\n\n const pendingCerts = certRows.filter((c) => c.status === 'PENDING').length;\n const expiringCerts = certRows.filter(\n (c) => c.expiresAt != null && (isExpired(c.expiresAt) || isExpiringSoon(c.expiresAt))\n ).length;\n const attentionCerts = certRows.filter(\n (c) =>\n c.status === 'PENDING' ||\n (c.expiresAt != null && (isExpired(c.expiresAt) || isExpiringSoon(c.expiresAt)))\n ).length;\n\n const withPlus = (rows: unknown[], hasMore: boolean | undefined): string =>\n hasMore ? `${rows.length}+` : formatNumber(rows.length);\n\n // ── Production trend (metered output by month) ───────────────────────────────\n const productionSeries = useMemo<LabeledValue[]>(\n () =>\n monthlySeries(\n bucketByMonth(\n productionRows,\n (p) => p.periodEnd,\n (p) => p.volume ?? 0\n )\n ),\n [productionRows]\n );\n\n // ── Commodity distribution + shared per-commodity colors ─────────────────────\n const commodityDist = useMemo(() => distribution(assetRows, (a) => a.commodity), [assetRows]);\n\n const commodityColor = useMemo(() => {\n const palette = chartPalette(commodityDist.length);\n const map = new Map<string, string>();\n commodityDist.forEach((d, i) => map.set(d.key, palette[i]));\n return map;\n }, [commodityDist]);\n\n const commodityMix = useMemo<Segment[]>(\n () =>\n commodityDist.map((d) => ({\n label: formatEnumLabel(d.key),\n value: d.count,\n color: commodityColor.get(d.key),\n })),\n [commodityDist, commodityColor]\n );\n\n // ── Emissions by scope (tonnes CO₂e) ─────────────────────────────────────────\n const scopeMix = useMemo<Segment[]>(() => {\n if (emissionRows.length === 0) return [];\n const totals: Record<TheEmissionScope, number> = { SCOPE_1: 0, SCOPE_2: 0, SCOPE_3: 0 };\n for (const e of emissionRows) totals[e.scope] += e.co2eTonnes ?? 0;\n return ALL_SCOPES.filter((s) => totals[s] > 0).map((s) => ({\n label: formatEnumLabel(s),\n value: totals[s],\n color: SCOPE_COLOR[s],\n }));\n }, [emissionRows]);\n\n // ── Assets by lifecycle (MiniBar rows) ───────────────────────────────────────\n const lifecycleBars = useMemo<DistBar[]>(\n () =>\n distribution(assetRows, (a) => a.status).map((d) => ({\n key: d.key,\n label: <StatusBadge status={d.key} />,\n value: formatNumber(d.count),\n pct: d.pct,\n barClassName: ASSET_STATUS_BAR[d.key as TheAssetStatus] ?? 'bg-action-primary-bg',\n })),\n [assetRows]\n );\n\n // ── Commodity portfolio (one entry per commodity with assets) ────────────────\n const assetCommodity = useMemo(() => {\n const m = new Map<string, TheCommodityType>();\n for (const a of assetRows) m.set(a.id, a.commodity);\n return m;\n }, [assetRows]);\n\n const commodityCards = useMemo<CommodityPortfolioEntry[]>(() => {\n if (commodityDist.length === 0) return [];\n\n // Per-commodity asset aggregates.\n interface Agg {\n count: number;\n producing: number;\n capacity: number;\n units: Map<string, number>;\n }\n const agg = new Map<string, Agg>();\n for (const a of assetRows) {\n const cur =\n agg.get(a.commodity) ??\n { count: 0, producing: 0, capacity: 0, units: new Map<string, number>() };\n cur.count += 1;\n if (a.status === 'PRODUCING') cur.producing += 1;\n cur.capacity += a.capacityPerDay ?? 0;\n if (a.capacityUnit) cur.units.set(a.capacityUnit, (cur.units.get(a.capacityUnit) ?? 0) + 1);\n agg.set(a.commodity, cur);\n }\n\n // Per-commodity monthly production buckets → sparkline series.\n const prodBuckets = new Map<string, Map<string, number>>();\n for (const p of productionRows) {\n const commodity = assetCommodity.get(p.assetId);\n if (!commodity) continue;\n const d = new Date(p.periodEnd);\n if (Number.isNaN(d.getTime())) continue;\n const mk = monthKey(d);\n let bucket = prodBuckets.get(commodity);\n if (!bucket) {\n bucket = new Map<string, number>();\n prodBuckets.set(commodity, bucket);\n }\n bucket.set(mk, (bucket.get(mk) ?? 0) + (p.volume ?? 0));\n }\n\n const dominantUnit = (units: Map<string, number>): string => {\n let best = '';\n let bestN = -1;\n for (const [unit, n] of units) {\n if (n > bestN) {\n best = unit;\n bestN = n;\n }\n }\n return best;\n };\n\n return commodityDist.map((d) => {\n const a =\n agg.get(d.key) ??\n { count: 0, producing: 0, capacity: 0, units: new Map<string, number>() };\n const bucket = prodBuckets.get(d.key);\n const spark = bucket ? monthlySeries(bucket, 12).map((s) => s.value) : [];\n return {\n key: d.key as TheCommodityType,\n name: formatEnumLabel(d.key),\n color: commodityColor.get(d.key) ?? 'var(--color-accent-primary)',\n assetCount: a.count,\n producing: a.producing,\n capacity: a.capacity,\n unit: dominantUnit(a.units),\n spark,\n };\n });\n }, [assetRows, productionRows, assetCommodity, commodityDist, commodityColor]);\n\n // ── Recent activity ────────────────────────────────────────────────────────\n const assetName = useMemo(() => {\n const m = new Map<string, string>();\n for (const a of assetRows) m.set(a.id, a.name);\n return m;\n }, [assetRows]);\n\n const recentContracts = useMemo(\n () =>\n [...contractRows]\n .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())\n .slice(0, 6),\n [contractRows]\n );\n\n const recentProduction = useMemo(\n () =>\n [...productionRows]\n .sort((a, b) => new Date(b.periodEnd).getTime() - new Date(a.periodEnd).getTime())\n .slice(0, 6),\n [productionRows]\n );\n\n const contractColumns: Column<TheOfftakeContract>[] = [\n {\n key: 'reference',\n header: 'Reference',\n render: (c) => <span className=\"font-medium text-text-primary\">{c.reference}</span>,\n },\n {\n key: 'counterparty',\n header: 'Counterparty',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-secondary\">{c.counterparty}</span>,\n },\n {\n key: 'commodity',\n header: 'Commodity',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-secondary\">{formatEnumLabel(c.commodity)}</span>,\n },\n { key: 'side', header: 'Side', render: (c) => <StatusBadge status={c.side} /> },\n {\n key: 'volume',\n header: 'Volume',\n align: 'right',\n hideOnMobile: true,\n render: (c) => (\n <span className=\"tabular-nums text-text-secondary\">\n {formatVolume(c.contractedVolume, c.unit)}\n </span>\n ),\n },\n { key: 'status', header: 'Status', render: (c) => <StatusBadge status={c.status} /> },\n {\n key: 'created',\n header: 'Created',\n align: 'right',\n hideOnMobile: true,\n render: (c) => <span className=\"text-text-tertiary\">{formatRelativeTime(c.createdAt)}</span>,\n },\n ];\n\n const productionColumns: Column<TheProductionRecord>[] = [\n {\n key: 'asset',\n header: 'Asset',\n render: (p) => (\n <span className=\"font-medium text-text-primary\">\n {assetName.get(p.assetId) ?? 'Unknown asset'}\n </span>\n ),\n },\n {\n key: 'period',\n header: 'Period',\n hideOnMobile: true,\n render: (p) => (\n <span className=\"text-text-secondary\">\n {formatDate(p.periodStart)} – {formatDate(p.periodEnd)}\n </span>\n ),\n },\n {\n key: 'volume',\n header: 'Volume',\n align: 'right',\n render: (p) => (\n <span className=\"tabular-nums font-medium text-text-primary\">\n {formatVolume(p.volume, p.unit)}\n </span>\n ),\n },\n {\n key: 'downtime',\n header: 'Downtime',\n align: 'right',\n hideOnMobile: true,\n render: (p) => (\n <span className=\"tabular-nums text-text-secondary\">{formatNumber(p.downtimeHours)} h</span>\n ),\n },\n {\n key: 'logged',\n header: 'Logged',\n align: 'right',\n hideOnMobile: true,\n render: (p) => <span className=\"text-text-tertiary\">{formatRelativeTime(p.createdAt)}</span>,\n },\n ];\n\n const greetingName = currentUser?.firstName || currentUser?.name || 'there';\n const description = `Welcome back, ${greetingName} — your energy, mineral & commodity resource control room.`;\n\n // Full-page loader only while every primary domain is still loading its first page.\n const initialLoading =\n assets.isLoading &&\n contracts.isLoading &&\n emissions.isLoading &&\n inventory.isLoading &&\n compliance.isLoading;\n\n if (initialLoading) {\n return (\n <PageLayout title=\"TheGlobalFuel\" titleGradient aurora description={description}>\n <LoadingView label=\"Loading your resource portfolio…\" />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout title=\"TheGlobalFuel\" titleGradient aurora description={description}>\n {/* KPI grid */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6\">\n <MetricsCard\n icon={<Layers className=\"h-5 w-5\" />}\n value={withPlus(assetRows, assets.data?.pageInfo?.hasMore)}\n label=\"Resource assets\"\n featured\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={assetRows.length ? (producingCount / assetRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-status-success-text\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">{producingCount}</span> producing\n </p>\n </div>\n }\n />\n\n <MetricsCard\n icon={<ScrollText className=\"h-5 w-5\" />}\n value={withPlus(contractRows, contracts.data?.pageInfo?.hasMore)}\n label=\"Offtake contracts\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={contractRows.length ? (activeContracts / contractRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-action-primary-bg\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">{activeContracts}</span> active\n </p>\n </div>\n }\n />\n\n <MetricsCard\n icon={<Ship className=\"h-5 w-5\" />}\n value={shipments.isError ? '—' : formatNumber(inTransitRows.length)}\n label=\"Shipments in transit\"\n footer={\n <p className=\"text-xs text-text-tertiary\">\n {inTransitRows.length > 0 ? 'In motion across carriers' : 'No active movements'}\n </p>\n }\n />\n\n <MetricsCard\n icon={<Factory className=\"h-5 w-5\" />}\n value={emissions.isError ? '—' : formatTonnesCo2e(totalTonnes)}\n label=\"Emissions logged\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={emissionRows.length ? (verifiedEmissions / emissionRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-status-success-text\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">{verifiedEmissions}</span>{' '}\n verified\n </p>\n </div>\n }\n />\n\n <MetricsCard\n icon={<Boxes className=\"h-5 w-5\" />}\n value={inventory.isError ? '—' : formatNumber(availableLots)}\n label=\"Inventory available\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={inventoryRows.length ? (availableLots / inventoryRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-action-primary-bg\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">\n {withPlus(inventoryRows, inventory.data?.pageInfo?.hasMore)}\n </span>{' '}\n lots total\n </p>\n </div>\n }\n />\n\n <MetricsCard\n icon={<ShieldCheck className=\"h-5 w-5\" />}\n value={compliance.isError ? '—' : formatNumber(attentionCerts)}\n label=\"Certs need attention\"\n accent={attentionCerts > 0 ? 'warning' : certRows.length > 0 ? 'success' : undefined}\n footer={\n <p\n className={\n attentionCerts > 0\n ? 'text-xs font-medium text-status-warning-text'\n : 'text-xs text-text-tertiary'\n }\n >\n {certRows.length === 0\n ? 'No certifications tracked yet'\n : attentionCerts > 0\n ? `${pendingCerts} pending · ${expiringCerts} expiring`\n : 'All certifications current'}\n </p>\n }\n />\n </div>\n\n {/* Analytics — production trend + commodity mix (real aggregates) */}\n <div className=\"mt-6 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n <ChartCard\n className=\"lg:col-span-2\"\n title=\"Production trend\"\n caption=\"Metered output aggregated by month across your producing assets.\"\n icon={<Activity className=\"h-4 w-4\" />}\n link={{ label: 'Production', onClick: () => navigateTo('production') }}\n isLoading={production.isLoading}\n isError={production.isError}\n onRetry={() => production.refetch()}\n isEmpty={productionSeries.length === 0}\n emptyLabel=\"No production logged yet — record output to build the trend.\"\n footer={\n productionSeries.length > 0\n ? `${formatNumber(totalProductionVolume, { maximumFractionDigits: 0 })} total volume across ${withPlus(productionRows, production.data?.pageInfo?.hasMore)} records`\n : undefined\n }\n >\n <AreaChart series={productionSeries} height={220} title=\"Monthly production volume\" />\n </ChartCard>\n\n <ChartCard\n title=\"Commodity mix\"\n caption=\"Share of assets across your commodity streams.\"\n icon={<Fuel className=\"h-4 w-4\" />}\n link={{ label: 'Assets', onClick: () => navigateTo('assets') }}\n isLoading={assets.isLoading}\n isError={assets.isError}\n onRetry={() => assets.refetch()}\n isEmpty={commodityMix.length === 0}\n emptyLabel=\"No assets registered yet.\"\n footer={\n commodityMix.length > 0\n ? `${withPlus(assetRows, assets.data?.pageInfo?.hasMore)} assets · ${commodityMix.length} ${commodityMix.length === 1 ? 'commodity' : 'commodities'}`\n : undefined\n }\n >\n <div className=\"flex items-center justify-center py-2\">\n <DonutChart\n segments={commodityMix}\n size={168}\n centerLabel={formatNumber(assetRows.length)}\n centerCaption=\"assets\"\n valueFormatter={(v) => formatNumber(v)}\n title=\"Assets by commodity\"\n />\n </div>\n </ChartCard>\n </div>\n\n {/* Commodity portfolio — one model, every commodity */}\n <Section\n title=\"Commodity portfolio\"\n description=\"One model, every commodity — assets, capacity and output across your book.\"\n >\n {assets.isLoading ? (\n <LoadingView label=\"Loading commodities…\" />\n ) : assets.isError ? (\n <ErrorView\n message=\"Couldn't load your commodity portfolio.\"\n onRetry={() => assets.refetch()}\n />\n ) : commodityCards.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Layers className=\"h-10 w-10\" />}\n title=\"No commodities yet\"\n description=\"Register your first resource asset to build out your commodity portfolio.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n {commodityCards.map((card) => (\n <CommodityCard key={card.key} card={card} onOpen={() => navigateTo('assets')} />\n ))}\n </div>\n )}\n </Section>\n\n {/* Lifecycle distribution + emissions by scope */}\n <div className=\"mt-6 grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <DistributionCard\n title=\"Assets by lifecycle\"\n description=\"Where the portfolio sits from exploration to retirement.\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n linkLabel=\"Assets\"\n onLink={() => navigateTo('assets')}\n isLoading={assets.isLoading}\n isError={assets.isError}\n onRetry={() => assets.refetch()}\n emptyLabel=\"No assets to profile yet.\"\n bars={lifecycleBars}\n footer={\n assetRows.length > 0\n ? `${producingCount} of ${withPlus(assetRows, assets.data?.pageInfo?.hasMore)} currently producing`\n : undefined\n }\n />\n\n <ChartCard\n title=\"Emissions by scope\"\n caption=\"GHG Protocol Scope 1 / 2 / 3 — tonnes CO₂e logged.\"\n icon={<Gauge className=\"h-4 w-4\" />}\n link={{ label: 'Emissions', onClick: () => navigateTo('emissions') }}\n isLoading={emissions.isLoading}\n isError={emissions.isError}\n onRetry={() => emissions.refetch()}\n isEmpty={scopeMix.length === 0}\n emptyLabel=\"No emission records logged yet.\"\n footer={\n emissionRows.length > 0\n ? `${formatTonnesCo2e(totalTonnes)} across ${withPlus(emissionRows, emissions.data?.pageInfo?.hasMore)} records`\n : undefined\n }\n >\n <div className=\"flex items-center justify-center py-2\">\n <DonutChart\n segments={scopeMix}\n size={168}\n centerLabel={formatNumber(totalTonnes, {\n notation: 'compact',\n maximumFractionDigits: 1,\n })}\n centerCaption=\"t CO₂e\"\n valueFormatter={(v) =>\n `${formatNumber(v, { maximumFractionDigits: v >= 100 ? 0 : 1 })} t`\n }\n title=\"Emissions by scope\"\n />\n </div>\n </ChartCard>\n </div>\n\n {/* Recent offtake contracts */}\n <Section\n title=\"Recent offtake contracts\"\n description=\"Latest buy/sell agreements across your commodity book.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('contracts')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n All contracts <ArrowRight className=\"h-4 w-4\" />\n </button>\n }\n >\n {contracts.isLoading ? (\n <LoadingView label=\"Loading contracts…\" />\n ) : contracts.isError ? (\n <ErrorView message=\"Couldn't load contracts.\" onRetry={() => contracts.refetch()} />\n ) : recentContracts.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<ScrollText className=\"h-10 w-10\" />}\n title=\"No contracts yet\"\n description=\"Draft your first offtake contract to start tracking commodity trade.\"\n />\n ) : (\n <DataTable\n columns={contractColumns}\n rows={recentContracts}\n rowKey={(c) => c.id}\n onRowClick={(c) => navigateTo(`contracts/${c.id}`)}\n rowLabel={(c) => `Open contract ${c.reference}`}\n />\n )}\n </Section>\n\n {/* Recent production */}\n <Section\n title=\"Recent production\"\n description=\"Latest metered output captured against your producing assets.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('production')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n All production <ArrowRight className=\"h-4 w-4\" />\n </button>\n }\n >\n {production.isLoading ? (\n <LoadingView label=\"Loading production…\" />\n ) : production.isError ? (\n <ErrorView message=\"Couldn't load production records.\" onRetry={() => production.refetch()} />\n ) : recentProduction.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<ClipboardList className=\"h-10 w-10\" />}\n title=\"No production logged yet\"\n description=\"Record production against an asset to build its output history.\"\n />\n ) : (\n <DataTable\n columns={productionColumns}\n rows={recentProduction}\n rowKey={(p) => p.id}\n onRowClick={(p) => navigateTo(`assets/${p.assetId}`)}\n rowLabel={(p) => `Open ${assetName.get(p.assetId) ?? 'asset'}`}\n />\n )}\n </Section>\n </PageLayout>\n );\n}\n"],"mappings":"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"}