@burdenoff/microfe-technospam 2026.1030.4 → 2026.1030.6

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 (67) hide show
  1. package/dist/generated/wspace-types.d.ts +1501 -11
  2. package/dist/generated/wspace-types.d.ts.map +1 -1
  3. package/dist/node_modules/recharts/es6/cartesian/Brush.js.map +1 -1
  4. package/dist/node_modules/recharts/es6/cartesian/ErrorBar.js.map +1 -1
  5. package/dist/node_modules/recharts/es6/cartesian/ReferenceArea.js.map +1 -1
  6. package/dist/node_modules/recharts/es6/cartesian/ReferenceDot.js.map +1 -1
  7. package/dist/node_modules/recharts/es6/cartesian/ReferenceLine.js.map +1 -1
  8. package/dist/node_modules/recharts/es6/cartesian/XAxis.js.map +1 -1
  9. package/dist/node_modules/recharts/es6/cartesian/YAxis.js.map +1 -1
  10. package/dist/node_modules/recharts/es6/component/ResponsiveContainer.js.map +1 -1
  11. package/dist/node_modules/sonner/dist/index.js.map +1 -1
  12. package/dist/stories/fixtures/technospamFixtures.d.ts +1 -0
  13. package/dist/stories/fixtures/technospamFixtures.d.ts.map +1 -1
  14. package/dist/stories/journeys/Courses.stories.d.ts +5 -2
  15. package/dist/stories/journeys/Courses.stories.d.ts.map +1 -1
  16. package/dist/stories/journeys/Dashboard.stories.d.ts +2 -2
  17. package/dist/stories/journeys/Dashboard.stories.d.ts.map +1 -1
  18. package/dist/technospam/TechnoSpamRoutes.d.ts.map +1 -1
  19. package/dist/technospam/TechnoSpamRoutes.js +31 -27
  20. package/dist/technospam/TechnoSpamRoutes.js.map +1 -1
  21. package/dist/technospam/api/technospamApi.d.ts +101 -5
  22. package/dist/technospam/api/technospamApi.d.ts.map +1 -1
  23. package/dist/technospam/api/technospamApi.js +278 -146
  24. package/dist/technospam/api/technospamApi.js.map +1 -1
  25. package/dist/technospam/components/lesson/InteractiveWorkspace.d.ts +15 -0
  26. package/dist/technospam/components/lesson/InteractiveWorkspace.d.ts.map +1 -0
  27. package/dist/technospam/components/lesson/InteractiveWorkspace.js +198 -0
  28. package/dist/technospam/components/lesson/InteractiveWorkspace.js.map +1 -0
  29. package/dist/technospam/components/lesson/LessonKindFields.d.ts +15 -0
  30. package/dist/technospam/components/lesson/LessonKindFields.d.ts.map +1 -0
  31. package/dist/technospam/components/lesson/LessonKindFields.js +150 -0
  32. package/dist/technospam/components/lesson/LessonKindFields.js.map +1 -0
  33. package/dist/technospam/components/lesson/QuizLesson.d.ts +14 -0
  34. package/dist/technospam/components/lesson/QuizLesson.d.ts.map +1 -0
  35. package/dist/technospam/components/lesson/QuizLesson.js +105 -0
  36. package/dist/technospam/components/lesson/QuizLesson.js.map +1 -0
  37. package/dist/technospam/components/lesson/lessonAuthoring.d.ts +47 -0
  38. package/dist/technospam/components/lesson/lessonAuthoring.d.ts.map +1 -0
  39. package/dist/technospam/components/lesson/lessonAuthoring.js +80 -0
  40. package/dist/technospam/components/lesson/lessonAuthoring.js.map +1 -0
  41. package/dist/technospam/hooks/useTechnoSpamAnalytics.d.ts +1 -1
  42. package/dist/technospam/hooks/useTechnoSpamAnalytics.d.ts.map +1 -1
  43. package/dist/technospam/hooks/useTechnoSpamAnalytics.js.map +1 -1
  44. package/dist/technospam/pages/AdminAdminDashboardPagePage.d.ts.map +1 -1
  45. package/dist/technospam/pages/AdminAdminDashboardPagePage.js +230 -207
  46. package/dist/technospam/pages/AdminAdminDashboardPagePage.js.map +1 -1
  47. package/dist/technospam/pages/CoursesCourseDetailsPagePage.d.ts.map +1 -1
  48. package/dist/technospam/pages/CoursesCourseDetailsPagePage.js +130 -132
  49. package/dist/technospam/pages/CoursesCourseDetailsPagePage.js.map +1 -1
  50. package/dist/technospam/pages/CoursesLessonPlayerPagePage.d.ts +9 -0
  51. package/dist/technospam/pages/CoursesLessonPlayerPagePage.d.ts.map +1 -0
  52. package/dist/technospam/pages/CoursesLessonPlayerPagePage.js +291 -0
  53. package/dist/technospam/pages/CoursesLessonPlayerPagePage.js.map +1 -0
  54. package/dist/technospam/pages/CoursesMyLearningPagePage.d.ts.map +1 -1
  55. package/dist/technospam/pages/CoursesMyLearningPagePage.js +80 -78
  56. package/dist/technospam/pages/CoursesMyLearningPagePage.js.map +1 -1
  57. package/dist/technospam/pages/DashboardDashboardPagePage.d.ts.map +1 -1
  58. package/dist/technospam/pages/DashboardDashboardPagePage.js +136 -133
  59. package/dist/technospam/pages/DashboardDashboardPagePage.js.map +1 -1
  60. package/dist/technospam/utils/lessonPath.d.ts +15 -0
  61. package/dist/technospam/utils/lessonPath.d.ts.map +1 -0
  62. package/dist/technospam/utils/lessonPath.js +15 -0
  63. package/dist/technospam/utils/lessonPath.js.map +1 -0
  64. package/dist/technospam/utils/pageContext.d.ts.map +1 -1
  65. package/dist/technospam/utils/pageContext.js +10 -0
  66. package/dist/technospam/utils/pageContext.js.map +1 -1
  67. package/package.json +1 -1
