@burdenoff/microfe-technospam 2026.1101.1 → 2026.1101.2

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