@burdenoff/microfe-ecoimpacthub 2026.704.1 → 2026.704.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/ecoimpacthub/components/EcoDiscussion.js +109 -0
  2. package/dist/ecoimpacthub/components/EcoDiscussion.js.map +1 -0
  3. package/dist/ecoimpacthub/components/EcoTags.js +149 -0
  4. package/dist/ecoimpacthub/components/EcoTags.js.map +1 -0
  5. package/dist/ecoimpacthub/components/EvidenceUpload.js +93 -0
  6. package/dist/ecoimpacthub/components/EvidenceUpload.js.map +1 -0
  7. package/dist/ecoimpacthub/components/FileLink.js +36 -0
  8. package/dist/ecoimpacthub/components/FileLink.js.map +1 -0
  9. package/dist/ecoimpacthub/components/PageLayout.js +2 -2
  10. package/dist/ecoimpacthub/components/PageLayout.js.map +1 -1
  11. package/dist/ecoimpacthub/hooks/index.js +3 -0
  12. package/dist/ecoimpacthub/hooks/useCursorPager.js +1 -1
  13. package/dist/ecoimpacthub/hooks/useCursorPager.js.map +1 -1
  14. package/dist/ecoimpacthub/hooks/useEcoComments.js +45 -0
  15. package/dist/ecoimpacthub/hooks/useEcoComments.js.map +1 -0
  16. package/dist/ecoimpacthub/hooks/useEcoFiles.js +81 -0
  17. package/dist/ecoimpacthub/hooks/useEcoFiles.js.map +1 -0
  18. package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.js +169 -166
  19. package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.js.map +1 -1
  20. package/dist/ecoimpacthub/hooks/useEcoTags.js +89 -0
  21. package/dist/ecoimpacthub/hooks/useEcoTags.js.map +1 -0
  22. package/dist/ecoimpacthub/pages/observations/ObservationsPage.js +124 -101
  23. package/dist/ecoimpacthub/pages/observations/ObservationsPage.js.map +1 -1
  24. package/dist/ecoimpacthub/pages/reports/ReportDetailPage.js +153 -126
  25. package/dist/ecoimpacthub/pages/reports/ReportDetailPage.js.map +1 -1
  26. package/dist/ecoimpacthub/pages/sites/SiteDetailPage.js +241 -230
  27. package/dist/ecoimpacthub/pages/sites/SiteDetailPage.js.map +1 -1
  28. package/dist/ecoimpacthub/pages/species/SpeciesDetailPage.js +260 -225
  29. package/dist/ecoimpacthub/pages/species/SpeciesDetailPage.js.map +1 -1
  30. package/package.json +1 -1
@@ -8,151 +8,173 @@ import "../../context/index.js";
8
8
  import { useEcoAddReportLineItem as u, useEcoPublishReport as d, useEcoReport as f } from "../../hooks/useEcoImpactHubApi.js";
9
9
  import "../../hooks/index.js";
10
10
  import { DataTable as p } from "../../components/DataTable.js";
11
- import { useMemo as m, useState as h } from "react";
12
- import { ArrowLeft as g, ListPlus as _, Plus as v, Send as y } from "lucide-react";
13
- import { useParams as b } from "react-router-dom";
14
- import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
15
- import { Button as w, GlassCard as T, Input as E, Label as D, ResponsiveDialog as O, ResponsiveDialogContent as k, ResponsiveDialogDescription as A, ResponsiveDialogFooter as j, ResponsiveDialogHeader as M, ResponsiveDialogTitle as N } from "@burdenoff/fe-libs/ui";
11
+ import { EvidenceUpload as m } from "../../components/EvidenceUpload.js";
12
+ import { FileLink as h } from "../../components/FileLink.js";
13
+ import { EcoDiscussion as g } from "../../components/EcoDiscussion.js";
14
+ import { useMemo as _, useState as v } from "react";
15
+ import { ArrowLeft as y, ListPlus as b, Plus as x, Send as S } from "lucide-react";
16
+ import { useParams as C } from "react-router-dom";
17
+ import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
18
+ import { Button as D, GlassCard as O, Input as k, Label as A, ResponsiveDialog as j, ResponsiveDialogContent as M, ResponsiveDialogDescription as N, ResponsiveDialogFooter as P, ResponsiveDialogHeader as F, ResponsiveDialogTitle as I } from "@burdenoff/fe-libs/ui";
16
19
  //#region src/ecoimpacthub/pages/reports/ReportDetailPage.tsx