@@ -1,21 +1,22 @@
1
- import { useTechnoSpam as e } from "../providers/TechnoSpamProvider.js";
2
- import { useTechnoSpamAnalytics as t } from "../hooks/useTechnoSpamAnalytics.js";
3
- import { cn as n } from "../utils/cn.js";
4
- import { PageLayout as r } from "../components/PageLayout.js";
5
- import { StatCard as i } from "../components/StatCard.js";
6
- import { MediaCover as a, topicIcon as o } from "../components/MediaCover.js";
7
- import { formatDate as s, formatDuration as c, humanizeEnum as l } from "../utils/format.js";
8
- import { EmptyView as u, ErrorView as ee } from "../components/StateViews.js";
9
- import { TagStrip as te } from "../components/TagStrip.js";
10
- import { PremiumBadge as ne, UpgradeGate as d } from "../components/UpgradeGate.js";
11
- import { notify as f } from "../lib/toast.js";
12
- import { useCourseQuery as re, useEnroll as ie, useIssueCertificate as p, useMyCertificatesQuery as m, useUpdateProgress as ae } from "../api/technospamApi.js";
1
+ import { useTechnoSpam as e, useTechnoSpamNavigate as t } from "../providers/TechnoSpamProvider.js";
2
+ import { useTechnoSpamAnalytics as n } from "../hooks/useTechnoSpamAnalytics.js";
3
+ import { cn as r } from "../utils/cn.js";
4
+ import { PageLayout as i } from "../components/PageLayout.js";
5
+ import { StatCard as a } from "../components/StatCard.js";
6
+ import { MediaCover as o, topicIcon as s } from "../components/MediaCover.js";
7
+ import { formatDate as c, formatDuration as l, humanizeEnum as u } from "../utils/format.js";
8
+ import { EmptyView as d, ErrorView as ee } from "../components/StateViews.js";
9
+ import { TagStrip as f } from "../components/TagStrip.js";
10
+ import { PremiumBadge as te, UpgradeGate as p } from "../components/UpgradeGate.js";
11
+ import { notify as m } from "../lib/toast.js";
12
+ import { useCourseQuery as ne, useEnroll as re, useIssueCertificate as ie, useMyCertificatesQuery as ae } from "../api/technospamApi.js";
13
13
  import "../components/index.js";
14
14
  import { FOCUS_PARAMS as oe } from "../utils/pageContext.js";
