@burdenoff/microfe-ecoimpacthub 2026.716.1 → 2026.720.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.d.ts +5 -5
- package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.d.ts.map +1 -1
- package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.js +20 -5
- package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.js.map +1 -1
- package/dist/ecoimpacthub/pages/DashboardPage.js +1 -1
- package/dist/ecoimpacthub/pages/DashboardPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/badges.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/badges.js +3 -0
- package/dist/ecoimpacthub/pages/badges.js.map +1 -1
- package/dist/ecoimpacthub/pages/carbon/CarbonPage.js +4 -4
- package/dist/ecoimpacthub/pages/carbon/CarbonPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/habitat/HabitatProjectsPage.d.ts +1 -1
- package/dist/ecoimpacthub/pages/habitat/HabitatProjectsPage.js +1 -1
- package/dist/ecoimpacthub/pages/habitat/HabitatProjectsPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/monitoring/MonitoringPage.js +5 -5
- package/dist/ecoimpacthub/pages/monitoring/MonitoringPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/reports/ReportsPage.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/reports/ReportsPage.js +3 -0
- package/dist/ecoimpacthub/pages/reports/ReportsPage.js.map +1 -1
- package/dist/ecoimpacthub/types/index.d.ts +1 -1
- package/dist/ecoimpacthub/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MonitoringPage.js","names":[],"sources":["../../../../src/ecoimpacthub/pages/monitoring/MonitoringPage.tsx"],"sourcesContent":["/**\n * Monitoring — a cross-site hub for environmental measurements, sensors &\n * alert thresholds.\n * @module ecoimpacthub/pages/monitoring\n *\n * Reads `ecoListMeasurements`, `ecoListSensors`, `ecoListThresholds` (and\n * `ecoListSites` for name lookups); writes `ecoRecordMeasurement`,\n * `ecoCreateSensor`, `ecoSetSensorStatus`, `ecoCreateThreshold`,\n * `ecoSetThresholdActive`.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Plus, Activity, Radio, Gauge } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { DataTable, type Column } from '../../components/DataTable';\nimport { FilterTabs, type FilterOption } from '../../components/FilterTabs';\nimport { Tabs, type TabItem } from '../../components/Tabs';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { Pagination } from '../../components/Pagination';\nimport {\n useEcoSites,\n useEcoMeasurements,\n useEcoRecordMeasurement,\n useEcoSensors,\n useEcoCreateSensor,\n useEcoSetSensorStatus,\n useEcoThresholds,\n useEcoCreateThreshold,\n useEcoSetThresholdActive,\n useCursorPager,\n} from '../../hooks';\nimport { formatDateTime, formatEnumLabel, formatNumber } from '../../utils/formatters';\nimport type {\n EcoMeasurement,\n EcoSensor,\n EcoSensorKind,\n EcoSensorStatus,\n EcoAlertThreshold,\n EcoThresholdDirection,\n EcoThresholdSeverity,\n} from '../../types';\n\ntype MonitoringTab = 'measurements' | 'sensors' | 'thresholds';\n\nconst SENSOR_KINDS: EcoSensorKind[] = [\n 'AIR_QUALITY',\n 'WATER_QUALITY',\n 'WEATHER',\n 'SOIL',\n 'ENERGY_METER',\n 'FLOW',\n 'ACOUSTIC',\n 'CAMERA_TRAP',\n 'MANUAL',\n];\nconst SENSOR_STATUSES: EcoSensorStatus[] = [\n 'ONLINE',\n 'OFFLINE',\n 'DEGRADED',\n 'MAINTENANCE',\n 'RETIRED',\n];\nconst THRESHOLD_DIRECTIONS: EcoThresholdDirection[] = ['ABOVE', 'BELOW', 'OUTSIDE_RANGE'];\nconst THRESHOLD_SEVERITIES: EcoThresholdSeverity[] = ['INFO', 'WARNING', 'CRITICAL'];\n\nconst BREACH_FILTERS: FilterOption<'ALL' | 'BREACHES'>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'BREACHES', label: 'Breaches only' },\n];\n\nconst ALL = 'ALL';\nconst PAGE_SIZE = 25;\n\nexport function MonitoringPage() {\n const [tab, setTab] = useState<MonitoringTab>('measurements');\n\n // Site directory — powers name lookups + the per-tab site filters/selects.\n const sitesQuery = useEcoSites({ pagination: { limit: 100, offset: 0 } });\n const allSites = useMemo(() => sitesQuery.data?.items ?? [], [sitesQuery.data]);\n const siteNameById = useMemo(() => {\n const map = new Map<string, string>();\n for (const s of allSites) map.set(s.id, s.name);\n return map;\n }, [allSites]);\n const siteName = (id?: string | null): string => (id ? (siteNameById.get(id) ?? '—') : '—');\n\n // ── Measurements tab state ────────────────────────────────────────────────\n const [measSiteId, setMeasSiteId] = useState<string>(ALL);\n const [breachFilter, setBreachFilter] = useState<'ALL' | 'BREACHES'>('ALL');\n const measPager = useCursorPager();\n\n const measurementsQuery = useEcoMeasurements({\n siteId: measSiteId === ALL ? undefined : measSiteId,\n breachesOnly: breachFilter === 'BREACHES' ? true : undefined,\n pagination: { limit: PAGE_SIZE, cursor: measPager.cursor },\n });\n const recordMeasurement = useEcoRecordMeasurement();\n\n const [measureOpen, setMeasureOpen] = useState(false);\n const [measureForm, setMeasureForm] = useState({\n siteId: '',\n parameter: '',\n value: '',\n unit: '',\n sensorId: '',\n });\n const dialogSensors = useEcoSensors({ siteId: measureForm.siteId || undefined });\n const dialogSensorList = dialogSensors.data ?? [];\n\n // ── Sensors tab state ─────────────────────────────────────────────────────\n const [sensorSiteId, setSensorSiteId] = useState<string>(ALL);\n const [sensorStatusFilter, setSensorStatusFilter] = useState<EcoSensorStatus | 'ALL'>(ALL);\n\n const sensorsQuery = useEcoSensors({\n siteId: sensorSiteId === ALL ? undefined : sensorSiteId,\n status: sensorStatusFilter === ALL ? undefined : sensorStatusFilter,\n });\n const sensors = sensorsQuery.data ?? [];\n const createSensor = useEcoCreateSensor();\n const setSensorStatus = useEcoSetSensorStatus();\n\n const [sensorOpen, setSensorOpen] = useState(false);\n const [sensorForm, setSensorForm] = useState({\n siteId: '',\n name: '',\n kind: 'AIR_QUALITY' as EcoSensorKind,\n unit: '',\n });\n\n // ── Thresholds tab state ──────────────────────────────────────────────────\n const [thresholdSiteId, setThresholdSiteId] = useState<string>(ALL);\n\n const thresholdsQuery = useEcoThresholds(thresholdSiteId === ALL ? undefined : thresholdSiteId);\n const thresholds = thresholdsQuery.data ?? [];\n const createThreshold = useEcoCreateThreshold();\n const setThresholdActive = useEcoSetThresholdActive();\n\n const [thresholdOpen, setThresholdOpen] = useState(false);\n const [thresholdForm, setThresholdForm] = useState({\n siteId: '',\n parameter: '',\n unit: '',\n direction: 'ABOVE' as EcoThresholdDirection,\n severity: 'WARNING' as EcoThresholdSeverity,\n limitValue: '',\n minValue: '',\n maxValue: '',\n });\n\n const [error, setError] = useState<string | null>(null);\n\n const tabItems: TabItem<MonitoringTab>[] = [\n { value: 'measurements', label: 'Measurements', icon: <Activity className=\"h-4 w-4\" /> },\n {\n value: 'sensors',\n label: 'Sensors',\n icon: <Radio className=\"h-4 w-4\" />,\n count: sensorsQuery.data?.length,\n },\n {\n value: 'thresholds',\n label: 'Thresholds',\n icon: <Gauge className=\"h-4 w-4\" />,\n count: thresholdsQuery.data?.length,\n },\n ];\n\n // ── Mutations ─────────────────────────────────────────────────────────────\n const handleRecordMeasurement = async () => {\n if (\n !measureForm.siteId ||\n !measureForm.parameter.trim() ||\n !measureForm.unit.trim() ||\n !measureForm.value\n ) {\n setError('Site, parameter, value and unit are required.');\n return;\n }\n setError(null);\n try {\n await recordMeasurement.mutateAsync({\n siteId: measureForm.siteId,\n parameter: measureForm.parameter.trim(),\n value: Number(measureForm.value),\n unit: measureForm.unit.trim(),\n recordedAt: new Date().toISOString(),\n sensorId: measureForm.sensorId || null,\n source: 'MANUAL',\n });\n setMeasureOpen(false);\n setMeasureForm({ siteId: '', parameter: '', value: '', unit: '', sensorId: '' });\n measurementsQuery.refetch();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to record measurement.');\n }\n };\n\n const handleAddSensor = async () => {\n if (!sensorForm.siteId || !sensorForm.name.trim()) {\n setError('Site and sensor name are required.');\n return;\n }\n setError(null);\n try {\n await createSensor.mutateAsync({\n name: sensorForm.name.trim(),\n siteId: sensorForm.siteId,\n kind: sensorForm.kind,\n unit: sensorForm.unit.trim() || null,\n });\n setSensorOpen(false);\n setSensorForm({ siteId: '', name: '', kind: 'AIR_QUALITY', unit: '' });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add sensor.');\n }\n };\n\n const handleAddThreshold = async () => {\n if (!thresholdForm.siteId || !thresholdForm.parameter.trim() || !thresholdForm.unit.trim()) {\n setError('Site, parameter and unit are required.');\n return;\n }\n setError(null);\n try {\n await createThreshold.mutateAsync({\n siteId: thresholdForm.siteId,\n parameter: thresholdForm.parameter.trim(),\n unit: thresholdForm.unit.trim(),\n direction: thresholdForm.direction,\n severity: thresholdForm.severity,\n limitValue: thresholdForm.limitValue ? Number(thresholdForm.limitValue) : null,\n minValue: thresholdForm.minValue ? Number(thresholdForm.minValue) : null,\n maxValue: thresholdForm.maxValue ? Number(thresholdForm.maxValue) : null,\n });\n setThresholdOpen(false);\n setThresholdForm({\n siteId: '',\n parameter: '',\n unit: '',\n direction: 'ABOVE',\n severity: 'WARNING',\n limitValue: '',\n minValue: '',\n maxValue: '',\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add threshold.');\n }\n };\n\n // ── Columns ───────────────────────────────────────────────────────────────\n const measurementColumns: Column<EcoMeasurement>[] = [\n {\n key: 'parameter',\n header: 'Parameter',\n render: (m) => <span className=\"font-medium text-text-primary\">{m.parameter}</span>,\n },\n {\n key: 'value',\n header: 'Value',\n align: 'right',\n render: (m) => (\n <span className=\"tabular-nums text-text-primary\">\n {formatNumber(m.value)} {m.unit}\n </span>\n ),\n },\n {\n key: 'source',\n header: 'Source',\n hideOnMobile: true,\n render: (m) => <span className=\"text-text-secondary\">{formatEnumLabel(m.source)}</span>,\n },\n {\n key: 'breach',\n header: 'Status',\n render: (m) =>\n m.isBreach ? (\n <StatusBadge status=\"BREACH\" className=\"uppercase\" />\n ) : (\n <StatusBadge status=\"OK\" className=\"uppercase\" />\n ),\n },\n {\n key: 'site',\n header: 'Site',\n hideOnMobile: true,\n render: (m) => <span className=\"text-text-secondary\">{siteName(m.siteId)}</span>,\n },\n {\n key: 'recorded',\n header: 'Recorded',\n align: 'right',\n hideOnMobile: true,\n render: (m) => <span className=\"text-text-tertiary\">{formatDateTime(m.recordedAt)}</span>,\n },\n ];\n\n const sensorColumns: Column<EcoSensor>[] = [\n {\n key: 'name',\n header: 'Sensor',\n render: (s) => (\n <div>\n <p className=\"font-medium text-text-primary\">{s.name}</p>\n <p className=\"text-xs text-text-tertiary\">{formatEnumLabel(s.kind)}</p>\n </div>\n ),\n },\n {\n key: 'site',\n header: 'Site',\n hideOnMobile: true,\n render: (s) => <span className=\"text-text-secondary\">{siteName(s.siteId)}</span>,\n },\n {\n key: 'unit',\n header: 'Unit',\n hideOnMobile: true,\n render: (s) => <span className=\"text-text-secondary\">{s.unit ?? '—'}</span>,\n },\n { key: 'status', header: 'Status', render: (s) => <StatusBadge status={s.status} /> },\n {\n key: 'action',\n header: '',\n align: 'right',\n render: (s) => (\n <Select\n value={s.status}\n onValueChange={(v) => setSensorStatus.mutate({ id: s.id, status: v as EcoSensorStatus })}\n >\n <SelectTrigger className=\"h-8 w-36\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SENSOR_STATUSES.map((st) => (\n <SelectItem key={st} value={st}>\n {formatEnumLabel(st)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ),\n },\n ];\n\n const thresholdColumns: Column<EcoAlertThreshold>[] = [\n {\n key: 'parameter',\n header: 'Parameter',\n render: (t) => <span className=\"font-medium text-text-primary\">{t.parameter}</span>,\n },\n {\n key: 'site',\n header: 'Site',\n hideOnMobile: true,\n render: (t) => <span className=\"text-text-secondary\">{siteName(t.siteId)}</span>,\n },\n {\n key: 'rule',\n header: 'Rule',\n render: (t) => (\n <span className=\"text-text-secondary\">\n {t.direction === 'OUTSIDE_RANGE'\n ? `${formatNumber(t.minValue)}–${formatNumber(t.maxValue)} ${t.unit}`\n : `${formatEnumLabel(t.direction)} ${formatNumber(t.limitValue)} ${t.unit}`}\n </span>\n ),\n },\n { key: 'severity', header: 'Severity', render: (t) => <StatusBadge status={t.severity} /> },\n {\n key: 'active',\n header: 'Active',\n align: 'right',\n render: (t) => (\n <Button\n size=\"sm\"\n variant={t.isActive ? 'outline' : 'ghost'}\n onClick={() => setThresholdActive.mutate({ id: t.id, isActive: !t.isActive })}\n >\n {t.isActive ? 'Active' : 'Inactive'}\n </Button>\n ),\n },\n ];\n\n // ── Reusable site <Select> options ────────────────────────────────────────\n const siteOptions = allSites.map((s) => (\n <SelectItem key={s.id} value={s.id}>\n {s.name}\n </SelectItem>\n ));\n\n const measurementRows = measurementsQuery.data?.items ?? [];\n\n return (\n <PageLayout\n title=\"Monitoring\"\n description=\"Environmental sensors, readings and alert thresholds across every monitored site.\"\n actions={\n tab === 'measurements' ? (\n <Button\n onClick={() => {\n setError(null);\n setMeasureOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record measurement\n </Button>\n ) : tab === 'sensors' ? (\n <Button\n onClick={() => {\n setError(null);\n setSensorOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add sensor\n </Button>\n ) : (\n <Button\n onClick={() => {\n setError(null);\n setThresholdOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add threshold\n </Button>\n )\n }\n >\n <Tabs items={tabItems} value={tab} onChange={setTab} className=\"mb-5\" />\n\n {/* ── Measurements ─────────────────────────────────────────────────── */}\n {tab === 'measurements' && (\n <>\n <div className=\"mb-5 flex flex-wrap items-center gap-3\">\n <Select\n value={measSiteId}\n onValueChange={(v) => {\n setMeasSiteId(v);\n measPager.reset();\n }}\n >\n <SelectTrigger className=\"w-52\">\n <SelectValue placeholder=\"All sites\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All sites</SelectItem>\n {siteOptions}\n </SelectContent>\n </Select>\n <FilterTabs\n options={BREACH_FILTERS}\n value={breachFilter}\n onChange={(v) => {\n setBreachFilter(v);\n measPager.reset();\n }}\n />\n </div>\n\n {measurementsQuery.isLoading ? (\n <LoadingView label=\"Loading measurements…\" />\n ) : measurementsQuery.isError ? (\n <ErrorView\n message=\"Couldn't load measurements.\"\n onRetry={() => measurementsQuery.refetch()}\n />\n ) : measurementRows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Activity className=\"h-10 w-10\" />}\n title=\"No measurements\"\n description={\n measSiteId === ALL && breachFilter === 'ALL'\n ? 'Record a measurement to start building a reading history.'\n : 'No measurements match these filters.'\n }\n action={\n <Button\n onClick={() => {\n setError(null);\n setMeasureOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record measurement\n </Button>\n }\n />\n ) : (\n <>\n <DataTable columns={measurementColumns} rows={measurementRows} rowKey={(m) => m.id} />\n <Pagination\n page={measPager.page}\n pageSize={PAGE_SIZE}\n itemCount={measurementRows.length}\n hasMore={measurementsQuery.data?.pageInfo?.hasMore ?? false}\n onPageChange={(target) =>\n measPager.onPageChange(target, measurementsQuery.data?.pageInfo?.cursor)\n }\n />\n </>\n )}\n </>\n )}\n\n {/* ── Sensors ──────────────────────────────────────────────────────── */}\n {tab === 'sensors' && (\n <>\n <div className=\"mb-5 flex flex-wrap items-center gap-3\">\n <Select value={sensorSiteId} onValueChange={setSensorSiteId}>\n <SelectTrigger className=\"w-52\">\n <SelectValue placeholder=\"All sites\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All sites</SelectItem>\n {siteOptions}\n </SelectContent>\n </Select>\n <Select\n value={sensorStatusFilter}\n onValueChange={(v) => setSensorStatusFilter(v as EcoSensorStatus | 'ALL')}\n >\n <SelectTrigger className=\"w-44\">\n <SelectValue placeholder=\"All statuses\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {SENSOR_STATUSES.map((st) => (\n <SelectItem key={st} value={st}>\n {formatEnumLabel(st)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {sensorsQuery.isLoading ? (\n <LoadingView label=\"Loading sensors…\" />\n ) : sensorsQuery.isError ? (\n <ErrorView message=\"Couldn't load sensors.\" onRetry={() => sensorsQuery.refetch()} />\n ) : sensors.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Radio className=\"h-10 w-10\" />}\n title=\"No sensors\"\n description={\n sensorSiteId === ALL && sensorStatusFilter === ALL\n ? 'Add a sensor to begin streaming or logging readings.'\n : 'No sensors match these filters.'\n }\n action={\n <Button\n onClick={() => {\n setError(null);\n setSensorOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add sensor\n </Button>\n }\n />\n ) : (\n <DataTable columns={sensorColumns} rows={sensors} rowKey={(s) => s.id} />\n )}\n </>\n )}\n\n {/* ── Thresholds ───────────────────────────────────────────────────── */}\n {tab === 'thresholds' && (\n <>\n <div className=\"mb-5 flex flex-wrap items-center gap-3\">\n <Select value={thresholdSiteId} onValueChange={setThresholdSiteId}>\n <SelectTrigger className=\"w-52\">\n <SelectValue placeholder=\"All sites\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All sites</SelectItem>\n {siteOptions}\n </SelectContent>\n </Select>\n </div>\n\n {thresholdsQuery.isLoading ? (\n <LoadingView label=\"Loading thresholds…\" />\n ) : thresholdsQuery.isError ? (\n <ErrorView\n message=\"Couldn't load thresholds.\"\n onRetry={() => thresholdsQuery.refetch()}\n />\n ) : thresholds.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Gauge className=\"h-10 w-10\" />}\n title=\"No thresholds\"\n description={\n thresholdSiteId === ALL\n ? 'Define a threshold to flag readings that drift out of range.'\n : 'This site has no thresholds yet.'\n }\n action={\n <Button\n onClick={() => {\n setError(null);\n setThresholdOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add threshold\n </Button>\n }\n />\n ) : (\n <DataTable columns={thresholdColumns} rows={thresholds} rowKey={(t) => t.id} />\n )}\n </>\n )}\n\n {/* ── Record measurement dialog ────────────────────────────────────── */}\n <ResponsiveDialog\n open={measureOpen}\n onOpenChange={(open) => {\n setMeasureOpen(open);\n if (!open) setError(null);\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Record measurement</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Log a reading. It is checked against the site's active thresholds and flagged if\n it breaches.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"mSite\">Site *</Label>\n <Select\n value={measureForm.siteId}\n onValueChange={(v) => setMeasureForm({ ...measureForm, siteId: v, sensorId: '' })}\n >\n <SelectTrigger id=\"mSite\">\n <SelectValue placeholder=\"Select a site\" />\n </SelectTrigger>\n <SelectContent>{siteOptions}</SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-3\">\n <div className=\"grid gap-1.5 sm:col-span-1\">\n <Label htmlFor=\"mParam\">Parameter *</Label>\n <Input\n id=\"mParam\"\n value={measureForm.parameter}\n onChange={(e) => setMeasureForm({ ...measureForm, parameter: e.target.value })}\n placeholder=\"PM2.5\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"mValue\">Value *</Label>\n <Input\n id=\"mValue\"\n type=\"number\"\n step=\"any\"\n value={measureForm.value}\n onChange={(e) => setMeasureForm({ ...measureForm, value: e.target.value })}\n placeholder=\"42\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"mUnit\">Unit *</Label>\n <Input\n id=\"mUnit\"\n value={measureForm.unit}\n onChange={(e) => setMeasureForm({ ...measureForm, unit: e.target.value })}\n placeholder=\"µg/m³\"\n />\n </div>\n </div>\n {measureForm.siteId && dialogSensorList.length > 0 && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"mSensor\">Sensor (optional)</Label>\n <Select\n value={measureForm.sensorId}\n onValueChange={(v) => setMeasureForm({ ...measureForm, sensorId: v })}\n >\n <SelectTrigger id=\"mSensor\">\n <SelectValue placeholder=\"Manual entry\" />\n </SelectTrigger>\n <SelectContent>\n {dialogSensorList.map((s) => (\n <SelectItem key={s.id} value={s.id}>\n {s.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-xs text-text-tertiary\">\n Select a specific sensor for context, or leave blank for a site-level reading.\n </p>\n </div>\n )}\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setMeasureOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleRecordMeasurement} disabled={recordMeasurement.isPending}>\n {recordMeasurement.isPending ? 'Recording…' : 'Record'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* ── Add sensor dialog ────────────────────────────────────────────── */}\n <ResponsiveDialog\n open={sensorOpen}\n onOpenChange={(open) => {\n setSensorOpen(open);\n if (!open) setError(null);\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Add sensor</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Register a sensor and attribute it to a monitored site.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"sSite\">Site *</Label>\n <Select\n value={sensorForm.siteId}\n onValueChange={(v) => setSensorForm({ ...sensorForm, siteId: v })}\n >\n <SelectTrigger id=\"sSite\">\n <SelectValue placeholder=\"Select a site\" />\n </SelectTrigger>\n <SelectContent>{siteOptions}</SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"sName\">Name *</Label>\n <Input\n id=\"sName\"\n value={sensorForm.name}\n onChange={(e) => setSensorForm({ ...sensorForm, name: e.target.value })}\n placeholder=\"North gate PM2.5\"\n />\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"sKind\">Kind</Label>\n <Select\n value={sensorForm.kind}\n onValueChange={(v) => setSensorForm({ ...sensorForm, kind: v as EcoSensorKind })}\n >\n <SelectTrigger id=\"sKind\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SENSOR_KINDS.map((k) => (\n <SelectItem key={k} value={k}>\n {formatEnumLabel(k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"sUnit\">Unit</Label>\n <Input\n id=\"sUnit\"\n value={sensorForm.unit}\n onChange={(e) => setSensorForm({ ...sensorForm, unit: e.target.value })}\n placeholder=\"µg/m³\"\n />\n </div>\n </div>\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setSensorOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleAddSensor} disabled={createSensor.isPending}>\n {createSensor.isPending ? 'Adding…' : 'Add sensor'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* ── Add threshold dialog ─────────────────────────────────────────── */}\n <ResponsiveDialog\n open={thresholdOpen}\n onOpenChange={(open) => {\n setThresholdOpen(open);\n if (!open) setError(null);\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Add alert threshold</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Flag readings that drift out of an acceptable range.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tSite\">Site *</Label>\n <Select\n value={thresholdForm.siteId}\n onValueChange={(v) => setThresholdForm({ ...thresholdForm, siteId: v })}\n >\n <SelectTrigger id=\"tSite\">\n <SelectValue placeholder=\"Select a site\" />\n </SelectTrigger>\n <SelectContent>{siteOptions}</SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tParam\">Parameter *</Label>\n <Input\n id=\"tParam\"\n value={thresholdForm.parameter}\n onChange={(e) =>\n setThresholdForm({ ...thresholdForm, parameter: e.target.value })\n }\n placeholder=\"PM2.5\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tUnit\">Unit *</Label>\n <Input\n id=\"tUnit\"\n value={thresholdForm.unit}\n onChange={(e) => setThresholdForm({ ...thresholdForm, unit: e.target.value })}\n placeholder=\"µg/m³\"\n />\n </div>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tDir\">Direction</Label>\n <Select\n value={thresholdForm.direction}\n onValueChange={(v) =>\n setThresholdForm({ ...thresholdForm, direction: v as EcoThresholdDirection })\n }\n >\n <SelectTrigger id=\"tDir\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {THRESHOLD_DIRECTIONS.map((d) => (\n <SelectItem key={d} value={d}>\n {formatEnumLabel(d)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tSev\">Severity</Label>\n <Select\n value={thresholdForm.severity}\n onValueChange={(v) =>\n setThresholdForm({ ...thresholdForm, severity: v as EcoThresholdSeverity })\n }\n >\n <SelectTrigger id=\"tSev\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {THRESHOLD_SEVERITIES.map((s) => (\n <SelectItem key={s} value={s}>\n {formatEnumLabel(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n {thresholdForm.direction === 'OUTSIDE_RANGE' ? (\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tMin\">Min value</Label>\n <Input\n id=\"tMin\"\n type=\"number\"\n step=\"any\"\n value={thresholdForm.minValue}\n onChange={(e) =>\n setThresholdForm({ ...thresholdForm, minValue: e.target.value })\n }\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tMax\">Max value</Label>\n <Input\n id=\"tMax\"\n type=\"number\"\n step=\"any\"\n value={thresholdForm.maxValue}\n onChange={(e) =>\n setThresholdForm({ ...thresholdForm, maxValue: e.target.value })\n }\n />\n </div>\n </div>\n ) : (\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tLimit\">Limit value</Label>\n <Input\n id=\"tLimit\"\n type=\"number\"\n step=\"any\"\n value={thresholdForm.limitValue}\n onChange={(e) =>\n setThresholdForm({ ...thresholdForm, limitValue: e.target.value })\n }\n placeholder=\"35\"\n />\n </div>\n )}\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setThresholdOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleAddThreshold} disabled={createThreshold.isPending}>\n {createThreshold.isPending ? 'Adding…' : 'Add threshold'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MonitoringPage.js","names":[],"sources":["../../../../src/ecoimpacthub/pages/monitoring/MonitoringPage.tsx"],"sourcesContent":["/**\n * Monitoring — a cross-site hub for environmental measurements, sensors &\n * alert thresholds.\n * @module ecoimpacthub/pages/monitoring\n *\n * Reads `ecoListMeasurements`, `ecoListSensors`, `ecoListThresholds` (and\n * `ecoListSites` for name lookups); writes `ecoRecordMeasurement`,\n * `ecoCreateSensor`, `ecoSetSensorStatus`, `ecoCreateThreshold`,\n * `ecoSetThresholdActive`.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Plus, Activity, Radio, Gauge } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { DataTable, type Column } from '../../components/DataTable';\nimport { FilterTabs, type FilterOption } from '../../components/FilterTabs';\nimport { Tabs, type TabItem } from '../../components/Tabs';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { Pagination } from '../../components/Pagination';\nimport {\n useEcoSites,\n useEcoMeasurements,\n useEcoRecordMeasurement,\n useEcoSensors,\n useEcoCreateSensor,\n useEcoSetSensorStatus,\n useEcoThresholds,\n useEcoCreateThreshold,\n useEcoSetThresholdActive,\n useCursorPager,\n} from '../../hooks';\nimport { formatDateTime, formatEnumLabel, formatNumber } from '../../utils/formatters';\nimport type {\n EcoMeasurement,\n EcoSensor,\n EcoSensorKind,\n EcoSensorStatus,\n EcoAlertThreshold,\n EcoThresholdDirection,\n EcoThresholdSeverity,\n} from '../../types';\n\ntype MonitoringTab = 'measurements' | 'sensors' | 'thresholds';\n\nconst SENSOR_KINDS: EcoSensorKind[] = [\n 'AIR_QUALITY',\n 'WATER_QUALITY',\n 'WEATHER',\n 'SOIL',\n 'ENERGY_METER',\n 'FLOW',\n 'ACOUSTIC',\n 'CAMERA_TRAP',\n 'MANUAL',\n];\nconst SENSOR_STATUSES: EcoSensorStatus[] = [\n 'ONLINE',\n 'OFFLINE',\n 'DEGRADED',\n 'MAINTENANCE',\n 'RETIRED',\n];\nconst THRESHOLD_DIRECTIONS: EcoThresholdDirection[] = ['ABOVE', 'BELOW', 'OUTSIDE_RANGE'];\nconst THRESHOLD_SEVERITIES: EcoThresholdSeverity[] = ['INFO', 'WARNING', 'CRITICAL'];\n\nconst BREACH_FILTERS: FilterOption<'ALL' | 'BREACHES'>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'BREACHES', label: 'Breaches only' },\n];\n\nconst ALL = 'ALL';\nconst PAGE_SIZE = 25;\n\nexport function MonitoringPage() {\n const [tab, setTab] = useState<MonitoringTab>('measurements');\n\n // Site directory — powers name lookups + the per-tab site filters/selects.\n const sitesQuery = useEcoSites({ pagination: { limit: 100, offset: 0 } });\n const allSites = useMemo(() => sitesQuery.data?.items ?? [], [sitesQuery.data]);\n const siteNameById = useMemo(() => {\n const map = new Map<string, string>();\n for (const s of allSites) map.set(s.id, s.name);\n return map;\n }, [allSites]);\n const siteName = (id?: string | null): string => (id ? (siteNameById.get(id) ?? '—') : '—');\n\n // ── Measurements tab state ────────────────────────────────────────────────\n const [measSiteId, setMeasSiteId] = useState<string>(ALL);\n const [breachFilter, setBreachFilter] = useState<'ALL' | 'BREACHES'>('ALL');\n const measPager = useCursorPager();\n\n const measurementsQuery = useEcoMeasurements({\n siteId: measSiteId === ALL ? undefined : measSiteId,\n breachesOnly: breachFilter === 'BREACHES' ? true : undefined,\n pagination: { limit: PAGE_SIZE, cursor: measPager.cursor },\n });\n const recordMeasurement = useEcoRecordMeasurement();\n\n const [measureOpen, setMeasureOpen] = useState(false);\n const [measureForm, setMeasureForm] = useState({\n siteId: '',\n parameter: '',\n value: '',\n unit: '',\n sensorId: '',\n });\n const dialogSensors = useEcoSensors({ siteId: measureForm.siteId || undefined });\n const dialogSensorList = dialogSensors.data?.items ?? [];\n\n // ── Sensors tab state ─────────────────────────────────────────────────────\n const [sensorSiteId, setSensorSiteId] = useState<string>(ALL);\n const [sensorStatusFilter, setSensorStatusFilter] = useState<EcoSensorStatus | 'ALL'>(ALL);\n\n const sensorsQuery = useEcoSensors({\n siteId: sensorSiteId === ALL ? undefined : sensorSiteId,\n status: sensorStatusFilter === ALL ? undefined : sensorStatusFilter,\n });\n const sensors = sensorsQuery.data?.items ?? [];\n const createSensor = useEcoCreateSensor();\n const setSensorStatus = useEcoSetSensorStatus();\n\n const [sensorOpen, setSensorOpen] = useState(false);\n const [sensorForm, setSensorForm] = useState({\n siteId: '',\n name: '',\n kind: 'AIR_QUALITY' as EcoSensorKind,\n unit: '',\n });\n\n // ── Thresholds tab state ──────────────────────────────────────────────────\n const [thresholdSiteId, setThresholdSiteId] = useState<string>(ALL);\n\n const thresholdsQuery = useEcoThresholds(thresholdSiteId === ALL ? undefined : thresholdSiteId);\n const thresholds = thresholdsQuery.data?.items ?? [];\n const createThreshold = useEcoCreateThreshold();\n const setThresholdActive = useEcoSetThresholdActive();\n\n const [thresholdOpen, setThresholdOpen] = useState(false);\n const [thresholdForm, setThresholdForm] = useState({\n siteId: '',\n parameter: '',\n unit: '',\n direction: 'ABOVE' as EcoThresholdDirection,\n severity: 'WARNING' as EcoThresholdSeverity,\n limitValue: '',\n minValue: '',\n maxValue: '',\n });\n\n const [error, setError] = useState<string | null>(null);\n\n const tabItems: TabItem<MonitoringTab>[] = [\n { value: 'measurements', label: 'Measurements', icon: <Activity className=\"h-4 w-4\" /> },\n {\n value: 'sensors',\n label: 'Sensors',\n icon: <Radio className=\"h-4 w-4\" />,\n count: sensorsQuery.data?.items?.length,\n },\n {\n value: 'thresholds',\n label: 'Thresholds',\n icon: <Gauge className=\"h-4 w-4\" />,\n count: thresholdsQuery.data?.items?.length,\n },\n ];\n\n // ── Mutations ─────────────────────────────────────────────────────────────\n const handleRecordMeasurement = async () => {\n if (\n !measureForm.siteId ||\n !measureForm.parameter.trim() ||\n !measureForm.unit.trim() ||\n !measureForm.value\n ) {\n setError('Site, parameter, value and unit are required.');\n return;\n }\n setError(null);\n try {\n await recordMeasurement.mutateAsync({\n siteId: measureForm.siteId,\n parameter: measureForm.parameter.trim(),\n value: Number(measureForm.value),\n unit: measureForm.unit.trim(),\n recordedAt: new Date().toISOString(),\n sensorId: measureForm.sensorId || null,\n source: 'MANUAL',\n });\n setMeasureOpen(false);\n setMeasureForm({ siteId: '', parameter: '', value: '', unit: '', sensorId: '' });\n measurementsQuery.refetch();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to record measurement.');\n }\n };\n\n const handleAddSensor = async () => {\n if (!sensorForm.siteId || !sensorForm.name.trim()) {\n setError('Site and sensor name are required.');\n return;\n }\n setError(null);\n try {\n await createSensor.mutateAsync({\n name: sensorForm.name.trim(),\n siteId: sensorForm.siteId,\n kind: sensorForm.kind,\n unit: sensorForm.unit.trim() || null,\n });\n setSensorOpen(false);\n setSensorForm({ siteId: '', name: '', kind: 'AIR_QUALITY', unit: '' });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add sensor.');\n }\n };\n\n const handleAddThreshold = async () => {\n if (!thresholdForm.siteId || !thresholdForm.parameter.trim() || !thresholdForm.unit.trim()) {\n setError('Site, parameter and unit are required.');\n return;\n }\n setError(null);\n try {\n await createThreshold.mutateAsync({\n siteId: thresholdForm.siteId,\n parameter: thresholdForm.parameter.trim(),\n unit: thresholdForm.unit.trim(),\n direction: thresholdForm.direction,\n severity: thresholdForm.severity,\n limitValue: thresholdForm.limitValue ? Number(thresholdForm.limitValue) : null,\n minValue: thresholdForm.minValue ? Number(thresholdForm.minValue) : null,\n maxValue: thresholdForm.maxValue ? Number(thresholdForm.maxValue) : null,\n });\n setThresholdOpen(false);\n setThresholdForm({\n siteId: '',\n parameter: '',\n unit: '',\n direction: 'ABOVE',\n severity: 'WARNING',\n limitValue: '',\n minValue: '',\n maxValue: '',\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add threshold.');\n }\n };\n\n // ── Columns ───────────────────────────────────────────────────────────────\n const measurementColumns: Column<EcoMeasurement>[] = [\n {\n key: 'parameter',\n header: 'Parameter',\n render: (m) => <span className=\"font-medium text-text-primary\">{m.parameter}</span>,\n },\n {\n key: 'value',\n header: 'Value',\n align: 'right',\n render: (m) => (\n <span className=\"tabular-nums text-text-primary\">\n {formatNumber(m.value)} {m.unit}\n </span>\n ),\n },\n {\n key: 'source',\n header: 'Source',\n hideOnMobile: true,\n render: (m) => <span className=\"text-text-secondary\">{formatEnumLabel(m.source)}</span>,\n },\n {\n key: 'breach',\n header: 'Status',\n render: (m) =>\n m.isBreach ? (\n <StatusBadge status=\"BREACH\" className=\"uppercase\" />\n ) : (\n <StatusBadge status=\"OK\" className=\"uppercase\" />\n ),\n },\n {\n key: 'site',\n header: 'Site',\n hideOnMobile: true,\n render: (m) => <span className=\"text-text-secondary\">{siteName(m.siteId)}</span>,\n },\n {\n key: 'recorded',\n header: 'Recorded',\n align: 'right',\n hideOnMobile: true,\n render: (m) => <span className=\"text-text-tertiary\">{formatDateTime(m.recordedAt)}</span>,\n },\n ];\n\n const sensorColumns: Column<EcoSensor>[] = [\n {\n key: 'name',\n header: 'Sensor',\n render: (s) => (\n <div>\n <p className=\"font-medium text-text-primary\">{s.name}</p>\n <p className=\"text-xs text-text-tertiary\">{formatEnumLabel(s.kind)}</p>\n </div>\n ),\n },\n {\n key: 'site',\n header: 'Site',\n hideOnMobile: true,\n render: (s) => <span className=\"text-text-secondary\">{siteName(s.siteId)}</span>,\n },\n {\n key: 'unit',\n header: 'Unit',\n hideOnMobile: true,\n render: (s) => <span className=\"text-text-secondary\">{s.unit ?? '—'}</span>,\n },\n { key: 'status', header: 'Status', render: (s) => <StatusBadge status={s.status} /> },\n {\n key: 'action',\n header: '',\n align: 'right',\n render: (s) => (\n <Select\n value={s.status}\n onValueChange={(v) => setSensorStatus.mutate({ id: s.id, status: v as EcoSensorStatus })}\n >\n <SelectTrigger className=\"h-8 w-36\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SENSOR_STATUSES.map((st) => (\n <SelectItem key={st} value={st}>\n {formatEnumLabel(st)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ),\n },\n ];\n\n const thresholdColumns: Column<EcoAlertThreshold>[] = [\n {\n key: 'parameter',\n header: 'Parameter',\n render: (t) => <span className=\"font-medium text-text-primary\">{t.parameter}</span>,\n },\n {\n key: 'site',\n header: 'Site',\n hideOnMobile: true,\n render: (t) => <span className=\"text-text-secondary\">{siteName(t.siteId)}</span>,\n },\n {\n key: 'rule',\n header: 'Rule',\n render: (t) => (\n <span className=\"text-text-secondary\">\n {t.direction === 'OUTSIDE_RANGE'\n ? `${formatNumber(t.minValue)}–${formatNumber(t.maxValue)} ${t.unit}`\n : `${formatEnumLabel(t.direction)} ${formatNumber(t.limitValue)} ${t.unit}`}\n </span>\n ),\n },\n { key: 'severity', header: 'Severity', render: (t) => <StatusBadge status={t.severity} /> },\n {\n key: 'active',\n header: 'Active',\n align: 'right',\n render: (t) => (\n <Button\n size=\"sm\"\n variant={t.isActive ? 'outline' : 'ghost'}\n onClick={() => setThresholdActive.mutate({ id: t.id, isActive: !t.isActive })}\n >\n {t.isActive ? 'Active' : 'Inactive'}\n </Button>\n ),\n },\n ];\n\n // ── Reusable site <Select> options ────────────────────────────────────────\n const siteOptions = allSites.map((s) => (\n <SelectItem key={s.id} value={s.id}>\n {s.name}\n </SelectItem>\n ));\n\n const measurementRows = measurementsQuery.data?.items ?? [];\n\n return (\n <PageLayout\n title=\"Monitoring\"\n description=\"Environmental sensors, readings and alert thresholds across every monitored site.\"\n actions={\n tab === 'measurements' ? (\n <Button\n onClick={() => {\n setError(null);\n setMeasureOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record measurement\n </Button>\n ) : tab === 'sensors' ? (\n <Button\n onClick={() => {\n setError(null);\n setSensorOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add sensor\n </Button>\n ) : (\n <Button\n onClick={() => {\n setError(null);\n setThresholdOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add threshold\n </Button>\n )\n }\n >\n <Tabs items={tabItems} value={tab} onChange={setTab} className=\"mb-5\" />\n\n {/* ── Measurements ─────────────────────────────────────────────────── */}\n {tab === 'measurements' && (\n <>\n <div className=\"mb-5 flex flex-wrap items-center gap-3\">\n <Select\n value={measSiteId}\n onValueChange={(v) => {\n setMeasSiteId(v);\n measPager.reset();\n }}\n >\n <SelectTrigger className=\"w-52\">\n <SelectValue placeholder=\"All sites\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All sites</SelectItem>\n {siteOptions}\n </SelectContent>\n </Select>\n <FilterTabs\n options={BREACH_FILTERS}\n value={breachFilter}\n onChange={(v) => {\n setBreachFilter(v);\n measPager.reset();\n }}\n />\n </div>\n\n {measurementsQuery.isLoading ? (\n <LoadingView label=\"Loading measurements…\" />\n ) : measurementsQuery.isError ? (\n <ErrorView\n message=\"Couldn't load measurements.\"\n onRetry={() => measurementsQuery.refetch()}\n />\n ) : measurementRows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Activity className=\"h-10 w-10\" />}\n title=\"No measurements\"\n description={\n measSiteId === ALL && breachFilter === 'ALL'\n ? 'Record a measurement to start building a reading history.'\n : 'No measurements match these filters.'\n }\n action={\n <Button\n onClick={() => {\n setError(null);\n setMeasureOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record measurement\n </Button>\n }\n />\n ) : (\n <>\n <DataTable columns={measurementColumns} rows={measurementRows} rowKey={(m) => m.id} />\n <Pagination\n page={measPager.page}\n pageSize={PAGE_SIZE}\n itemCount={measurementRows.length}\n hasMore={measurementsQuery.data?.pageInfo?.hasMore ?? false}\n onPageChange={(target) =>\n measPager.onPageChange(target, measurementsQuery.data?.pageInfo?.cursor)\n }\n />\n </>\n )}\n </>\n )}\n\n {/* ── Sensors ──────────────────────────────────────────────────────── */}\n {tab === 'sensors' && (\n <>\n <div className=\"mb-5 flex flex-wrap items-center gap-3\">\n <Select value={sensorSiteId} onValueChange={setSensorSiteId}>\n <SelectTrigger className=\"w-52\">\n <SelectValue placeholder=\"All sites\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All sites</SelectItem>\n {siteOptions}\n </SelectContent>\n </Select>\n <Select\n value={sensorStatusFilter}\n onValueChange={(v) => setSensorStatusFilter(v as EcoSensorStatus | 'ALL')}\n >\n <SelectTrigger className=\"w-44\">\n <SelectValue placeholder=\"All statuses\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {SENSOR_STATUSES.map((st) => (\n <SelectItem key={st} value={st}>\n {formatEnumLabel(st)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {sensorsQuery.isLoading ? (\n <LoadingView label=\"Loading sensors…\" />\n ) : sensorsQuery.isError ? (\n <ErrorView message=\"Couldn't load sensors.\" onRetry={() => sensorsQuery.refetch()} />\n ) : sensors.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Radio className=\"h-10 w-10\" />}\n title=\"No sensors\"\n description={\n sensorSiteId === ALL && sensorStatusFilter === ALL\n ? 'Add a sensor to begin streaming or logging readings.'\n : 'No sensors match these filters.'\n }\n action={\n <Button\n onClick={() => {\n setError(null);\n setSensorOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add sensor\n </Button>\n }\n />\n ) : (\n <DataTable columns={sensorColumns} rows={sensors} rowKey={(s) => s.id} />\n )}\n </>\n )}\n\n {/* ── Thresholds ───────────────────────────────────────────────────── */}\n {tab === 'thresholds' && (\n <>\n <div className=\"mb-5 flex flex-wrap items-center gap-3\">\n <Select value={thresholdSiteId} onValueChange={setThresholdSiteId}>\n <SelectTrigger className=\"w-52\">\n <SelectValue placeholder=\"All sites\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All sites</SelectItem>\n {siteOptions}\n </SelectContent>\n </Select>\n </div>\n\n {thresholdsQuery.isLoading ? (\n <LoadingView label=\"Loading thresholds…\" />\n ) : thresholdsQuery.isError ? (\n <ErrorView\n message=\"Couldn't load thresholds.\"\n onRetry={() => thresholdsQuery.refetch()}\n />\n ) : thresholds.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Gauge className=\"h-10 w-10\" />}\n title=\"No thresholds\"\n description={\n thresholdSiteId === ALL\n ? 'Define a threshold to flag readings that drift out of range.'\n : 'This site has no thresholds yet.'\n }\n action={\n <Button\n onClick={() => {\n setError(null);\n setThresholdOpen(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add threshold\n </Button>\n }\n />\n ) : (\n <DataTable columns={thresholdColumns} rows={thresholds} rowKey={(t) => t.id} />\n )}\n </>\n )}\n\n {/* ── Record measurement dialog ────────────────────────────────────── */}\n <ResponsiveDialog\n open={measureOpen}\n onOpenChange={(open) => {\n setMeasureOpen(open);\n if (!open) setError(null);\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Record measurement</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Log a reading. It is checked against the site's active thresholds and flagged if\n it breaches.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"mSite\">Site *</Label>\n <Select\n value={measureForm.siteId}\n onValueChange={(v) => setMeasureForm({ ...measureForm, siteId: v, sensorId: '' })}\n >\n <SelectTrigger id=\"mSite\">\n <SelectValue placeholder=\"Select a site\" />\n </SelectTrigger>\n <SelectContent>{siteOptions}</SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-3\">\n <div className=\"grid gap-1.5 sm:col-span-1\">\n <Label htmlFor=\"mParam\">Parameter *</Label>\n <Input\n id=\"mParam\"\n value={measureForm.parameter}\n onChange={(e) => setMeasureForm({ ...measureForm, parameter: e.target.value })}\n placeholder=\"PM2.5\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"mValue\">Value *</Label>\n <Input\n id=\"mValue\"\n type=\"number\"\n step=\"any\"\n value={measureForm.value}\n onChange={(e) => setMeasureForm({ ...measureForm, value: e.target.value })}\n placeholder=\"42\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"mUnit\">Unit *</Label>\n <Input\n id=\"mUnit\"\n value={measureForm.unit}\n onChange={(e) => setMeasureForm({ ...measureForm, unit: e.target.value })}\n placeholder=\"µg/m³\"\n />\n </div>\n </div>\n {measureForm.siteId && dialogSensorList.length > 0 && (\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"mSensor\">Sensor (optional)</Label>\n <Select\n value={measureForm.sensorId}\n onValueChange={(v) => setMeasureForm({ ...measureForm, sensorId: v })}\n >\n <SelectTrigger id=\"mSensor\">\n <SelectValue placeholder=\"Manual entry\" />\n </SelectTrigger>\n <SelectContent>\n {dialogSensorList.map((s) => (\n <SelectItem key={s.id} value={s.id}>\n {s.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-xs text-text-tertiary\">\n Select a specific sensor for context, or leave blank for a site-level reading.\n </p>\n </div>\n )}\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setMeasureOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleRecordMeasurement} disabled={recordMeasurement.isPending}>\n {recordMeasurement.isPending ? 'Recording…' : 'Record'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* ── Add sensor dialog ────────────────────────────────────────────── */}\n <ResponsiveDialog\n open={sensorOpen}\n onOpenChange={(open) => {\n setSensorOpen(open);\n if (!open) setError(null);\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Add sensor</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Register a sensor and attribute it to a monitored site.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"sSite\">Site *</Label>\n <Select\n value={sensorForm.siteId}\n onValueChange={(v) => setSensorForm({ ...sensorForm, siteId: v })}\n >\n <SelectTrigger id=\"sSite\">\n <SelectValue placeholder=\"Select a site\" />\n </SelectTrigger>\n <SelectContent>{siteOptions}</SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"sName\">Name *</Label>\n <Input\n id=\"sName\"\n value={sensorForm.name}\n onChange={(e) => setSensorForm({ ...sensorForm, name: e.target.value })}\n placeholder=\"North gate PM2.5\"\n />\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"sKind\">Kind</Label>\n <Select\n value={sensorForm.kind}\n onValueChange={(v) => setSensorForm({ ...sensorForm, kind: v as EcoSensorKind })}\n >\n <SelectTrigger id=\"sKind\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SENSOR_KINDS.map((k) => (\n <SelectItem key={k} value={k}>\n {formatEnumLabel(k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"sUnit\">Unit</Label>\n <Input\n id=\"sUnit\"\n value={sensorForm.unit}\n onChange={(e) => setSensorForm({ ...sensorForm, unit: e.target.value })}\n placeholder=\"µg/m³\"\n />\n </div>\n </div>\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setSensorOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleAddSensor} disabled={createSensor.isPending}>\n {createSensor.isPending ? 'Adding…' : 'Add sensor'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* ── Add threshold dialog ─────────────────────────────────────────── */}\n <ResponsiveDialog\n open={thresholdOpen}\n onOpenChange={(open) => {\n setThresholdOpen(open);\n if (!open) setError(null);\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Add alert threshold</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Flag readings that drift out of an acceptable range.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tSite\">Site *</Label>\n <Select\n value={thresholdForm.siteId}\n onValueChange={(v) => setThresholdForm({ ...thresholdForm, siteId: v })}\n >\n <SelectTrigger id=\"tSite\">\n <SelectValue placeholder=\"Select a site\" />\n </SelectTrigger>\n <SelectContent>{siteOptions}</SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tParam\">Parameter *</Label>\n <Input\n id=\"tParam\"\n value={thresholdForm.parameter}\n onChange={(e) =>\n setThresholdForm({ ...thresholdForm, parameter: e.target.value })\n }\n placeholder=\"PM2.5\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tUnit\">Unit *</Label>\n <Input\n id=\"tUnit\"\n value={thresholdForm.unit}\n onChange={(e) => setThresholdForm({ ...thresholdForm, unit: e.target.value })}\n placeholder=\"µg/m³\"\n />\n </div>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tDir\">Direction</Label>\n <Select\n value={thresholdForm.direction}\n onValueChange={(v) =>\n setThresholdForm({ ...thresholdForm, direction: v as EcoThresholdDirection })\n }\n >\n <SelectTrigger id=\"tDir\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {THRESHOLD_DIRECTIONS.map((d) => (\n <SelectItem key={d} value={d}>\n {formatEnumLabel(d)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tSev\">Severity</Label>\n <Select\n value={thresholdForm.severity}\n onValueChange={(v) =>\n setThresholdForm({ ...thresholdForm, severity: v as EcoThresholdSeverity })\n }\n >\n <SelectTrigger id=\"tSev\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {THRESHOLD_SEVERITIES.map((s) => (\n <SelectItem key={s} value={s}>\n {formatEnumLabel(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n {thresholdForm.direction === 'OUTSIDE_RANGE' ? (\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tMin\">Min value</Label>\n <Input\n id=\"tMin\"\n type=\"number\"\n step=\"any\"\n value={thresholdForm.minValue}\n onChange={(e) =>\n setThresholdForm({ ...thresholdForm, minValue: e.target.value })\n }\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tMax\">Max value</Label>\n <Input\n id=\"tMax\"\n type=\"number\"\n step=\"any\"\n value={thresholdForm.maxValue}\n onChange={(e) =>\n setThresholdForm({ ...thresholdForm, maxValue: e.target.value })\n }\n />\n </div>\n </div>\n ) : (\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"tLimit\">Limit value</Label>\n <Input\n id=\"tLimit\"\n type=\"number\"\n step=\"any\"\n value={thresholdForm.limitValue}\n onChange={(e) =>\n setThresholdForm({ ...thresholdForm, limitValue: e.target.value })\n }\n placeholder=\"35\"\n />\n </div>\n )}\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setThresholdOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleAddThreshold} disabled={createThreshold.isPending}>\n {createThreshold.isPending ? 'Adding…' : 'Add threshold'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReportsPage.d.ts","sourceRoot":"","sources":["../../../../src/ecoimpacthub/pages/reports/ReportsPage.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"ReportsPage.d.ts","sourceRoot":"","sources":["../../../../src/ecoimpacthub/pages/reports/ReportsPage.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwEH,wBAAgB,WAAW,4CAoP1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReportsPage.js","names":[],"sources":["../../../../src/ecoimpacthub/pages/reports/ReportsPage.tsx"],"sourcesContent":["/**\n * ESG Reports — list, filter, and draft sustainability disclosures.\n * @module ecoimpacthub/pages/reports\n *\n * Reads `ecoListReports`; writes `ecoCreateReport`.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Plus, FileText } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { DataTable, type Column } from '../../components/DataTable';\nimport { FilterTabs, type FilterOption } from '../../components/FilterTabs';\nimport { FrameworkBadge } from '../badges';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { Pagination } from '../../components/Pagination';\nimport { useEcoImpactHub } from '../../context';\nimport { useEcoReports, useEcoCreateReport, useCursorPager } from '../../hooks';\nimport { formatDate, formatEnumLabel, formatRelativeTime } from '../../utils/formatters';\nimport type { EcoReport, EcoReportStatus, EcoReportFramework } from '../../types';\n\nconst STATUS_FILTERS: FilterOption<EcoReportStatus | 'ALL'>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'DRAFT', label: 'Draft' },\n { value: 'IN_REVIEW', label: 'In review' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nconst FRAMEWORKS: EcoReportFramework[] = ['GHG_PROTOCOL', 'GRI', 'TCFD', 'CDP', 'SASB', 'CUSTOM'];\n\nconst PAGE_SIZE = 25;\n\ninterface CreateFormState {\n title: string;\n framework: EcoReportFramework;\n periodStart: string;\n periodEnd: string;\n summary: string;\n}\n\nconst EMPTY_FORM: CreateFormState = {\n title: '',\n framework: 'GHG_PROTOCOL',\n periodStart: '',\n periodEnd: '',\n summary: '',\n};\n\nexport function ReportsPage() {\n const { navigateTo } = useEcoImpactHub();\n const [status, setStatus] = useState<EcoReportStatus | 'ALL'>('ALL');\n const pager = useCursorPager();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<CreateFormState>(EMPTY_FORM);\n const [formError, setFormError] = useState<string | null>(null);\n\n const { data, isLoading, isError, refetch } = useEcoReports(\n status === 'ALL' ? undefined : status,\n { limit: PAGE_SIZE, cursor: pager.cursor }\n );\n const createReport = useEcoCreateReport();\n\n const rows = useMemo(() => data?.items ?? [], [data]);\n\n const columns: Column<EcoReport>[] = [\n {\n key: 'title',\n header: 'Report',\n render: (r) => <p className=\"font-semibold text-text-primary\">{r.title}</p>,\n },\n {\n key: 'framework',\n header: 'Framework',\n hideOnMobile: true,\n render: (r) => <FrameworkBadge framework={r.framework} />,\n },\n {\n key: 'status',\n header: 'Status',\n render: (r) => <StatusBadge status={r.status} />,\n },\n {\n key: 'period',\n header: 'Period',\n hideOnMobile: true,\n render: (r) => (\n <span className=\"whitespace-nowrap text-text-secondary tabular-nums\">\n {formatDate(r.periodStart)} – {formatDate(r.periodEnd)}\n </span>\n ),\n },\n {\n key: 'published',\n header: 'Published',\n hideOnMobile: true,\n render: (r) =>\n r.publishedAt ? (\n <span className=\"whitespace-nowrap text-text-secondary\">{formatDate(r.publishedAt)}</span>\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'updated',\n header: 'Updated',\n align: 'right',\n hideOnMobile: true,\n render: (r) => <span className=\"text-text-tertiary\">{formatRelativeTime(r.updatedAt)}</span>,\n },\n ];\n\n const resetForm = () => {\n setForm(EMPTY_FORM);\n setFormError(null);\n };\n\n const handleCreate = async () => {\n if (!form.title.trim()) {\n setFormError('Report title is required.');\n return;\n }\n if (!form.periodStart || !form.periodEnd) {\n setFormError('Reporting period start and end are required.');\n return;\n }\n try {\n const created = await createReport.mutateAsync({\n title: form.title.trim(),\n framework: form.framework,\n periodStart: form.periodStart,\n periodEnd: form.periodEnd,\n summary: form.summary.trim() || null,\n });\n setDialogOpen(false);\n resetForm();\n navigateTo(`reports/${created.id}`);\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to create report.');\n }\n };\n\n return (\n <PageLayout\n title=\"ESG Reports\"\n description=\"Sustainability disclosures — draft, review & publish GHG Protocol, GRI, TCFD, CDP & SASB reports.\"\n actions={\n <Button onClick={() => setDialogOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New report\n </Button>\n }\n >\n <div className=\"mb-5 flex flex-wrap items-center gap-3\">\n <FilterTabs\n options={STATUS_FILTERS}\n value={status}\n onChange={(v) => {\n setStatus(v);\n pager.reset();\n }}\n />\n </div>\n\n {isLoading ? (\n <LoadingView label=\"Loading reports…\" />\n ) : isError ? (\n <ErrorView message=\"Couldn't load reports.\" onRetry={() => refetch()} />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<FileText className=\"h-10 w-10\" />}\n title=\"No reports yet\"\n description={\n status === 'ALL'\n ? 'Draft your first ESG report to compile disclosures against a reporting framework.'\n : 'No reports match this filter.'\n }\n action={\n <Button onClick={() => setDialogOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New report\n </Button>\n }\n />\n ) : (\n <>\n <DataTable\n columns={columns}\n rows={rows}\n rowKey={(r) => r.id}\n onRowClick={(r) => navigateTo(`reports/${r.id}`)}\n />\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={data?.pageInfo?.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo?.cursor)}\n />\n </>\n )}\n\n <ResponsiveDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n setDialogOpen(open);\n if (!open) resetForm();\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>New report</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Start a sustainability disclosure for a reporting period and framework.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"title\">Title *</Label>\n <Input\n id=\"title\"\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n placeholder=\"FY2026 Sustainability Report\"\n />\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"framework\">Framework</Label>\n <Select\n value={form.framework}\n onValueChange={(v) => setForm({ ...form, framework: v as EcoReportFramework })}\n >\n <SelectTrigger id=\"framework\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {FRAMEWORKS.map((f) => (\n <SelectItem key={f} value={f}>\n {formatEnumLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"periodStart\">Period start *</Label>\n <Input\n id=\"periodStart\"\n type=\"date\"\n value={form.periodStart}\n onChange={(e) => setForm({ ...form, periodStart: e.target.value })}\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"periodEnd\">Period end *</Label>\n <Input\n id=\"periodEnd\"\n type=\"date\"\n value={form.periodEnd}\n onChange={(e) => setForm({ ...form, periodEnd: e.target.value })}\n />\n </div>\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"summary\">Summary</Label>\n <Textarea\n id=\"summary\"\n value={form.summary}\n onChange={(e) => setForm({ ...form, summary: e.target.value })}\n placeholder=\"Optional executive summary or scope note for this report.\"\n rows={3}\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setDialogOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleCreate} disabled={createReport.isPending}>\n {createReport.isPending ? 'Creating…' : 'Create report'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ReportsPage.js","names":[],"sources":["../../../../src/ecoimpacthub/pages/reports/ReportsPage.tsx"],"sourcesContent":["/**\n * ESG Reports — list, filter, and draft sustainability disclosures.\n * @module ecoimpacthub/pages/reports\n *\n * Reads `ecoListReports`; writes `ecoCreateReport`.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Plus, FileText } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { DataTable, type Column } from '../../components/DataTable';\nimport { FilterTabs, type FilterOption } from '../../components/FilterTabs';\nimport { FrameworkBadge } from '../badges';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { Pagination } from '../../components/Pagination';\nimport { useEcoImpactHub } from '../../context';\nimport { useEcoReports, useEcoCreateReport, useCursorPager } from '../../hooks';\nimport { formatDate, formatEnumLabel, formatRelativeTime } from '../../utils/formatters';\nimport type { EcoReport, EcoReportStatus, EcoReportFramework } from '../../types';\n\nconst STATUS_FILTERS: FilterOption<EcoReportStatus | 'ALL'>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'DRAFT', label: 'Draft' },\n { value: 'IN_REVIEW', label: 'In review' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nconst FRAMEWORKS: EcoReportFramework[] = [\n 'GHG_PROTOCOL',\n 'GRI',\n 'TCFD',\n 'CDP',\n 'SASB',\n 'CSRD',\n 'ISSB',\n 'EU_TAXONOMY',\n 'CUSTOM',\n];\n\nconst PAGE_SIZE = 25;\n\ninterface CreateFormState {\n title: string;\n framework: EcoReportFramework;\n periodStart: string;\n periodEnd: string;\n summary: string;\n}\n\nconst EMPTY_FORM: CreateFormState = {\n title: '',\n framework: 'GHG_PROTOCOL',\n periodStart: '',\n periodEnd: '',\n summary: '',\n};\n\nexport function ReportsPage() {\n const { navigateTo } = useEcoImpactHub();\n const [status, setStatus] = useState<EcoReportStatus | 'ALL'>('ALL');\n const pager = useCursorPager();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<CreateFormState>(EMPTY_FORM);\n const [formError, setFormError] = useState<string | null>(null);\n\n const { data, isLoading, isError, refetch } = useEcoReports(\n status === 'ALL' ? undefined : status,\n { limit: PAGE_SIZE, cursor: pager.cursor }\n );\n const createReport = useEcoCreateReport();\n\n const rows = useMemo(() => data?.items ?? [], [data]);\n\n const columns: Column<EcoReport>[] = [\n {\n key: 'title',\n header: 'Report',\n render: (r) => <p className=\"font-semibold text-text-primary\">{r.title}</p>,\n },\n {\n key: 'framework',\n header: 'Framework',\n hideOnMobile: true,\n render: (r) => <FrameworkBadge framework={r.framework} />,\n },\n {\n key: 'status',\n header: 'Status',\n render: (r) => <StatusBadge status={r.status} />,\n },\n {\n key: 'period',\n header: 'Period',\n hideOnMobile: true,\n render: (r) => (\n <span className=\"whitespace-nowrap text-text-secondary tabular-nums\">\n {formatDate(r.periodStart)} – {formatDate(r.periodEnd)}\n </span>\n ),\n },\n {\n key: 'published',\n header: 'Published',\n hideOnMobile: true,\n render: (r) =>\n r.publishedAt ? (\n <span className=\"whitespace-nowrap text-text-secondary\">{formatDate(r.publishedAt)}</span>\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'updated',\n header: 'Updated',\n align: 'right',\n hideOnMobile: true,\n render: (r) => <span className=\"text-text-tertiary\">{formatRelativeTime(r.updatedAt)}</span>,\n },\n ];\n\n const resetForm = () => {\n setForm(EMPTY_FORM);\n setFormError(null);\n };\n\n const handleCreate = async () => {\n if (!form.title.trim()) {\n setFormError('Report title is required.');\n return;\n }\n if (!form.periodStart || !form.periodEnd) {\n setFormError('Reporting period start and end are required.');\n return;\n }\n try {\n const created = await createReport.mutateAsync({\n title: form.title.trim(),\n framework: form.framework,\n periodStart: form.periodStart,\n periodEnd: form.periodEnd,\n summary: form.summary.trim() || null,\n });\n setDialogOpen(false);\n resetForm();\n navigateTo(`reports/${created.id}`);\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to create report.');\n }\n };\n\n return (\n <PageLayout\n title=\"ESG Reports\"\n description=\"Sustainability disclosures — draft, review & publish GHG Protocol, GRI, TCFD, CDP & SASB reports.\"\n actions={\n <Button onClick={() => setDialogOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New report\n </Button>\n }\n >\n <div className=\"mb-5 flex flex-wrap items-center gap-3\">\n <FilterTabs\n options={STATUS_FILTERS}\n value={status}\n onChange={(v) => {\n setStatus(v);\n pager.reset();\n }}\n />\n </div>\n\n {isLoading ? (\n <LoadingView label=\"Loading reports…\" />\n ) : isError ? (\n <ErrorView message=\"Couldn't load reports.\" onRetry={() => refetch()} />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<FileText className=\"h-10 w-10\" />}\n title=\"No reports yet\"\n description={\n status === 'ALL'\n ? 'Draft your first ESG report to compile disclosures against a reporting framework.'\n : 'No reports match this filter.'\n }\n action={\n <Button onClick={() => setDialogOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New report\n </Button>\n }\n />\n ) : (\n <>\n <DataTable\n columns={columns}\n rows={rows}\n rowKey={(r) => r.id}\n onRowClick={(r) => navigateTo(`reports/${r.id}`)}\n />\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={data?.pageInfo?.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo?.cursor)}\n />\n </>\n )}\n\n <ResponsiveDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n setDialogOpen(open);\n if (!open) resetForm();\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>New report</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Start a sustainability disclosure for a reporting period and framework.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"title\">Title *</Label>\n <Input\n id=\"title\"\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n placeholder=\"FY2026 Sustainability Report\"\n />\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"framework\">Framework</Label>\n <Select\n value={form.framework}\n onValueChange={(v) => setForm({ ...form, framework: v as EcoReportFramework })}\n >\n <SelectTrigger id=\"framework\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {FRAMEWORKS.map((f) => (\n <SelectItem key={f} value={f}>\n {formatEnumLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"periodStart\">Period start *</Label>\n <Input\n id=\"periodStart\"\n type=\"date\"\n value={form.periodStart}\n onChange={(e) => setForm({ ...form, periodStart: e.target.value })}\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"periodEnd\">Period end *</Label>\n <Input\n id=\"periodEnd\"\n type=\"date\"\n value={form.periodEnd}\n onChange={(e) => setForm({ ...form, periodEnd: e.target.value })}\n />\n </div>\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"summary\">Summary</Label>\n <Textarea\n id=\"summary\"\n value={form.summary}\n onChange={(e) => setForm({ ...form, summary: e.target.value })}\n placeholder=\"Optional executive summary or scope note for this report.\"\n rows={3}\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setDialogOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleCreate} disabled={createReport.isPending}>\n {createReport.isPending ? 'Creating…' : 'Create report'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -91,7 +91,7 @@ export type EcoRestorationActivityType = 'PLANTING' | 'INVASIVE_REMOVAL' | 'REWI
|
|
|
91
91
|
export type EcoEmissionScope = 'SCOPE_1' | 'SCOPE_2' | 'SCOPE_3';
|
|
92
92
|
export type EcoCarbonEntryStatus = 'DRAFT' | 'RECORDED' | 'VERIFIED' | 'ADJUSTED';
|
|
93
93
|
export type EcoReportStatus = 'DRAFT' | 'IN_REVIEW' | 'PUBLISHED' | 'ARCHIVED';
|
|
94
|
-
export type EcoReportFramework = 'GHG_PROTOCOL' | 'GRI' | 'TCFD' | 'CDP' | 'SASB' | 'CUSTOM';
|
|
94
|
+
export type EcoReportFramework = 'GHG_PROTOCOL' | 'GRI' | 'TCFD' | 'CDP' | 'SASB' | 'CSRD' | 'ISSB' | 'EU_TAXONOMY' | 'CUSTOM';
|
|
95
95
|
export type EcoReductionTargetStatus = 'PROPOSED' | 'ACTIVE' | 'ACHIEVED' | 'MISSED' | 'RETIRED';
|
|
96
96
|
export interface EcoSite {
|
|
97
97
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ecoimpacthub/types/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ecoimpacthub/types/index.ts"],"names":[],"mappings":"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"}
|