@burdenoff/microfe-timecampus 2026.626.2 → 2026.703.2

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 (93) hide show
  1. package/dist/generated/wspace-operations.js +996 -816
  2. package/dist/generated/wspace-operations.js.map +1 -1
  3. package/dist/generated/wspace-types.js +28 -0
  4. package/dist/generated/wspace-types.js.map +1 -0
  5. package/dist/index.js +4 -4
  6. package/dist/timecampus/TimeCampusRoutes.js +16 -12
  7. package/dist/timecampus/TimeCampusRoutes.js.map +1 -1
  8. package/dist/timecampus/components/Modal.js +65 -0
  9. package/dist/timecampus/components/Modal.js.map +1 -0
  10. package/dist/timecampus/components/StatusBadge.js +28 -0
  11. package/dist/timecampus/components/StatusBadge.js.map +1 -0
  12. package/dist/timecampus/components/Toast.js +87 -0
  13. package/dist/timecampus/components/Toast.js.map +1 -0
  14. package/dist/timecampus/index.js +1 -1
  15. package/dist/timecampus/pages/HomePage.js +143 -135
  16. package/dist/timecampus/pages/HomePage.js.map +1 -1
  17. package/dist/timecampus/pages/applets/AppletStorePage.js +14 -19
  18. package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -1
  19. package/dist/timecampus/pages/applets/InstalledAppletsPage.js +49 -37
  20. package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -1
  21. package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +315 -87
  22. package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
  23. package/dist/timecampus/pages/channels/ChannelsPage.js +340 -46
  24. package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -1
  25. package/dist/timecampus/pages/client-portal/ClientPortalPage.js +374 -92
  26. package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
  27. package/dist/timecampus/pages/dashboard/ReportsPage.js +70 -37
  28. package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
  29. package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +366 -60
  30. package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
  31. package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +461 -87
  32. package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
  33. package/dist/timecampus/pages/geofencing/GeofencingPage.js +314 -55
  34. package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
  35. package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +30 -27
  36. package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -1
  37. package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +269 -74
  38. package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
  39. package/dist/timecampus/pages/meetings/ActionItemFormModal.js +127 -0
  40. package/dist/timecampus/pages/meetings/ActionItemFormModal.js.map +1 -0
  41. package/dist/timecampus/pages/meetings/MeetingCreatePage.js +62 -52
  42. package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
  43. package/dist/timecampus/pages/meetings/MeetingDetailPage.js +361 -74
  44. package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
  45. package/dist/timecampus/pages/meetings/MeetingFormModal.js +156 -0
  46. package/dist/timecampus/pages/meetings/MeetingFormModal.js.map +1 -0
  47. package/dist/timecampus/pages/meetings/MeetingsPage.js +175 -74
  48. package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
  49. package/dist/timecampus/pages/meetings/ParticipantFormModal.js +105 -0
  50. package/dist/timecampus/pages/meetings/ParticipantFormModal.js.map +1 -0
  51. package/dist/timecampus/pages/pomodoro/PomodoroPage.js +307 -67
  52. package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
  53. package/dist/timecampus/pages/projects/ProjectCreatePage.js +51 -48
  54. package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
  55. package/dist/timecampus/pages/projects/ProjectDetailPage.js +248 -51
  56. package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
  57. package/dist/timecampus/pages/projects/ProjectsPage.js +354 -87
  58. package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
  59. package/dist/timecampus/pages/projects/TasksPage.js +367 -65
  60. package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
  61. package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +674 -104
  62. package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
  63. package/dist/timecampus/pages/team/TeamAnalyticsPage.js +46 -34
  64. package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
  65. package/dist/timecampus/pages/team/TeamMembersPage.js +93 -69
  66. package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
  67. package/dist/timecampus/pages/team/TeamPage.js +4 -3
  68. package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
  69. package/dist/timecampus/pages/templates/TemplateDetailPage.js +72 -53
  70. package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -1
  71. package/dist/timecampus/pages/templates/TemplatesPage.js +40 -35
  72. package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -1
  73. package/dist/timecampus/pages/time/TimeEntriesPage.js +484 -97
  74. package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
  75. package/dist/timecampus/pages/time/TimeTrackingPage.js +210 -99
  76. package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
  77. package/dist/timecampus/pages/time/TimerPage.js +229 -97
  78. package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
  79. package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +315 -110
  80. package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
  81. package/dist/timecampus/pages/timeline/TimelinePage.js +250 -0
  82. package/dist/timecampus/pages/timeline/TimelinePage.js.map +1 -0
  83. package/dist/timecampus/pages/widgets/WidgetDetailPage.js +158 -76
  84. package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -1
  85. package/dist/timecampus/pages/widgets/WidgetsPage.js +181 -52
  86. package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -1
  87. package/dist/timecampus/pages/workflows/WorkflowsPage.js +212 -61
  88. package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -1
  89. package/dist/timecampus/store/timecampusStore.js +13 -1
  90. package/dist/timecampus/store/timecampusStore.js.map +1 -1
  91. package/dist/timecampus/utils/helpers.js +20 -10
  92. package/dist/timecampus/utils/helpers.js.map +1 -1
  93. package/package.json +1 -1
@@ -1,141 +1,428 @@
1
1
  import { useTimeCampus as e, useTimeCampusNavigate as t } from "../../providers/TimeCampusProvider.js";
2
- import { formatCurrency as n } from "../../utils/helpers.js";
3
- import { StatCard as r } from "../../components/StatCard.js";
4
- import { LoadingSkeleton as i } from "../../components/LoadingSkeleton.js";
5
- import { useGetMeetingQuery as a } from "../../../generated/wspace-operations.js";
6
- import { PageLayout as o } from "../../components/PageLayout.js";
7
- import { EmptyState as s } from "../../components/EmptyState.js";
8
- import { Clock as c, Users as l } from "lucide-react";
9
- import { useParams as u } from "react-router-dom";
10
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
11
- import { NextSteps as p } from "@burdenoff/fe-libs/ui";
2
+ import { cn as n, formatCurrency as r } from "../../utils/helpers.js";
3
+ import { StatCard as i } from "../../components/StatCard.js";
4
+ import { LoadingSkeleton as ee } from "../../components/LoadingSkeleton.js";
5
+ import { useAddParticipantMutation as te, useCompleteActionItemMutation as ne, useCreateActionItemMutation as re, useDeleteActionItemMutation as ie, useDeleteMeetingMutation as ae, useGetMeetingQuery as a, useRateMeetingMutation as o, useRemoveParticipantMutation as s, useUpdateActionItemMutation as c, useUpdateMeetingMutation as l, useUpdateParticipantStatusMutation as u } from "../../../generated/wspace-operations.js";
6
+ import { PageLayout as d } from "../../components/PageLayout.js";
7
+ import { EmptyState as f } from "../../components/EmptyState.js";
8
+ import { MeetingActionItemStatus as p, MeetingParticipantStatus as m } from "../../../generated/wspace-types.js";
9
+ import { Modal as h } from "../../components/Modal.js";
10
+ import { MeetingFormModal as oe } from "./MeetingFormModal.js";
11
+ import { ParticipantFormModal as se } from "./ParticipantFormModal.js";
12
+ import { ActionItemFormModal as ce } from "./ActionItemFormModal.js";
13
+ import { useState as g } from "react";
14
+ import { Check as le, Clock as ue, Pencil as _, Plus as v, Star as de, Trash2 as y, UserMinus as fe, Users as b } from "lucide-react";
15
+ import { useParams as x } from "react-router-dom";
16
+ import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
17
+ import { NextSteps as T } from "@burdenoff/fe-libs/ui";
12
18
  //#region src/timecampus/pages/meetings/MeetingDetailPage.tsx
