@burdenoff/microfe-technospam 2026.705.1 → 2026.709.1

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 (48) hide show
  1. package/dist/generated/wspace-operations.js +67 -0
  2. package/dist/generated/wspace-operations.js.map +1 -0
  3. package/dist/index.js +3 -1
  4. package/dist/technospam/components/MediaCover.js +57 -0
  5. package/dist/technospam/components/MediaCover.js.map +1 -0
  6. package/dist/technospam/components/PageLayout.js +1 -1
  7. package/dist/technospam/components/PageLayout.js.map +1 -1
  8. package/dist/technospam/components/StatCard.js +19 -11
  9. package/dist/technospam/components/StatCard.js.map +1 -1
  10. package/dist/technospam/components/StatusBadge.js +1 -1
  11. package/dist/technospam/components/StatusBadge.js.map +1 -1
  12. package/dist/technospam/components/index.js +1 -0
  13. package/dist/technospam/hooks/useTechnoSpamAnalytics.js +13 -0
  14. package/dist/technospam/hooks/useTechnoSpamAnalytics.js.map +1 -0
  15. package/dist/technospam/index.js +2 -0
  16. package/dist/technospam/pages/AdminAdminDashboardPagePage.js +525 -459
  17. package/dist/technospam/pages/AdminAdminDashboardPagePage.js.map +1 -1
  18. package/dist/technospam/pages/AnalyticsAnalyticsPagePage.js +167 -127
  19. package/dist/technospam/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  20. package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js +178 -101
  21. package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js.map +1 -1
  22. package/dist/technospam/pages/ApplicationsProblemsPagePage.js +103 -99
  23. package/dist/technospam/pages/ApplicationsProblemsPagePage.js.map +1 -1
  24. package/dist/technospam/pages/CoursesCourseDetailsPagePage.js +316 -184
  25. package/dist/technospam/pages/CoursesCourseDetailsPagePage.js.map +1 -1
  26. package/dist/technospam/pages/CoursesCoursesPagePage.js +101 -93
  27. package/dist/technospam/pages/CoursesCoursesPagePage.js.map +1 -1
  28. package/dist/technospam/pages/CoursesMyLearningPagePage.js +119 -88
  29. package/dist/technospam/pages/CoursesMyLearningPagePage.js.map +1 -1
  30. package/dist/technospam/pages/DashboardDashboardPagePage.js +232 -199
  31. package/dist/technospam/pages/DashboardDashboardPagePage.js.map +1 -1
  32. package/dist/technospam/pages/HackathonsHackathonDetailsPagePage.js +128 -106
  33. package/dist/technospam/pages/HackathonsHackathonDetailsPagePage.js.map +1 -1
  34. package/dist/technospam/pages/HackathonsHackathonsPagePage.js +99 -91
  35. package/dist/technospam/pages/HackathonsHackathonsPagePage.js.map +1 -1
  36. package/dist/technospam/pages/MentorshipMentorProfilePagePage.js +185 -116
  37. package/dist/technospam/pages/MentorshipMentorProfilePagePage.js.map +1 -1
  38. package/dist/technospam/pages/MentorshipMentorsPagePage.js +233 -165
  39. package/dist/technospam/pages/MentorshipMentorsPagePage.js.map +1 -1
  40. package/dist/technospam/pages/MentorshipSessionsPagePage.js +146 -113
  41. package/dist/technospam/pages/MentorshipSessionsPagePage.js.map +1 -1
  42. package/dist/technospam/services/assistantApi.js +222 -0
  43. package/dist/technospam/services/assistantApi.js.map +1 -0
  44. package/dist/technospam/services/createSandboxAssistantTransport.js +120 -0
  45. package/dist/technospam/services/createSandboxAssistantTransport.js.map +1 -0
  46. package/dist/technospam/utils/pageContext.js +46 -0
  47. package/dist/technospam/utils/pageContext.js.map +1 -0
  48. package/package.json +5 -1
@@ -7,36 +7,37 @@ import { EmptyView as s, ErrorView as c, LoadingRows as l } from "../components/
7
7
  import "../components/index.js";
8
8
  import { notify as u } from "../lib/toast.js";
9
9
  import { useCancelSession as d, useCompleteSession as f, useConfirmSession as p, useMentorsQuery as m, useSessionsQuery as h } from "../api/technospamApi.js";
10
- import { useState as g } from "react";
11
- import { CalendarClock as _, Check as v, CheckCircle2 as y, Clock as b, MessageSquare as x, Users as S, Video as C, X as w } from "lucide-react";
12
- import { jsx as T, jsxs as E } from "react/jsx-runtime";
13
- import { Button as D, GlassCard as O, Input as k, Tabs as A, TabsList as j, TabsTrigger as M } from "@burdenoff/fe-libs/ui";
10
+ import { useTechnoSpamAnalytics as g } from "../hooks/useTechnoSpamAnalytics.js";
11
+ import { useState as _ } from "react";
12
+ import { CalendarClock as v, Check as y, CheckCircle2 as b, Clock as x, MessageSquare as S, Users as C, Video as w, X as T } from "lucide-react";
13
+ import { jsx as E, jsxs as D } from "react/jsx-runtime";
14
+ import { Button as O, GlassCard as k, Input as A, Tabs as j, TabsList as M, TabsTrigger as N } from "@burdenoff/fe-libs/ui";
14
15
  //#region src/technospam/pages/MentorshipSessionsPagePage.tsx
