@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.
Files changed (67) hide show
  1. package/dist/buildmyiq/BuildmyiqRoot.d.ts.map +1 -1
  2. package/dist/buildmyiq/BuildmyiqRoot.js +57 -49
  3. package/dist/buildmyiq/BuildmyiqRoot.js.map +1 -1
  4. package/dist/buildmyiq/BuildmyiqRoutes.d.ts.map +1 -1
  5. package/dist/buildmyiq/BuildmyiqRoutes.js +15 -11
  6. package/dist/buildmyiq/BuildmyiqRoutes.js.map +1 -1
  7. package/dist/buildmyiq/components/Avatar.d.ts +15 -0
  8. package/dist/buildmyiq/components/Avatar.d.ts.map +1 -0
  9. package/dist/buildmyiq/components/Avatar.js +42 -0
  10. package/dist/buildmyiq/components/Avatar.js.map +1 -0
  11. package/dist/buildmyiq/components/Viz.d.ts +25 -0
  12. package/dist/buildmyiq/components/Viz.d.ts.map +1 -0
  13. package/dist/buildmyiq/components/Viz.js +78 -0
  14. package/dist/buildmyiq/components/Viz.js.map +1 -0
  15. package/dist/buildmyiq/components/index.d.ts +2 -0
  16. package/dist/buildmyiq/components/index.d.ts.map +1 -1
  17. package/dist/buildmyiq/components/index.js +2 -0
  18. package/dist/buildmyiq/pages/DashboardPage.d.ts.map +1 -1
  19. package/dist/buildmyiq/pages/DashboardPage.js +200 -98
  20. package/dist/buildmyiq/pages/DashboardPage.js.map +1 -1
  21. package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.d.ts.map +1 -1
  22. package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.js +262 -241
  23. package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.js.map +1 -1
  24. package/dist/buildmyiq/pages/assessments/AssessmentsPage.d.ts.map +1 -1
  25. package/dist/buildmyiq/pages/assessments/AssessmentsPage.js +142 -115
  26. package/dist/buildmyiq/pages/assessments/AssessmentsPage.js.map +1 -1
  27. package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.d.ts.map +1 -1
  28. package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.js +220 -156
  29. package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.js.map +1 -1
  30. package/dist/buildmyiq/pages/authoring/AuthoringPage.d.ts.map +1 -1
  31. package/dist/buildmyiq/pages/authoring/AuthoringPage.js +51 -46
  32. package/dist/buildmyiq/pages/authoring/AuthoringPage.js.map +1 -1
  33. package/dist/buildmyiq/pages/authoring/CourseBuilderPage.d.ts.map +1 -1
  34. package/dist/buildmyiq/pages/authoring/CourseBuilderPage.js +581 -448
  35. package/dist/buildmyiq/pages/authoring/CourseBuilderPage.js.map +1 -1
  36. package/dist/buildmyiq/pages/catalog/CatalogPage.d.ts.map +1 -1
  37. package/dist/buildmyiq/pages/catalog/CatalogPage.js +52 -42
  38. package/dist/buildmyiq/pages/catalog/CatalogPage.js.map +1 -1
  39. package/dist/buildmyiq/pages/catalog/CourseDetailPage.d.ts.map +1 -1
  40. package/dist/buildmyiq/pages/catalog/CourseDetailPage.js +422 -301
  41. package/dist/buildmyiq/pages/catalog/CourseDetailPage.js.map +1 -1
  42. package/dist/buildmyiq/pages/certificates/CertificatesPage.d.ts.map +1 -1
  43. package/dist/buildmyiq/pages/certificates/CertificatesPage.js +237 -151
  44. package/dist/buildmyiq/pages/certificates/CertificatesPage.js.map +1 -1
  45. package/dist/buildmyiq/pages/cohorts/CohortsPage.d.ts.map +1 -1
  46. package/dist/buildmyiq/pages/cohorts/CohortsPage.js +219 -138
  47. package/dist/buildmyiq/pages/cohorts/CohortsPage.js.map +1 -1
  48. package/dist/buildmyiq/pages/insights/InsightsPage.d.ts.map +1 -1
  49. package/dist/buildmyiq/pages/insights/InsightsPage.js +276 -152
  50. package/dist/buildmyiq/pages/insights/InsightsPage.js.map +1 -1
  51. package/dist/buildmyiq/pages/learning/LessonPlayerPage.d.ts.map +1 -1
  52. package/dist/buildmyiq/pages/learning/LessonPlayerPage.js +237 -174
  53. package/dist/buildmyiq/pages/learning/LessonPlayerPage.js.map +1 -1
  54. package/dist/buildmyiq/pages/learning/MyLearningPage.d.ts.map +1 -1
  55. package/dist/buildmyiq/pages/learning/MyLearningPage.js +307 -169
  56. package/dist/buildmyiq/pages/learning/MyLearningPage.js.map +1 -1
  57. package/dist/buildmyiq/pages/paths/PathsPage.d.ts +4 -0
  58. package/dist/buildmyiq/pages/paths/PathsPage.d.ts.map +1 -0
  59. package/dist/buildmyiq/pages/paths/PathsPage.js +187 -0
  60. package/dist/buildmyiq/pages/paths/PathsPage.js.map +1 -0
  61. package/dist/buildmyiq/pages/skills/SkillsPage.d.ts.map +1 -1
  62. package/dist/buildmyiq/pages/skills/SkillsPage.js +233 -140
  63. package/dist/buildmyiq/pages/skills/SkillsPage.js.map +1 -1
  64. package/dist/buildmyiq/pages/submissions/SubmissionsPage.d.ts.map +1 -1
  65. package/dist/buildmyiq/pages/submissions/SubmissionsPage.js +379 -275
  66. package/dist/buildmyiq/pages/submissions/SubmissionsPage.js.map +1 -1
  67. package/package.json +1 -1
@@ -1,22 +1,23 @@
1
1
  import { useBuildmyiq as e } from "../../context/BuildmyiqContext.js";
2
2
  import { PageLayout as t } from "../../components/PageLayout.js";
3
- import { formatEnumLabel as n, formatRelativeTime as r } from "../../utils/formatters.js";
4
- import { StatusBadge as i } from "../../components/StatusBadge.js";
5
- import { EmptyState as a } from "../../components/EmptyState.js";
6
- import { ErrorView as o, LoadingView as s } from "../../components/StateViews.js";
7
- import { DataTable as c } from "../../components/DataTable.js";
8
- import { FilterTabs as l } from "../../components/FilterTabs.js";
3
+ import { MetricsCard as n } from "../../components/MetricsCard.js";
4
+ import { formatEnumLabel as ee, formatRelativeTime as te } from "../../utils/formatters.js";
5
+ import { StatusBadge as r } from "../../components/StatusBadge.js";
6
+ import { EmptyState as i } from "../../components/EmptyState.js";
7
+ import { ErrorView as ne, LoadingView as a } from "../../components/StateViews.js";
8
+ import { DataTable as o } from "../../components/DataTable.js";
9
+ import { FilterTabs as s } from "../../components/FilterTabs.js";
9
10
  import "../../context/index.js";
