@burdenoff/microfe-ecoimpacthub 2026.819.4 → 2026.830.1
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/index.d.ts +2 -0
- package/dist/ecoimpacthub/hooks/index.d.ts.map +1 -1
- package/dist/ecoimpacthub/hooks/index.js +2 -0
- package/dist/ecoimpacthub/hooks/useActiveEcoEntity.d.ts +11 -0
- package/dist/ecoimpacthub/hooks/useActiveEcoEntity.d.ts.map +1 -0
- package/dist/ecoimpacthub/hooks/useActiveEcoEntity.js +21 -0
- package/dist/ecoimpacthub/hooks/useActiveEcoEntity.js.map +1 -0
- package/dist/ecoimpacthub/hooks/useTr.d.ts +4 -0
- package/dist/ecoimpacthub/hooks/useTr.d.ts.map +1 -0
- package/dist/ecoimpacthub/hooks/useTr.js +20 -0
- package/dist/ecoimpacthub/hooks/useTr.js.map +1 -0
- package/dist/ecoimpacthub/pages/DashboardPage.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/DashboardPage.js +162 -138
- package/dist/ecoimpacthub/pages/DashboardPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/_shared/MethodPicker.d.ts +15 -0
- package/dist/ecoimpacthub/pages/_shared/MethodPicker.d.ts.map +1 -0
- package/dist/ecoimpacthub/pages/_shared/MethodPicker.js +36 -0
- package/dist/ecoimpacthub/pages/_shared/MethodPicker.js.map +1 -0
- package/dist/ecoimpacthub/pages/_shared/UseMyLocationButton.d.ts +15 -0
- package/dist/ecoimpacthub/pages/_shared/UseMyLocationButton.d.ts.map +1 -0
- package/dist/ecoimpacthub/pages/_shared/UseMyLocationButton.js +66 -0
- package/dist/ecoimpacthub/pages/_shared/UseMyLocationButton.js.map +1 -0
- package/dist/ecoimpacthub/pages/habitat/HabitatProjectDetailPage.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/habitat/HabitatProjectDetailPage.js +127 -124
- package/dist/ecoimpacthub/pages/habitat/HabitatProjectDetailPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/observations/ObservationsPage.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/observations/ObservationsPage.js +226 -224
- package/dist/ecoimpacthub/pages/observations/ObservationsPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/reports/ReportDetailPage.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/reports/ReportDetailPage.js +159 -156
- package/dist/ecoimpacthub/pages/reports/ReportDetailPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/sites/SiteDetailPage.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/sites/SiteDetailPage.js +40 -37
- package/dist/ecoimpacthub/pages/sites/SiteDetailPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/sites/SitesPage.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/sites/SitesPage.js +208 -171
- package/dist/ecoimpacthub/pages/sites/SitesPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/species/SpeciesDetailPage.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/species/SpeciesDetailPage.js +211 -214
- package/dist/ecoimpacthub/pages/species/SpeciesDetailPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/species/SpeciesPage.d.ts.map +1 -1
- package/dist/ecoimpacthub/pages/species/SpeciesPage.js +174 -157
- package/dist/ecoimpacthub/pages/species/SpeciesPage.js.map +1 -1
- package/dist/ecoimpacthub/utils/activeEntity.d.ts +30 -0
- package/dist/ecoimpacthub/utils/activeEntity.d.ts.map +1 -0
- package/dist/ecoimpacthub/utils/activeEntity.js +12 -0
- package/dist/ecoimpacthub/utils/activeEntity.js.map +1 -0
- package/dist/ecoimpacthub/utils/pageContext.d.ts.map +1 -1
- package/dist/ecoimpacthub/utils/pageContext.js +30 -25
- package/dist/ecoimpacthub/utils/pageContext.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReportDetailPage.js","names":[],"sources":["../../../../src/ecoimpacthub/pages/reports/ReportDetailPage.tsx"],"sourcesContent":["/**\n * Report detail — overview, line items (with total) & disclosure actions.\n * @module ecoimpacthub/pages/reports\n *\n * Reads `ecoReport` (+ nested lineItems); writes `ecoAddReportLineItem`,\n * `ecoPublishReport`. The hero pairs a fact-rich overview with an actions card;\n * line items render as a crisp table whose footer carries the running TOTAL, and\n * a discussion thread (platform EntityComment API) sits below.\n */\n\nimport { useMemo, useState, type ReactNode } from 'react';\nimport { useParams } from 'react-router';\nimport { ArrowLeft, ListPlus, Send } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n GlassCard,\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 { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { EvidenceUpload } from '../../components/EvidenceUpload';\nimport { FileLink } from '../../components/FileLink';\nimport { EcoDiscussion } from '../../components/EcoDiscussion';\nimport { useEcoImpactHub } from '../../context';\nimport {\n useEcoReport,\n useEcoAddReportLineItem,\n useEcoPublishReport,\n type UploadedEcoFile,\n} from '../../hooks';\nimport { formatDate, formatNumber } from '../../utils/formatters';\nimport { FrameworkBadge } from '../badges';\n\n/** A labelled key/value cell for the overview grid. */\nfunction Fact({ label, children }: { label: string; children: ReactNode }) {\n return (\n <div>\n <dt className=\"text-xs text-text-tertiary\">{label}</dt>\n <dd className=\"mt-1 text-sm text-text-primary\">{children}</dd>\n </div>\n );\n}\n\nexport function ReportDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useEcoImpactHub();\n const { data: report, isLoading, isError, refetch } = useEcoReport(id);\n\n const addLineItem = useEcoAddReportLineItem();\n const publishReport = useEcoPublishReport();\n\n const [lineItemOpen, setLineItemOpen] = useState(false);\n const [lineItemForm, setLineItemForm] = useState({\n label: '',\n value: '',\n unit: '',\n category: '',\n carbonEntryId: '',\n });\n const [error, setError] = useState<string | null>(null);\n const [attachment, setAttachment] = useState<UploadedEcoFile | null>(null);\n\n const lineItems = useMemo(() => report?.lineItems ?? [], [report]);\n const total = useMemo(() => lineItems.reduce((sum, li) => sum + li.value, 0), [lineItems]);\n const totalUnit = useMemo(() => {\n const units = new Set(lineItems.map((li) => li.unit));\n return units.size === 1 ? [...units][0] : null;\n }, [lineItems]);\n\n if (isLoading) {\n return (\n <PageLayout title=\"Report\">\n <LoadingView />\n </PageLayout>\n );\n }\n if (isError || !report) {\n return (\n <PageLayout title=\"Report\">\n <ErrorView message=\"This report could not be loaded.\" onRetry={() => refetch()} />\n </PageLayout>\n );\n }\n\n const isPublished = report.status === 'PUBLISHED';\n\n const handleAddLineItem = async () => {\n if (!id) return;\n if (!lineItemForm.label.trim() || !lineItemForm.value || !lineItemForm.unit.trim()) {\n setError('Label, value and unit are required.');\n return;\n }\n setError(null);\n try {\n await addLineItem.mutateAsync({\n reportId: id,\n label: lineItemForm.label.trim(),\n value: Number(lineItemForm.value),\n unit: lineItemForm.unit.trim(),\n category: lineItemForm.category.trim() || null,\n carbonEntryId: lineItemForm.carbonEntryId.trim() || null,\n });\n setLineItemOpen(false);\n setLineItemForm({ label: '', value: '', unit: '', category: '', carbonEntryId: '' });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add line item.');\n }\n };\n\n const handlePublish = async () => {\n if (!id) return;\n setError(null);\n try {\n await publishReport.mutateAsync({ id, fileId: attachment?.fileId ?? null });\n setAttachment(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to publish report.');\n }\n };\n\n return (\n <PageLayout\n title={\n <span className=\"flex flex-wrap items-center gap-x-3 gap-y-2\">\n <span className=\"text-text-primary\">{report.title}</span>\n <FrameworkBadge framework={report.framework} />\n </span>\n }\n description={`Reporting period ${formatDate(report.periodStart)} – ${formatDate(report.periodEnd)}`}\n actions={\n <>\n <StatusBadge status={report.status} />\n <Button variant=\"ghost\" onClick={() => navigateTo('reports')}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" /> Back\n </Button>\n </>\n }\n >\n {/* Overview + actions */}\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <GlassCard treatment=\"glass\" className=\"p-6 lg:col-span-2\">\n <dl className=\"grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-3\">\n <Fact label=\"Framework\">\n <FrameworkBadge framework={report.framework} />\n </Fact>\n <Fact label=\"Status\">\n <StatusBadge status={report.status} />\n </Fact>\n <Fact label=\"Period\">\n <span className=\"tabular-nums\">\n {formatDate(report.periodStart)} – {formatDate(report.periodEnd)}\n </span>\n </Fact>\n <Fact label=\"Published\">{formatDate(report.publishedAt)}</Fact>\n <Fact label=\"Line items\">\n <span className=\"tabular-nums\">{lineItems.length}</span>\n </Fact>\n <Fact label=\"Attachment\">\n {report.file?.id ? (\n <FileLink fileId={report.file.id} />\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n )}\n </Fact>\n </dl>\n {report.summary && (\n <p className=\"mt-5 rounded-lg bg-bg-sunken/60 p-3 text-sm text-text-secondary\">\n {report.summary}\n </p>\n )}\n </GlassCard>\n\n <GlassCard treatment=\"glass\" className=\"flex flex-col gap-3 p-6\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-tertiary\">Actions</p>\n <Button onClick={() => setLineItemOpen(true)}>\n <ListPlus className=\"mr-1.5 h-4 w-4\" /> Add line item\n </Button>\n {isPublished ? (\n <p className=\"mt-1 text-sm text-text-secondary\">\n Published {formatDate(report.publishedAt)}. This disclosure is finalised.\n </p>\n ) : (\n <>\n <EvidenceUpload\n id=\"reportAttachment\"\n label=\"Attach file (optional)\"\n value={attachment}\n onChange={setAttachment}\n hint=\"Attach the signed report PDF or supporting document, then publish.\"\n />\n <Button variant=\"outline\" onClick={handlePublish} disabled={publishReport.isPending}>\n <Send className=\"mr-1.5 h-4 w-4\" />\n {publishReport.isPending ? 'Publishing…' : 'Publish report'}\n </Button>\n </>\n )}\n </GlassCard>\n </div>\n\n {error && <p className=\"mt-4 text-sm text-status-error-text\">{error}</p>}\n\n {/* Line items */}\n <Section\n title=\"Line items\"\n description=\"Quantified disclosures that make up this report.\"\n action={\n <Button size=\"sm\" onClick={() => setLineItemOpen(true)}>\n <ListPlus className=\"mr-1.5 h-4 w-4\" /> Add line item\n </Button>\n }\n >\n {lineItems.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No line items\"\n description=\"Add a line item to record a quantified disclosure for this report.\"\n action={\n <Button size=\"sm\" onClick={() => setLineItemOpen(true)}>\n <ListPlus className=\"mr-1.5 h-4 w-4\" /> Add line item\n </Button>\n }\n />\n ) : (\n <GlassCard treatment=\"plain\" className=\"overflow-hidden\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full border-collapse text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left\">\n <th className=\"px-4 py-3 font-medium text-text-secondary\">Line item</th>\n <th className=\"hidden px-4 py-3 font-medium text-text-secondary md:table-cell\">\n Category\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-text-secondary\">Value</th>\n </tr>\n </thead>\n <tbody>\n {lineItems.map((li) => (\n <tr key={li.id} className=\"border-b border-border-seam/60\">\n <td className=\"px-4 py-3 font-medium text-text-primary\">{li.label}</td>\n <td className=\"hidden px-4 py-3 text-text-secondary md:table-cell\">\n {li.category ?? '—'}\n </td>\n <td className=\"px-4 py-3 text-right text-text-primary tabular-nums\">\n {formatNumber(li.value)} {li.unit}\n </td>\n </tr>\n ))}\n </tbody>\n <tfoot>\n <tr className=\"border-t-2 border-border-seam bg-bg-sunken/40\">\n <td className=\"px-4 py-3 text-sm font-semibold text-text-primary\" colSpan={2}>\n Total\n </td>\n <td className=\"px-4 py-3 text-right text-base font-bold text-text-primary tabular-nums\">\n {formatNumber(total)}\n {totalUnit ? ` ${totalUnit}` : ''}\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </GlassCard>\n )}\n </Section>\n\n {/* Discussion — reuses the platform EntityComment API (no eco-svc change) */}\n <EcoDiscussion\n entityType=\"ecoimpacthub-report\"\n entityId={report.id}\n description=\"Coordinate review and sign-off on this disclosure with your team.\"\n />\n\n {/* Add line item dialog */}\n <ResponsiveDialog open={lineItemOpen} onOpenChange={setLineItemOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Add line item</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Record a quantified disclosure for {report.title}.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liLabel\">Label *</Label>\n <Input\n id=\"liLabel\"\n value={lineItemForm.label}\n onChange={(e) => setLineItemForm({ ...lineItemForm, label: e.target.value })}\n placeholder=\"Scope 1 emissions\"\n />\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liValue\">Value *</Label>\n <Input\n id=\"liValue\"\n type=\"number\"\n step=\"any\"\n value={lineItemForm.value}\n onChange={(e) => setLineItemForm({ ...lineItemForm, value: e.target.value })}\n placeholder=\"1250\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liUnit\">Unit *</Label>\n <Input\n id=\"liUnit\"\n value={lineItemForm.unit}\n onChange={(e) => setLineItemForm({ ...lineItemForm, unit: e.target.value })}\n placeholder=\"t CO₂e\"\n />\n </div>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liCategory\">Category</Label>\n <Input\n id=\"liCategory\"\n value={lineItemForm.category}\n onChange={(e) => setLineItemForm({ ...lineItemForm, category: e.target.value })}\n placeholder=\"Optional grouping, e.g. Energy\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liCarbonEntry\">Carbon entry ID</Label>\n <Input\n id=\"liCarbonEntry\"\n value={lineItemForm.carbonEntryId}\n onChange={(e) =>\n setLineItemForm({ ...lineItemForm, carbonEntryId: e.target.value })\n }\n placeholder=\"Optional linked carbon-ledger entry\"\n />\n </div>\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setLineItemOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleAddLineItem} disabled={addLineItem.isPending}>\n {addLineItem.isPending ? 'Adding…' : 'Add line item'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ReportDetailPage.js","names":[],"sources":["../../../../src/ecoimpacthub/pages/reports/ReportDetailPage.tsx"],"sourcesContent":["/**\n * Report detail — overview, line items (with total) & disclosure actions.\n * @module ecoimpacthub/pages/reports\n *\n * Reads `ecoReport` (+ nested lineItems); writes `ecoAddReportLineItem`,\n * `ecoPublishReport`. The hero pairs a fact-rich overview with an actions card;\n * line items render as a crisp table whose footer carries the running TOTAL, and\n * a discussion thread (platform EntityComment API) sits below.\n */\n\nimport { useMemo, useState, type ReactNode } from 'react';\nimport { useParams } from 'react-router';\nimport { ArrowLeft, ListPlus, Send } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n GlassCard,\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 { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { EvidenceUpload } from '../../components/EvidenceUpload';\nimport { FileLink } from '../../components/FileLink';\nimport { EcoDiscussion } from '../../components/EcoDiscussion';\nimport { useEcoImpactHub } from '../../context';\nimport {\n useEcoReport,\n useEcoAddReportLineItem,\n useEcoPublishReport,\n useActiveEcoEntity,\n type UploadedEcoFile,\n} from '../../hooks';\nimport { formatDate, formatNumber } from '../../utils/formatters';\nimport { FrameworkBadge } from '../badges';\n\n/** A labelled key/value cell for the overview grid. */\nfunction Fact({ label, children }: { label: string; children: ReactNode }) {\n return (\n <div>\n <dt className=\"text-xs text-text-tertiary\">{label}</dt>\n <dd className=\"mt-1 text-sm text-text-primary\">{children}</dd>\n </div>\n );\n}\n\nexport function ReportDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useEcoImpactHub();\n const { data: report, isLoading, isError, refetch } = useEcoReport(id);\n\n // Let the assistant refer to this record by name (see utils/activeEntity).\n useActiveEcoEntity(report?.id, report?.title);\n\n const addLineItem = useEcoAddReportLineItem();\n const publishReport = useEcoPublishReport();\n\n const [lineItemOpen, setLineItemOpen] = useState(false);\n const [lineItemForm, setLineItemForm] = useState({\n label: '',\n value: '',\n unit: '',\n category: '',\n carbonEntryId: '',\n });\n const [error, setError] = useState<string | null>(null);\n const [attachment, setAttachment] = useState<UploadedEcoFile | null>(null);\n\n const lineItems = useMemo(() => report?.lineItems ?? [], [report]);\n const total = useMemo(() => lineItems.reduce((sum, li) => sum + li.value, 0), [lineItems]);\n const totalUnit = useMemo(() => {\n const units = new Set(lineItems.map((li) => li.unit));\n return units.size === 1 ? [...units][0] : null;\n }, [lineItems]);\n\n if (isLoading) {\n return (\n <PageLayout title=\"Report\">\n <LoadingView />\n </PageLayout>\n );\n }\n if (isError || !report) {\n return (\n <PageLayout title=\"Report\">\n <ErrorView message=\"This report could not be loaded.\" onRetry={() => refetch()} />\n </PageLayout>\n );\n }\n\n const isPublished = report.status === 'PUBLISHED';\n\n const handleAddLineItem = async () => {\n if (!id) return;\n if (!lineItemForm.label.trim() || !lineItemForm.value || !lineItemForm.unit.trim()) {\n setError('Label, value and unit are required.');\n return;\n }\n setError(null);\n try {\n await addLineItem.mutateAsync({\n reportId: id,\n label: lineItemForm.label.trim(),\n value: Number(lineItemForm.value),\n unit: lineItemForm.unit.trim(),\n category: lineItemForm.category.trim() || null,\n carbonEntryId: lineItemForm.carbonEntryId.trim() || null,\n });\n setLineItemOpen(false);\n setLineItemForm({ label: '', value: '', unit: '', category: '', carbonEntryId: '' });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add line item.');\n }\n };\n\n const handlePublish = async () => {\n if (!id) return;\n setError(null);\n try {\n await publishReport.mutateAsync({ id, fileId: attachment?.fileId ?? null });\n setAttachment(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to publish report.');\n }\n };\n\n return (\n <PageLayout\n title={\n <span className=\"flex flex-wrap items-center gap-x-3 gap-y-2\">\n <span className=\"text-text-primary\">{report.title}</span>\n <FrameworkBadge framework={report.framework} />\n </span>\n }\n description={`Reporting period ${formatDate(report.periodStart)} – ${formatDate(report.periodEnd)}`}\n actions={\n <>\n <StatusBadge status={report.status} />\n <Button variant=\"ghost\" onClick={() => navigateTo('reports')}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" /> Back\n </Button>\n </>\n }\n >\n {/* Overview + actions */}\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <GlassCard treatment=\"glass\" className=\"p-6 lg:col-span-2\">\n <dl className=\"grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-3\">\n <Fact label=\"Framework\">\n <FrameworkBadge framework={report.framework} />\n </Fact>\n <Fact label=\"Status\">\n <StatusBadge status={report.status} />\n </Fact>\n <Fact label=\"Period\">\n <span className=\"tabular-nums\">\n {formatDate(report.periodStart)} – {formatDate(report.periodEnd)}\n </span>\n </Fact>\n <Fact label=\"Published\">{formatDate(report.publishedAt)}</Fact>\n <Fact label=\"Line items\">\n <span className=\"tabular-nums\">{lineItems.length}</span>\n </Fact>\n <Fact label=\"Attachment\">\n {report.file?.id ? (\n <FileLink fileId={report.file.id} />\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n )}\n </Fact>\n </dl>\n {report.summary && (\n <p className=\"mt-5 rounded-lg bg-bg-sunken/60 p-3 text-sm text-text-secondary\">\n {report.summary}\n </p>\n )}\n </GlassCard>\n\n <GlassCard treatment=\"glass\" className=\"flex flex-col gap-3 p-6\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-tertiary\">Actions</p>\n <Button onClick={() => setLineItemOpen(true)}>\n <ListPlus className=\"mr-1.5 h-4 w-4\" /> Add line item\n </Button>\n {isPublished ? (\n <p className=\"mt-1 text-sm text-text-secondary\">\n Published {formatDate(report.publishedAt)}. This disclosure is finalised.\n </p>\n ) : (\n <>\n <EvidenceUpload\n id=\"reportAttachment\"\n label=\"Attach file (optional)\"\n value={attachment}\n onChange={setAttachment}\n hint=\"Attach the signed report PDF or supporting document, then publish.\"\n />\n <Button variant=\"outline\" onClick={handlePublish} disabled={publishReport.isPending}>\n <Send className=\"mr-1.5 h-4 w-4\" />\n {publishReport.isPending ? 'Publishing…' : 'Publish report'}\n </Button>\n </>\n )}\n </GlassCard>\n </div>\n\n {error && <p className=\"mt-4 text-sm text-status-error-text\">{error}</p>}\n\n {/* Line items */}\n <Section\n title=\"Line items\"\n description=\"Quantified disclosures that make up this report.\"\n action={\n <Button size=\"sm\" onClick={() => setLineItemOpen(true)}>\n <ListPlus className=\"mr-1.5 h-4 w-4\" /> Add line item\n </Button>\n }\n >\n {lineItems.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No line items\"\n description=\"Add a line item to record a quantified disclosure for this report.\"\n action={\n <Button size=\"sm\" onClick={() => setLineItemOpen(true)}>\n <ListPlus className=\"mr-1.5 h-4 w-4\" /> Add line item\n </Button>\n }\n />\n ) : (\n <GlassCard treatment=\"plain\" className=\"overflow-hidden\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full border-collapse text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left\">\n <th className=\"px-4 py-3 font-medium text-text-secondary\">Line item</th>\n <th className=\"hidden px-4 py-3 font-medium text-text-secondary md:table-cell\">\n Category\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-text-secondary\">Value</th>\n </tr>\n </thead>\n <tbody>\n {lineItems.map((li) => (\n <tr key={li.id} className=\"border-b border-border-seam/60\">\n <td className=\"px-4 py-3 font-medium text-text-primary\">{li.label}</td>\n <td className=\"hidden px-4 py-3 text-text-secondary md:table-cell\">\n {li.category ?? '—'}\n </td>\n <td className=\"px-4 py-3 text-right text-text-primary tabular-nums\">\n {formatNumber(li.value)} {li.unit}\n </td>\n </tr>\n ))}\n </tbody>\n <tfoot>\n <tr className=\"border-t-2 border-border-seam bg-bg-sunken/40\">\n <td className=\"px-4 py-3 text-sm font-semibold text-text-primary\" colSpan={2}>\n Total\n </td>\n <td className=\"px-4 py-3 text-right text-base font-bold text-text-primary tabular-nums\">\n {formatNumber(total)}\n {totalUnit ? ` ${totalUnit}` : ''}\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </GlassCard>\n )}\n </Section>\n\n {/* Discussion — reuses the platform EntityComment API (no eco-svc change) */}\n <EcoDiscussion\n entityType=\"ecoimpacthub-report\"\n entityId={report.id}\n description=\"Coordinate review and sign-off on this disclosure with your team.\"\n />\n\n {/* Add line item dialog */}\n <ResponsiveDialog open={lineItemOpen} onOpenChange={setLineItemOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Add line item</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Record a quantified disclosure for {report.title}.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liLabel\">Label *</Label>\n <Input\n id=\"liLabel\"\n value={lineItemForm.label}\n onChange={(e) => setLineItemForm({ ...lineItemForm, label: e.target.value })}\n placeholder=\"Scope 1 emissions\"\n />\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liValue\">Value *</Label>\n <Input\n id=\"liValue\"\n type=\"number\"\n step=\"any\"\n value={lineItemForm.value}\n onChange={(e) => setLineItemForm({ ...lineItemForm, value: e.target.value })}\n placeholder=\"1250\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liUnit\">Unit *</Label>\n <Input\n id=\"liUnit\"\n value={lineItemForm.unit}\n onChange={(e) => setLineItemForm({ ...lineItemForm, unit: e.target.value })}\n placeholder=\"t CO₂e\"\n />\n </div>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liCategory\">Category</Label>\n <Input\n id=\"liCategory\"\n value={lineItemForm.category}\n onChange={(e) => setLineItemForm({ ...lineItemForm, category: e.target.value })}\n placeholder=\"Optional grouping, e.g. Energy\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"liCarbonEntry\">Carbon entry ID</Label>\n <Input\n id=\"liCarbonEntry\"\n value={lineItemForm.carbonEntryId}\n onChange={(e) =>\n setLineItemForm({ ...lineItemForm, carbonEntryId: e.target.value })\n }\n placeholder=\"Optional linked carbon-ledger entry\"\n />\n </div>\n </div>\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => setLineItemOpen(false)}>\n Cancel\n </Button>\n <Button onClick={handleAddLineItem} disabled={addLineItem.isPending}>\n {addLineItem.isPending ? 'Adding…' : 'Add line item'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SiteDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/ecoimpacthub/pages/sites/SiteDetailPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"SiteDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/ecoimpacthub/pages/sites/SiteDetailPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgFH,wBAAgB,cAAc,4CA6vB7B"}
|
|
@@ -7,17 +7,18 @@ import { ErrorView as ie, LoadingView as ae, Section as a } from "../../componen
|
|
|
7
7
|
import { EmptyState as o } from "../../components/EmptyState.js";
|
|
8
8
|
import "../../context/index.js";
|
|
9
9
|
import { useEcoArchiveSite as oe, useEcoCreateSensor as se, useEcoCreateThreshold as ce, useEcoMeasurements as s, useEcoRecordMeasurement as le, useEcoSetSensorStatus as ue, useEcoSetThresholdActive as de, useEcoSite as fe } from "../../hooks/useEcoImpactHubApi.js";
|
|
10
|
+
import { useActiveEcoEntity as pe } from "../../hooks/useActiveEcoEntity.js";
|
|
10
11
|
import "../../hooks/index.js";
|
|
11
12
|
import { DataTable as c } from "../../components/DataTable.js";
|
|
12
|
-
import { EcoTags as
|
|
13
|
-
import { SiteTypeBadge as
|
|
13
|
+
import { EcoTags as me } from "../../components/EcoTags.js";
|
|
14
|
+
import { SiteTypeBadge as he } from "./siteTypeVisuals.js";
|
|
14
15
|
import { useState as l } from "react";
|
|
15
|
-
import { Activity as
|
|
16
|
-
import { useParams as
|
|
17
|
-
import { Fragment as
|
|
16
|
+
import { Activity as ge, Archive as _e, ArrowLeft as ve, Gauge as ye, Plus as u, Radio as d, ShieldCheck as be, Zap as xe } from "lucide-react";
|
|
17
|
+
import { useParams as Se } from "react-router";
|
|
18
|
+
import { Fragment as Ce, jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
18
19
|
import { Button as m, GlassCard as h, Input as g, Label as _, ResponsiveDialog as v, ResponsiveDialogContent as y, ResponsiveDialogDescription as b, ResponsiveDialogFooter as x, ResponsiveDialogHeader as S, ResponsiveDialogTitle as C, Select as w, SelectContent as T, SelectItem as E, SelectTrigger as D, SelectValue as O } from "@burdenoff/fe-libs/ui";
|
|
19
20
|
//#region src/ecoimpacthub/pages/sites/SiteDetailPage.tsx
|
|
20
|
-
var
|
|
21
|
+
var we = [
|
|
21
22
|
"AIR_QUALITY",
|
|
22
23
|
"WATER_QUALITY",
|
|
23
24
|
"WEATHER",
|
|
@@ -27,41 +28,43 @@ var Ce = [
|
|
|
27
28
|
"ACOUSTIC",
|
|
28
29
|
"CAMERA_TRAP",
|
|
29
30
|
"MANUAL"
|
|
30
|
-
],
|
|
31
|
+
], Te = [
|
|
31
32
|
"ONLINE",
|
|
32
33
|
"OFFLINE",
|
|
33
34
|
"DEGRADED",
|
|
34
35
|
"MAINTENANCE",
|
|
35
36
|
"RETIRED"
|
|
36
|
-
],
|
|
37
|
+
], Ee = [
|
|
37
38
|
"ABOVE",
|
|
38
39
|
"BELOW",
|
|
39
40
|
"OUTSIDE_RANGE"
|
|
40
|
-
],
|
|
41
|
+
], De = [
|
|
41
42
|
"INFO",
|
|
42
43
|
"WARNING",
|
|
43
44
|
"CRITICAL"
|
|
44
45
|
];
|
|
45
46
|
function k() {
|
|
46
|
-
let { id: k } =
|
|
47
|
+
let { id: k } = Se(), { navigateTo: A } = e(), { data: j, isLoading: Oe, isError: ke, refetch: Ae } = fe(k);
|
|
48
|
+
pe(j?.id, j?.name);
|
|
49
|
+
let M = s({
|
|
47
50
|
siteId: k,
|
|
48
51
|
pagination: {
|
|
49
52
|
limit: 10,
|
|
50
53
|
offset: 0
|
|
51
54
|
}
|
|
52
|
-
}),
|
|
55
|
+
}), je = s({
|
|
53
56
|
siteId: k,
|
|
54
57
|
breachesOnly: !0,
|
|
55
58
|
pagination: {
|
|
56
59
|
limit: 1,
|
|
57
60
|
offset: 0
|
|
58
61
|
}
|
|
59
|
-
}), N = se(),
|
|
62
|
+
}), N = se(), Me = ue(), P = ce(), Ne = de(), F = le(), I = oe(), [Pe, L] = l(!1), [R, z] = l({
|
|
60
63
|
name: "",
|
|
61
64
|
kind: "AIR_QUALITY",
|
|
62
65
|
unit: "",
|
|
63
66
|
hardwareId: ""
|
|
64
|
-
}), [
|
|
67
|
+
}), [Fe, B] = l(!1), [V, H] = l({
|
|
65
68
|
parameter: "",
|
|
66
69
|
unit: "",
|
|
67
70
|
direction: "ABOVE",
|
|
@@ -69,35 +72,35 @@ function k() {
|
|
|
69
72
|
limitValue: "",
|
|
70
73
|
minValue: "",
|
|
71
74
|
maxValue: ""
|
|
72
|
-
}), [
|
|
75
|
+
}), [Ie, U] = l(!1), [W, G] = l({
|
|
73
76
|
parameter: "",
|
|
74
77
|
value: "",
|
|
75
78
|
unit: "",
|
|
76
79
|
sensorId: ""
|
|
77
80
|
}), [K, q] = l(null);
|
|
78
|
-
if (
|
|
81
|
+
if (Oe) return /* @__PURE__ */ f(t, {
|
|
79
82
|
title: "Site",
|
|
80
83
|
children: /* @__PURE__ */ f(ae, {})
|
|
81
84
|
});
|
|
82
|
-
if (
|
|
85
|
+
if (ke || !j) return /* @__PURE__ */ f(t, {
|
|
83
86
|
title: "Site",
|
|
84
87
|
children: /* @__PURE__ */ f(ie, {
|
|
85
88
|
message: "This site could not be loaded.",
|
|
86
|
-
onRetry: () =>
|
|
89
|
+
onRetry: () => Ae()
|
|
87
90
|
})
|
|
88
91
|
});
|
|
89
92
|
let J = j.sensors ?? [], Y = j.thresholds ?? [], X = M.data?.items ?? [], Z = J.filter((e) => e.status === "ONLINE").length, Q = J.filter((e) => [
|
|
90
93
|
"OFFLINE",
|
|
91
94
|
"DEGRADED",
|
|
92
95
|
"MAINTENANCE"
|
|
93
|
-
].includes(e.status)).length,
|
|
96
|
+
].includes(e.status)).length, Le = Y.filter((e) => e.isActive).length, $ = je.data?.items?.[0] ?? null;
|
|
94
97
|
return /* @__PURE__ */ p(t, {
|
|
95
98
|
title: j.name,
|
|
96
99
|
description: [j.code, n(j.type)].filter(Boolean).join(" · "),
|
|
97
|
-
actions: /* @__PURE__ */ p(
|
|
100
|
+
actions: /* @__PURE__ */ p(Ce, { children: [/* @__PURE__ */ f(i, { status: j.status }), /* @__PURE__ */ p(m, {
|
|
98
101
|
variant: "ghost",
|
|
99
102
|
onClick: () => A("sites"),
|
|
100
|
-
children: [/* @__PURE__ */ f(
|
|
103
|
+
children: [/* @__PURE__ */ f(ve, { className: "mr-1.5 h-4 w-4" }), " Back"]
|
|
101
104
|
})] }),
|
|
102
105
|
children: [
|
|
103
106
|
/* @__PURE__ */ p("div", {
|
|
@@ -114,7 +117,7 @@ function k() {
|
|
|
114
117
|
children: "Type"
|
|
115
118
|
}), /* @__PURE__ */ f("dd", {
|
|
116
119
|
className: "mt-1",
|
|
117
|
-
children: /* @__PURE__ */ f(
|
|
120
|
+
children: /* @__PURE__ */ f(he, { type: j.type })
|
|
118
121
|
})] }),
|
|
119
122
|
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("dt", {
|
|
120
123
|
className: "text-xs text-text-tertiary",
|
|
@@ -159,7 +162,7 @@ function k() {
|
|
|
159
162
|
}),
|
|
160
163
|
/* @__PURE__ */ f("div", {
|
|
161
164
|
className: "mt-5 border-t border-border-seam pt-4",
|
|
162
|
-
children: /* @__PURE__ */ f(
|
|
165
|
+
children: /* @__PURE__ */ f(me, {
|
|
163
166
|
entityType: "ecoimpacthub-site",
|
|
164
167
|
entityId: j.id
|
|
165
168
|
})
|
|
@@ -172,7 +175,7 @@ function k() {
|
|
|
172
175
|
className: "p-6",
|
|
173
176
|
children: [/* @__PURE__ */ p("div", {
|
|
174
177
|
className: "mb-3 flex items-center gap-2",
|
|
175
|
-
children: [/* @__PURE__ */ f(
|
|
178
|
+
children: [/* @__PURE__ */ f(xe, { className: "h-4 w-4 text-accent" }), /* @__PURE__ */ f("h2", {
|
|
176
179
|
className: "text-base font-semibold text-text-primary",
|
|
177
180
|
children: "Quick actions"
|
|
178
181
|
})]
|
|
@@ -181,7 +184,7 @@ function k() {
|
|
|
181
184
|
children: [
|
|
182
185
|
/* @__PURE__ */ p(m, {
|
|
183
186
|
onClick: () => U(!0),
|
|
184
|
-
children: [/* @__PURE__ */ f(
|
|
187
|
+
children: [/* @__PURE__ */ f(ge, { className: "mr-1.5 h-4 w-4" }), " Record measurement"]
|
|
185
188
|
}),
|
|
186
189
|
/* @__PURE__ */ p(m, {
|
|
187
190
|
variant: "outline",
|
|
@@ -191,7 +194,7 @@ function k() {
|
|
|
191
194
|
/* @__PURE__ */ p(m, {
|
|
192
195
|
variant: "outline",
|
|
193
196
|
onClick: () => B(!0),
|
|
194
|
-
children: [/* @__PURE__ */ f(
|
|
197
|
+
children: [/* @__PURE__ */ f(ye, { className: "mr-1.5 h-4 w-4" }), " Add threshold"]
|
|
195
198
|
}),
|
|
196
199
|
j.status !== "ARCHIVED" && /* @__PURE__ */ p(m, {
|
|
197
200
|
variant: "ghost",
|
|
@@ -207,7 +210,7 @@ function k() {
|
|
|
207
210
|
},
|
|
208
211
|
disabled: I.isPending,
|
|
209
212
|
className: "text-status-error-text hover:text-status-error-text",
|
|
210
|
-
children: [/* @__PURE__ */ f(
|
|
213
|
+
children: [/* @__PURE__ */ f(_e, { className: "mr-1.5 h-4 w-4" }), " Archive site"]
|
|
211
214
|
})
|
|
212
215
|
]
|
|
213
216
|
})]
|
|
@@ -249,7 +252,7 @@ function k() {
|
|
|
249
252
|
children: [
|
|
250
253
|
/* @__PURE__ */ p("p", {
|
|
251
254
|
className: "text-2xl font-semibold text-text-primary tabular-nums",
|
|
252
|
-
children: [
|
|
255
|
+
children: [Le, /* @__PURE__ */ p("span", {
|
|
253
256
|
className: "text-base text-text-tertiary",
|
|
254
257
|
children: ["/", Y.length]
|
|
255
258
|
})]
|
|
@@ -294,7 +297,7 @@ function k() {
|
|
|
294
297
|
})]
|
|
295
298
|
}) : /* @__PURE__ */ p("div", {
|
|
296
299
|
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
297
|
-
children: [/* @__PURE__ */ f(
|
|
300
|
+
children: [/* @__PURE__ */ f(be, { className: "h-4 w-4 shrink-0 text-status-success-text" }), "No breaches recorded"]
|
|
298
301
|
})]
|
|
299
302
|
})
|
|
300
303
|
]
|
|
@@ -350,14 +353,14 @@ function k() {
|
|
|
350
353
|
align: "right",
|
|
351
354
|
render: (e) => /* @__PURE__ */ p(w, {
|
|
352
355
|
value: e.status,
|
|
353
|
-
onValueChange: (t) =>
|
|
356
|
+
onValueChange: (t) => Me.mutate({
|
|
354
357
|
id: e.id,
|
|
355
358
|
status: t
|
|
356
359
|
}),
|
|
357
360
|
children: [/* @__PURE__ */ f(D, {
|
|
358
361
|
className: "h-8 w-36",
|
|
359
362
|
children: /* @__PURE__ */ f(O, {})
|
|
360
|
-
}), /* @__PURE__ */ f(T, { children:
|
|
363
|
+
}), /* @__PURE__ */ f(T, { children: Te.map((e) => /* @__PURE__ */ f(E, {
|
|
361
364
|
value: e,
|
|
362
365
|
children: n(e)
|
|
363
366
|
}, e)) })]
|
|
@@ -410,7 +413,7 @@ function k() {
|
|
|
410
413
|
render: (e) => /* @__PURE__ */ f(m, {
|
|
411
414
|
size: "sm",
|
|
412
415
|
variant: e.isActive ? "outline" : "ghost",
|
|
413
|
-
onClick: () =>
|
|
416
|
+
onClick: () => Ne.mutate({
|
|
414
417
|
id: e.id,
|
|
415
418
|
isActive: !e.isActive
|
|
416
419
|
}),
|
|
@@ -488,7 +491,7 @@ function k() {
|
|
|
488
491
|
})
|
|
489
492
|
}),
|
|
490
493
|
/* @__PURE__ */ f(v, {
|
|
491
|
-
open:
|
|
494
|
+
open: Pe,
|
|
492
495
|
onOpenChange: L,
|
|
493
496
|
children: /* @__PURE__ */ p(y, { children: [
|
|
494
497
|
/* @__PURE__ */ p(S, { children: [/* @__PURE__ */ f(C, { children: "Add sensor" }), /* @__PURE__ */ p(b, { children: [
|
|
@@ -530,7 +533,7 @@ function k() {
|
|
|
530
533
|
children: [/* @__PURE__ */ f(D, {
|
|
531
534
|
id: "sensorKind",
|
|
532
535
|
children: /* @__PURE__ */ f(O, {})
|
|
533
|
-
}), /* @__PURE__ */ f(T, { children:
|
|
536
|
+
}), /* @__PURE__ */ f(T, { children: we.map((e) => /* @__PURE__ */ f(E, {
|
|
534
537
|
value: e,
|
|
535
538
|
children: n(e)
|
|
536
539
|
}, e)) })]
|
|
@@ -602,7 +605,7 @@ function k() {
|
|
|
602
605
|
] })
|
|
603
606
|
}),
|
|
604
607
|
/* @__PURE__ */ f(v, {
|
|
605
|
-
open:
|
|
608
|
+
open: Fe,
|
|
606
609
|
onOpenChange: B,
|
|
607
610
|
children: /* @__PURE__ */ p(y, { children: [
|
|
608
611
|
/* @__PURE__ */ p(S, { children: [/* @__PURE__ */ f(C, { children: "Add alert threshold" }), /* @__PURE__ */ f(b, { children: "Flag readings that drift out of an acceptable range." })] }),
|
|
@@ -657,7 +660,7 @@ function k() {
|
|
|
657
660
|
children: [/* @__PURE__ */ f(D, {
|
|
658
661
|
id: "thDir",
|
|
659
662
|
children: /* @__PURE__ */ f(O, {})
|
|
660
|
-
}), /* @__PURE__ */ f(T, { children:
|
|
663
|
+
}), /* @__PURE__ */ f(T, { children: Ee.map((e) => /* @__PURE__ */ f(E, {
|
|
661
664
|
value: e,
|
|
662
665
|
children: n(e)
|
|
663
666
|
}, e)) })]
|
|
@@ -676,7 +679,7 @@ function k() {
|
|
|
676
679
|
children: [/* @__PURE__ */ f(D, {
|
|
677
680
|
id: "thSev",
|
|
678
681
|
children: /* @__PURE__ */ f(O, {})
|
|
679
|
-
}), /* @__PURE__ */ f(T, { children:
|
|
682
|
+
}), /* @__PURE__ */ f(T, { children: De.map((e) => /* @__PURE__ */ f(E, {
|
|
680
683
|
value: e,
|
|
681
684
|
children: n(e)
|
|
682
685
|
}, e)) })]
|
|
@@ -775,7 +778,7 @@ function k() {
|
|
|
775
778
|
] })
|
|
776
779
|
}),
|
|
777
780
|
/* @__PURE__ */ f(v, {
|
|
778
|
-
open:
|
|
781
|
+
open: Ie,
|
|
779
782
|
onOpenChange: U,
|
|
780
783
|
children: /* @__PURE__ */ p(y, { children: [
|
|
781
784
|
/* @__PURE__ */ p(S, { children: [/* @__PURE__ */ f(C, { children: "Record measurement" }), /* @__PURE__ */ f(b, { children: "Log a reading. It is checked against active thresholds and flagged if it breaches." })] }),
|