@burdenoff/microfe-technospam 2026.1031.6 → 2026.1031.8

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