10
- import { useBuiAssessments as ee, useBuiCourses as u, useBuiCreateAssessment as d } from "../../hooks/useBuildmyiqApi.js";
11
+ import { useBuiAssessments as c, useBuiCourses as l, useBuiCreateAssessment as u } from "../../hooks/useBuildmyiqApi.js";
11
12
  import "../../hooks/index.js";
12
13
  import "../../components/index.js";
13
- import { ASSESSMENT_TYPES as f } from "../../types/index.js";
14
- import { useMemo as p, useState as m } from "react";
15
- import { ClipboardList as h, Plus as g } from "lucide-react";
14
+ import { ASSESSMENT_TYPES as re } from "../../types/index.js";
15
+ import { useMemo as d, useState as f } from "react";
16
+ import { CheckCircle2 as ie, ClipboardList as p, FileEdit as m, ListChecks as h, Plus as g } from "lucide-react";
16
17
  import { jsx as _, jsxs as v } from "react/jsx-runtime";
17
- import { Button as y, GlassCard as te, Input as b, Label as x, ResponsiveDialog as S, ResponsiveDialogContent as C, ResponsiveDialogDescription as w, ResponsiveDialogFooter as T, ResponsiveDialogHeader as E, ResponsiveDialogTitle as D, Select as O, SelectContent as k, SelectItem as A, SelectTrigger as j, SelectValue as M, Switch as N, Textarea as ne } from "@burdenoff/fe-libs/ui";
18
+ import { Button as y, GlassCard as b, Input as x, Label as S, ResponsiveDialog as C, ResponsiveDialogContent as w, ResponsiveDialogDescription as ae, ResponsiveDialogFooter as oe, ResponsiveDialogHeader as se, ResponsiveDialogTitle as ce, Select as T, SelectContent as E, SelectItem as D, SelectTrigger as O, SelectValue as k, Switch as A, Textarea as j } from "@burdenoff/fe-libs/ui";
18
19
  //#region src/buildmyiq/pages/assessments/AssessmentsPage.tsx
