@burdenoff/microfe-ecoimpacthub 2026.704.2 → 2026.704.4

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/useEcoComments.js +45 -0
  13. package/dist/ecoimpacthub/hooks/useEcoComments.js.map +1 -0
  14. package/dist/ecoimpacthub/hooks/useEcoFiles.js +81 -0
  15. package/dist/ecoimpacthub/hooks/useEcoFiles.js.map +1 -0
  16. package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.js +169 -166
  17. package/dist/ecoimpacthub/hooks/useEcoImpactHubApi.js.map +1 -1
  18. package/dist/ecoimpacthub/hooks/useEcoTags.js +89 -0
  19. package/dist/ecoimpacthub/hooks/useEcoTags.js.map +1 -0
  20. package/dist/ecoimpacthub/pages/carbon/CarbonPage.js +4 -0
  21. package/dist/ecoimpacthub/pages/carbon/CarbonPage.js.map +1 -1
  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
@@ -1,20 +1,23 @@
1
1
  import { useEcoImpactHub as e } from "../../context/EcoImpactHubContext.js";
2
2
  import { PageLayout as t } from "../../components/PageLayout.js";
3
- import { formatDateTime as ee, formatEnumLabel as n, formatNumber as te } from "../../utils/formatters.js";
4
- import { StatusBadge as r } from "../../components/StatusBadge.js";
5
- import { ErrorView as i, LoadingView as a, Section as o } from "../../components/StateViews.js";
6
- import { EmptyState as s } from "../../components/EmptyState.js";
3
+ import { formatDateTime as n, formatEnumLabel as r, formatNumber as ee } from "../../utils/formatters.js";
4
+ import { StatusBadge as i } from "../../components/StatusBadge.js";
5
+ import { ErrorView as a, LoadingView as te, Section as ne } from "../../components/StateViews.js";
6
+ import { EmptyState as re } from "../../components/EmptyState.js";
7
7
  import "../../context/index.js";
8
- import { useEcoArchiveSpecies as c, useEcoRecordObservation as ne, useEcoSites as re, useEcoSpeciesDetail as ie, useEcoUpdateSpecies as ae } from "../../hooks/useEcoImpactHubApi.js";
8
+ import { useEcoArchiveSpecies as ie, useEcoRecordObservation as ae, useEcoSites as oe, useEcoSpeciesDetail as se, useEcoUpdateSpecies as ce } from "../../hooks/useEcoImpactHubApi.js";
9
9
  import "../../hooks/index.js";
10
- import { DataTable as oe } from "../../components/DataTable.js";
11
- import { useState as l } from "react";
12
- import { Archive as se, ArrowLeft as ce, Binoculars as u, Pencil as le, Star as ue } from "lucide-react";
13
- import { useParams as de } from "react-router-dom";
14
- import { Fragment as fe, jsx as d, jsxs as f } from "react/jsx-runtime";
15
- import { Button as p, GlassCard as m, Input as h, Label as g, ResponsiveDialog as _, ResponsiveDialogContent as v, ResponsiveDialogDescription as y, ResponsiveDialogFooter as b, ResponsiveDialogHeader as x, ResponsiveDialogTitle as S, Select as C, SelectContent as w, SelectItem as T, SelectTrigger as E, SelectValue as D, Textarea as O } from "@burdenoff/fe-libs/ui";
10
+ import { DataTable as le } from "../../components/DataTable.js";
11
+ import { EvidenceUpload as ue } from "../../components/EvidenceUpload.js";
12
+ import { FileLink as de } from "../../components/FileLink.js";
13
+ import { EcoTags as fe } from "../../components/EcoTags.js";
14
+ import { useState as o } from "react";
15
+ import { Archive as pe, ArrowLeft as s, Binoculars as c, Pencil as l, Star as u } from "lucide-react";
16
+ import { useParams as d } from "react-router-dom";
17
+ import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
18
+ import { Button as h, GlassCard as g, Input as _, Label as v, ResponsiveDialog as y, ResponsiveDialogContent as b, ResponsiveDialogDescription as x, ResponsiveDialogFooter as S, ResponsiveDialogHeader as C, ResponsiveDialogTitle as w, Select as T, SelectContent as E, SelectItem as D, SelectTrigger as O, SelectValue as k, Textarea as A } from "@burdenoff/fe-libs/ui";
16
19
  //#region src/ecoimpacthub/pages/species/SpeciesDetailPage.tsx