15
- import { useFocusedRecordParam as se } from "../hooks/useFocusedRecordParam.js";
16
- import { useEffect as h } from "react";
17
- import { Award as g, BookOpen as _, CheckCircle2 as v, ChevronDown as y, Clock as b, Eye as x, FileText as S, Layers as C, Lock as w, PlayCircle as T, ShieldCheck as E, Sparkles as D, TrendingUp as O, Trophy as k, Users as ce } from "lucide-react";
18
- import { useSearchParams as A } from "react-router";
15
+ import { lessonPlayerPath as se } from "../utils/lessonPath.js";
16
+ import { useFocusedRecordParam as ce } from "../hooks/useFocusedRecordParam.js";
17
+ import { useEffect as le } from "react";
18
+ import { ArrowRight as h, Award as g, BookOpen as _, CheckCircle2 as v, ChevronDown as y, Clock as b, Eye as x, FileText as S, Layers as C, Lock as w, PlayCircle as T, ShieldCheck as E, Sparkles as D, TrendingUp as O, Trophy as k, Users as A } from "lucide-react";
19
+ import { useSearchParams as ue } from "react-router";
19
20
  import { jsx as j, jsxs as M } from "react/jsx-runtime";
20
21
  import { Button as N, GlassCard as P, Skeleton as F } from "@burdenoff/fe-libs/ui";
21
22
  //#region src/technospam/pages/CoursesCourseDetailsPagePage.tsx
@@ -52,15 +53,15 @@ function L({ icon: e, children: t }) {
52
53
  children: [e ? /* @__PURE__ */ j(e, { size: 12 }) : null, t]
53
54
  });
54
55
  }