13
- function m() {
14
- let { id: m } = u(), { workspaceId: h = "" } = e(), g = t(), { data: _, loading: v, error: y } = a({
19
+ var E = [
20
+ m.Pending,
21
+ m.Accepted,
22
+ m.Tentative,
23
+ m.Declined
24
+ ];
25
+ function D() {
26
+ let { id: m } = x(), { workspaceId: D = "", currentUser: O } = e(), k = t(), A = m ?? "", { data: j, loading: M, error: N, refetch: P } = a({
15
27
  variables: {
16
- id: m ?? "",
17
- workspaceId: h
28
+ id: A,
29
+ workspaceId: D
18
30
  },
19
- skip: !h || !m
20
- }), b = _?.meeting;
21
- if (v) return /* @__PURE__ */ d(o, {
31
+ skip: !D || !m
32
+ }), [F, { loading: I, error: L }] = l(), [R, { loading: z }] = ae(), [B, { loading: V }] = o(), [pe, { loading: me, error: he }] = te(), [ge] = s(), [_e] = u(), [ve, { loading: ye, error: be }] = re(), [xe, { loading: Se, error: Ce }] = c(), [we] = ne(), [Te] = ie(), [Ee, H] = g(!1), [De, U] = g(!1), [Oe, W] = g(!1), [G, K] = g(null), [q, J] = g(null), [Y, X] = g(null), Z = j?.meeting;
33
+ if (M) return /* @__PURE__ */ C(d, {
22
34
  title: "Meeting Details",
23
35
  description: `Meeting ID: ${m}`,
24
- children: /* @__PURE__ */ d(i, { variant: "detail" })
36
+ children: /* @__PURE__ */ C(ee, { variant: "detail" })
25
37
  });
26
- if (y || !b) return /* @__PURE__ */ d(o, {
38
+ if (N || !Z) return /* @__PURE__ */ C(d, {
27
39
  title: "Meeting Details",
28
40
  description: `Meeting ID: ${m}`,
29
- children: /* @__PURE__ */ d("div", {
41
+ children: /* @__PURE__ */ C("div", {
30
42
  className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
31
- children: y ? "Failed to load meeting details. Please try again later." : "Meeting not found."
43
+ children: N ? "Failed to load meeting details. Please try again later." : "Meeting not found."
32
44
  })
33
45
  });
34
- let x = b.actionItems.filter((e) => e.status !== "COMPLETED").length;
35
- return /* @__PURE__ */ f(o, {
46
+ let ke = Z.actionItems.filter((e) => e.status !== "COMPLETED").length, Q = Z.rating ?? 0, Ae = async (e) => {
47
+ await F({ variables: {
48
+ id: A,
49
+ workspaceId: D,
50
+ input: e
51
+ } }), await P(), H(!1);
52
+ }, $ = async () => {
53
+ await R({ variables: {
54
+ id: A,
55
+ workspaceId: D
56
+ } }), U(!1), k("/meetings");
57
+ }, je = async (e) => {
58
+ await B({ variables: {
59
+ id: A,
60
+ workspaceId: D,
61
+ rating: e
62
+ } }), await P();
63
+ }, Me = async (e) => {
64
+ await pe({ variables: {
65
+ meetingId: A,
66
+ workspaceId: D,
67
+ input: e
68
+ } }), await P(), W(!1);
69
+ }, Ne = async () => {
70
+ G && (await ge({ variables: {
71
+ meetingId: A,
72
+ participantId: G.id,
73
+ workspaceId: D
74
+ } }), K(null), await P());
75
+ }, Pe = async (e, t) => {
76
+ await _e({ variables: {
77
+ meetingId: A,
78
+ participantId: e,
79
+ workspaceId: D,
80
+ status: t
81
+ } }), await P();
82
+ }, Fe = async (e) => {
83
+ await ve({ variables: {
84
+ meetingId: A,
85
+ workspaceId: D,
86
+ input: e
87
+ } }), await P(), J(null);
88
+ }, Ie = async (e, t) => {
89
+ await xe({ variables: {
90
+ id: e,
91
+ workspaceId: D,
92
+ input: t
93
+ } }), await P(), J(null);
94
+ }, Le = async (e) => {
95
+ await we({ variables: {
96
+ id: e,
97
+ workspaceId: D
98
+ } }), await P();
99
+ };
100
+ return /* @__PURE__ */ w(d, {
36
101
  title: "Meeting Details",
37
- description: b.title,
102
+ description: Z.title,
38
103
  purpose: "The full record of one meeting — who attended, what it cost in people's time, and the action items it produced — so you can follow up on commitments and judge whether the meeting was worth it.",
104
+ actions: /* @__PURE__ */ w(S, { children: [/* @__PURE__ */ w("button", {
105
+ onClick: () => H(!0),
106
+ className: "inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
107
+ children: [/* @__PURE__ */ C(_, { className: "h-4 w-4" }), "Edit"]
108
+ }), /* @__PURE__ */ w("button", {
109
+ onClick: () => U(!0),
110
+ className: "inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/40",
111
+ children: [/* @__PURE__ */ C(y, { className: "h-4 w-4" }), "Delete"]
112
+ })] }),
39
113
  children: [
40
- /* @__PURE__ */ d(p, {
114
+ /* @__PURE__ */ C(T, {
41
115
  storageKey: "timecampus-meeting-detail",
42
116
  className: "mb-6",
43
117
  steps: [{
44
118
  id: "all-meetings",
45
119
  label: "Back to all meetings",
46
120
  description: "Browse and schedule other meetings.",
47
- onClick: () => g("/meetings")
121
+ onClick: () => k("/meetings")
48
122
  }, {
49
123
  id: "analytics",
50
124
  label: "See meeting analytics",
51
125
  description: "Understand your overall meeting load and cost.",
52
- onClick: () => g("/meetings/analytics")
126
+ onClick: () => k("/meetings/analytics")
53
127
  }]
54
128
  }),
55
- /* @__PURE__ */ f("div", {
129
+ /* @__PURE__ */ w("div", {
56
130
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
57
131
  children: [
58
- /* @__PURE__ */ d(r, {
132
+ /* @__PURE__ */ C(i, {
59
133
  featured: !0,
60
134
  title: "Duration",
61
- value: `${b.duration ?? 0} min`,
62
- icon: /* @__PURE__ */ d(c, { className: "h-5 w-5" })
135
+ value: `${Z.duration ?? 0} min`,
136
+ icon: /* @__PURE__ */ C(ue, { className: "h-5 w-5" })
63
137
  }),
64
- /* @__PURE__ */ d(r, {
138
+ /* @__PURE__ */ C(i, {
65
139
  title: "Participants",
66
- value: String(b.participants.length),
67
- icon: /* @__PURE__ */ d(l, { className: "h-5 w-5" })
140
+ value: String(Z.participants.length),
141
+ icon: /* @__PURE__ */ C(b, { className: "h-5 w-5" })
68
142
  }),
69
- /* @__PURE__ */ d(r, {
143
+ /* @__PURE__ */ C(i, {
70
144
  title: "Cost",
71
- value: b.cost == null ? "N/A" : n(b.cost),
145
+ value: Z.cost == null ? "N/A" : r(Z.cost),
72
146
  description: "Based on participant rates"
73
147
  }),
74
- /* @__PURE__ */ d(r, {
148
+ /* @__PURE__ */ C(i, {
75
149
  title: "Action Items",
76
- value: String(b.actionItems.length),
77
- description: `${x} pending`
150
+ value: String(Z.actionItems.length),
151
+ description: `${ke} pending`
78
152
  })
79
153
  ]
80
154
  }),
81
- /* @__PURE__ */ f("div", {
155
+ /* @__PURE__ */ w("div", {
156
+ className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
157
+ children: [
158
+ /* @__PURE__ */ C("h3", {
159
+ className: "mb-1 text-sm font-semibold text-text-primary",
160
+ children: "Rate this meeting"
161
+ }),
162
+ /* @__PURE__ */ C("p", {
163
+ className: "mb-3 text-xs text-text-secondary",
164
+ children: "Was it worth the time? Your rating feeds meeting analytics."
165
+ }),
166
+ /* @__PURE__ */ w("div", {
167
+ className: "flex items-center gap-1",
168
+ children: [[
169
+ 1,
170
+ 2,
171
+ 3,
172
+ 4,
173
+ 5
174
+ ].map((e) => /* @__PURE__ */ C("button", {
175
+ onClick: () => je(e),
176
+ disabled: V,
177
+ "aria-label": `Rate ${e} star${e > 1 ? "s" : ""}`,
178
+ className: "rounded-md p-1 text-text-secondary hover:bg-bg-sunken disabled:opacity-50",
179
+ children: /* @__PURE__ */ C(de, { className: n("h-6 w-6", e <= Q ? "fill-status-warning-text text-status-warning-text" : "text-text-secondary") })
180
+ }, e)), Q > 0 && /* @__PURE__ */ w("span", {
181
+ className: "ml-2 text-sm text-text-secondary",
182
+ children: [Q, " / 5"]
183
+ })]
184
+ })
185
+ ]
186
+ }),
187
+ /* @__PURE__ */ w("div", {
82
188
  className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
83
- children: [/* @__PURE__ */ f("div", {
189
+ children: [/* @__PURE__ */ w("div", {
84
190
  className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
85
- children: [/* @__PURE__ */ d("h3", {
86
- className: "mb-4 text-sm font-semibold text-text-primary",
87
- children: "Participants"
88
- }), b.participants.length > 0 ? /* @__PURE__ */ d("div", {
191
+ children: [/* @__PURE__ */ w("div", {
192
+ className: "mb-4 flex items-center justify-between",
193
+ children: [/* @__PURE__ */ C("h3", {
194
+ className: "text-sm font-semibold text-text-primary",
195
+ children: "Participants"
196
+ }), /* @__PURE__ */ w("button", {
197
+ onClick: () => W(!0),
198
+ className: "inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-2.5 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90",
199
+ children: [/* @__PURE__ */ C(v, { className: "h-3.5 w-3.5" }), "Add"]
200
+ })]
201
+ }), Z.participants.length > 0 ? /* @__PURE__ */ C("div", {
89
202
  className: "space-y-2",
90
- children: b.participants.map((e) => /* @__PURE__ */ f("div", {
91
- className: "flex items-center justify-between rounded-lg border border-border-subtle px-3 py-2",
92
- children: [/* @__PURE__ */ d("span", {
93
- className: "text-sm text-text-primary",
94
- children: e.userId
95
- }), /* @__PURE__ */ f("div", {
96
- className: "flex items-center gap-2",
97
- children: [/* @__PURE__ */ d("span", {
203
+ children: Z.participants.map((e) => /* @__PURE__ */ w("div", {
204
+ className: "flex items-center justify-between gap-2 rounded-lg border border-border-subtle px-3 py-2",
205
+ children: [/* @__PURE__ */ w("div", {
206
+ className: "min-w-0",
207
+ children: [/* @__PURE__ */ C("p", {
208
+ className: "truncate text-sm text-text-primary",
209
+ children: e.userId
210
+ }), /* @__PURE__ */ C("p", {
98
211
  className: "text-xs text-text-secondary",
99
212
  children: e.role
100
- }), /* @__PURE__ */ d("span", {
101
- className: "inline-flex rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
102
- children: e.status
213
+ })]
214
+ }), /* @__PURE__ */ w("div", {
215
+ className: "flex items-center gap-2",
216
+ children: [/* @__PURE__ */ C("select", {
217
+ value: e.status,
218
+ onChange: (t) => Pe(e.id, t.target.value),
219
+ className: "rounded-md border border-border-subtle bg-bg-surface px-2 py-1 text-xs text-text-primary",
220
+ "aria-label": "Participant status",
221
+ children: E.map((e) => /* @__PURE__ */ C("option", {
222
+ value: e,
223
+ children: e
224
+ }, e))
225
+ }), /* @__PURE__ */ C("button", {
226
+ onClick: () => K(e),
227
+ className: "rounded-md p-1 text-text-secondary hover:bg-status-error-bg hover:text-status-error-text",
228
+ "aria-label": "Remove participant",
229
+ children: /* @__PURE__ */ C(fe, { className: "h-4 w-4" })
103
230
  })]
104
231
  })]
105
232
  }, e.id))
106
- }) : /* @__PURE__ */ d(s, {
233
+ }) : /* @__PURE__ */ C(f, {
107
234
  illustration: "empty-people",
108
235
  title: "No participants added",
109
- description: "Add attendees to capture who was in the room and what it cost."
236
+ description: "Add attendees to capture who was in the room and what it cost.",
237
+ action: /* @__PURE__ */ w("button", {
238
+ onClick: () => W(!0),
239
+ className: "inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
240
+ children: [/* @__PURE__ */ C(v, { className: "h-4 w-4" }), "Add participant"]
241
+ })
110
242
  })]
111
- }), /* @__PURE__ */ f("div", {
243
+ }), /* @__PURE__ */ w("div", {
112
244
  className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
113
- children: [/* @__PURE__ */ d("h3", {
114
- className: "mb-4 text-sm font-semibold text-text-primary",
115
- children: "Action Items"
116
- }), b.actionItems.length > 0 ? /* @__PURE__ */ d("div", {
245
+ children: [/* @__PURE__ */ w("div", {
246
+ className: "mb-4 flex items-center justify-between",
247
+ children: [/* @__PURE__ */ C("h3", {
248
+ className: "text-sm font-semibold text-text-primary",
249
+ children: "Action Items"
250
+ }), /* @__PURE__ */ w("button", {
251
+ onClick: () => J({ mode: "create" }),
252
+ className: "inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-2.5 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90",
253
+ children: [/* @__PURE__ */ C(v, { className: "h-3.5 w-3.5" }), "Add"]
254
+ })]
255
+ }), Z.actionItems.length > 0 ? /* @__PURE__ */ C("div", {
117
256
  className: "space-y-2",
118
- children: b.actionItems.map((e) => /* @__PURE__ */ f("div", {
119
- className: "flex items-center justify-between rounded-lg border border-border-subtle px-3 py-2",
120
- children: [/* @__PURE__ */ d("span", {
121
- className: "text-sm text-text-primary",
122
- children: e.title
123
- }), /* @__PURE__ */ d("span", {
124
- className: "inline-flex rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
125
- children: e.status
257
+ children: Z.actionItems.map((e) => /* @__PURE__ */ w("div", {
258
+ className: "flex items-center justify-between gap-2 rounded-lg border border-border-subtle px-3 py-2",
259
+ children: [/* @__PURE__ */ w("div", {
260
+ className: "min-w-0",
261
+ children: [/* @__PURE__ */ C("p", {
262
+ className: "truncate text-sm text-text-primary",
263
+ children: e.title
264
+ }), /* @__PURE__ */ C("span", {
265
+ className: "inline-flex rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
266
+ children: e.status
267
+ })]
268
+ }), /* @__PURE__ */ w("div", {
269
+ className: "flex items-center gap-1",
270
+ children: [
271
+ e.status !== p.Completed && /* @__PURE__ */ C("button", {
272
+ onClick: () => Le(e.id),
273
+ className: "rounded-md p-1 text-text-secondary hover:bg-status-success-bg hover:text-status-success-text",
274
+ "aria-label": "Complete action item",
275
+ children: /* @__PURE__ */ C(le, { className: "h-4 w-4" })
276
+ }),
277
+ /* @__PURE__ */ C("button", {
278
+ onClick: () => J({
279
+ mode: "edit",
280
+ item: e
281
+ }),
282
+ className: "rounded-md p-1 text-text-secondary hover:bg-bg-sunken hover:text-text-primary",
283
+ "aria-label": "Edit action item",
284
+ children: /* @__PURE__ */ C(_, { className: "h-4 w-4" })
285
+ }),
286
+ /* @__PURE__ */ C("button", {
287
+ onClick: () => X(e),
288
+ className: "rounded-md p-1 text-text-secondary hover:bg-status-error-bg hover:text-status-error-text",
289
+ "aria-label": "Delete action item",
290
+ children: /* @__PURE__ */ C(y, { className: "h-4 w-4" })
291
+ })
292
+ ]
126
293
  })]
127
294
  }, e.id))
128
- }) : /* @__PURE__ */ d(s, {
295
+ }) : /* @__PURE__ */ C(f, {
129
296
  illustration: "empty-generic",
130
297
  title: "No action items",
131
- description: "Capture follow-ups here so commitments from the meeting don't get lost."
298
+ description: "Capture follow-ups here so commitments from the meeting don't get lost.",
299
+ action: /* @__PURE__ */ w("button", {
300
+ onClick: () => J({ mode: "create" }),
301
+ className: "inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
302
+ children: [/* @__PURE__ */ C(v, { className: "h-4 w-4" }), "Add action item"]
303
+ })
132
304
  })]
133
305
  })]
306
+ }),
307
+ Ee && /* @__PURE__ */ C(oe, {
308
+ open: !0,
309
+ onClose: () => H(!1),
310
+ workspaceId: D,
311
+ meeting: Z,
312
+ submitting: I,
313
+ error: !!L,
314
+ onUpdate: Ae
315
+ }),
316
+ /* @__PURE__ */ C(h, {
317
+ open: De,
318
+ onClose: () => U(!1),
319
+ title: "Delete meeting",
320
+ description: "This permanently removes the meeting and its analytics.",
321
+ size: "sm",
322
+ footer: /* @__PURE__ */ w(S, { children: [/* @__PURE__ */ C("button", {
323
+ onClick: () => U(!1),
324
+ className: "rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
325
+ children: "Cancel"
326
+ }), /* @__PURE__ */ C("button", {
327
+ onClick: $,
328
+ disabled: z,
329
+ className: "rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/90 disabled:opacity-50",
330
+ children: z ? "Deleting..." : "Delete"
331
+ })] }),
332
+ children: /* @__PURE__ */ w("p", {
333
+ className: "text-sm text-text-secondary",
334
+ children: [
335
+ "Are you sure you want to delete",
336
+ " ",
337
+ /* @__PURE__ */ C("span", {
338
+ className: "font-medium text-text-primary",
339
+ children: Z.title
340
+ }),
341
+ "? This action cannot be undone."
342
+ ]
343
+ })
344
+ }),
345
+ Oe && /* @__PURE__ */ C(se, {
346
+ open: !0,
347
+ onClose: () => W(!1),
348
+ defaultUserId: O?.id,
349
+ submitting: me,
350
+ error: !!he,
351
+ onSubmit: Me
352
+ }),
353
+ /* @__PURE__ */ C(h, {
354
+ open: !!G,
355
+ onClose: () => K(null),
356
+ title: "Remove participant",
357
+ size: "sm",
358
+ footer: /* @__PURE__ */ w(S, { children: [/* @__PURE__ */ C("button", {
359
+ onClick: () => K(null),
360
+ className: "rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
361
+ children: "Cancel"
362
+ }), /* @__PURE__ */ C("button", {
363
+ onClick: Ne,
364
+ className: "rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/90",
365
+ children: "Remove"
366
+ })] }),
367
+ children: /* @__PURE__ */ w("p", {
368
+ className: "text-sm text-text-secondary",
369
+ children: [
370
+ "Remove",
371
+ " ",
372
+ /* @__PURE__ */ C("span", {
373
+ className: "font-medium text-text-primary",
374
+ children: G?.userId
375
+ }),
376
+ " ",
377
+ "from this meeting?"
378
+ ]
379
+ })
380
+ }),
381
+ q && /* @__PURE__ */ C(ce, {
382
+ open: !0,
383
+ onClose: () => J(null),
384
+ item: q.mode === "edit" ? q.item : void 0,
385
+ submitting: q.mode === "edit" ? Se : ye,
386
+ error: !!(q.mode === "edit" ? Ce : be),
387
+ onCreate: Fe,
388
+ onUpdate: q.mode === "edit" ? (e) => Ie(q.item.id, e) : void 0
389
+ }),
390
+ /* @__PURE__ */ C(h, {
391
+ open: !!Y,
392
+ onClose: () => X(null),
393
+ title: "Delete action item",
394
+ size: "sm",
395
+ footer: /* @__PURE__ */ w(S, { children: [/* @__PURE__ */ C("button", {
396
+ onClick: () => X(null),
397
+ className: "rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
398
+ children: "Cancel"
399
+ }), /* @__PURE__ */ C("button", {
400
+ onClick: async () => {
401
+ Y && (await Te({ variables: {
402
+ id: Y.id,
403
+ workspaceId: D
404
+ } }), X(null), await P());
405
+ },
406
+ className: "rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/90",
407
+ children: "Delete"
408
+ })] }),
409
+ children: /* @__PURE__ */ w("p", {
410
+ className: "text-sm text-text-secondary",
411
+ children: [
412
+ "Delete action item",
413
+ " ",
414
+ /* @__PURE__ */ C("span", {
415
+ className: "font-medium text-text-primary",
416
+ children: Y?.title
417
+ }),
418
+ "?"
419
+ ]
420
+ })
134
421
  })
135
422
  ]
136
423
  });
137
424
  }
138
425
  //#endregion
139
- export { m as MeetingDetailPage };
426
+ export { D as MeetingDetailPage };
140
427
 
141
428
  //# sourceMappingURL=MeetingDetailPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MeetingDetailPage.js","names":[],"sources":["../../../../src/timecampus/pages/meetings/MeetingDetailPage.tsx"],"sourcesContent":["import { useParams } from \"react-router-dom\";\nimport { Users, Clock } from \"lucide-react\";\nimport { NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { EmptyState } from \"../../components/EmptyState\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport {\n useTimeCampus,\n useTimeCampusNavigate,\n} from \"../../providers/TimeCampusProvider\";\nimport {\n useGetMeetingQuery,\n type MeetingParticipantFieldsFragment,\n type MeetingActionItemFieldsFragment,\n} from \"@/generated/wspace-operations\";\nimport { formatCurrency } from \"../../utils/helpers\";\n\nexport function MeetingDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { workspaceId = \"\" } = useTimeCampus();\n const navigate = useTimeCampusNavigate();\n\n const { data, loading, error } = useGetMeetingQuery({\n variables: { id: id ?? \"\", workspaceId },\n skip: !workspaceId || !id,\n });\n\n const meeting = data?.meeting;\n\n if (loading) {\n return (\n <PageLayout title=\"Meeting Details\" description={`Meeting ID: ${id}`}>\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error || !meeting) {\n return (\n <PageLayout title=\"Meeting Details\" description={`Meeting ID: ${id}`}>\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n {error\n ? \"Failed to load meeting details. Please try again later.\"\n : \"Meeting not found.\"}\n </div>\n </PageLayout>\n );\n }\n\n const pendingActions = meeting.actionItems.filter(\n (a: MeetingActionItemFieldsFragment) => a.status !== \"COMPLETED\",\n ).length;\n\n return (\n <PageLayout\n title=\"Meeting Details\"\n description={meeting.title}\n purpose=\"The full record of one meeting — who attended, what it cost in people's time, and the action items it produced — so you can follow up on commitments and judge whether the meeting was worth it.\"\n >\n <NextSteps\n storageKey=\"timecampus-meeting-detail\"\n className=\"mb-6\"\n steps={[\n {\n id: \"all-meetings\",\n label: \"Back to all meetings\",\n description: \"Browse and schedule other meetings.\",\n onClick: () => navigate(\"/meetings\"),\n },\n {\n id: \"analytics\",\n label: \"See meeting analytics\",\n description: \"Understand your overall meeting load and cost.\",\n onClick: () => navigate(\"/meetings/analytics\"),\n },\n ]}\n />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n featured\n title=\"Duration\"\n value={`${meeting.duration ?? 0} min`}\n icon={<Clock className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Participants\"\n value={String(meeting.participants.length)}\n icon={<Users className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Cost\"\n value={meeting.cost != null ? formatCurrency(meeting.cost) : \"N/A\"}\n description=\"Based on participant rates\"\n />\n <StatCard\n title=\"Action Items\"\n value={String(meeting.actionItems.length)}\n description={`${pendingActions} pending`}\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary\">\n Participants\n </h3>\n {meeting.participants.length > 0 ? (\n <div className=\"space-y-2\">\n {meeting.participants.map(\n (p: MeetingParticipantFieldsFragment) => (\n <div\n key={p.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle px-3 py-2\"\n >\n <span className=\"text-sm text-text-primary\">\n {p.userId}\n </span>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-text-secondary\">\n {p.role}\n </span>\n <span className=\"inline-flex rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {p.status}\n </span>\n </div>\n </div>\n ),\n )}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title=\"No participants added\"\n description=\"Add attendees to capture who was in the room and what it cost.\"\n />\n )}\n </div>\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary\">\n Action Items\n </h3>\n {meeting.actionItems.length > 0 ? (\n <div className=\"space-y-2\">\n {meeting.actionItems.map(\n (item: MeetingActionItemFieldsFragment) => (\n <div\n key={item.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle px-3 py-2\"\n >\n <span className=\"text-sm text-text-primary\">\n {item.title}\n </span>\n <span className=\"inline-flex rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {item.status}\n </span>\n </div>\n ),\n )}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title=\"No action items\"\n description=\"Capture follow-ups here so commitments from the meeting don't get lost.\"\n />\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MeetingDetailPage.js","names":[],"sources":["../../../../src/timecampus/pages/meetings/MeetingDetailPage.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport {\n Users,\n Clock,\n Pencil,\n Trash2,\n Plus,\n Star,\n Check,\n UserMinus,\n} from \"lucide-react\";\nimport { NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { EmptyState } from \"../../components/EmptyState\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { Modal } from \"../../components/Modal\";\nimport { cn } from \"../../utils/helpers\";\nimport {\n useTimeCampus,\n useTimeCampusNavigate,\n} from \"../../providers/TimeCampusProvider\";\nimport {\n useGetMeetingQuery,\n useUpdateMeetingMutation,\n useDeleteMeetingMutation,\n useRateMeetingMutation,\n useAddParticipantMutation,\n useRemoveParticipantMutation,\n useUpdateParticipantStatusMutation,\n useCreateActionItemMutation,\n useUpdateActionItemMutation,\n useCompleteActionItemMutation,\n useDeleteActionItemMutation,\n type MeetingParticipantFieldsFragment,\n type MeetingActionItemFieldsFragment,\n} from \"@/generated/wspace-operations\";\nimport {\n MeetingParticipantStatus,\n MeetingActionItemStatus,\n type UpdateMeetingInput,\n type AddMeetingParticipantInput,\n type CreateActionItemInput,\n type UpdateActionItemInput,\n} from \"@/generated/wspace-types\";\nimport { formatCurrency } from \"../../utils/helpers\";\nimport { MeetingFormModal } from \"./MeetingFormModal\";\nimport { ParticipantFormModal } from \"./ParticipantFormModal\";\nimport { ActionItemFormModal } from \"./ActionItemFormModal\";\n\nconst PARTICIPANT_STATUS_OPTIONS = [\n MeetingParticipantStatus.Pending,\n MeetingParticipantStatus.Accepted,\n MeetingParticipantStatus.Tentative,\n MeetingParticipantStatus.Declined,\n];\n\nexport function MeetingDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { workspaceId = \"\", currentUser } = useTimeCampus();\n const navigate = useTimeCampusNavigate();\n const meetingId = id ?? \"\";\n\n const { data, loading, error, refetch } = useGetMeetingQuery({\n variables: { id: meetingId, workspaceId },\n skip: !workspaceId || !id,\n });\n\n const [updateMeeting, { loading: updating, error: updateError }] =\n useUpdateMeetingMutation();\n const [deleteMeeting, { loading: deletingMeeting }] =\n useDeleteMeetingMutation();\n const [rateMeeting, { loading: rating }] = useRateMeetingMutation();\n const [addParticipant, { loading: addingParticipant, error: addPError }] =\n useAddParticipantMutation();\n const [removeParticipant] = useRemoveParticipantMutation();\n const [updateParticipantStatus] = useUpdateParticipantStatusMutation();\n const [createActionItem, { loading: creatingItem, error: createItemError }] =\n useCreateActionItemMutation();\n const [updateActionItem, { loading: updatingItem, error: updateItemError }] =\n useUpdateActionItemMutation();\n const [completeActionItem] = useCompleteActionItemMutation();\n const [deleteActionItem] = useDeleteActionItemMutation();\n\n const [editOpen, setEditOpen] = useState(false);\n const [deleteOpen, setDeleteOpen] = useState(false);\n const [participantOpen, setParticipantOpen] = useState(false);\n const [removingParticipant, setRemovingParticipant] =\n useState<MeetingParticipantFieldsFragment | null>(null);\n const [actionItemModal, setActionItemModal] = useState<\n | { mode: \"create\" }\n | { mode: \"edit\"; item: MeetingActionItemFieldsFragment }\n | null\n >(null);\n const [deletingItem, setDeletingItem] =\n useState<MeetingActionItemFieldsFragment | null>(null);\n\n const meeting = data?.meeting;\n\n if (loading) {\n return (\n <PageLayout title=\"Meeting Details\" description={`Meeting ID: ${id}`}>\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error || !meeting) {\n return (\n <PageLayout title=\"Meeting Details\" description={`Meeting ID: ${id}`}>\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n {error\n ? \"Failed to load meeting details. Please try again later.\"\n : \"Meeting not found.\"}\n </div>\n </PageLayout>\n );\n }\n\n const pendingActions = meeting.actionItems.filter(\n (a: MeetingActionItemFieldsFragment) => a.status !== \"COMPLETED\",\n ).length;\n const currentRating = meeting.rating ?? 0;\n\n const handleUpdateMeeting = async (input: UpdateMeetingInput) => {\n await updateMeeting({ variables: { id: meetingId, workspaceId, input } });\n await refetch();\n setEditOpen(false);\n };\n\n const handleDeleteMeeting = async () => {\n await deleteMeeting({ variables: { id: meetingId, workspaceId } });\n setDeleteOpen(false);\n navigate(\"/meetings\");\n };\n\n const handleRate = async (value: number) => {\n await rateMeeting({\n variables: { id: meetingId, workspaceId, rating: value },\n });\n await refetch();\n };\n\n const handleAddParticipant = async (input: AddMeetingParticipantInput) => {\n await addParticipant({\n variables: { meetingId, workspaceId, input },\n });\n await refetch();\n setParticipantOpen(false);\n };\n\n const handleRemoveParticipant = async () => {\n if (!removingParticipant) return;\n await removeParticipant({\n variables: {\n meetingId,\n participantId: removingParticipant.id,\n workspaceId,\n },\n });\n setRemovingParticipant(null);\n await refetch();\n };\n\n const handleParticipantStatus = async (\n participantId: string,\n status: MeetingParticipantStatus,\n ) => {\n await updateParticipantStatus({\n variables: { meetingId, participantId, workspaceId, status },\n });\n await refetch();\n };\n\n const handleCreateItem = async (input: CreateActionItemInput) => {\n await createActionItem({ variables: { meetingId, workspaceId, input } });\n await refetch();\n setActionItemModal(null);\n };\n\n const handleUpdateItem = async (\n itemId: string,\n input: UpdateActionItemInput,\n ) => {\n await updateActionItem({ variables: { id: itemId, workspaceId, input } });\n await refetch();\n setActionItemModal(null);\n };\n\n const handleCompleteItem = async (itemId: string) => {\n await completeActionItem({ variables: { id: itemId, workspaceId } });\n await refetch();\n };\n\n const handleDeleteItem = async () => {\n if (!deletingItem) return;\n await deleteActionItem({ variables: { id: deletingItem.id, workspaceId } });\n setDeletingItem(null);\n await refetch();\n };\n\n return (\n <PageLayout\n title=\"Meeting Details\"\n description={meeting.title}\n purpose=\"The full record of one meeting — who attended, what it cost in people's time, and the action items it produced — so you can follow up on commitments and judge whether the meeting was worth it.\"\n actions={\n <>\n <button\n onClick={() => setEditOpen(true)}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n <Pencil className=\"h-4 w-4\" />\n Edit\n </button>\n <button\n onClick={() => setDeleteOpen(true)}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/40\"\n >\n <Trash2 className=\"h-4 w-4\" />\n Delete\n </button>\n </>\n }\n >\n <NextSteps\n storageKey=\"timecampus-meeting-detail\"\n className=\"mb-6\"\n steps={[\n {\n id: \"all-meetings\",\n label: \"Back to all meetings\",\n description: \"Browse and schedule other meetings.\",\n onClick: () => navigate(\"/meetings\"),\n },\n {\n id: \"analytics\",\n label: \"See meeting analytics\",\n description: \"Understand your overall meeting load and cost.\",\n onClick: () => navigate(\"/meetings/analytics\"),\n },\n ]}\n />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n featured\n title=\"Duration\"\n value={`${meeting.duration ?? 0} min`}\n icon={<Clock className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Participants\"\n value={String(meeting.participants.length)}\n icon={<Users className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Cost\"\n value={meeting.cost != null ? formatCurrency(meeting.cost) : \"N/A\"}\n description=\"Based on participant rates\"\n />\n <StatCard\n title=\"Action Items\"\n value={String(meeting.actionItems.length)}\n description={`${pendingActions} pending`}\n />\n </div>\n\n {/* Rating */}\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <h3 className=\"mb-1 text-sm font-semibold text-text-primary\">\n Rate this meeting\n </h3>\n <p className=\"mb-3 text-xs text-text-secondary\">\n Was it worth the time? Your rating feeds meeting analytics.\n </p>\n <div className=\"flex items-center gap-1\">\n {[1, 2, 3, 4, 5].map((value) => (\n <button\n key={value}\n onClick={() => handleRate(value)}\n disabled={rating}\n aria-label={`Rate ${value} star${value > 1 ? \"s\" : \"\"}`}\n className=\"rounded-md p-1 text-text-secondary hover:bg-bg-sunken disabled:opacity-50\"\n >\n <Star\n className={cn(\n \"h-6 w-6\",\n value <= currentRating\n ? \"fill-status-warning-text text-status-warning-text\"\n : \"text-text-secondary\",\n )}\n />\n </button>\n ))}\n {currentRating > 0 && (\n <span className=\"ml-2 text-sm text-text-secondary\">\n {currentRating} / 5\n </span>\n )}\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Participants\n </h3>\n <button\n onClick={() => setParticipantOpen(true)}\n className=\"inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-2.5 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n Add\n </button>\n </div>\n {meeting.participants.length > 0 ? (\n <div className=\"space-y-2\">\n {meeting.participants.map(\n (p: MeetingParticipantFieldsFragment) => (\n <div\n key={p.id}\n className=\"flex items-center justify-between gap-2 rounded-lg border border-border-subtle px-3 py-2\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm text-text-primary\">\n {p.userId}\n </p>\n <p className=\"text-xs text-text-secondary\">{p.role}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <select\n value={p.status}\n onChange={(e) =>\n handleParticipantStatus(\n p.id,\n e.target.value as MeetingParticipantStatus,\n )\n }\n className=\"rounded-md border border-border-subtle bg-bg-surface px-2 py-1 text-xs text-text-primary\"\n aria-label=\"Participant status\"\n >\n {PARTICIPANT_STATUS_OPTIONS.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n <button\n onClick={() => setRemovingParticipant(p)}\n className=\"rounded-md p-1 text-text-secondary hover:bg-status-error-bg hover:text-status-error-text\"\n aria-label=\"Remove participant\"\n >\n <UserMinus className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n ),\n )}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title=\"No participants added\"\n description=\"Add attendees to capture who was in the room and what it cost.\"\n action={\n <button\n onClick={() => setParticipantOpen(true)}\n className=\"inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus className=\"h-4 w-4\" />\n Add participant\n </button>\n }\n />\n )}\n </div>\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Action Items\n </h3>\n <button\n onClick={() => setActionItemModal({ mode: \"create\" })}\n className=\"inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-2.5 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n Add\n </button>\n </div>\n {meeting.actionItems.length > 0 ? (\n <div className=\"space-y-2\">\n {meeting.actionItems.map(\n (item: MeetingActionItemFieldsFragment) => (\n <div\n key={item.id}\n className=\"flex items-center justify-between gap-2 rounded-lg border border-border-subtle px-3 py-2\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm text-text-primary\">\n {item.title}\n </p>\n <span className=\"inline-flex rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {item.status}\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n {item.status !== MeetingActionItemStatus.Completed && (\n <button\n onClick={() => handleCompleteItem(item.id)}\n className=\"rounded-md p-1 text-text-secondary hover:bg-status-success-bg hover:text-status-success-text\"\n aria-label=\"Complete action item\"\n >\n <Check className=\"h-4 w-4\" />\n </button>\n )}\n <button\n onClick={() =>\n setActionItemModal({ mode: \"edit\", item })\n }\n className=\"rounded-md p-1 text-text-secondary hover:bg-bg-sunken hover:text-text-primary\"\n aria-label=\"Edit action item\"\n >\n <Pencil className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setDeletingItem(item)}\n className=\"rounded-md p-1 text-text-secondary hover:bg-status-error-bg hover:text-status-error-text\"\n aria-label=\"Delete action item\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n ),\n )}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title=\"No action items\"\n description=\"Capture follow-ups here so commitments from the meeting don't get lost.\"\n action={\n <button\n onClick={() => setActionItemModal({ mode: \"create\" })}\n className=\"inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus className=\"h-4 w-4\" />\n Add action item\n </button>\n }\n />\n )}\n </div>\n </div>\n\n {/* Edit meeting */}\n {editOpen && (\n <MeetingFormModal\n open\n onClose={() => setEditOpen(false)}\n workspaceId={workspaceId}\n meeting={meeting}\n submitting={updating}\n error={Boolean(updateError)}\n onUpdate={handleUpdateMeeting}\n />\n )}\n\n {/* Delete meeting */}\n <Modal\n open={deleteOpen}\n onClose={() => setDeleteOpen(false)}\n title=\"Delete meeting\"\n description=\"This permanently removes the meeting and its analytics.\"\n size=\"sm\"\n footer={\n <>\n <button\n onClick={() => setDeleteOpen(false)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleDeleteMeeting}\n disabled={deletingMeeting}\n className=\"rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/90 disabled:opacity-50\"\n >\n {deletingMeeting ? \"Deleting...\" : \"Delete\"}\n </button>\n </>\n }\n >\n <p className=\"text-sm text-text-secondary\">\n Are you sure you want to delete{\" \"}\n <span className=\"font-medium text-text-primary\">{meeting.title}</span>\n ? This action cannot be undone.\n </p>\n </Modal>\n\n {/* Add participant */}\n {participantOpen && (\n <ParticipantFormModal\n open\n onClose={() => setParticipantOpen(false)}\n defaultUserId={currentUser?.id}\n submitting={addingParticipant}\n error={Boolean(addPError)}\n onSubmit={handleAddParticipant}\n />\n )}\n\n {/* Remove participant confirm */}\n <Modal\n open={Boolean(removingParticipant)}\n onClose={() => setRemovingParticipant(null)}\n title=\"Remove participant\"\n size=\"sm\"\n footer={\n <>\n <button\n onClick={() => setRemovingParticipant(null)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleRemoveParticipant}\n className=\"rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/90\"\n >\n Remove\n </button>\n </>\n }\n >\n <p className=\"text-sm text-text-secondary\">\n Remove{\" \"}\n <span className=\"font-medium text-text-primary\">\n {removingParticipant?.userId}\n </span>{\" \"}\n from this meeting?\n </p>\n </Modal>\n\n {/* Create / edit action item */}\n {actionItemModal && (\n <ActionItemFormModal\n open\n onClose={() => setActionItemModal(null)}\n item={\n actionItemModal.mode === \"edit\" ? actionItemModal.item : undefined\n }\n submitting={\n actionItemModal.mode === \"edit\" ? updatingItem : creatingItem\n }\n error={Boolean(\n actionItemModal.mode === \"edit\" ? updateItemError : createItemError,\n )}\n onCreate={handleCreateItem}\n onUpdate={\n actionItemModal.mode === \"edit\"\n ? (input) => handleUpdateItem(actionItemModal.item.id, input)\n : undefined\n }\n />\n )}\n\n {/* Delete action item confirm */}\n <Modal\n open={Boolean(deletingItem)}\n onClose={() => setDeletingItem(null)}\n title=\"Delete action item\"\n size=\"sm\"\n footer={\n <>\n <button\n onClick={() => setDeletingItem(null)}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n Cancel\n </button>\n <button\n onClick={handleDeleteItem}\n className=\"rounded-md bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg/90\"\n >\n Delete\n </button>\n </>\n }\n >\n <p className=\"text-sm text-text-secondary\">\n Delete action item{\" \"}\n <span className=\"font-medium text-text-primary\">\n {deletingItem?.title}\n </span>\n ?\n </p>\n </Modal>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmDA,IAAM,IAA6B;CACjC,EAAyB;CACzB,EAAyB;CACzB,EAAyB;CACzB,EAAyB;CAC1B;AAED,SAAgB,IAAoB;CAClC,IAAM,EAAE,UAAO,GAA2B,EACpC,EAAE,iBAAc,IAAI,mBAAgB,GAAe,EACnD,IAAW,GAAuB,EAClC,IAAY,KAAM,IAElB,EAAE,SAAM,YAAS,UAAO,eAAY,EAAmB;EAC3D,WAAW;GAAE,IAAI;GAAW;GAAa;EACzC,MAAM,CAAC,KAAe,CAAC;EACxB,CAAC,EAEI,CAAC,GAAe,EAAE,SAAS,GAAU,OAAO,OAChD,GAA0B,EACtB,CAAC,GAAe,EAAE,SAAS,OAC/B,IAA0B,EACtB,CAAC,GAAa,EAAE,SAAS,OAAY,GAAwB,EAC7D,CAAC,IAAgB,EAAE,SAAS,IAAmB,OAAO,QAC1D,IAA2B,EACvB,CAAC,MAAqB,GAA8B,EACpD,CAAC,MAA2B,GAAoC,EAChE,CAAC,IAAkB,EAAE,SAAS,IAAc,OAAO,QACvD,IAA6B,EACzB,CAAC,IAAkB,EAAE,SAAS,IAAc,OAAO,QACvD,GAA6B,EACzB,CAAC,MAAsB,IAA+B,EACtD,CAAC,MAAoB,IAA6B,EAElD,CAAC,IAAU,KAAe,EAAS,GAAM,EACzC,CAAC,IAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,IAAiB,KAAsB,EAAS,GAAM,EACvD,CAAC,GAAqB,KAC1B,EAAkD,KAAK,EACnD,CAAC,GAAiB,KAAsB,EAI5C,KAAK,EACD,CAAC,GAAc,KACnB,EAAiD,KAAK,EAElD,IAAU,GAAM;AAEtB,KAAI,EACF,QACE,kBAAC,GAAD;EAAY,OAAM;EAAkB,aAAa,eAAe;YAC9D,kBAAC,IAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,CAAA;AAIjB,KAAI,KAAS,CAAC,EACZ,QACE,kBAAC,GAAD;EAAY,OAAM;EAAkB,aAAa,eAAe;YAC9D,kBAAC,OAAD;GAAK,WAAU;aACZ,IACG,4DACA;GACA,CAAA;EACK,CAAA;CAIjB,IAAM,KAAiB,EAAQ,YAAY,QACxC,MAAuC,EAAE,WAAW,YACtD,CAAC,QACI,IAAgB,EAAQ,UAAU,GAElC,KAAsB,OAAO,MAA8B;AAG/D,EAFA,MAAM,EAAc,EAAE,WAAW;GAAE,IAAI;GAAW;GAAa;GAAO,EAAE,CAAC,EACzE,MAAM,GAAS,EACf,EAAY,GAAM;IAGd,IAAsB,YAAY;AAGtC,EAFA,MAAM,EAAc,EAAE,WAAW;GAAE,IAAI;GAAW;GAAa,EAAE,CAAC,EAClE,EAAc,GAAM,EACpB,EAAS,YAAY;IAGjB,KAAa,OAAO,MAAkB;AAI1C,EAHA,MAAM,EAAY,EAChB,WAAW;GAAE,IAAI;GAAW;GAAa,QAAQ;GAAO,EACzD,CAAC,EACF,MAAM,GAAS;IAGX,KAAuB,OAAO,MAAsC;AAKxE,EAJA,MAAM,GAAe,EACnB,WAAW;GAAE;GAAW;GAAa;GAAO,EAC7C,CAAC,EACF,MAAM,GAAS,EACf,EAAmB,GAAM;IAGrB,KAA0B,YAAY;AACrC,QACL,MAAM,GAAkB,EACtB,WAAW;GACT;GACA,eAAe,EAAoB;GACnC;GACD,EACF,CAAC,EACF,EAAuB,KAAK,EAC5B,MAAM,GAAS;IAGX,KAA0B,OAC9B,GACA,MACG;AAIH,EAHA,MAAM,GAAwB,EAC5B,WAAW;GAAE;GAAW;GAAe;GAAa;GAAQ,EAC7D,CAAC,EACF,MAAM,GAAS;IAGX,KAAmB,OAAO,MAAiC;AAG/D,EAFA,MAAM,GAAiB,EAAE,WAAW;GAAE;GAAW;GAAa;GAAO,EAAE,CAAC,EACxE,MAAM,GAAS,EACf,EAAmB,KAAK;IAGpB,KAAmB,OACvB,GACA,MACG;AAGH,EAFA,MAAM,GAAiB,EAAE,WAAW;GAAE,IAAI;GAAQ;GAAa;GAAO,EAAE,CAAC,EACzE,MAAM,GAAS,EACf,EAAmB,KAAK;IAGpB,KAAqB,OAAO,MAAmB;AAEnD,EADA,MAAM,GAAmB,EAAE,WAAW;GAAE,IAAI;GAAQ;GAAa,EAAE,CAAC,EACpE,MAAM,GAAS;;AAUjB,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAa,EAAQ;EACrB,SAAQ;EACR,SACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;GACE,eAAe,EAAY,GAAK;GAChC,WAAU;aAFZ,CAIE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,OAEvB;MACT,kBAAC,UAAD;GACE,eAAe,EAAc,GAAK;GAClC,WAAU;aAFZ,CAIE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,SAEvB;KACR,EAAA,CAAA;YApBP;GAuBE,kBAAC,GAAD;IACE,YAAW;IACX,WAAU;IACV,OAAO,CACL;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,eAAe,EAAS,YAAY;KACrC,EACD;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,eAAe,EAAS,sBAAsB;KAC/C,CACF;IACD,CAAA;GACF,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MACE,UAAA;MACA,OAAM;MACN,OAAO,GAAG,EAAQ,YAAY,EAAE;MAChC,MAAM,kBAAC,IAAD,EAAO,WAAU,WAAY,CAAA;MACnC,CAAA;KACF,kBAAC,GAAD;MACE,OAAM;MACN,OAAO,OAAO,EAAQ,aAAa,OAAO;MAC1C,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;MACnC,CAAA;KACF,kBAAC,GAAD;MACE,OAAM;MACN,OAAO,EAAQ,QAAQ,OAAsC,QAA/B,EAAe,EAAQ,KAAK;MAC1D,aAAY;MACZ,CAAA;KACF,kBAAC,GAAD;MACE,OAAM;MACN,OAAO,OAAO,EAAQ,YAAY,OAAO;MACzC,aAAa,GAAG,GAAe;MAC/B,CAAA;KACE;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,MAAD;MAAI,WAAU;gBAA+C;MAExD,CAAA;KACL,kBAAC,KAAD;MAAG,WAAU;gBAAmC;MAE5C,CAAA;KACJ,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACG;OAAC;OAAG;OAAG;OAAG;OAAG;OAAE,CAAC,KAAK,MACpB,kBAAC,UAAD;OAEE,eAAe,GAAW,EAAM;OAChC,UAAU;OACV,cAAY,QAAQ,EAAM,OAAO,IAAQ,IAAI,MAAM;OACnD,WAAU;iBAEV,kBAAC,IAAD,EACE,WAAW,EACT,WACA,KAAS,IACL,sDACA,sBACL,EACD,CAAA;OACK,EAdF,EAcE,CACT,EACD,IAAgB,KACf,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CACG,GAAc,OACV;SAEL;;KACF;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA0C;OAEnD,CAAA,EACL,kBAAC,UAAD;OACE,eAAe,EAAmB,GAAK;OACvC,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,eAAgB,CAAA,EAAA,MAEzB;SACL;SACL,EAAQ,aAAa,SAAS,IAC7B,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAQ,aAAa,KACnB,MACC,kBAAC,OAAD;OAEE,WAAU;iBAFZ,CAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAE;SACD,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBAA+B,EAAE;SAAS,CAAA,CACnD;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,OAAO,EAAE;SACT,WAAW,MACT,GACE,EAAE,IACF,EAAE,OAAO,MACV;SAEH,WAAU;SACV,cAAW;mBAEV,EAA2B,KAAK,MAC/B,kBAAC,UAAD;UAAgB,OAAO;oBACpB;UACM,EAFI,EAEJ,CACT;SACK,CAAA,EACT,kBAAC,UAAD;SACE,eAAe,EAAuB,EAAE;SACxC,WAAU;SACV,cAAW;mBAEX,kBAAC,IAAD,EAAW,WAAU,WAAY,CAAA;SAC1B,CAAA,CACL;UACF;SAnCC,EAAE,GAmCH,CAET;MACG,CAAA,GAEN,kBAAC,GAAD;MACE,cAAa;MACb,OAAM;MACN,aAAY;MACZ,QACE,kBAAC,UAAD;OACE,eAAe,EAAmB,GAAK;OACvC,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBAErB;;MAEX,CAAA,CAEA;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA0C;OAEnD,CAAA,EACL,kBAAC,UAAD;OACE,eAAe,EAAmB,EAAE,MAAM,UAAU,CAAC;OACrD,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,eAAgB,CAAA,EAAA,MAEzB;SACL;SACL,EAAQ,YAAY,SAAS,IAC5B,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAQ,YAAY,KAClB,MACC,kBAAC,OAAD;OAEE,WAAU;iBAFZ,CAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAK;SACJ,CAAA,EACJ,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAK;SACD,CAAA,CACH;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACG,EAAK,WAAW,EAAwB,aACvC,kBAAC,UAAD;UACE,eAAe,GAAmB,EAAK,GAAG;UAC1C,WAAU;UACV,cAAW;oBAEX,kBAAC,IAAD,EAAO,WAAU,WAAY,CAAA;UACtB,CAAA;SAEX,kBAAC,UAAD;UACE,eACE,EAAmB;WAAE,MAAM;WAAQ;WAAM,CAAC;UAE5C,WAAU;UACV,cAAW;oBAEX,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;UACvB,CAAA;SACT,kBAAC,UAAD;UACE,eAAe,EAAgB,EAAK;UACpC,WAAU;UACV,cAAW;oBAEX,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;UACvB,CAAA;SACL;UACF;SAtCC,EAAK,GAsCN,CAET;MACG,CAAA,GAEN,kBAAC,GAAD;MACE,cAAa;MACb,OAAM;MACN,aAAY;MACZ,QACE,kBAAC,UAAD;OACE,eAAe,EAAmB,EAAE,MAAM,UAAU,CAAC;OACrD,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBAErB;;MAEX,CAAA,CAEA;OACF;;GAGL,MACC,kBAAC,IAAD;IACE,MAAA;IACA,eAAe,EAAY,GAAM;IACpB;IACJ;IACT,YAAY;IACZ,OAAO,EAAQ;IACf,UAAU;IACV,CAAA;GAIJ,kBAAC,GAAD;IACE,MAAM;IACN,eAAe,EAAc,GAAM;IACnC,OAAM;IACN,aAAY;IACZ,MAAK;IACL,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;KACE,eAAe,EAAc,GAAM;KACnC,WAAU;eACX;KAEQ,CAAA,EACT,kBAAC,UAAD;KACE,SAAS;KACT,UAAU;KACV,WAAU;eAET,IAAkB,gBAAgB;KAC5B,CAAA,CACR,EAAA,CAAA;cAGL,kBAAC,KAAD;KAAG,WAAU;eAAb;MAA2C;MACT;MAChC,kBAAC,QAAD;OAAM,WAAU;iBAAiC,EAAQ;OAAa,CAAA;;MAEpE;;IACE,CAAA;GAGP,MACC,kBAAC,IAAD;IACE,MAAA;IACA,eAAe,EAAmB,GAAM;IACxC,eAAe,GAAa;IAC5B,YAAY;IACZ,OAAO,EAAQ;IACf,UAAU;IACV,CAAA;GAIJ,kBAAC,GAAD;IACE,MAAM,EAAQ;IACd,eAAe,EAAuB,KAAK;IAC3C,OAAM;IACN,MAAK;IACL,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;KACE,eAAe,EAAuB,KAAK;KAC3C,WAAU;eACX;KAEQ,CAAA,EACT,kBAAC,UAAD;KACE,SAAS;KACT,WAAU;eACX;KAEQ,CAAA,CACR,EAAA,CAAA;cAGL,kBAAC,KAAD;KAAG,WAAU;eAAb;MAA2C;MAClC;MACP,kBAAC,QAAD;OAAM,WAAU;iBACb,GAAqB;OACjB,CAAA;MAAC;MAAI;MAEV;;IACE,CAAA;GAGP,KACC,kBAAC,IAAD;IACE,MAAA;IACA,eAAe,EAAmB,KAAK;IACvC,MACE,EAAgB,SAAS,SAAS,EAAgB,OAAO,KAAA;IAE3D,YACE,EAAgB,SAAS,SAAS,KAAe;IAEnD,OAAO,GACL,EAAgB,SAAS,SAAS,KAAkB;IAEtD,UAAU;IACV,UACE,EAAgB,SAAS,UACpB,MAAU,GAAiB,EAAgB,KAAK,IAAI,EAAM,GAC3D,KAAA;IAEN,CAAA;GAIJ,kBAAC,GAAD;IACE,MAAM,EAAQ;IACd,eAAe,EAAgB,KAAK;IACpC,OAAM;IACN,MAAK;IACL,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;KACE,eAAe,EAAgB,KAAK;KACpC,WAAU;eACX;KAEQ,CAAA,EACT,kBAAC,UAAD;KACE,SArYa,YAAY;AAC9B,YACL,MAAM,GAAiB,EAAE,WAAW;OAAE,IAAI,EAAa;OAAI;OAAa,EAAE,CAAC,EAC3E,EAAgB,KAAK,EACrB,MAAM,GAAS;;KAkYL,WAAU;eACX;KAEQ,CAAA,CACR,EAAA,CAAA;cAGL,kBAAC,KAAD;KAAG,WAAU;eAAb;MAA2C;MACtB;MACnB,kBAAC,QAAD;OAAM,WAAU;iBACb,GAAc;OACV,CAAA;;MAEL;;IACE,CAAA;GACG"}