15
- var N = new Set(["REQUESTED", "CONFIRMED"]);
16
- function P({ session: e, showMentor: t, isMentor: n, onCancel: r, onConfirm: s, onComplete: c, busy: l }) {
17
- let u = N.has(e.status), [d, f] = g("none"), [p, m] = g(""), [h, x] = g("5"), [S, A] = g("");
18
- return /* @__PURE__ */ E(O, {
19
- className: "flex flex-col gap-3 p-4",
16
+ var P = new Set(["REQUESTED", "CONFIRMED"]);
17
+ function F({ session: e, showMentor: t, isMentor: n, onCancel: r, onConfirm: s, onComplete: c, busy: l }) {
18
+ let u = P.has(e.status), [d, f] = _("none"), [p, m] = _(""), [h, g] = _("5"), [S, C] = _("");
19
+ return /* @__PURE__ */ D(k, {
20
+ className: "flex flex-col gap-3 p-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md",
20
21
  children: [
21
- /* @__PURE__ */ E("div", {
22
+ /* @__PURE__ */ D("div", {
22
23
  className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
23
- children: [/* @__PURE__ */ E("div", {
24
+ children: [/* @__PURE__ */ D("div", {
24
25
  className: "flex items-start gap-3",
25
- children: [/* @__PURE__ */ T("span", {
26
- className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-accent-wash text-accent-primary",
27
- children: /* @__PURE__ */ T(C, { size: 18 })
28
- }), /* @__PURE__ */ E("div", {
26
+ children: [/* @__PURE__ */ E("span", {
27
+ className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-accent-primary to-accent-purple text-white shadow-sm",
28
+ children: /* @__PURE__ */ E(w, { size: 18 })
29
+ }), /* @__PURE__ */ D("div", {
29
30
  className: "min-w-0",
30
31
  children: [
31
- /* @__PURE__ */ E("div", {
32
+ /* @__PURE__ */ D("div", {
32
33
  className: "flex flex-wrap items-center gap-2",
33
34
  children: [
34
- /* @__PURE__ */ T("span", {
35
+ /* @__PURE__ */ E("span", {
35
36
  className: "truncate text-sm font-semibold text-text-primary",
36
37
  children: e.topic
37
38
  }),
38
- /* @__PURE__ */ T(o, { status: e.status }),
39
- e.rating ? /* @__PURE__ */ E("span", {
39
+ /* @__PURE__ */ E(o, { status: e.status }),
40
+ e.rating ? /* @__PURE__ */ D("span", {
40
41
  className: "text-xs text-text-muted",
41
42
  children: [
42
43
  "★ ",
@@ -46,73 +47,72 @@ function P({ session: e, showMentor: t, isMentor: n, onCancel: r, onConfirm: s,
46
47
  }) : null
47
48
  ]
48
49
  }),
49
- t && e.mentor?.headline ? /* @__PURE__ */ E("div", {
50
+ t && e.mentor?.headline ? /* @__PURE__ */ D("div", {
50
51
  className: "mt-0.5 truncate text-xs text-text-secondary",
51
52
  children: ["with ", e.mentor.headline]
52
53
  }) : null,
53
- /* @__PURE__ */ E("div", {
54
+ /* @__PURE__ */ D("div", {
54
55
  className: "mt-1 flex flex-wrap items-center gap-3 text-xs text-text-muted",
55
- children: [/* @__PURE__ */ E("span", {
56
+ children: [/* @__PURE__ */ D("span", {
56
57
  className: "inline-flex items-center gap-1",
57
58
  children: [
58
- /* @__PURE__ */ T(_, { size: 13 }),
59
+ /* @__PURE__ */ E(v, { size: 13 }),
59
60
  " ",
60
61
  i(e.scheduledAt)
61
62
  ]
62
- }), /* @__PURE__ */ E("span", {
63
+ }), /* @__PURE__ */ D("span", {
63
64
  className: "inline-flex items-center gap-1",
64
65
  children: [
65
- /* @__PURE__ */ T(b, { size: 13 }),
66
+ /* @__PURE__ */ E(x, { size: 13 }),
66
67
  " ",
67
68
  a(e.durationMinutes)
68
69
  ]
69
70
  })]
70
71
  }),
71
- e.agenda ? /* @__PURE__ */ T("p", {
72
+ e.agenda ? /* @__PURE__ */ E("p", {
72
73
  className: "mt-1 line-clamp-2 text-xs text-text-secondary",
73
74
  children: e.agenda
74
75
  }) : null
75
76
  ]
76
77
  })]
77
- }), /* @__PURE__ */ E("div", {
78
+ }), /* @__PURE__ */ D("div", {
78
79
  className: "flex shrink-0 flex-wrap items-center gap-2",
79
80
  children: [
80
- e.meetingUrl ? /* @__PURE__ */ E(D, {
81
- variant: "outline",
81
+ e.meetingUrl ? /* @__PURE__ */ D(O, {
82
82
  size: "sm",
83
83
  onClick: () => window.open(e.meetingUrl ?? "", "_blank", "noopener,noreferrer"),
84
- children: [/* @__PURE__ */ T(C, { size: 15 }), " Join"]
84
+ children: [/* @__PURE__ */ E(w, { size: 15 }), " Join"]
85
85
  }) : null,
86
- n && e.status === "REQUESTED" ? /* @__PURE__ */ E(D, {
86
+ n && e.status === "REQUESTED" ? /* @__PURE__ */ D(O, {
87
87
  variant: "outline",
88
88
  size: "sm",
89
89
  onClick: () => f(d === "confirm" ? "none" : "confirm"),
90
- children: [/* @__PURE__ */ T(v, { size: 15 }), " Confirm"]
90
+ children: [/* @__PURE__ */ E(y, { size: 15 }), " Confirm"]
91
91
  }) : null,
92
- n && e.status === "CONFIRMED" ? /* @__PURE__ */ E(D, {
92
+ n && e.status === "CONFIRMED" ? /* @__PURE__ */ D(O, {
93
93
  variant: "outline",
94
94
  size: "sm",
95
95
  onClick: () => f(d === "complete" ? "none" : "complete"),
96
- children: [/* @__PURE__ */ T(y, { size: 15 }), " Mark complete"]
96
+ children: [/* @__PURE__ */ E(b, { size: 15 }), " Mark complete"]
97
97
  }) : null,
98
- u ? /* @__PURE__ */ E(D, {
98
+ u ? /* @__PURE__ */ D(O, {
99
99
  variant: "ghost",
100
100
  size: "sm",
101
101
  onClick: () => r(e.id),
102
102
  disabled: l,
103
- children: [/* @__PURE__ */ T(w, { size: 15 }), " Cancel"]
103
+ children: [/* @__PURE__ */ E(T, { size: 15 }), " Cancel"]
104
104
  }) : null
105
105
  ]
106
106
  })]
107
107
  }),
108
- d === "confirm" ? /* @__PURE__ */ E("div", {
108
+ d === "confirm" ? /* @__PURE__ */ D("div", {
109
109
  className: "flex flex-col gap-2 rounded-lg border border-border-seam bg-bg-sunken p-3 sm:flex-row sm:items-center",
110
- children: [/* @__PURE__ */ T(k, {
110
+ children: [/* @__PURE__ */ E(A, {
111
111
  className: "flex-1",
112
112
  placeholder: "Meeting link (e.g. https://meet.…)",
113
113
  value: p,
114
114
  onChange: (e) => m(e.target.value)
115
- }), /* @__PURE__ */ T(D, {
115
+ }), /* @__PURE__ */ E(O, {
116
116
  size: "sm",
117
117
  onClick: async () => {
118
118
  await s(e.id, p.trim()), f("none"), m("");
@@ -121,29 +121,29 @@ function P({ session: e, showMentor: t, isMentor: n, onCancel: r, onConfirm: s,
121
121
  children: "Confirm session"
122
122
  })]
123
123
  }) : null,
124
- d === "complete" ? /* @__PURE__ */ E("div", {
124
+ d === "complete" ? /* @__PURE__ */ D("div", {
125
125
  className: "flex flex-col gap-2 rounded-lg border border-border-seam bg-bg-sunken p-3",
126
126
  children: [
127
- /* @__PURE__ */ E("div", {
127
+ /* @__PURE__ */ D("div", {
128
128
  className: "flex items-center gap-2",
129
- children: [/* @__PURE__ */ T("label", {
129
+ children: [/* @__PURE__ */ E("label", {
130
130
  className: "text-xs text-text-secondary",
131
131
  children: "Rating (1–5)"
132
- }), /* @__PURE__ */ T(k, {
132
+ }), /* @__PURE__ */ E(A, {
133
133
  type: "number",
134
134
  min: 1,
135
135
  max: 5,
136
136
  className: "w-20",
137
137
  value: h,
138
- onChange: (e) => x(e.target.value)
138
+ onChange: (e) => g(e.target.value)
139
139
  })]
140
140
  }),
141
- /* @__PURE__ */ T(k, {
141
+ /* @__PURE__ */ E(A, {
142
142
  placeholder: "Feedback for the mentee (optional)",
143
143
  value: S,
144
- onChange: (e) => A(e.target.value)
144
+ onChange: (e) => C(e.target.value)
145
145
  }),
146
- /* @__PURE__ */ T("div", { children: /* @__PURE__ */ T(D, {
146
+ /* @__PURE__ */ E("div", { children: /* @__PURE__ */ E(O, {
147
147
  size: "sm",
148
148
  onClick: async () => {
149
149
  await c(e.id, Math.min(5, Math.max(1, Number(h) || 5)), S.trim()), f("none");
@@ -156,21 +156,21 @@ function P({ session: e, showMentor: t, isMentor: n, onCancel: r, onConfirm: s,
156
156
  ]
157
157
  });
158
158
  }
159
- function F({ loading: e, error: t, sessions: n, showMentor: r, emptyTitle: i, emptyDescription: a, emptyAction: o, isMentor: u, onCancel: d, onConfirm: f, onComplete: p, busyId: m }) {
160
- return e && n.length === 0 ? /* @__PURE__ */ T(l, {
159
+ function I({ loading: e, error: t, sessions: n, showMentor: r, emptyTitle: i, emptyDescription: a, emptyAction: o, isMentor: u, onCancel: d, onConfirm: f, onComplete: p, busyId: m }) {
160
+ return e && n.length === 0 ? /* @__PURE__ */ E(l, {
161
161
  count: 3,
162
162
  height: "h-24"
163
- }) : t ? /* @__PURE__ */ T(c, {
163
+ }) : t ? /* @__PURE__ */ E(c, {
164
164
  title: "Couldn't load sessions",
165
165
  error: t
166
- }) : n.length === 0 ? /* @__PURE__ */ T(s, {
167
- icon: /* @__PURE__ */ T(x, { size: 26 }),
166
+ }) : n.length === 0 ? /* @__PURE__ */ E(s, {
167
+ icon: /* @__PURE__ */ E(S, { size: 26 }),
168
168
  title: i,
169
169
  description: a,
170
170
  action: o
171
- }) : /* @__PURE__ */ T("div", {
171
+ }) : /* @__PURE__ */ E("div", {
172
172
  className: "space-y-3",
173
- children: [...n].sort((e, t) => new Date(t.scheduledAt).getTime() - new Date(e.scheduledAt).getTime()).map((e) => /* @__PURE__ */ T(P, {
173
+ children: [...n].sort((e, t) => new Date(t.scheduledAt).getTime() - new Date(e.scheduledAt).getTime()).map((e) => /* @__PURE__ */ E(F, {
174
174
  session: e,
175
175
  showMentor: r,
176
176
  isMentor: u,
@@ -181,123 +181,156 @@ function F({ loading: e, error: t, sessions: n, showMentor: r, emptyTitle: i, em
181
181
  }, e.id))
182
182
  });
183
183
  }
184
- function I() {
185
- let i = t(), { currentUser: a } = e(), [o, c] = g("mentee"), [_, v] = g(null), y = a?.id, b = h(y ? { menteeId: y } : {}), C = m({}), w = C.data?.tecListMentors.items.find((e) => e.userId === a?.id), O = w?.id, k = h(O ? { mentorId: O } : {}), [N] = d(), [P] = p(), [I] = f(), L = y ? b.data?.tecListSessions ?? [] : [], R = O ? k.data?.tecListSessions ?? [] : [], z = async (e) => {
186
- v(e);
184
+ function L() {
185
+ let i = t(), { currentUser: a, workspaceId: o } = e(), { emit: c } = g(), [y, x] = _("mentee"), [w, T] = _(null), k = a?.id, A = h(k ? { menteeId: k } : {}), P = m({}), F = P.data?.tecListMentors.items.find((e) => e.userId === a?.id), L = F?.id, R = h(L ? { mentorId: L } : {}), [z] = d(), [B] = p(), [V] = f(), H = k ? A.data?.tecListSessions ?? [] : [], U = L ? R.data?.tecListSessions ?? [] : [], W = [...H, ...U], G = W.filter((e) => e.status === "REQUESTED" || e.status === "CONFIRMED").length, K = W.filter((e) => e.status === "COMPLETED").length, q = async (e) => {
186
+ T(e), c("technospam.session.cancel_clicked", {
187
+ workspaceId: o,
188
+ entityId: e,
189
+ entityType: "TEC_MENTOR_SESSION"
190
+ });
187
191
  try {
188
- (await N({ variables: { id: e } })).data?.tecCancelSession && u.success("Session cancelled", "The session has been cancelled.");
192
+ (await z({ variables: { id: e } })).data?.tecCancelSession && (c("technospam.session.cancelled", {
193
+ workspaceId: o,
194
+ entityId: e,
195
+ entityType: "TEC_MENTOR_SESSION"
196
+ }), u.success("Session cancelled", "The session has been cancelled."));
189
197
  } finally {
190
- v(null);
198
+ T(null);
191
199
  }
192
- }, B = async (e, t) => {
193
- v(e);
200
+ }, J = async (e, t) => {
201
+ T(e);
194
202
  try {
195
- (await P({ variables: {
203
+ (await B({ variables: {
196
204
  id: e,
197
205
  meetingUrl: t || void 0
198
- } })).data?.tecConfirmSession && (u.success("Session confirmed", "The mentee has been notified."), await k.refetch());
206
+ } })).data?.tecConfirmSession && (u.success("Session confirmed", "The mentee has been notified."), await R.refetch());
199
207
  } finally {
200
- v(null);
208
+ T(null);
201
209
  }
202
- }, V = async (e, t, n) => {
203
- v(e);
210
+ }, Y = async (e, t, n) => {
211
+ T(e), c("technospam.session.complete_clicked", {
212
+ workspaceId: o,
213
+ entityId: e,
214
+ entityType: "TEC_MENTOR_SESSION"
215
+ });
204
216
  try {
205
- (await I({ variables: {
217
+ (await V({ variables: {
206
218
  id: e,
207
219
  rating: t,
208
220
  feedback: n || void 0
209
- } })).data?.tecCompleteSession && (u.success("Session completed", "Nice work — the session is wrapped up."), await k.refetch());
221
+ } })).data?.tecCompleteSession && (c("technospam.session.completed", {
222
+ workspaceId: o,
223
+ entityId: e,
224
+ entityType: "TEC_MENTOR_SESSION"
225
+ }), u.success("Session completed", "Nice work — the session is wrapped up."), await R.refetch());
210
226
  } finally {
211
- v(null);
227
+ T(null);
212
228
  }
213
229
  };
214
- return a?.id ? /* @__PURE__ */ E(n, {
230
+ return a?.id ? /* @__PURE__ */ D(n, {
215
231
  hero: !0,
216
232
  title: "My Sessions",
217
233
  description: "Manage the mentorship sessions you've booked and the ones you host.",
218
- actions: /* @__PURE__ */ E(D, {
234
+ actions: /* @__PURE__ */ D(O, {
219
235
  variant: "outline",
220
236
  onClick: () => i("/mentorship/mentors-page"),
221
- children: [/* @__PURE__ */ T(S, { size: 16 }), " Find a mentor"]
237
+ children: [/* @__PURE__ */ E(C, { size: 16 }), " Find a mentor"]
222
238
  }),
223
239
  children: [
224
- /* @__PURE__ */ E("div", {
225
- className: "mb-5 grid grid-cols-2 gap-3 sm:max-w-md",
226
- children: [/* @__PURE__ */ T(r, {
227
- label: "As mentee",
228
- value: L.length,
229
- icon: x
230
- }), /* @__PURE__ */ T(r, {
231
- label: "As mentor",
232
- value: O ? R.length : 0,
233
- icon: S
234
- })]
240
+ /* @__PURE__ */ D("div", {
241
+ className: "mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4",
242
+ children: [
243
+ /* @__PURE__ */ E(r, {
244
+ label: "As mentee",
245
+ value: H.length,
246
+ icon: S,
247
+ tone: "blue"
248
+ }),
249
+ /* @__PURE__ */ E(r, {
250
+ label: "As mentor",
251
+ value: L ? U.length : 0,
252
+ icon: C,
253
+ tone: "purple"
254
+ }),
255
+ /* @__PURE__ */ E(r, {
256
+ label: "Upcoming",
257
+ value: G,
258
+ icon: v,
259
+ tone: "teal"
260
+ }),
261
+ /* @__PURE__ */ E(r, {
262
+ label: "Completed",
263
+ value: K,
264
+ icon: b,
265
+ tone: "green"
266
+ })
267
+ ]
235
268
  }),
236
- /* @__PURE__ */ T(A, {
237
- value: o,
238
- onValueChange: (e) => c(e),
269
+ /* @__PURE__ */ E(j, {
270
+ value: y,
271
+ onValueChange: (e) => x(e),
239
272
  className: "mb-4",
240
- children: /* @__PURE__ */ E(j, { children: [/* @__PURE__ */ T(M, {
273
+ children: /* @__PURE__ */ D(M, { children: [/* @__PURE__ */ E(N, {
241
274
  value: "mentee",
242
275
  children: "As mentee"
243
- }), /* @__PURE__ */ T(M, {
276
+ }), /* @__PURE__ */ E(N, {
244
277
  value: "mentor",
245
278
  children: "As mentor"
246
279
  })] })
247
280
  }),
248
- o === "mentee" ? /* @__PURE__ */ T(F, {
249
- loading: b.loading,
250
- error: b.error,
251
- sessions: L,
281
+ y === "mentee" ? /* @__PURE__ */ E(I, {
282
+ loading: A.loading,
283
+ error: A.error,
284
+ sessions: H,
252
285
  showMentor: !0,
253
286
  emptyTitle: "No sessions booked yet",
254
287
  emptyDescription: "Find a mentor and request a session to get personalized guidance.",
255
- emptyAction: /* @__PURE__ */ T(D, {
288
+ emptyAction: /* @__PURE__ */ E(O, {
256
289
  onClick: () => i("/mentorship/mentors-page"),
257
290
  children: "Find a mentor"
258
291
  }),
259
292
  isMentor: !1,
260
- onCancel: z,
261
- onConfirm: B,
262
- onComplete: V,
263
- busyId: _
264
- }) : C.loading && !w ? /* @__PURE__ */ T(l, {
293
+ onCancel: q,
294
+ onConfirm: J,
295
+ onComplete: Y,
296
+ busyId: w
297
+ }) : P.loading && !F ? /* @__PURE__ */ E(l, {
265
298
  count: 3,
266
299
  height: "h-24"
267
- }) : O ? /* @__PURE__ */ T(F, {
268
- loading: k.loading,
269
- error: k.error,
270
- sessions: R,
300
+ }) : L ? /* @__PURE__ */ E(I, {
301
+ loading: R.loading,
302
+ error: R.error,
303
+ sessions: U,
271
304
  showMentor: !1,
272
305
  emptyTitle: "No sessions to host yet",
273
306
  emptyDescription: "When mentees request time with you, their sessions will show up here.",
274
307
  isMentor: !0,
275
- onCancel: z,
276
- onConfirm: B,
277
- onComplete: V,
278
- busyId: _
279
- }) : /* @__PURE__ */ T(s, {
280
- icon: /* @__PURE__ */ T(S, { size: 26 }),
308
+ onCancel: q,
309
+ onConfirm: J,
310
+ onComplete: Y,
311
+ busyId: w
312
+ }) : /* @__PURE__ */ E(s, {
313
+ icon: /* @__PURE__ */ E(C, { size: 26 }),
281
314
  title: "You're not a mentor yet",
282
315
  description: "Create a mentor profile to start hosting sessions and helping others build.",
283
- action: /* @__PURE__ */ T(D, {
316
+ action: /* @__PURE__ */ E(O, {
284
317
  onClick: () => i("/mentorship/mentors-page"),
285
318
  children: "Become a mentor"
286
319
  })
287
320
  })
288
321
  ]
289
- }) : /* @__PURE__ */ T(n, {
322
+ }) : /* @__PURE__ */ E(n, {
290
323
  hero: !0,
291
324
  title: "My Sessions",
292
325
  description: "Track your mentorship sessions.",
293
- children: /* @__PURE__ */ T(s, {
294
- icon: /* @__PURE__ */ T(x, { size: 26 }),
326
+ children: /* @__PURE__ */ E(s, {
327
+ icon: /* @__PURE__ */ E(S, { size: 26 }),
295
328
  title: "Sign in to view your sessions",
296
329
  description: "Your booked and hosted mentorship sessions will appear here once you're signed in."
297
330
  })
298
331
  });
299
332
  }
300
333
  //#endregion
301
- export { I as MentorshipSessionsPagePage };
334
+ export { L as MentorshipSessionsPagePage };
302
335
 
303
336
  //# sourceMappingURL=MentorshipSessionsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MentorshipSessionsPagePage.js","names":[],"sources":["../../../src/technospam/pages/MentorshipSessionsPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n CalendarClock,\n Check,\n CheckCircle2,\n Clock,\n MessageSquare,\n Users,\n Video,\n X,\n} from 'lucide-react';\nimport { Button, GlassCard, Input, Tabs, TabsList, TabsTrigger } from '@burdenoff/fe-libs/ui';\nimport {\n EmptyView,\n ErrorView,\n LoadingRows,\n PageLayout,\n StatCard,\n StatusBadge,\n} from '../components';\nimport { useTechnoSpam, useTechnoSpamNavigate } from '../providers/TechnoSpamProvider';\nimport {\n useCancelSession,\n useCompleteSession,\n useConfirmSession,\n useMentorsQuery,\n useSessionsQuery,\n type TecMentorSession,\n} from '../api/technospamApi';\nimport { formatDateTime, formatDuration } from '../utils/format';\nimport { notify } from '../lib/toast';\n\ntype Perspective = 'mentee' | 'mentor';\n\nconst CANCELLABLE = new Set(['REQUESTED', 'CONFIRMED']);\n\nfunction SessionRow({\n session,\n showMentor,\n isMentor,\n onCancel,\n onConfirm,\n onComplete,\n busy,\n}: {\n session: TecMentorSession;\n showMentor: boolean;\n isMentor: boolean;\n onCancel: (id: string) => void;\n onConfirm: (id: string, meetingUrl: string) => Promise<void>;\n onComplete: (id: string, rating: number, feedback: string) => Promise<void>;\n busy: boolean;\n}) {\n const canCancel = CANCELLABLE.has(session.status);\n const [mode, setMode] = useState<'none' | 'confirm' | 'complete'>('none');\n const [meetingUrl, setMeetingUrl] = useState('');\n const [rating, setRating] = useState('5');\n const [feedback, setFeedback] = useState('');\n\n const submitConfirm = async () => {\n await onConfirm(session.id, meetingUrl.trim());\n setMode('none');\n setMeetingUrl('');\n };\n const submitComplete = async () => {\n await onComplete(session.id, Math.min(5, Math.max(1, Number(rating) || 5)), feedback.trim());\n setMode('none');\n };\n\n return (\n <GlassCard className=\"flex flex-col gap-3 p-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-start gap-3\">\n <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-accent-wash text-accent-primary\">\n <Video size={18} />\n </span>\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {session.topic}\n </span>\n <StatusBadge status={session.status} />\n {session.rating ? (\n <span className=\"text-xs text-text-muted\">★ {session.rating}/5</span>\n ) : null}\n </div>\n {showMentor && session.mentor?.headline ? (\n <div className=\"mt-0.5 truncate text-xs text-text-secondary\">\n with {session.mentor.headline}\n </div>\n ) : null}\n <div className=\"mt-1 flex flex-wrap items-center gap-3 text-xs text-text-muted\">\n <span className=\"inline-flex items-center gap-1\">\n <CalendarClock size={13} /> {formatDateTime(session.scheduledAt)}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Clock size={13} /> {formatDuration(session.durationMinutes)}\n </span>\n </div>\n {session.agenda ? (\n <p className=\"mt-1 line-clamp-2 text-xs text-text-secondary\">{session.agenda}</p>\n ) : null}\n </div>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center gap-2\">\n {session.meetingUrl ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => window.open(session.meetingUrl ?? '', '_blank', 'noopener,noreferrer')}\n >\n <Video size={15} /> Join\n </Button>\n ) : null}\n {isMentor && session.status === 'REQUESTED' ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setMode(mode === 'confirm' ? 'none' : 'confirm')}\n >\n <Check size={15} /> Confirm\n </Button>\n ) : null}\n {isMentor && session.status === 'CONFIRMED' ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setMode(mode === 'complete' ? 'none' : 'complete')}\n >\n <CheckCircle2 size={15} /> Mark complete\n </Button>\n ) : null}\n {canCancel ? (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => onCancel(session.id)} disabled={busy}>\n <X size={15} /> Cancel\n </Button>\n ) : null}\n </div>\n </div>\n\n {mode === 'confirm' ? (\n <div className=\"flex flex-col gap-2 rounded-lg border border-border-seam bg-bg-sunken p-3 sm:flex-row sm:items-center\">\n <Input\n className=\"flex-1\"\n placeholder=\"Meeting link (e.g. https://meet.…)\"\n value={meetingUrl}\n onChange={(e) => setMeetingUrl(e.target.value)}\n />\n <Button size=\"sm\" onClick={submitConfirm} disabled={busy}>\n Confirm session\n </Button>\n </div>\n ) : null}\n {mode === 'complete' ? (\n <div className=\"flex flex-col gap-2 rounded-lg border border-border-seam bg-bg-sunken p-3\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-text-secondary\">Rating (1–5)</label>\n <Input\n type=\"number\"\n min={1}\n max={5}\n className=\"w-20\"\n value={rating}\n onChange={(e) => setRating(e.target.value)}\n />\n </div>\n <Input\n placeholder=\"Feedback for the mentee (optional)\"\n value={feedback}\n onChange={(e) => setFeedback(e.target.value)}\n />\n <div>\n <Button size=\"sm\" onClick={submitComplete} disabled={busy}>\n Complete session\n </Button>\n </div>\n </div>\n ) : null}\n </GlassCard>\n );\n}\n\nfunction SessionsList({\n loading,\n error,\n sessions,\n showMentor,\n emptyTitle,\n emptyDescription,\n emptyAction,\n isMentor,\n onCancel,\n onConfirm,\n onComplete,\n busyId,\n}: {\n loading: boolean;\n error?: { message?: string };\n sessions: TecMentorSession[];\n showMentor: boolean;\n emptyTitle: string;\n emptyDescription: string;\n emptyAction?: React.ReactNode;\n isMentor: boolean;\n onCancel: (id: string) => void;\n onConfirm: (id: string, meetingUrl: string) => Promise<void>;\n onComplete: (id: string, rating: number, feedback: string) => Promise<void>;\n busyId: string | null;\n}) {\n if (loading && sessions.length === 0) return <LoadingRows count={3} height=\"h-24\" />;\n if (error) return <ErrorView title=\"Couldn't load sessions\" error={error} />;\n if (sessions.length === 0) {\n return (\n <EmptyView\n icon={<MessageSquare size={26} />}\n title={emptyTitle}\n description={emptyDescription}\n action={emptyAction}\n />\n );\n }\n const sorted = [...sessions].sort(\n (a, b) => new Date(b.scheduledAt).getTime() - new Date(a.scheduledAt).getTime()\n );\n return (\n <div className=\"space-y-3\">\n {sorted.map((session) => (\n <SessionRow\n key={session.id}\n session={session}\n showMentor={showMentor}\n isMentor={isMentor}\n onCancel={onCancel}\n onConfirm={onConfirm}\n onComplete={onComplete}\n busy={busyId === session.id}\n />\n ))}\n </div>\n );\n}\n\nexport function MentorshipSessionsPagePage() {\n const navigate = useTechnoSpamNavigate();\n const { currentUser } = useTechnoSpam();\n const [tab, setTab] = useState<Perspective>('mentee');\n const [cancellingId, setCancellingId] = useState<string | null>(null);\n\n const menteeId = currentUser?.id;\n\n // As mentee: sessions the current user booked.\n const menteeQ = useSessionsQuery(menteeId ? { menteeId } : {});\n\n // Resolve whether the current user is a mentor, to load their mentor sessions.\n const mentorsQ = useMentorsQuery({});\n const myMentor = mentorsQ.data?.tecListMentors.items.find((m) => m.userId === currentUser?.id);\n const mentorId = myMentor?.id;\n const mentorQ = useSessionsQuery(mentorId ? { mentorId } : {});\n\n const [cancelSession] = useCancelSession();\n const [confirmSession] = useConfirmSession();\n const [completeSession] = useCompleteSession();\n\n const menteeSessions = menteeId ? (menteeQ.data?.tecListSessions ?? []) : [];\n const mentorSessions = mentorId ? (mentorQ.data?.tecListSessions ?? []) : [];\n\n const handleCancel = async (id: string) => {\n setCancellingId(id);\n try {\n const res = await cancelSession({ variables: { id } });\n if (res.data?.tecCancelSession) {\n notify.success('Session cancelled', 'The session has been cancelled.');\n }\n } finally {\n setCancellingId(null);\n }\n };\n\n const handleConfirm = async (id: string, meetingUrl: string) => {\n setCancellingId(id);\n try {\n const res = await confirmSession({\n variables: { id, meetingUrl: meetingUrl || undefined },\n });\n if (res.data?.tecConfirmSession) {\n notify.success('Session confirmed', 'The mentee has been notified.');\n await mentorQ.refetch();\n }\n } finally {\n setCancellingId(null);\n }\n };\n\n const handleComplete = async (id: string, rating: number, feedback: string) => {\n setCancellingId(id);\n try {\n const res = await completeSession({\n variables: { id, rating, feedback: feedback || undefined },\n });\n if (res.data?.tecCompleteSession) {\n notify.success('Session completed', 'Nice work — the session is wrapped up.');\n await mentorQ.refetch();\n }\n } finally {\n setCancellingId(null);\n }\n };\n\n if (!currentUser?.id) {\n return (\n <PageLayout hero title=\"My Sessions\" description=\"Track your mentorship sessions.\">\n <EmptyView\n icon={<MessageSquare size={26} />}\n title=\"Sign in to view your sessions\"\n description=\"Your booked and hosted mentorship sessions will appear here once you're signed in.\"\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n hero\n title=\"My Sessions\"\n description=\"Manage the mentorship sessions you've booked and the ones you host.\"\n actions={\n <Button variant=\"outline\" onClick={() => navigate('/mentorship/mentors-page')}>\n <Users size={16} /> Find a mentor\n </Button>\n }\n >\n <div className=\"mb-5 grid grid-cols-2 gap-3 sm:max-w-md\">\n <StatCard label=\"As mentee\" value={menteeSessions.length} icon={MessageSquare} />\n <StatCard label=\"As mentor\" value={mentorId ? mentorSessions.length : 0} icon={Users} />\n </div>\n\n <Tabs value={tab} onValueChange={(v) => setTab(v as Perspective)} className=\"mb-4\">\n <TabsList>\n <TabsTrigger value=\"mentee\">As mentee</TabsTrigger>\n <TabsTrigger value=\"mentor\">As mentor</TabsTrigger>\n </TabsList>\n </Tabs>\n\n {tab === 'mentee' ? (\n <SessionsList\n loading={menteeQ.loading}\n error={menteeQ.error}\n sessions={menteeSessions}\n showMentor\n emptyTitle=\"No sessions booked yet\"\n emptyDescription=\"Find a mentor and request a session to get personalized guidance.\"\n emptyAction={\n <Button onClick={() => navigate('/mentorship/mentors-page')}>Find a mentor</Button>\n }\n isMentor={false}\n onCancel={handleCancel}\n onConfirm={handleConfirm}\n onComplete={handleComplete}\n busyId={cancellingId}\n />\n ) : mentorsQ.loading && !myMentor ? (\n <LoadingRows count={3} height=\"h-24\" />\n ) : !mentorId ? (\n <EmptyView\n icon={<Users size={26} />}\n title=\"You're not a mentor yet\"\n description=\"Create a mentor profile to start hosting sessions and helping others build.\"\n action={\n <Button onClick={() => navigate('/mentorship/mentors-page')}>Become a mentor</Button>\n }\n />\n ) : (\n <SessionsList\n loading={mentorQ.loading}\n error={mentorQ.error}\n sessions={mentorSessions}\n showMentor={false}\n emptyTitle=\"No sessions to host yet\"\n emptyDescription=\"When mentees request time with you, their sessions will show up here.\"\n isMentor\n onCancel={handleCancel}\n onConfirm={handleConfirm}\n onComplete={handleComplete}\n busyId={cancellingId}\n />\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MentorshipSessionsPagePage.js","names":[],"sources":["../../../src/technospam/pages/MentorshipSessionsPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n CalendarClock,\n Check,\n CheckCircle2,\n Clock,\n MessageSquare,\n Users,\n Video,\n X,\n} from 'lucide-react';\nimport { Button, GlassCard, Input, Tabs, TabsList, TabsTrigger } from '@burdenoff/fe-libs/ui';\nimport {\n EmptyView,\n ErrorView,\n LoadingRows,\n PageLayout,\n StatCard,\n StatusBadge,\n} from '../components';\nimport { useTechnoSpam, useTechnoSpamNavigate } from '../providers/TechnoSpamProvider';\nimport {\n useCancelSession,\n useCompleteSession,\n useConfirmSession,\n useMentorsQuery,\n useSessionsQuery,\n type TecMentorSession,\n} from '../api/technospamApi';\nimport { formatDateTime, formatDuration } from '../utils/format';\nimport { notify } from '../lib/toast';\nimport { useTechnoSpamAnalytics } from '../hooks/useTechnoSpamAnalytics';\n\ntype Perspective = 'mentee' | 'mentor';\n\nconst CANCELLABLE = new Set(['REQUESTED', 'CONFIRMED']);\n\nfunction SessionRow({\n session,\n showMentor,\n isMentor,\n onCancel,\n onConfirm,\n onComplete,\n busy,\n}: {\n session: TecMentorSession;\n showMentor: boolean;\n isMentor: boolean;\n onCancel: (id: string) => void;\n onConfirm: (id: string, meetingUrl: string) => Promise<void>;\n onComplete: (id: string, rating: number, feedback: string) => Promise<void>;\n busy: boolean;\n}) {\n const canCancel = CANCELLABLE.has(session.status);\n const [mode, setMode] = useState<'none' | 'confirm' | 'complete'>('none');\n const [meetingUrl, setMeetingUrl] = useState('');\n const [rating, setRating] = useState('5');\n const [feedback, setFeedback] = useState('');\n\n const submitConfirm = async () => {\n await onConfirm(session.id, meetingUrl.trim());\n setMode('none');\n setMeetingUrl('');\n };\n const submitComplete = async () => {\n await onComplete(session.id, Math.min(5, Math.max(1, Number(rating) || 5)), feedback.trim());\n setMode('none');\n };\n\n return (\n <GlassCard className=\"flex flex-col gap-3 p-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-start gap-3\">\n <span className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-accent-primary to-accent-purple text-white shadow-sm\">\n <Video size={18} />\n </span>\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {session.topic}\n </span>\n <StatusBadge status={session.status} />\n {session.rating ? (\n <span className=\"text-xs text-text-muted\">★ {session.rating}/5</span>\n ) : null}\n </div>\n {showMentor && session.mentor?.headline ? (\n <div className=\"mt-0.5 truncate text-xs text-text-secondary\">\n with {session.mentor.headline}\n </div>\n ) : null}\n <div className=\"mt-1 flex flex-wrap items-center gap-3 text-xs text-text-muted\">\n <span className=\"inline-flex items-center gap-1\">\n <CalendarClock size={13} /> {formatDateTime(session.scheduledAt)}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Clock size={13} /> {formatDuration(session.durationMinutes)}\n </span>\n </div>\n {session.agenda ? (\n <p className=\"mt-1 line-clamp-2 text-xs text-text-secondary\">{session.agenda}</p>\n ) : null}\n </div>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center gap-2\">\n {session.meetingUrl ? (\n <Button\n size=\"sm\"\n onClick={() => window.open(session.meetingUrl ?? '', '_blank', 'noopener,noreferrer')}\n >\n <Video size={15} /> Join\n </Button>\n ) : null}\n {isMentor && session.status === 'REQUESTED' ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setMode(mode === 'confirm' ? 'none' : 'confirm')}\n >\n <Check size={15} /> Confirm\n </Button>\n ) : null}\n {isMentor && session.status === 'CONFIRMED' ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setMode(mode === 'complete' ? 'none' : 'complete')}\n >\n <CheckCircle2 size={15} /> Mark complete\n </Button>\n ) : null}\n {canCancel ? (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => onCancel(session.id)} disabled={busy}>\n <X size={15} /> Cancel\n </Button>\n ) : null}\n </div>\n </div>\n\n {mode === 'confirm' ? (\n <div className=\"flex flex-col gap-2 rounded-lg border border-border-seam bg-bg-sunken p-3 sm:flex-row sm:items-center\">\n <Input\n className=\"flex-1\"\n placeholder=\"Meeting link (e.g. https://meet.…)\"\n value={meetingUrl}\n onChange={(e) => setMeetingUrl(e.target.value)}\n />\n <Button size=\"sm\" onClick={submitConfirm} disabled={busy}>\n Confirm session\n </Button>\n </div>\n ) : null}\n {mode === 'complete' ? (\n <div className=\"flex flex-col gap-2 rounded-lg border border-border-seam bg-bg-sunken p-3\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-text-secondary\">Rating (1–5)</label>\n <Input\n type=\"number\"\n min={1}\n max={5}\n className=\"w-20\"\n value={rating}\n onChange={(e) => setRating(e.target.value)}\n />\n </div>\n <Input\n placeholder=\"Feedback for the mentee (optional)\"\n value={feedback}\n onChange={(e) => setFeedback(e.target.value)}\n />\n <div>\n <Button size=\"sm\" onClick={submitComplete} disabled={busy}>\n Complete session\n </Button>\n </div>\n </div>\n ) : null}\n </GlassCard>\n );\n}\n\nfunction SessionsList({\n loading,\n error,\n sessions,\n showMentor,\n emptyTitle,\n emptyDescription,\n emptyAction,\n isMentor,\n onCancel,\n onConfirm,\n onComplete,\n busyId,\n}: {\n loading: boolean;\n error?: { message?: string };\n sessions: TecMentorSession[];\n showMentor: boolean;\n emptyTitle: string;\n emptyDescription: string;\n emptyAction?: React.ReactNode;\n isMentor: boolean;\n onCancel: (id: string) => void;\n onConfirm: (id: string, meetingUrl: string) => Promise<void>;\n onComplete: (id: string, rating: number, feedback: string) => Promise<void>;\n busyId: string | null;\n}) {\n if (loading && sessions.length === 0) return <LoadingRows count={3} height=\"h-24\" />;\n if (error) return <ErrorView title=\"Couldn't load sessions\" error={error} />;\n if (sessions.length === 0) {\n return (\n <EmptyView\n icon={<MessageSquare size={26} />}\n title={emptyTitle}\n description={emptyDescription}\n action={emptyAction}\n />\n );\n }\n const sorted = [...sessions].sort(\n (a, b) => new Date(b.scheduledAt).getTime() - new Date(a.scheduledAt).getTime()\n );\n return (\n <div className=\"space-y-3\">\n {sorted.map((session) => (\n <SessionRow\n key={session.id}\n session={session}\n showMentor={showMentor}\n isMentor={isMentor}\n onCancel={onCancel}\n onConfirm={onConfirm}\n onComplete={onComplete}\n busy={busyId === session.id}\n />\n ))}\n </div>\n );\n}\n\nexport function MentorshipSessionsPagePage() {\n const navigate = useTechnoSpamNavigate();\n const { currentUser, workspaceId } = useTechnoSpam();\n const { emit } = useTechnoSpamAnalytics();\n const [tab, setTab] = useState<Perspective>('mentee');\n const [cancellingId, setCancellingId] = useState<string | null>(null);\n\n const menteeId = currentUser?.id;\n\n // As mentee: sessions the current user booked.\n const menteeQ = useSessionsQuery(menteeId ? { menteeId } : {});\n\n // Resolve whether the current user is a mentor, to load their mentor sessions.\n const mentorsQ = useMentorsQuery({});\n const myMentor = mentorsQ.data?.tecListMentors.items.find((m) => m.userId === currentUser?.id);\n const mentorId = myMentor?.id;\n const mentorQ = useSessionsQuery(mentorId ? { mentorId } : {});\n\n const [cancelSession] = useCancelSession();\n const [confirmSession] = useConfirmSession();\n const [completeSession] = useCompleteSession();\n\n const menteeSessions = menteeId ? (menteeQ.data?.tecListSessions ?? []) : [];\n const mentorSessions = mentorId ? (mentorQ.data?.tecListSessions ?? []) : [];\n const allSessions = [...menteeSessions, ...mentorSessions];\n const upcomingCount = allSessions.filter(\n (s) => s.status === 'REQUESTED' || s.status === 'CONFIRMED'\n ).length;\n const completedCount = allSessions.filter((s) => s.status === 'COMPLETED').length;\n\n const handleCancel = async (id: string) => {\n setCancellingId(id);\n emit('technospam.session.cancel_clicked', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_MENTOR_SESSION',\n });\n try {\n const res = await cancelSession({ variables: { id } });\n if (res.data?.tecCancelSession) {\n emit('technospam.session.cancelled', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_MENTOR_SESSION',\n });\n notify.success('Session cancelled', 'The session has been cancelled.');\n }\n } finally {\n setCancellingId(null);\n }\n };\n\n const handleConfirm = async (id: string, meetingUrl: string) => {\n setCancellingId(id);\n try {\n const res = await confirmSession({\n variables: { id, meetingUrl: meetingUrl || undefined },\n });\n if (res.data?.tecConfirmSession) {\n notify.success('Session confirmed', 'The mentee has been notified.');\n await mentorQ.refetch();\n }\n } finally {\n setCancellingId(null);\n }\n };\n\n const handleComplete = async (id: string, rating: number, feedback: string) => {\n setCancellingId(id);\n emit('technospam.session.complete_clicked', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_MENTOR_SESSION',\n });\n try {\n const res = await completeSession({\n variables: { id, rating, feedback: feedback || undefined },\n });\n if (res.data?.tecCompleteSession) {\n emit('technospam.session.completed', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_MENTOR_SESSION',\n });\n notify.success('Session completed', 'Nice work — the session is wrapped up.');\n await mentorQ.refetch();\n }\n } finally {\n setCancellingId(null);\n }\n };\n\n if (!currentUser?.id) {\n return (\n <PageLayout hero title=\"My Sessions\" description=\"Track your mentorship sessions.\">\n <EmptyView\n icon={<MessageSquare size={26} />}\n title=\"Sign in to view your sessions\"\n description=\"Your booked and hosted mentorship sessions will appear here once you're signed in.\"\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n hero\n title=\"My Sessions\"\n description=\"Manage the mentorship sessions you've booked and the ones you host.\"\n actions={\n <Button variant=\"outline\" onClick={() => navigate('/mentorship/mentors-page')}>\n <Users size={16} /> Find a mentor\n </Button>\n }\n >\n <div className=\"mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <StatCard\n label=\"As mentee\"\n value={menteeSessions.length}\n icon={MessageSquare}\n tone=\"blue\"\n />\n <StatCard\n label=\"As mentor\"\n value={mentorId ? mentorSessions.length : 0}\n icon={Users}\n tone=\"purple\"\n />\n <StatCard label=\"Upcoming\" value={upcomingCount} icon={CalendarClock} tone=\"teal\" />\n <StatCard label=\"Completed\" value={completedCount} icon={CheckCircle2} tone=\"green\" />\n </div>\n\n <Tabs value={tab} onValueChange={(v) => setTab(v as Perspective)} className=\"mb-4\">\n <TabsList>\n <TabsTrigger value=\"mentee\">As mentee</TabsTrigger>\n <TabsTrigger value=\"mentor\">As mentor</TabsTrigger>\n </TabsList>\n </Tabs>\n\n {tab === 'mentee' ? (\n <SessionsList\n loading={menteeQ.loading}\n error={menteeQ.error}\n sessions={menteeSessions}\n showMentor\n emptyTitle=\"No sessions booked yet\"\n emptyDescription=\"Find a mentor and request a session to get personalized guidance.\"\n emptyAction={\n <Button onClick={() => navigate('/mentorship/mentors-page')}>Find a mentor</Button>\n }\n isMentor={false}\n onCancel={handleCancel}\n onConfirm={handleConfirm}\n onComplete={handleComplete}\n busyId={cancellingId}\n />\n ) : mentorsQ.loading && !myMentor ? (\n <LoadingRows count={3} height=\"h-24\" />\n ) : !mentorId ? (\n <EmptyView\n icon={<Users size={26} />}\n title=\"You're not a mentor yet\"\n description=\"Create a mentor profile to start hosting sessions and helping others build.\"\n action={\n <Button onClick={() => navigate('/mentorship/mentors-page')}>Become a mentor</Button>\n }\n />\n ) : (\n <SessionsList\n loading={mentorQ.loading}\n error={mentorQ.error}\n sessions={mentorSessions}\n showMentor={false}\n emptyTitle=\"No sessions to host yet\"\n emptyDescription=\"When mentees request time with you, their sessions will show up here.\"\n isMentor\n onCancel={handleCancel}\n onConfirm={handleConfirm}\n onComplete={handleComplete}\n busyId={cancellingId}\n />\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAmCA,IAAM,IAAc,IAAI,IAAI,CAAC,aAAa,YAAY,CAAC;AAEvD,SAAS,EAAW,EAClB,YACA,eACA,aACA,aACA,cACA,eACA,WASC;CACD,IAAM,IAAY,EAAY,IAAI,EAAQ,OAAO,EAC3C,CAAC,GAAM,KAAW,EAA0C,OAAO,EACnE,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,CAAC,GAAQ,KAAa,EAAS,IAAI,EACnC,CAAC,GAAU,KAAe,EAAS,GAAG;AAY5C,QACE,kBAAC,GAAD;EAAW,WAAU;YAArB;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBACd,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;MACd,CAAA,EACP,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAQ;UACJ,CAAA;SACP,kBAAC,GAAD,EAAa,QAAQ,EAAQ,QAAU,CAAA;SACtC,EAAQ,SACP,kBAAC,QAAD;UAAM,WAAU;oBAAhB;WAA0C;WAAG,EAAQ;WAAO;WAAS;cACnE;SACA;;OACL,KAAc,EAAQ,QAAQ,WAC7B,kBAAC,OAAD;QAAK,WAAU;kBAAf,CAA6D,SACrD,EAAQ,OAAO,SACjB;YACJ;OACJ,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAhB;UACE,kBAAC,GAAD,EAAe,MAAM,IAAM,CAAA;;UAAE,EAAe,EAAQ,YAAY;UAC3D;YACP,kBAAC,QAAD;SAAM,WAAU;mBAAhB;UACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;;UAAE,EAAe,EAAQ,gBAAgB;UACvD;WACH;;OACL,EAAQ,SACP,kBAAC,KAAD;QAAG,WAAU;kBAAiD,EAAQ;QAAW,CAAA,GAC/E;OACA;QACF;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACG,EAAQ,aACP,kBAAC,GAAD;OACE,MAAK;OACL,eAAe,OAAO,KAAK,EAAQ,cAAc,IAAI,UAAU,sBAAsB;iBAFvF,CAIE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAAA,QACZ;WACP;MACH,KAAY,EAAQ,WAAW,cAC9B,kBAAC,GAAD;OACE,SAAQ;OACR,MAAK;OACL,eAAe,EAAQ,MAAS,YAAY,SAAS,UAAU;iBAHjE,CAKE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAAA,WACZ;WACP;MACH,KAAY,EAAQ,WAAW,cAC9B,kBAAC,GAAD;OACE,SAAQ;OACR,MAAK;OACL,eAAe,EAAQ,MAAS,aAAa,SAAS,WAAW;iBAHnE,CAKE,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA,EAAA,iBACnB;WACP;MACH,IACC,kBAAC,GAAD;OAAQ,SAAQ;OAAQ,MAAK;OAAK,eAAe,EAAS,EAAQ,GAAG;OAAE,UAAU;iBAAjF,CACE,kBAAC,GAAD,EAAG,MAAM,IAAM,CAAA,EAAA,UACR;WACP;MACA;OACF;;GAEL,MAAS,YACR,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KACE,WAAU;KACV,aAAY;KACZ,OAAO;KACP,WAAW,MAAM,EAAc,EAAE,OAAO,MAAM;KAC9C,CAAA,EACF,kBAAC,GAAD;KAAQ,MAAK;KAAK,SAxFJ,YAAY;AAGhC,MAFA,MAAM,EAAU,EAAQ,IAAI,EAAW,MAAM,CAAC,EAC9C,EAAQ,OAAO,EACf,EAAc,GAAG;;KAqF+B,UAAU;eAAM;KAEjD,CAAA,CACL;QACJ;GACH,MAAS,aACR,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,WAAU;iBAA8B;OAAoB,CAAA,EACnE,kBAAC,GAAD;OACE,MAAK;OACL,KAAK;OACL,KAAK;OACL,WAAU;OACV,OAAO;OACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;OAC1C,CAAA,CACE;;KACN,kBAAC,GAAD;MACE,aAAY;MACZ,OAAO;MACP,WAAW,MAAM,EAAY,EAAE,OAAO,MAAM;MAC5C,CAAA;KACF,kBAAC,OAAD,EAAA,UACE,kBAAC,GAAD;MAAQ,MAAK;MAAK,SA3GL,YAAY;AAEjC,OADA,MAAM,EAAW,EAAQ,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,EAAO,IAAI,EAAE,CAAC,EAAE,EAAS,MAAM,CAAC,EAC5F,EAAQ,OAAO;;MAyGoC,UAAU;gBAAM;MAElD,CAAA,EACL,CAAA;KACF;QACJ;GACM;;;AAIhB,SAAS,EAAa,EACpB,YACA,UACA,aACA,eACA,eACA,qBACA,gBACA,aACA,aACA,cACA,eACA,aAcC;AAgBD,QAfI,KAAW,EAAS,WAAW,IAAU,kBAAC,GAAD;EAAa,OAAO;EAAG,QAAO;EAAS,CAAA,GAChF,IAAc,kBAAC,GAAD;EAAW,OAAM;EAAgC;EAAS,CAAA,GACxE,EAAS,WAAW,IAEpB,kBAAC,GAAD;EACE,MAAM,kBAAC,GAAD,EAAe,MAAM,IAAM,CAAA;EACjC,OAAO;EACP,aAAa;EACb,QAAQ;EACR,CAAA,GAOJ,kBAAC,OAAD;EAAK,WAAU;YAJF,CAAC,GAAG,EAAS,CAAC,MAC1B,GAAG,MAAM,IAAI,KAAK,EAAE,YAAY,CAAC,SAAS,GAAG,IAAI,KAAK,EAAE,YAAY,CAAC,SAAS,CAChF,CAGW,KAAK,MACX,kBAAC,GAAD;GAEW;GACG;GACF;GACA;GACC;GACC;GACZ,MAAM,MAAW,EAAQ;GACzB,EARK,EAAQ,GAQb,CACF;EACE,CAAA;;AAIV,SAAgB,IAA6B;CAC3C,IAAM,IAAW,GAAuB,EAClC,EAAE,gBAAa,mBAAgB,GAAe,EAC9C,EAAE,YAAS,GAAwB,EACnC,CAAC,GAAK,KAAU,EAAsB,SAAS,EAC/C,CAAC,GAAc,KAAmB,EAAwB,KAAK,EAE/D,IAAW,GAAa,IAGxB,IAAU,EAAiB,IAAW,EAAE,aAAU,GAAG,EAAE,CAAC,EAGxD,IAAW,EAAgB,EAAE,CAAC,EAC9B,IAAW,EAAS,MAAM,eAAe,MAAM,MAAM,MAAM,EAAE,WAAW,GAAa,GAAG,EACxF,IAAW,GAAU,IACrB,IAAU,EAAiB,IAAW,EAAE,aAAU,GAAG,EAAE,CAAC,EAExD,CAAC,KAAiB,GAAkB,EACpC,CAAC,KAAkB,GAAmB,EACtC,CAAC,KAAmB,GAAoB,EAExC,IAAiB,IAAY,EAAQ,MAAM,mBAAmB,EAAE,GAAI,EAAE,EACtE,IAAiB,IAAY,EAAQ,MAAM,mBAAmB,EAAE,GAAI,EAAE,EACtE,IAAc,CAAC,GAAG,GAAgB,GAAG,EAAe,EACpD,IAAgB,EAAY,QAC/B,MAAM,EAAE,WAAW,eAAe,EAAE,WAAW,YACjD,CAAC,QACI,IAAiB,EAAY,QAAQ,MAAM,EAAE,WAAW,YAAY,CAAC,QAErE,IAAe,OAAO,MAAe;AAEzC,EADA,EAAgB,EAAG,EACnB,EAAK,qCAAqC;GACxC;GACA,UAAU;GACV,YAAY;GACb,CAAC;AACF,MAAI;AAEF,IADY,MAAM,EAAc,EAAE,WAAW,EAAE,OAAI,EAAE,CAAC,EAC9C,MAAM,qBACZ,EAAK,gCAAgC;IACnC;IACA,UAAU;IACV,YAAY;IACb,CAAC,EACF,EAAO,QAAQ,qBAAqB,kCAAkC;YAEhE;AACR,KAAgB,KAAK;;IAInB,IAAgB,OAAO,GAAY,MAAuB;AAC9D,IAAgB,EAAG;AACnB,MAAI;AAIF,IAHY,MAAM,EAAe,EAC/B,WAAW;IAAE;IAAI,YAAY,KAAc,KAAA;IAAW,EACvD,CAAC,EACM,MAAM,sBACZ,EAAO,QAAQ,qBAAqB,gCAAgC,EACpE,MAAM,EAAQ,SAAS;YAEjB;AACR,KAAgB,KAAK;;IAInB,IAAiB,OAAO,GAAY,GAAgB,MAAqB;AAE7E,EADA,EAAgB,EAAG,EACnB,EAAK,uCAAuC;GAC1C;GACA,UAAU;GACV,YAAY;GACb,CAAC;AACF,MAAI;AAIF,IAHY,MAAM,EAAgB,EAChC,WAAW;IAAE;IAAI;IAAQ,UAAU,KAAY,KAAA;IAAW,EAC3D,CAAC,EACM,MAAM,uBACZ,EAAK,gCAAgC;IACnC;IACA,UAAU;IACV,YAAY;IACb,CAAC,EACF,EAAO,QAAQ,qBAAqB,yCAAyC,EAC7E,MAAM,EAAQ,SAAS;YAEjB;AACR,KAAgB,KAAK;;;AAgBzB,QAZK,GAAa,KAahB,kBAAC,GAAD;EACE,MAAA;EACA,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,GAAD;GAAQ,SAAQ;GAAU,eAAe,EAAS,2BAA2B;aAA7E,CACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAAA,iBACZ;;YAPb;GAUE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MACE,OAAM;MACN,OAAO,EAAe;MACtB,MAAM;MACN,MAAK;MACL,CAAA;KACF,kBAAC,GAAD;MACE,OAAM;MACN,OAAO,IAAW,EAAe,SAAS;MAC1C,MAAM;MACN,MAAK;MACL,CAAA;KACF,kBAAC,GAAD;MAAU,OAAM;MAAW,OAAO;MAAe,MAAM;MAAe,MAAK;MAAS,CAAA;KACpF,kBAAC,GAAD;MAAU,OAAM;MAAY,OAAO;MAAgB,MAAM;MAAc,MAAK;MAAU,CAAA;KAClF;;GAEN,kBAAC,GAAD;IAAM,OAAO;IAAK,gBAAgB,MAAM,EAAO,EAAiB;IAAE,WAAU;cAC1E,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;KAAa,OAAM;eAAS;KAAuB,CAAA,EACnD,kBAAC,GAAD;KAAa,OAAM;eAAS;KAAuB,CAAA,CAC1C,EAAA,CAAA;IACN,CAAA;GAEN,MAAQ,WACP,kBAAC,GAAD;IACE,SAAS,EAAQ;IACjB,OAAO,EAAQ;IACf,UAAU;IACV,YAAA;IACA,YAAW;IACX,kBAAiB;IACjB,aACE,kBAAC,GAAD;KAAQ,eAAe,EAAS,2BAA2B;eAAE;KAAsB,CAAA;IAErF,UAAU;IACV,UAAU;IACV,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,CAAA,GACA,EAAS,WAAW,CAAC,IACvB,kBAAC,GAAD;IAAa,OAAO;IAAG,QAAO;IAAS,CAAA,GACpC,IAUH,kBAAC,GAAD;IACE,SAAS,EAAQ;IACjB,OAAO,EAAQ;IACf,UAAU;IACV,YAAY;IACZ,YAAW;IACX,kBAAiB;IACjB,UAAA;IACA,UAAU;IACV,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,CAAA,GArBF,kBAAC,GAAD;IACE,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;IACzB,OAAM;IACN,aAAY;IACZ,QACE,kBAAC,GAAD;KAAQ,eAAe,EAAS,2BAA2B;eAAE;KAAwB,CAAA;IAEvF,CAAA;GAgBO;MAxFX,kBAAC,GAAD;EAAY,MAAA;EAAK,OAAM;EAAc,aAAY;YAC/C,kBAAC,GAAD;GACE,MAAM,kBAAC,GAAD,EAAe,MAAM,IAAM,CAAA;GACjC,OAAM;GACN,aAAY;GACZ,CAAA;EACS,CAAA"}