@burdenoff/microfe-buildmyiq 2026.705.13 → 2026.706.10
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.
- package/dist/buildmyiq/BuildmyiqRoot.d.ts.map +1 -1
- package/dist/buildmyiq/BuildmyiqRoot.js +57 -49
- package/dist/buildmyiq/BuildmyiqRoot.js.map +1 -1
- package/dist/buildmyiq/BuildmyiqRoutes.d.ts.map +1 -1
- package/dist/buildmyiq/BuildmyiqRoutes.js +15 -11
- package/dist/buildmyiq/BuildmyiqRoutes.js.map +1 -1
- package/dist/buildmyiq/components/Avatar.d.ts +15 -0
- package/dist/buildmyiq/components/Avatar.d.ts.map +1 -0
- package/dist/buildmyiq/components/Avatar.js +42 -0
- package/dist/buildmyiq/components/Avatar.js.map +1 -0
- package/dist/buildmyiq/components/Viz.d.ts +25 -0
- package/dist/buildmyiq/components/Viz.d.ts.map +1 -0
- package/dist/buildmyiq/components/Viz.js +78 -0
- package/dist/buildmyiq/components/Viz.js.map +1 -0
- package/dist/buildmyiq/components/index.d.ts +2 -0
- package/dist/buildmyiq/components/index.d.ts.map +1 -1
- package/dist/buildmyiq/components/index.js +2 -0
- package/dist/buildmyiq/pages/DashboardPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/DashboardPage.js +200 -98
- package/dist/buildmyiq/pages/DashboardPage.js.map +1 -1
- package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.js +262 -241
- package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.js.map +1 -1
- package/dist/buildmyiq/pages/assessments/AssessmentsPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/assessments/AssessmentsPage.js +142 -115
- package/dist/buildmyiq/pages/assessments/AssessmentsPage.js.map +1 -1
- package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.js +220 -156
- package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.js.map +1 -1
- package/dist/buildmyiq/pages/authoring/AuthoringPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/authoring/AuthoringPage.js +51 -46
- package/dist/buildmyiq/pages/authoring/AuthoringPage.js.map +1 -1
- package/dist/buildmyiq/pages/authoring/CourseBuilderPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/authoring/CourseBuilderPage.js +581 -448
- package/dist/buildmyiq/pages/authoring/CourseBuilderPage.js.map +1 -1
- package/dist/buildmyiq/pages/catalog/CatalogPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/catalog/CatalogPage.js +52 -42
- package/dist/buildmyiq/pages/catalog/CatalogPage.js.map +1 -1
- package/dist/buildmyiq/pages/catalog/CourseDetailPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/catalog/CourseDetailPage.js +422 -301
- package/dist/buildmyiq/pages/catalog/CourseDetailPage.js.map +1 -1
- package/dist/buildmyiq/pages/certificates/CertificatesPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/certificates/CertificatesPage.js +237 -151
- package/dist/buildmyiq/pages/certificates/CertificatesPage.js.map +1 -1
- package/dist/buildmyiq/pages/cohorts/CohortsPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/cohorts/CohortsPage.js +219 -138
- package/dist/buildmyiq/pages/cohorts/CohortsPage.js.map +1 -1
- package/dist/buildmyiq/pages/insights/InsightsPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/insights/InsightsPage.js +276 -152
- package/dist/buildmyiq/pages/insights/InsightsPage.js.map +1 -1
- package/dist/buildmyiq/pages/learning/LessonPlayerPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/learning/LessonPlayerPage.js +237 -174
- package/dist/buildmyiq/pages/learning/LessonPlayerPage.js.map +1 -1
- package/dist/buildmyiq/pages/learning/MyLearningPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/learning/MyLearningPage.js +307 -169
- package/dist/buildmyiq/pages/learning/MyLearningPage.js.map +1 -1
- package/dist/buildmyiq/pages/paths/PathsPage.d.ts +4 -0
- package/dist/buildmyiq/pages/paths/PathsPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/paths/PathsPage.js +187 -0
- package/dist/buildmyiq/pages/paths/PathsPage.js.map +1 -0
- package/dist/buildmyiq/pages/skills/SkillsPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/skills/SkillsPage.js +233 -140
- package/dist/buildmyiq/pages/skills/SkillsPage.js.map +1 -1
- package/dist/buildmyiq/pages/submissions/SubmissionsPage.d.ts.map +1 -1
- package/dist/buildmyiq/pages/submissions/SubmissionsPage.js +379 -275
- package/dist/buildmyiq/pages/submissions/SubmissionsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,38 +1,61 @@
|
|
|
1
1
|
import { useBuildmyiq as e } from "../../context/BuildmyiqContext.js";
|
|
2
2
|
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { MetricsCard as n } from "../../components/MetricsCard.js";
|
|
4
|
+
import { formatDate as r, formatPercent as ee } from "../../utils/formatters.js";
|
|
5
|
+
import { StatusBadge as te } from "../../components/StatusBadge.js";
|
|
6
|
+
import { EmptyState as ne } from "../../components/EmptyState.js";
|
|
7
|
+
import { ErrorView as re, LoadingView as i } from "../../components/StateViews.js";
|
|
8
|
+
import { DataTable as ie } from "../../components/DataTable.js";
|
|
9
|
+
import { FilterTabs as ae } from "../../components/FilterTabs.js";
|
|
10
|
+
import { Pagination as oe } from "../../components/Pagination.js";
|
|
11
|
+
import { Avatar as se } from "../../components/Avatar.js";
|
|
9
12
|
import "../../context/index.js";
|
|
10
|
-
import { useBuiCertificates as
|
|
13
|
+
import { useBuiCertificates as ce, useBuiCourses as le, useBuiIssueCertificate as ue, useBuiRevokeCertificate as de } from "../../hooks/useBuildmyiqApi.js";
|
|
11
14
|
import "../../hooks/index.js";
|
|
12
|
-
import { FileLink as
|
|
15
|
+
import { FileLink as fe } from "../../components/FileLink.js";
|
|
13
16
|
import "../../components/index.js";
|
|
14
|
-
import { useMemo as
|
|
15
|
-
import { Award as
|
|
16
|
-
import { jsx as
|
|
17
|
-
import { Button as
|
|
17
|
+
import { useMemo as a, useState as o } from "react";
|
|
18
|
+
import { Award as s, Ban as c, CalendarClock as pe, Download as me, Plus as l, Search as he, ShieldCheck as ge } from "lucide-react";
|
|
19
|
+
import { Fragment as _e, jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
20
|
+
import { Button as f, Input as p, Label as m, ResponsiveDialog as ve, ResponsiveDialogContent as ye, ResponsiveDialogDescription as be, ResponsiveDialogFooter as xe, ResponsiveDialogHeader as Se, ResponsiveDialogTitle as Ce, Select as h, SelectContent as g, SelectItem as _, SelectTrigger as v, SelectValue as y } from "@burdenoff/fe-libs/ui";
|
|
18
21
|
//#region src/buildmyiq/pages/certificates/CertificatesPage.tsx
|
|
19
|
-
var
|
|
22
|
+
var b = 8, we = (e) => {
|
|
20
23
|
let t = e.trim();
|
|
21
24
|
if (!t) return;
|
|
22
25
|
let n = new Date(t);
|
|
23
26
|
return Number.isNaN(n.getTime()) ? void 0 : n.toISOString();
|
|
24
|
-
},
|
|
25
|
-
let { currentUser:
|
|
27
|
+
}, Te = () => `BMIQ-${Date.now().toString(36).toUpperCase()}`, x = () => {
|
|
28
|
+
let { currentUser: x } = e(), S = x?.id, [C, Ee] = o(S ? "MINE" : "ALL"), [w, T] = o("ALL"), [E, D] = o(""), [De, O] = o(0), [Oe, k] = o(!1), [A, j] = o(null), [M, N] = o(null), [P, F] = o(null), I = () => ({
|
|
26
29
|
courseId: "",
|
|
27
|
-
learnerId:
|
|
28
|
-
serial:
|
|
30
|
+
learnerId: S ?? "",
|
|
31
|
+
serial: Te(),
|
|
29
32
|
finalScore: "",
|
|
30
33
|
expiresAt: ""
|
|
31
|
-
}), [
|
|
34
|
+
}), [L, R] = o(I), z = le({ limit: 100 }), B = a(() => z.data?.items ?? [], [z.data]), V = a(() => {
|
|
32
35
|
let e = /* @__PURE__ */ new Map();
|
|
33
|
-
for (let t of
|
|
36
|
+
for (let t of B) e.set(t.id, t.title);
|
|
34
37
|
return e;
|
|
35
|
-
}, [
|
|
38
|
+
}, [B]), H = ce(w === "ALL" ? void 0 : w, C === "MINE" ? S : void 0), U = ue(), ke = de(), W = a(() => H.data ?? [], [H.data]), G = a(() => {
|
|
39
|
+
let e = E.trim().toLowerCase();
|
|
40
|
+
return e ? W.filter((t) => {
|
|
41
|
+
let n = (V.get(t.courseId) ?? "").toLowerCase(), r = t.learnerId === S ? "you me mine" : t.learnerId.toLowerCase();
|
|
42
|
+
return t.serial.toLowerCase().includes(e) || n.includes(e) || r.includes(e);
|
|
43
|
+
}) : W;
|
|
44
|
+
}, [
|
|
45
|
+
W,
|
|
46
|
+
E,
|
|
47
|
+
V,
|
|
48
|
+
S
|
|
49
|
+
]), K = a(() => {
|
|
50
|
+
let e = 0, t = 0, n = 0;
|
|
51
|
+
for (let r of W) r.status === "ISSUED" ? e += 1 : r.status === "EXPIRED" ? t += 1 : r.status === "REVOKED" && (n += 1);
|
|
52
|
+
return {
|
|
53
|
+
total: W.length,
|
|
54
|
+
issued: e,
|
|
55
|
+
expired: t,
|
|
56
|
+
revoked: n
|
|
57
|
+
};
|
|
58
|
+
}, [W]), Ae = Math.max(1, Math.ceil(G.length / b)), q = Math.min(De, Ae - 1), J = a(() => G.slice(q * b, q * b + b), [G, q]), je = [{
|
|
36
59
|
value: "MINE",
|
|
37
60
|
label: "Mine"
|
|
38
61
|
}, {
|
|
@@ -40,26 +63,26 @@ var le = (e) => {
|
|
|
40
63
|
label: "All"
|
|
41
64
|
}], Y = async (e) => {
|
|
42
65
|
if (!(typeof window < "u" && !window.confirm(`Revoke certificate ${e.serial}? This cannot be undone.`))) {
|
|
43
|
-
|
|
66
|
+
N(null), F(e.id);
|
|
44
67
|
try {
|
|
45
|
-
await
|
|
68
|
+
await ke.mutateAsync(e.id);
|
|
46
69
|
} catch (e) {
|
|
47
|
-
|
|
70
|
+
N(e instanceof Error ? e.message : "Failed to revoke certificate.");
|
|
48
71
|
} finally {
|
|
49
|
-
|
|
72
|
+
F(null);
|
|
50
73
|
}
|
|
51
74
|
}
|
|
52
|
-
},
|
|
75
|
+
}, Me = [
|
|
53
76
|
{
|
|
54
77
|
key: "serial",
|
|
55
78
|
header: "Serial",
|
|
56
79
|
sortValue: (e) => e.serial.toLowerCase(),
|
|
57
|
-
render: (e) => /* @__PURE__ */
|
|
80
|
+
render: (e) => /* @__PURE__ */ d("div", {
|
|
58
81
|
className: "flex items-center gap-3",
|
|
59
|
-
children: [/* @__PURE__ */
|
|
82
|
+
children: [/* @__PURE__ */ u("div", {
|
|
60
83
|
className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-[var(--color-accent-primary)]",
|
|
61
|
-
children: /* @__PURE__ */
|
|
62
|
-
}), /* @__PURE__ */
|
|
84
|
+
children: /* @__PURE__ */ u(s, { className: "h-4 w-4" })
|
|
85
|
+
}), /* @__PURE__ */ u("span", {
|
|
63
86
|
className: "min-w-0 truncate font-mono text-xs font-semibold text-text-primary",
|
|
64
87
|
children: e.serial
|
|
65
88
|
})]
|
|
@@ -68,39 +91,49 @@ var le = (e) => {
|
|
|
68
91
|
{
|
|
69
92
|
key: "course",
|
|
70
93
|
header: "Course",
|
|
71
|
-
|
|
72
|
-
|
|
94
|
+
hideOnMobile: !0,
|
|
95
|
+
sortValue: (e) => (V.get(e.courseId) ?? "").toLowerCase(),
|
|
96
|
+
render: (e) => /* @__PURE__ */ u("span", {
|
|
73
97
|
className: "text-text-secondary",
|
|
74
|
-
children:
|
|
98
|
+
children: V.get(e.courseId) ?? "—"
|
|
75
99
|
})
|
|
76
100
|
},
|
|
77
101
|
{
|
|
78
102
|
key: "learner",
|
|
79
103
|
header: "Learner",
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
104
|
+
sortValue: (e) => e.learnerId === S ? "" : e.learnerId,
|
|
105
|
+
render: (e) => {
|
|
106
|
+
let t = e.learnerId === S, n = t ? x?.name ?? x?.username ?? x?.email ?? null : null;
|
|
107
|
+
return /* @__PURE__ */ d("div", {
|
|
108
|
+
className: "flex items-center gap-2.5",
|
|
109
|
+
children: [/* @__PURE__ */ u(se, {
|
|
110
|
+
size: "sm",
|
|
111
|
+
seed: e.learnerId,
|
|
112
|
+
name: n
|
|
113
|
+
}), t ? /* @__PURE__ */ u("span", {
|
|
114
|
+
className: "font-medium text-text-primary",
|
|
115
|
+
children: "You"
|
|
116
|
+
}) : /* @__PURE__ */ d("span", {
|
|
117
|
+
className: "font-mono text-xs text-text-tertiary",
|
|
118
|
+
title: e.learnerId,
|
|
119
|
+
children: [e.learnerId.slice(0, 8), "…"]
|
|
120
|
+
})]
|
|
121
|
+
});
|
|
122
|
+
}
|
|
90
123
|
},
|
|
91
124
|
{
|
|
92
125
|
key: "status",
|
|
93
126
|
header: "Status",
|
|
94
|
-
render: (e) => /* @__PURE__ */
|
|
127
|
+
render: (e) => /* @__PURE__ */ u(te, { status: e.status })
|
|
95
128
|
},
|
|
96
129
|
{
|
|
97
130
|
key: "issuedAt",
|
|
98
131
|
header: "Issued",
|
|
99
132
|
hideOnMobile: !0,
|
|
100
133
|
sortValue: (e) => e.issuedAt,
|
|
101
|
-
render: (e) => /* @__PURE__ */
|
|
134
|
+
render: (e) => /* @__PURE__ */ u("span", {
|
|
102
135
|
className: "text-text-secondary",
|
|
103
|
-
children:
|
|
136
|
+
children: r(e.issuedAt)
|
|
104
137
|
})
|
|
105
138
|
},
|
|
106
139
|
{
|
|
@@ -108,9 +141,9 @@ var le = (e) => {
|
|
|
108
141
|
header: "Expires",
|
|
109
142
|
hideOnMobile: !0,
|
|
110
143
|
sortValue: (e) => e.expiresAt ?? "",
|
|
111
|
-
render: (e) => /* @__PURE__ */
|
|
144
|
+
render: (e) => /* @__PURE__ */ u("span", {
|
|
112
145
|
className: "text-text-tertiary",
|
|
113
|
-
children:
|
|
146
|
+
children: r(e.expiresAt)
|
|
114
147
|
})
|
|
115
148
|
},
|
|
116
149
|
{
|
|
@@ -119,16 +152,16 @@ var le = (e) => {
|
|
|
119
152
|
align: "right",
|
|
120
153
|
hideOnMobile: !0,
|
|
121
154
|
sortValue: (e) => e.finalScore ?? -1,
|
|
122
|
-
render: (e) => /* @__PURE__ */
|
|
123
|
-
className: "tabular-nums text-text-
|
|
124
|
-
children: e.finalScore
|
|
155
|
+
render: (e) => /* @__PURE__ */ u("span", {
|
|
156
|
+
className: "font-medium tabular-nums text-text-primary",
|
|
157
|
+
children: e.finalScore == null ? "—" : ee(e.finalScore)
|
|
125
158
|
})
|
|
126
159
|
},
|
|
127
160
|
{
|
|
128
161
|
key: "file",
|
|
129
|
-
header: "
|
|
162
|
+
header: "PDF",
|
|
130
163
|
hideOnMobile: !0,
|
|
131
|
-
render: (e) => e.file ? /* @__PURE__ */
|
|
164
|
+
render: (e) => e.file ? /* @__PURE__ */ u(fe, { fileId: e.file.id }) : /* @__PURE__ */ u("span", {
|
|
132
165
|
className: "text-text-tertiary",
|
|
133
166
|
children: "—"
|
|
134
167
|
})
|
|
@@ -137,220 +170,273 @@ var le = (e) => {
|
|
|
137
170
|
key: "actions",
|
|
138
171
|
header: "",
|
|
139
172
|
align: "right",
|
|
140
|
-
render: (e) => e.status === "ISSUED" ? /* @__PURE__ */
|
|
173
|
+
render: (e) => e.status === "ISSUED" ? /* @__PURE__ */ d(f, {
|
|
141
174
|
variant: "ghost",
|
|
142
175
|
size: "sm",
|
|
143
176
|
className: "text-status-error-text hover:text-status-error-text",
|
|
144
|
-
disabled:
|
|
177
|
+
disabled: P === e.id,
|
|
145
178
|
onClick: () => void Y(e),
|
|
146
|
-
children: [/* @__PURE__ */
|
|
179
|
+
children: [/* @__PURE__ */ u(c, { className: "mr-1.5 h-4 w-4" }), P === e.id ? "Revoking…" : "Revoke"]
|
|
147
180
|
}) : null
|
|
148
181
|
}
|
|
149
182
|
], X = () => {
|
|
150
|
-
|
|
183
|
+
R(I()), j(null), k(!0);
|
|
151
184
|
}, Z = () => {
|
|
152
|
-
|
|
153
|
-
},
|
|
154
|
-
if (!
|
|
155
|
-
|
|
185
|
+
k(!1), R(I()), j(null);
|
|
186
|
+
}, Ne = async () => {
|
|
187
|
+
if (!L.courseId) {
|
|
188
|
+
j("Please choose a course for this certificate.");
|
|
156
189
|
return;
|
|
157
190
|
}
|
|
158
|
-
if (!
|
|
159
|
-
|
|
191
|
+
if (!L.learnerId.trim()) {
|
|
192
|
+
j("A learner (user ID) is required.");
|
|
160
193
|
return;
|
|
161
194
|
}
|
|
162
|
-
if (!
|
|
163
|
-
|
|
195
|
+
if (!L.serial.trim()) {
|
|
196
|
+
j("A certificate serial is required.");
|
|
164
197
|
return;
|
|
165
198
|
}
|
|
166
|
-
let e =
|
|
199
|
+
let e = L.finalScore.trim() ? Number(L.finalScore) : void 0;
|
|
167
200
|
if (e !== void 0 && (!Number.isFinite(e) || e < 0)) {
|
|
168
|
-
|
|
201
|
+
j("Final score must be a non-negative number.");
|
|
169
202
|
return;
|
|
170
203
|
}
|
|
171
|
-
let t =
|
|
172
|
-
|
|
204
|
+
let t = we(L.expiresAt);
|
|
205
|
+
j(null);
|
|
173
206
|
try {
|
|
174
|
-
await
|
|
175
|
-
courseId:
|
|
176
|
-
learnerId:
|
|
177
|
-
serial:
|
|
207
|
+
await U.mutateAsync({
|
|
208
|
+
courseId: L.courseId,
|
|
209
|
+
learnerId: L.learnerId.trim(),
|
|
210
|
+
serial: L.serial.trim(),
|
|
178
211
|
finalScore: e,
|
|
179
212
|
expiresAt: t
|
|
180
213
|
}), Z();
|
|
181
214
|
} catch (e) {
|
|
182
|
-
|
|
215
|
+
j(e instanceof Error ? e.message : "Failed to issue certificate.");
|
|
183
216
|
}
|
|
184
|
-
}, Q =
|
|
185
|
-
return /* @__PURE__ */
|
|
217
|
+
}, Q = B.length > 0, $ = C === "MINE" || w !== "ALL" || E.trim().length > 0, Pe = !H.isLoading && !H.isError && K.total > 0;
|
|
218
|
+
return /* @__PURE__ */ d(t, {
|
|
186
219
|
title: "Certificates",
|
|
187
220
|
description: "Verifiable credentials issued to learners on course completion.",
|
|
188
221
|
titleGradient: !0,
|
|
189
222
|
aurora: !0,
|
|
190
|
-
actions: /* @__PURE__ */
|
|
223
|
+
actions: /* @__PURE__ */ d(f, {
|
|
191
224
|
onClick: X,
|
|
192
225
|
disabled: !Q,
|
|
193
|
-
children: [/* @__PURE__ */
|
|
226
|
+
children: [/* @__PURE__ */ u(l, { className: "mr-1.5 h-4 w-4" }), " Issue certificate"]
|
|
194
227
|
}),
|
|
195
228
|
children: [
|
|
196
|
-
/* @__PURE__ */
|
|
229
|
+
Pe && /* @__PURE__ */ d("div", {
|
|
230
|
+
className: "mb-5 grid grid-cols-2 gap-4 sm:grid-cols-4",
|
|
231
|
+
children: [
|
|
232
|
+
/* @__PURE__ */ u(n, {
|
|
233
|
+
icon: /* @__PURE__ */ u(s, { className: "h-5 w-5" }),
|
|
234
|
+
value: K.total,
|
|
235
|
+
label: "Certificates",
|
|
236
|
+
featured: !0
|
|
237
|
+
}),
|
|
238
|
+
/* @__PURE__ */ u(n, {
|
|
239
|
+
icon: /* @__PURE__ */ u(ge, { className: "h-5 w-5" }),
|
|
240
|
+
value: K.issued,
|
|
241
|
+
label: "Issued",
|
|
242
|
+
accent: "success"
|
|
243
|
+
}),
|
|
244
|
+
/* @__PURE__ */ u(n, {
|
|
245
|
+
icon: /* @__PURE__ */ u(pe, { className: "h-5 w-5" }),
|
|
246
|
+
value: K.expired,
|
|
247
|
+
label: "Expired"
|
|
248
|
+
}),
|
|
249
|
+
/* @__PURE__ */ u(n, {
|
|
250
|
+
icon: /* @__PURE__ */ u(c, { className: "h-5 w-5" }),
|
|
251
|
+
value: K.revoked,
|
|
252
|
+
label: "Revoked",
|
|
253
|
+
accent: "error"
|
|
254
|
+
})
|
|
255
|
+
]
|
|
256
|
+
}),
|
|
257
|
+
/* @__PURE__ */ d("div", {
|
|
197
258
|
className: "mb-5 flex flex-wrap items-center gap-3",
|
|
198
|
-
children: [
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
children:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
259
|
+
children: [
|
|
260
|
+
/* @__PURE__ */ u(ae, {
|
|
261
|
+
options: je,
|
|
262
|
+
value: C,
|
|
263
|
+
onChange: (e) => {
|
|
264
|
+
Ee(e), O(0);
|
|
265
|
+
}
|
|
266
|
+
}),
|
|
267
|
+
/* @__PURE__ */ d(h, {
|
|
268
|
+
value: w,
|
|
269
|
+
onValueChange: (e) => {
|
|
270
|
+
T(e), O(0);
|
|
271
|
+
},
|
|
272
|
+
children: [/* @__PURE__ */ u(v, {
|
|
273
|
+
className: "w-56",
|
|
274
|
+
"aria-label": "Filter by course",
|
|
275
|
+
children: /* @__PURE__ */ u(y, { placeholder: "All courses" })
|
|
276
|
+
}), /* @__PURE__ */ d(g, { children: [/* @__PURE__ */ u(_, {
|
|
277
|
+
value: "ALL",
|
|
278
|
+
children: "All courses"
|
|
279
|
+
}), B.map((e) => /* @__PURE__ */ u(_, {
|
|
280
|
+
value: e.id,
|
|
281
|
+
children: e.title
|
|
282
|
+
}, e.id))] })]
|
|
283
|
+
}),
|
|
284
|
+
/* @__PURE__ */ d("div", {
|
|
285
|
+
className: "relative w-full sm:ml-auto sm:w-64",
|
|
286
|
+
children: [/* @__PURE__ */ u(he, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ u(p, {
|
|
287
|
+
value: E,
|
|
288
|
+
onChange: (e) => {
|
|
289
|
+
D(e.target.value), O(0);
|
|
290
|
+
},
|
|
291
|
+
placeholder: "Search certificates…",
|
|
292
|
+
"aria-label": "Search certificates",
|
|
293
|
+
className: "pl-9"
|
|
294
|
+
})]
|
|
295
|
+
})
|
|
296
|
+
]
|
|
217
297
|
}),
|
|
218
|
-
|
|
298
|
+
M && /* @__PURE__ */ u("p", {
|
|
219
299
|
className: "mb-4 rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
|
|
220
|
-
children:
|
|
300
|
+
children: M
|
|
221
301
|
}),
|
|
222
|
-
|
|
302
|
+
H.isLoading ? /* @__PURE__ */ u(i, { label: "Loading certificates…" }) : H.isError ? /* @__PURE__ */ u(re, {
|
|
223
303
|
message: "Couldn't load certificates.",
|
|
224
|
-
onRetry: () =>
|
|
225
|
-
}) :
|
|
304
|
+
onRetry: () => H.refetch()
|
|
305
|
+
}) : G.length === 0 ? /* @__PURE__ */ u(ne, {
|
|
226
306
|
illustration: $ ? "empty-search" : "onboarding",
|
|
227
|
-
icon: /* @__PURE__ */
|
|
307
|
+
icon: /* @__PURE__ */ u(s, { className: "h-10 w-10" }),
|
|
228
308
|
title: $ ? "No certificates match these filters" : "No certificates issued yet",
|
|
229
|
-
description: $ ?
|
|
230
|
-
action: !$ && Q ? /* @__PURE__ */
|
|
309
|
+
description: $ ? E.trim().length > 0 ? "No credentials match your search. Try a different serial, course, or learner." : C === "MINE" ? "You haven't earned a certificate for this selection yet." : "No certificates have been issued for this course yet." : Q ? "Issue a certificate to credential a learner who has completed a course." : "Publish a course first, then issue certificates to learners who complete it.",
|
|
310
|
+
action: !$ && Q ? /* @__PURE__ */ d(f, {
|
|
231
311
|
onClick: X,
|
|
232
|
-
children: [/* @__PURE__ */
|
|
312
|
+
children: [/* @__PURE__ */ u(l, { className: "mr-1.5 h-4 w-4" }), " Issue certificate"]
|
|
233
313
|
}) : void 0
|
|
234
|
-
}) : /* @__PURE__ */
|
|
235
|
-
columns:
|
|
314
|
+
}) : /* @__PURE__ */ d(_e, { children: [/* @__PURE__ */ u(ie, {
|
|
315
|
+
columns: Me,
|
|
236
316
|
rows: J,
|
|
237
317
|
rowKey: (e) => e.id,
|
|
238
318
|
defaultSort: {
|
|
239
319
|
key: "issuedAt",
|
|
240
320
|
dir: "desc"
|
|
241
321
|
}
|
|
242
|
-
}),
|
|
243
|
-
|
|
244
|
-
|
|
322
|
+
}), /* @__PURE__ */ u(oe, {
|
|
323
|
+
page: q,
|
|
324
|
+
pageSize: b,
|
|
325
|
+
itemCount: J.length,
|
|
326
|
+
hasMore: (q + 1) * b < G.length,
|
|
327
|
+
onPageChange: O
|
|
328
|
+
})] }),
|
|
329
|
+
/* @__PURE__ */ u(ve, {
|
|
330
|
+
open: Oe,
|
|
245
331
|
onOpenChange: (e) => {
|
|
246
|
-
e ?
|
|
332
|
+
e ? k(!0) : Z();
|
|
247
333
|
},
|
|
248
|
-
children: /* @__PURE__ */
|
|
334
|
+
children: /* @__PURE__ */ d(ye, { children: [/* @__PURE__ */ d(Se, { children: [/* @__PURE__ */ u(Ce, { children: "Issue certificate" }), /* @__PURE__ */ u(be, { children: "Credential a learner for completing a course. The serial is auto-generated but editable." })] }), /* @__PURE__ */ d("form", {
|
|
249
335
|
onSubmit: (e) => {
|
|
250
|
-
e.preventDefault(),
|
|
336
|
+
e.preventDefault(), Ne();
|
|
251
337
|
},
|
|
252
|
-
children: [/* @__PURE__ */
|
|
338
|
+
children: [/* @__PURE__ */ d("div", {
|
|
253
339
|
className: "grid gap-4 py-2",
|
|
254
340
|
children: [
|
|
255
|
-
/* @__PURE__ */
|
|
341
|
+
/* @__PURE__ */ d("div", {
|
|
256
342
|
className: "grid gap-1.5",
|
|
257
|
-
children: [/* @__PURE__ */
|
|
343
|
+
children: [/* @__PURE__ */ u(m, {
|
|
258
344
|
htmlFor: "cert-course",
|
|
259
345
|
children: "Course *"
|
|
260
|
-
}), /* @__PURE__ */
|
|
261
|
-
value:
|
|
262
|
-
onValueChange: (e) =>
|
|
346
|
+
}), /* @__PURE__ */ d(h, {
|
|
347
|
+
value: L.courseId,
|
|
348
|
+
onValueChange: (e) => R((t) => ({
|
|
263
349
|
...t,
|
|
264
350
|
courseId: e
|
|
265
351
|
})),
|
|
266
|
-
children: [/* @__PURE__ */
|
|
352
|
+
children: [/* @__PURE__ */ u(v, {
|
|
267
353
|
id: "cert-course",
|
|
268
|
-
children: /* @__PURE__ */
|
|
269
|
-
}), /* @__PURE__ */
|
|
354
|
+
children: /* @__PURE__ */ u(y, { placeholder: "Select a course" })
|
|
355
|
+
}), /* @__PURE__ */ u(g, { children: B.map((e) => /* @__PURE__ */ u(_, {
|
|
270
356
|
value: e.id,
|
|
271
357
|
children: e.title
|
|
272
358
|
}, e.id)) })]
|
|
273
359
|
})]
|
|
274
360
|
}),
|
|
275
|
-
/* @__PURE__ */
|
|
361
|
+
/* @__PURE__ */ d("div", {
|
|
276
362
|
className: "grid gap-1.5",
|
|
277
|
-
children: [/* @__PURE__ */
|
|
363
|
+
children: [/* @__PURE__ */ u(m, {
|
|
278
364
|
htmlFor: "cert-learner",
|
|
279
365
|
children: "Learner (user ID) *"
|
|
280
|
-
}), /* @__PURE__ */
|
|
366
|
+
}), /* @__PURE__ */ u(p, {
|
|
281
367
|
id: "cert-learner",
|
|
282
|
-
value:
|
|
283
|
-
onChange: (e) =>
|
|
368
|
+
value: L.learnerId,
|
|
369
|
+
onChange: (e) => R((t) => ({
|
|
284
370
|
...t,
|
|
285
371
|
learnerId: e.target.value
|
|
286
372
|
})),
|
|
287
373
|
placeholder: "Defaults to you"
|
|
288
374
|
})]
|
|
289
375
|
}),
|
|
290
|
-
/* @__PURE__ */
|
|
376
|
+
/* @__PURE__ */ d("div", {
|
|
291
377
|
className: "grid gap-1.5",
|
|
292
|
-
children: [/* @__PURE__ */
|
|
378
|
+
children: [/* @__PURE__ */ u(m, {
|
|
293
379
|
htmlFor: "cert-serial",
|
|
294
380
|
children: "Serial *"
|
|
295
|
-
}), /* @__PURE__ */
|
|
381
|
+
}), /* @__PURE__ */ u(p, {
|
|
296
382
|
id: "cert-serial",
|
|
297
|
-
value:
|
|
298
|
-
onChange: (e) =>
|
|
383
|
+
value: L.serial,
|
|
384
|
+
onChange: (e) => R((t) => ({
|
|
299
385
|
...t,
|
|
300
386
|
serial: e.target.value
|
|
301
387
|
})),
|
|
302
388
|
placeholder: "BMIQ-XXXXXX"
|
|
303
389
|
})]
|
|
304
390
|
}),
|
|
305
|
-
/* @__PURE__ */
|
|
391
|
+
/* @__PURE__ */ d("div", {
|
|
306
392
|
className: "grid gap-2 sm:grid-cols-2",
|
|
307
|
-
children: [/* @__PURE__ */
|
|
393
|
+
children: [/* @__PURE__ */ d("div", {
|
|
308
394
|
className: "grid gap-1.5",
|
|
309
|
-
children: [/* @__PURE__ */
|
|
395
|
+
children: [/* @__PURE__ */ u(m, {
|
|
310
396
|
htmlFor: "cert-score",
|
|
311
397
|
children: "Final score"
|
|
312
|
-
}), /* @__PURE__ */
|
|
398
|
+
}), /* @__PURE__ */ u(p, {
|
|
313
399
|
id: "cert-score",
|
|
314
400
|
type: "number",
|
|
315
401
|
min: "0",
|
|
316
402
|
step: "0.1",
|
|
317
|
-
value:
|
|
318
|
-
onChange: (e) =>
|
|
403
|
+
value: L.finalScore,
|
|
404
|
+
onChange: (e) => R((t) => ({
|
|
319
405
|
...t,
|
|
320
406
|
finalScore: e.target.value
|
|
321
407
|
})),
|
|
322
408
|
placeholder: "e.g. 92"
|
|
323
409
|
})]
|
|
324
|
-
}), /* @__PURE__ */
|
|
410
|
+
}), /* @__PURE__ */ d("div", {
|
|
325
411
|
className: "grid gap-1.5",
|
|
326
|
-
children: [/* @__PURE__ */
|
|
412
|
+
children: [/* @__PURE__ */ u(m, {
|
|
327
413
|
htmlFor: "cert-expires",
|
|
328
414
|
children: "Expires"
|
|
329
|
-
}), /* @__PURE__ */
|
|
415
|
+
}), /* @__PURE__ */ u(p, {
|
|
330
416
|
id: "cert-expires",
|
|
331
417
|
type: "date",
|
|
332
|
-
value:
|
|
333
|
-
onChange: (e) =>
|
|
418
|
+
value: L.expiresAt,
|
|
419
|
+
onChange: (e) => R((t) => ({
|
|
334
420
|
...t,
|
|
335
421
|
expiresAt: e.target.value
|
|
336
422
|
}))
|
|
337
423
|
})]
|
|
338
424
|
})]
|
|
339
425
|
}),
|
|
340
|
-
|
|
426
|
+
A && /* @__PURE__ */ u("p", {
|
|
341
427
|
className: "text-sm text-status-error-text",
|
|
342
|
-
children:
|
|
428
|
+
children: A
|
|
343
429
|
})
|
|
344
430
|
]
|
|
345
|
-
}), /* @__PURE__ */
|
|
431
|
+
}), /* @__PURE__ */ d(xe, { children: [/* @__PURE__ */ u(f, {
|
|
346
432
|
type: "button",
|
|
347
433
|
variant: "outline",
|
|
348
434
|
onClick: Z,
|
|
349
435
|
children: "Cancel"
|
|
350
|
-
}), /* @__PURE__ */
|
|
436
|
+
}), /* @__PURE__ */ d(f, {
|
|
351
437
|
type: "submit",
|
|
352
|
-
disabled:
|
|
353
|
-
children: [/* @__PURE__ */
|
|
438
|
+
disabled: U.isPending,
|
|
439
|
+
children: [/* @__PURE__ */ u(me, { className: "mr-1.5 h-4 w-4" }), U.isPending ? "Issuing…" : "Issue certificate"]
|
|
354
440
|
})] })]
|
|
355
441
|
})] })
|
|
356
442
|
})
|
|
@@ -358,6 +444,6 @@ var le = (e) => {
|
|
|
358
444
|
});
|
|
359
445
|
};
|
|
360
446
|
//#endregion
|
|
361
|
-
export {
|
|
447
|
+
export { x as CertificatesPage };
|
|
362
448
|
|
|
363
449
|
//# sourceMappingURL=CertificatesPage.js.map
|