@burdenoff/microfe-ecoimpacthub 2026.704.2 → 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.
- package/dist/ecoimpacthub/components/EcoDiscussion.js +109 -0
- package/dist/ecoimpacthub/components/EcoDiscussion.js.map +1 -0
- package/dist/ecoimpacthub/components/EcoTags.js +149 -0
- package/dist/ecoimpacthub/components/EcoTags.js.map +1 -0
- package/dist/ecoimpacthub/components/EvidenceUpload.js +93 -0
- package/dist/ecoimpacthub/components/EvidenceUpload.js.map +1 -0
- package/dist/ecoimpacthub/components/FileLink.js +36 -0
- package/dist/ecoimpacthub/components/FileLink.js.map +1 -0
- package/dist/ecoimpacthub/components/PageLayout.js +2 -2
- package/dist/ecoimpacthub/components/PageLayout.js.map +1 -1
- package/dist/ecoimpacthub/hooks/index.js +3 -0
- package/dist/ecoimpacthub/hooks/useEcoComments.js +45 -0
- package/dist/ecoimpacthub/hooks/useEcoComments.js.map +1 -0
- package/dist/ecoimpacthub/hooks/useEcoFiles.js +81 -0
- package/dist/ecoimpacthub/hooks/useEcoFiles.js.map +1 -0
- package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.js +169 -166
- package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.js.map +1 -1
- package/dist/ecoimpacthub/hooks/useEcoTags.js +89 -0
- package/dist/ecoimpacthub/hooks/useEcoTags.js.map +1 -0
- package/dist/ecoimpacthub/pages/observations/ObservationsPage.js +124 -101
- package/dist/ecoimpacthub/pages/observations/ObservationsPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/reports/ReportDetailPage.js +153 -126
- package/dist/ecoimpacthub/pages/reports/ReportDetailPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/sites/SiteDetailPage.js +241 -230
- package/dist/ecoimpacthub/pages/sites/SiteDetailPage.js.map +1 -1
- package/dist/ecoimpacthub/pages/species/SpeciesDetailPage.js +260 -225
- package/dist/ecoimpacthub/pages/species/SpeciesDetailPage.js.map +1 -1
- 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 {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
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
|
|
18
|
-
let { id:
|
|
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
|
-
}), [
|
|
25
|
-
return
|
|
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__ */
|
|
28
|
-
}) :
|
|
30
|
+
children: /* @__PURE__ */ T(s, {})
|
|
31
|
+
}) : V || !z ? /* @__PURE__ */ T(t, {
|
|
29
32
|
title: "Report",
|
|
30
|
-
children: /* @__PURE__ */
|
|
33
|
+
children: /* @__PURE__ */ T(o, {
|
|
31
34
|
message: "This report could not be loaded.",
|
|
32
|
-
onRetry: () =>
|
|
35
|
+
onRetry: () => H()
|
|
33
36
|
})
|
|
34
|
-
}) : /* @__PURE__ */
|
|
35
|
-
title:
|
|
36
|
-
description: [r(
|
|
37
|
-
actions: /* @__PURE__ */
|
|
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: () =>
|
|
40
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
46
|
+
/* @__PURE__ */ E("div", {
|
|
44
47
|
className: "grid grid-cols-1 gap-4 lg:grid-cols-3",
|
|
45
|
-
children: [/* @__PURE__ */
|
|
48
|
+
children: [/* @__PURE__ */ E(O, {
|
|
46
49
|
treatment: "glass",
|
|
47
50
|
className: "p-6 lg:col-span-2",
|
|
48
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
54
|
+
/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
|
|
52
55
|
className: "text-xs text-text-tertiary",
|
|
53
56
|
children: "Framework"
|
|
54
|
-
}), /* @__PURE__ */
|
|
57
|
+
}), /* @__PURE__ */ T("dd", {
|
|
55
58
|
className: "mt-0.5",
|
|
56
|
-
children: /* @__PURE__ */
|
|
59
|
+
children: /* @__PURE__ */ T(a, { status: z.framework })
|
|
57
60
|
})] }),
|
|
58
|
-
/* @__PURE__ */
|
|
61
|
+
/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
|
|
59
62
|
className: "text-xs text-text-tertiary",
|
|
60
63
|
children: "Status"
|
|
61
|
-
}), /* @__PURE__ */
|
|
64
|
+
}), /* @__PURE__ */ T("dd", {
|
|
62
65
|
className: "mt-0.5",
|
|
63
|
-
children: /* @__PURE__ */
|
|
66
|
+
children: /* @__PURE__ */ T(a, { status: z.status })
|
|
64
67
|
})] }),
|
|
65
|
-
/* @__PURE__ */
|
|
68
|
+
/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
|
|
66
69
|
className: "text-xs text-text-tertiary",
|
|
67
70
|
children: "Period"
|
|
68
|
-
}), /* @__PURE__ */
|
|
71
|
+
}), /* @__PURE__ */ E("dd", {
|
|
69
72
|
className: "mt-0.5 text-sm text-text-primary tabular-nums",
|
|
70
73
|
children: [
|
|
71
|
-
n(
|
|
74
|
+
n(z.periodStart),
|
|
72
75
|
" – ",
|
|
73
|
-
n(
|
|
76
|
+
n(z.periodEnd)
|
|
74
77
|
]
|
|
75
78
|
})] }),
|
|
76
|
-
/* @__PURE__ */
|
|
79
|
+
/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
|
|
77
80
|
className: "text-xs text-text-tertiary",
|
|
78
81
|
children: "Published"
|
|
79
|
-
}), /* @__PURE__ */
|
|
82
|
+
}), /* @__PURE__ */ T("dd", {
|
|
80
83
|
className: "mt-0.5 text-sm text-text-primary",
|
|
81
|
-
children: n(
|
|
84
|
+
children: n(z.publishedAt)
|
|
82
85
|
})] }),
|
|
83
|
-
/* @__PURE__ */
|
|
86
|
+
/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("dt", {
|
|
84
87
|
className: "text-xs text-text-tertiary",
|
|
85
88
|
children: "Line items"
|
|
86
|
-
}), /* @__PURE__ */
|
|
89
|
+
}), /* @__PURE__ */ T("dd", {
|
|
87
90
|
className: "mt-0.5 text-sm text-text-primary tabular-nums",
|
|
88
|
-
children:
|
|
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
|
-
}),
|
|
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:
|
|
106
|
+
children: z.summary
|
|
94
107
|
})]
|
|
95
|
-
}), /* @__PURE__ */
|
|
108
|
+
}), /* @__PURE__ */ E(O, {
|
|
96
109
|
treatment: "glass",
|
|
97
110
|
className: "flex flex-col gap-3 p-6",
|
|
98
111
|
children: [
|
|
99
|
-
/* @__PURE__ */
|
|
112
|
+
/* @__PURE__ */ T("p", {
|
|
100
113
|
className: "text-xs text-text-tertiary",
|
|
101
114
|
children: "Quick actions"
|
|
102
115
|
}),
|
|
103
|
-
/* @__PURE__ */
|
|
104
|
-
onClick: () =>
|
|
105
|
-
children: [/* @__PURE__ */
|
|
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
|
-
|
|
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 (
|
|
111
|
-
|
|
129
|
+
if (L) {
|
|
130
|
+
X(null);
|
|
112
131
|
try {
|
|
113
|
-
await
|
|
132
|
+
await W.mutateAsync({
|
|
133
|
+
id: L,
|
|
134
|
+
fileId: Z?.fileId ?? null
|
|
135
|
+
}), Q(null);
|
|
114
136
|
} catch (e) {
|
|
115
|
-
|
|
137
|
+
X(e instanceof Error ? e.message : "Failed to publish report.");
|
|
116
138
|
}
|
|
117
139
|
}
|
|
118
140
|
},
|
|
119
|
-
disabled:
|
|
120
|
-
children: [/* @__PURE__ */ S
|
|
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
|
-
|
|
147
|
+
Y && /* @__PURE__ */ T("p", {
|
|
126
148
|
className: "mt-4 text-sm text-status-error-text",
|
|
127
|
-
children:
|
|
149
|
+
children: Y
|
|
128
150
|
}),
|
|
129
|
-
/* @__PURE__ */
|
|
151
|
+
/* @__PURE__ */ T(c, {
|
|
130
152
|
title: "Line items",
|
|
131
153
|
description: "Quantified disclosures that make up this report.",
|
|
132
|
-
action: /* @__PURE__ */
|
|
154
|
+
action: /* @__PURE__ */ E(D, {
|
|
133
155
|
size: "sm",
|
|
134
|
-
onClick: () =>
|
|
135
|
-
children: [/* @__PURE__ */
|
|
156
|
+
onClick: () => K(!0),
|
|
157
|
+
children: [/* @__PURE__ */ T(x, { className: "mr-1.5 h-4 w-4" }), " Add line item"]
|
|
136
158
|
}),
|
|
137
|
-
children:
|
|
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__ */
|
|
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__ */
|
|
165
|
+
children: [/* @__PURE__ */ T("span", {
|
|
144
166
|
className: "text-text-tertiary",
|
|
145
167
|
children: "Total value"
|
|
146
|
-
}), /* @__PURE__ */
|
|
168
|
+
}), /* @__PURE__ */ T("span", {
|
|
147
169
|
className: "font-semibold text-text-primary tabular-nums",
|
|
148
|
-
children: i(
|
|
170
|
+
children: i(ee)
|
|
149
171
|
})]
|
|
150
|
-
}), /* @__PURE__ */
|
|
172
|
+
}), /* @__PURE__ */ T(p, {
|
|
151
173
|
columns: [
|
|
152
174
|
{
|
|
153
175
|
key: "label",
|
|
154
176
|
header: "Line item",
|
|
155
|
-
render: (e) => /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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:
|
|
206
|
+
rows: $,
|
|
185
207
|
rowKey: (e) => e.id
|
|
186
208
|
})] })
|
|
187
209
|
}),
|
|
188
|
-
/* @__PURE__ */
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
221
|
+
z.title,
|
|
195
222
|
"."
|
|
196
223
|
] })] }),
|
|
197
|
-
/* @__PURE__ */
|
|
224
|
+
/* @__PURE__ */ E("div", {
|
|
198
225
|
className: "grid gap-4 py-2",
|
|
199
226
|
children: [
|
|
200
|
-
/* @__PURE__ */
|
|
227
|
+
/* @__PURE__ */ E("div", {
|
|
201
228
|
className: "grid gap-1.5",
|
|
202
|
-
children: [/* @__PURE__ */
|
|
229
|
+
children: [/* @__PURE__ */ T(A, {
|
|
203
230
|
htmlFor: "liLabel",
|
|
204
231
|
children: "Label *"
|
|
205
|
-
}), /* @__PURE__ */
|
|
232
|
+
}), /* @__PURE__ */ T(k, {
|
|
206
233
|
id: "liLabel",
|
|
207
|
-
value:
|
|
208
|
-
onChange: (e) =>
|
|
209
|
-
...
|
|
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__ */
|
|
242
|
+
/* @__PURE__ */ E("div", {
|
|
216
243
|
className: "grid gap-2 sm:grid-cols-2",
|
|
217
|
-
children: [/* @__PURE__ */
|
|
244
|
+
children: [/* @__PURE__ */ E("div", {
|
|
218
245
|
className: "grid gap-1.5",
|
|
219
|
-
children: [/* @__PURE__ */
|
|
246
|
+
children: [/* @__PURE__ */ T(A, {
|
|
220
247
|
htmlFor: "liValue",
|
|
221
248
|
children: "Value *"
|
|
222
|
-
}), /* @__PURE__ */
|
|
249
|
+
}), /* @__PURE__ */ T(k, {
|
|
223
250
|
id: "liValue",
|
|
224
251
|
type: "number",
|
|
225
252
|
step: "any",
|
|
226
|
-
value:
|
|
227
|
-
onChange: (e) =>
|
|
228
|
-
...
|
|
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__ */
|
|
260
|
+
}), /* @__PURE__ */ E("div", {
|
|
234
261
|
className: "grid gap-1.5",
|
|
235
|
-
children: [/* @__PURE__ */
|
|
262
|
+
children: [/* @__PURE__ */ T(A, {
|
|
236
263
|
htmlFor: "liUnit",
|
|
237
264
|
children: "Unit *"
|
|
238
|
-
}), /* @__PURE__ */
|
|
265
|
+
}), /* @__PURE__ */ T(k, {
|
|
239
266
|
id: "liUnit",
|
|
240
|
-
value:
|
|
241
|
-
onChange: (e) =>
|
|
242
|
-
...
|
|
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__ */
|
|
276
|
+
/* @__PURE__ */ E("div", {
|
|
250
277
|
className: "grid gap-1.5",
|
|
251
|
-
children: [/* @__PURE__ */
|
|
278
|
+
children: [/* @__PURE__ */ T(A, {
|
|
252
279
|
htmlFor: "liCategory",
|
|
253
280
|
children: "Category"
|
|
254
|
-
}), /* @__PURE__ */
|
|
281
|
+
}), /* @__PURE__ */ T(k, {
|
|
255
282
|
id: "liCategory",
|
|
256
|
-
value:
|
|
257
|
-
onChange: (e) =>
|
|
258
|
-
...
|
|
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__ */
|
|
291
|
+
/* @__PURE__ */ E("div", {
|
|
265
292
|
className: "grid gap-1.5",
|
|
266
|
-
children: [/* @__PURE__ */
|
|
293
|
+
children: [/* @__PURE__ */ T(A, {
|
|
267
294
|
htmlFor: "liCarbonEntry",
|
|
268
295
|
children: "Carbon entry ID"
|
|
269
|
-
}), /* @__PURE__ */
|
|
296
|
+
}), /* @__PURE__ */ T(k, {
|
|
270
297
|
id: "liCarbonEntry",
|
|
271
|
-
value:
|
|
272
|
-
onChange: (e) =>
|
|
273
|
-
...
|
|
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__ */
|
|
308
|
+
/* @__PURE__ */ E(P, { children: [/* @__PURE__ */ T(D, {
|
|
282
309
|
variant: "outline",
|
|
283
|
-
onClick: () =>
|
|
310
|
+
onClick: () => K(!1),
|
|
284
311
|
children: "Cancel"
|
|
285
|
-
}), /* @__PURE__ */
|
|
312
|
+
}), /* @__PURE__ */ T(D, {
|
|
286
313
|
onClick: async () => {
|
|
287
|
-
if (
|
|
288
|
-
if (!
|
|
289
|
-
|
|
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
|
-
|
|
319
|
+
X(null);
|
|
293
320
|
try {
|
|
294
|
-
await
|
|
295
|
-
reportId:
|
|
296
|
-
label:
|
|
297
|
-
value: Number(
|
|
298
|
-
unit:
|
|
299
|
-
category:
|
|
300
|
-
carbonEntryId:
|
|
301
|
-
}),
|
|
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
|
-
|
|
336
|
+
X(e instanceof Error ? e.message : "Failed to add line item.");
|
|
310
337
|
}
|
|
311
338
|
}
|
|
312
339
|
},
|
|
313
|
-
disabled:
|
|
314
|
-
children:
|
|
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 {
|
|
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":";;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,IAAmB;CACjC,IAAM,EAAE,UAAO,GAA2B,EACpC,EAAE,kBAAe,GAAiB,EAClC,EAAE,MAAM,GAAQ,cAAW,YAAS,eAAY,EAAa,EAAG,EAEhE,IAAc,GAAyB,EACvC,IAAgB,GAAqB,EAErC,CAAC,GAAc,KAAmB,EAAS,GAAM,EACjD,CAAC,GAAc,KAAmB,EAAS;EAC/C,OAAO;EACP,OAAO;EACP,MAAM;EACN,UAAU;EACV,eAAe;EAChB,CAAC,EACI,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAY,KAAiB,EAAiC,KAAK,EAEpE,IAAY,QAAc,GAAQ,aAAa,EAAE,EAAE,CAAC,EAAO,CAAC,EAC5D,KAAQ,QAAc,EAAU,QAAQ,GAAK,MAAO,IAAM,EAAG,OAAO,EAAE,EAAE,CAAC,EAAU,CAAC;AA4E1F,QA1EI,IAEA,kBAAC,GAAD;EAAY,OAAM;YAChB,kBAAC,GAAD,EAAe,CAAA;EACJ,CAAA,GAGb,KAAW,CAAC,IAEZ,kBAAC,GAAD;EAAY,OAAM;YAChB,kBAAC,GAAD;GAAW,SAAQ;GAAmC,eAAe,GAAS;GAAI,CAAA;EACvE,CAAA,GAgEf,kBAAC,GAAD;EACE,OAAO,EAAO;EACd,aAAa,CAAC,EAAgB,EAAO,UAAU,EAAE,EAAgB,EAAO,OAAO,CAAC,CAC7E,OAAO,QAAQ,CACf,KAAK,MAAM;EACd,SACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAa,QAAQ,EAAO,QAAU,CAAA,EACtC,kBAAC,GAAD;GAAQ,SAAQ;GAAQ,eAAe,EAAW,UAAU;aAA5D,CACE,kBAAC,GAAD,EAAW,WAAU,kBAAmB,CAAA,EAAA,QACjC;KACR,EAAA,CAAA;YAXP;GAeE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAW,WAAU;KAAQ,WAAU;eAAvC,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBAA6B;QAAc,CAAA,EACzD,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,GAAD,EAAa,QAAQ,EAAO,WAAa,CAAA;QACtC,CAAA,CACD,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBAA6B;QAAW,CAAA,EACtD,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,GAAD,EAAa,QAAQ,EAAO,QAAU,CAAA;QACnC,CAAA,CACD,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBAA6B;QAAW,CAAA,EACtD,kBAAC,MAAD;QAAI,WAAU;kBAAd;SACG,EAAW,EAAO,YAAY;SAAC;SAAI,EAAW,EAAO,UAAU;SAC7D;UACD,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBAA6B;QAAc,CAAA,EACzD,kBAAC,MAAD;QAAI,WAAU;kBAAoC,EAAW,EAAO,YAAY;QAAM,CAAA,CAClF,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBAA6B;QAAe,CAAA,EAC1D,kBAAC,MAAD;QAAI,WAAU;kBAAiD,EAAU;QAAY,CAAA,CACjF,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBAA6B;QAAe,CAAA,EAC1D,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAO,MAAM,KACZ,kBAAC,GAAD,EAAU,QAAQ,EAAO,KAAK,IAAM,CAAA,GAEpC,kBAAC,QAAD;SAAM,WAAU;mBAAqB;SAAQ,CAAA;QAE5C,CAAA,CACD,EAAA,CAAA;OACH;SACJ,EAAO,WACN,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAO;MACN,CAAA,CAEI;QAEZ,kBAAC,GAAD;KAAW,WAAU;KAAQ,WAAU;eAAvC;MACE,kBAAC,KAAD;OAAG,WAAU;iBAA6B;OAAiB,CAAA;MAC3D,kBAAC,GAAD;OAAQ,eAAe,EAAgB,GAAK;iBAA5C,CACE,kBAAC,GAAD,EAAU,WAAU,kBAAmB,CAAA,EAAA,iBAChC;;MACR,EAAO,WAAW,eACjB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;OACE,IAAG;OACH,OAAM;OACN,OAAO;OACP,UAAU;OACV,MAAK;OACL,CAAA,EACF,kBAAC,GAAD;OAAQ,SAAQ;OAAU,SAjHhB,YAAY;AAC3B,eACL;WAAS,KAAK;AACd,aAAI;AAEF,UADA,MAAM,EAAc,YAAY;WAAE;WAAI,QAAQ,GAAY,UAAU;WAAM,CAAC,EAC3E,EAAc,KAAK;kBACZ,GAAK;AACZ,YAAS,aAAe,QAAQ,EAAI,UAAU,4BAA4B;;;;OA0GhB,UAAU,EAAc;iBAA1E,CACE,kBAAC,GAAD,EAAM,WAAU,kBAAmB,CAAA,EAClC,EAAc,YAAY,gBAAgB,iBACpC;SACR,EAAA,CAAA;MAEK;OACR;;GAEL,KAAS,kBAAC,KAAD;IAAG,WAAU;cAAuC;IAAU,CAAA;GAGxE,kBAAC,GAAD;IACE,OAAM;IACN,aAAY;IACZ,QACE,kBAAC,GAAD;KAAQ,MAAK;KAAK,eAAe,EAAgB,GAAK;eAAtD,CACE,kBAAC,GAAD,EAAM,WAAU,kBAAmB,CAAA,EAAA,iBAC5B;;cAGV,EAAU,WAAW,IACpB,kBAAC,GAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,CAAA,GAEF,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAqB;MAAkB,CAAA,EACvD,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAa,GAAM;MACf,CAAA,CACH;QACN,kBAAC,GAAD;KAAW,SAzIgC;MACnD;OACE,KAAK;OACL,QAAQ;OACR,SAAS,MAAO,kBAAC,QAAD;QAAM,WAAU;kBAAmC,EAAG;QAAa,CAAA;OACpF;MACD;OACE,KAAK;OACL,QAAQ;OACR,cAAc;OACd,SAAS,MAAO,kBAAC,QAAD;QAAM,WAAU;kBAAuB,EAAG,YAAY;QAAW,CAAA;OAClF;MACD;OACE,KAAK;OACL,QAAQ;OACR,OAAO;OACP,YAAY,MAAO,EAAG;OACtB,SAAS,MACP,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACG,EAAa,EAAG,MAAM;SAAC;SAAE,EAAG;SACxB;;OAEV;MACF;KAkH8C,MAAM;KAAW,SAAS,MAAO,EAAG;KAAM,CAAA,CAC9E,EAAA,CAAA;IAEG,CAAA;GAGV,kBAAC,GAAD;IACE,YAAW;IACX,UAAU,EAAO;IACjB,aAAY;IACZ,CAAA;GAGF,kBAAC,GAAD;IAAkB,MAAM;IAAc,cAAc;cAClD,kBAAC,GAAD,EAAA,UAAA;KACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAuB,iBAAqC,CAAA,EAC5D,kBAAC,GAAD,EAAA,UAAA;MAA6B;MACS,EAAO;MAAM;MACrB,EAAA,CAAA,CACP,EAAA,CAAA;KACzB,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;mBAAU;SAAe,CAAA,EACxC,kBAAC,GAAD;SACE,IAAG;SACH,OAAO,EAAa;SACpB,WAAW,MAAM,EAAgB;UAAE,GAAG;UAAc,OAAO,EAAE,OAAO;UAAO,CAAC;SAC5E,aAAY;SACZ,CAAA,CACE;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;oBAAU;UAAe,CAAA,EACxC,kBAAC,GAAD;UACE,IAAG;UACH,MAAK;UACL,MAAK;UACL,OAAO,EAAa;UACpB,WAAW,MAAM,EAAgB;WAAE,GAAG;WAAc,OAAO,EAAE,OAAO;WAAO,CAAC;UAC5E,aAAY;UACZ,CAAA,CACE;YACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;oBAAS;UAAc,CAAA,EACtC,kBAAC,GAAD;UACE,IAAG;UACH,OAAO,EAAa;UACpB,WAAW,MAAM,EAAgB;WAAE,GAAG;WAAc,MAAM,EAAE,OAAO;WAAO,CAAC;UAC3E,aAAY;UACZ,CAAA,CACE;WACF;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;mBAAa;SAAgB,CAAA,EAC5C,kBAAC,GAAD;SACE,IAAG;SACH,OAAO,EAAa;SACpB,WAAW,MAAM,EAAgB;UAAE,GAAG;UAAc,UAAU,EAAE,OAAO;UAAO,CAAC;SAC/E,aAAY;SACZ,CAAA,CACE;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;mBAAgB;SAAuB,CAAA,EACtD,kBAAC,GAAD;SACE,IAAG;SACH,OAAO,EAAa;SACpB,WAAW,MACT,EAAgB;UAAE,GAAG;UAAc,eAAe,EAAE,OAAO;UAAO,CAAC;SAErE,aAAY;SACZ,CAAA,CACE;;OACF;;KACN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAQ,SAAQ;MAAU,eAAe,EAAgB,GAAM;gBAAE;MAExD,CAAA,EACT,kBAAC,GAAD;MAAQ,SAzPQ,YAAY;AAC/B,cACL;YAAI,CAAC,EAAa,MAAM,MAAM,IAAI,CAAC,EAAa,SAAS,CAAC,EAAa,KAAK,MAAM,EAAE;AAClF,WAAS,sCAAsC;AAC/C;;AAEF,UAAS,KAAK;AACd,YAAI;AAUF,SATA,MAAM,EAAY,YAAY;UAC5B,UAAU;UACV,OAAO,EAAa,MAAM,MAAM;UAChC,OAAO,OAAO,EAAa,MAAM;UACjC,MAAM,EAAa,KAAK,MAAM;UAC9B,UAAU,EAAa,SAAS,MAAM,IAAI;UAC1C,eAAe,EAAa,cAAc,MAAM,IAAI;UACrD,CAAC,EACF,EAAgB,GAAM,EACtB,EAAgB;UAAE,OAAO;UAAI,OAAO;UAAI,MAAM;UAAI,UAAU;UAAI,eAAe;UAAI,CAAC;iBAC7E,GAAK;AACZ,WAAS,aAAe,QAAQ,EAAI,UAAU,2BAA2B;;;;MAsO/B,UAAU,EAAY;gBACvD,EAAY,YAAY,YAAY;MAC9B,CAAA,CACc,EAAA,CAAA;KACD,EAAA,CAAA;IACT,CAAA;GACR"}
|