55
- function R({ lesson: e, index: t, done: r, open: i, onToggle: a }) {
56
- let o = I[e.kind] ?? I.ARTICLE, s = o.icon, u = `tec-lesson-body-${e.id}`;
56
+ function de({ lesson: e, index: t, done: n, open: i, onToggle: a, onStart: o }) {
57
+ let s = I[e.kind] ?? I.ARTICLE, c = s.icon, d = `tec-lesson-body-${e.id}`;
57
58
  return /* @__PURE__ */ M("div", {
58
59
  className: "border-b border-border-seam last:border-b-0",
59
60
  children: [/* @__PURE__ */ M("button", {
60
61
  type: "button",
61
62
  onClick: a,
62
63
  "aria-expanded": i,
63
- "aria-controls": u,
64
+ "aria-controls": d,
64
65
  className: "group flex w-full items-center gap-3 rounded-xl px-2 py-3 text-left transition-colors hover:bg-bg-sunken/60",
65
66
  children: [
66
67
  /* @__PURE__ */ j("span", {
@@ -68,8 +69,8 @@ function R({ lesson: e, index: t, done: r, open: i, onToggle: a }) {
68
69
  children: t + 1
69
70
  }),
70
71
  /* @__PURE__ */ j("span", {
71
- className: n("flex h-9 w-9 shrink-0 items-center justify-center rounded-lg", r ? "bg-status-success-bg-subtle text-status-success-text" : o.chip),
72
- children: j(r ? v : s, { size: 17 })
72
+ className: r("flex h-9 w-9 shrink-0 items-center justify-center rounded-lg", n ? "bg-status-success-bg-subtle text-status-success-text" : s.chip),
73
+ children: j(n ? v : c, { size: 17 })
73
74
  }),
74
75
  /* @__PURE__ */ M("div", {
75
76
  className: "min-w-0 flex-1",
@@ -79,21 +80,21 @@ function R({ lesson: e, index: t, done: r, open: i, onToggle: a }) {
79
80
  }), /* @__PURE__ */ M("div", {
80
81
  className: "mt-1 flex flex-wrap items-center gap-2",
81
82
  children: [/* @__PURE__ */ j("span", {
82
- className: n("inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] font-medium", o.badge),
83
- children: l(e.kind)
83
+ className: r("inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] font-medium", s.badge),
84
+ children: u(e.kind)
84
85
  }), /* @__PURE__ */ M("span", {
85
86
  className: "inline-flex items-center gap-1 text-xs text-text-muted",
86
87
  children: [
87
88
  /* @__PURE__ */ j(b, { size: 12 }),
88
89
  " ",
89
- c(e.estimatedMinutes)
90
+ l(e.estimatedMinutes)
90
91
  ]
91
92
  })]
92
93
  })]
93
94
  }),
94
95
  /* @__PURE__ */ M("div", {
95
96
  className: "flex shrink-0 items-center gap-2",
96
- children: [r ? /* @__PURE__ */ j(v, {
97
+ children: [n ? /* @__PURE__ */ j(v, {
97
98
  size: 18,
98
99
  className: "text-status-success-text"
99
100
  }) : e.isPreview ? /* @__PURE__ */ M("span", {
@@ -108,30 +109,39 @@ function R({ lesson: e, index: t, done: r, open: i, onToggle: a }) {
108
109
  }), /* @__PURE__ */ j(y, {
109
110
  size: 16,
110
111
  "aria-hidden": !0,
111
- className: n("text-text-muted transition-transform duration-200", i ? "rotate-180" : "")
112
+ className: r("text-text-muted transition-transform duration-200", i ? "rotate-180" : "")
112
113
  })]
113
114
  })
114
115
  ]
115
116
  }), i ? /* @__PURE__ */ j("div", {
116
- id: u,
117
+ id: d,
117
118
  className: "px-2 pb-4 sm:pl-11",
118
- children: e.isLocked ? /* @__PURE__ */ j(d, {
119
+ children: e.isLocked ? /* @__PURE__ */ j(p, {
119
120
  compact: !0,
120
121
  description: "This lesson is part of a paid TechnoSpam plan — its content unlocks once your workspace upgrades."
121
- }) : e.content ? /* @__PURE__ */ j("div", {
122
- className: "rounded-xl border border-border-seam bg-bg-sunken p-4",
123
- children: /* @__PURE__ */ j("p", {
124
- className: "whitespace-pre-wrap text-sm leading-relaxed text-text-secondary",
125
- children: e.content
126
- })
127
- }) : /* @__PURE__ */ j("p", {
128
- className: "rounded-xl border border-dashed border-border-seam px-4 py-3 text-sm text-text-muted",
129
- children: "No content published for this lesson yet."
122
+ }) : /* @__PURE__ */ M("div", {
123
+ className: "space-y-3",
124
+ children: [e.content ? /* @__PURE__ */ j("div", {
125
+ className: "rounded-xl border border-border-seam bg-bg-sunken p-4",
126
+ children: /* @__PURE__ */ j("p", {
127
+ className: "line-clamp-6 whitespace-pre-wrap text-sm leading-relaxed text-text-secondary",
128
+ children: e.content
129
+ })
130
+ }) : null, /* @__PURE__ */ M(N, {
131
+ size: "sm",
132
+ onClick: o,
133
+ "data-testid": `open-lesson-${e.id}`,
134
+ children: [
135
+ /* @__PURE__ */ j(T, { size: 15 }),
136
+ " ",
137
+ n ? "Review lesson" : "Start lesson"
138
+ ]
139
+ })]
130
140
  })
131
141
  }) : null]
132
142
  });
133
143
  }
134
- function z({ certificate: e, learnerName: t, courseTitle: n }) {
144
+ function fe({ certificate: e, learnerName: t, courseTitle: n }) {
135
145
  let r = e.status === "REVOKED";
136
146
  return /* @__PURE__ */ M(P, {
137
147
  className: "overflow-hidden p-0",
@@ -184,7 +194,7 @@ function z({ certificate: e, learnerName: t, courseTitle: n }) {
184
194
  children: "Issued on"
185
195
  }), /* @__PURE__ */ j("div", {
186
196
  className: "text-sm text-text-primary",
187
- children: s(e.issuedAt)
197
+ children: c(e.issuedAt)
188
198
  })] })
189
199
  ]
190
200
  }),
@@ -192,7 +202,7 @@ function z({ certificate: e, learnerName: t, courseTitle: n }) {
192
202
  className: "rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-left text-xs text-status-error-text",
193
203
  children: [
194
204
  "This certificate was revoked",
195
- e.revokedAt ? ` on ${s(e.revokedAt)}` : "",
205
+ e.revokedAt ? ` on ${c(e.revokedAt)}` : "",
196
206
  e.revokeReason ? ` — ${e.revokeReason}` : "."
197
207
  ]
198
208
  }) : /* @__PURE__ */ M("span", {
@@ -203,10 +213,10 @@ function z({ certificate: e, learnerName: t, courseTitle: n }) {
203
213
  })]
204
214
  });
205
215
  }
