@burdenoff/microfe-comradecircle 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 (54) hide show
  1. package/dist/comradecircle/components/Avatar.js +52 -17
  2. package/dist/comradecircle/components/Avatar.js.map +1 -1
  3. package/dist/comradecircle/components/AvatarUploadField.js +91 -0
  4. package/dist/comradecircle/components/AvatarUploadField.js.map +1 -0
  5. package/dist/comradecircle/components/CircleCard.js +55 -52
  6. package/dist/comradecircle/components/CircleCard.js.map +1 -1
  7. package/dist/comradecircle/components/CommentThread.js +80 -64
  8. package/dist/comradecircle/components/CommentThread.js.map +1 -1
  9. package/dist/comradecircle/components/CreateCircleDialog.js +74 -63
  10. package/dist/comradecircle/components/CreateCircleDialog.js.map +1 -1
  11. package/dist/comradecircle/components/EventCard.js +84 -58
  12. package/dist/comradecircle/components/EventCard.js.map +1 -1
  13. package/dist/comradecircle/components/FileImage.js +20 -0
  14. package/dist/comradecircle/components/FileImage.js.map +1 -0
  15. package/dist/comradecircle/components/ImageAttachments.js +97 -0
  16. package/dist/comradecircle/components/ImageAttachments.js.map +1 -0
  17. package/dist/comradecircle/components/MemberIdentity.js +4 -2
  18. package/dist/comradecircle/components/MemberIdentity.js.map +1 -1
  19. package/dist/comradecircle/components/PollCard.js +65 -44
  20. package/dist/comradecircle/components/PollCard.js.map +1 -1
  21. package/dist/comradecircle/components/PostCard.js +8 -15
  22. package/dist/comradecircle/components/PostCard.js.map +1 -1
  23. package/dist/comradecircle/components/PostComposer.js +45 -35
  24. package/dist/comradecircle/components/PostComposer.js.map +1 -1
  25. package/dist/comradecircle/components/ReactionBar.js +1 -1
  26. package/dist/comradecircle/components/ReactionBar.js.map +1 -1
  27. package/dist/comradecircle/components/StateViews.js +1 -16
  28. package/dist/comradecircle/components/StateViews.js.map +1 -1
  29. package/dist/comradecircle/components/StatusBadge.js +1 -1
  30. package/dist/comradecircle/components/StatusBadge.js.map +1 -1
  31. package/dist/comradecircle/hooks/index.js +1 -0
  32. package/dist/comradecircle/hooks/useComradeCircleApi.js +244 -241
  33. package/dist/comradecircle/hooks/useComradeCircleApi.js.map +1 -1
  34. package/dist/comradecircle/hooks/useFiles.js +78 -0
  35. package/dist/comradecircle/hooks/useFiles.js.map +1 -0
  36. package/dist/comradecircle/lib/graphql-cache.js +9 -0
  37. package/dist/comradecircle/lib/graphql-cache.js.map +1 -0
  38. package/dist/comradecircle/pages/FeedPage.js +79 -33
  39. package/dist/comradecircle/pages/FeedPage.js.map +1 -1
  40. package/dist/comradecircle/pages/circles/CircleDetailPage.js +354 -242
  41. package/dist/comradecircle/pages/circles/CircleDetailPage.js.map +1 -1
  42. package/dist/comradecircle/pages/circles/CirclesPage.js +97 -47
  43. package/dist/comradecircle/pages/circles/CirclesPage.js.map +1 -1
  44. package/dist/comradecircle/pages/events/EventDetailPage.js +193 -126
  45. package/dist/comradecircle/pages/events/EventDetailPage.js.map +1 -1
  46. package/dist/comradecircle/pages/events/EventsPage.js +74 -34
  47. package/dist/comradecircle/pages/events/EventsPage.js.map +1 -1
  48. package/dist/comradecircle/pages/members/MemberProfilePage.js +154 -81
  49. package/dist/comradecircle/pages/members/MemberProfilePage.js.map +1 -1
  50. package/dist/comradecircle/pages/members/MembersPage.js +141 -71
  51. package/dist/comradecircle/pages/members/MembersPage.js.map +1 -1
  52. package/dist/comradecircle/pages/profile/MyProfilePage.js +298 -191
  53. package/dist/comradecircle/pages/profile/MyProfilePage.js.map +1 -1
  54. package/package.json +1 -1
@@ -1,19 +1,22 @@
1
1
  import { useComradeCircle as e } from "../../context/ComradeCircleContext.js";
2
- import { PageLayout as t } from "../../components/PageLayout.js";
2
+ import { cn as t } from "../../utils/cn.js";
3
+ import { PageLayout as n } from "../../components/PageLayout.js";
3
4
  import "../../context/index.js";
4
- import { useComEvent as n, useComRsvpEvent as r, useComTransitionEvent as i } from "../../hooks/useComradeCircleApi.js";
5
+ import { useComEvent as ee, useComRsvpEvent as te, useComTransitionEvent as r } from "../../hooks/useComradeCircleApi.js";
5
6
  import "../../hooks/index.js";
6
- import { MemberIdentity as a } from "../../components/MemberIdentity.js";
7
- import { describeError as o, notify as s } from "../../lib/toast.js";
8
- import { formatDateTime as c, formatEnumLabel as l, formatNumber as u } from "../../utils/formatters.js";
7
+ import { MemberIdentity as i } from "../../components/MemberIdentity.js";
8
+ import { describeError as a, notify as o } from "../../lib/toast.js";
9
+ import { formatDateTime as s, formatEnumLabel as c, formatNumber as l } from "../../utils/formatters.js";
10
+ import { EmptyState as u } from "../../components/EmptyState.js";
9
11
  import { ErrorView as d, LoadingView as f } from "../../components/StateViews.js";
10
12
  import { StatusBadge as p } from "../../components/StatusBadge.js";
11
- import { ArrowLeft as m, Ban as h, CalendarDays as g, CheckCircle2 as _, ExternalLink as v, MapPin as y, Radio as b, Tag as x, Users as S, Video as C } from "lucide-react";
12
- import { useParams as w } from "react-router-dom";
13
- import { Fragment as T, jsx as E, jsxs as D } from "react/jsx-runtime";
14
- import { Button as O, GlassCard as k } from "@burdenoff/fe-libs/ui";
13
+ import { MiniBar as m } from "../../components/MiniBar.js";
14
+ import { ArrowLeft as h, Ban as ne, CalendarDays as re, Check as g, CheckCircle2 as _, MapPin as v, Radio as y, Tag as b, Users as x, Video as S } from "lucide-react";
15
+ import { useParams as C } from "react-router-dom";
16
+ import { Fragment as ie, jsx as w, jsxs as T } from "react/jsx-runtime";
17
+ import { Button as E, GlassCard as ae } from "@burdenoff/fe-libs/ui";
15
18
  //#region src/comradecircle/pages/events/EventDetailPage.tsx
