@burdenoff/microfe-technospam 2026.704.1 → 2026.705.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 (23) hide show
  1. package/dist/technospam/api/technospamApi.js +232 -150
  2. package/dist/technospam/api/technospamApi.js.map +1 -1
  3. package/dist/technospam/components/LoadMore.js +18 -2
  4. package/dist/technospam/components/LoadMore.js.map +1 -0
  5. package/dist/technospam/pages/AdminAdminDashboardPagePage.js +664 -334
  6. package/dist/technospam/pages/AdminAdminDashboardPagePage.js.map +1 -1
  7. package/dist/technospam/pages/ApplicationsProblemsPagePage.js +79 -72
  8. package/dist/technospam/pages/ApplicationsProblemsPagePage.js.map +1 -1
  9. package/dist/technospam/pages/CoursesCourseDetailsPagePage.js +140 -87
  10. package/dist/technospam/pages/CoursesCourseDetailsPagePage.js.map +1 -1
  11. package/dist/technospam/pages/CoursesCoursesPagePage.js +75 -68
  12. package/dist/technospam/pages/CoursesCoursesPagePage.js.map +1 -1
  13. package/dist/technospam/pages/CoursesMyLearningPagePage.js +3 -0
  14. package/dist/technospam/pages/CoursesMyLearningPagePage.js.map +1 -1
  15. package/dist/technospam/pages/HackathonsHackathonsPagePage.js +76 -53
  16. package/dist/technospam/pages/HackathonsHackathonsPagePage.js.map +1 -1
  17. package/dist/technospam/pages/MentorshipMentorProfilePagePage.js +36 -35
  18. package/dist/technospam/pages/MentorshipMentorProfilePagePage.js.map +1 -1
  19. package/dist/technospam/pages/MentorshipMentorsPagePage.js +112 -103
  20. package/dist/technospam/pages/MentorshipMentorsPagePage.js.map +1 -1
  21. package/dist/technospam/pages/MentorshipSessionsPagePage.js +219 -110
  22. package/dist/technospam/pages/MentorshipSessionsPagePage.js.map +1 -1
  23. package/package.json +1 -1
@@ -2,55 +2,56 @@ import { useTechnoSpam as e, useTechnoSpamNavigate as t } from "../providers/Tec
2
2
  import { PageLayout as n } from "../components/PageLayout.js";
3
3
  import { StatCard as r } from "../components/StatCard.js";
4
4
  import { formatMoney as i } from "../utils/format.js";
5
- import { EmptyView as a, ErrorView as o, LoadingGrid as s } from "../components/StateViews.js";
5
+ import { LoadMore as a } from "../components/LoadMore.js";
6
+ import { EmptyView as o, ErrorView as s, LoadingGrid as c } from "../components/StateViews.js";
6
7
  import "../components/index.js";
7
- import { notify as c } from "../lib/toast.js";
8
- import { useBecomeMentor as l, useMentorsQuery as u } from "../api/technospamApi.js";
9
- import { useMemo as d, useState as f } from "react";
10
- import { Award as p, MessageSquare as m, Search as h, Sparkles as g, Star as _, UserPlus as v, Users as y, X as b } from "lucide-react";
11
- import { jsx as x, jsxs as S } from "react/jsx-runtime";
12
- import { Badge as C, Button as w, GlassCard as T, Input as E, Textarea as D } from "@burdenoff/fe-libs/ui";
8
+ import { notify as l } from "../lib/toast.js";
9
+ import { pageArg as u, useBecomeMentor as d, useMentorsQuery as f, usePageLimit as p } from "../api/technospamApi.js";
10
+ import { useMemo as m, useState as h } from "react";
11
+ import { Award as g, MessageSquare as _, Search as v, Sparkles as y, Star as b, UserPlus as x, Users as S, X as C } from "lucide-react";
12
+ import { jsx as w, jsxs as T } from "react/jsx-runtime";
13
+ import { Badge as E, Button as D, GlassCard as O, Input as k, Textarea as A } from "@burdenoff/fe-libs/ui";
13
14
  //#region src/technospam/pages/MentorshipMentorsPagePage.tsx