17
- var k = [
20
+ var j = [
18
21
  "DIRECT_SIGHTING",
19
22
  "CAMERA_TRAP",
20
23
  "ACOUSTIC",
@@ -22,7 +25,7 @@ var k = [
22
25
  "EDNA",
23
26
  "TELEMETRY",
24
27
  "COMMUNITY_REPORT"
25
- ], A = [
28
+ ], M = [
26
29
  "MAMMAL",
27
30
  "BIRD",
28
31
  "REPTILE",
@@ -32,7 +35,7 @@ var k = [
32
35
  "PLANT",
33
36
  "FUNGI",
34
37
  "OTHER"
35
- ], j = [
38
+ ], N = [
36
39
  "LEAST_CONCERN",
37
40
  "NEAR_THREATENED",
38
41
  "VULNERABLE",
@@ -41,177 +44,189 @@ var k = [
41
44
  "EXTINCT_IN_WILD",
42
45
  "DATA_DEFICIENT",
43
46
  "NOT_EVALUATED"
44
- ], M = (e) => {
47
+ ], P = (e) => {
45
48
  let t = (e) => String(e).padStart(2, "0");
46
49
  return `${e.getFullYear()}-${t(e.getMonth() + 1)}-${t(e.getDate())}T${t(e.getHours())}:${t(e.getMinutes())}`;
47
50
  };
48
- function N() {
49
- let { id: N } = de(), { navigateTo: P } = e(), { data: F, isLoading: I, isError: L, refetch: R } = ie(N), z = re({ pagination: {
51
+ function F() {
52
+ let { id: F } = d(), { navigateTo: I } = e(), { data: L, isLoading: R, isError: z, refetch: me } = se(F), he = oe({ pagination: {
50
53
  limit: 100,
51
54
  offset: 0
52
- } }), B = ne(), V = ae(), H = c(), [pe, U] = l(!1), [W, G] = l({
55
+ } }), B = ae(), V = ce(), H = ie(), [ge, U] = o(!1), [W, G] = o({
53
56
  method: "DIRECT_SIGHTING",
54
57
  count: "1",
55
- observedAt: M(/* @__PURE__ */ new Date()),
58
+ observedAt: P(/* @__PURE__ */ new Date()),
56
59
  siteId: "",
57
- notes: ""
58
- }), [K, q] = l(!1), [J, Y] = l({
60
+ notes: "",
61
+ evidence: null
62
+ }), [_e, K] = o(!1), [q, J] = o({
59
63
  commonName: "",
60
64
  scientificName: "",
61
65
  taxonGroup: "MAMMAL",
62
66
  conservationStatus: "NOT_EVALUATED",
63
67
  isPriority: !1,
64
68
  description: ""
65
- }), [X, Z] = l(null);
66
- if (I) return /* @__PURE__ */ d(t, {
69
+ }), [Y, X] = o(null);
70
+ if (R) return /* @__PURE__ */ p(t, {
67
71
  title: "Species",
68
- children: /* @__PURE__ */ d(a, {})
72
+ children: /* @__PURE__ */ p(te, {})
69
73
  });
70
- if (L || !F) return /* @__PURE__ */ d(t, {
74
+ if (z || !L) return /* @__PURE__ */ p(t, {
71
75
  title: "Species",
72
- children: /* @__PURE__ */ d(i, {
76
+ children: /* @__PURE__ */ p(a, {
73
77
  message: "This species could not be loaded.",
74
- onRetry: () => R()
78
+ onRetry: () => me()
75
79
  })
76
80
  });
77
- let Q = F.observations ?? [], me = z.data?.items ?? [], $ = () => {
81
+ let Z = L.observations ?? [], Q = he.data?.items ?? [], $ = () => {
78
82
  G({
79
83
  method: "DIRECT_SIGHTING",
80
84
  count: "1",
81
- observedAt: M(/* @__PURE__ */ new Date()),
85
+ observedAt: P(/* @__PURE__ */ new Date()),
82
86
  siteId: "",
83
- notes: ""
84
- }), Z(null), U(!0);
87
+ notes: "",
88
+ evidence: null
89
+ }), X(null), U(!0);
85
90
  };
86
- return /* @__PURE__ */ f(t, {
87
- title: F.commonName,
88
- description: [F.scientificName, n(F.taxonGroup)].filter(Boolean).join(" · "),
89
- actions: /* @__PURE__ */ f(fe, { children: [/* @__PURE__ */ d(r, { status: F.conservationStatus }), /* @__PURE__ */ f(p, {
91
+ return /* @__PURE__ */ m(t, {
92
+ title: L.commonName,
93
+ description: [L.scientificName, r(L.taxonGroup)].filter(Boolean).join(" · "),
94
+ actions: /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(i, { status: L.conservationStatus }), /* @__PURE__ */ m(h, {
90
95
  variant: "ghost",
91
- onClick: () => P("species"),
92
- children: [/* @__PURE__ */ d(ce, { className: "mr-1.5 h-4 w-4" }), " Back"]
96
+ onClick: () => I("species"),
97
+ children: [/* @__PURE__ */ p(s, { className: "mr-1.5 h-4 w-4" }), " Back"]
93
98
  })] }),
94
99
  children: [
95
- /* @__PURE__ */ f("div", {
100
+ /* @__PURE__ */ m("div", {
96
101
  className: "grid grid-cols-1 gap-4 lg:grid-cols-3",
97
- children: [/* @__PURE__ */ f(m, {
102
+ children: [/* @__PURE__ */ m(g, {
98
103
  treatment: "glass",
99
104
  className: "p-6 lg:col-span-2",
100
- children: [/* @__PURE__ */ f("dl", {
101
- className: "grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-3",
102
- children: [
103
- /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("dt", {
104
- className: "text-xs text-text-tertiary",
105
- children: "Scientific name"
106
- }), /* @__PURE__ */ d("dd", {
107
- className: "mt-0.5 text-sm italic text-text-primary",
108
- children: F.scientificName ?? "—"
109
- })] }),
110
- /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("dt", {
111
- className: "text-xs text-text-tertiary",
112
- children: "Taxon group"
113
- }), /* @__PURE__ */ d("dd", {
114
- className: "mt-0.5 text-sm text-text-primary",
115
- children: n(F.taxonGroup)
116
- })] }),
117
- /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("dt", {
118
- className: "text-xs text-text-tertiary",
119
- children: "Conservation"
120
- }), /* @__PURE__ */ d("dd", {
121
- className: "mt-0.5",
122
- children: /* @__PURE__ */ d(r, { status: F.conservationStatus })
123
- })] }),
124
- /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("dt", {
125
- className: "text-xs text-text-tertiary",
126
- children: "Priority"
127
- }), /* @__PURE__ */ d("dd", {
128
- className: "mt-0.5 text-sm text-text-primary",
129
- children: F.isPriority ? /* @__PURE__ */ f("span", {
130
- className: "inline-flex items-center gap-1 text-status-warning-text",
131
- children: [/* @__PURE__ */ d(ue, { className: "h-4 w-4 fill-current" }), " Priority"]
132
- }) : "—"
133
- })] }),
134
- /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("dt", {
135
- className: "text-xs text-text-tertiary",
136
- children: "Observations"
137
- }), /* @__PURE__ */ d("dd", {
138
- className: "mt-0.5 text-sm text-text-primary tabular-nums",
139
- children: Q.length
140
- })] })
141
- ]
142
- }), F.description && /* @__PURE__ */ d("p", {
143
- className: "mt-5 rounded-lg bg-bg-sunken/60 p-3 text-sm text-text-secondary",
144
- children: F.description
145
- })]
146
- }), /* @__PURE__ */ f(m, {
105
+ children: [
106
+ /* @__PURE__ */ m("dl", {
107
+ className: "grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-3",
108
+ children: [
109
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
110
+ className: "text-xs text-text-tertiary",
111
+ children: "Scientific name"
112
+ }), /* @__PURE__ */ p("dd", {
113
+ className: "mt-0.5 text-sm italic text-text-primary",
114
+ children: L.scientificName ?? "—"
115
+ })] }),
116
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
117
+ className: "text-xs text-text-tertiary",
118
+ children: "Taxon group"
119
+ }), /* @__PURE__ */ p("dd", {
120
+ className: "mt-0.5 text-sm text-text-primary",
121
+ children: r(L.taxonGroup)
122
+ })] }),
123
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
124
+ className: "text-xs text-text-tertiary",
125
+ children: "Conservation"
126
+ }), /* @__PURE__ */ p("dd", {
127
+ className: "mt-0.5",
128
+ children: /* @__PURE__ */ p(i, { status: L.conservationStatus })
129
+ })] }),
130
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
131
+ className: "text-xs text-text-tertiary",
132
+ children: "Priority"
133
+ }), /* @__PURE__ */ p("dd", {
134
+ className: "mt-0.5 text-sm text-text-primary",
135
+ children: L.isPriority ? /* @__PURE__ */ m("span", {
136
+ className: "inline-flex items-center gap-1 text-status-warning-text",
137
+ children: [/* @__PURE__ */ p(u, { className: "h-4 w-4 fill-current" }), " Priority"]
138
+ }) : "—"
139
+ })] }),
140
+ /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
141
+ className: "text-xs text-text-tertiary",
142
+ children: "Observations"
143
+ }), /* @__PURE__ */ p("dd", {
144
+ className: "mt-0.5 text-sm text-text-primary tabular-nums",
145
+ children: Z.length
146
+ })] })
147
+ ]
148
+ }),
149
+ L.description && /* @__PURE__ */ p("p", {
150
+ className: "mt-5 rounded-lg bg-bg-sunken/60 p-3 text-sm text-text-secondary",
151
+ children: L.description
152
+ }),
153
+ /* @__PURE__ */ p("div", {
154
+ className: "mt-5 border-t border-border-seam pt-4",
155
+ children: /* @__PURE__ */ p(fe, {
156
+ entityType: "ecoimpacthub-species",
157
+ entityId: L.id
158
+ })
159
+ })
160
+ ]
161
+ }), /* @__PURE__ */ m(g, {
147
162
  treatment: "glass",
148
163
  className: "flex flex-col gap-3 p-6",
149
164
  children: [
150
- /* @__PURE__ */ d("p", {
165
+ /* @__PURE__ */ p("p", {
151
166
  className: "text-xs text-text-tertiary",
152
167
  children: "Quick actions"
153
168
  }),
154
- /* @__PURE__ */ f(p, {
169
+ /* @__PURE__ */ m(h, {
155
170
  onClick: $,
156
- children: [/* @__PURE__ */ d(u, { className: "mr-1.5 h-4 w-4" }), " Record observation"]
171
+ children: [/* @__PURE__ */ p(c, { className: "mr-1.5 h-4 w-4" }), " Record observation"]
157
172
  }),
158
- /* @__PURE__ */ f(p, {
173
+ /* @__PURE__ */ m(h, {
159
174
  variant: "outline",
160
175
  onClick: () => {
161
- Y({
162
- commonName: F.commonName,
163
- scientificName: F.scientificName ?? "",
164
- taxonGroup: F.taxonGroup,
165
- conservationStatus: F.conservationStatus,
166
- isPriority: F.isPriority,
167
- description: F.description ?? ""
168
- }), Z(null), q(!0);
176
+ J({
177
+ commonName: L.commonName,
178
+ scientificName: L.scientificName ?? "",
179
+ taxonGroup: L.taxonGroup,
180
+ conservationStatus: L.conservationStatus,
181
+ isPriority: L.isPriority,
182
+ description: L.description ?? ""
183
+ }), X(null), K(!0);
169
184
  },
170
- children: [/* @__PURE__ */ d(le, { className: "mr-1.5 h-4 w-4" }), " Edit species"]
185
+ children: [/* @__PURE__ */ p(l, { className: "mr-1.5 h-4 w-4" }), " Edit species"]
171
186
  }),
172
- /* @__PURE__ */ f(p, {
187
+ /* @__PURE__ */ m(h, {
173
188
  variant: "ghost",
174
189
  onClick: async () => {
175
- if (N) {
176
- Z(null);
190
+ if (F) {
191
+ X(null);
177
192
  try {
178
- await H.mutateAsync(N), P("species");
193
+ await H.mutateAsync(F), I("species");
179
194
  } catch (e) {
180
- Z(e instanceof Error ? e.message : "Failed to archive species.");
195
+ X(e instanceof Error ? e.message : "Failed to archive species.");
181
196
  }
182
197
  }
183
198
  },
184
199
  disabled: H.isPending,
185
200
  className: "text-status-error-text hover:text-status-error-text",
186
- children: [/* @__PURE__ */ d(se, { className: "mr-1.5 h-4 w-4" }), " Archive"]
201
+ children: [/* @__PURE__ */ p(pe, { className: "mr-1.5 h-4 w-4" }), " Archive"]
187
202
  })
188
203
  ]
189
204
  })]
190
205
  }),
191
- X && /* @__PURE__ */ d("p", {
206
+ Y && /* @__PURE__ */ p("p", {
192
207
  className: "mt-4 text-sm text-status-error-text",
193
- children: X
208
+ children: Y
194
209
  }),
195
- /* @__PURE__ */ d(o, {
210
+ /* @__PURE__ */ p(ne, {
196
211
  title: "Observations",
197
212
  description: "Field records logged against this species.",
198
- action: /* @__PURE__ */ f(p, {
213
+ action: /* @__PURE__ */ m(h, {
199
214
  size: "sm",
200
215
  onClick: $,
201
- children: [/* @__PURE__ */ d(u, { className: "mr-1.5 h-4 w-4" }), " Record observation"]
216
+ children: [/* @__PURE__ */ p(c, { className: "mr-1.5 h-4 w-4" }), " Record observation"]
202
217
  }),
203
- children: Q.length === 0 ? /* @__PURE__ */ d(s, {
218
+ children: Z.length === 0 ? /* @__PURE__ */ p(re, {
204
219
  illustration: "empty-data",
205
220
  title: "No observations yet",
206
221
  description: "Record a field observation to see it here."
207
- }) : /* @__PURE__ */ d(oe, {
222
+ }) : /* @__PURE__ */ p(le, {
208
223
  columns: [
209
224
  {
210
225
  key: "method",
211
226
  header: "Method",
212
- render: (e) => /* @__PURE__ */ d("span", {
227
+ render: (e) => /* @__PURE__ */ p("span", {
213
228
  className: "font-medium text-text-primary",
214
- children: n(e.method)
229
+ children: r(e.method)
215
230
  })
216
231
  },
217
232
  {
@@ -219,27 +234,27 @@ function N() {
219
234
  header: "Count",
220
235
  align: "right",
221
236
  sortValue: (e) => e.count,
222
- render: (e) => /* @__PURE__ */ d("span", {
237
+ render: (e) => /* @__PURE__ */ p("span", {
223
238
  className: "tabular-nums text-text-primary",
224
- children: te(e.count)
239
+ children: ee(e.count)
225
240
  })
226
241
  },
227
242
  {
228
243
  key: "observedAt",
229
244
  header: "Observed",
230
- render: (e) => /* @__PURE__ */ d("span", {
245
+ render: (e) => /* @__PURE__ */ p("span", {
231
246
  className: "text-text-secondary",
232
- children: ee(e.observedAt)
247
+ children: n(e.observedAt)
233
248
  })
234
249
  },
235
250
  {
236
251
  key: "site",
237
252
  header: "Site",
238
253
  hideOnMobile: !0,
239
- render: (e) => e.siteId ? /* @__PURE__ */ d("span", {
254
+ render: (e) => e.siteId ? /* @__PURE__ */ p("span", {
240
255
  className: "text-text-secondary",
241
256
  children: e.siteId
242
- }) : /* @__PURE__ */ d("span", {
257
+ }) : /* @__PURE__ */ p("span", {
243
258
  className: "text-text-tertiary",
244
259
  children: "—"
245
260
  })
@@ -248,55 +263,64 @@ function N() {
248
263
  key: "notes",
249
264
  header: "Notes",
250
265
  hideOnMobile: !0,
251
- render: (e) => /* @__PURE__ */ d("span", {
266
+ render: (e) => /* @__PURE__ */ p("span", {
252
267
  className: "text-text-secondary",
253
268
  children: e.notes ?? "—"
254
269
  })
270
+ },
271
+ {
272
+ key: "evidence",
273
+ header: "Evidence",
274
+ hideOnMobile: !0,
275
+ render: (e) => e.evidence?.id ? /* @__PURE__ */ p(de, { fileId: e.evidence.id }) : /* @__PURE__ */ p("span", {
276
+ className: "text-text-tertiary",
277
+ children: "—"
278
+ })
255
279
  }
256
280
  ],
257
- rows: Q,
281
+ rows: Z,
258
282
  rowKey: (e) => e.id
259
283
  })
260
284
  }),
261
- /* @__PURE__ */ d(_, {
262
- open: pe,
285
+ /* @__PURE__ */ p(y, {
286
+ open: ge,
263
287
  onOpenChange: U,
264
- children: /* @__PURE__ */ f(v, { children: [
265
- /* @__PURE__ */ f(x, { children: [/* @__PURE__ */ d(S, { children: "Record observation" }), /* @__PURE__ */ f(y, { children: [
288
+ children: /* @__PURE__ */ m(b, { children: [
289
+ /* @__PURE__ */ m(C, { children: [/* @__PURE__ */ p(w, { children: "Record observation" }), /* @__PURE__ */ m(x, { children: [
266
290
  "Log a field sighting or detection of ",
267
- F.commonName,
291
+ L.commonName,
268
292
  "."
269
293
  ] })] }),
270
- /* @__PURE__ */ f("div", {
294
+ /* @__PURE__ */ m("div", {
271
295
  className: "grid gap-4 py-2",
272
296
  children: [
273
- /* @__PURE__ */ f("div", {
297
+ /* @__PURE__ */ m("div", {
274
298
  className: "grid gap-2 sm:grid-cols-2",
275
- children: [/* @__PURE__ */ f("div", {
299
+ children: [/* @__PURE__ */ m("div", {
276
300
  className: "grid gap-1.5",
277
- children: [/* @__PURE__ */ d(g, {
301
+ children: [/* @__PURE__ */ p(v, {
278
302
  htmlFor: "obsMethod",
279
303
  children: "Method"
280
- }), /* @__PURE__ */ f(C, {
304
+ }), /* @__PURE__ */ m(T, {
281
305
  value: W.method,
282
306
  onValueChange: (e) => G({
283
307
  ...W,
284
308
  method: e
285
309
  }),
286
- children: [/* @__PURE__ */ d(E, {
310
+ children: [/* @__PURE__ */ p(O, {
287
311
  id: "obsMethod",
288
- children: /* @__PURE__ */ d(D, {})
289
- }), /* @__PURE__ */ d(w, { children: k.map((e) => /* @__PURE__ */ d(T, {
312
+ children: /* @__PURE__ */ p(k, {})
313
+ }), /* @__PURE__ */ p(E, { children: j.map((e) => /* @__PURE__ */ p(D, {
290
314
  value: e,
291
- children: n(e)
315
+ children: r(e)
292
316
  }, e)) })]
293
317
  })]
294
- }), /* @__PURE__ */ f("div", {
318
+ }), /* @__PURE__ */ m("div", {
295
319
  className: "grid gap-1.5",
296
- children: [/* @__PURE__ */ d(g, {
320
+ children: [/* @__PURE__ */ p(v, {
297
321
  htmlFor: "obsCount",
298
322
  children: "Count"
299
- }), /* @__PURE__ */ d(h, {
323
+ }), /* @__PURE__ */ p(_, {
300
324
  id: "obsCount",
301
325
  type: "number",
302
326
  min: "1",
@@ -310,12 +334,12 @@ function N() {
310
334
  })]
311
335
  })]
312
336
  }),
313
- /* @__PURE__ */ f("div", {
337
+ /* @__PURE__ */ m("div", {
314
338
  className: "grid gap-1.5",
315
- children: [/* @__PURE__ */ d(g, {
339
+ children: [/* @__PURE__ */ p(v, {
316
340
  htmlFor: "obsAt",
317
341
  children: "Observed at"
318
- }), /* @__PURE__ */ d(h, {
342
+ }), /* @__PURE__ */ p(_, {
319
343
  id: "obsAt",
320
344
  type: "datetime-local",
321
345
  value: W.observedAt,
@@ -325,32 +349,32 @@ function N() {
325
349
  })
326
350
  })]
327
351
  }),
328
- /* @__PURE__ */ f("div", {
352
+ /* @__PURE__ */ m("div", {
329
353
  className: "grid gap-1.5",
330
- children: [/* @__PURE__ */ d(g, {
354
+ children: [/* @__PURE__ */ p(v, {
331
355
  htmlFor: "obsSite",
332
356
  children: "Site (optional)"
333
- }), /* @__PURE__ */ f(C, {
357
+ }), /* @__PURE__ */ m(T, {
334
358
  value: W.siteId,
335
359
  onValueChange: (e) => G({
336
360
  ...W,
337
361
  siteId: e
338
362
  }),
339
- children: [/* @__PURE__ */ d(E, {
363
+ children: [/* @__PURE__ */ p(O, {
340
364
  id: "obsSite",
341
- children: /* @__PURE__ */ d(D, { placeholder: "No site" })
342
- }), /* @__PURE__ */ d(w, { children: me.map((e) => /* @__PURE__ */ d(T, {
365
+ children: /* @__PURE__ */ p(k, { placeholder: "No site" })
366
+ }), /* @__PURE__ */ p(E, { children: Q.map((e) => /* @__PURE__ */ p(D, {
343
367
  value: e.id,
344
368
  children: e.name
345
369
  }, e.id)) })]
346
370
  })]
347
371
  }),
348
- /* @__PURE__ */ f("div", {
372
+ /* @__PURE__ */ m("div", {
349
373
  className: "grid gap-1.5",
350
- children: [/* @__PURE__ */ d(g, {
374
+ children: [/* @__PURE__ */ p(v, {
351
375
  htmlFor: "obsNotes",
352
376
  children: "Notes"
353
- }), /* @__PURE__ */ d(O, {
377
+ }), /* @__PURE__ */ p(A, {
354
378
  id: "obsNotes",
355
379
  value: W.notes,
356
380
  onChange: (e) => G({
@@ -360,28 +384,39 @@ function N() {
360
384
  placeholder: "Optional context — behaviour, conditions, evidence.",
361
385
  rows: 2
362
386
  })]
387
+ }),
388
+ /* @__PURE__ */ p(ue, {
389
+ id: "speciesObsEvidence",
390
+ label: "Evidence photo (optional)",
391
+ value: W.evidence,
392
+ onChange: (e) => G({
393
+ ...W,
394
+ evidence: e
395
+ }),
396
+ hint: "Attach a photo, audio clip or PDF as supporting evidence."
363
397
  })
364
398
  ]
365
399
  }),
366
- /* @__PURE__ */ f(b, { children: [/* @__PURE__ */ d(p, {
400
+ /* @__PURE__ */ m(S, { children: [/* @__PURE__ */ p(h, {
367
401
  variant: "outline",
368
402
  onClick: () => U(!1),
369
403
  children: "Cancel"
370
- }), /* @__PURE__ */ d(p, {
404
+ }), /* @__PURE__ */ p(h, {
371
405
  onClick: async () => {
372
- if (N) {
373
- Z(null);
406
+ if (F) {
407
+ X(null);
374
408
  try {
375
409
  await B.mutateAsync({
376
- speciesId: N,
410
+ speciesId: F,
377
411
  method: W.method,
378
412
  count: W.count ? Number(W.count) : 1,
379
413
  observedAt: new Date(W.observedAt).toISOString(),
380
414
  siteId: W.siteId || null,
381
- notes: W.notes.trim() || null
415
+ notes: W.notes.trim() || null,
416
+ evidenceFileId: W.evidence?.fileId ?? null
382
417
  }), U(!1);
383
418
  } catch (e) {
384
- Z(e instanceof Error ? e.message : "Failed to record observation.");
419
+ X(e instanceof Error ? e.message : "Failed to record observation.");
385
420
  }
386
421
  }
387
422
  },
@@ -390,110 +425,110 @@ function N() {
390
425
  })] })
391
426
  ] })
392
427
  }),
393
- /* @__PURE__ */ d(_, {
394
- open: K,
395
- onOpenChange: q,
396
- children: /* @__PURE__ */ f(v, { children: [
397
- /* @__PURE__ */ f(x, { children: [/* @__PURE__ */ d(S, { children: "Edit species" }), /* @__PURE__ */ d(y, { children: "Update naming, classification and priority for this species." })] }),
398
- /* @__PURE__ */ f("div", {
428
+ /* @__PURE__ */ p(y, {
429
+ open: _e,
430
+ onOpenChange: K,
431
+ children: /* @__PURE__ */ m(b, { children: [
432
+ /* @__PURE__ */ m(C, { children: [/* @__PURE__ */ p(w, { children: "Edit species" }), /* @__PURE__ */ p(x, { children: "Update naming, classification and priority for this species." })] }),
433
+ /* @__PURE__ */ m("div", {
399
434
  className: "grid gap-4 py-2",
400
435
  children: [
401
- /* @__PURE__ */ f("div", {
436
+ /* @__PURE__ */ m("div", {
402
437
  className: "grid gap-2 sm:grid-cols-2",
403
- children: [/* @__PURE__ */ f("div", {
438
+ children: [/* @__PURE__ */ m("div", {
404
439
  className: "grid gap-1.5",
405
- children: [/* @__PURE__ */ d(g, {
440
+ children: [/* @__PURE__ */ p(v, {
406
441
  htmlFor: "editCommon",
407
442
  children: "Common name *"
408
- }), /* @__PURE__ */ d(h, {
443
+ }), /* @__PURE__ */ p(_, {
409
444
  id: "editCommon",
410
- value: J.commonName,
411
- onChange: (e) => Y({
412
- ...J,
445
+ value: q.commonName,
446
+ onChange: (e) => J({
447
+ ...q,
413
448
  commonName: e.target.value
414
449
  }),
415
450
  placeholder: "Indian Pangolin"
416
451
  })]
417
- }), /* @__PURE__ */ f("div", {
452
+ }), /* @__PURE__ */ m("div", {
418
453
  className: "grid gap-1.5",
419
- children: [/* @__PURE__ */ d(g, {
454
+ children: [/* @__PURE__ */ p(v, {
420
455
  htmlFor: "editScientific",
421
456
  children: "Scientific name"
422
- }), /* @__PURE__ */ d(h, {
457
+ }), /* @__PURE__ */ p(_, {
423
458
  id: "editScientific",
424
- value: J.scientificName,
425
- onChange: (e) => Y({
426
- ...J,
459
+ value: q.scientificName,
460
+ onChange: (e) => J({
461
+ ...q,
427
462
  scientificName: e.target.value
428
463
  }),
429
464
  placeholder: "Manis crassicaudata"
430
465
  })]
431
466
  })]
432
467
  }),
433
- /* @__PURE__ */ f("div", {
468
+ /* @__PURE__ */ m("div", {
434
469
  className: "grid gap-2 sm:grid-cols-2",
435
- children: [/* @__PURE__ */ f("div", {
470
+ children: [/* @__PURE__ */ m("div", {
436
471
  className: "grid gap-1.5",
437
- children: [/* @__PURE__ */ d(g, {
472
+ children: [/* @__PURE__ */ p(v, {
438
473
  htmlFor: "editTaxon",
439
474
  children: "Taxon group"
440
- }), /* @__PURE__ */ f(C, {
441
- value: J.taxonGroup,
442
- onValueChange: (e) => Y({
443
- ...J,
475
+ }), /* @__PURE__ */ m(T, {
476
+ value: q.taxonGroup,
477
+ onValueChange: (e) => J({
478
+ ...q,
444
479
  taxonGroup: e
445
480
  }),
446
- children: [/* @__PURE__ */ d(E, {
481
+ children: [/* @__PURE__ */ p(O, {
447
482
  id: "editTaxon",
448
- children: /* @__PURE__ */ d(D, {})
449
- }), /* @__PURE__ */ d(w, { children: A.map((e) => /* @__PURE__ */ d(T, {
483
+ children: /* @__PURE__ */ p(k, {})
484
+ }), /* @__PURE__ */ p(E, { children: M.map((e) => /* @__PURE__ */ p(D, {
450
485
  value: e,
451
- children: n(e)
486
+ children: r(e)
452
487
  }, e)) })]
453
488
  })]
454
- }), /* @__PURE__ */ f("div", {
489
+ }), /* @__PURE__ */ m("div", {
455
490
  className: "grid gap-1.5",
456
- children: [/* @__PURE__ */ d(g, {
491
+ children: [/* @__PURE__ */ p(v, {
457
492
  htmlFor: "editConservation",
458
493
  children: "Conservation status"
459
- }), /* @__PURE__ */ f(C, {
460
- value: J.conservationStatus,
461
- onValueChange: (e) => Y({
462
- ...J,
494
+ }), /* @__PURE__ */ m(T, {
495
+ value: q.conservationStatus,
496
+ onValueChange: (e) => J({
497
+ ...q,
463
498
  conservationStatus: e
464
499
  }),
465
- children: [/* @__PURE__ */ d(E, {
500
+ children: [/* @__PURE__ */ p(O, {
466
501
  id: "editConservation",
467
- children: /* @__PURE__ */ d(D, {})
468
- }), /* @__PURE__ */ d(w, { children: j.map((e) => /* @__PURE__ */ d(T, {
502
+ children: /* @__PURE__ */ p(k, {})
503
+ }), /* @__PURE__ */ p(E, { children: N.map((e) => /* @__PURE__ */ p(D, {
469
504
  value: e,
470
- children: n(e)
505
+ children: r(e)
471
506
  }, e)) })]
472
507
  })]
473
508
  })]
474
509
  }),
475
- /* @__PURE__ */ f("label", {
510
+ /* @__PURE__ */ m("label", {
476
511
  className: "flex items-center gap-2 text-sm text-text-primary",
477
- children: [/* @__PURE__ */ d("input", {
512
+ children: [/* @__PURE__ */ p("input", {
478
513
  type: "checkbox",
479
- checked: J.isPriority,
480
- onChange: (e) => Y({
481
- ...J,
514
+ checked: q.isPriority,
515
+ onChange: (e) => J({
516
+ ...q,
482
517
  isPriority: e.target.checked
483
518
  }),
484
519
  className: "h-4 w-4 rounded border-border-seam accent-action-primary-bg"
485
520
  }), "Mark as priority species"]
486
521
  }),
487
- /* @__PURE__ */ f("div", {
522
+ /* @__PURE__ */ m("div", {
488
523
  className: "grid gap-1.5",
489
- children: [/* @__PURE__ */ d(g, {
524
+ children: [/* @__PURE__ */ p(v, {
490
525
  htmlFor: "editDescription",
491
526
  children: "Description"
492
- }), /* @__PURE__ */ d(O, {
527
+ }), /* @__PURE__ */ p(A, {
493
528
  id: "editDescription",
494
- value: J.description,
495
- onChange: (e) => Y({
496
- ...J,
529
+ value: q.description,
530
+ onChange: (e) => J({
531
+ ...q,
497
532
  description: e.target.value
498
533
  }),
499
534
  placeholder: "Optional notes on habitat, range or identification.",
@@ -502,31 +537,31 @@ function N() {
502
537
  })
503
538
  ]
504
539
  }),
505
- /* @__PURE__ */ f(b, { children: [/* @__PURE__ */ d(p, {
540
+ /* @__PURE__ */ m(S, { children: [/* @__PURE__ */ p(h, {
506
541
  variant: "outline",
507
- onClick: () => q(!1),
542
+ onClick: () => K(!1),
508
543
  children: "Cancel"
509
- }), /* @__PURE__ */ d(p, {
544
+ }), /* @__PURE__ */ p(h, {
510
545
  onClick: async () => {
511
- if (!N || !J.commonName.trim()) {
512
- Z("Common name is required.");
546
+ if (!F || !q.commonName.trim()) {
547
+ X("Common name is required.");
513
548
  return;
514
549
  }
515
- Z(null);
550
+ X(null);
516
551
  try {
517
552
  await V.mutateAsync({
518
- id: N,
553
+ id: F,
519
554
  input: {
520
- commonName: J.commonName.trim(),
521
- scientificName: J.scientificName.trim() || null,
522
- taxonGroup: J.taxonGroup,
523
- conservationStatus: J.conservationStatus,
524
- isPriority: J.isPriority,
525
- description: J.description.trim() || null
555
+ commonName: q.commonName.trim(),
556
+ scientificName: q.scientificName.trim() || null,
557
+ taxonGroup: q.taxonGroup,
558
+ conservationStatus: q.conservationStatus,
559
+ isPriority: q.isPriority,
560
+ description: q.description.trim() || null
526
561
  }
527
- }), q(!1);
562
+ }), K(!1);
528
563
  } catch (e) {
529
- Z(e instanceof Error ? e.message : "Failed to update species.");
564
+ X(e instanceof Error ? e.message : "Failed to update species.");
530
565
  }
531
566
  },
532
567
  disabled: V.isPending,
@@ -538,6 +573,6 @@ function N() {
538
573
  });
539
574
  }
540
575
  //#endregion
541
- export { N as SpeciesDetailPage };
576
+ export { F as SpeciesDetailPage };
542
577
 
543
578
  //# sourceMappingURL=SpeciesDetailPage.js.map