16
- var A = [
19
+ var oe = [
17
20
  {
18
21
  status: "GOING",
19
22
  label: "Going"
@@ -30,139 +33,192 @@ var A = [
30
33
  status: "NOT_GOING",
31
34
  label: "Can't go"
32
35
  }
36
+ ], D = {
37
+ GOING: 0,
38
+ INTERESTED: 1,
39
+ WAITLISTED: 2,
40
+ NOT_GOING: 3
41
+ }, O = [
42
+ {
43
+ status: "GOING",
44
+ label: "going"
45
+ },
46
+ {
47
+ status: "INTERESTED",
48
+ label: "interested"
49
+ },
50
+ {
51
+ status: "WAITLISTED",
52
+ label: "waitlisted"
53
+ },
54
+ {
55
+ status: "NOT_GOING",
56
+ label: "can't go"
57
+ }
33
58
  ];
34
- function j() {
35
- let { id: j } = w(), { currentUser: M, navigateTo: N } = e(), { data: P, isLoading: F, isError: I, refetch: L } = n(j), R = r(), z = i(), B = /* @__PURE__ */ D(O, {
59
+ function k() {
60
+ let { id: k } = C(), { currentUser: A, navigateTo: j } = e(), { data: M, isLoading: N, isError: P, refetch: F } = ee(k), I = te(), L = r(), R = /* @__PURE__ */ T(E, {
36
61
  variant: "ghost",
37
62
  size: "sm",
38
- onClick: () => N("events"),
39
- children: [/* @__PURE__ */ E(m, { className: "mr-1.5 h-4 w-4" }), " Back"]
63
+ onClick: () => j("events"),
64
+ children: [/* @__PURE__ */ w(h, { className: "mr-1.5 h-4 w-4" }), " Back"]
40
65
  });
41
- if (F) return /* @__PURE__ */ E(t, {
66
+ if (N) return /* @__PURE__ */ w(n, {
42
67
  title: "Event",
43
- actions: B,
44
- children: /* @__PURE__ */ E(f, { label: "Loading event…" })
68
+ actions: R,
69
+ children: /* @__PURE__ */ w(f, { label: "Loading event…" })
45
70
  });
46
- if (I || !P) return /* @__PURE__ */ E(t, {
71
+ if (P || !M) return /* @__PURE__ */ w(n, {
47
72
  title: "Event",
48
- actions: B,
49
- children: /* @__PURE__ */ E(d, {
73
+ actions: R,
74
+ children: /* @__PURE__ */ w(d, {
50
75
  title: "Event not found",
51
76
  message: "This event may have been cancelled, or you may not have access to it.",
52
- onRetry: () => L()
77
+ onRetry: () => F()
53
78
  })
54
79
  });
55
- let V = !!(M?.id && M.id === P.hostId), H = P.status === "SCHEDULED" || P.status === "LIVE", U = P.mode === "ONLINE" || P.mode === "HYBRID", W = P.mode === "IN_PERSON" || P.mode === "HYBRID", G = P.status === "LIVE" && U && !!P.joinUrl, K = M?.id ? P.rsvps.find((e) => e.memberId === M.id) : void 0, q = async (e) => {
80
+ let z = !!(A?.id && A.id === M.hostId), B = M.status === "LIVE", V = M.status === "SCHEDULED" || M.status === "LIVE", H = M.mode === "ONLINE" || M.mode === "HYBRID", U = M.mode === "IN_PERSON" || M.mode === "HYBRID", W = B && H && !!M.joinUrl, G = A?.id ? M.rsvps.find((e) => e.memberId === A.id) : void 0, K = M.capacity ?? null, q = K && K > 0 ? Math.min(100, M.rsvpCount / K * 100) : null, J = q != null && q >= 80, Y = q != null && q >= 100, X = q == null ? "" : Y ? "Full" : `${Math.round(q)}% full`, se = Y ? "bg-status-error-text" : J ? "bg-status-warning-text" : "bg-accent", ce = Y ? "text-status-error-text" : J ? "text-status-warning-text" : "text-text-tertiary", Z = M.rsvps.reduce((e, t) => (e[t.status] += 1, e), {
81
+ GOING: 0,
82
+ INTERESTED: 0,
83
+ WAITLISTED: 0,
84
+ NOT_GOING: 0
85
+ }), le = [...M.rsvps].sort((e, t) => D[e.status] - D[t.status]), Q = O.filter((e) => Z[e.status] > 0).map((e) => `${l(Z[e.status])} ${e.label}`).join(" · "), ue = async (e) => {
56
86
  try {
57
- await R.mutateAsync({
58
- eventId: P.id,
87
+ await I.mutateAsync({
88
+ eventId: M.id,
59
89
  status: e
60
- }), s.success("RSVP updated", `${l(e)} · ${P.title}`);
90
+ }), o.success("RSVP updated", `${c(e)} · ${M.title}`);
61
91
  } catch (e) {
62
- s.error("Could not RSVP", o(e));
92
+ o.error("Could not RSVP", a(e));
63
93
  }
64
- }, J = async (e, t) => {
94
+ }, $ = async (e, t) => {
65
95
  try {
66
- await z.mutateAsync({
67
- id: P.id,
96
+ await L.mutateAsync({
97
+ id: M.id,
68
98
  status: e
69
- }), s.success(t, P.title);
99
+ }), o.success(t, M.title);
70
100
  } catch (e) {
71
- s.error("Could not update the event", o(e));
101
+ o.error("Could not update the event", a(e));
72
102
  }
73
- }, Y = P.endsAt ? `${c(P.startsAt)} – ${c(P.endsAt)}` : c(P.startsAt);
74
- return /* @__PURE__ */ E(t, {
75
- title: P.title,
76
- actions: B,
77
- children: /* @__PURE__ */ D("div", {
103
+ }, de = M.endsAt ? `${s(M.startsAt)} – ${s(M.endsAt)}` : s(M.startsAt);
104
+ return /* @__PURE__ */ w(n, {
105
+ title: M.title,
106
+ actions: R,
107
+ children: /* @__PURE__ */ T("div", {
78
108
  className: "mx-auto flex max-w-3xl flex-col gap-6",
79
109
  children: [
80
- /* @__PURE__ */ D(k, {
110
+ /* @__PURE__ */ T(ae, {
81
111
  treatment: "plain",
82
- className: "flex flex-col gap-5 p-5 sm:p-6",
112
+ className: t("flex flex-col gap-5 p-5 sm:p-6", B && "ring-1 ring-[var(--color-accent-soft)]"),
83
113
  children: [
84
- /* @__PURE__ */ D("div", {
114
+ B && /* @__PURE__ */ w("span", {
115
+ "aria-hidden": "true",
116
+ className: "pointer-events-none absolute inset-0 rounded-card ring-2 ring-accent/60 motion-safe:animate-pulse"
117
+ }),
118
+ /* @__PURE__ */ T("div", {
85
119
  className: "flex flex-wrap items-center gap-2",
86
- children: [/* @__PURE__ */ E(p, { status: P.status }), /* @__PURE__ */ E(p, { status: P.mode })]
120
+ children: [/* @__PURE__ */ w(p, { status: M.status }), /* @__PURE__ */ w(p, { status: M.mode })]
121
+ }),
122
+ W && M.joinUrl && /* @__PURE__ */ w(E, {
123
+ asChild: !0,
124
+ size: "lg",
125
+ className: "w-full justify-center sm:w-auto sm:self-start",
126
+ children: /* @__PURE__ */ T("a", {
127
+ href: M.joinUrl,
128
+ target: "_blank",
129
+ rel: "noreferrer noopener",
130
+ children: [/* @__PURE__ */ w(S, { className: "h-4 w-4" }), " Join the live event"]
131
+ })
87
132
  }),
88
- P.description && /* @__PURE__ */ E("p", {
133
+ M.description && /* @__PURE__ */ w("p", {
89
134
  className: "whitespace-pre-wrap text-sm text-text-secondary",
90
- children: P.description
135
+ children: M.description
91
136
  }),
92
- /* @__PURE__ */ D("dl", {
137
+ /* @__PURE__ */ T("dl", {
93
138
  className: "flex flex-col gap-3 text-sm",
94
139
  children: [
95
- /* @__PURE__ */ D("div", {
140
+ /* @__PURE__ */ T("div", {
96
141
  className: "flex items-start gap-2.5",
97
- children: [/* @__PURE__ */ E(g, { className: "mt-0.5 h-4 w-4 shrink-0 text-text-tertiary" }), /* @__PURE__ */ D("div", { children: [/* @__PURE__ */ E("dt", {
142
+ children: [/* @__PURE__ */ w(re, { className: "mt-0.5 h-4 w-4 shrink-0 text-text-tertiary" }), /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("dt", {
98
143
  className: "text-text-tertiary",
99
144
  children: "When"
100
- }), /* @__PURE__ */ E("dd", {
145
+ }), /* @__PURE__ */ w("dd", {
101
146
  className: "mt-0.5 text-text-primary",
102
- children: Y
147
+ children: de
103
148
  })] })]
104
149
  }),
105
- W && P.location && /* @__PURE__ */ D("div", {
150
+ U && M.location && /* @__PURE__ */ T("div", {
106
151
  className: "flex items-start gap-2.5",
107
- children: [/* @__PURE__ */ E(y, { className: "mt-0.5 h-4 w-4 shrink-0 text-text-tertiary" }), /* @__PURE__ */ D("div", { children: [/* @__PURE__ */ E("dt", {
152
+ children: [/* @__PURE__ */ w(v, { className: "mt-0.5 h-4 w-4 shrink-0 text-text-tertiary" }), /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("dt", {
108
153
  className: "text-text-tertiary",
109
154
  children: "Where"
110
- }), /* @__PURE__ */ E("dd", {
155
+ }), /* @__PURE__ */ w("dd", {
111
156
  className: "mt-0.5 text-text-primary",
112
- children: P.location
157
+ children: M.location
113
158
  })] })]
114
159
  }),
115
- U && /* @__PURE__ */ D("div", {
160
+ H && /* @__PURE__ */ T("div", {
116
161
  className: "flex items-start gap-2.5",
117
- children: [/* @__PURE__ */ E(C, { className: "mt-0.5 h-4 w-4 shrink-0 text-text-tertiary" }), /* @__PURE__ */ D("div", {
162
+ children: [/* @__PURE__ */ w(S, { className: "mt-0.5 h-4 w-4 shrink-0 text-text-tertiary" }), /* @__PURE__ */ T("div", {
118
163
  className: "min-w-0",
119
- children: [/* @__PURE__ */ E("dt", {
164
+ children: [/* @__PURE__ */ w("dt", {
120
165
  className: "text-text-tertiary",
121
166
  children: "Online"
122
- }), /* @__PURE__ */ E("dd", {
167
+ }), /* @__PURE__ */ w("dd", {
123
168
  className: "mt-0.5 text-text-primary",
124
- children: G && P.joinUrl ? /* @__PURE__ */ D("a", {
125
- href: P.joinUrl,
126
- target: "_blank",
127
- rel: "noreferrer noopener",
128
- className: "inline-flex items-center gap-1 font-medium text-accent hover:underline",
129
- children: ["Join the live event ", /* @__PURE__ */ E(v, { className: "h-3.5 w-3.5" })]
130
- }) : /* @__PURE__ */ E("span", {
169
+ children: W ? /* @__PURE__ */ w("span", {
170
+ className: "font-medium text-accent",
171
+ children: "The join link is live — use the button above."
172
+ }) : /* @__PURE__ */ w("span", {
131
173
  className: "text-text-secondary",
132
- children: P.status === "LIVE" ? "A join link has not been provided." : "The join link becomes available when the event goes live."
174
+ children: B ? "A join link has not been provided." : "The join link becomes available when the event goes live."
133
175
  })
134
176
  })]
135
177
  })]
136
178
  }),
137
- /* @__PURE__ */ D("div", {
179
+ /* @__PURE__ */ T("div", {
138
180
  className: "flex items-start gap-2.5",
139
- children: [/* @__PURE__ */ E(S, { className: "mt-0.5 h-4 w-4 shrink-0 text-text-tertiary" }), /* @__PURE__ */ D("div", { children: [/* @__PURE__ */ E("dt", {
140
- className: "text-text-tertiary",
141
- children: "Attending"
142
- }), /* @__PURE__ */ D("dd", {
143
- className: "mt-0.5 text-text-primary",
144
- children: [u(P.rsvpCount), P.capacity ? ` / ${u(P.capacity)}` : ""]
145
- })] })]
181
+ children: [/* @__PURE__ */ w(x, { className: "mt-0.5 h-4 w-4 shrink-0 text-text-tertiary" }), /* @__PURE__ */ T("div", {
182
+ className: "min-w-0 flex-1",
183
+ children: [
184
+ /* @__PURE__ */ w("dt", {
185
+ className: "text-text-tertiary",
186
+ children: "Attending"
187
+ }),
188
+ /* @__PURE__ */ T("dd", {
189
+ className: "mt-0.5 flex flex-wrap items-baseline gap-x-2 text-text-primary",
190
+ children: [/* @__PURE__ */ T("span", { children: [l(M.rsvpCount), K ? ` / ${l(K)}` : ""] }), X && /* @__PURE__ */ w("span", {
191
+ className: t("text-xs font-semibold", ce),
192
+ children: X
193
+ })]
194
+ }),
195
+ q != null && /* @__PURE__ */ w(m, {
196
+ value: q,
197
+ barClassName: se,
198
+ className: "mt-2 max-w-xs"
199
+ })
200
+ ]
201
+ })]
146
202
  })
147
203
  ]
148
204
  }),
149
- P.tags.length > 0 && /* @__PURE__ */ D("div", {
205
+ M.tags.length > 0 && /* @__PURE__ */ T("div", {
150
206
  className: "flex flex-wrap items-center gap-1.5",
151
- children: [/* @__PURE__ */ E(x, {
207
+ children: [/* @__PURE__ */ w(b, {
152
208
  className: "h-3.5 w-3.5 text-text-tertiary",
153
209
  "aria-hidden": "true"
154
- }), P.tags.map((e) => /* @__PURE__ */ D("span", {
210
+ }), M.tags.map((e) => /* @__PURE__ */ T("span", {
155
211
  className: "rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary",
156
212
  children: ["#", e]
157
213
  }, e))]
158
214
  }),
159
- /* @__PURE__ */ D("div", {
215
+ /* @__PURE__ */ T("div", {
160
216
  className: "border-t border-border-seam pt-4",
161
- children: [/* @__PURE__ */ E("p", {
217
+ children: [/* @__PURE__ */ w("p", {
162
218
  className: "mb-2 text-xs font-semibold uppercase tracking-wide text-text-tertiary",
163
219
  children: "Hosted by"
164
- }), /* @__PURE__ */ E(a, {
165
- memberId: P.hostId,
220
+ }), /* @__PURE__ */ w(i, {
221
+ memberId: M.hostId,
166
222
  variant: "row",
167
223
  size: "md",
168
224
  showPresence: !0
@@ -170,98 +226,109 @@ function j() {
170
226
  })
171
227
  ]
172
228
  }),
173
- H && /* @__PURE__ */ D("section", {
229
+ V && /* @__PURE__ */ T("section", {
174
230
  className: "rounded-2xl border border-border-seam bg-bg-surface p-5",
175
231
  children: [
176
- /* @__PURE__ */ E("h2", {
232
+ /* @__PURE__ */ w("h2", {
177
233
  className: "text-base font-semibold text-text-primary",
178
234
  children: "Your RSVP"
179
235
  }),
180
- /* @__PURE__ */ E("p", {
236
+ /* @__PURE__ */ w("p", {
181
237
  className: "mt-0.5 text-sm text-text-secondary",
182
238
  children: "Let the host know whether you'll attend."
183
239
  }),
184
- /* @__PURE__ */ E("div", {
185
- className: "mt-4 flex flex-wrap gap-2",
186
- children: A.map((e) => /* @__PURE__ */ E(O, {
187
- size: "sm",
188
- variant: K?.status === e.status ? "default" : "outline",
189
- onClick: () => q(e.status),
190
- disabled: R.isPending,
191
- children: e.label
192
- }, e.status))
240
+ /* @__PURE__ */ w("div", {
241
+ className: "mt-4 flex flex-col gap-2 sm:flex-row sm:flex-wrap",
242
+ children: oe.map((e) => {
243
+ let n = G?.status === e.status;
244
+ return /* @__PURE__ */ T(E, {
245
+ variant: n ? "default" : "outline",
246
+ onClick: () => ue(e.status),
247
+ disabled: I.isPending,
248
+ "aria-pressed": n,
249
+ className: t("w-full justify-center sm:w-auto", n && "font-semibold shadow-elevation-1"),
250
+ children: [n && /* @__PURE__ */ w(g, { className: "h-4 w-4" }), e.label]
251
+ }, e.status);
252
+ })
193
253
  })
194
254
  ]
195
255
  }),
196
- V && (P.status === "SCHEDULED" || P.status === "LIVE") && /* @__PURE__ */ D("section", {
256
+ z && (M.status === "SCHEDULED" || M.status === "LIVE") && /* @__PURE__ */ T("section", {
197
257
  className: "rounded-2xl border border-border-seam bg-bg-surface p-5",
198
258
  children: [
199
- /* @__PURE__ */ E("h2", {
259
+ /* @__PURE__ */ w("h2", {
200
260
  className: "text-base font-semibold text-text-primary",
201
261
  children: "Host controls"
202
262
  }),
203
- /* @__PURE__ */ E("p", {
263
+ /* @__PURE__ */ w("p", {
204
264
  className: "mt-0.5 text-sm text-text-secondary",
205
265
  children: "Move this event through its lifecycle."
206
266
  }),
207
- /* @__PURE__ */ D("div", {
267
+ /* @__PURE__ */ T("div", {
208
268
  className: "mt-4 flex flex-wrap gap-2",
209
- children: [P.status === "SCHEDULED" && /* @__PURE__ */ D(T, { children: [/* @__PURE__ */ D(O, {
269
+ children: [M.status === "SCHEDULED" && /* @__PURE__ */ T(ie, { children: [/* @__PURE__ */ T(E, {
210
270
  size: "sm",
211
- onClick: () => J("LIVE", "Event is now live"),
212
- disabled: z.isPending,
213
- children: [/* @__PURE__ */ E(b, { className: "mr-1.5 h-4 w-4" }), " Go live"]
214
- }), /* @__PURE__ */ D(O, {
271
+ onClick: () => $("LIVE", "Event is now live"),
272
+ disabled: L.isPending,
273
+ children: [/* @__PURE__ */ w(y, { className: "mr-1.5 h-4 w-4" }), " Go live"]
274
+ }), /* @__PURE__ */ T(E, {
215
275
  size: "sm",
216
276
  variant: "destructive",
217
- onClick: () => J("CANCELLED", "Event cancelled"),
218
- disabled: z.isPending,
219
- children: [/* @__PURE__ */ E(h, { className: "mr-1.5 h-4 w-4" }), " Cancel"]
220
- })] }), P.status === "LIVE" && /* @__PURE__ */ D(O, {
277
+ onClick: () => $("CANCELLED", "Event cancelled"),
278
+ disabled: L.isPending,
279
+ children: [/* @__PURE__ */ w(ne, { className: "mr-1.5 h-4 w-4" }), " Cancel"]
280
+ })] }), M.status === "LIVE" && /* @__PURE__ */ T(E, {
221
281
  size: "sm",
222
- onClick: () => J("COMPLETED", "Event marked complete"),
223
- disabled: z.isPending,
224
- children: [/* @__PURE__ */ E(_, { className: "mr-1.5 h-4 w-4" }), " Mark complete"]
282
+ onClick: () => $("COMPLETED", "Event marked complete"),
283
+ disabled: L.isPending,
284
+ children: [/* @__PURE__ */ w(_, { className: "mr-1.5 h-4 w-4" }), " Mark complete"]
225
285
  })]
226
286
  })
227
287
  ]
228
288
  }),
229
- /* @__PURE__ */ D("section", {
289
+ /* @__PURE__ */ T("section", {
230
290
  className: "rounded-2xl border border-border-seam bg-bg-surface p-5",
231
- children: [/* @__PURE__ */ D("div", {
291
+ children: [/* @__PURE__ */ T("div", {
232
292
  className: "mb-3 flex items-center justify-between gap-3",
233
- children: [/* @__PURE__ */ E("h2", {
234
- className: "text-base font-semibold text-text-primary",
235
- children: "Attendees"
236
- }), /* @__PURE__ */ D("span", {
237
- className: "inline-flex items-center gap-1 text-xs text-text-tertiary",
293
+ children: [/* @__PURE__ */ T("div", {
294
+ className: "min-w-0",
295
+ children: [/* @__PURE__ */ w("h2", {
296
+ className: "text-base font-semibold text-text-primary",
297
+ children: "Attendees"
298
+ }), Q && /* @__PURE__ */ w("p", {
299
+ className: "mt-0.5 truncate text-xs text-text-tertiary",
300
+ children: Q
301
+ })]
302
+ }), /* @__PURE__ */ T("span", {
303
+ className: "inline-flex shrink-0 items-center gap-1 text-xs text-text-tertiary",
238
304
  children: [
239
- /* @__PURE__ */ E(S, { className: "h-3.5 w-3.5" }),
305
+ /* @__PURE__ */ w(x, { className: "h-3.5 w-3.5" }),
240
306
  " ",
241
- u(P.rsvps.length)
307
+ l(M.rsvps.length)
242
308
  ]
243
309
  })]
244
- }), P.rsvps.length === 0 ? /* @__PURE__ */ E("p", {
245
- className: "py-4 text-center text-sm text-text-tertiary",
246
- children: "No RSVPs yet."
247
- }) : /* @__PURE__ */ E("ul", {
310
+ }), M.rsvps.length === 0 ? /* @__PURE__ */ w(u, {
311
+ illustration: "empty-people",
312
+ title: "No RSVPs yet",
313
+ description: "Be the first to let the host know you're coming."
314
+ }) : /* @__PURE__ */ w("ul", {
248
315
  className: "flex flex-col gap-2",
249
- children: P.rsvps.map((e) => /* @__PURE__ */ D("li", {
250
- className: "flex flex-wrap items-center justify-between gap-3 rounded-xl border border-border-seam bg-bg-sunken px-4 py-2.5",
251
- children: [/* @__PURE__ */ E(a, {
316
+ children: le.map((e) => /* @__PURE__ */ T("li", {
317
+ className: "flex flex-wrap items-center justify-between gap-3 rounded-xl border border-border-seam bg-bg-sunken px-4 py-2.5 transition-colors hover:border-[var(--color-accent-soft)]",
318
+ children: [/* @__PURE__ */ w(i, {
252
319
  memberId: e.memberId,
253
320
  variant: "row",
254
321
  size: "sm"
255
- }), /* @__PURE__ */ D("div", {
322
+ }), /* @__PURE__ */ T("div", {
256
323
  className: "flex min-w-0 items-center gap-2",
257
- children: [e.note && /* @__PURE__ */ D("span", {
324
+ children: [e.note && /* @__PURE__ */ T("span", {
258
325
  className: "max-w-[16rem] truncate text-xs text-text-tertiary",
259
326
  children: [
260
327
  "“",
261
328
  e.note,
262
329
  "”"
263
330
  ]
264
- }), /* @__PURE__ */ E(p, { status: e.status })]
331
+ }), /* @__PURE__ */ w(p, { status: e.status })]
265
332
  })]
266
333
  }, e.id))
267
334
  })]
@@ -271,6 +338,6 @@ function j() {
271
338
  });
272
339
  }
273
340
  //#endregion
274
- export { j as EventDetailPage };
341
+ export { k as EventDetailPage };
275
342
 
276
343
  //# sourceMappingURL=EventDetailPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EventDetailPage.js","names":[],"sources":["../../../../src/comradecircle/pages/events/EventDetailPage.tsx"],"sourcesContent":["/**\n * EventDetailPage — a single community event.\n * @module comradecircle/pages/events\n *\n * Reads `comEvent` (with its RSVPs). Members RSVP (GOING / INTERESTED /\n * WAITLISTED / NOT_GOING) while the event is SCHEDULED or LIVE; the host drives\n * the lifecycle (SCHEDULED → LIVE → COMPLETED, or CANCELLED). Person references\n * always resolve through {@link MemberIdentity} — never a raw actor id.\n */\n\nimport {\n ArrowLeft,\n CalendarDays,\n MapPin,\n Video,\n Users,\n ExternalLink,\n Radio,\n CheckCircle2,\n Ban,\n Tag,\n} from 'lucide-react';\nimport { GlassCard, Button } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { MemberIdentity } from '../../components/MemberIdentity';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { useComEvent, useComRsvpEvent, useComTransitionEvent } from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport { formatDateTime, formatNumber, formatEnumLabel } from '../../utils';\nimport { notify, describeError } from '../../lib/toast';\nimport { useParams } from 'react-router-dom';\nimport type { ComEventStatus, ComRsvpStatus } from '../../types';\n\nconst RSVP_OPTIONS: { status: ComRsvpStatus; label: string }[] = [\n { status: 'GOING', label: 'Going' },\n { status: 'INTERESTED', label: 'Interested' },\n { status: 'WAITLISTED', label: 'Waitlist' },\n { status: 'NOT_GOING', label: \"Can't go\" },\n];\n\nexport function EventDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { currentUser, navigateTo } = useComradeCircle();\n const { data: event, isLoading, isError, refetch } = useComEvent(id);\n const rsvp = useComRsvpEvent();\n const transition = useComTransitionEvent();\n\n const backButton = (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateTo('events')}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" /> Back\n </Button>\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"Event\" actions={backButton}>\n <LoadingView label=\"Loading event…\" />\n </PageLayout>\n );\n }\n\n if (isError || !event) {\n return (\n <PageLayout title=\"Event\" actions={backButton}>\n <ErrorView\n title=\"Event not found\"\n message=\"This event may have been cancelled, or you may not have access to it.\"\n onRetry={() => refetch()}\n />\n </PageLayout>\n );\n }\n\n const isHost = Boolean(currentUser?.id && currentUser.id === event.hostId);\n const canRsvp = event.status === 'SCHEDULED' || event.status === 'LIVE';\n const isOnlineish = event.mode === 'ONLINE' || event.mode === 'HYBRID';\n const isInPersonish = event.mode === 'IN_PERSON' || event.mode === 'HYBRID';\n const showJoin = event.status === 'LIVE' && isOnlineish && Boolean(event.joinUrl);\n const myRsvp = currentUser?.id\n ? event.rsvps.find((r) => r.memberId === currentUser.id)\n : undefined;\n\n const doRsvp = async (status: ComRsvpStatus) => {\n try {\n await rsvp.mutateAsync({ eventId: event.id, status });\n notify.success('RSVP updated', `${formatEnumLabel(status)} · ${event.title}`);\n } catch (err) {\n notify.error('Could not RSVP', describeError(err));\n }\n };\n\n const doTransition = async (status: ComEventStatus, successMessage: string) => {\n try {\n await transition.mutateAsync({ id: event.id, status });\n notify.success(successMessage, event.title);\n } catch (err) {\n notify.error('Could not update the event', describeError(err));\n }\n };\n\n const scheduleText = event.endsAt\n ? `${formatDateTime(event.startsAt)} – ${formatDateTime(event.endsAt)}`\n : formatDateTime(event.startsAt);\n\n return (\n <PageLayout title={event.title} actions={backButton}>\n <div className=\"mx-auto flex max-w-3xl flex-col gap-6\">\n {/* Overview */}\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-5 p-5 sm:p-6\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <StatusBadge status={event.status} />\n <StatusBadge status={event.mode} />\n </div>\n\n {event.description && (\n <p className=\"whitespace-pre-wrap text-sm text-text-secondary\">{event.description}</p>\n )}\n\n <dl className=\"flex flex-col gap-3 text-sm\">\n {/* Schedule */}\n <div className=\"flex items-start gap-2.5\">\n <CalendarDays className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div>\n <dt className=\"text-text-tertiary\">When</dt>\n <dd className=\"mt-0.5 text-text-primary\">{scheduleText}</dd>\n </div>\n </div>\n\n {/* Location (in-person / hybrid) */}\n {isInPersonish && event.location && (\n <div className=\"flex items-start gap-2.5\">\n <MapPin className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div>\n <dt className=\"text-text-tertiary\">Where</dt>\n <dd className=\"mt-0.5 text-text-primary\">{event.location}</dd>\n </div>\n </div>\n )}\n\n {/* Online join link (online / hybrid) */}\n {isOnlineish && (\n <div className=\"flex items-start gap-2.5\">\n <Video className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div className=\"min-w-0\">\n <dt className=\"text-text-tertiary\">Online</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {showJoin && event.joinUrl ? (\n <a\n href={event.joinUrl}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n className=\"inline-flex items-center gap-1 font-medium text-accent hover:underline\"\n >\n Join the live event <ExternalLink className=\"h-3.5 w-3.5\" />\n </a>\n ) : (\n <span className=\"text-text-secondary\">\n {event.status === 'LIVE'\n ? 'A join link has not been provided.'\n : 'The join link becomes available when the event goes live.'}\n </span>\n )}\n </dd>\n </div>\n </div>\n )}\n\n {/* Attendance */}\n <div className=\"flex items-start gap-2.5\">\n <Users className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div>\n <dt className=\"text-text-tertiary\">Attending</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {formatNumber(event.rsvpCount)}\n {event.capacity ? ` / ${formatNumber(event.capacity)}` : ''}\n </dd>\n </div>\n </div>\n </dl>\n\n {/* Tags */}\n {event.tags.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <Tag className=\"h-3.5 w-3.5 text-text-tertiary\" aria-hidden=\"true\" />\n {event.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\"\n >\n #{tag}\n </span>\n ))}\n </div>\n )}\n\n {/* Host */}\n <div className=\"border-t border-border-seam pt-4\">\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-text-tertiary\">\n Hosted by\n </p>\n <MemberIdentity memberId={event.hostId} variant=\"row\" size=\"md\" showPresence />\n </div>\n </GlassCard>\n\n {/* RSVP controls */}\n {canRsvp && (\n <section className=\"rounded-2xl border border-border-seam bg-bg-surface p-5\">\n <h2 className=\"text-base font-semibold text-text-primary\">Your RSVP</h2>\n <p className=\"mt-0.5 text-sm text-text-secondary\">\n Let the host know whether you&apos;ll attend.\n </p>\n <div className=\"mt-4 flex flex-wrap gap-2\">\n {RSVP_OPTIONS.map((opt) => {\n const active = myRsvp?.status === opt.status;\n return (\n <Button\n key={opt.status}\n size=\"sm\"\n variant={active ? 'default' : 'outline'}\n onClick={() => doRsvp(opt.status)}\n disabled={rsvp.isPending}\n >\n {opt.label}\n </Button>\n );\n })}\n </div>\n </section>\n )}\n\n {/* Host lifecycle controls */}\n {isHost && (event.status === 'SCHEDULED' || event.status === 'LIVE') && (\n <section className=\"rounded-2xl border border-border-seam bg-bg-surface p-5\">\n <h2 className=\"text-base font-semibold text-text-primary\">Host controls</h2>\n <p className=\"mt-0.5 text-sm text-text-secondary\">\n Move this event through its lifecycle.\n </p>\n <div className=\"mt-4 flex flex-wrap gap-2\">\n {event.status === 'SCHEDULED' && (\n <>\n <Button\n size=\"sm\"\n onClick={() => doTransition('LIVE', 'Event is now live')}\n disabled={transition.isPending}\n >\n <Radio className=\"mr-1.5 h-4 w-4\" /> Go live\n </Button>\n <Button\n size=\"sm\"\n variant=\"destructive\"\n onClick={() => doTransition('CANCELLED', 'Event cancelled')}\n disabled={transition.isPending}\n >\n <Ban className=\"mr-1.5 h-4 w-4\" /> Cancel\n </Button>\n </>\n )}\n {event.status === 'LIVE' && (\n <Button\n size=\"sm\"\n onClick={() => doTransition('COMPLETED', 'Event marked complete')}\n disabled={transition.isPending}\n >\n <CheckCircle2 className=\"mr-1.5 h-4 w-4\" /> Mark complete\n </Button>\n )}\n </div>\n </section>\n )}\n\n {/* Attendees */}\n <section className=\"rounded-2xl border border-border-seam bg-bg-surface p-5\">\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h2 className=\"text-base font-semibold text-text-primary\">Attendees</h2>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-tertiary\">\n <Users className=\"h-3.5 w-3.5\" /> {formatNumber(event.rsvps.length)}\n </span>\n </div>\n {event.rsvps.length === 0 ? (\n <p className=\"py-4 text-center text-sm text-text-tertiary\">No RSVPs yet.</p>\n ) : (\n <ul className=\"flex flex-col gap-2\">\n {event.rsvps.map((r) => (\n <li\n key={r.id}\n className=\"flex flex-wrap items-center justify-between gap-3 rounded-xl border border-border-seam bg-bg-sunken px-4 py-2.5\"\n >\n <MemberIdentity memberId={r.memberId} variant=\"row\" size=\"sm\" />\n <div className=\"flex min-w-0 items-center gap-2\">\n {r.note && (\n <span className=\"max-w-[16rem] truncate text-xs text-text-tertiary\">\n “{r.note}”\n </span>\n )}\n <StatusBadge status={r.status} />\n </div>\n </li>\n ))}\n </ul>\n )}\n </section>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EventDetailPage.js","names":[],"sources":["../../../../src/comradecircle/pages/events/EventDetailPage.tsx"],"sourcesContent":["/**\n * EventDetailPage — a single community event.\n * @module comradecircle/pages/events\n *\n * Reads `comEvent` (with its RSVPs). Members RSVP (GOING / INTERESTED /\n * WAITLISTED / NOT_GOING) while the event is SCHEDULED or LIVE; the host drives\n * the lifecycle (SCHEDULED → LIVE → COMPLETED, or CANCELLED). Person references\n * always resolve through {@link MemberIdentity} — never a raw actor id.\n */\n\nimport {\n ArrowLeft,\n CalendarDays,\n MapPin,\n Video,\n Users,\n Radio,\n CheckCircle2,\n Check,\n Ban,\n Tag,\n} from 'lucide-react';\nimport { GlassCard, Button } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { MemberIdentity } from '../../components/MemberIdentity';\nimport { MiniBar } from '../../components/MiniBar';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { useComEvent, useComRsvpEvent, useComTransitionEvent } from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport { formatDateTime, formatNumber, formatEnumLabel } from '../../utils';\nimport { cn } from '../../utils/cn';\nimport { notify, describeError } from '../../lib/toast';\nimport { useParams } from 'react-router-dom';\nimport type { ComEventStatus, ComRsvpStatus } from '../../types';\n\nconst RSVP_OPTIONS: { status: ComRsvpStatus; label: string }[] = [\n { status: 'GOING', label: 'Going' },\n { status: 'INTERESTED', label: 'Interested' },\n { status: 'WAITLISTED', label: 'Waitlist' },\n { status: 'NOT_GOING', label: \"Can't go\" },\n];\n\n/** Attendee display order: confirmed first, declines last. */\nconst RSVP_ORDER: Record<ComRsvpStatus, number> = {\n GOING: 0,\n INTERESTED: 1,\n WAITLISTED: 2,\n NOT_GOING: 3,\n};\n\n/** Facet labels for the one-line attendee summary. */\nconst RSVP_FACETS: { status: ComRsvpStatus; label: string }[] = [\n { status: 'GOING', label: 'going' },\n { status: 'INTERESTED', label: 'interested' },\n { status: 'WAITLISTED', label: 'waitlisted' },\n { status: 'NOT_GOING', label: \"can't go\" },\n];\n\nexport function EventDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { currentUser, navigateTo } = useComradeCircle();\n const { data: event, isLoading, isError, refetch } = useComEvent(id);\n const rsvp = useComRsvpEvent();\n const transition = useComTransitionEvent();\n\n const backButton = (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateTo('events')}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" /> Back\n </Button>\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"Event\" actions={backButton}>\n <LoadingView label=\"Loading event…\" />\n </PageLayout>\n );\n }\n\n if (isError || !event) {\n return (\n <PageLayout title=\"Event\" actions={backButton}>\n <ErrorView\n title=\"Event not found\"\n message=\"This event may have been cancelled, or you may not have access to it.\"\n onRetry={() => refetch()}\n />\n </PageLayout>\n );\n }\n\n const isHost = Boolean(currentUser?.id && currentUser.id === event.hostId);\n const isLive = event.status === 'LIVE';\n const canRsvp = event.status === 'SCHEDULED' || event.status === 'LIVE';\n const isOnlineish = event.mode === 'ONLINE' || event.mode === 'HYBRID';\n const isInPersonish = event.mode === 'IN_PERSON' || event.mode === 'HYBRID';\n const showJoin = isLive && isOnlineish && Boolean(event.joinUrl);\n const myRsvp = currentUser?.id\n ? event.rsvps.find((r) => r.memberId === currentUser.id)\n : undefined;\n\n // Attendance / capacity — derived from real rsvpCount + capacity only.\n const capacity = event.capacity ?? null;\n const fillPct =\n capacity && capacity > 0 ? Math.min(100, (event.rsvpCount / capacity) * 100) : null;\n const nearFull = fillPct != null && fillPct >= 80;\n const isFull = fillPct != null && fillPct >= 100;\n const capacityLabel = fillPct == null ? '' : isFull ? 'Full' : `${Math.round(fillPct)}% full`;\n const capacityBar = isFull\n ? 'bg-status-error-text'\n : nearFull\n ? 'bg-status-warning-text'\n : 'bg-accent';\n const capacityTone = isFull\n ? 'text-status-error-text'\n : nearFull\n ? 'text-status-warning-text'\n : 'text-text-tertiary';\n\n // Attendees — sort GOING → INTERESTED → WAITLISTED → NOT_GOING; facet summary.\n const rsvpCounts = event.rsvps.reduce<Record<ComRsvpStatus, number>>(\n (acc, r) => {\n acc[r.status] += 1;\n return acc;\n },\n { GOING: 0, INTERESTED: 0, WAITLISTED: 0, NOT_GOING: 0 }\n );\n const sortedRsvps = [...event.rsvps].sort((a, b) => RSVP_ORDER[a.status] - RSVP_ORDER[b.status]);\n const facetSummary = RSVP_FACETS.filter((f) => rsvpCounts[f.status] > 0)\n .map((f) => `${formatNumber(rsvpCounts[f.status])} ${f.label}`)\n .join(' · ');\n\n const doRsvp = async (status: ComRsvpStatus) => {\n try {\n await rsvp.mutateAsync({ eventId: event.id, status });\n notify.success('RSVP updated', `${formatEnumLabel(status)} · ${event.title}`);\n } catch (err) {\n notify.error('Could not RSVP', describeError(err));\n }\n };\n\n const doTransition = async (status: ComEventStatus, successMessage: string) => {\n try {\n await transition.mutateAsync({ id: event.id, status });\n notify.success(successMessage, event.title);\n } catch (err) {\n notify.error('Could not update the event', describeError(err));\n }\n };\n\n const scheduleText = event.endsAt\n ? `${formatDateTime(event.startsAt)} – ${formatDateTime(event.endsAt)}`\n : formatDateTime(event.startsAt);\n\n return (\n <PageLayout title={event.title} actions={backButton}>\n <div className=\"mx-auto flex max-w-3xl flex-col gap-6\">\n {/* Overview */}\n <GlassCard\n treatment=\"plain\"\n className={cn(\n 'flex flex-col gap-5 p-5 sm:p-6',\n isLive && 'ring-1 ring-[var(--color-accent-soft)]'\n )}\n >\n {/* Motion-safe live ring — a pulsing accent halo, gated for reduced motion. */}\n {isLive && (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 rounded-card ring-2 ring-accent/60 motion-safe:animate-pulse\"\n />\n )}\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <StatusBadge status={event.status} />\n <StatusBadge status={event.mode} />\n </div>\n\n {/* Prominent live-join CTA, promoted near the header. */}\n {showJoin && event.joinUrl && (\n <Button asChild size=\"lg\" className=\"w-full justify-center sm:w-auto sm:self-start\">\n <a href={event.joinUrl} target=\"_blank\" rel=\"noreferrer noopener\">\n <Video className=\"h-4 w-4\" /> Join the live event\n </a>\n </Button>\n )}\n\n {event.description && (\n <p className=\"whitespace-pre-wrap text-sm text-text-secondary\">{event.description}</p>\n )}\n\n <dl className=\"flex flex-col gap-3 text-sm\">\n {/* Schedule */}\n <div className=\"flex items-start gap-2.5\">\n <CalendarDays className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div>\n <dt className=\"text-text-tertiary\">When</dt>\n <dd className=\"mt-0.5 text-text-primary\">{scheduleText}</dd>\n </div>\n </div>\n\n {/* Location (in-person / hybrid) */}\n {isInPersonish && event.location && (\n <div className=\"flex items-start gap-2.5\">\n <MapPin className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div>\n <dt className=\"text-text-tertiary\">Where</dt>\n <dd className=\"mt-0.5 text-text-primary\">{event.location}</dd>\n </div>\n </div>\n )}\n\n {/* Online join link (online / hybrid) */}\n {isOnlineish && (\n <div className=\"flex items-start gap-2.5\">\n <Video className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div className=\"min-w-0\">\n <dt className=\"text-text-tertiary\">Online</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {showJoin ? (\n <span className=\"font-medium text-accent\">\n The join link is live — use the button above.\n </span>\n ) : (\n <span className=\"text-text-secondary\">\n {isLive\n ? 'A join link has not been provided.'\n : 'The join link becomes available when the event goes live.'}\n </span>\n )}\n </dd>\n </div>\n </div>\n )}\n\n {/* Attendance */}\n <div className=\"flex items-start gap-2.5\">\n <Users className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div className=\"min-w-0 flex-1\">\n <dt className=\"text-text-tertiary\">Attending</dt>\n <dd className=\"mt-0.5 flex flex-wrap items-baseline gap-x-2 text-text-primary\">\n <span>\n {formatNumber(event.rsvpCount)}\n {capacity ? ` / ${formatNumber(capacity)}` : ''}\n </span>\n {capacityLabel && (\n <span className={cn('text-xs font-semibold', capacityTone)}>\n {capacityLabel}\n </span>\n )}\n </dd>\n {fillPct != null && (\n <MiniBar value={fillPct} barClassName={capacityBar} className=\"mt-2 max-w-xs\" />\n )}\n </div>\n </div>\n </dl>\n\n {/* Tags */}\n {event.tags.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <Tag className=\"h-3.5 w-3.5 text-text-tertiary\" aria-hidden=\"true\" />\n {event.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\"\n >\n #{tag}\n </span>\n ))}\n </div>\n )}\n\n {/* Host */}\n <div className=\"border-t border-border-seam pt-4\">\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-text-tertiary\">\n Hosted by\n </p>\n <MemberIdentity memberId={event.hostId} variant=\"row\" size=\"md\" showPresence />\n </div>\n </GlassCard>\n\n {/* RSVP controls */}\n {canRsvp && (\n <section className=\"rounded-2xl border border-border-seam bg-bg-surface p-5\">\n <h2 className=\"text-base font-semibold text-text-primary\">Your RSVP</h2>\n <p className=\"mt-0.5 text-sm text-text-secondary\">\n Let the host know whether you&apos;ll attend.\n </p>\n <div className=\"mt-4 flex flex-col gap-2 sm:flex-row sm:flex-wrap\">\n {RSVP_OPTIONS.map((opt) => {\n const active = myRsvp?.status === opt.status;\n return (\n <Button\n key={opt.status}\n variant={active ? 'default' : 'outline'}\n onClick={() => doRsvp(opt.status)}\n disabled={rsvp.isPending}\n aria-pressed={active}\n className={cn(\n 'w-full justify-center sm:w-auto',\n active && 'font-semibold shadow-elevation-1'\n )}\n >\n {active && <Check className=\"h-4 w-4\" />}\n {opt.label}\n </Button>\n );\n })}\n </div>\n </section>\n )}\n\n {/* Host lifecycle controls */}\n {isHost && (event.status === 'SCHEDULED' || event.status === 'LIVE') && (\n <section className=\"rounded-2xl border border-border-seam bg-bg-surface p-5\">\n <h2 className=\"text-base font-semibold text-text-primary\">Host controls</h2>\n <p className=\"mt-0.5 text-sm text-text-secondary\">\n Move this event through its lifecycle.\n </p>\n <div className=\"mt-4 flex flex-wrap gap-2\">\n {event.status === 'SCHEDULED' && (\n <>\n <Button\n size=\"sm\"\n onClick={() => doTransition('LIVE', 'Event is now live')}\n disabled={transition.isPending}\n >\n <Radio className=\"mr-1.5 h-4 w-4\" /> Go live\n </Button>\n <Button\n size=\"sm\"\n variant=\"destructive\"\n onClick={() => doTransition('CANCELLED', 'Event cancelled')}\n disabled={transition.isPending}\n >\n <Ban className=\"mr-1.5 h-4 w-4\" /> Cancel\n </Button>\n </>\n )}\n {event.status === 'LIVE' && (\n <Button\n size=\"sm\"\n onClick={() => doTransition('COMPLETED', 'Event marked complete')}\n disabled={transition.isPending}\n >\n <CheckCircle2 className=\"mr-1.5 h-4 w-4\" /> Mark complete\n </Button>\n )}\n </div>\n </section>\n )}\n\n {/* Attendees */}\n <section className=\"rounded-2xl border border-border-seam bg-bg-surface p-5\">\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <h2 className=\"text-base font-semibold text-text-primary\">Attendees</h2>\n {facetSummary && (\n <p className=\"mt-0.5 truncate text-xs text-text-tertiary\">{facetSummary}</p>\n )}\n </div>\n <span className=\"inline-flex shrink-0 items-center gap-1 text-xs text-text-tertiary\">\n <Users className=\"h-3.5 w-3.5\" /> {formatNumber(event.rsvps.length)}\n </span>\n </div>\n {event.rsvps.length === 0 ? (\n <EmptyState\n illustration=\"empty-people\"\n title=\"No RSVPs yet\"\n description=\"Be the first to let the host know you're coming.\"\n />\n ) : (\n <ul className=\"flex flex-col gap-2\">\n {sortedRsvps.map((r) => (\n <li\n key={r.id}\n className=\"flex flex-wrap items-center justify-between gap-3 rounded-xl border border-border-seam bg-bg-sunken px-4 py-2.5 transition-colors hover:border-[var(--color-accent-soft)]\"\n >\n <MemberIdentity memberId={r.memberId} variant=\"row\" size=\"sm\" />\n <div className=\"flex min-w-0 items-center gap-2\">\n {r.note && (\n <span className=\"max-w-[16rem] truncate text-xs text-text-tertiary\">\n “{r.note}”\n </span>\n )}\n <StatusBadge status={r.status} />\n </div>\n </li>\n ))}\n </ul>\n )}\n </section>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}