14
- function O({ mentor: e, onOpen: t }) {
15
- return /* @__PURE__ */ S(T, {
15
+ function j({ mentor: e, onOpen: t }) {
16
+ return /* @__PURE__ */ T(O, {
16
17
  className: "group flex cursor-pointer flex-col gap-3 p-5 transition-shadow hover:shadow-md",
17
18
  onClick: t,
18
19
  children: [
19
- /* @__PURE__ */ S("div", {
20
+ /* @__PURE__ */ T("div", {
20
21
  className: "flex items-start justify-between gap-3",
21
- children: [/* @__PURE__ */ S("div", {
22
+ children: [/* @__PURE__ */ T("div", {
22
23
  className: "min-w-0",
23
- children: [/* @__PURE__ */ x("h3", {
24
+ children: [/* @__PURE__ */ w("h3", {
24
25
  className: "truncate text-base font-semibold text-text-primary group-hover:text-accent-primary",
25
26
  children: e.headline
26
- }), /* @__PURE__ */ S("div", {
27
+ }), /* @__PURE__ */ T("div", {
27
28
  className: "mt-1 text-sm font-medium text-text-secondary",
28
- children: [i(e.hourlyRate, e.currency), /* @__PURE__ */ x("span", {
29
+ children: [i(e.hourlyRate, e.currency), /* @__PURE__ */ w("span", {
29
30
  className: "text-text-muted",
30
31
  children: " / hr"
31
32
  })]
32
33
  })]
33
- }), e.isAcceptingMentees ? /* @__PURE__ */ x(C, {
34
+ }), e.isAcceptingMentees ? /* @__PURE__ */ w(E, {
34
35
  variant: "outline",
35
36
  className: "shrink-0 border-status-success-border bg-status-success-bg-subtle text-status-success-text",
36
37
  children: "Accepting mentees"
37
- }) : /* @__PURE__ */ x(C, {
38
+ }) : /* @__PURE__ */ w(E, {
38
39
  variant: "outline",
39
40
  className: "shrink-0 border-border-seam bg-bg-sunken text-text-secondary",
40
41
  children: "Not accepting"
41
42
  })]
42
43
  }),
43
- e.bio ? /* @__PURE__ */ x("p", {
44
+ e.bio ? /* @__PURE__ */ w("p", {
44
45
  className: "line-clamp-2 text-sm text-text-secondary",
45
46
  children: e.bio
46
47
  }) : null,
47
- e.expertise.length ? /* @__PURE__ */ S("div", {
48
+ e.expertise.length ? /* @__PURE__ */ T("div", {
48
49
  className: "flex flex-wrap gap-1.5",
49
- children: [e.expertise.slice(0, 4).map((e) => /* @__PURE__ */ x(C, {
50
+ children: [e.expertise.slice(0, 4).map((e) => /* @__PURE__ */ w(E, {
50
51
  variant: "secondary",
51
52
  className: "text-[11px]",
52
53
  children: e
53
- }, e)), e.expertise.length > 4 ? /* @__PURE__ */ S("span", {
54
+ }, e)), e.expertise.length > 4 ? /* @__PURE__ */ T("span", {
54
55
  className: "text-xs text-text-muted",
55
56
  children: [
56
57
  "+",
@@ -59,18 +60,18 @@ function O({ mentor: e, onOpen: t }) {
59
60
  ]
60
61
  }) : null]
61
62
  }) : null,
62
- /* @__PURE__ */ S("div", {
63
+ /* @__PURE__ */ T("div", {
63
64
  className: "mt-auto flex items-center gap-4 pt-1 text-xs text-text-muted",
64
- children: [/* @__PURE__ */ S("span", {
65
+ children: [/* @__PURE__ */ T("span", {
65
66
  className: "inline-flex items-center gap-1",
66
- children: [/* @__PURE__ */ x(_, {
67
+ children: [/* @__PURE__ */ w(b, {
67
68
  size: 13,
68
69
  className: "text-accent-teal"
69
70
  }), e.ratingAvg > 0 ? e.ratingAvg.toFixed(1) : "New"]
70
- }), /* @__PURE__ */ S("span", {
71
+ }), /* @__PURE__ */ T("span", {
71
72
  className: "inline-flex items-center gap-1",
72
73
  children: [
73
- /* @__PURE__ */ x(m, { size: 13 }),
74
+ /* @__PURE__ */ w(_, { size: 13 }),
74
75
  " ",
75
76
  e.sessionsCount,
76
77
  " sessions"
@@ -80,109 +81,109 @@ function O({ mentor: e, onOpen: t }) {
80
81
  ]
81
82
  });
82
83
  }
83
- function k({ onClose: e, onDone: t }) {
84
- let [n, r] = f(""), [i, a] = f(""), [o, s] = f(""), [u, d] = f(""), [p, m] = f("USD"), [h, { loading: g }] = l(), _ = n.trim().length > 0 && !g;
85
- return /* @__PURE__ */ S(T, {
84
+ function M({ onClose: e, onDone: t }) {
85
+ let [n, r] = h(""), [i, a] = h(""), [o, s] = h(""), [c, u] = h(""), [f, p] = h("USD"), [m, { loading: g }] = d(), _ = n.trim().length > 0 && !g;
86
+ return /* @__PURE__ */ T(O, {
86
87
  className: "mb-6 p-5",
87
- children: [/* @__PURE__ */ S("div", {
88
+ children: [/* @__PURE__ */ T("div", {
88
89
  className: "mb-4 flex items-center justify-between",
89
- children: [/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("h2", {
90
+ children: [/* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("h2", {
90
91
  className: "text-base font-semibold text-text-primary",
91
92
  children: "Become a mentor"
92
- }), /* @__PURE__ */ x("p", {
93
+ }), /* @__PURE__ */ w("p", {
93
94
  className: "text-sm text-text-secondary",
94
95
  children: "Share your expertise and start mentoring builders in the community."
95
- })] }), /* @__PURE__ */ x(w, {
96
+ })] }), /* @__PURE__ */ w(D, {
96
97
  variant: "ghost",
97
98
  size: "sm",
98
99
  onClick: e,
99
100
  "aria-label": "Close",
100
- children: /* @__PURE__ */ x(b, { size: 16 })
101
+ children: /* @__PURE__ */ w(C, { size: 16 })
101
102
  })]
102
- }), /* @__PURE__ */ S("div", {
103
+ }), /* @__PURE__ */ T("div", {
103
104
  className: "grid grid-cols-1 gap-4",
104
105
  children: [
105
- /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ S("label", {
106
+ /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ T("label", {
106
107
  className: "mb-1.5 block text-sm font-medium text-text-primary",
107
- children: ["Headline ", /* @__PURE__ */ x("span", {
108
+ children: ["Headline ", /* @__PURE__ */ w("span", {
108
109
  className: "text-status-error-text",
109
110
  children: "*"
110
111
  })]
111
- }), /* @__PURE__ */ x(E, {
112
+ }), /* @__PURE__ */ w(k, {
112
113
  placeholder: "e.g. Staff Engineer · Distributed systems & career growth",
113
114
  value: n,
114
115
  onChange: (e) => r(e.target.value)
115
116
  })] }),
116
- /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("label", {
117
+ /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
117
118
  className: "mb-1.5 block text-sm font-medium text-text-primary",
118
119
  children: "Bio"
119
- }), /* @__PURE__ */ x(D, {
120
+ }), /* @__PURE__ */ w(A, {
120
121
  rows: 3,
121
122
  placeholder: "Tell mentees about your experience and how you can help.",
122
123
  value: i,
123
124
  onChange: (e) => a(e.target.value)
124
125
  })] }),
125
- /* @__PURE__ */ S("div", { children: [
126
- /* @__PURE__ */ x("label", {
126
+ /* @__PURE__ */ T("div", { children: [
127
+ /* @__PURE__ */ w("label", {
127
128
  className: "mb-1.5 block text-sm font-medium text-text-primary",
128
129
  children: "Expertise"
129
130
  }),
130
- /* @__PURE__ */ x(E, {
131
+ /* @__PURE__ */ w(k, {
131
132
  placeholder: "React, System design, Career coaching",
132
133
  value: o,
133
134
  onChange: (e) => s(e.target.value)
134
135
  }),
135
- /* @__PURE__ */ x("p", {
136
+ /* @__PURE__ */ w("p", {
136
137
  className: "mt-1 text-xs text-text-muted",
137
138
  children: "Comma-separated topics."
138
139
  })
139
140
  ] }),
140
- /* @__PURE__ */ S("div", {
141
+ /* @__PURE__ */ T("div", {
141
142
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
142
- children: [/* @__PURE__ */ S("div", { children: [
143
- /* @__PURE__ */ x("label", {
143
+ children: [/* @__PURE__ */ T("div", { children: [
144
+ /* @__PURE__ */ w("label", {
144
145
  className: "mb-1.5 block text-sm font-medium text-text-primary",
145
146
  children: "Hourly rate"
146
147
  }),
147
- /* @__PURE__ */ x(E, {
148
+ /* @__PURE__ */ w(k, {
148
149
  type: "number",
149
150
  min: 0,
150
151
  placeholder: "0",
151
- value: u,
152
- onChange: (e) => d(e.target.value)
152
+ value: c,
153
+ onChange: (e) => u(e.target.value)
153
154
  }),
154
- /* @__PURE__ */ x("p", {
155
+ /* @__PURE__ */ w("p", {
155
156
  className: "mt-1 text-xs text-text-muted",
156
157
  children: "Whole number. Leave 0 for free."
157
158
  })
158
- ] }), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("label", {
159
+ ] }), /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
159
160
  className: "mb-1.5 block text-sm font-medium text-text-primary",
160
161
  children: "Currency"
161
- }), /* @__PURE__ */ x(E, {
162
+ }), /* @__PURE__ */ w(k, {
162
163
  placeholder: "USD",
163
- value: p,
164
- onChange: (e) => m(e.target.value)
164
+ value: f,
165
+ onChange: (e) => p(e.target.value)
165
166
  })] })]
166
167
  }),
167
- /* @__PURE__ */ S("div", {
168
+ /* @__PURE__ */ T("div", {
168
169
  className: "flex flex-wrap items-center gap-2",
169
- children: [/* @__PURE__ */ S(w, {
170
+ children: [/* @__PURE__ */ T(D, {
170
171
  onClick: async () => {
171
172
  if (!_) return;
172
173
  let e = { headline: n.trim() };
173
174
  i.trim() && (e.bio = i.trim());
174
175
  let r = o.split(",").map((e) => e.trim()).filter(Boolean);
175
176
  r.length && (e.expertise = r);
176
- let a = Number.parseInt(u, 10);
177
- !Number.isNaN(a) && a >= 0 && (e.hourlyRate = a), p.trim() && (e.currency = p.trim().toUpperCase()), (await h({ variables: { input: e } })).data?.tecBecomeMentor && (c.success("Mentor profile created", "Your profile is pending review."), t());
177
+ let a = Number.parseInt(c, 10);
178
+ !Number.isNaN(a) && a >= 0 && (e.hourlyRate = a), f.trim() && (e.currency = f.trim().toUpperCase()), (await m({ variables: { input: e } })).data?.tecBecomeMentor && (l.success("Mentor profile created", "Your profile is pending review."), t());
178
179
  },
179
180
  disabled: !_,
180
181
  children: [
181
- /* @__PURE__ */ x(v, { size: 16 }),
182
+ /* @__PURE__ */ w(x, { size: 16 }),
182
183
  " ",
183
184
  g ? "Submitting…" : "Submit profile"
184
185
  ]
185
- }), /* @__PURE__ */ x(w, {
186
+ }), /* @__PURE__ */ w(D, {
186
187
  variant: "outline",
187
188
  onClick: e,
188
189
  disabled: g,
@@ -193,91 +194,99 @@ function k({ onClose: e, onDone: t }) {
193
194
  })]
194
195
  });
195
196
  }
196
- function A() {
197
- let i = t(), { currentUser: c } = e(), [l, _] = f(""), [b, C] = f(!1), { data: D, loading: A, error: j, refetch: M } = u({ status: "ACTIVE" }), N = D?.tecListMentors.items ?? [], P = c?.id, F = !!(P && N.some((e) => e.userId === P)), I = d(() => {
198
- let e = l.trim().toLowerCase();
199
- return e ? N.filter((t) => t.headline.toLowerCase().includes(e) || t.expertise.some((t) => t.toLowerCase().includes(e))) : N;
200
- }, [N, l]), L = N.filter((e) => e.isAcceptingMentees).length;
201
- return /* @__PURE__ */ S(n, {
197
+ function N() {
198
+ let i = t(), { currentUser: l } = e(), [d, b] = h(""), [C, E] = h(!1), { limit: A, more: N } = p(), { data: P, loading: F, error: I, refetch: L } = f({
199
+ status: "ACTIVE",
200
+ pagination: u(A)
201
+ }), R = P?.tecListMentors.items ?? [], z = P?.tecListMentors.pageInfo.hasMore ?? !1, B = l?.id, V = !!(B && R.some((e) => e.userId === B)), H = m(() => {
202
+ let e = d.trim().toLowerCase();
203
+ return e ? R.filter((t) => t.headline.toLowerCase().includes(e) || t.expertise.some((t) => t.toLowerCase().includes(e))) : R;
204
+ }, [R, d]), U = R.filter((e) => e.isAcceptingMentees).length;
205
+ return /* @__PURE__ */ T(n, {
202
206
  hero: !0,
203
207
  title: "Find a Mentor",
204
208
  description: "Connect with experienced builders for 1:1 guidance, code review, and career coaching.",
205
- actions: /* @__PURE__ */ S(w, {
209
+ actions: /* @__PURE__ */ T(D, {
206
210
  variant: "outline",
207
211
  onClick: () => i("/mentorship/sessions-page"),
208
- children: [/* @__PURE__ */ x(m, { size: 16 }), " My sessions"]
212
+ children: [/* @__PURE__ */ w(_, { size: 16 }), " My sessions"]
209
213
  }),
210
214
  children: [
211
- F ? /* @__PURE__ */ S(T, {
215
+ V ? /* @__PURE__ */ T(O, {
212
216
  className: "mb-6 flex items-center gap-3 p-4",
213
- children: [/* @__PURE__ */ x("span", {
217
+ children: [/* @__PURE__ */ w("span", {
214
218
  className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-status-success-bg-subtle text-status-success-text",
215
- children: /* @__PURE__ */ x(p, { size: 20 })
216
- }), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("div", {
219
+ children: /* @__PURE__ */ w(g, { size: 20 })
220
+ }), /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("div", {
217
221
  className: "text-sm font-semibold text-text-primary",
218
222
  children: "You're a mentor"
219
- }), /* @__PURE__ */ x("div", {
223
+ }), /* @__PURE__ */ w("div", {
220
224
  className: "text-xs text-text-secondary",
221
225
  children: "Your mentor profile is live. Mentees can request sessions with you."
222
226
  })] })]
223
- }) : b ? /* @__PURE__ */ x(k, {
224
- onClose: () => C(!1),
227
+ }) : C ? /* @__PURE__ */ w(M, {
228
+ onClose: () => E(!1),
225
229
  onDone: () => {
226
- C(!1), M();
230
+ E(!1), L();
227
231
  }
228
232
  }) : null,
229
- /* @__PURE__ */ S("div", {
233
+ /* @__PURE__ */ T("div", {
230
234
  className: "mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4",
231
- children: [/* @__PURE__ */ x(r, {
235
+ children: [/* @__PURE__ */ w(r, {
232
236
  label: "Mentors",
233
- value: N.length,
234
- icon: y
235
- }), /* @__PURE__ */ x(r, {
237
+ value: R.length,
238
+ icon: S
239
+ }), /* @__PURE__ */ w(r, {
236
240
  label: "Accepting mentees",
237
- value: L,
238
- icon: g
241
+ value: U,
242
+ icon: y
239
243
  })]
240
244
  }),
241
- /* @__PURE__ */ S("div", {
245
+ /* @__PURE__ */ T("div", {
242
246
  className: "mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
243
- children: [/* @__PURE__ */ S("div", {
247
+ children: [/* @__PURE__ */ T("div", {
244
248
  className: "relative w-full sm:w-80",
245
- children: [/* @__PURE__ */ x(h, {
249
+ children: [/* @__PURE__ */ w(v, {
246
250
  className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-muted",
247
251
  size: 16
248
- }), /* @__PURE__ */ x(E, {
252
+ }), /* @__PURE__ */ w(k, {
249
253
  className: "pl-9",
250
254
  placeholder: "Search by headline or expertise…",
251
- value: l,
252
- onChange: (e) => _(e.target.value)
255
+ value: d,
256
+ onChange: (e) => b(e.target.value)
253
257
  })]
254
- }), !F && !b ? /* @__PURE__ */ S(w, {
255
- onClick: () => C(!0),
256
- children: [/* @__PURE__ */ x(v, { size: 16 }), " Become a mentor"]
258
+ }), !V && !C ? /* @__PURE__ */ T(D, {
259
+ onClick: () => E(!0),
260
+ children: [/* @__PURE__ */ w(x, { size: 16 }), " Become a mentor"]
257
261
  }) : null]
258
262
  }),
259
- A && !N.length ? /* @__PURE__ */ x(s, {}) : j ? /* @__PURE__ */ x(o, {
263
+ F && !R.length ? /* @__PURE__ */ w(c, {}) : I ? /* @__PURE__ */ w(s, {
260
264
  title: "Couldn't load mentors",
261
- error: j
262
- }) : I.length === 0 ? /* @__PURE__ */ x(a, {
263
- icon: /* @__PURE__ */ x(y, { size: 26 }),
264
- title: l ? "No matching mentors" : "No mentors yet",
265
- description: l ? "Try a different search term." : "Active mentors will appear here. TechnoSpam is pre-launch — be one of the first to sign up.",
266
- action: !l && !F ? /* @__PURE__ */ x(w, {
267
- onClick: () => C(!0),
265
+ error: I
266
+ }) : H.length === 0 ? /* @__PURE__ */ w(o, {
267
+ icon: /* @__PURE__ */ w(S, { size: 26 }),
268
+ title: d ? "No matching mentors" : "No mentors yet",
269
+ description: d ? "Try a different search term." : "Active mentors will appear here. TechnoSpam is pre-launch — be one of the first to sign up.",
270
+ action: !d && !V ? /* @__PURE__ */ w(D, {
271
+ onClick: () => E(!0),
268
272
  children: "Become a mentor"
269
273
  }) : void 0
270
- }) : /* @__PURE__ */ x("div", {
274
+ }) : /* @__PURE__ */ w("div", {
271
275
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
272
- children: I.map((e) => /* @__PURE__ */ x(O, {
276
+ children: H.map((e) => /* @__PURE__ */ w(j, {
273
277
  mentor: e,
274
278
  onOpen: () => i(`/mentorship/mentor-profile-page?id=${e.id}`)
275
279
  }, e.id))
280
+ }),
281
+ /* @__PURE__ */ w(a, {
282
+ hasMore: z,
283
+ loading: F,
284
+ onClick: N
276
285
  })
277
286
  ]
278
287
  });
279
288
  }
280
289
  //#endregion
281
- export { A as MentorshipMentorsPagePage };
290
+ export { N as MentorshipMentorsPagePage };
282
291
 
283
292
  //# sourceMappingURL=MentorshipMentorsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MentorshipMentorsPagePage.js","names":[],"sources":["../../../src/technospam/pages/MentorshipMentorsPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { Award, MessageSquare, Search, Sparkles, Star, UserPlus, Users, X } from 'lucide-react';\nimport { Badge, Button, GlassCard, Input, Textarea } from '@burdenoff/fe-libs/ui';\nimport { EmptyView, ErrorView, LoadingGrid, PageLayout, StatCard } from '../components';\nimport { useTechnoSpam, useTechnoSpamNavigate } from '../providers/TechnoSpamProvider';\nimport { useBecomeMentor, useMentorsQuery, type TecMentor } from '../api/technospamApi';\nimport { formatMoney } from '../utils/format';\nimport { notify } from '../lib/toast';\n\nfunction MentorCard({ mentor, onOpen }: { mentor: TecMentor; onOpen: () => void }) {\n return (\n <GlassCard\n className=\"group flex cursor-pointer flex-col gap-3 p-5 transition-shadow hover:shadow-md\"\n onClick={onOpen}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <h3 className=\"truncate text-base font-semibold text-text-primary group-hover:text-accent-primary\">\n {mentor.headline}\n </h3>\n <div className=\"mt-1 text-sm font-medium text-text-secondary\">\n {formatMoney(mentor.hourlyRate, mentor.currency)}\n <span className=\"text-text-muted\"> / hr</span>\n </div>\n </div>\n {mentor.isAcceptingMentees ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 border-status-success-border bg-status-success-bg-subtle text-status-success-text\"\n >\n Accepting mentees\n </Badge>\n ) : (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 border-border-seam bg-bg-sunken text-text-secondary\"\n >\n Not accepting\n </Badge>\n )}\n </div>\n\n {mentor.bio ? <p className=\"line-clamp-2 text-sm text-text-secondary\">{mentor.bio}</p> : null}\n\n {mentor.expertise.length ? (\n <div className=\"flex flex-wrap gap-1.5\">\n {mentor.expertise.slice(0, 4).map((skill) => (\n <Badge key={skill} variant=\"secondary\" className=\"text-[11px]\">\n {skill}\n </Badge>\n ))}\n {mentor.expertise.length > 4 ? (\n <span className=\"text-xs text-text-muted\">+{mentor.expertise.length - 4} more</span>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"mt-auto flex items-center gap-4 pt-1 text-xs text-text-muted\">\n <span className=\"inline-flex items-center gap-1\">\n <Star size={13} className=\"text-accent-teal\" />\n {mentor.ratingAvg > 0 ? mentor.ratingAvg.toFixed(1) : 'New'}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <MessageSquare size={13} /> {mentor.sessionsCount} sessions\n </span>\n </div>\n </GlassCard>\n );\n}\n\nfunction BecomeMentorForm({ onClose, onDone }: { onClose: () => void; onDone: () => void }) {\n const [headline, setHeadline] = useState('');\n const [bio, setBio] = useState('');\n const [expertise, setExpertise] = useState('');\n const [hourlyRate, setHourlyRate] = useState('');\n const [currency, setCurrency] = useState('USD');\n const [becomeMentor, { loading }] = useBecomeMentor();\n\n const canSubmit = headline.trim().length > 0 && !loading;\n\n const handleSubmit = async () => {\n if (!canSubmit) return;\n const input: {\n headline: string;\n bio?: string;\n expertise?: string[];\n hourlyRate?: number;\n currency?: string;\n } = { headline: headline.trim() };\n if (bio.trim()) input.bio = bio.trim();\n const exp = expertise\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n if (exp.length) input.expertise = exp;\n const rate = Number.parseInt(hourlyRate, 10);\n if (!Number.isNaN(rate) && rate >= 0) input.hourlyRate = rate;\n if (currency.trim()) input.currency = currency.trim().toUpperCase();\n\n const res = await becomeMentor({ variables: { input } });\n if (res.data?.tecBecomeMentor) {\n notify.success('Mentor profile created', 'Your profile is pending review.');\n onDone();\n }\n };\n\n return (\n <GlassCard className=\"mb-6 p-5\">\n <div className=\"mb-4 flex items-center justify-between\">\n <div>\n <h2 className=\"text-base font-semibold text-text-primary\">Become a mentor</h2>\n <p className=\"text-sm text-text-secondary\">\n Share your expertise and start mentoring builders in the community.\n </p>\n </div>\n <Button variant=\"ghost\" size=\"sm\" onClick={onClose} aria-label=\"Close\">\n <X size={16} />\n </Button>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Headline <span className=\"text-status-error-text\">*</span>\n </label>\n <Input\n placeholder=\"e.g. Staff Engineer · Distributed systems & career growth\"\n value={headline}\n onChange={(e) => setHeadline(e.target.value)}\n />\n </div>\n\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Bio</label>\n <Textarea\n rows={3}\n placeholder=\"Tell mentees about your experience and how you can help.\"\n value={bio}\n onChange={(e) => setBio(e.target.value)}\n />\n </div>\n\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Expertise</label>\n <Input\n placeholder=\"React, System design, Career coaching\"\n value={expertise}\n onChange={(e) => setExpertise(e.target.value)}\n />\n <p className=\"mt-1 text-xs text-text-muted\">Comma-separated topics.</p>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Hourly rate\n </label>\n <Input\n type=\"number\"\n min={0}\n placeholder=\"0\"\n value={hourlyRate}\n onChange={(e) => setHourlyRate(e.target.value)}\n />\n <p className=\"mt-1 text-xs text-text-muted\">Whole number. Leave 0 for free.</p>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Currency</label>\n <Input\n placeholder=\"USD\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value)}\n />\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button onClick={handleSubmit} disabled={!canSubmit}>\n <UserPlus size={16} /> {loading ? 'Submitting…' : 'Submit profile'}\n </Button>\n <Button variant=\"outline\" onClick={onClose} disabled={loading}>\n Cancel\n </Button>\n </div>\n </div>\n </GlassCard>\n );\n}\n\nexport function MentorshipMentorsPagePage() {\n const navigate = useTechnoSpamNavigate();\n const { currentUser } = useTechnoSpam();\n const [search, setSearch] = useState('');\n const [showForm, setShowForm] = useState(false);\n\n const { data, loading, error, refetch } = useMentorsQuery({ status: 'ACTIVE' });\n\n const mentors = data?.tecListMentors.items ?? [];\n const userId = currentUser?.id;\n const alreadyMentor = Boolean(userId && mentors.some((m) => m.userId === userId));\n\n const filtered = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return mentors;\n return mentors.filter(\n (m) =>\n m.headline.toLowerCase().includes(q) ||\n m.expertise.some((skill) => skill.toLowerCase().includes(q))\n );\n }, [mentors, search]);\n\n const accepting = mentors.filter((m) => m.isAcceptingMentees).length;\n\n return (\n <PageLayout\n hero\n title=\"Find a Mentor\"\n description=\"Connect with experienced builders for 1:1 guidance, code review, and career coaching.\"\n actions={\n <Button variant=\"outline\" onClick={() => navigate('/mentorship/sessions-page')}>\n <MessageSquare size={16} /> My sessions\n </Button>\n }\n >\n {alreadyMentor ? (\n <GlassCard className=\"mb-6 flex items-center gap-3 p-4\">\n <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-status-success-bg-subtle text-status-success-text\">\n <Award size={20} />\n </span>\n <div>\n <div className=\"text-sm font-semibold text-text-primary\">You&apos;re a mentor</div>\n <div className=\"text-xs text-text-secondary\">\n Your mentor profile is live. Mentees can request sessions with you.\n </div>\n </div>\n </GlassCard>\n ) : showForm ? (\n <BecomeMentorForm\n onClose={() => setShowForm(false)}\n onDone={() => {\n setShowForm(false);\n void refetch();\n }}\n />\n ) : null}\n\n <div className=\"mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <StatCard label=\"Mentors\" value={mentors.length} icon={Users} />\n <StatCard label=\"Accepting mentees\" value={accepting} icon={Sparkles} />\n </div>\n\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"relative w-full sm:w-80\">\n <Search\n className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-muted\"\n size={16}\n />\n <Input\n className=\"pl-9\"\n placeholder=\"Search by headline or expertise…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n {!alreadyMentor && !showForm ? (\n <Button onClick={() => setShowForm(true)}>\n <UserPlus size={16} /> Become a mentor\n </Button>\n ) : null}\n </div>\n\n {loading && !mentors.length ? (\n <LoadingGrid />\n ) : error ? (\n <ErrorView title=\"Couldn't load mentors\" error={error} />\n ) : filtered.length === 0 ? (\n <EmptyView\n icon={<Users size={26} />}\n title={search ? 'No matching mentors' : 'No mentors yet'}\n description={\n search\n ? 'Try a different search term.'\n : 'Active mentors will appear here. TechnoSpam is pre-launch — be one of the first to sign up.'\n }\n action={\n !search && !alreadyMentor ? (\n <Button onClick={() => setShowForm(true)}>Become a mentor</Button>\n ) : undefined\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {filtered.map((mentor) => (\n <MentorCard\n key={mentor.id}\n mentor={mentor}\n onOpen={() => navigate(`/mentorship/mentor-profile-page?id=${mentor.id}`)}\n />\n ))}\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MentorshipMentorsPagePage.js","names":[],"sources":["../../../src/technospam/pages/MentorshipMentorsPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { Award, MessageSquare, Search, Sparkles, Star, UserPlus, Users, X } from 'lucide-react';\nimport { Badge, Button, GlassCard, Input, Textarea } from '@burdenoff/fe-libs/ui';\nimport { EmptyView, ErrorView, LoadMore, LoadingGrid, PageLayout, StatCard } from '../components';\nimport { useTechnoSpam, useTechnoSpamNavigate } from '../providers/TechnoSpamProvider';\nimport {\n pageArg,\n useBecomeMentor,\n useMentorsQuery,\n usePageLimit,\n type TecMentor,\n} from '../api/technospamApi';\nimport { formatMoney } from '../utils/format';\nimport { notify } from '../lib/toast';\n\nfunction MentorCard({ mentor, onOpen }: { mentor: TecMentor; onOpen: () => void }) {\n return (\n <GlassCard\n className=\"group flex cursor-pointer flex-col gap-3 p-5 transition-shadow hover:shadow-md\"\n onClick={onOpen}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <h3 className=\"truncate text-base font-semibold text-text-primary group-hover:text-accent-primary\">\n {mentor.headline}\n </h3>\n <div className=\"mt-1 text-sm font-medium text-text-secondary\">\n {formatMoney(mentor.hourlyRate, mentor.currency)}\n <span className=\"text-text-muted\"> / hr</span>\n </div>\n </div>\n {mentor.isAcceptingMentees ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 border-status-success-border bg-status-success-bg-subtle text-status-success-text\"\n >\n Accepting mentees\n </Badge>\n ) : (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 border-border-seam bg-bg-sunken text-text-secondary\"\n >\n Not accepting\n </Badge>\n )}\n </div>\n\n {mentor.bio ? <p className=\"line-clamp-2 text-sm text-text-secondary\">{mentor.bio}</p> : null}\n\n {mentor.expertise.length ? (\n <div className=\"flex flex-wrap gap-1.5\">\n {mentor.expertise.slice(0, 4).map((skill) => (\n <Badge key={skill} variant=\"secondary\" className=\"text-[11px]\">\n {skill}\n </Badge>\n ))}\n {mentor.expertise.length > 4 ? (\n <span className=\"text-xs text-text-muted\">+{mentor.expertise.length - 4} more</span>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"mt-auto flex items-center gap-4 pt-1 text-xs text-text-muted\">\n <span className=\"inline-flex items-center gap-1\">\n <Star size={13} className=\"text-accent-teal\" />\n {mentor.ratingAvg > 0 ? mentor.ratingAvg.toFixed(1) : 'New'}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <MessageSquare size={13} /> {mentor.sessionsCount} sessions\n </span>\n </div>\n </GlassCard>\n );\n}\n\nfunction BecomeMentorForm({ onClose, onDone }: { onClose: () => void; onDone: () => void }) {\n const [headline, setHeadline] = useState('');\n const [bio, setBio] = useState('');\n const [expertise, setExpertise] = useState('');\n const [hourlyRate, setHourlyRate] = useState('');\n const [currency, setCurrency] = useState('USD');\n const [becomeMentor, { loading }] = useBecomeMentor();\n\n const canSubmit = headline.trim().length > 0 && !loading;\n\n const handleSubmit = async () => {\n if (!canSubmit) return;\n const input: {\n headline: string;\n bio?: string;\n expertise?: string[];\n hourlyRate?: number;\n currency?: string;\n } = { headline: headline.trim() };\n if (bio.trim()) input.bio = bio.trim();\n const exp = expertise\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n if (exp.length) input.expertise = exp;\n const rate = Number.parseInt(hourlyRate, 10);\n if (!Number.isNaN(rate) && rate >= 0) input.hourlyRate = rate;\n if (currency.trim()) input.currency = currency.trim().toUpperCase();\n\n const res = await becomeMentor({ variables: { input } });\n if (res.data?.tecBecomeMentor) {\n notify.success('Mentor profile created', 'Your profile is pending review.');\n onDone();\n }\n };\n\n return (\n <GlassCard className=\"mb-6 p-5\">\n <div className=\"mb-4 flex items-center justify-between\">\n <div>\n <h2 className=\"text-base font-semibold text-text-primary\">Become a mentor</h2>\n <p className=\"text-sm text-text-secondary\">\n Share your expertise and start mentoring builders in the community.\n </p>\n </div>\n <Button variant=\"ghost\" size=\"sm\" onClick={onClose} aria-label=\"Close\">\n <X size={16} />\n </Button>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Headline <span className=\"text-status-error-text\">*</span>\n </label>\n <Input\n placeholder=\"e.g. Staff Engineer · Distributed systems & career growth\"\n value={headline}\n onChange={(e) => setHeadline(e.target.value)}\n />\n </div>\n\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Bio</label>\n <Textarea\n rows={3}\n placeholder=\"Tell mentees about your experience and how you can help.\"\n value={bio}\n onChange={(e) => setBio(e.target.value)}\n />\n </div>\n\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Expertise</label>\n <Input\n placeholder=\"React, System design, Career coaching\"\n value={expertise}\n onChange={(e) => setExpertise(e.target.value)}\n />\n <p className=\"mt-1 text-xs text-text-muted\">Comma-separated topics.</p>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Hourly rate\n </label>\n <Input\n type=\"number\"\n min={0}\n placeholder=\"0\"\n value={hourlyRate}\n onChange={(e) => setHourlyRate(e.target.value)}\n />\n <p className=\"mt-1 text-xs text-text-muted\">Whole number. Leave 0 for free.</p>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Currency</label>\n <Input\n placeholder=\"USD\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value)}\n />\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button onClick={handleSubmit} disabled={!canSubmit}>\n <UserPlus size={16} /> {loading ? 'Submitting…' : 'Submit profile'}\n </Button>\n <Button variant=\"outline\" onClick={onClose} disabled={loading}>\n Cancel\n </Button>\n </div>\n </div>\n </GlassCard>\n );\n}\n\nexport function MentorshipMentorsPagePage() {\n const navigate = useTechnoSpamNavigate();\n const { currentUser } = useTechnoSpam();\n const [search, setSearch] = useState('');\n const [showForm, setShowForm] = useState(false);\n\n const { limit, more } = usePageLimit();\n const { data, loading, error, refetch } = useMentorsQuery({\n status: 'ACTIVE',\n pagination: pageArg(limit),\n });\n\n const mentors = data?.tecListMentors.items ?? [];\n const hasMore = data?.tecListMentors.pageInfo.hasMore ?? false;\n const userId = currentUser?.id;\n const alreadyMentor = Boolean(userId && mentors.some((m) => m.userId === userId));\n\n const filtered = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return mentors;\n return mentors.filter(\n (m) =>\n m.headline.toLowerCase().includes(q) ||\n m.expertise.some((skill) => skill.toLowerCase().includes(q))\n );\n }, [mentors, search]);\n\n const accepting = mentors.filter((m) => m.isAcceptingMentees).length;\n\n return (\n <PageLayout\n hero\n title=\"Find a Mentor\"\n description=\"Connect with experienced builders for 1:1 guidance, code review, and career coaching.\"\n actions={\n <Button variant=\"outline\" onClick={() => navigate('/mentorship/sessions-page')}>\n <MessageSquare size={16} /> My sessions\n </Button>\n }\n >\n {alreadyMentor ? (\n <GlassCard className=\"mb-6 flex items-center gap-3 p-4\">\n <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-status-success-bg-subtle text-status-success-text\">\n <Award size={20} />\n </span>\n <div>\n <div className=\"text-sm font-semibold text-text-primary\">You&apos;re a mentor</div>\n <div className=\"text-xs text-text-secondary\">\n Your mentor profile is live. Mentees can request sessions with you.\n </div>\n </div>\n </GlassCard>\n ) : showForm ? (\n <BecomeMentorForm\n onClose={() => setShowForm(false)}\n onDone={() => {\n setShowForm(false);\n void refetch();\n }}\n />\n ) : null}\n\n <div className=\"mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <StatCard label=\"Mentors\" value={mentors.length} icon={Users} />\n <StatCard label=\"Accepting mentees\" value={accepting} icon={Sparkles} />\n </div>\n\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"relative w-full sm:w-80\">\n <Search\n className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-muted\"\n size={16}\n />\n <Input\n className=\"pl-9\"\n placeholder=\"Search by headline or expertise…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n {!alreadyMentor && !showForm ? (\n <Button onClick={() => setShowForm(true)}>\n <UserPlus size={16} /> Become a mentor\n </Button>\n ) : null}\n </div>\n\n {loading && !mentors.length ? (\n <LoadingGrid />\n ) : error ? (\n <ErrorView title=\"Couldn't load mentors\" error={error} />\n ) : filtered.length === 0 ? (\n <EmptyView\n icon={<Users size={26} />}\n title={search ? 'No matching mentors' : 'No mentors yet'}\n description={\n search\n ? 'Try a different search term.'\n : 'Active mentors will appear here. TechnoSpam is pre-launch — be one of the first to sign up.'\n }\n action={\n !search && !alreadyMentor ? (\n <Button onClick={() => setShowForm(true)}>Become a mentor</Button>\n ) : undefined\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {filtered.map((mentor) => (\n <MentorCard\n key={mentor.id}\n mentor={mentor}\n onOpen={() => navigate(`/mentorship/mentor-profile-page?id=${mentor.id}`)}\n />\n ))}\n </div>\n )}\n <LoadMore hasMore={hasMore} loading={loading} onClick={more} />\n </PageLayout>\n );\n}\n"],"mappings":"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"}