@burdenoff/microfe-ecoimpacthub 2026.720.4 → 2026.720.6

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 (44) hide show
  1. package/dist/ecoimpacthub/EcoImpactHubAdminRoot.d.ts +10 -0
  2. package/dist/ecoimpacthub/EcoImpactHubAdminRoot.d.ts.map +1 -0
  3. package/dist/ecoimpacthub/EcoImpactHubAdminRoot.js +579 -0
  4. package/dist/ecoimpacthub/EcoImpactHubAdminRoot.js.map +1 -0
  5. package/dist/ecoimpacthub/components/DashboardCustomizerDialog.d.ts +11 -0
  6. package/dist/ecoimpacthub/components/DashboardCustomizerDialog.d.ts.map +1 -0
  7. package/dist/ecoimpacthub/components/DashboardCustomizerDialog.js +182 -0
  8. package/dist/ecoimpacthub/components/DashboardCustomizerDialog.js.map +1 -0
  9. package/dist/ecoimpacthub/hooks/index.d.ts +1 -0
  10. package/dist/ecoimpacthub/hooks/index.d.ts.map +1 -1
  11. package/dist/ecoimpacthub/hooks/index.js +1 -0
  12. package/dist/ecoimpacthub/hooks/useDashboardLayout.d.ts +29 -0
  13. package/dist/ecoimpacthub/hooks/useDashboardLayout.d.ts.map +1 -0
  14. package/dist/ecoimpacthub/hooks/useDashboardLayout.js +95 -0
  15. package/dist/ecoimpacthub/hooks/useDashboardLayout.js.map +1 -0
  16. package/dist/ecoimpacthub/index.d.ts +1 -0
  17. package/dist/ecoimpacthub/index.d.ts.map +1 -1
  18. package/dist/ecoimpacthub/index.js +1 -0
  19. package/dist/ecoimpacthub/pages/DashboardPage.d.ts +7 -0
  20. package/dist/ecoimpacthub/pages/DashboardPage.d.ts.map +1 -1
  21. package/dist/ecoimpacthub/pages/DashboardPage.js +505 -447
  22. package/dist/ecoimpacthub/pages/DashboardPage.js.map +1 -1
  23. package/dist/ecoimpacthub/pages/carbon/CarbonPage.js +1 -1
  24. package/dist/ecoimpacthub/pages/habitat/HabitatProjectsPage.js +4 -4
  25. package/dist/ecoimpacthub/pages/monitoring/MonitoringPage.js +1 -1
  26. package/dist/ecoimpacthub/pages/reports/ReportsPage.js +4 -4
  27. package/dist/index.js +3 -2
  28. package/dist/stories/DashboardCustomizerDialog.stories.d.ts +9 -0
  29. package/dist/stories/DashboardCustomizerDialog.stories.d.ts.map +1 -0
  30. package/dist/stories/DataTable.stories.d.ts +11 -0
  31. package/dist/stories/DataTable.stories.d.ts.map +1 -0
  32. package/dist/stories/FeatureFlagGate.stories.d.ts +19 -0
  33. package/dist/stories/FeatureFlagGate.stories.d.ts.map +1 -0
  34. package/dist/stories/FilterTabs.stories.d.ts +9 -0
  35. package/dist/stories/FilterTabs.stories.d.ts.map +1 -0
  36. package/dist/stories/PageLayout.stories.d.ts +10 -0
  37. package/dist/stories/PageLayout.stories.d.ts.map +1 -0
  38. package/dist/stories/Pagination.stories.d.ts +11 -0
  39. package/dist/stories/Pagination.stories.d.ts.map +1 -0
  40. package/dist/stories/StateViews.stories.d.ts +10 -0
  41. package/dist/stories/StateViews.stories.d.ts.map +1 -0
  42. package/dist/stories/Tabs.stories.d.ts +9 -0
  43. package/dist/stories/Tabs.stories.d.ts.map +1 -0
  44. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/ecoimpacthub/pages/DashboardPage.tsx"],"sourcesContent":["/**\n * Dashboard — EcoImpactHub environment, conservation & sustainability overview.\n * @module ecoimpacthub/pages\n *\n * KPIs are aggregated client-side from the real `eco*` list endpoints plus the\n * `ecoCarbonTotalKg` aggregate (by scope). Widgets show recent field\n * observations and open threshold breaches. No mock data.\n */\n\nimport { useMemo } from 'react';\nimport {\n MapPin,\n PawPrint,\n Trees,\n Factory,\n TriangleAlert,\n Binoculars,\n ShieldCheck,\n ArrowRight,\n Radio,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport {\n BarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n ResponsiveContainer,\n Tooltip,\n Cell,\n LabelList,\n} from 'recharts';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { StatusBadge } from '../components/StatusBadge';\nimport { MiniBar } from '../components/MiniBar';\nimport { LoadingView, Section } from '../components/StateViews';\nimport { EmptyState } from '../components/EmptyState';\nimport { ScopeSplitBar, ScopeLegend, Meter, SCOPE_HUE } from './carbonVisuals';\nimport { useEcoImpactHub } from '../context';\nimport {\n useEcoSites,\n useEcoSpecies,\n useEcoHabitatProjects,\n useEcoCarbonTotals,\n useEcoMeasurements,\n useEcoObservations,\n useEcoSensors,\n} from '../hooks';\nimport {\n formatNumber,\n formatRelativeTime,\n formatCo2e,\n formatEnumLabel,\n formatPercent,\n} from '../utils/formatters';\nimport type { EcoConservationStatus, EcoEmissionScope } from '../types';\n\nconst ACTIVE_PROJECT_STATUSES = new Set(['PLANNED', 'IN_PROGRESS', 'MONITORING']);\n\n/** Conservation-status → meter tint (semantic, IUCN-severity ordered). */\nconst CONSERVATION_TONE: Record<EcoConservationStatus, string> = {\n LEAST_CONCERN: 'var(--color-status-success-text)',\n NEAR_THREATENED: 'var(--color-accent-teal)',\n VULNERABLE: 'var(--color-status-warning-text)',\n ENDANGERED: 'var(--color-status-error-text)',\n CRITICALLY_ENDANGERED: 'var(--color-status-error-text)',\n EXTINCT_IN_WILD: 'var(--color-text-tertiary)',\n DATA_DEFICIENT: 'var(--color-text-tertiary)',\n NOT_EVALUATED: 'var(--color-text-tertiary)',\n};\n\nexport function DashboardPage() {\n const { navigateTo, currentUser } = useEcoImpactHub();\n\n const sites = useEcoSites({ pagination: { limit: 100, offset: 0 } });\n const species = useEcoSpecies({ pagination: { limit: 100, offset: 0 } });\n const projects = useEcoHabitatProjects();\n const carbon = useEcoCarbonTotals();\n const breaches = useEcoMeasurements({ breachesOnly: true, pagination: { limit: 6, offset: 0 } });\n const observations = useEcoObservations({ pagination: { limit: 6, offset: 0 } });\n const sensors = useEcoSensors();\n\n const siteRows = sites.data?.items ?? [];\n const speciesRows = species.data?.items ?? [];\n const projectRows = projects.data?.items ?? [];\n const sensorRows = sensors.data?.items ?? [];\n\n const activeSites = siteRows.filter((s) => s.status === 'ACTIVE').length;\n const priorityCount = speciesRows.filter((s) => s.isPriority).length;\n const threatened = speciesRows.filter((s) =>\n ['VULNERABLE', 'ENDANGERED', 'CRITICALLY_ENDANGERED'].includes(s.conservationStatus)\n ).length;\n const activeProjects = projectRows.filter((p) => ACTIVE_PROJECT_STATUSES.has(p.status)).length;\n const onlineSensors = sensorRows.filter((s) => s.status === 'ONLINE').length;\n const offlineSensors = sensorRows.filter((s) =>\n ['OFFLINE', 'DEGRADED', 'MAINTENANCE'].includes(s.status)\n ).length;\n\n const carbonData = useMemo<{ scope: EcoEmissionScope; label: string; kg: number }[]>(() => {\n const c = carbon.data;\n if (!c) return [];\n return [\n { scope: 'SCOPE_1', label: 'Scope 1', kg: c.scope1 },\n { scope: 'SCOPE_2', label: 'Scope 2', kg: c.scope2 },\n { scope: 'SCOPE_3', label: 'Scope 3', kg: c.scope3 },\n ];\n }, [carbon.data]);\n\n const isInitialLoading =\n sites.isLoading && species.isLoading && projects.isLoading && carbon.isLoading;\n\n if (isInitialLoading) {\n return (\n <PageLayout title=\"EcoImpactHub\" titleGradient aurora>\n <LoadingView label=\"Loading your impact overview…\" />\n </PageLayout>\n );\n }\n\n const greetingName = currentUser?.firstName || currentUser?.name || 'there';\n const breachRows = breaches.data?.items ?? [];\n const observationRows = observations.data?.items ?? [];\n\n return (\n <PageLayout\n title=\"EcoImpactHub\"\n titleGradient\n aurora\n description={`Welcome back, ${greetingName} — your environment, conservation & sustainability control room.`}\n >\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={<MapPin className=\"h-5 w-5\" />}\n value={\n sites.data?.pageInfo?.hasMore ? `${siteRows.length}+` : formatNumber(siteRows.length)\n }\n label=\"Monitored sites\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={siteRows.length ? (activeSites / siteRows.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\">{activeSites}</span> active\n </p>\n </div>\n }\n />\n <MetricsCard\n icon={<PawPrint className=\"h-5 w-5\" />}\n value={\n species.data?.pageInfo?.hasMore\n ? `${speciesRows.length}+`\n : formatNumber(speciesRows.length)\n }\n label=\"Species tracked\"\n accent={threatened > 0 ? 'warning' : undefined}\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={speciesRows.length ? (threatened / speciesRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-status-warning-text\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">{priorityCount}</span> priority ·{' '}\n <span className=\"tabular-nums text-text-secondary\">{threatened}</span> threatened\n </p>\n </div>\n }\n />\n <MetricsCard\n icon={<Trees className=\"h-5 w-5\" />}\n value={formatNumber(activeProjects)}\n label=\"Active habitat projects\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={projectRows.length ? (activeProjects / projectRows.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 {formatNumber(projectRows.length)}\n </span>{' '}\n total\n </p>\n </div>\n }\n />\n <MetricsCard\n icon={<Factory className=\"h-5 w-5\" />}\n value={carbon.data ? formatCo2e(carbon.data.total) : '—'}\n label=\"Total footprint\"\n featured\n footer={\n carbon.data && carbon.data.total > 0 ? (\n <div className=\"space-y-2\">\n <ScopeSplitBar\n scope1={carbon.data.scope1}\n scope2={carbon.data.scope2}\n scope3={carbon.data.scope3}\n height={6}\n />\n <p className=\"text-xs text-text-tertiary\">Scope 1 · 2 · 3 split</p>\n </div>\n ) : undefined\n }\n />\n <MetricsCard\n icon={<Radio className=\"h-5 w-5\" />}\n value={formatNumber(onlineSensors)}\n label=\"Sensors online\"\n accent={offlineSensors > 0 ? 'warning' : 'success'}\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={sensorRows.length ? (onlineSensors / sensorRows.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\">{offlineSensors}</span> need\n attention\n </p>\n </div>\n }\n />\n <MetricsCard\n icon={<TriangleAlert className=\"h-5 w-5\" />}\n value={\n breaches.data?.pageInfo?.hasMore\n ? `${breachRows.length}+`\n : formatNumber(breachRows.length)\n }\n label=\"Open breaches\"\n accent={breachRows.length > 0 ? 'error' : 'success'}\n footer={\n <p\n className={\n breachRows.length > 0\n ? 'text-xs font-medium text-status-error-text'\n : 'text-xs text-text-tertiary'\n }\n >\n {breachRows.length > 0 ? 'Needs attention' : 'All parameters in range'}\n </p>\n }\n />\n </div>\n\n <div className=\"mt-6 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Carbon by scope */}\n <GlassCard treatment=\"glass\" className=\"p-6 lg:col-span-2\">\n <div className=\"mb-4 flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-base font-semibold text-text-primary\">\n Carbon footprint by scope\n </h2>\n <p className=\"mt-0.5 text-sm text-text-secondary\">\n GHG Protocol Scope 1 / 2 / 3 emissions (CO₂e).\n </p>\n </div>\n <div className=\"flex items-center gap-4\">\n {carbon.data && carbon.data.total > 0 && (\n <div className=\"text-right\">\n <p className=\"text-lg font-semibold tabular-nums text-text-primary\">\n {formatCo2e(carbon.data.total)}\n </p>\n <p className=\"text-xs text-text-tertiary\">total</p>\n </div>\n )}\n <button\n type=\"button\"\n onClick={() => navigateTo('carbon')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n Ledger <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n {carbonData.every((d) => d.kg === 0) ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Factory className=\"h-10 w-10\" />}\n title=\"No carbon entries yet\"\n description=\"Record activity in the carbon ledger to see your Scope 1–3 footprint here.\"\n />\n ) : (\n <>\n <div className=\"h-56\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={carbonData} margin={{ top: 20, right: 8, left: 8, bottom: 0 }}>\n <defs>\n {carbonData.map((d) => (\n <linearGradient\n key={d.scope}\n id={`ecoScopeGrad-${d.scope}`}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop\n offset=\"0%\"\n style={{ stopColor: SCOPE_HUE[d.scope], stopOpacity: 1 }}\n />\n <stop\n offset=\"100%\"\n style={{ stopColor: SCOPE_HUE[d.scope], stopOpacity: 0.55 }}\n />\n </linearGradient>\n ))}\n </defs>\n <CartesianGrid\n vertical={false}\n stroke=\"var(--color-border-seam)\"\n strokeOpacity={0.6}\n strokeDasharray=\"3 4\"\n />\n <XAxis\n dataKey=\"label\"\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n axisLine={{ stroke: 'var(--color-border-seam)' }}\n tickLine={false}\n dy={4}\n />\n <YAxis\n tick={{ fill: 'var(--color-text-tertiary)', fontSize: 11 }}\n axisLine={false}\n tickLine={false}\n width={48}\n tickFormatter={(v: number) =>\n v >= 1000 ? `${Math.round(v / 1000)}t` : `${v}`\n }\n />\n <Tooltip\n cursor={{ fill: 'var(--color-bg-sunken)', opacity: 0.4 }}\n contentStyle={{\n background: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-seam)',\n borderRadius: 12,\n color: 'var(--color-text-primary)',\n }}\n formatter={(value: number) => [formatCo2e(value), 'Emissions']}\n />\n <Bar dataKey=\"kg\" radius={[8, 8, 2, 2]} maxBarSize={72}>\n {carbonData.map((d) => (\n <Cell key={d.scope} fill={`url(#ecoScopeGrad-${d.scope})`} />\n ))}\n <LabelList\n dataKey=\"kg\"\n position=\"top\"\n formatter={(v: number) => (v > 0 ? formatCo2e(v) : '')}\n style={{\n fill: 'var(--color-text-secondary)',\n fontSize: 11,\n fontWeight: 600,\n }}\n />\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </div>\n <ScopeLegend data={carbonData} className=\"mt-4 border-t border-border-seam pt-4\" />\n </>\n )}\n </GlassCard>\n\n {/* Recent breaches */}\n <GlassCard treatment=\"glass\" className=\"p-6\">\n <div className=\"mb-4 flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"text-base font-semibold text-text-primary\">Recent breaches</h2>\n {breachRows.length > 0 && (\n <span className=\"rounded-full bg-status-error-bg-subtle px-2 py-0.5 text-xs font-medium tabular-nums text-status-error-text\">\n {breaches.data?.pageInfo?.hasMore ? `${breachRows.length}+` : breachRows.length}\n </span>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo('monitoring')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n Monitoring <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n {breachRows.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed border-border-seam py-10 text-center\">\n <span className=\"flex size-12 items-center justify-center rounded-full bg-status-success-bg-subtle\">\n <ShieldCheck className=\"h-6 w-6 text-status-success-text\" />\n </span>\n <p className=\"mt-3 text-sm font-medium text-text-primary\">All parameters in range</p>\n <p className=\"mt-1 text-xs text-text-tertiary\">No open threshold breaches.</p>\n </div>\n ) : (\n <ul className=\"space-y-2.5\">\n {breachRows.map((m) => (\n <li\n key={m.id}\n className=\"flex items-start justify-between gap-3 rounded-xl bg-bg-sunken/50 p-3\"\n >\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span\n aria-hidden=\"true\"\n className=\"mt-1.5 size-2 shrink-0 rounded-full bg-status-error-text motion-safe:animate-vc-glow-pulse\"\n />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {m.parameter}\n </p>\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums\">\n {formatNumber(m.value)} {m.unit}\n </span>{' '}\n · {formatRelativeTime(m.recordedAt)}\n </p>\n </div>\n </div>\n <StatusBadge status=\"BREACH\" />\n </li>\n ))}\n </ul>\n )}\n </GlassCard>\n </div>\n\n {/* Recent observations */}\n <Section\n title=\"Recent field observations\"\n description=\"Latest wildlife & biodiversity sightings recorded across your sites.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('observations')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n All observations <ArrowRight className=\"h-4 w-4\" />\n </button>\n }\n >\n {observationRows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Binoculars className=\"h-10 w-10\" />}\n title=\"No observations yet\"\n description=\"Record your first field observation to build your biodiversity dataset.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {observationRows.map((o) => (\n <GlassCard\n key={o.id}\n treatment=\"plain\"\n className=\"p-4 transition-shadow hover:shadow-float\"\n >\n <div className=\"flex items-start justify-between gap-2\">\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 <Binoculars className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold text-text-primary\">\n {o.species?.commonName ?? 'Unknown species'}\n </p>\n {o.species?.scientificName && (\n <p className=\"truncate text-xs italic text-text-tertiary\">\n {o.species.scientificName}\n </p>\n )}\n </div>\n </div>\n <span className=\"shrink-0 rounded-full bg-[var(--color-accent-soft)] px-2 py-0.5 text-xs font-medium tabular-nums text-text-primary\">\n ×{formatNumber(o.count)}\n </span>\n </div>\n <div className=\"mt-3 flex items-center justify-between border-t border-border-seam/70 pt-2.5\">\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\">\n {formatEnumLabel(o.method)}\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {formatRelativeTime(o.observedAt)}\n </span>\n </div>\n </GlassCard>\n ))}\n </div>\n )}\n </Section>\n\n {/* Conservation status snapshot */}\n {speciesRows.length > 0 && (\n <Section\n title=\"Conservation status\"\n description=\"Distribution of tracked species by IUCN-style status.\"\n >\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"space-y-3.5\">\n {(() => {\n const counts = new Map<string, number>();\n for (const s of speciesRows) {\n counts.set(s.conservationStatus, (counts.get(s.conservationStatus) ?? 0) + 1);\n }\n const total = speciesRows.length;\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([status, count]) => {\n const pct = (count / total) * 100;\n const tone =\n CONSERVATION_TONE[status as EcoConservationStatus] ??\n 'var(--color-text-tertiary)';\n return (\n <div key={status} className=\"flex items-center gap-3 sm:gap-4\">\n <div className=\"w-36 shrink-0 sm:w-48\">\n <StatusBadge status={status} />\n </div>\n <Meter value={pct} color={tone} className=\"flex-1\" />\n <span className=\"w-9 shrink-0 text-right text-sm font-medium tabular-nums text-text-primary\">\n {count}\n </span>\n <span className=\"hidden w-12 shrink-0 text-right text-xs tabular-nums text-text-tertiary sm:inline\">\n {formatPercent(pct)}\n </span>\n </div>\n );\n });\n })()}\n </div>\n </GlassCard>\n </Section>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/ecoimpacthub/pages/DashboardPage.tsx"],"sourcesContent":["/**\n * Dashboard — EcoImpactHub environment, conservation & sustainability overview.\n * @module ecoimpacthub/pages\n *\n * KPIs are aggregated client-side from the real `eco*` list endpoints plus the\n * `ecoCarbonTotalKg` aggregate (by scope). Widgets show recent field\n * observations and open threshold breaches. No mock data.\n *\n * Customizable (BOFF-3943): the \"Customize dashboard\" CTA opens a widget\n * palette (show/hide/reorder + freeform notes), persisted per user/workspace\n * via {@link useDashboardLayout}. Uncustomized users see the exact same\n * layout as before this change — the widget order defaults to this file's\n * original hardcoded order, and the carbon-by-scope / recent-breaches pair\n * keeps its original side-by-side layout whenever they remain adjacent.\n */\n\nimport { useMemo, useState, type ReactNode } from 'react';\nimport {\n MapPin,\n PawPrint,\n Trees,\n Factory,\n TriangleAlert,\n Binoculars,\n ShieldCheck,\n ArrowRight,\n Radio,\n LayoutGrid,\n StickyNote,\n} from 'lucide-react';\nimport { Button, GlassCard } from '@burdenoff/fe-libs/ui';\nimport {\n BarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n ResponsiveContainer,\n Tooltip,\n Cell,\n LabelList,\n} from 'recharts';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { StatusBadge } from '../components/StatusBadge';\nimport { MiniBar } from '../components/MiniBar';\nimport { LoadingView, Section } from '../components/StateViews';\nimport { EmptyState } from '../components/EmptyState';\nimport { DashboardCustomizerDialog } from '../components/DashboardCustomizerDialog';\nimport { ScopeSplitBar, ScopeLegend, Meter, SCOPE_HUE } from './carbonVisuals';\nimport { useEcoImpactHub } from '../context';\nimport {\n useEcoSites,\n useEcoSpecies,\n useEcoHabitatProjects,\n useEcoCarbonTotals,\n useEcoMeasurements,\n useEcoObservations,\n useEcoSensors,\n useDashboardLayout,\n type DashboardWidgetId,\n} from '../hooks';\nimport {\n formatNumber,\n formatRelativeTime,\n formatCo2e,\n formatEnumLabel,\n formatPercent,\n} from '../utils/formatters';\nimport type { EcoConservationStatus, EcoEmissionScope } from '../types';\n\nconst ACTIVE_PROJECT_STATUSES = new Set(['PLANNED', 'IN_PROGRESS', 'MONITORING']);\n\n/** Conservation-status → meter tint (semantic, IUCN-severity ordered). */\nconst CONSERVATION_TONE: Record<EcoConservationStatus, string> = {\n LEAST_CONCERN: 'var(--color-status-success-text)',\n NEAR_THREATENED: 'var(--color-accent-teal)',\n VULNERABLE: 'var(--color-status-warning-text)',\n ENDANGERED: 'var(--color-status-error-text)',\n CRITICALLY_ENDANGERED: 'var(--color-status-error-text)',\n EXTINCT_IN_WILD: 'var(--color-text-tertiary)',\n DATA_DEFICIENT: 'var(--color-text-tertiary)',\n NOT_EVALUATED: 'var(--color-text-tertiary)',\n};\n\nexport function DashboardPage() {\n const { navigateTo, currentUser, workspaceId } = useEcoImpactHub();\n const [customizerOpen, setCustomizerOpen] = useState(false);\n const dashboardLayout = useDashboardLayout(workspaceId, currentUser?.id);\n\n const sites = useEcoSites({ pagination: { limit: 100, offset: 0 } });\n const species = useEcoSpecies({ pagination: { limit: 100, offset: 0 } });\n const projects = useEcoHabitatProjects();\n const carbon = useEcoCarbonTotals();\n const breaches = useEcoMeasurements({ breachesOnly: true, pagination: { limit: 6, offset: 0 } });\n const observations = useEcoObservations({ pagination: { limit: 6, offset: 0 } });\n const sensors = useEcoSensors();\n\n const siteRows = sites.data?.items ?? [];\n const speciesRows = species.data?.items ?? [];\n const projectRows = projects.data?.items ?? [];\n const sensorRows = sensors.data?.items ?? [];\n\n const activeSites = siteRows.filter((s) => s.status === 'ACTIVE').length;\n const priorityCount = speciesRows.filter((s) => s.isPriority).length;\n const threatened = speciesRows.filter((s) =>\n ['VULNERABLE', 'ENDANGERED', 'CRITICALLY_ENDANGERED'].includes(s.conservationStatus)\n ).length;\n const activeProjects = projectRows.filter((p) => ACTIVE_PROJECT_STATUSES.has(p.status)).length;\n const onlineSensors = sensorRows.filter((s) => s.status === 'ONLINE').length;\n const offlineSensors = sensorRows.filter((s) =>\n ['OFFLINE', 'DEGRADED', 'MAINTENANCE'].includes(s.status)\n ).length;\n\n const carbonData = useMemo<{ scope: EcoEmissionScope; label: string; kg: number }[]>(() => {\n const c = carbon.data;\n if (!c) return [];\n return [\n { scope: 'SCOPE_1', label: 'Scope 1', kg: c.scope1 },\n { scope: 'SCOPE_2', label: 'Scope 2', kg: c.scope2 },\n { scope: 'SCOPE_3', label: 'Scope 3', kg: c.scope3 },\n ];\n }, [carbon.data]);\n\n const isInitialLoading =\n sites.isLoading && species.isLoading && projects.isLoading && carbon.isLoading;\n\n const headerActions = (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setCustomizerOpen(true)}>\n <LayoutGrid className=\"mr-1.5 h-3.5 w-3.5\" />\n Customize dashboard\n </Button>\n );\n\n if (isInitialLoading) {\n return (\n <PageLayout title=\"EcoImpactHub\" titleGradient aurora actions={headerActions}>\n <LoadingView label=\"Loading your impact overview…\" />\n </PageLayout>\n );\n }\n\n const greetingName = currentUser?.firstName || currentUser?.name || 'there';\n const breachRows = breaches.data?.items ?? [];\n const observationRows = observations.data?.items ?? [];\n\n const kpisWidget = (\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={<MapPin className=\"h-5 w-5\" />}\n value={\n sites.data?.pageInfo?.hasMore ? `${siteRows.length}+` : formatNumber(siteRows.length)\n }\n label=\"Monitored sites\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={siteRows.length ? (activeSites / siteRows.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\">{activeSites}</span> active\n </p>\n </div>\n }\n />\n <MetricsCard\n icon={<PawPrint className=\"h-5 w-5\" />}\n value={\n species.data?.pageInfo?.hasMore\n ? `${speciesRows.length}+`\n : formatNumber(speciesRows.length)\n }\n label=\"Species tracked\"\n accent={threatened > 0 ? 'warning' : undefined}\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={speciesRows.length ? (threatened / speciesRows.length) * 100 : 0}\n height={4}\n barClassName=\"bg-status-warning-text\"\n />\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums text-text-secondary\">{priorityCount}</span> priority ·{' '}\n <span className=\"tabular-nums text-text-secondary\">{threatened}</span> threatened\n </p>\n </div>\n }\n />\n <MetricsCard\n icon={<Trees className=\"h-5 w-5\" />}\n value={formatNumber(activeProjects)}\n label=\"Active habitat projects\"\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={projectRows.length ? (activeProjects / projectRows.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 {formatNumber(projectRows.length)}\n </span>{' '}\n total\n </p>\n </div>\n }\n />\n <MetricsCard\n icon={<Factory className=\"h-5 w-5\" />}\n value={carbon.data ? formatCo2e(carbon.data.total) : '—'}\n label=\"Total footprint\"\n featured\n footer={\n carbon.data && carbon.data.total > 0 ? (\n <div className=\"space-y-2\">\n <ScopeSplitBar\n scope1={carbon.data.scope1}\n scope2={carbon.data.scope2}\n scope3={carbon.data.scope3}\n height={6}\n />\n <p className=\"text-xs text-text-tertiary\">Scope 1 · 2 · 3 split</p>\n </div>\n ) : undefined\n }\n />\n <MetricsCard\n icon={<Radio className=\"h-5 w-5\" />}\n value={formatNumber(onlineSensors)}\n label=\"Sensors online\"\n accent={offlineSensors > 0 ? 'warning' : 'success'}\n footer={\n <div className=\"space-y-2\">\n <MiniBar\n value={sensorRows.length ? (onlineSensors / sensorRows.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\">{offlineSensors}</span> need\n attention\n </p>\n </div>\n }\n />\n <MetricsCard\n icon={<TriangleAlert className=\"h-5 w-5\" />}\n value={\n breaches.data?.pageInfo?.hasMore\n ? `${breachRows.length}+`\n : formatNumber(breachRows.length)\n }\n label=\"Open breaches\"\n accent={breachRows.length > 0 ? 'error' : 'success'}\n footer={\n <p\n className={\n breachRows.length > 0\n ? 'text-xs font-medium text-status-error-text'\n : 'text-xs text-text-tertiary'\n }\n >\n {breachRows.length > 0 ? 'Needs attention' : 'All parameters in range'}\n </p>\n }\n />\n </div>\n );\n\n const carbonByScopeWidget = (\n <GlassCard treatment=\"glass\" className=\"p-6 h-full\">\n <div className=\"mb-4 flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-base font-semibold text-text-primary\">Carbon footprint by scope</h2>\n <p className=\"mt-0.5 text-sm text-text-secondary\">\n GHG Protocol Scope 1 / 2 / 3 emissions (CO₂e).\n </p>\n </div>\n <div className=\"flex items-center gap-4\">\n {carbon.data && carbon.data.total > 0 && (\n <div className=\"text-right\">\n <p className=\"text-lg font-semibold tabular-nums text-text-primary\">\n {formatCo2e(carbon.data.total)}\n </p>\n <p className=\"text-xs text-text-tertiary\">total</p>\n </div>\n )}\n <button\n type=\"button\"\n onClick={() => navigateTo('carbon')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n Ledger <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n {carbonData.every((d) => d.kg === 0) ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Factory className=\"h-10 w-10\" />}\n title=\"No carbon entries yet\"\n description=\"Record activity in the carbon ledger to see your Scope 1–3 footprint here.\"\n />\n ) : (\n <>\n <div className=\"h-56\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={carbonData} margin={{ top: 20, right: 8, left: 8, bottom: 0 }}>\n <defs>\n {carbonData.map((d) => (\n <linearGradient\n key={d.scope}\n id={`ecoScopeGrad-${d.scope}`}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop offset=\"0%\" style={{ stopColor: SCOPE_HUE[d.scope], stopOpacity: 1 }} />\n <stop\n offset=\"100%\"\n style={{ stopColor: SCOPE_HUE[d.scope], stopOpacity: 0.55 }}\n />\n </linearGradient>\n ))}\n </defs>\n <CartesianGrid\n vertical={false}\n stroke=\"var(--color-border-seam)\"\n strokeOpacity={0.6}\n strokeDasharray=\"3 4\"\n />\n <XAxis\n dataKey=\"label\"\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n axisLine={{ stroke: 'var(--color-border-seam)' }}\n tickLine={false}\n dy={4}\n />\n <YAxis\n tick={{ fill: 'var(--color-text-tertiary)', fontSize: 11 }}\n axisLine={false}\n tickLine={false}\n width={48}\n tickFormatter={(v: number) => (v >= 1000 ? `${Math.round(v / 1000)}t` : `${v}`)}\n />\n <Tooltip\n cursor={{ fill: 'var(--color-bg-sunken)', opacity: 0.4 }}\n contentStyle={{\n background: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-seam)',\n borderRadius: 12,\n color: 'var(--color-text-primary)',\n }}\n formatter={(value: number) => [formatCo2e(value), 'Emissions']}\n />\n <Bar dataKey=\"kg\" radius={[8, 8, 2, 2]} maxBarSize={72}>\n {carbonData.map((d) => (\n <Cell key={d.scope} fill={`url(#ecoScopeGrad-${d.scope})`} />\n ))}\n <LabelList\n dataKey=\"kg\"\n position=\"top\"\n formatter={(v: number) => (v > 0 ? formatCo2e(v) : '')}\n style={{ fill: 'var(--color-text-secondary)', fontSize: 11, fontWeight: 600 }}\n />\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </div>\n <ScopeLegend data={carbonData} className=\"mt-4 border-t border-border-seam pt-4\" />\n </>\n )}\n </GlassCard>\n );\n\n const recentBreachesWidget = (\n <GlassCard treatment=\"glass\" className=\"p-6 h-full\">\n <div className=\"mb-4 flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"text-base font-semibold text-text-primary\">Recent breaches</h2>\n {breachRows.length > 0 && (\n <span className=\"rounded-full bg-status-error-bg-subtle px-2 py-0.5 text-xs font-medium tabular-nums text-status-error-text\">\n {breaches.data?.pageInfo?.hasMore ? `${breachRows.length}+` : breachRows.length}\n </span>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo('monitoring')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n Monitoring <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n {breachRows.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed border-border-seam py-10 text-center\">\n <span className=\"flex size-12 items-center justify-center rounded-full bg-status-success-bg-subtle\">\n <ShieldCheck className=\"h-6 w-6 text-status-success-text\" />\n </span>\n <p className=\"mt-3 text-sm font-medium text-text-primary\">All parameters in range</p>\n <p className=\"mt-1 text-xs text-text-tertiary\">No open threshold breaches.</p>\n </div>\n ) : (\n <ul className=\"space-y-2.5\">\n {breachRows.map((m) => (\n <li\n key={m.id}\n className=\"flex items-start justify-between gap-3 rounded-xl bg-bg-sunken/50 p-3\"\n >\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span\n aria-hidden=\"true\"\n className=\"mt-1.5 size-2 shrink-0 rounded-full bg-status-error-text motion-safe:animate-vc-glow-pulse\"\n />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{m.parameter}</p>\n <p className=\"text-xs text-text-tertiary\">\n <span className=\"tabular-nums\">\n {formatNumber(m.value)} {m.unit}\n </span>{' '}\n · {formatRelativeTime(m.recordedAt)}\n </p>\n </div>\n </div>\n <StatusBadge status=\"BREACH\" />\n </li>\n ))}\n </ul>\n )}\n </GlassCard>\n );\n\n const recentObservationsWidget = (\n <Section\n title=\"Recent field observations\"\n description=\"Latest wildlife & biodiversity sightings recorded across your sites.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('observations')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-accent hover:underline\"\n >\n All observations <ArrowRight className=\"h-4 w-4\" />\n </button>\n }\n >\n {observationRows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Binoculars className=\"h-10 w-10\" />}\n title=\"No observations yet\"\n description=\"Record your first field observation to build your biodiversity dataset.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {observationRows.map((o) => (\n <GlassCard\n key={o.id}\n treatment=\"plain\"\n className=\"p-4 transition-shadow hover:shadow-float\"\n >\n <div className=\"flex items-start justify-between gap-2\">\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 <Binoculars className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold text-text-primary\">\n {o.species?.commonName ?? 'Unknown species'}\n </p>\n {o.species?.scientificName && (\n <p className=\"truncate text-xs italic text-text-tertiary\">\n {o.species.scientificName}\n </p>\n )}\n </div>\n </div>\n <span className=\"shrink-0 rounded-full bg-[var(--color-accent-soft)] px-2 py-0.5 text-xs font-medium tabular-nums text-text-primary\">\n ×{formatNumber(o.count)}\n </span>\n </div>\n <div className=\"mt-3 flex items-center justify-between border-t border-border-seam/70 pt-2.5\">\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\">\n {formatEnumLabel(o.method)}\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {formatRelativeTime(o.observedAt)}\n </span>\n </div>\n </GlassCard>\n ))}\n </div>\n )}\n </Section>\n );\n\n const conservationStatusWidget =\n speciesRows.length > 0 ? (\n <Section\n title=\"Conservation status\"\n description=\"Distribution of tracked species by IUCN-style status.\"\n >\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"space-y-3.5\">\n {(() => {\n const counts = new Map<string, number>();\n for (const s of speciesRows) {\n counts.set(s.conservationStatus, (counts.get(s.conservationStatus) ?? 0) + 1);\n }\n const total = speciesRows.length;\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([status, count]) => {\n const pct = (count / total) * 100;\n const tone =\n CONSERVATION_TONE[status as EcoConservationStatus] ??\n 'var(--color-text-tertiary)';\n return (\n <div key={status} className=\"flex items-center gap-3 sm:gap-4\">\n <div className=\"w-36 shrink-0 sm:w-48\">\n <StatusBadge status={status} />\n </div>\n <Meter value={pct} color={tone} className=\"flex-1\" />\n <span className=\"w-9 shrink-0 text-right text-sm font-medium tabular-nums text-text-primary\">\n {count}\n </span>\n <span className=\"hidden w-12 shrink-0 text-right text-xs tabular-nums text-text-tertiary sm:inline\">\n {formatPercent(pct)}\n </span>\n </div>\n );\n });\n })()}\n </div>\n </GlassCard>\n </Section>\n ) : null;\n\n const WIDGET_RENDER: Record<DashboardWidgetId, ReactNode> = {\n kpis: kpisWidget,\n carbonByScope: carbonByScopeWidget,\n recentBreaches: recentBreachesWidget,\n recentObservations: recentObservationsWidget,\n conservationStatus: conservationStatusWidget,\n };\n\n const order = dashboardLayout.layout.widgetOrder;\n const blocks: ReactNode[] = [];\n for (let i = 0; i < order.length; i++) {\n const id = order[i];\n if (id === 'kpis') {\n blocks.push(<div key={id}>{WIDGET_RENDER[id]}</div>);\n continue;\n }\n // Preserve the original side-by-side carbon-by-scope / recent-breaches pairing\n // whenever they remain adjacent in that order (the default, uncustomized case).\n if (id === 'carbonByScope' && order[i + 1] === 'recentBreaches') {\n blocks.push(\n <div key={`${id}-pair`} className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2\">{carbonByScopeWidget}</div>\n <div>{recentBreachesWidget}</div>\n </div>\n );\n i += 1;\n continue;\n }\n if (id === 'recentBreaches' && order[i - 1] === 'carbonByScope') {\n // Already rendered as part of the pair above.\n continue;\n }\n const content = WIDGET_RENDER[id];\n if (!content) continue;\n blocks.push(<div key={id}>{content}</div>);\n }\n\n return (\n <PageLayout\n title=\"EcoImpactHub\"\n titleGradient\n aurora\n description={`Welcome back, ${greetingName} — your environment, conservation & sustainability control room.`}\n actions={headerActions}\n >\n <div className=\"space-y-6\">\n {blocks}\n\n {dashboardLayout.layout.notes.length > 0 && (\n <Section title=\"Custom notes\" description=\"Your personal notes, visible only to you.\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {dashboardLayout.layout.notes.map((note) => (\n <GlassCard key={note.id} treatment=\"plain\" className=\"p-4\">\n <div className=\"flex items-start gap-2.5\">\n <StickyNote className=\"mt-0.5 h-4 w-4 shrink-0 text-accent\" />\n <div className=\"min-w-0\">\n {note.title && (\n <p className=\"truncate text-sm font-semibold text-text-primary\">\n {note.title}\n </p>\n )}\n {note.body && (\n <p className=\"mt-0.5 text-sm text-text-secondary\">{note.body}</p>\n )}\n </div>\n </div>\n </GlassCard>\n ))}\n </div>\n </Section>\n )}\n </div>\n\n <DashboardCustomizerDialog\n open={customizerOpen}\n onOpenChange={setCustomizerOpen}\n layout={dashboardLayout}\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -8,8 +8,8 @@ import { Meter as te, SCOPE_HUE as ne, ScopeSplitBar as re } from "../carbonVisu
8
8
  import { useEcoCarbonEntries as ie, useEcoCarbonTotals as ae, useEcoCreateEmissionFactor as oe, useEcoCreateReductionTarget as se, useEcoEmissionFactors as ce, useEcoRecordCarbonEntry as le, useEcoReductionTargets as ue, useEcoSetReductionTargetStatus as de, useEcoSites as fe, useEcoVerifyCarbonEntry as pe } from "../../hooks/useEcoImpactHubApi.js";
9
9
  import { useCursorPager as me } from "../../hooks/useCursorPager.js";
10
10
  import "../../hooks/index.js";
11
- import { DataTable as u } from "../../components/DataTable.js";
12
11
  import { Tabs as he } from "../../components/Tabs.js";
12
+ import { DataTable as u } from "../../components/DataTable.js";
13
13
  import { Pagination as ge } from "../../components/Pagination.js";
14
14
  import { useMemo as _e, useState as d } from "react";
15
15
  import { Factory as f, Flame as ve, Leaf as ye, Plus as p, Target as be, Truck as xe, Zap as Se } from "lucide-react";
@@ -7,8 +7,8 @@ import "../../context/index.js";
7
7
  import { useEcoCreateHabitatProject as c, useEcoHabitatProjects as l, useEcoSites as u } from "../../hooks/useEcoImpactHubApi.js";
8
8
  import "../../hooks/index.js";
9
9
  import { DataTable as d } from "../../components/DataTable.js";
10
- import { LifecycleBadge as f } from "../badges.js";
11
- import { FilterTabs as p } from "../../components/FilterTabs.js";
10
+ import { FilterTabs as f } from "../../components/FilterTabs.js";
11
+ import { LifecycleBadge as p } from "../badges.js";
12
12
  import { useMemo as m, useState as h } from "react";
13
13
  import { Plus as g, Trees as _ } from "lucide-react";
14
14
  import { jsx as v, jsxs as y } from "react/jsx-runtime";
@@ -72,7 +72,7 @@ function L() {
72
72
  {
73
73
  key: "status",
74
74
  header: "Status",
75
- render: (e) => /* @__PURE__ */ v(f, { status: e.status })
75
+ render: (e) => /* @__PURE__ */ v(p, { status: e.status })
76
76
  },
77
77
  {
78
78
  key: "target",
@@ -142,7 +142,7 @@ function L() {
142
142
  children: [
143
143
  /* @__PURE__ */ v("div", {
144
144
  className: "mb-5 flex flex-wrap items-center gap-3",
145
- children: /* @__PURE__ */ v(p, {
145
+ children: /* @__PURE__ */ v(f, {
146
146
  options: N,
147
147
  value: R,
148
148
  onChange: z
@@ -6,8 +6,8 @@ import { EmptyState as te } from "../../components/EmptyState.js";
6
6
  import { useEcoCreateSensor as ne, useEcoCreateThreshold as re, useEcoMeasurements as ie, useEcoRecordMeasurement as ae, useEcoSensors as oe, useEcoSetSensorStatus as se, useEcoSetThresholdActive as ce, useEcoSites as le, useEcoThresholds as ue } from "../../hooks/useEcoImpactHubApi.js";
7
7
  import { useCursorPager as de } from "../../hooks/useCursorPager.js";
8
8
  import "../../hooks/index.js";
9
- import { DataTable as o } from "../../components/DataTable.js";
10
9
  import { Tabs as fe } from "../../components/Tabs.js";
10
+ import { DataTable as o } from "../../components/DataTable.js";
11
11
  import { Pagination as pe } from "../../components/Pagination.js";
12
12
  import { FilterTabs as me } from "../../components/FilterTabs.js";
13
13
  import { useMemo as he, useState as s } from "react";
@@ -10,8 +10,8 @@ import { useCursorPager as ne } from "../../hooks/useCursorPager.js";
10
10
  import "../../hooks/index.js";
11
11
  import { DataTable as l } from "../../components/DataTable.js";
12
12
  import { Pagination as re } from "../../components/Pagination.js";
13
- import { FrameworkBadge as u } from "../badges.js";
14
- import { FilterTabs as d } from "../../components/FilterTabs.js";
13
+ import { FilterTabs as u } from "../../components/FilterTabs.js";
14
+ import { FrameworkBadge as d } from "../badges.js";
15
15
  import { useMemo as f, useState as p } from "react";
16
16
  import { FileText as m, Plus as h } from "lucide-react";
17
17
  import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
@@ -72,7 +72,7 @@ function R() {
72
72
  key: "framework",
73
73
  header: "Framework",
74
74
  hideOnMobile: !0,
75
- render: (e) => /* @__PURE__ */ _(u, { framework: e.framework })
75
+ render: (e) => /* @__PURE__ */ _(d, { framework: e.framework })
76
76
  },
77
77
  {
78
78
  key: "status",
@@ -127,7 +127,7 @@ function R() {
127
127
  children: [
128
128
  /* @__PURE__ */ _("div", {
129
129
  className: "mb-5 flex flex-wrap items-center gap-3",
130
- children: /* @__PURE__ */ _(d, {
130
+ children: /* @__PURE__ */ _(u, {
131
131
  options: P,
132
132
  value: z,
133
133
  onChange: (e) => {
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ import { EcoImpactHubProvider as t, useEcoImpactHub as n } from "./ecoimpacthub/
3
3
  import { cn as r } from "./ecoimpacthub/utils/cn.js";
4
4
  import { formatCo2e as i, formatCoords as a, formatDate as o, formatDateTime as s, formatEnumLabel as c, formatNumber as l, formatPercent as u, formatQuantity as d, formatRelativeTime as f } from "./ecoimpacthub/utils/formatters.js";
5
5
  import { EcoImpactHubRoot as p } from "./ecoimpacthub/EcoImpactHubRoot.js";
6
- import { useSandboxAssistantTransport as m } from "./ecoimpacthub/services/createSandboxAssistantTransport.js";
6
+ import { EcoImpactHubAdminRoot as m } from "./ecoimpacthub/EcoImpactHubAdminRoot.js";
7
+ import { useSandboxAssistantTransport as h } from "./ecoimpacthub/services/createSandboxAssistantTransport.js";
7
8
  import "./ecoimpacthub/index.js";
8
- export { t as EcoImpactHubProvider, p as EcoImpactHubRoot, r as cn, i as formatCo2e, a as formatCoords, o as formatDate, s as formatDateTime, c as formatEnumLabel, l as formatNumber, u as formatPercent, d as formatQuantity, f as formatRelativeTime, e as joinPath, n as useEcoImpactHub, m as useSandboxAssistantTransport };
9
+ export { m as AdminRoot, m as EcoImpactHubAdminRoot, t as EcoImpactHubProvider, p as EcoImpactHubRoot, r as cn, i as formatCo2e, a as formatCoords, o as formatDate, s as formatDateTime, c as formatEnumLabel, l as formatNumber, u as formatPercent, d as formatQuantity, f as formatRelativeTime, e as joinPath, n as useEcoImpactHub, h as useSandboxAssistantTransport };
@@ -0,0 +1,9 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { DashboardCustomizerDialog } from '../ecoimpacthub/components/DashboardCustomizerDialog';
3
+
4
+ declare const meta: Meta<typeof DashboardCustomizerDialog>;
5
+ export default meta;
6
+ type Story = StoryObj<typeof meta>;
7
+ export declare const AllWidgetsVisible: Story;
8
+ export declare const SomeHiddenWithNote: Story;
9
+ //# sourceMappingURL=DashboardCustomizerDialog.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardCustomizerDialog.stories.d.ts","sourceRoot":"","sources":["../../src/stories/DashboardCustomizerDialog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,sDAAsD,CAAC;AAwDjG,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,yBAAyB,CAKhD,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,iBAAiB,EAAE,KAI/B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAShC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { DataTable } from '../ecoimpacthub/components/DataTable';
3
+
4
+ declare const meta: Meta<typeof DataTable>;
5
+ export default meta;
6
+ type Story = StoryObj<typeof meta>;
7
+ export declare const Default: Story;
8
+ export declare const Sortable: Story;
9
+ export declare const ClickableRows: Story;
10
+ export declare const Empty: Story;
11
+ //# sourceMappingURL=DataTable.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataTable.stories.d.ts","sourceRoot":"","sources":["../../src/stories/DataTable.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAe,MAAM,sCAAsC,CAAC;AAsD9E,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,SAAS,CAMhC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAStB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAS3B,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAEnB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { FeatureFlagGate } from '../ecoimpacthub/components/FeatureFlagGate';
3
+
4
+ /**
5
+ * FeatureFlagGate calls `useFeatureFlag(flag, true)` from
6
+ * `@burdenoff/fe-libs/shared/feature-flags`, whose `useFeatureFlags()` hook
7
+ * requires a `FeatureFlagProvider` ancestor (it throws otherwise — Storybook
8
+ * has no app shell to supply one). We wrap every story in a provider with
9
+ * `workspaceId={null}`, which skips the network fetch entirely and leaves
10
+ * every flag resolving to its default-allow value — the same behavior real
11
+ * users see when the flag service is unreachable, which is exactly the case
12
+ * this component exists to guarantee never locks anyone out.
13
+ */
14
+ declare const meta: Meta<typeof FeatureFlagGate>;
15
+ export default meta;
16
+ type Story = StoryObj<typeof meta>;
17
+ export declare const DefaultAllow: Story;
18
+ export declare const WithFallback: Story;
19
+ //# sourceMappingURL=FeatureFlagGate.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureFlagGate.stories.d.ts","sourceRoot":"","sources":["../../src/stories/FeatureFlagGate.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAE7E;;;;;;;;;GASG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,eAAe,CAatC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,YAAY,EAAE,KAS1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAc1B,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { FilterTabs } from '../ecoimpacthub/components/FilterTabs';
3
+
4
+ declare const meta: Meta<typeof FilterTabs>;
5
+ export default meta;
6
+ type Story = StoryObj<typeof meta>;
7
+ export declare const Default: Story;
8
+ export declare const WithoutCounts: Story;
9
+ //# sourceMappingURL=FilterTabs.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterTabs.stories.d.ts","sourceRoot":"","sources":["../../src/stories/FilterTabs.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAqB,MAAM,uCAAuC,CAAC;AAUtF,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,CAMjC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAW3B,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { PageLayout } from '../ecoimpacthub/components/PageLayout';
3
+
4
+ declare const meta: Meta<typeof PageLayout>;
5
+ export default meta;
6
+ type Story = StoryObj<typeof meta>;
7
+ export declare const Default: Story;
8
+ export declare const AuroraHero: Story;
9
+ export declare const NoActions: Story;
10
+ //# sourceMappingURL=PageLayout.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageLayout.stories.d.ts","sourceRoot":"","sources":["../../src/stories/PageLayout.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AAEnE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,CAMjC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAWrB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAWxB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { Pagination } from '../ecoimpacthub/components/Pagination';
3
+
4
+ declare const meta: Meta<typeof Pagination>;
5
+ export default meta;
6
+ type Story = StoryObj<typeof meta>;
7
+ export declare const MiddlePage: Story;
8
+ export declare const FirstPage: Story;
9
+ export declare const LastPage: Story;
10
+ export declare const SinglePage: Story;
11
+ //# sourceMappingURL=Pagination.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.stories.d.ts","sourceRoot":"","sources":["../../src/stories/Pagination.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AAEnE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,CAMjC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAKvB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAOtB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAIxB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { LoadingView, ErrorView, Section } from '../ecoimpacthub/components/StateViews';
3
+
4
+ declare const meta: Meta;
5
+ export default meta;
6
+ export declare const Loading: StoryObj<typeof LoadingView>;
7
+ export declare const Error: StoryObj<typeof ErrorView>;
8
+ export declare const ErrorWithoutRetry: StoryObj<typeof ErrorView>;
9
+ export declare const SectionWithAction: StoryObj<typeof Section>;
10
+ //# sourceMappingURL=StateViews.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StateViews.stories.d.ts","sourceRoot":"","sources":["../../src/stories/StateViews.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAExF,QAAA,MAAM,IAAI,EAAE,IAKX,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,OAAO,WAAW,CAKhD,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,QAAQ,CAAC,OAAO,SAAS,CAO5C,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,OAAO,SAAS,CAKxD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,OAAO,OAAO,CAetD,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { Tabs } from '../ecoimpacthub/components/Tabs';
3
+
4
+ declare const meta: Meta<typeof Tabs>;
5
+ export default meta;
6
+ type Story = StoryObj<typeof meta>;
7
+ export declare const Default: Story;
8
+ export declare const NoCounts: Story;
9
+ //# sourceMappingURL=Tabs.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tabs.stories.d.ts","sourceRoot":"","sources":["../../src/stories/Tabs.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,IAAI,EAAgB,MAAM,iCAAiC,CAAC;AAoBrE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,IAAI,CAM3B,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAWtB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-ecoimpacthub",
3
- "version": "2026.720.4",
3
+ "version": "2026.720.6",
4
4
  "description": "Burdenoff EcoImpactHub Microfrontend",
5
5
  "type": "module",
6
6
  "files": [