17
- function P() {
18
- let { id: P } = b(), { navigateTo: F } = e(), { data: I, isLoading: L, isError: R, refetch: z } = f(P), B = u(), V = d(), [H, U] = h(!1), [W, G] = h({
20
+ function L() {
21
+ let { id: L } = C(), { navigateTo: R } = e(), { data: z, isLoading: B, isError: V, refetch: H } = f(L), U = u(), W = d(), [G, K] = v(!1), [q, J] = v({
19
22
  label: "",
20
23
  value: "",
21
24
  unit: "",
22
25
  category: "",
23
26
  carbonEntryId: ""
24
- }), [K, q] = h(null), J = m(() => I?.lineItems ?? [], [I]), Y = m(() => J.reduce((e, t) => e + t.value, 0), [J]);
25
- return L ? /* @__PURE__ */ S(t, {
27
+ }), [Y, X] = v(null), [Z, Q] = v(null), $ = _(() => z?.lineItems ?? [], [z]), ee = _(() => $.reduce((e, t) => e + t.value, 0), [$]);
28
+ return B ? /* @__PURE__ */ T(t, {
26
29
  title: "Report",
27
- children: /* @__PURE__ */ S(s, {})
28
- }) : R || !I ? /* @__PURE__ */ S(t, {
30
+ children: /* @__PURE__ */ T(s, {})
31
+ }) : V || !z ? /* @__PURE__ */ T(t, {
29
32
  title: "Report",
30
- children: /* @__PURE__ */ S(o, {
33
+ children: /* @__PURE__ */ T(o, {
31
34
  message: "This report could not be loaded.",
32
- onRetry: () => z()
35
+ onRetry: () => H()
33
36
  })
34
- }) : /* @__PURE__ */ C(t, {
35
- title: I.title,
36
- description: [r(I.framework), r(I.status)].filter(Boolean).join(" · "),
37
- actions: /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ S(a, { status: I.status }), /* @__PURE__ */ C(w, {
37
+ }) : /* @__PURE__ */ E(t, {
38
+ title: z.title,
39
+ description: [r(z.framework), r(z.status)].filter(Boolean).join(" · "),
40
+ actions: /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ T(a, { status: z.status }), /* @__PURE__ */ E(D, {
38
41
  variant: "ghost",
39
- onClick: () => F("reports"),
40
- children: [/* @__PURE__ */ S(g, { className: "mr-1.5 h-4 w-4" }), " Back"]
42
+ onClick: () => R("reports"),
43
+ children: [/* @__PURE__ */ T(y, { className: "mr-1.5 h-4 w-4" }), " Back"]
41
44
  })] }),
42
45
  children: [
43
- /* @__PURE__ */ C("div", {
46
+ /* @__PURE__ */ E("div", {
44
47
  className: "grid grid-cols-1 gap-4 lg:grid-cols-3",
45
- children: [/* @__PURE__ */ C(T, {
48
+ children: [/* @__PURE__ */ E(O, {
46
49
  treatment: "glass",
47
50
  className: "p-6 lg:col-span-2",
48
- children: [/* @__PURE__ */ C("dl", {
51
+ children: [/* @__PURE__ */ E("dl", {
49
52
  className: "grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-3",
50
53
  children: [
51
- /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("dt", {
54
+ /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
52
55
  className: "text-xs text-text-tertiary",
53
56
  children: "Framework"
54
- }), /* @__PURE__ */ S("dd", {
57
+ }), /* @__PURE__ */ T("dd", {
55
58
  className: "mt-0.5",
56
- children: /* @__PURE__ */ S(a, { status: I.framework })
59
+ children: /* @__PURE__ */ T(a, { status: z.framework })
57
60
  })] }),
58
- /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("dt", {
61
+ /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
59
62
  className: "text-xs text-text-tertiary",
60
63
  children: "Status"
61
- }), /* @__PURE__ */ S("dd", {
64
+ }), /* @__PURE__ */ T("dd", {
62
65
  className: "mt-0.5",
63
- children: /* @__PURE__ */ S(a, { status: I.status })
66
+ children: /* @__PURE__ */ T(a, { status: z.status })
64
67
  })] }),
65
- /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("dt", {
68
+ /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
66
69
  className: "text-xs text-text-tertiary",
67
70
  children: "Period"
68
- }), /* @__PURE__ */ C("dd", {
71
+ }), /* @__PURE__ */ E("dd", {
69
72
  className: "mt-0.5 text-sm text-text-primary tabular-nums",
70
73
  children: [
71
- n(I.periodStart),
74
+ n(z.periodStart),
72
75
  " – ",
73
- n(I.periodEnd)
76
+ n(z.periodEnd)
74
77
  ]
75
78
  })] }),
76
- /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("dt", {
79
+ /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
77
80
  className: "text-xs text-text-tertiary",
78
81
  children: "Published"
79
- }), /* @__PURE__ */ S("dd", {
82
+ }), /* @__PURE__ */ T("dd", {
80
83
  className: "mt-0.5 text-sm text-text-primary",
81
- children: n(I.publishedAt)
84
+ children: n(z.publishedAt)
82
85
  })] }),
83
- /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("dt", {
86
+ /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
84
87
  className: "text-xs text-text-tertiary",
85
88
  children: "Line items"
86
- }), /* @__PURE__ */ S("dd", {
89
+ }), /* @__PURE__ */ T("dd", {
87
90
  className: "mt-0.5 text-sm text-text-primary tabular-nums",
88
- children: J.length
91
+ children: $.length
92
+ })] }),
93
+ /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
94
+ className: "text-xs text-text-tertiary",
95
+ children: "Attachment"
96
+ }), /* @__PURE__ */ T("dd", {
97
+ className: "mt-0.5 text-sm",
98
+ children: z.file?.id ? /* @__PURE__ */ T(h, { fileId: z.file.id }) : /* @__PURE__ */ T("span", {
99
+ className: "text-text-tertiary",
100
+ children: "—"
101
+ })
89
102
  })] })
90
103
  ]
91
- }), I.summary && /* @__PURE__ */ S("p", {
104
+ }), z.summary && /* @__PURE__ */ T("p", {
92
105
  className: "mt-5 rounded-lg bg-bg-sunken/60 p-3 text-sm text-text-secondary",
93
- children: I.summary
106
+ children: z.summary
94
107
  })]
95
- }), /* @__PURE__ */ C(T, {
108
+ }), /* @__PURE__ */ E(O, {
96
109
  treatment: "glass",
97
110
  className: "flex flex-col gap-3 p-6",
98
111
  children: [
99
- /* @__PURE__ */ S("p", {
112
+ /* @__PURE__ */ T("p", {
100
113
  className: "text-xs text-text-tertiary",
101
114
  children: "Quick actions"
102
115
  }),
103
- /* @__PURE__ */ C(w, {
104
- onClick: () => U(!0),
105
- children: [/* @__PURE__ */ S(_, { className: "mr-1.5 h-4 w-4" }), " Add line item"]
116
+ /* @__PURE__ */ E(D, {
117
+ onClick: () => K(!0),
118
+ children: [/* @__PURE__ */ T(b, { className: "mr-1.5 h-4 w-4" }), " Add line item"]
106
119
  }),
107
- I.status !== "PUBLISHED" && /* @__PURE__ */ C(w, {
120
+ z.status !== "PUBLISHED" && /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ T(m, {
121
+ id: "reportAttachment",
122
+ label: "Attach file (optional)",
123
+ value: Z,
124
+ onChange: Q,
125
+ hint: "Attach the signed report PDF or supporting document, then publish."
126
+ }), /* @__PURE__ */ E(D, {
108
127
  variant: "outline",
109
128
  onClick: async () => {
110
- if (P) {
111
- q(null);
129
+ if (L) {
130
+ X(null);
112
131
  try {
113
- await V.mutateAsync({ id: P });
132
+ await W.mutateAsync({
133
+ id: L,
134
+ fileId: Z?.fileId ?? null
135
+ }), Q(null);
114
136
  } catch (e) {
115
- q(e instanceof Error ? e.message : "Failed to publish report.");
137
+ X(e instanceof Error ? e.message : "Failed to publish report.");
116
138
  }
117
139
  }
118
140
  },
119
- disabled: V.isPending,
120
- children: [/* @__PURE__ */ S(y, { className: "mr-1.5 h-4 w-4" }), V.isPending ? "Publishing…" : "Publish report"]
121
- })
141
+ disabled: W.isPending,
142
+ children: [/* @__PURE__ */ T(S, { className: "mr-1.5 h-4 w-4" }), W.isPending ? "Publishing…" : "Publish report"]
143
+ })] })
122
144
  ]
123
145
  })]
124
146
  }),