206
- function B() {
207
- let [s] = A(), y = s.get("id") ?? "", [x, T] = se(oe.lesson), { currentUser: E, workspaceId: D } = e(), { emit: I } = t(), { data: B, loading: V, error: H, refetch: U } = re(y);
208
- h(() => {
209
- y && I("technospam.course.viewed", {
216
+ function R() {
217
+ let [c] = ue(), y = c.get("id") ?? "", [x, T] = ce(oe.lesson), { currentUser: E, workspaceId: D } = e(), I = t(), { emit: R } = n(), { data: z, loading: B, error: V, refetch: pe } = ne(y);
218
+ le(() => {
219
+ y && R("technospam.course.viewed", {
210
220
  workspaceId: D,
211
221
  entityId: y,
212
222
  entityType: "TEC_COURSE"
@@ -214,109 +224,96 @@ function B() {
214
224
  }, [
215
225
  y,
216
226
  D,
217
- I
227
+ R
218
228
  ]);
219
- let [W, { loading: G }] = ie(), [le, { loading: ue }] = ae(), { data: de, refetch: fe } = m(y ? { courseId: y } : {}), [pe, { loading: K }] = p(), q = B?.tecCourse ?? null, J = [...q?.lessons ?? []].sort((e, t) => e.position - t.position), Y = (q?.enrollments ?? []).find((e) => e.learnerId === E?.id), X = de?.tecMyCertificates ?? [], Z = X.find((e) => e.status === "ISSUED") ?? X[0], me = !!Y && Y.progressPct >= 100, he = async () => {
220
- !y || !E?.id || (I("technospam.course.certificate_claimed", {
229
+ let [me, { loading: H }] = re(), { data: he, refetch: ge } = ae(y ? { courseId: y } : {}), [_e, { loading: U }] = ie(), W = z?.tecCourse ?? null, G = [...W?.lessons ?? []].sort((e, t) => e.position - t.position), K = (W?.enrollments ?? []).find((e) => e.learnerId === E?.id), q = he?.tecMyCertificates ?? [], J = q.find((e) => e.status === "ISSUED") ?? q[0], ve = !!K && K.progressPct >= 100, ye = async () => {
230
+ !y || !E?.id || (R("technospam.course.certificate_claimed", {
221
231
  workspaceId: D,
222
232
  entityId: y,
223
233
  entityType: "TEC_COURSE"
224
- }), (await pe({ variables: {
234
+ }), (await _e({ variables: {
225
235
  courseId: y,
226
236
  learnerId: E.id,
227
237
  score: 100
228
- } })).data?.tecIssueCertificate && (f.success("Certificate issued", "Your verifiable certificate is ready in My Learning."), await fe()));
229
- }, ge = async () => {
230
- y && (I("technospam.course.enroll_clicked", {
238
+ } })).data?.tecIssueCertificate && (m.success("Certificate issued", "Your verifiable certificate is ready in My Learning."), await ge()));
239
+ }, be = async () => {
240
+ y && (R("technospam.course.enroll_clicked", {
231
241
  workspaceId: D,
232
242
  entityId: y,
233
243
  entityType: "TEC_COURSE"
234
- }), (await W({ variables: { input: { courseId: y } } })).data?.tecEnroll && (I("technospam.course.enrolled", {
244
+ }), (await me({ variables: { input: { courseId: y } } })).data?.tecEnroll && (R("technospam.course.enrolled", {
235
245
  workspaceId: D,
236
246
  entityId: y,
237
247
  entityType: "TEC_COURSE"
238
- }), f.success("Enrolled", `You're enrolled in "${q?.title}".`), await U()));
239
- }, _e = async () => {
240
- if (!Y) return;
241
- let e = Math.min(J.length, Y.lessonsCompleted + 1), t = J.length ? Math.round(e / J.length * 100) : 100;
242
- (await le({ variables: { input: {
243
- enrollmentId: Y.id,
244
- lessonsCompleted: e,
245
- progressPct: t
246
- } } })).data?.tecUpdateProgress && (I("technospam.course.progress_updated", {
247
- workspaceId: D,
248
- entityId: Y.id,
249
- entityType: "TEC_ENROLLMENT",
250
- progressPct: t
251
- }), f.success("Progress saved", `${t}% complete`), await U());
248
+ }), m.success("Enrolled", `You're enrolled in "${W?.title}".`), await pe()));
252
249
  };
253
- if (V && !q) return /* @__PURE__ */ M(r, {
250
+ if (B && !W) return /* @__PURE__ */ M(i, {
254
251
  title: "Course",
255
252
  backPath: "/courses/courses-page",
256
253
  children: [/* @__PURE__ */ j(F, { className: "mb-4 h-40 w-full rounded-2xl" }), /* @__PURE__ */ j(F, { className: "h-64 w-full rounded-xl" })]
257
254
  });
258
- if (H || !q) return /* @__PURE__ */ j(r, {
255
+ if (V || !W) return /* @__PURE__ */ j(i, {
259
256
  title: "Course",
260
257
  backPath: "/courses/courses-page",
261
- children: H ? /* @__PURE__ */ j(ee, {
258
+ children: V ? /* @__PURE__ */ j(ee, {
262
259
  title: "Couldn't load course",
263
- error: H
264
- }) : /* @__PURE__ */ j(u, {
260
+ error: V
261
+ }) : /* @__PURE__ */ j(d, {
265
262
  title: "Course not found",
266
263
  description: "This course may have been unpublished."
267
264
  })
268
265
  });
269
- let Q = Y?.lessonsCompleted ?? 0, $ = Math.max(0, J.length - Q), ve = Y && Y.progressPct >= 100 ? "Course complete — claim your certificate below." : $ === 1 ? "1 lesson to go — almost there!" : `${$} lessons to go — keep it up!`, ye = `${q.topic ?? ""} ${q.title}`;
270
- return /* @__PURE__ */ M(r, {
266
+ let Y = K?.lessonsCompleted ?? 0, X = G.find((e) => !e.completedByMe) ?? G[0], Z = G.length > 0 && G.every((e) => e.completedByMe), Q = (e) => I(se(y, e)), $ = Math.max(0, G.length - Y), xe = K && K.progressPct >= 100 ? "Course complete — claim your certificate below." : $ === 1 ? "1 lesson to go — almost there!" : `${$} lessons to go — keep it up!`, Se = `${W.topic ?? ""} ${W.title}`;
267
+ return /* @__PURE__ */ M(i, {
271
268
  backPath: "/courses/courses-page",
272
- title: q.title,
273
- description: q.summary ?? void 0,
274
- actions: Y ? /* @__PURE__ */ M(N, {
275
- onClick: _e,
276
- disabled: ue || Q >= J.length,
277
- children: [/* @__PURE__ */ j(v, { size: 16 }), Q >= J.length ? "Completed" : "Complete next lesson"]
278
- }) : /* @__PURE__ */ M(N, {
279
- onClick: ge,
280
- disabled: G,
269
+ title: W.title,
270
+ description: W.summary ?? void 0,
271
+ actions: K ? X ? /* @__PURE__ */ M(N, {
272
+ onClick: () => Q(X.id),
273
+ "data-testid": "continue-learning",
274
+ children: [j(Z ? v : h, { size: 16 }), Z ? "Review course" : Y > 0 ? "Continue learning" : "Start course"]
275
+ }) : null : /* @__PURE__ */ M(N, {
276
+ onClick: be,
277
+ disabled: H,
281
278
  children: [
282
279
  /* @__PURE__ */ j(_, { size: 16 }),
283
280
  " ",
284
- G ? "Enrolling…" : "Enroll"
281
+ H ? "Enrolling…" : "Enroll"
285
282
  ]
286
283
  }),
287
284
  children: [
288
- /* @__PURE__ */ j(a, {
285
+ /* @__PURE__ */ j(o, {
289
286
  height: "h-40",
290
- seed: ye,
291
- icon: o(q.topic ?? q.title),
287
+ seed: Se,
288
+ icon: s(W.topic ?? W.title),
292
289
  className: "mb-5 rounded-2xl",
293
290
  children: /* @__PURE__ */ M("div", {
294
291
  className: "flex w-full flex-col gap-2",
295
292
  children: [
296
293
  /* @__PURE__ */ j("span", {
297
294
  className: "text-xs font-medium uppercase tracking-wide text-white/80",
298
- children: q.topic ?? "Course"
295
+ children: W.topic ?? "Course"
299
296
  }),
300
297
  /* @__PURE__ */ j("h2", {
301
298
  className: "text-2xl font-bold leading-tight text-white drop-shadow-sm sm:text-3xl",
302
- children: q.title
299
+ children: W.title
303
300
  }),
304
301
  /* @__PURE__ */ M("div", {
305
302
  className: "flex flex-wrap items-center gap-2",
306
303
  children: [
307
304
  /* @__PURE__ */ j(L, {
308
305
  icon: O,
309
- children: l(q.level)
306
+ children: u(W.level)
310
307
  }),
311
308
  /* @__PURE__ */ j(L, {
312
309
  icon: v,
313
- children: l(q.status)
310
+ children: u(W.status)
314
311
  }),
315
- q.topic ? /* @__PURE__ */ j(L, {
312
+ W.topic ? /* @__PURE__ */ j(L, {
316
313
  icon: C,
317
- children: q.topic
314
+ children: W.topic
318
315
  }) : null,
319
- q.isPremiumOnly ? /* @__PURE__ */ j(L, {
316
+ W.isPremiumOnly ? /* @__PURE__ */ j(L, {
320
317
  icon: w,
321
318
  children: "Premium"
322
319
  }) : null
@@ -325,40 +322,40 @@ function B() {
325
322
  ]
326
323
  })
327
324
  }),
328
- /* @__PURE__ */ j(te, {
329
- tags: q.tags,
325
+ /* @__PURE__ */ j(f, {
326
+ tags: W.tags,
330
327
  className: "mb-5"
331
328
  }),
332
329
  /* @__PURE__ */ M("div", {
333
330
  className: "mb-6 grid grid-cols-2 gap-3 sm:grid-cols-4",
334
331
  children: [
335
- /* @__PURE__ */ j(i, {
332
+ /* @__PURE__ */ j(a, {
336
333
  label: "Lessons",
337
- value: J.length,
334
+ value: G.length,
338
335
  icon: S,
339
336
  tone: "blue"
340
337
  }),
341
- /* @__PURE__ */ j(i, {
338
+ /* @__PURE__ */ j(a, {
342
339
  label: "Duration",
343
- value: c(q.estimatedMinutes),
340
+ value: l(W.estimatedMinutes),
344
341
  icon: b,
345
342
  tone: "teal"
346
343
  }),
347
- /* @__PURE__ */ j(i, {
344
+ /* @__PURE__ */ j(a, {
348
345
  label: "Enrolled",
349
- value: q.enrollments?.length ?? 0,
350
- icon: ce,
346
+ value: W.enrollments?.length ?? 0,
347
+ icon: A,
351
348
  tone: "indigo"
352
349
  }),
353
- /* @__PURE__ */ j(i, {
350
+ /* @__PURE__ */ j(a, {
354
351
  label: "Your progress",
355
- value: Y ? `${Y.progressPct}%` : "Not started",
352
+ value: K ? `${K.progressPct}%` : "Not started",
356
353
  icon: O,
357
354
  tone: "purple"
358
355
  })
359
356
  ]
360
357
  }),
361
- Y ? /* @__PURE__ */ M(P, {
358
+ K ? /* @__PURE__ */ M(P, {
362
359
  className: "mb-6 p-5",
363
360
  children: [
364
361
  /* @__PURE__ */ M("div", {
@@ -375,11 +372,11 @@ function B() {
375
372
  /* @__PURE__ */ M("span", {
376
373
  className: "ml-auto text-sm text-text-secondary",
377
374
  children: [
378
- Q,
375
+ Y,
379
376
  "/",
380
- J.length,
377
+ G.length,
381
378
  " lessons · ",
382
- Y.progressPct,
379
+ K.progressPct,
383
380
  "%"
384
381
  ]
385
382
  })
@@ -389,19 +386,19 @@ function B() {
389
386
  className: "h-2.5 w-full overflow-hidden rounded-full bg-bg-sunken",
390
387
  children: /* @__PURE__ */ j("div", {
391
388
  className: "h-full rounded-full bg-gradient-to-r from-accent-primary via-accent-indigo to-accent-purple transition-all duration-500",
392
- style: { width: `${Y.progressPct}%` }
389
+ style: { width: `${K.progressPct}%` }
393
390
  })
394
391
  }),
395
392
  /* @__PURE__ */ j("p", {
396
393
  className: "mt-2 text-xs text-text-muted",
397
- children: ve
394
+ children: xe
398
395
  })
399
396
  ]
400
397
  }) : null,
401
- Z ? /* @__PURE__ */ M("div", {
398
+ J ? /* @__PURE__ */ M("div", {
402
399
  className: "mb-6 grid grid-cols-1 gap-4 lg:grid-cols-2",
403
400
  children: [/* @__PURE__ */ M(P, {
404
- className: n("flex items-center gap-4 border p-5", Z.status === "REVOKED" ? "border-status-error-border/60 bg-status-error-bg-subtle/20" : "border-status-success-border/60 bg-status-success-bg-subtle/30"),
401
+ className: r("flex items-center gap-4 border p-5", J.status === "REVOKED" ? "border-status-error-border/60 bg-status-error-bg-subtle/20" : "border-status-success-border/60 bg-status-success-bg-subtle/30"),
405
402
  children: [/* @__PURE__ */ j("span", {
406
403
  className: "flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl bg-status-warning-bg-subtle text-status-warning-text ring-1 ring-status-warning-border/40",
407
404
  children: /* @__PURE__ */ j(k, { size: 26 })
@@ -409,18 +406,18 @@ function B() {
409
406
  className: "min-w-0",
410
407
  children: [/* @__PURE__ */ j("div", {
411
408
  className: "text-base font-semibold text-text-primary",
412
- children: Z.status === "REVOKED" ? "Your certificate was revoked" : "You finished this course"
409
+ children: J.status === "REVOKED" ? "Your certificate was revoked" : "You finished this course"
413
410
  }), /* @__PURE__ */ j("div", {
414
411
  className: "text-sm text-text-muted",
415
- children: Z.status === "REVOKED" ? "Contact a workspace admin if you believe this was a mistake." : "Your verifiable certificate of completion is issued — it also appears in My Learning."
412
+ children: J.status === "REVOKED" ? "Contact a workspace admin if you believe this was a mistake." : "Your verifiable certificate of completion is issued — it also appears in My Learning."
416
413
  })]
417
414
  })]
418
- }), /* @__PURE__ */ j(z, {
419
- certificate: Z,
415
+ }), /* @__PURE__ */ j(fe, {
416
+ certificate: J,
420
417
  learnerName: E?.name ?? void 0,
421
- courseTitle: Z.course?.title ?? q.title
418
+ courseTitle: J.course?.title ?? W.title
422
419
  })]
423
- }) : me ? /* @__PURE__ */ M(P, {
420
+ }) : ve ? /* @__PURE__ */ M(P, {
424
421
  className: "mb-6 flex flex-col items-start gap-4 border border-status-success-border/60 bg-status-success-bg-subtle/40 p-5 sm:flex-row sm:items-center sm:justify-between",
425
422
  children: [/* @__PURE__ */ M("div", {
426
423
  className: "flex items-center gap-4",
@@ -435,12 +432,12 @@ function B() {
435
432
  children: "Claim your verifiable certificate of completion."
436
433
  })] })]
437
434
  }), /* @__PURE__ */ M(N, {
438
- onClick: he,
439
- disabled: K,
435
+ onClick: ye,
436
+ disabled: U,
440
437
  children: [
441
438
  /* @__PURE__ */ j(g, { size: 16 }),
442
439
  " ",
443
- K ? "Issuing…" : "Claim certificate"
440
+ U ? "Issuing…" : "Claim certificate"
444
441
  ]
445
442
  })]
446
443
  }) : null,
@@ -457,36 +454,37 @@ function B() {
457
454
  className: "text-accent-primary"
458
455
  }),
459
456
  " Curriculum",
460
- q.isPremiumOnly ? /* @__PURE__ */ j(ne, { locked: q.isLocked }) : null
457
+ W.isPremiumOnly ? /* @__PURE__ */ j(te, { locked: W.isLocked }) : null
461
458
  ]
462
- }), J.length ? /* @__PURE__ */ M("span", {
459
+ }), G.length ? /* @__PURE__ */ M("span", {
463
460
  className: "rounded-full bg-status-success-bg-subtle px-2.5 py-1 text-xs font-medium text-status-success-text",
464
461
  children: [
465
- Q,
462
+ Y,
466
463
  "/",
467
- J.length,
464
+ G.length,
468
465
  " completed"
469
466
  ]
470
467
  }) : null]
471
468
  }),
472
- q.isLocked ? /* @__PURE__ */ j("div", {
469
+ W.isLocked ? /* @__PURE__ */ j("div", {
473
470
  className: "mb-4",
474
- children: /* @__PURE__ */ j(d, {
471
+ children: /* @__PURE__ */ j(p, {
475
472
  compact: !0,
476
473
  description: "This course is on a paid TechnoSpam plan. Preview lessons below stay free — the rest unlock once your workspace upgrades."
477
474
  })
478
475
  }) : null,
479
- J.length === 0 ? /* @__PURE__ */ j("p", {
476
+ G.length === 0 ? /* @__PURE__ */ j("p", {
480
477
  className: "py-6 text-center text-sm text-text-muted",
481
478
  children: "Lessons for this course are being prepared."
482
479
  }) : /* @__PURE__ */ j("div", {
483
480
  className: "flex flex-col",
484
- children: J.map((e, t) => /* @__PURE__ */ j(R, {
481
+ children: G.map((e, t) => /* @__PURE__ */ j(de, {
485
482
  lesson: e,
486
483
  index: t,
487
- done: t < Q,
484
+ done: !!e.completedByMe,
488
485
  open: x === e.id,
489
- onToggle: () => T(x === e.id ? null : e.id)
486
+ onToggle: () => T(x === e.id ? null : e.id),
487
+ onStart: () => Q(e.id)
490
488
  }, e.id))
491
489
  })
492
490
  ]
@@ -495,6 +493,6 @@ function B() {
495
493
  });
496
494
  }
497
495
  //#endregion
498
- export { B as CoursesCourseDetailsPagePage };
496
+ export { R as CoursesCourseDetailsPagePage };
499
497
 
500
498
  //# sourceMappingURL=CoursesCourseDetailsPagePage.js.map