@burdenoff/microfe-technospam 2026.705.2 → 2026.709.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.
- package/dist/dev/main.d.ts +2 -0
- package/dist/dev/main.d.ts.map +1 -0
- package/dist/generated/global-operations.d.ts +2 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-types.d.ts +18199 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/wspace-operations.d.ts +267 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-operations.js +67 -0
- package/dist/generated/wspace-operations.js.map +1 -0
- package/dist/generated/wspace-types.d.ts +43083 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -1
- package/dist/technospam/TechnoSpamRoot.d.ts +5 -0
- package/dist/technospam/TechnoSpamRoot.d.ts.map +1 -0
- package/dist/technospam/TechnoSpamRoutes.d.ts +2 -0
- package/dist/technospam/TechnoSpamRoutes.d.ts.map +1 -0
- package/dist/technospam/api/technospamApi.d.ts +402 -0
- package/dist/technospam/api/technospamApi.d.ts.map +1 -0
- package/dist/technospam/components/LoadMore.d.ts +11 -0
- package/dist/technospam/components/LoadMore.d.ts.map +1 -0
- package/dist/technospam/components/MediaCover.d.ts +20 -0
- package/dist/technospam/components/MediaCover.d.ts.map +1 -0
- package/dist/technospam/components/PageLayout.d.ts +20 -0
- package/dist/technospam/components/PageLayout.d.ts.map +1 -0
- package/dist/technospam/components/StatCard.d.ts +20 -0
- package/dist/technospam/components/StatCard.d.ts.map +1 -0
- package/dist/technospam/components/StateViews.d.ts +30 -0
- package/dist/technospam/components/StateViews.d.ts.map +1 -0
- package/dist/technospam/components/StatusBadge.d.ts +5 -0
- package/dist/technospam/components/StatusBadge.d.ts.map +1 -0
- package/dist/technospam/components/index.d.ts +7 -0
- package/dist/technospam/components/index.d.ts.map +1 -0
- package/dist/technospam/hooks/useTechnoSpamAnalytics.d.ts +20 -0
- package/dist/technospam/hooks/useTechnoSpamAnalytics.d.ts.map +1 -0
- package/dist/technospam/hooks/useTechnoSpamAnalytics.js +13 -0
- package/dist/technospam/hooks/useTechnoSpamAnalytics.js.map +1 -0
- package/dist/technospam/index.d.ts +6 -0
- package/dist/technospam/index.d.ts.map +1 -0
- package/dist/technospam/index.js +2 -0
- package/dist/technospam/lib/toast.d.ts +18 -0
- package/dist/technospam/lib/toast.d.ts.map +1 -0
- package/dist/technospam/pages/AdminAdminDashboardPagePage.d.ts +2 -0
- package/dist/technospam/pages/AdminAdminDashboardPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/AnalyticsAnalyticsPagePage.d.ts +2 -0
- package/dist/technospam/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.d.ts +2 -0
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js +129 -105
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js.map +1 -1
- package/dist/technospam/pages/ApplicationsProblemsPagePage.d.ts +2 -0
- package/dist/technospam/pages/ApplicationsProblemsPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/ApplicationsProblemsPagePage.js +87 -72
- package/dist/technospam/pages/ApplicationsProblemsPagePage.js.map +1 -1
- package/dist/technospam/pages/CoursesCourseDetailsPagePage.d.ts +2 -0
- package/dist/technospam/pages/CoursesCourseDetailsPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/CoursesCourseDetailsPagePage.js +174 -143
- package/dist/technospam/pages/CoursesCourseDetailsPagePage.js.map +1 -1
- package/dist/technospam/pages/CoursesCoursesPagePage.d.ts +2 -0
- package/dist/technospam/pages/CoursesCoursesPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/CoursesCoursesPagePage.js +95 -80
- package/dist/technospam/pages/CoursesCoursesPagePage.js.map +1 -1
- package/dist/technospam/pages/CoursesMyLearningPagePage.d.ts +2 -0
- package/dist/technospam/pages/CoursesMyLearningPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/DashboardDashboardPagePage.d.ts +2 -0
- package/dist/technospam/pages/DashboardDashboardPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/HackathonsHackathonDetailsPagePage.d.ts +2 -0
- package/dist/technospam/pages/HackathonsHackathonDetailsPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/HackathonsHackathonsPagePage.d.ts +2 -0
- package/dist/technospam/pages/HackathonsHackathonsPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/HackathonsHackathonsPagePage.js +93 -78
- package/dist/technospam/pages/HackathonsHackathonsPagePage.js.map +1 -1
- package/dist/technospam/pages/MentorshipMentorProfilePagePage.d.ts +2 -0
- package/dist/technospam/pages/MentorshipMentorProfilePagePage.d.ts.map +1 -0
- package/dist/technospam/pages/MentorshipMentorProfilePagePage.js +135 -121
- package/dist/technospam/pages/MentorshipMentorProfilePagePage.js.map +1 -1
- package/dist/technospam/pages/MentorshipMentorsPagePage.d.ts +2 -0
- package/dist/technospam/pages/MentorshipMentorsPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/MentorshipMentorsPagePage.js +156 -142
- package/dist/technospam/pages/MentorshipMentorsPagePage.js.map +1 -1
- package/dist/technospam/pages/MentorshipSessionsPagePage.d.ts +2 -0
- package/dist/technospam/pages/MentorshipSessionsPagePage.d.ts.map +1 -0
- package/dist/technospam/pages/MentorshipSessionsPagePage.js +129 -112
- package/dist/technospam/pages/MentorshipSessionsPagePage.js.map +1 -1
- package/dist/technospam/providers/TechnoSpamProvider.d.ts +13 -0
- package/dist/technospam/providers/TechnoSpamProvider.d.ts.map +1 -0
- package/dist/technospam/services/assistantApi.d.ts +76 -0
- package/dist/technospam/services/assistantApi.d.ts.map +1 -0
- package/dist/technospam/services/assistantApi.js +222 -0
- package/dist/technospam/services/assistantApi.js.map +1 -0
- package/dist/technospam/services/createSandboxAssistantTransport.d.ts +40 -0
- package/dist/technospam/services/createSandboxAssistantTransport.d.ts.map +1 -0
- package/dist/technospam/services/createSandboxAssistantTransport.js +120 -0
- package/dist/technospam/services/createSandboxAssistantTransport.js.map +1 -0
- package/dist/technospam/types/assistant.d.ts +15 -0
- package/dist/technospam/types/assistant.d.ts.map +1 -0
- package/dist/technospam/types/index.d.ts +51 -0
- package/dist/technospam/types/index.d.ts.map +1 -0
- package/dist/technospam/utils/cn.d.ts +4 -0
- package/dist/technospam/utils/cn.d.ts.map +1 -0
- package/dist/technospam/utils/format.d.ts +9 -0
- package/dist/technospam/utils/format.d.ts.map +1 -0
- package/dist/technospam/utils/i18n.d.ts +6 -0
- package/dist/technospam/utils/i18n.d.ts.map +1 -0
- package/dist/technospam/utils/navigation.d.ts +2 -0
- package/dist/technospam/utils/navigation.d.ts.map +1 -0
- package/dist/technospam/utils/pageContext.d.ts +28 -0
- package/dist/technospam/utils/pageContext.d.ts.map +1 -0
- package/dist/technospam/utils/pageContext.js +46 -0
- package/dist/technospam/utils/pageContext.js.map +1 -0
- 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 {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
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
|
|
16
|
-
function
|
|
17
|
-
let u =
|
|
18
|
-
return /* @__PURE__ */
|
|
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, {
|
|
19
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__ */
|
|
22
|
+
/* @__PURE__ */ D("div", {
|
|
22
23
|
className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
|
|
23
|
-
children: [/* @__PURE__ */
|
|
24
|
+
children: [/* @__PURE__ */ D("div", {
|
|
24
25
|
className: "flex items-start gap-3",
|
|
25
|
-
children: [/* @__PURE__ */
|
|
26
|
+
children: [/* @__PURE__ */ E("span", {
|
|
26
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",
|
|
27
|
-
children: /* @__PURE__ */
|
|
28
|
-
}), /* @__PURE__ */
|
|
28
|
+
children: /* @__PURE__ */ E(w, { size: 18 })
|
|
29
|
+
}), /* @__PURE__ */ D("div", {
|
|
29
30
|
className: "min-w-0",
|
|
30
31
|
children: [
|
|
31
|
-
/* @__PURE__ */
|
|
32
|
+
/* @__PURE__ */ D("div", {
|
|
32
33
|
className: "flex flex-wrap items-center gap-2",
|
|
33
34
|
children: [
|
|
34
|
-
/* @__PURE__ */
|
|
35
|
+
/* @__PURE__ */ E("span", {
|
|
35
36
|
className: "truncate text-sm font-semibold text-text-primary",
|
|
36
37
|
children: e.topic
|
|
37
38
|
}),
|
|
38
|
-
/* @__PURE__ */
|
|
39
|
-
e.rating ? /* @__PURE__ */
|
|
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,72 +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__ */
|
|
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__ */
|
|
54
|
+
/* @__PURE__ */ D("div", {
|
|
54
55
|
className: "mt-1 flex flex-wrap items-center gap-3 text-xs text-text-muted",
|
|
55
|
-
children: [/* @__PURE__ */
|
|
56
|
+
children: [/* @__PURE__ */ D("span", {
|
|
56
57
|
className: "inline-flex items-center gap-1",
|
|
57
58
|
children: [
|
|
58
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ E(v, { size: 13 }),
|
|
59
60
|
" ",
|
|
60
61
|
i(e.scheduledAt)
|
|
61
62
|
]
|
|
62
|
-
}), /* @__PURE__ */
|
|
63
|
+
}), /* @__PURE__ */ D("span", {
|
|
63
64
|
className: "inline-flex items-center gap-1",
|
|
64
65
|
children: [
|
|
65
|
-
/* @__PURE__ */
|
|
66
|
+
/* @__PURE__ */ E(x, { size: 13 }),
|
|
66
67
|
" ",
|
|
67
68
|
a(e.durationMinutes)
|
|
68
69
|
]
|
|
69
70
|
})]
|
|
70
71
|
}),
|
|
71
|
-
e.agenda ? /* @__PURE__ */
|
|
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__ */
|
|
78
|
+
}), /* @__PURE__ */ D("div", {
|
|
78
79
|
className: "flex shrink-0 flex-wrap items-center gap-2",
|
|
79
80
|
children: [
|
|
80
|
-
e.meetingUrl ? /* @__PURE__ */
|
|
81
|
+
e.meetingUrl ? /* @__PURE__ */ D(O, {
|
|
81
82
|
size: "sm",
|
|
82
83
|
onClick: () => window.open(e.meetingUrl ?? "", "_blank", "noopener,noreferrer"),
|
|
83
|
-
children: [/* @__PURE__ */
|
|
84
|
+
children: [/* @__PURE__ */ E(w, { size: 15 }), " Join"]
|
|
84
85
|
}) : null,
|
|
85
|
-
n && e.status === "REQUESTED" ? /* @__PURE__ */
|
|
86
|
+
n && e.status === "REQUESTED" ? /* @__PURE__ */ D(O, {
|
|
86
87
|
variant: "outline",
|
|
87
88
|
size: "sm",
|
|
88
89
|
onClick: () => f(d === "confirm" ? "none" : "confirm"),
|
|
89
|
-
children: [/* @__PURE__ */
|
|
90
|
+
children: [/* @__PURE__ */ E(y, { size: 15 }), " Confirm"]
|
|
90
91
|
}) : null,
|
|
91
|
-
n && e.status === "CONFIRMED" ? /* @__PURE__ */
|
|
92
|
+
n && e.status === "CONFIRMED" ? /* @__PURE__ */ D(O, {
|
|
92
93
|
variant: "outline",
|
|
93
94
|
size: "sm",
|
|
94
95
|
onClick: () => f(d === "complete" ? "none" : "complete"),
|
|
95
|
-
children: [/* @__PURE__ */
|
|
96
|
+
children: [/* @__PURE__ */ E(b, { size: 15 }), " Mark complete"]
|
|
96
97
|
}) : null,
|
|
97
|
-
u ? /* @__PURE__ */
|
|
98
|
+
u ? /* @__PURE__ */ D(O, {
|
|
98
99
|
variant: "ghost",
|
|
99
100
|
size: "sm",
|
|
100
101
|
onClick: () => r(e.id),
|
|
101
102
|
disabled: l,
|
|
102
|
-
children: [/* @__PURE__ */ T
|
|
103
|
+
children: [/* @__PURE__ */ E(T, { size: 15 }), " Cancel"]
|
|
103
104
|
}) : null
|
|
104
105
|
]
|
|
105
106
|
})]
|
|
106
107
|
}),
|
|
107
|
-
d === "confirm" ? /* @__PURE__ */
|
|
108
|
+
d === "confirm" ? /* @__PURE__ */ D("div", {
|
|
108
109
|
className: "flex flex-col gap-2 rounded-lg border border-border-seam bg-bg-sunken p-3 sm:flex-row sm:items-center",
|
|
109
|
-
children: [/* @__PURE__ */
|
|
110
|
+
children: [/* @__PURE__ */ E(A, {
|
|
110
111
|
className: "flex-1",
|
|
111
112
|
placeholder: "Meeting link (e.g. https://meet.…)",
|
|
112
113
|
value: p,
|
|
113
114
|
onChange: (e) => m(e.target.value)
|
|
114
|
-
}), /* @__PURE__ */
|
|
115
|
+
}), /* @__PURE__ */ E(O, {
|
|
115
116
|
size: "sm",
|
|
116
117
|
onClick: async () => {
|
|
117
118
|
await s(e.id, p.trim()), f("none"), m("");
|
|
@@ -120,29 +121,29 @@ function P({ session: e, showMentor: t, isMentor: n, onCancel: r, onConfirm: s,
|
|
|
120
121
|
children: "Confirm session"
|
|
121
122
|
})]
|
|
122
123
|
}) : null,
|
|
123
|
-
d === "complete" ? /* @__PURE__ */
|
|
124
|
+
d === "complete" ? /* @__PURE__ */ D("div", {
|
|
124
125
|
className: "flex flex-col gap-2 rounded-lg border border-border-seam bg-bg-sunken p-3",
|
|
125
126
|
children: [
|
|
126
|
-
/* @__PURE__ */
|
|
127
|
+
/* @__PURE__ */ D("div", {
|
|
127
128
|
className: "flex items-center gap-2",
|
|
128
|
-
children: [/* @__PURE__ */
|
|
129
|
+
children: [/* @__PURE__ */ E("label", {
|
|
129
130
|
className: "text-xs text-text-secondary",
|
|
130
131
|
children: "Rating (1–5)"
|
|
131
|
-
}), /* @__PURE__ */
|
|
132
|
+
}), /* @__PURE__ */ E(A, {
|
|
132
133
|
type: "number",
|
|
133
134
|
min: 1,
|
|
134
135
|
max: 5,
|
|
135
136
|
className: "w-20",
|
|
136
137
|
value: h,
|
|
137
|
-
onChange: (e) =>
|
|
138
|
+
onChange: (e) => g(e.target.value)
|
|
138
139
|
})]
|
|
139
140
|
}),
|
|
140
|
-
/* @__PURE__ */
|
|
141
|
+
/* @__PURE__ */ E(A, {
|
|
141
142
|
placeholder: "Feedback for the mentee (optional)",
|
|
142
143
|
value: S,
|
|
143
|
-
onChange: (e) =>
|
|
144
|
+
onChange: (e) => C(e.target.value)
|
|
144
145
|
}),
|
|
145
|
-
/* @__PURE__ */
|
|
146
|
+
/* @__PURE__ */ E("div", { children: /* @__PURE__ */ E(O, {
|
|
146
147
|
size: "sm",
|
|
147
148
|
onClick: async () => {
|
|
148
149
|
await c(e.id, Math.min(5, Math.max(1, Number(h) || 5)), S.trim()), f("none");
|
|
@@ -155,21 +156,21 @@ function P({ session: e, showMentor: t, isMentor: n, onCancel: r, onConfirm: s,
|
|
|
155
156
|
]
|
|
156
157
|
});
|
|
157
158
|
}
|
|
158
|
-
function
|
|
159
|
-
return e && n.length === 0 ? /* @__PURE__ */
|
|
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, {
|
|
160
161
|
count: 3,
|
|
161
162
|
height: "h-24"
|
|
162
|
-
}) : t ? /* @__PURE__ */
|
|
163
|
+
}) : t ? /* @__PURE__ */ E(c, {
|
|
163
164
|
title: "Couldn't load sessions",
|
|
164
165
|
error: t
|
|
165
|
-
}) : n.length === 0 ? /* @__PURE__ */
|
|
166
|
-
icon: /* @__PURE__ */
|
|
166
|
+
}) : n.length === 0 ? /* @__PURE__ */ E(s, {
|
|
167
|
+
icon: /* @__PURE__ */ E(S, { size: 26 }),
|
|
167
168
|
title: i,
|
|
168
169
|
description: a,
|
|
169
170
|
action: o
|
|
170
|
-
}) : /* @__PURE__ */
|
|
171
|
+
}) : /* @__PURE__ */ E("div", {
|
|
171
172
|
className: "space-y-3",
|
|
172
|
-
children: [...n].sort((e, t) => new Date(t.scheduledAt).getTime() - new Date(e.scheduledAt).getTime()).map((e) => /* @__PURE__ */
|
|
173
|
+
children: [...n].sort((e, t) => new Date(t.scheduledAt).getTime() - new Date(e.scheduledAt).getTime()).map((e) => /* @__PURE__ */ E(F, {
|
|
173
174
|
session: e,
|
|
174
175
|
showMentor: r,
|
|
175
176
|
isMentor: u,
|
|
@@ -180,140 +181,156 @@ function F({ loading: e, error: t, sessions: n, showMentor: r, emptyTitle: i, em
|
|
|
180
181
|
}, e.id))
|
|
181
182
|
});
|
|
182
183
|
}
|
|
183
|
-
function
|
|
184
|
-
let i = t(), { currentUser: a } = e(), [
|
|
185
|
-
|
|
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
|
+
});
|
|
186
191
|
try {
|
|
187
|
-
(await
|
|
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."));
|
|
188
197
|
} finally {
|
|
189
|
-
|
|
198
|
+
T(null);
|
|
190
199
|
}
|
|
191
|
-
},
|
|
192
|
-
|
|
200
|
+
}, J = async (e, t) => {
|
|
201
|
+
T(e);
|
|
193
202
|
try {
|
|
194
|
-
(await
|
|
203
|
+
(await B({ variables: {
|
|
195
204
|
id: e,
|
|
196
205
|
meetingUrl: t || void 0
|
|
197
|
-
} })).data?.tecConfirmSession && (u.success("Session confirmed", "The mentee has been notified."), await
|
|
206
|
+
} })).data?.tecConfirmSession && (u.success("Session confirmed", "The mentee has been notified."), await R.refetch());
|
|
198
207
|
} finally {
|
|
199
|
-
|
|
208
|
+
T(null);
|
|
200
209
|
}
|
|
201
|
-
},
|
|
202
|
-
|
|
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
|
+
});
|
|
203
216
|
try {
|
|
204
|
-
(await
|
|
217
|
+
(await V({ variables: {
|
|
205
218
|
id: e,
|
|
206
219
|
rating: t,
|
|
207
220
|
feedback: n || void 0
|
|
208
|
-
} })).data?.tecCompleteSession && (
|
|
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());
|
|
209
226
|
} finally {
|
|
210
|
-
|
|
227
|
+
T(null);
|
|
211
228
|
}
|
|
212
229
|
};
|
|
213
|
-
return a?.id ? /* @__PURE__ */
|
|
230
|
+
return a?.id ? /* @__PURE__ */ D(n, {
|
|
214
231
|
hero: !0,
|
|
215
232
|
title: "My Sessions",
|
|
216
233
|
description: "Manage the mentorship sessions you've booked and the ones you host.",
|
|
217
|
-
actions: /* @__PURE__ */
|
|
234
|
+
actions: /* @__PURE__ */ D(O, {
|
|
218
235
|
variant: "outline",
|
|
219
236
|
onClick: () => i("/mentorship/mentors-page"),
|
|
220
|
-
children: [/* @__PURE__ */
|
|
237
|
+
children: [/* @__PURE__ */ E(C, { size: 16 }), " Find a mentor"]
|
|
221
238
|
}),
|
|
222
239
|
children: [
|
|
223
|
-
/* @__PURE__ */
|
|
240
|
+
/* @__PURE__ */ D("div", {
|
|
224
241
|
className: "mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4",
|
|
225
242
|
children: [
|
|
226
|
-
/* @__PURE__ */
|
|
243
|
+
/* @__PURE__ */ E(r, {
|
|
227
244
|
label: "As mentee",
|
|
228
|
-
value:
|
|
229
|
-
icon:
|
|
245
|
+
value: H.length,
|
|
246
|
+
icon: S,
|
|
230
247
|
tone: "blue"
|
|
231
248
|
}),
|
|
232
|
-
/* @__PURE__ */
|
|
249
|
+
/* @__PURE__ */ E(r, {
|
|
233
250
|
label: "As mentor",
|
|
234
|
-
value:
|
|
235
|
-
icon:
|
|
251
|
+
value: L ? U.length : 0,
|
|
252
|
+
icon: C,
|
|
236
253
|
tone: "purple"
|
|
237
254
|
}),
|
|
238
|
-
/* @__PURE__ */
|
|
255
|
+
/* @__PURE__ */ E(r, {
|
|
239
256
|
label: "Upcoming",
|
|
240
|
-
value:
|
|
241
|
-
icon:
|
|
257
|
+
value: G,
|
|
258
|
+
icon: v,
|
|
242
259
|
tone: "teal"
|
|
243
260
|
}),
|
|
244
|
-
/* @__PURE__ */
|
|
261
|
+
/* @__PURE__ */ E(r, {
|
|
245
262
|
label: "Completed",
|
|
246
|
-
value:
|
|
247
|
-
icon:
|
|
263
|
+
value: K,
|
|
264
|
+
icon: b,
|
|
248
265
|
tone: "green"
|
|
249
266
|
})
|
|
250
267
|
]
|
|
251
268
|
}),
|
|
252
|
-
/* @__PURE__ */
|
|
253
|
-
value:
|
|
254
|
-
onValueChange: (e) =>
|
|
269
|
+
/* @__PURE__ */ E(j, {
|
|
270
|
+
value: y,
|
|
271
|
+
onValueChange: (e) => x(e),
|
|
255
272
|
className: "mb-4",
|
|
256
|
-
children: /* @__PURE__ */
|
|
273
|
+
children: /* @__PURE__ */ D(M, { children: [/* @__PURE__ */ E(N, {
|
|
257
274
|
value: "mentee",
|
|
258
275
|
children: "As mentee"
|
|
259
|
-
}), /* @__PURE__ */
|
|
276
|
+
}), /* @__PURE__ */ E(N, {
|
|
260
277
|
value: "mentor",
|
|
261
278
|
children: "As mentor"
|
|
262
279
|
})] })
|
|
263
280
|
}),
|
|
264
|
-
|
|
265
|
-
loading:
|
|
266
|
-
error:
|
|
267
|
-
sessions:
|
|
281
|
+
y === "mentee" ? /* @__PURE__ */ E(I, {
|
|
282
|
+
loading: A.loading,
|
|
283
|
+
error: A.error,
|
|
284
|
+
sessions: H,
|
|
268
285
|
showMentor: !0,
|
|
269
286
|
emptyTitle: "No sessions booked yet",
|
|
270
287
|
emptyDescription: "Find a mentor and request a session to get personalized guidance.",
|
|
271
|
-
emptyAction: /* @__PURE__ */
|
|
288
|
+
emptyAction: /* @__PURE__ */ E(O, {
|
|
272
289
|
onClick: () => i("/mentorship/mentors-page"),
|
|
273
290
|
children: "Find a mentor"
|
|
274
291
|
}),
|
|
275
292
|
isMentor: !1,
|
|
276
|
-
onCancel:
|
|
277
|
-
onConfirm:
|
|
278
|
-
onComplete:
|
|
279
|
-
busyId:
|
|
280
|
-
}) :
|
|
293
|
+
onCancel: q,
|
|
294
|
+
onConfirm: J,
|
|
295
|
+
onComplete: Y,
|
|
296
|
+
busyId: w
|
|
297
|
+
}) : P.loading && !F ? /* @__PURE__ */ E(l, {
|
|
281
298
|
count: 3,
|
|
282
299
|
height: "h-24"
|
|
283
|
-
}) :
|
|
284
|
-
loading:
|
|
285
|
-
error:
|
|
286
|
-
sessions:
|
|
300
|
+
}) : L ? /* @__PURE__ */ E(I, {
|
|
301
|
+
loading: R.loading,
|
|
302
|
+
error: R.error,
|
|
303
|
+
sessions: U,
|
|
287
304
|
showMentor: !1,
|
|
288
305
|
emptyTitle: "No sessions to host yet",
|
|
289
306
|
emptyDescription: "When mentees request time with you, their sessions will show up here.",
|
|
290
307
|
isMentor: !0,
|
|
291
|
-
onCancel:
|
|
292
|
-
onConfirm:
|
|
293
|
-
onComplete:
|
|
294
|
-
busyId:
|
|
295
|
-
}) : /* @__PURE__ */
|
|
296
|
-
icon: /* @__PURE__ */
|
|
308
|
+
onCancel: q,
|
|
309
|
+
onConfirm: J,
|
|
310
|
+
onComplete: Y,
|
|
311
|
+
busyId: w
|
|
312
|
+
}) : /* @__PURE__ */ E(s, {
|
|
313
|
+
icon: /* @__PURE__ */ E(C, { size: 26 }),
|
|
297
314
|
title: "You're not a mentor yet",
|
|
298
315
|
description: "Create a mentor profile to start hosting sessions and helping others build.",
|
|
299
|
-
action: /* @__PURE__ */
|
|
316
|
+
action: /* @__PURE__ */ E(O, {
|
|
300
317
|
onClick: () => i("/mentorship/mentors-page"),
|
|
301
318
|
children: "Become a mentor"
|
|
302
319
|
})
|
|
303
320
|
})
|
|
304
321
|
]
|
|
305
|
-
}) : /* @__PURE__ */
|
|
322
|
+
}) : /* @__PURE__ */ E(n, {
|
|
306
323
|
hero: !0,
|
|
307
324
|
title: "My Sessions",
|
|
308
325
|
description: "Track your mentorship sessions.",
|
|
309
|
-
children: /* @__PURE__ */
|
|
310
|
-
icon: /* @__PURE__ */
|
|
326
|
+
children: /* @__PURE__ */ E(s, {
|
|
327
|
+
icon: /* @__PURE__ */ E(S, { size: 26 }),
|
|
311
328
|
title: "Sign in to view your sessions",
|
|
312
329
|
description: "Your booked and hosted mentorship sessions will appear here once you're signed in."
|
|
313
330
|
})
|
|
314
331
|
});
|
|
315
332
|
}
|
|
316
333
|
//#endregion
|
|
317
|
-
export {
|
|
334
|
+
export { L as MentorshipSessionsPagePage };
|
|
318
335
|
|
|
319
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 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 } = 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 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 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: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":"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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":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FC, PropsWithChildren } from 'react';
|
|
2
|
+
import { TechnoSpamRootProps } from '../types';
|
|
3
|
+
|
|
4
|
+
export declare const useTechnoSpam: () => TechnoSpamRootProps;
|
|
5
|
+
/**
|
|
6
|
+
* basePath-aware navigation. Returns a `navigate(path)` that prepends the MFE
|
|
7
|
+
* basePath (so pages navigate with module-relative paths like
|
|
8
|
+
* `/courses/courses-page`) and falls back to react-router when the host does
|
|
9
|
+
* not inject a navigate function.
|
|
10
|
+
*/
|
|
11
|
+
export declare const useTechnoSpamNavigate: () => ((path: string) => void);
|
|
12
|
+
export declare const TechnoSpamProvider: FC<PropsWithChildren<TechnoSpamRootProps>>;
|
|
13
|
+
//# sourceMappingURL=TechnoSpamProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TechnoSpamProvider.d.ts","sourceRoot":"","sources":["../../../src/technospam/providers/TechnoSpamProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAMpD,eAAO,MAAM,aAAa,2BAIzB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAAO,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAW/D,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAsBzE,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ApolloClient } from '@apollo/client';
|
|
2
|
+
import { AssistantArtifact, AssistantMode } from '../types/assistant';
|
|
3
|
+
import { PageContext } from '../utils/pageContext';
|
|
4
|
+
|
|
5
|
+
export interface AssistantPromptResult {
|
|
6
|
+
response: string;
|
|
7
|
+
tokens?: {
|
|
8
|
+
input: number;
|
|
9
|
+
output: number;
|
|
10
|
+
};
|
|
11
|
+
artifacts?: AssistantArtifact[];
|
|
12
|
+
}
|
|
13
|
+
export interface AssistantRawMessagePart {
|
|
14
|
+
type?: string;
|
|
15
|
+
text?: string;
|
|
16
|
+
tool?: string;
|
|
17
|
+
state?: {
|
|
18
|
+
status?: string;
|
|
19
|
+
input?: unknown;
|
|
20
|
+
output?: unknown;
|
|
21
|
+
raw?: unknown;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface AssistantRawMessage {
|
|
25
|
+
info?: {
|
|
26
|
+
id?: string;
|
|
27
|
+
role?: string;
|
|
28
|
+
providerID?: string;
|
|
29
|
+
modelID?: string;
|
|
30
|
+
tokens?: {
|
|
31
|
+
input: number;
|
|
32
|
+
output: number;
|
|
33
|
+
};
|
|
34
|
+
time?: {
|
|
35
|
+
created?: number;
|
|
36
|
+
completed?: number;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
parts?: AssistantRawMessagePart[];
|
|
40
|
+
}
|
|
41
|
+
export interface AssistantSandboxAuthContext {
|
|
42
|
+
accessToken?: string | null;
|
|
43
|
+
workspaceToken?: string | null;
|
|
44
|
+
userId?: string | null;
|
|
45
|
+
organizationId?: string | null;
|
|
46
|
+
}
|
|
47
|
+
export interface AssistantSessionInfo {
|
|
48
|
+
id: string;
|
|
49
|
+
mode: string;
|
|
50
|
+
}
|
|
51
|
+
export interface DownloadedAssistantArtifact {
|
|
52
|
+
filename: string;
|
|
53
|
+
mimeType: string;
|
|
54
|
+
contentBase64: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function findExistingSandbox(_apollo: ApolloClient, workspaceId: string, mode: AssistantMode, authContext?: AssistantSandboxAuthContext): Promise<string | null>;
|
|
57
|
+
export declare function createAssistantSandbox(_apollo: ApolloClient, mode: AssistantMode, workspaceId: string, authContext?: AssistantSandboxAuthContext): Promise<string>;
|
|
58
|
+
export declare function waitForSandboxReady(_apollo: ApolloClient, sandboxId: string, workspaceId: string, authContext?: AssistantSandboxAuthContext, maxWaitMs?: number, onProgress?: (message: string) => void): Promise<void>;
|
|
59
|
+
export declare function waitForAssistantServiceReady(apollo: ApolloClient, sandboxId: string, workspaceId: string, authContext?: AssistantSandboxAuthContext, maxWaitMs?: number, onProgress?: (message: string) => void): Promise<void>;
|
|
60
|
+
export declare function createAssistantSession(apollo: ApolloClient, sandboxId: string, workspaceId: string, mode: AssistantMode, authContext?: AssistantSandboxAuthContext): Promise<{
|
|
61
|
+
sessionId: string;
|
|
62
|
+
}>;
|
|
63
|
+
export declare function getAssistantSession(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, authContext?: AssistantSandboxAuthContext): Promise<AssistantSessionInfo>;
|
|
64
|
+
export declare function sendAssistantPrompt(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, prompt: string, mode: AssistantMode, pageContext?: PageContext, authContext?: AssistantSandboxAuthContext): Promise<AssistantPromptResult>;
|
|
65
|
+
export declare function sendAssistantPromptAsync(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, prompt: string, mode: AssistantMode, pageContext?: PageContext, authContext?: AssistantSandboxAuthContext): Promise<void>;
|
|
66
|
+
export declare function getAssistantMessages(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, authContext?: AssistantSandboxAuthContext, limit?: number): Promise<AssistantRawMessage[]>;
|
|
67
|
+
export declare function checkAssistantAiCredits(_apollo: ApolloClient, workspaceId: string, authContext?: AssistantSandboxAuthContext): Promise<boolean>;
|
|
68
|
+
export declare function reportAssistantAiTokenUsage(_apollo: ApolloClient, workspaceId: string, sessionId: string, messageId: string, model: string | undefined, tokens: {
|
|
69
|
+
input: number;
|
|
70
|
+
output: number;
|
|
71
|
+
}, authContext?: AssistantSandboxAuthContext): Promise<void>;
|
|
72
|
+
export declare function getAssistantArtifacts(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, authContext?: AssistantSandboxAuthContext): Promise<AssistantArtifact[]>;
|
|
73
|
+
export declare function downloadAssistantArtifact(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, artifactPath: string, authContext?: AssistantSandboxAuthContext): Promise<DownloadedAssistantArtifact>;
|
|
74
|
+
export declare function sendHeartbeat(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, authContext?: AssistantSandboxAuthContext): Promise<void>;
|
|
75
|
+
export declare function extendAssistantSandboxTTL(_apollo: ApolloClient, sandboxId: string, workspaceId: string, additionalSeconds?: number, authContext?: AssistantSandboxAuthContext): Promise<void>;
|
|
76
|
+
//# sourceMappingURL=assistantApi.d.ts.map
|