125
- K && /* @__PURE__ */ S("p", {
147
+ Y && /* @__PURE__ */ T("p", {
126
148
  className: "mt-4 text-sm text-status-error-text",
127
- children: K
149
+ children: Y
128
150
  }),
129
- /* @__PURE__ */ S(c, {
151
+ /* @__PURE__ */ T(c, {
130
152
  title: "Line items",
131
153
  description: "Quantified disclosures that make up this report.",
132
- action: /* @__PURE__ */ C(w, {
154
+ action: /* @__PURE__ */ E(D, {
133
155
  size: "sm",
134
- onClick: () => U(!0),
135
- children: [/* @__PURE__ */ S(v, { className: "mr-1.5 h-4 w-4" }), " Add line item"]
156
+ onClick: () => K(!0),
157
+ children: [/* @__PURE__ */ T(x, { className: "mr-1.5 h-4 w-4" }), " Add line item"]
136
158
  }),
137
- children: J.length === 0 ? /* @__PURE__ */ S(l, {
159
+ children: $.length === 0 ? /* @__PURE__ */ T(l, {
138
160
  illustration: "empty-data",
139
161
  title: "No line items",
140
162
  description: "Add a line item to record a quantified disclosure for this report."
141
- }) : /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ C("div", {
163
+ }) : /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ E("div", {
142
164
  className: "mb-3 flex items-center justify-end gap-2 text-sm",
143
- children: [/* @__PURE__ */ S("span", {
165
+ children: [/* @__PURE__ */ T("span", {
144
166
  className: "text-text-tertiary",
145
167
  children: "Total value"
146
- }), /* @__PURE__ */ S("span", {
168
+ }), /* @__PURE__ */ T("span", {
147
169
  className: "font-semibold text-text-primary tabular-nums",
148
- children: i(Y)
170
+ children: i(ee)
149
171
  })]
150
- }), /* @__PURE__ */ S(p, {
172
+ }), /* @__PURE__ */ T(p, {
151
173
  columns: [
152
174
  {
153
175
  key: "label",
154
176
  header: "Line item",
155
- render: (e) => /* @__PURE__ */ S("span", {
177
+ render: (e) => /* @__PURE__ */ T("span", {
156
178
  className: "font-semibold text-text-primary",
157
179
  children: e.label
158
180
  })
@@ -161,7 +183,7 @@ function P() {
161
183
  key: "category",
162
184
  header: "Category",
163
185
  hideOnMobile: !0,
164
- render: (e) => /* @__PURE__ */ S("span", {
186
+ render: (e) => /* @__PURE__ */ T("span", {
165
187
  className: "text-text-secondary",
166
188
  children: e.category ?? "—"
167
189
  })
@@ -171,7 +193,7 @@ function P() {
171
193
  header: "Value",
172
194
  align: "right",
173
195
  sortValue: (e) => e.value,
174
- render: (e) => /* @__PURE__ */ C("span", {
196
+ render: (e) => /* @__PURE__ */ E("span", {
175
197
  className: "tabular-nums text-text-primary",
176
198
  children: [
177
199
  i(e.value),
@@ -181,96 +203,101 @@ function P() {
181
203
  })
182
204
  }
183
205
  ],
184
- rows: J,
206
+ rows: $,
185
207
  rowKey: (e) => e.id
186
208
  })] })
187
209
  }),
188
- /* @__PURE__ */ S(O, {
189
- open: H,
190
- onOpenChange: U,
191
- children: /* @__PURE__ */ C(k, { children: [
192
- /* @__PURE__ */ C(M, { children: [/* @__PURE__ */ S(N, { children: "Add line item" }), /* @__PURE__ */ C(A, { children: [
210
+ /* @__PURE__ */ T(g, {
211
+ entityType: "ecoimpacthub-report",
212
+ entityId: z.id,
213
+ description: "Coordinate review and sign-off on this disclosure with your team."
214
+ }),
215
+ /* @__PURE__ */ T(j, {
216
+ open: G,
217
+ onOpenChange: K,
218
+ children: /* @__PURE__ */ E(M, { children: [
219
+ /* @__PURE__ */ E(F, { children: [/* @__PURE__ */ T(I, { children: "Add line item" }), /* @__PURE__ */ E(N, { children: [
193
220
  "Record a quantified disclosure for ",
194
- I.title,
221
+ z.title,
195
222
  "."
196
223
  ] })] }),
197
- /* @__PURE__ */ C("div", {
224
+ /* @__PURE__ */ E("div", {
198
225
  className: "grid gap-4 py-2",
199
226
  children: [
200
- /* @__PURE__ */ C("div", {
227
+ /* @__PURE__ */ E("div", {
201
228
  className: "grid gap-1.5",
202
- children: [/* @__PURE__ */ S(D, {
229
+ children: [/* @__PURE__ */ T(A, {
203
230
  htmlFor: "liLabel",
204
231
  children: "Label *"
205
- }), /* @__PURE__ */ S(E, {
232
+ }), /* @__PURE__ */ T(k, {
206
233
  id: "liLabel",
207
- value: W.label,
208
- onChange: (e) => G({
209
- ...W,
234
+ value: q.label,
235
+ onChange: (e) => J({
236
+ ...q,
210
237
  label: e.target.value
211
238
  }),
212
239
  placeholder: "Scope 1 emissions"
213
240
  })]
214
241
  }),
215
- /* @__PURE__ */ C("div", {
242
+ /* @__PURE__ */ E("div", {
216
243
  className: "grid gap-2 sm:grid-cols-2",
217
- children: [/* @__PURE__ */ C("div", {
244
+ children: [/* @__PURE__ */ E("div", {
218
245
  className: "grid gap-1.5",
219
- children: [/* @__PURE__ */ S(D, {
246
+ children: [/* @__PURE__ */ T(A, {
220
247
  htmlFor: "liValue",
221
248
  children: "Value *"
222
- }), /* @__PURE__ */ S(E, {
249
+ }), /* @__PURE__ */ T(k, {
223
250
  id: "liValue",
224
251
  type: "number",
225
252
  step: "any",
226
- value: W.value,
227
- onChange: (e) => G({
228
- ...W,
253
+ value: q.value,
254
+ onChange: (e) => J({
255
+ ...q,
229
256
  value: e.target.value
230
257
  }),
231
258
  placeholder: "1250"
232
259
  })]
233
- }), /* @__PURE__ */ C("div", {
260
+ }), /* @__PURE__ */ E("div", {
234
261
  className: "grid gap-1.5",
235
- children: [/* @__PURE__ */ S(D, {
262
+ children: [/* @__PURE__ */ T(A, {
236
263
  htmlFor: "liUnit",
237
264
  children: "Unit *"
238
- }), /* @__PURE__ */ S(E, {
265
+ }), /* @__PURE__ */ T(k, {
239
266
  id: "liUnit",
240
- value: W.unit,
241
- onChange: (e) => G({
242
- ...W,
267
+ value: q.unit,
268
+ onChange: (e) => J({
269
+ ...q,
243
270
  unit: e.target.value
244
271
  }),
245
272
  placeholder: "t CO₂e"
246
273
  })]
247
274
  })]
248
275
  }),
249
- /* @__PURE__ */ C("div", {
276
+ /* @__PURE__ */ E("div", {
250
277
  className: "grid gap-1.5",
251
- children: [/* @__PURE__ */ S(D, {
278
+ children: [/* @__PURE__ */ T(A, {
252
279
  htmlFor: "liCategory",
253
280
  children: "Category"
254
- }), /* @__PURE__ */ S(E, {
281
+ }), /* @__PURE__ */ T(k, {
255
282
  id: "liCategory",
256
- value: W.category,
257
- onChange: (e) => G({
258
- ...W,
283
+ value: q.category,
284
+ onChange: (e) => J({
285
+ ...q,
259
286
  category: e.target.value
260
287
  }),
261
288
  placeholder: "Optional grouping, e.g. Energy"
262
289
  })]
263
290
  }),
264
- /* @__PURE__ */ C("div", {
291
+ /* @__PURE__ */ E("div", {
265
292
  className: "grid gap-1.5",
266
- children: [/* @__PURE__ */ S(D, {
293
+ children: [/* @__PURE__ */ T(A, {
267
294
  htmlFor: "liCarbonEntry",
268
295
  children: "Carbon entry ID"
269
- }), /* @__PURE__ */ S(E, {
296
+ }), /* @__PURE__ */ T(k, {
270
297
  id: "liCarbonEntry",
271
- value: W.carbonEntryId,
272
- onChange: (e) => G({
273
- ...W,
298
+ value: q.carbonEntryId,
299
+ onChange: (e) => J({
300
+ ...q,
274
301
  carbonEntryId: e.target.value
275
302
  }),
276
303
  placeholder: "Optional linked carbon-ledger entry"
@@ -278,27 +305,27 @@ function P() {
278
305
  })
279
306
  ]
280
307
  }),
281
- /* @__PURE__ */ C(j, { children: [/* @__PURE__ */ S(w, {
308
+ /* @__PURE__ */ E(P, { children: [/* @__PURE__ */ T(D, {
282
309
  variant: "outline",
283
- onClick: () => U(!1),
310
+ onClick: () => K(!1),
284
311
  children: "Cancel"
285
- }), /* @__PURE__ */ S(w, {
312
+ }), /* @__PURE__ */ T(D, {
286
313
  onClick: async () => {
287
- if (P) {
288
- if (!W.label.trim() || !W.value || !W.unit.trim()) {
289
- q("Label, value and unit are required.");
314
+ if (L) {
315
+ if (!q.label.trim() || !q.value || !q.unit.trim()) {
316
+ X("Label, value and unit are required.");
290
317
  return;
291
318
  }
292
- q(null);
319
+ X(null);
293
320
  try {
294
- await B.mutateAsync({
295
- reportId: P,
296
- label: W.label.trim(),
297
- value: Number(W.value),
298
- unit: W.unit.trim(),
299
- category: W.category.trim() || null,
300
- carbonEntryId: W.carbonEntryId.trim() || null
301
- }), U(!1), G({
321
+ await U.mutateAsync({
322
+ reportId: L,
323
+ label: q.label.trim(),
324
+ value: Number(q.value),
325
+ unit: q.unit.trim(),
326
+ category: q.category.trim() || null,
327
+ carbonEntryId: q.carbonEntryId.trim() || null
328
+ }), K(!1), J({
302
329
  label: "",
303
330
  value: "",
304
331
  unit: "",
@@ -306,12 +333,12 @@ function P() {
306
333
  carbonEntryId: ""
307
334
  });
308
335
  } catch (e) {
309
- q(e instanceof Error ? e.message : "Failed to add line item.");
336
+ X(e instanceof Error ? e.message : "Failed to add line item.");
310
337
  }
311
338
  }
312
339
  },
313
- disabled: B.isPending,
314
- children: B.isPending ? "Adding…" : "Add line item"
340
+ disabled: U.isPending,
341
+ children: U.isPending ? "Adding…" : "Add line item"
315
342
  })] })
316
343
  ] })
317
344
  })
@@ -319,6 +346,6 @@ function P() {
319
346
  });
320
347
  }
321
348
  //#endregion
322
- export { P as ReportDetailPage };
349
+ export { L as ReportDetailPage };
323
350
 
324
351
  //# sourceMappingURL=ReportDetailPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReportDetailPage.js","names":[],"sources":["../../../../src/ecoimpacthub/pages/reports/ReportDetailPage.tsx"],"sourcesContent":["/**\n * Report detail — overview, line items & disclosure actions.\n * @module ecoimpacthub/pages/reports\n *\n * Reads `ecoReport` (+ nested lineItems); writes `ecoAddReportLineItem`,\n * `ecoPublishReport`.\n */\n\nimport { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Plus, 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 { DataTable, type Column } from '../../components/DataTable';\nimport { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useEcoImpactHub } from '../../context';\nimport { useEcoReport, useEcoAddReportLineItem, useEcoPublishReport } from '../../hooks';\nimport { formatDate, formatEnumLabel, formatNumber } from '../../utils/formatters';\nimport type { EcoReportLineItem } from '../../types';\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\n const lineItems = useMemo(() => report?.lineItems ?? [], [report]);\n const total = useMemo(() => lineItems.reduce((sum, li) => sum + li.value, 0), [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 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 });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to publish report.');\n }\n };\n\n const lineItemColumns: Column<EcoReportLineItem>[] = [\n {\n key: 'label',\n header: 'Line item',\n render: (li) => <span className=\"font-semibold text-text-primary\">{li.label}</span>,\n },\n {\n key: 'category',\n header: 'Category',\n hideOnMobile: true,\n render: (li) => <span className=\"text-text-secondary\">{li.category ?? '—'}</span>,\n },\n {\n key: 'value',\n header: 'Value',\n align: 'right',\n sortValue: (li) => li.value,\n render: (li) => (\n <span className=\"tabular-nums text-text-primary\">\n {formatNumber(li.value)} {li.unit}\n </span>\n ),\n },\n ];\n\n return (\n <PageLayout\n title={report.title}\n description={[formatEnumLabel(report.framework), formatEnumLabel(report.status)]\n .filter(Boolean)\n .join(' · ')}\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 */}\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 <div>\n <dt className=\"text-xs text-text-tertiary\">Framework</dt>\n <dd className=\"mt-0.5\">\n <StatusBadge status={report.framework} />\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Status</dt>\n <dd className=\"mt-0.5\">\n <StatusBadge status={report.status} />\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Period</dt>\n <dd className=\"mt-0.5 text-sm text-text-primary tabular-nums\">\n {formatDate(report.periodStart)} – {formatDate(report.periodEnd)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Published</dt>\n <dd className=\"mt-0.5 text-sm text-text-primary\">{formatDate(report.publishedAt)}</dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Line items</dt>\n <dd className=\"mt-0.5 text-sm text-text-primary tabular-nums\">{lineItems.length}</dd>\n </div>\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 text-text-tertiary\">Quick actions</p>\n <Button onClick={() => setLineItemOpen(true)}>\n <ListPlus className=\"mr-1.5 h-4 w-4\" /> Add line item\n </Button>\n {report.status !== 'PUBLISHED' && (\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 </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 <Plus 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 />\n ) : (\n <>\n <div className=\"mb-3 flex items-center justify-end gap-2 text-sm\">\n <span className=\"text-text-tertiary\">Total value</span>\n <span className=\"font-semibold text-text-primary tabular-nums\">\n {formatNumber(total)}\n </span>\n </div>\n <DataTable columns={lineItemColumns} rows={lineItems} rowKey={(li) => li.id} />\n </>\n )}\n </Section>\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 & disclosure actions.\n * @module ecoimpacthub/pages/reports\n *\n * Reads `ecoReport` (+ nested lineItems); writes `ecoAddReportLineItem`,\n * `ecoPublishReport`.\n */\n\nimport { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Plus, 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 { DataTable, type Column } from '../../components/DataTable';\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, formatEnumLabel, formatNumber } from '../../utils/formatters';\nimport type { EcoReportLineItem } from '../../types';\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\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 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 const lineItemColumns: Column<EcoReportLineItem>[] = [\n {\n key: 'label',\n header: 'Line item',\n render: (li) => <span className=\"font-semibold text-text-primary\">{li.label}</span>,\n },\n {\n key: 'category',\n header: 'Category',\n hideOnMobile: true,\n render: (li) => <span className=\"text-text-secondary\">{li.category ?? '—'}</span>,\n },\n {\n key: 'value',\n header: 'Value',\n align: 'right',\n sortValue: (li) => li.value,\n render: (li) => (\n <span className=\"tabular-nums text-text-primary\">\n {formatNumber(li.value)} {li.unit}\n </span>\n ),\n },\n ];\n\n return (\n <PageLayout\n title={report.title}\n description={[formatEnumLabel(report.framework), formatEnumLabel(report.status)]\n .filter(Boolean)\n .join(' · ')}\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 */}\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 <div>\n <dt className=\"text-xs text-text-tertiary\">Framework</dt>\n <dd className=\"mt-0.5\">\n <StatusBadge status={report.framework} />\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Status</dt>\n <dd className=\"mt-0.5\">\n <StatusBadge status={report.status} />\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Period</dt>\n <dd className=\"mt-0.5 text-sm text-text-primary tabular-nums\">\n {formatDate(report.periodStart)} – {formatDate(report.periodEnd)}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Published</dt>\n <dd className=\"mt-0.5 text-sm text-text-primary\">{formatDate(report.publishedAt)}</dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Line items</dt>\n <dd className=\"mt-0.5 text-sm text-text-primary tabular-nums\">{lineItems.length}</dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-tertiary\">Attachment</dt>\n <dd className=\"mt-0.5 text-sm\">\n {report.file?.id ? (\n <FileLink fileId={report.file.id} />\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n )}\n </dd>\n </div>\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 text-text-tertiary\">Quick actions</p>\n <Button onClick={() => setLineItemOpen(true)}>\n <ListPlus className=\"mr-1.5 h-4 w-4\" /> Add line item\n </Button>\n {report.status !== 'PUBLISHED' && (\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 <Plus 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 />\n ) : (\n <>\n <div className=\"mb-3 flex items-center justify-end gap-2 text-sm\">\n <span className=\"text-text-tertiary\">Total value</span>\n <span className=\"font-semibold text-text-primary tabular-nums\">\n {formatNumber(total)}\n </span>\n </div>\n <DataTable columns={lineItemColumns} rows={lineItems} rowKey={(li) => li.id} />\n </>\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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"}