@burdenoff/microfe-technospam 2026.801.1 → 2026.827.1

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