19
- var re = [
20
+ var M = [
20
21
  {
21
22
  value: "ALL",
22
23
  label: "All"
@@ -33,7 +34,7 @@ var re = [
33
34
  value: "ARCHIVED",
34
35
  label: "Archived"
35
36
  }
36
- ], P = () => ({
37
+ ], N = () => ({
37
38
  title: "",
38
39
  description: "",
39
40
  type: "QUIZ",
@@ -41,21 +42,21 @@ var re = [
41
42
  maxAttempts: "1",
42
43
  timeLimitMin: "0",
43
44
  isGraded: !0
44
- }), F = () => {
45
- let { navigateTo: F } = e(), [I, L] = m(""), [R, z] = m("ALL"), [B, V] = m(!1), [H, U] = m(P), [W, G] = m(null), K = u({ limit: 100 }), q = ee(I || void 0), J = d(), Y = K.data?.items ?? [], X = p(() => q.data ?? [], [q.data]), ie = p(() => {
45
+ }), P = () => {
46
+ let { navigateTo: P } = e(), [F, I] = f(""), [L, R] = f("ALL"), [z, B] = f(!1), [V, H] = f(N), [U, W] = f(null), G = l({ limit: 100 }), K = c(F || void 0), q = u(), J = G.data?.items ?? [], Y = d(() => K.data ?? [], [K.data]), X = d(() => {
46
47
  let e = {
47
- ALL: X.length,
48
+ ALL: Y.length,
48
49
  DRAFT: 0,
49
50
  PUBLISHED: 0,
50
51
  ARCHIVED: 0
51
52
  };
52
- for (let t of X) e[t.status] += 1;
53
+ for (let t of Y) e[t.status] += 1;
53
54
  return e;
54
- }, [X]), Z = p(() => R === "ALL" ? X : X.filter((e) => e.status === R), [X, R]), ae = re.map((e) => ({
55
+ }, [Y]), Z = d(() => L === "ALL" ? Y : Y.filter((e) => e.status === L), [Y, L]), le = d(() => Y.reduce((e, t) => e + (t.questions?.length ?? 0), 0), [Y]), ue = M.map((e) => ({
55
56
  value: e.value,
56
57
  label: e.label,
57
- count: ie[e.value]
58
- })), oe = [
58
+ count: X[e.value]
59
+ })), de = [
59
60
  {
60
61
  key: "title",
61
62
  header: "Assessment",
@@ -74,13 +75,13 @@ var re = [
74
75
  {
75
76
  key: "type",
76
77
  header: "Type",
77
- render: (e) => /* @__PURE__ */ _(i, { status: e.type })
78
+ render: (e) => /* @__PURE__ */ _(r, { status: e.type })
78
79
  },
79
80
  {
80
81
  key: "status",
81
82
  header: "Status",
82
83
  sortValue: (e) => e.status,
83
- render: (e) => /* @__PURE__ */ _(i, { status: e.status })
84
+ render: (e) => /* @__PURE__ */ _(r, { status: e.status })
84
85
  },
85
86
  {
86
87
  key: "passingScore",
@@ -110,13 +111,13 @@ var re = [
110
111
  sortValue: (e) => e.updatedAt,
111
112
  render: (e) => /* @__PURE__ */ _("span", {
112
113
  className: "whitespace-nowrap text-text-secondary",
113
- children: r(e.updatedAt)
114
+ children: te(e.updatedAt)
114
115
  })
115
116
  }
116
117
  ], Q = () => {
117
- U(P()), G(null), V(!0);
118
+ H(N()), W(null), B(!0);
118
119
  }, $ = () => {
119
- V(!1), U(P()), G(null);
120
+ B(!1), H(N()), W(null);
120
121
  };
121
122
  return /* @__PURE__ */ v(t, {
122
123
  title: "Assessments",
@@ -125,11 +126,11 @@ var re = [
125
126
  aurora: !0,
126
127
  actions: /* @__PURE__ */ v(y, {
127
128
  onClick: Q,
128
- disabled: !I,
129
+ disabled: !F,
129
130
  children: [/* @__PURE__ */ _(g, { className: "mr-1.5 h-4 w-4" }), " New assessment"]
130
131
  }),
131
132
  children: [
132
- /* @__PURE__ */ _(te, {
133
+ /* @__PURE__ */ _(b, {
133
134
  treatment: "plain",
134
135
  className: "mb-5 p-4",
135
136
  children: /* @__PURE__ */ v("div", {
@@ -141,84 +142,110 @@ var re = [
141
142
  className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
142
143
  children: "Course"
143
144
  }),
144
- /* @__PURE__ */ v(O, {
145
- value: I,
145
+ /* @__PURE__ */ v(T, {
146
+ value: F,
146
147
  onValueChange: (e) => {
147
- L(e), z("ALL");
148
+ I(e), R("ALL");
148
149
  },
149
- children: [/* @__PURE__ */ _(j, {
150
+ children: [/* @__PURE__ */ _(O, {
150
151
  className: "w-full sm:w-72",
151
- children: /* @__PURE__ */ _(M, { placeholder: "Select a course" })
152
- }), /* @__PURE__ */ _(k, { children: Y.map((e) => /* @__PURE__ */ _(A, {
152
+ children: /* @__PURE__ */ _(k, { placeholder: "Select a course" })
153
+ }), /* @__PURE__ */ _(E, { children: J.map((e) => /* @__PURE__ */ _(D, {
153
154
  value: e.id,
154
155
  children: e.title
155
156
  }, e.id)) })]
156
157
  }),
157
- K.isSuccess && Y.length === 0 && /* @__PURE__ */ _("p", {
158
+ G.isSuccess && J.length === 0 && /* @__PURE__ */ _("p", {
158
159
  className: "text-xs text-text-secondary",
159
160
  children: "No courses yet — create one in Authoring first."
160
161
  })
161
162
  ]
162
- }), I && /* @__PURE__ */ v("div", {
163
+ }), F && /* @__PURE__ */ v("div", {
163
164
  className: "grid gap-1.5",
164
165
  children: [/* @__PURE__ */ _("span", {
165
166
  className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
166
167
  children: "Status"
167
- }), /* @__PURE__ */ _(l, {
168
- options: ae,
169
- value: R,
170
- onChange: z
168
+ }), /* @__PURE__ */ _(s, {
169
+ options: ue,
170
+ value: L,
171
+ onChange: R
171
172
  })]
172
173
  })]
173
174
  })
174
175
  }),
175
- I ? q.isLoading ? /* @__PURE__ */ _(s, { label: "Loading assessments…" }) : q.isError ? /* @__PURE__ */ _(o, {
176
+ F && K.isSuccess && Y.length > 0 && /* @__PURE__ */ v("div", {
177
+ className: "mb-5 grid grid-cols-2 gap-4 lg:grid-cols-4",
178
+ children: [
179
+ /* @__PURE__ */ _(n, {
180
+ icon: /* @__PURE__ */ _(p, { className: "h-5 w-5" }),
181
+ value: X.ALL,
182
+ label: "Assessments"
183
+ }),
184
+ /* @__PURE__ */ _(n, {
185
+ icon: /* @__PURE__ */ _(ie, { className: "h-5 w-5" }),
186
+ value: X.PUBLISHED,
187
+ label: "Published",
188
+ accent: "success"
189
+ }),
190
+ /* @__PURE__ */ _(n, {
191
+ icon: /* @__PURE__ */ _(m, { className: "h-5 w-5" }),
192
+ value: X.DRAFT,
193
+ label: "Drafts"
194
+ }),
195
+ /* @__PURE__ */ _(n, {
196
+ icon: /* @__PURE__ */ _(h, { className: "h-5 w-5" }),
197
+ value: le,
198
+ label: "Questions"
199
+ })
200
+ ]
201
+ }),
202
+ F ? K.isLoading ? /* @__PURE__ */ _(a, { label: "Loading assessments…" }) : K.isError ? /* @__PURE__ */ _(ne, {
176
203
  message: "Couldn't load assessments for this course.",
177
- onRetry: () => q.refetch()
178
- }) : Z.length === 0 ? /* @__PURE__ */ _(a, {
204
+ onRetry: () => K.refetch()
205
+ }) : Z.length === 0 ? /* @__PURE__ */ _(i, {
179
206
  illustration: "empty-data",
180
- icon: /* @__PURE__ */ _(h, { className: "h-10 w-10" }),
181
- title: R === "ALL" ? "No assessments yet" : "No assessments match this filter",
182
- description: R === "ALL" ? "Create the first quiz, exam or assignment for this course." : "Try a different status filter, or create a new assessment.",
207
+ icon: /* @__PURE__ */ _(p, { className: "h-10 w-10" }),
208
+ title: L === "ALL" ? "No assessments yet" : "No assessments match this filter",
209
+ description: L === "ALL" ? "Create the first quiz, exam or assignment for this course." : "Try a different status filter, or create a new assessment.",
183
210
  action: /* @__PURE__ */ v(y, {
184
211
  onClick: Q,
185
212
  children: [/* @__PURE__ */ _(g, { className: "mr-1.5 h-4 w-4" }), " New assessment"]
186
213
  })
187
- }) : /* @__PURE__ */ _(c, {
188
- columns: oe,
214
+ }) : /* @__PURE__ */ _(o, {
215
+ columns: de,
189
216
  rows: Z,
190
217
  rowKey: (e) => e.id,
191
- onRowClick: (e) => F(`assessments/${e.id}`),
218
+ onRowClick: (e) => P(`assessments/${e.id}`),
192
219
  defaultSort: {
193
220
  key: "updatedAt",
194
221
  dir: "desc"
195
222
  }
196
- }) : /* @__PURE__ */ _(a, {
223
+ }) : /* @__PURE__ */ _(i, {
197
224
  illustration: "onboarding",
198
- icon: /* @__PURE__ */ _(h, { className: "h-10 w-10" }),
225
+ icon: /* @__PURE__ */ _(p, { className: "h-10 w-10" }),
199
226
  title: "Pick a course to see its assessments",
200
227
  description: "Assessments are scoped to a course. Choose a course above to view, filter and create its quizzes and exams."
201
228
  }),
202
- /* @__PURE__ */ _(S, {
203
- open: B,
229
+ /* @__PURE__ */ _(C, {
230
+ open: z,
204
231
  onOpenChange: (e) => {
205
- e ? V(!0) : $();
232
+ e ? B(!0) : $();
206
233
  },
207
- children: /* @__PURE__ */ v(C, { children: [
208
- /* @__PURE__ */ v(E, { children: [/* @__PURE__ */ _(D, { children: "New assessment" }), /* @__PURE__ */ _(w, { children: "Add a quiz, exam or assignment to this course. You can add questions after it's created." })] }),
234
+ children: /* @__PURE__ */ v(w, { children: [
235
+ /* @__PURE__ */ v(se, { children: [/* @__PURE__ */ _(ce, { children: "New assessment" }), /* @__PURE__ */ _(ae, { children: "Add a quiz, exam or assignment to this course. You can add questions after it's created." })] }),
209
236
  /* @__PURE__ */ v("div", {
210
237
  className: "grid gap-4 py-2",
211
238
  children: [
212
239
  /* @__PURE__ */ v("div", {
213
240
  className: "grid gap-1.5",
214
- children: [/* @__PURE__ */ _(x, {
241
+ children: [/* @__PURE__ */ _(S, {
215
242
  htmlFor: "assessmentTitle",
216
243
  children: "Title *"
217
- }), /* @__PURE__ */ _(b, {
244
+ }), /* @__PURE__ */ _(x, {
218
245
  id: "assessmentTitle",
219
- value: H.title,
220
- onChange: (e) => U({
221
- ...H,
246
+ value: V.title,
247
+ onChange: (e) => H({
248
+ ...V,
222
249
  title: e.target.value
223
250
  }),
224
251
  placeholder: "e.g. Module 1 knowledge check"
@@ -226,14 +253,14 @@ var re = [
226
253
  }),
227
254
  /* @__PURE__ */ v("div", {
228
255
  className: "grid gap-1.5",
229
- children: [/* @__PURE__ */ _(x, {
256
+ children: [/* @__PURE__ */ _(S, {
230
257
  htmlFor: "assessmentDescription",
231
258
  children: "Description"
232
- }), /* @__PURE__ */ _(ne, {
259
+ }), /* @__PURE__ */ _(j, {
233
260
  id: "assessmentDescription",
234
- value: H.description,
235
- onChange: (e) => U({
236
- ...H,
261
+ value: V.description,
262
+ onChange: (e) => H({
263
+ ...V,
237
264
  description: e.target.value
238
265
  }),
239
266
  placeholder: "What this assessment covers and how it's graded.",
@@ -244,37 +271,37 @@ var re = [
244
271
  className: "grid gap-2 sm:grid-cols-2",
245
272
  children: [/* @__PURE__ */ v("div", {
246
273
  className: "grid gap-1.5",
247
- children: [/* @__PURE__ */ _(x, {
274
+ children: [/* @__PURE__ */ _(S, {
248
275
  htmlFor: "assessmentType",
249
276
  children: "Type"
250
- }), /* @__PURE__ */ v(O, {
251
- value: H.type,
252
- onValueChange: (e) => U({
253
- ...H,
277
+ }), /* @__PURE__ */ v(T, {
278
+ value: V.type,
279
+ onValueChange: (e) => H({
280
+ ...V,
254
281
  type: e
255
282
  }),
256
- children: [/* @__PURE__ */ _(j, {
283
+ children: [/* @__PURE__ */ _(O, {
257
284
  id: "assessmentType",
258
- children: /* @__PURE__ */ _(M, {})
259
- }), /* @__PURE__ */ _(k, { children: f.map((e) => /* @__PURE__ */ _(A, {
285
+ children: /* @__PURE__ */ _(k, {})
286
+ }), /* @__PURE__ */ _(E, { children: re.map((e) => /* @__PURE__ */ _(D, {
260
287
  value: e,
261
- children: n(e)
288
+ children: ee(e)
262
289
  }, e)) })]
263
290
  })]
264
291
  }), /* @__PURE__ */ v("div", {
265
292
  className: "grid gap-1.5",
266
- children: [/* @__PURE__ */ _(x, {
293
+ children: [/* @__PURE__ */ _(S, {
267
294
  htmlFor: "passingScore",
268
295
  children: "Passing score (%)"
269
- }), /* @__PURE__ */ _(b, {
296
+ }), /* @__PURE__ */ _(x, {
270
297
  id: "passingScore",
271
298
  type: "number",
272
299
  min: "0",
273
300
  max: "100",
274
301
  step: "1",
275
- value: H.passingScore,
276
- onChange: (e) => U({
277
- ...H,
302
+ value: V.passingScore,
303
+ onChange: (e) => H({
304
+ ...V,
278
305
  passingScore: e.target.value
279
306
  }),
280
307
  placeholder: "70"
@@ -285,34 +312,34 @@ var re = [
285
312
  className: "grid gap-2 sm:grid-cols-2",
286
313
  children: [/* @__PURE__ */ v("div", {
287
314
  className: "grid gap-1.5",
288
- children: [/* @__PURE__ */ _(x, {
315
+ children: [/* @__PURE__ */ _(S, {
289
316
  htmlFor: "maxAttempts",
290
317
  children: "Max attempts"
291
- }), /* @__PURE__ */ _(b, {
318
+ }), /* @__PURE__ */ _(x, {
292
319
  id: "maxAttempts",
293
320
  type: "number",
294
321
  min: "1",
295
322
  step: "1",
296
- value: H.maxAttempts,
297
- onChange: (e) => U({
298
- ...H,
323
+ value: V.maxAttempts,
324
+ onChange: (e) => H({
325
+ ...V,
299
326
  maxAttempts: e.target.value
300
327
  }),
301
328
  placeholder: "1"
302
329
  })]
303
330
  }), /* @__PURE__ */ v("div", {
304
331
  className: "grid gap-1.5",
305
- children: [/* @__PURE__ */ _(x, {
332
+ children: [/* @__PURE__ */ _(S, {
306
333
  htmlFor: "timeLimitMin",
307
334
  children: "Time limit (minutes)"
308
- }), /* @__PURE__ */ _(b, {
335
+ }), /* @__PURE__ */ _(x, {
309
336
  id: "timeLimitMin",
310
337
  type: "number",
311
338
  min: "0",
312
339
  step: "1",
313
- value: H.timeLimitMin,
314
- onChange: (e) => U({
315
- ...H,
340
+ value: V.timeLimitMin,
341
+ onChange: (e) => H({
342
+ ...V,
316
343
  timeLimitMin: e.target.value
317
344
  }),
318
345
  placeholder: "0 = no limit"
@@ -323,7 +350,7 @@ var re = [
323
350
  className: "flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface px-3 py-2.5",
324
351
  children: [/* @__PURE__ */ v("div", {
325
352
  className: "min-w-0",
326
- children: [/* @__PURE__ */ _(x, {
353
+ children: [/* @__PURE__ */ _(S, {
327
354
  htmlFor: "isGraded",
328
355
  className: "cursor-pointer",
329
356
  children: "Graded"
@@ -331,53 +358,53 @@ var re = [
331
358
  className: "text-xs text-text-secondary",
332
359
  children: "Contributes to the learner's score and pass/fail outcome."
333
360
  })]
334
- }), /* @__PURE__ */ _(N, {
361
+ }), /* @__PURE__ */ _(A, {
335
362
  id: "isGraded",
336
- checked: H.isGraded,
337
- onCheckedChange: (e) => U({
338
- ...H,
363
+ checked: V.isGraded,
364
+ onCheckedChange: (e) => H({
365
+ ...V,
339
366
  isGraded: e
340
367
  })
341
368
  })]
342
369
  }),
343
- W && /* @__PURE__ */ _("p", {
370
+ U && /* @__PURE__ */ _("p", {
344
371
  className: "text-sm text-status-error-text",
345
- children: W
372
+ children: U
346
373
  })
347
374
  ]
348
375
  }),
349
- /* @__PURE__ */ v(T, { children: [/* @__PURE__ */ _(y, {
376
+ /* @__PURE__ */ v(oe, { children: [/* @__PURE__ */ _(y, {
350
377
  variant: "outline",
351
378
  onClick: $,
352
379
  children: "Cancel"
353
380
  }), /* @__PURE__ */ _(y, {
354
381
  onClick: async () => {
355
- if (!I) {
356
- G("Pick a course first.");
382
+ if (!F) {
383
+ W("Pick a course first.");
357
384
  return;
358
385
  }
359
- if (!H.title.trim()) {
360
- G("Title is required.");
386
+ if (!V.title.trim()) {
387
+ W("Title is required.");
361
388
  return;
362
389
  }
363
390
  try {
364
- let e = await J.mutateAsync({
365
- courseId: I,
366
- title: H.title.trim(),
367
- description: H.description.trim() || void 0,
368
- type: H.type,
369
- passingScore: H.passingScore ? Number(H.passingScore) : void 0,
370
- maxAttempts: H.maxAttempts ? Number(H.maxAttempts) : void 0,
371
- timeLimitMin: H.timeLimitMin ? Number(H.timeLimitMin) : void 0,
372
- isGraded: H.isGraded
391
+ let e = await q.mutateAsync({
392
+ courseId: F,
393
+ title: V.title.trim(),
394
+ description: V.description.trim() || void 0,
395
+ type: V.type,
396
+ passingScore: V.passingScore ? Number(V.passingScore) : void 0,
397
+ maxAttempts: V.maxAttempts ? Number(V.maxAttempts) : void 0,
398
+ timeLimitMin: V.timeLimitMin ? Number(V.timeLimitMin) : void 0,
399
+ isGraded: V.isGraded
373
400
  });
374
- $(), F(`assessments/${e.id}`);
401
+ $(), P(`assessments/${e.id}`);
375
402
  } catch (e) {
376
- G(e instanceof Error ? e.message : "Failed to create assessment.");
403
+ W(e instanceof Error ? e.message : "Failed to create assessment.");
377
404
  }
378
405
  },
379
- disabled: J.isPending,
380
- children: J.isPending ? "Creating…" : "Create assessment"
406
+ disabled: q.isPending,
407
+ children: q.isPending ? "Creating…" : "Create assessment"
381
408
  })] })
382
409
  ] })
383
410
  })
@@ -385,6 +412,6 @@ var re = [
385
412
  });
386
413
  };
387
414
  //#endregion
388
- export { F as AssessmentsPage };
415
+ export { P as AssessmentsPage };
389
416
 
390
417
  //# sourceMappingURL=AssessmentsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssessmentsPage.js","names":[],"sources":["../../../../src/buildmyiq/pages/assessments/AssessmentsPage.tsx"],"sourcesContent":["/**\n * AssessmentsPage — the assessment authoring surface (primary page of the section).\n * @module buildmyiq/pages/assessments\n *\n * `buiListAssessments` REQUIRES a courseId, so this page is course-scoped: the\n * educator first picks a course, then sees its assessments filtered by status.\n * Everything is real `bui*` data — no fabrication. Create flow wires\n * `useBuiCreateAssessment`.\n */\n\nimport { useMemo, useState, type FC } from 'react';\nimport { Plus, ClipboardList } from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Input,\n Label,\n Textarea,\n Switch,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n StatusBadge,\n FilterTabs,\n DataTable,\n EmptyState,\n LoadingView,\n ErrorView,\n type Column,\n type FilterOption,\n} from '../../components';\nimport { useBuildmyiq } from '../../context';\nimport { useBuiCourses, useBuiAssessments, useBuiCreateAssessment } from '../../hooks';\nimport { formatEnumLabel, formatRelativeTime } from '../../utils/formatters';\nimport { ASSESSMENT_TYPES } from '../../types';\nimport type { BuiAssessment, BuiAssessmentStatus, BuiAssessmentType } from '../../types';\n\ntype StatusFilter = 'ALL' | BuiAssessmentStatus;\n\nconst STATUS_TABS: { value: StatusFilter; label: string }[] = [\n { value: 'ALL', label: 'All' },\n { value: 'DRAFT', label: 'Draft' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\ninterface AssessmentFormState {\n title: string;\n description: string;\n type: BuiAssessmentType;\n passingScore: string;\n maxAttempts: string;\n timeLimitMin: string;\n isGraded: boolean;\n}\n\nconst makeEmptyForm = (): AssessmentFormState => ({\n title: '',\n description: '',\n type: 'QUIZ',\n passingScore: '70',\n maxAttempts: '1',\n timeLimitMin: '0',\n isGraded: true,\n});\n\nexport const AssessmentsPage: FC = () => {\n const { navigateTo } = useBuildmyiq();\n\n const [courseId, setCourseId] = useState<string>('');\n const [status, setStatus] = useState<StatusFilter>('ALL');\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<AssessmentFormState>(makeEmptyForm);\n const [formError, setFormError] = useState<string | null>(null);\n\n const coursesQuery = useBuiCourses({ limit: 100 });\n // Fetch the full (unfiltered) list so the tab counts stay accurate; filter client-side.\n const assessmentsQuery = useBuiAssessments(courseId || undefined);\n const createAssessment = useBuiCreateAssessment();\n\n const courses = coursesQuery.data?.items ?? [];\n const assessments = useMemo(() => assessmentsQuery.data ?? [], [assessmentsQuery.data]);\n\n const statusCounts = useMemo(() => {\n const counts: Record<StatusFilter, number> = {\n ALL: assessments.length,\n DRAFT: 0,\n PUBLISHED: 0,\n ARCHIVED: 0,\n };\n for (const a of assessments) counts[a.status] += 1;\n return counts;\n }, [assessments]);\n\n const rows = useMemo(\n () => (status === 'ALL' ? assessments : assessments.filter((a) => a.status === status)),\n [assessments, status]\n );\n\n const tabOptions: FilterOption<StatusFilter>[] = STATUS_TABS.map((t) => ({\n value: t.value,\n label: t.label,\n count: statusCounts[t.value],\n }));\n\n const columns: Column<BuiAssessment>[] = [\n {\n key: 'title',\n header: 'Assessment',\n render: (a) => (\n <div className=\"min-w-0\">\n <p className=\"font-semibold text-text-primary\">{a.title}</p>\n {a.description && (\n <p\n className=\"mt-0.5 max-w-md truncate text-xs text-text-secondary\"\n title={a.description}\n >\n {a.description}\n </p>\n )}\n </div>\n ),\n },\n {\n key: 'type',\n header: 'Type',\n render: (a) => <StatusBadge status={a.type} />,\n },\n {\n key: 'status',\n header: 'Status',\n sortValue: (a) => a.status,\n render: (a) => <StatusBadge status={a.status} />,\n },\n {\n key: 'passingScore',\n header: 'Pass',\n align: 'right',\n hideOnMobile: true,\n sortValue: (a) => a.passingScore,\n render: (a) => <span className=\"tabular-nums text-text-secondary\">{a.passingScore}%</span>,\n },\n {\n key: 'questions',\n header: 'Questions',\n align: 'right',\n hideOnMobile: true,\n render: (a) => (\n <span className=\"tabular-nums text-text-secondary\">{a.questions?.length ?? '—'}</span>\n ),\n },\n {\n key: 'updatedAt',\n header: 'Updated',\n hideOnMobile: true,\n sortValue: (a) => a.updatedAt,\n render: (a) => (\n <span className=\"whitespace-nowrap text-text-secondary\">\n {formatRelativeTime(a.updatedAt)}\n </span>\n ),\n },\n ];\n\n const openDialog = () => {\n setForm(makeEmptyForm());\n setFormError(null);\n setDialogOpen(true);\n };\n\n const closeDialog = () => {\n setDialogOpen(false);\n setForm(makeEmptyForm());\n setFormError(null);\n };\n\n const handleCreate = async () => {\n if (!courseId) {\n setFormError('Pick a course first.');\n return;\n }\n if (!form.title.trim()) {\n setFormError('Title is required.');\n return;\n }\n try {\n const created = await createAssessment.mutateAsync({\n courseId,\n title: form.title.trim(),\n description: form.description.trim() || undefined,\n type: form.type,\n passingScore: form.passingScore ? Number(form.passingScore) : undefined,\n maxAttempts: form.maxAttempts ? Number(form.maxAttempts) : undefined,\n timeLimitMin: form.timeLimitMin ? Number(form.timeLimitMin) : undefined,\n isGraded: form.isGraded,\n });\n closeDialog();\n navigateTo(`assessments/${created.id}`);\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to create assessment.');\n }\n };\n\n return (\n <PageLayout\n title=\"Assessments\"\n description=\"Quizzes, exams and graded assignments for every course in your workspace.\"\n titleGradient\n aurora\n actions={\n <Button onClick={openDialog} disabled={!courseId}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New assessment\n </Button>\n }\n >\n <GlassCard treatment=\"plain\" className=\"mb-5 p-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end\">\n <div className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Course\n </span>\n <Select\n value={courseId}\n onValueChange={(v) => {\n setCourseId(v);\n setStatus('ALL');\n }}\n >\n <SelectTrigger className=\"w-full sm:w-72\">\n <SelectValue placeholder=\"Select a course\" />\n </SelectTrigger>\n <SelectContent>\n {courses.map((c) => (\n <SelectItem key={c.id} value={c.id}>\n {c.title}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {coursesQuery.isSuccess && courses.length === 0 && (\n <p className=\"text-xs text-text-secondary\">\n No courses yet — create one in Authoring first.\n </p>\n )}\n </div>\n {courseId && (\n <div className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Status\n </span>\n <FilterTabs options={tabOptions} value={status} onChange={setStatus} />\n </div>\n )}\n </div>\n </GlassCard>\n\n {!courseId ? (\n <EmptyState\n illustration=\"onboarding\"\n icon={<ClipboardList className=\"h-10 w-10\" />}\n title=\"Pick a course to see its assessments\"\n description=\"Assessments are scoped to a course. Choose a course above to view, filter and create its quizzes and exams.\"\n />\n ) : assessmentsQuery.isLoading ? (\n <LoadingView label=\"Loading assessments…\" />\n ) : assessmentsQuery.isError ? (\n <ErrorView\n message=\"Couldn't load assessments for this course.\"\n onRetry={() => assessmentsQuery.refetch()}\n />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<ClipboardList className=\"h-10 w-10\" />}\n title={status === 'ALL' ? 'No assessments yet' : 'No assessments match this filter'}\n description={\n status === 'ALL'\n ? 'Create the first quiz, exam or assignment for this course.'\n : 'Try a different status filter, or create a new assessment.'\n }\n action={\n <Button onClick={openDialog}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New assessment\n </Button>\n }\n />\n ) : (\n <DataTable\n columns={columns}\n rows={rows}\n rowKey={(a) => a.id}\n onRowClick={(a) => navigateTo(`assessments/${a.id}`)}\n defaultSort={{ key: 'updatedAt', dir: 'desc' }}\n />\n )}\n\n <ResponsiveDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n if (!open) closeDialog();\n else setDialogOpen(true);\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>New assessment</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Add a quiz, exam or assignment to this course. You can add questions after it&apos;s\n created.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"assessmentTitle\">Title *</Label>\n <Input\n id=\"assessmentTitle\"\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n placeholder=\"e.g. Module 1 knowledge check\"\n />\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"assessmentDescription\">Description</Label>\n <Textarea\n id=\"assessmentDescription\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n placeholder=\"What this assessment covers and how it's graded.\"\n rows={2}\n />\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"assessmentType\">Type</Label>\n <Select\n value={form.type}\n onValueChange={(v) => setForm({ ...form, type: v as BuiAssessmentType })}\n >\n <SelectTrigger id=\"assessmentType\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ASSESSMENT_TYPES.map((t) => (\n <SelectItem key={t} value={t}>\n {formatEnumLabel(t)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"passingScore\">Passing score (%)</Label>\n <Input\n id=\"passingScore\"\n type=\"number\"\n min=\"0\"\n max=\"100\"\n step=\"1\"\n value={form.passingScore}\n onChange={(e) => setForm({ ...form, passingScore: e.target.value })}\n placeholder=\"70\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"maxAttempts\">Max attempts</Label>\n <Input\n id=\"maxAttempts\"\n type=\"number\"\n min=\"1\"\n step=\"1\"\n value={form.maxAttempts}\n onChange={(e) => setForm({ ...form, maxAttempts: e.target.value })}\n placeholder=\"1\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"timeLimitMin\">Time limit (minutes)</Label>\n <Input\n id=\"timeLimitMin\"\n type=\"number\"\n min=\"0\"\n step=\"1\"\n value={form.timeLimitMin}\n onChange={(e) => setForm({ ...form, timeLimitMin: e.target.value })}\n placeholder=\"0 = no limit\"\n />\n </div>\n </div>\n\n <div className=\"flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface px-3 py-2.5\">\n <div className=\"min-w-0\">\n <Label htmlFor=\"isGraded\" className=\"cursor-pointer\">\n Graded\n </Label>\n <p className=\"text-xs text-text-secondary\">\n Contributes to the learner&apos;s score and pass/fail outcome.\n </p>\n </div>\n <Switch\n id=\"isGraded\"\n checked={form.isGraded}\n onCheckedChange={(checked) => setForm({ ...form, isGraded: checked })}\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={closeDialog}>\n Cancel\n </Button>\n <Button onClick={handleCreate} disabled={createAssessment.isPending}>\n {createAssessment.isPending ? 'Creating…' : 'Create assessment'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AssessmentsPage.js","names":[],"sources":["../../../../src/buildmyiq/pages/assessments/AssessmentsPage.tsx"],"sourcesContent":["/**\n * AssessmentsPage — the assessment authoring surface (primary page of the section).\n * @module buildmyiq/pages/assessments\n *\n * `buiListAssessments` REQUIRES a courseId, so this page is course-scoped: the\n * educator first picks a course, then sees its assessments filtered by status.\n * Everything is real `bui*` data — no fabrication. Create flow wires\n * `useBuiCreateAssessment`.\n */\n\nimport { useMemo, useState, type FC } from 'react';\nimport { Plus, ClipboardList, CheckCircle2, FileEdit, ListChecks } from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Input,\n Label,\n Textarea,\n Switch,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n MetricsCard,\n StatusBadge,\n FilterTabs,\n DataTable,\n EmptyState,\n LoadingView,\n ErrorView,\n type Column,\n type FilterOption,\n} from '../../components';\nimport { useBuildmyiq } from '../../context';\nimport { useBuiCourses, useBuiAssessments, useBuiCreateAssessment } from '../../hooks';\nimport { formatEnumLabel, formatRelativeTime } from '../../utils/formatters';\nimport { ASSESSMENT_TYPES } from '../../types';\nimport type { BuiAssessment, BuiAssessmentStatus, BuiAssessmentType } from '../../types';\n\ntype StatusFilter = 'ALL' | BuiAssessmentStatus;\n\nconst STATUS_TABS: { value: StatusFilter; label: string }[] = [\n { value: 'ALL', label: 'All' },\n { value: 'DRAFT', label: 'Draft' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\ninterface AssessmentFormState {\n title: string;\n description: string;\n type: BuiAssessmentType;\n passingScore: string;\n maxAttempts: string;\n timeLimitMin: string;\n isGraded: boolean;\n}\n\nconst makeEmptyForm = (): AssessmentFormState => ({\n title: '',\n description: '',\n type: 'QUIZ',\n passingScore: '70',\n maxAttempts: '1',\n timeLimitMin: '0',\n isGraded: true,\n});\n\nexport const AssessmentsPage: FC = () => {\n const { navigateTo } = useBuildmyiq();\n\n const [courseId, setCourseId] = useState<string>('');\n const [status, setStatus] = useState<StatusFilter>('ALL');\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<AssessmentFormState>(makeEmptyForm);\n const [formError, setFormError] = useState<string | null>(null);\n\n const coursesQuery = useBuiCourses({ limit: 100 });\n // Fetch the full (unfiltered) list so the tab counts stay accurate; filter client-side.\n const assessmentsQuery = useBuiAssessments(courseId || undefined);\n const createAssessment = useBuiCreateAssessment();\n\n const courses = coursesQuery.data?.items ?? [];\n const assessments = useMemo(() => assessmentsQuery.data ?? [], [assessmentsQuery.data]);\n\n const statusCounts = useMemo(() => {\n const counts: Record<StatusFilter, number> = {\n ALL: assessments.length,\n DRAFT: 0,\n PUBLISHED: 0,\n ARCHIVED: 0,\n };\n for (const a of assessments) counts[a.status] += 1;\n return counts;\n }, [assessments]);\n\n const rows = useMemo(\n () => (status === 'ALL' ? assessments : assessments.filter((a) => a.status === status)),\n [assessments, status]\n );\n\n const totalQuestions = useMemo(\n () => assessments.reduce((sum, a) => sum + (a.questions?.length ?? 0), 0),\n [assessments]\n );\n\n const tabOptions: FilterOption<StatusFilter>[] = STATUS_TABS.map((t) => ({\n value: t.value,\n label: t.label,\n count: statusCounts[t.value],\n }));\n\n const columns: Column<BuiAssessment>[] = [\n {\n key: 'title',\n header: 'Assessment',\n render: (a) => (\n <div className=\"min-w-0\">\n <p className=\"font-semibold text-text-primary\">{a.title}</p>\n {a.description && (\n <p\n className=\"mt-0.5 max-w-md truncate text-xs text-text-secondary\"\n title={a.description}\n >\n {a.description}\n </p>\n )}\n </div>\n ),\n },\n {\n key: 'type',\n header: 'Type',\n render: (a) => <StatusBadge status={a.type} />,\n },\n {\n key: 'status',\n header: 'Status',\n sortValue: (a) => a.status,\n render: (a) => <StatusBadge status={a.status} />,\n },\n {\n key: 'passingScore',\n header: 'Pass',\n align: 'right',\n hideOnMobile: true,\n sortValue: (a) => a.passingScore,\n render: (a) => <span className=\"tabular-nums text-text-secondary\">{a.passingScore}%</span>,\n },\n {\n key: 'questions',\n header: 'Questions',\n align: 'right',\n hideOnMobile: true,\n render: (a) => (\n <span className=\"tabular-nums text-text-secondary\">{a.questions?.length ?? '—'}</span>\n ),\n },\n {\n key: 'updatedAt',\n header: 'Updated',\n hideOnMobile: true,\n sortValue: (a) => a.updatedAt,\n render: (a) => (\n <span className=\"whitespace-nowrap text-text-secondary\">\n {formatRelativeTime(a.updatedAt)}\n </span>\n ),\n },\n ];\n\n const openDialog = () => {\n setForm(makeEmptyForm());\n setFormError(null);\n setDialogOpen(true);\n };\n\n const closeDialog = () => {\n setDialogOpen(false);\n setForm(makeEmptyForm());\n setFormError(null);\n };\n\n const handleCreate = async () => {\n if (!courseId) {\n setFormError('Pick a course first.');\n return;\n }\n if (!form.title.trim()) {\n setFormError('Title is required.');\n return;\n }\n try {\n const created = await createAssessment.mutateAsync({\n courseId,\n title: form.title.trim(),\n description: form.description.trim() || undefined,\n type: form.type,\n passingScore: form.passingScore ? Number(form.passingScore) : undefined,\n maxAttempts: form.maxAttempts ? Number(form.maxAttempts) : undefined,\n timeLimitMin: form.timeLimitMin ? Number(form.timeLimitMin) : undefined,\n isGraded: form.isGraded,\n });\n closeDialog();\n navigateTo(`assessments/${created.id}`);\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to create assessment.');\n }\n };\n\n return (\n <PageLayout\n title=\"Assessments\"\n description=\"Quizzes, exams and graded assignments for every course in your workspace.\"\n titleGradient\n aurora\n actions={\n <Button onClick={openDialog} disabled={!courseId}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New assessment\n </Button>\n }\n >\n <GlassCard treatment=\"plain\" className=\"mb-5 p-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end\">\n <div className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Course\n </span>\n <Select\n value={courseId}\n onValueChange={(v) => {\n setCourseId(v);\n setStatus('ALL');\n }}\n >\n <SelectTrigger className=\"w-full sm:w-72\">\n <SelectValue placeholder=\"Select a course\" />\n </SelectTrigger>\n <SelectContent>\n {courses.map((c) => (\n <SelectItem key={c.id} value={c.id}>\n {c.title}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {coursesQuery.isSuccess && courses.length === 0 && (\n <p className=\"text-xs text-text-secondary\">\n No courses yet — create one in Authoring first.\n </p>\n )}\n </div>\n {courseId && (\n <div className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Status\n </span>\n <FilterTabs options={tabOptions} value={status} onChange={setStatus} />\n </div>\n )}\n </div>\n </GlassCard>\n\n {courseId && assessmentsQuery.isSuccess && assessments.length > 0 && (\n <div className=\"mb-5 grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <MetricsCard\n icon={<ClipboardList className=\"h-5 w-5\" />}\n value={statusCounts.ALL}\n label=\"Assessments\"\n />\n <MetricsCard\n icon={<CheckCircle2 className=\"h-5 w-5\" />}\n value={statusCounts.PUBLISHED}\n label=\"Published\"\n accent=\"success\"\n />\n <MetricsCard\n icon={<FileEdit className=\"h-5 w-5\" />}\n value={statusCounts.DRAFT}\n label=\"Drafts\"\n />\n <MetricsCard\n icon={<ListChecks className=\"h-5 w-5\" />}\n value={totalQuestions}\n label=\"Questions\"\n />\n </div>\n )}\n\n {!courseId ? (\n <EmptyState\n illustration=\"onboarding\"\n icon={<ClipboardList className=\"h-10 w-10\" />}\n title=\"Pick a course to see its assessments\"\n description=\"Assessments are scoped to a course. Choose a course above to view, filter and create its quizzes and exams.\"\n />\n ) : assessmentsQuery.isLoading ? (\n <LoadingView label=\"Loading assessments…\" />\n ) : assessmentsQuery.isError ? (\n <ErrorView\n message=\"Couldn't load assessments for this course.\"\n onRetry={() => assessmentsQuery.refetch()}\n />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<ClipboardList className=\"h-10 w-10\" />}\n title={status === 'ALL' ? 'No assessments yet' : 'No assessments match this filter'}\n description={\n status === 'ALL'\n ? 'Create the first quiz, exam or assignment for this course.'\n : 'Try a different status filter, or create a new assessment.'\n }\n action={\n <Button onClick={openDialog}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New assessment\n </Button>\n }\n />\n ) : (\n <DataTable\n columns={columns}\n rows={rows}\n rowKey={(a) => a.id}\n onRowClick={(a) => navigateTo(`assessments/${a.id}`)}\n defaultSort={{ key: 'updatedAt', dir: 'desc' }}\n />\n )}\n\n <ResponsiveDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n if (!open) closeDialog();\n else setDialogOpen(true);\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>New assessment</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Add a quiz, exam or assignment to this course. You can add questions after it&apos;s\n created.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"grid gap-4 py-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"assessmentTitle\">Title *</Label>\n <Input\n id=\"assessmentTitle\"\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n placeholder=\"e.g. Module 1 knowledge check\"\n />\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"assessmentDescription\">Description</Label>\n <Textarea\n id=\"assessmentDescription\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n placeholder=\"What this assessment covers and how it's graded.\"\n rows={2}\n />\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"assessmentType\">Type</Label>\n <Select\n value={form.type}\n onValueChange={(v) => setForm({ ...form, type: v as BuiAssessmentType })}\n >\n <SelectTrigger id=\"assessmentType\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ASSESSMENT_TYPES.map((t) => (\n <SelectItem key={t} value={t}>\n {formatEnumLabel(t)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"passingScore\">Passing score (%)</Label>\n <Input\n id=\"passingScore\"\n type=\"number\"\n min=\"0\"\n max=\"100\"\n step=\"1\"\n value={form.passingScore}\n onChange={(e) => setForm({ ...form, passingScore: e.target.value })}\n placeholder=\"70\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"maxAttempts\">Max attempts</Label>\n <Input\n id=\"maxAttempts\"\n type=\"number\"\n min=\"1\"\n step=\"1\"\n value={form.maxAttempts}\n onChange={(e) => setForm({ ...form, maxAttempts: e.target.value })}\n placeholder=\"1\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"timeLimitMin\">Time limit (minutes)</Label>\n <Input\n id=\"timeLimitMin\"\n type=\"number\"\n min=\"0\"\n step=\"1\"\n value={form.timeLimitMin}\n onChange={(e) => setForm({ ...form, timeLimitMin: e.target.value })}\n placeholder=\"0 = no limit\"\n />\n </div>\n </div>\n\n <div className=\"flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface px-3 py-2.5\">\n <div className=\"min-w-0\">\n <Label htmlFor=\"isGraded\" className=\"cursor-pointer\">\n Graded\n </Label>\n <p className=\"text-xs text-text-secondary\">\n Contributes to the learner&apos;s score and pass/fail outcome.\n </p>\n </div>\n <Switch\n id=\"isGraded\"\n checked={form.isGraded}\n onCheckedChange={(checked) => setForm({ ...form, isGraded: checked })}\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={closeDialog}>\n Cancel\n </Button>\n <Button onClick={handleCreate} disabled={createAssessment.isPending}>\n {createAssessment.isPending ? 'Creating…' : 'Create assessment'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TakeAssessmentPage.d.ts","sourceRoot":"","sources":["../../../../src/buildmyiq/pages/assessments/TakeAssessmentPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAkChC,eAAO,MAAM,kBAAkB,EAAE,EA8QhC,CAAC"}
1
+ {"version":3,"file":"TakeAssessmentPage.d.ts","sourceRoot":"","sources":["../../../../src/buildmyiq/pages/assessments/TakeAssessmentPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAa,MAAM,OAAO,CAAC;AA8D3C,eAAO,MAAM,kBAAkB,EAAE,EA+VhC,CAAC"}