@burdenoff/microfe-buildmyiq 2026.525.1 → 2026.705.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/buildmyiq/BuildmyiqRoot.js +123 -0
  2. package/dist/buildmyiq/BuildmyiqRoot.js.map +1 -0
  3. package/dist/buildmyiq/BuildmyiqRoutes.js +84 -0
  4. package/dist/buildmyiq/BuildmyiqRoutes.js.map +1 -0
  5. package/dist/buildmyiq/components/BuiDiscussion.js +109 -0
  6. package/dist/buildmyiq/components/BuiDiscussion.js.map +1 -0
  7. package/dist/buildmyiq/components/BuiTags.js +149 -0
  8. package/dist/buildmyiq/components/BuiTags.js.map +1 -0
  9. package/dist/buildmyiq/components/DataTable.js +71 -0
  10. package/dist/buildmyiq/components/DataTable.js.map +1 -0
  11. package/dist/buildmyiq/components/EmptyState.js +35 -0
  12. package/dist/buildmyiq/components/EmptyState.js.map +1 -0
  13. package/dist/buildmyiq/components/EvidenceUpload.js +93 -0
  14. package/dist/buildmyiq/components/EvidenceUpload.js.map +1 -0
  15. package/dist/buildmyiq/components/FileLink.js +36 -0
  16. package/dist/buildmyiq/components/FileLink.js.map +1 -0
  17. package/dist/buildmyiq/components/FilterTabs.js +27 -0
  18. package/dist/buildmyiq/components/FilterTabs.js.map +1 -0
  19. package/dist/buildmyiq/components/MetricsCard.js +64 -0
  20. package/dist/buildmyiq/components/MetricsCard.js.map +1 -0
  21. package/dist/buildmyiq/components/MiniBar.js +22 -0
  22. package/dist/buildmyiq/components/MiniBar.js.map +1 -0
  23. package/dist/buildmyiq/components/PageLayout.js +38 -0
  24. package/dist/buildmyiq/components/PageLayout.js.map +1 -0
  25. package/dist/buildmyiq/components/Pagination.js +50 -0
  26. package/dist/buildmyiq/components/Pagination.js.map +1 -0
  27. package/dist/buildmyiq/components/StateViews.js +49 -0
  28. package/dist/buildmyiq/components/StateViews.js.map +1 -0
  29. package/dist/buildmyiq/components/StatusBadge.js +60 -0
  30. package/dist/buildmyiq/components/StatusBadge.js.map +1 -0
  31. package/dist/buildmyiq/components/Tabs.js +31 -0
  32. package/dist/buildmyiq/components/Tabs.js.map +1 -0
  33. package/dist/buildmyiq/components/index.js +14 -0
  34. package/dist/buildmyiq/context/BuildmyiqContext.js +85 -0
  35. package/dist/buildmyiq/context/BuildmyiqContext.js.map +1 -0
  36. package/dist/buildmyiq/context/index.js +1 -0
  37. package/dist/buildmyiq/hooks/index.js +5 -0
  38. package/dist/buildmyiq/hooks/useBuiComments.js +45 -0
  39. package/dist/buildmyiq/hooks/useBuiComments.js.map +1 -0
  40. package/dist/buildmyiq/hooks/useBuiFiles.js +81 -0
  41. package/dist/buildmyiq/hooks/useBuiFiles.js.map +1 -0
  42. package/dist/buildmyiq/hooks/useBuiTags.js +89 -0
  43. package/dist/buildmyiq/hooks/useBuiTags.js.map +1 -0
  44. package/dist/buildmyiq/hooks/useBuildmyiqApi.js +412 -0
  45. package/dist/buildmyiq/hooks/useBuildmyiqApi.js.map +1 -0
  46. package/dist/buildmyiq/hooks/useCursorPager.js +25 -0
  47. package/dist/buildmyiq/hooks/useCursorPager.js.map +1 -0
  48. package/dist/buildmyiq/index.js +6 -3
  49. package/dist/buildmyiq/pages/DashboardPage.js +134 -247
  50. package/dist/buildmyiq/pages/DashboardPage.js.map +1 -1
  51. package/dist/buildmyiq/pages/_shared/CourseCard.js +74 -0
  52. package/dist/buildmyiq/pages/_shared/CourseCard.js.map +1 -0
  53. package/dist/buildmyiq/pages/_shared/index.js +1 -0
  54. package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.js +499 -0
  55. package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.js.map +1 -0
  56. package/dist/buildmyiq/pages/assessments/AssessmentsPage.js +390 -0
  57. package/dist/buildmyiq/pages/assessments/AssessmentsPage.js.map +1 -0
  58. package/dist/buildmyiq/pages/authoring/AuthoringPage.js +252 -0
  59. package/dist/buildmyiq/pages/authoring/AuthoringPage.js.map +1 -0
  60. package/dist/buildmyiq/pages/authoring/CourseBuilderPage.js +680 -0
  61. package/dist/buildmyiq/pages/authoring/CourseBuilderPage.js.map +1 -0
  62. package/dist/buildmyiq/pages/authoring/_forms.js +54 -0
  63. package/dist/buildmyiq/pages/authoring/_forms.js.map +1 -0
  64. package/dist/buildmyiq/pages/catalog/CatalogPage.js +97 -0
  65. package/dist/buildmyiq/pages/catalog/CatalogPage.js.map +1 -0
  66. package/dist/buildmyiq/pages/catalog/CourseDetailPage.js +354 -0
  67. package/dist/buildmyiq/pages/catalog/CourseDetailPage.js.map +1 -0
  68. package/dist/buildmyiq/pages/certificates/CertificatesPage.js +363 -0
  69. package/dist/buildmyiq/pages/certificates/CertificatesPage.js.map +1 -0
  70. package/dist/buildmyiq/pages/cohorts/CohortsPage.js +339 -0
  71. package/dist/buildmyiq/pages/cohorts/CohortsPage.js.map +1 -0
  72. package/dist/buildmyiq/pages/learning/LessonPlayerPage.js +303 -0
  73. package/dist/buildmyiq/pages/learning/LessonPlayerPage.js.map +1 -0
  74. package/dist/buildmyiq/pages/learning/MyLearningPage.js +187 -0
  75. package/dist/buildmyiq/pages/learning/MyLearningPage.js.map +1 -0
  76. package/dist/buildmyiq/pages/skills/SkillsPage.js +230 -0
  77. package/dist/buildmyiq/pages/skills/SkillsPage.js.map +1 -0
  78. package/dist/buildmyiq/pages/submissions/SubmissionsPage.js +433 -0
  79. package/dist/buildmyiq/pages/submissions/SubmissionsPage.js.map +1 -0
  80. package/dist/buildmyiq/types/index.js +44 -0
  81. package/dist/buildmyiq/types/index.js.map +1 -0
  82. package/dist/buildmyiq/utils/cn.js +10 -0
  83. package/dist/buildmyiq/utils/cn.js.map +1 -0
  84. package/dist/buildmyiq/utils/formatters.js +62 -0
  85. package/dist/buildmyiq/utils/formatters.js.map +1 -0
  86. package/dist/buildmyiq/utils/navigation.js +2 -1
  87. package/dist/buildmyiq/utils/navigation.js.map +1 -1
  88. package/dist/index.js +6 -4
  89. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  90. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  91. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
  92. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  93. package/package.json +3 -3
  94. package/dist/buildmyiq/BuildMyIQRoot.js +0 -329
  95. package/dist/buildmyiq/BuildMyIQRoot.js.map +0 -1
  96. package/dist/buildmyiq/BuildMyIQRoutes.js +0 -171
  97. package/dist/buildmyiq/BuildMyIQRoutes.js.map +0 -1
  98. package/dist/buildmyiq/pages/AdminAdminAnalyticsPagePage.js +0 -271
  99. package/dist/buildmyiq/pages/AdminAdminAnalyticsPagePage.js.map +0 -1
  100. package/dist/buildmyiq/pages/AdminAdminCoursesPagePage.js +0 -212
  101. package/dist/buildmyiq/pages/AdminAdminCoursesPagePage.js.map +0 -1
  102. package/dist/buildmyiq/pages/AdminAdminUsersPagePage.js +0 -235
  103. package/dist/buildmyiq/pages/AdminAdminUsersPagePage.js.map +0 -1
  104. package/dist/buildmyiq/pages/AdminIndexPage.js +0 -274
  105. package/dist/buildmyiq/pages/AdminIndexPage.js.map +0 -1
  106. package/dist/buildmyiq/pages/AiAichatPagePage.js +0 -209
  107. package/dist/buildmyiq/pages/AiAichatPagePage.js.map +0 -1
  108. package/dist/buildmyiq/pages/AiAicontentGenerationPagePage.js +0 -318
  109. package/dist/buildmyiq/pages/AiAicontentGenerationPagePage.js.map +0 -1
  110. package/dist/buildmyiq/pages/AiAitutoringPagePage.js +0 -290
  111. package/dist/buildmyiq/pages/AiAitutoringPagePage.js.map +0 -1
  112. package/dist/buildmyiq/pages/AiIndexPage.js +0 -191
  113. package/dist/buildmyiq/pages/AiIndexPage.js.map +0 -1
  114. package/dist/buildmyiq/pages/AssessmentsAssessmentBuilderPagePage.js +0 -290
  115. package/dist/buildmyiq/pages/AssessmentsAssessmentBuilderPagePage.js.map +0 -1
  116. package/dist/buildmyiq/pages/AssessmentsAssessmentGradingPagePage.js +0 -215
  117. package/dist/buildmyiq/pages/AssessmentsAssessmentGradingPagePage.js.map +0 -1
  118. package/dist/buildmyiq/pages/AssessmentsAssessmentResultsPagePage.js +0 -224
  119. package/dist/buildmyiq/pages/AssessmentsAssessmentResultsPagePage.js.map +0 -1
  120. package/dist/buildmyiq/pages/AssessmentsAssessmentTakePagePage.js +0 -174
  121. package/dist/buildmyiq/pages/AssessmentsAssessmentTakePagePage.js.map +0 -1
  122. package/dist/buildmyiq/pages/AssessmentsIndexPage.js +0 -174
  123. package/dist/buildmyiq/pages/AssessmentsIndexPage.js.map +0 -1
  124. package/dist/buildmyiq/pages/CalendarPage.js +0 -242
  125. package/dist/buildmyiq/pages/CalendarPage.js.map +0 -1
  126. package/dist/buildmyiq/pages/CommunicationAnnouncementsPagePage.js +0 -180
  127. package/dist/buildmyiq/pages/CommunicationAnnouncementsPagePage.js.map +0 -1
  128. package/dist/buildmyiq/pages/CommunicationForumsPagePage.js +0 -154
  129. package/dist/buildmyiq/pages/CommunicationForumsPagePage.js.map +0 -1
  130. package/dist/buildmyiq/pages/CommunicationIndexPage.js +0 -191
  131. package/dist/buildmyiq/pages/CommunicationIndexPage.js.map +0 -1
  132. package/dist/buildmyiq/pages/CommunicationMessagesPagePage.js +0 -261
  133. package/dist/buildmyiq/pages/CommunicationMessagesPagePage.js.map +0 -1
  134. package/dist/buildmyiq/pages/CoursesCourseContentPagePage.js +0 -164
  135. package/dist/buildmyiq/pages/CoursesCourseContentPagePage.js.map +0 -1
  136. package/dist/buildmyiq/pages/CoursesCourseCreatePagePage.js +0 -239
  137. package/dist/buildmyiq/pages/CoursesCourseCreatePagePage.js.map +0 -1
  138. package/dist/buildmyiq/pages/CoursesCourseDashboardPagePage.js +0 -368
  139. package/dist/buildmyiq/pages/CoursesCourseDashboardPagePage.js.map +0 -1
  140. package/dist/buildmyiq/pages/CoursesCourseDetailPagePage.js +0 -219
  141. package/dist/buildmyiq/pages/CoursesCourseDetailPagePage.js.map +0 -1
  142. package/dist/buildmyiq/pages/CoursesCourseListPagePage.js +0 -153
  143. package/dist/buildmyiq/pages/CoursesCourseListPagePage.js.map +0 -1
  144. package/dist/buildmyiq/pages/CoursesIndexPage.js +0 -138
  145. package/dist/buildmyiq/pages/CoursesIndexPage.js.map +0 -1
  146. package/dist/buildmyiq/pages/MessagesPage.js +0 -261
  147. package/dist/buildmyiq/pages/MessagesPage.js.map +0 -1
  148. package/dist/buildmyiq/pages/ProfileProgressPage.js +0 -194
  149. package/dist/buildmyiq/pages/ProfileProgressPage.js.map +0 -1
  150. package/dist/buildmyiq/pages/TeachingAnalyticsPage.js +0 -243
  151. package/dist/buildmyiq/pages/TeachingAnalyticsPage.js.map +0 -1
  152. package/dist/buildmyiq/pages/TeachingContentPage.js +0 -165
  153. package/dist/buildmyiq/pages/TeachingContentPage.js.map +0 -1
  154. package/dist/buildmyiq/pages/TeachingCoursesPage.js +0 -151
  155. package/dist/buildmyiq/pages/TeachingCoursesPage.js.map +0 -1
  156. package/dist/buildmyiq/pages/TeachingGradingPage.js +0 -204
  157. package/dist/buildmyiq/pages/TeachingGradingPage.js.map +0 -1
  158. package/dist/buildmyiq/pages/TeachingIndexPage.js +0 -220
  159. package/dist/buildmyiq/pages/TeachingIndexPage.js.map +0 -1
  160. package/dist/buildmyiq/pages/TeachingLessonPlansPage.js +0 -157
  161. package/dist/buildmyiq/pages/TeachingLessonPlansPage.js.map +0 -1
  162. package/dist/buildmyiq/pages/TeachingQuestionsPage.js +0 -184
  163. package/dist/buildmyiq/pages/TeachingQuestionsPage.js.map +0 -1
  164. package/dist/buildmyiq/pages/TeachingStudentsPage.js +0 -204
  165. package/dist/buildmyiq/pages/TeachingStudentsPage.js.map +0 -1
  166. package/dist/buildmyiq/providers/BuildMyIQProvider.js +0 -27
  167. package/dist/buildmyiq/providers/BuildMyIQProvider.js.map +0 -1
  168. package/dist/buildmyiq/store/buildmyiqStore.js +0 -1160
  169. package/dist/buildmyiq/store/buildmyiqStore.js.map +0 -1
@@ -0,0 +1,390 @@
1
+ import { useBuildmyiq as e } from "../../context/BuildmyiqContext.js";
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";
9
+ import "../../context/index.js";
10
+ import { useBuiAssessments as ee, useBuiCourses as u, useBuiCreateAssessment as d } from "../../hooks/useBuildmyiqApi.js";
11
+ import "../../hooks/index.js";
12
+ 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";
16
+ 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
+ //#region src/buildmyiq/pages/assessments/AssessmentsPage.tsx
19
+ var re = [
20
+ {
21
+ value: "ALL",
22
+ label: "All"
23
+ },
24
+ {
25
+ value: "DRAFT",
26
+ label: "Draft"
27
+ },
28
+ {
29
+ value: "PUBLISHED",
30
+ label: "Published"
31
+ },
32
+ {
33
+ value: "ARCHIVED",
34
+ label: "Archived"
35
+ }
36
+ ], P = () => ({
37
+ title: "",
38
+ description: "",
39
+ type: "QUIZ",
40
+ passingScore: "70",
41
+ maxAttempts: "1",
42
+ timeLimitMin: "0",
43
+ 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(() => {
46
+ let e = {
47
+ ALL: X.length,
48
+ DRAFT: 0,
49
+ PUBLISHED: 0,
50
+ ARCHIVED: 0
51
+ };
52
+ for (let t of X) e[t.status] += 1;
53
+ return e;
54
+ }, [X]), Z = p(() => R === "ALL" ? X : X.filter((e) => e.status === R), [X, R]), ae = re.map((e) => ({
55
+ value: e.value,
56
+ label: e.label,
57
+ count: ie[e.value]
58
+ })), oe = [
59
+ {
60
+ key: "title",
61
+ header: "Assessment",
62
+ render: (e) => /* @__PURE__ */ v("div", {
63
+ className: "min-w-0",
64
+ children: [/* @__PURE__ */ _("p", {
65
+ className: "font-semibold text-text-primary",
66
+ children: e.title
67
+ }), e.description && /* @__PURE__ */ _("p", {
68
+ className: "mt-0.5 max-w-md truncate text-xs text-text-secondary",
69
+ title: e.description,
70
+ children: e.description
71
+ })]
72
+ })
73
+ },
74
+ {
75
+ key: "type",
76
+ header: "Type",
77
+ render: (e) => /* @__PURE__ */ _(i, { status: e.type })
78
+ },
79
+ {
80
+ key: "status",
81
+ header: "Status",
82
+ sortValue: (e) => e.status,
83
+ render: (e) => /* @__PURE__ */ _(i, { status: e.status })
84
+ },
85
+ {
86
+ key: "passingScore",
87
+ header: "Pass",
88
+ align: "right",
89
+ hideOnMobile: !0,
90
+ sortValue: (e) => e.passingScore,
91
+ render: (e) => /* @__PURE__ */ v("span", {
92
+ className: "tabular-nums text-text-secondary",
93
+ children: [e.passingScore, "%"]
94
+ })
95
+ },
96
+ {
97
+ key: "questions",
98
+ header: "Questions",
99
+ align: "right",
100
+ hideOnMobile: !0,
101
+ render: (e) => /* @__PURE__ */ _("span", {
102
+ className: "tabular-nums text-text-secondary",
103
+ children: e.questions?.length ?? "—"
104
+ })
105
+ },
106
+ {
107
+ key: "updatedAt",
108
+ header: "Updated",
109
+ hideOnMobile: !0,
110
+ sortValue: (e) => e.updatedAt,
111
+ render: (e) => /* @__PURE__ */ _("span", {
112
+ className: "whitespace-nowrap text-text-secondary",
113
+ children: r(e.updatedAt)
114
+ })
115
+ }
116
+ ], Q = () => {
117
+ U(P()), G(null), V(!0);
118
+ }, $ = () => {
119
+ V(!1), U(P()), G(null);
120
+ };
121
+ return /* @__PURE__ */ v(t, {
122
+ title: "Assessments",
123
+ description: "Quizzes, exams and graded assignments for every course in your workspace.",
124
+ titleGradient: !0,
125
+ aurora: !0,
126
+ actions: /* @__PURE__ */ v(y, {
127
+ onClick: Q,
128
+ disabled: !I,
129
+ children: [/* @__PURE__ */ _(g, { className: "mr-1.5 h-4 w-4" }), " New assessment"]
130
+ }),
131
+ children: [
132
+ /* @__PURE__ */ _(te, {
133
+ treatment: "plain",
134
+ className: "mb-5 p-4",
135
+ children: /* @__PURE__ */ v("div", {
136
+ className: "flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end",
137
+ children: [/* @__PURE__ */ v("div", {
138
+ className: "grid gap-1.5",
139
+ children: [
140
+ /* @__PURE__ */ _("span", {
141
+ className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
142
+ children: "Course"
143
+ }),
144
+ /* @__PURE__ */ v(O, {
145
+ value: I,
146
+ onValueChange: (e) => {
147
+ L(e), z("ALL");
148
+ },
149
+ children: [/* @__PURE__ */ _(j, {
150
+ className: "w-full sm:w-72",
151
+ children: /* @__PURE__ */ _(M, { placeholder: "Select a course" })
152
+ }), /* @__PURE__ */ _(k, { children: Y.map((e) => /* @__PURE__ */ _(A, {
153
+ value: e.id,
154
+ children: e.title
155
+ }, e.id)) })]
156
+ }),
157
+ K.isSuccess && Y.length === 0 && /* @__PURE__ */ _("p", {
158
+ className: "text-xs text-text-secondary",
159
+ children: "No courses yet — create one in Authoring first."
160
+ })
161
+ ]
162
+ }), I && /* @__PURE__ */ v("div", {
163
+ className: "grid gap-1.5",
164
+ children: [/* @__PURE__ */ _("span", {
165
+ className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
166
+ children: "Status"
167
+ }), /* @__PURE__ */ _(l, {
168
+ options: ae,
169
+ value: R,
170
+ onChange: z
171
+ })]
172
+ })]
173
+ })
174
+ }),
175
+ I ? q.isLoading ? /* @__PURE__ */ _(s, { label: "Loading assessments…" }) : q.isError ? /* @__PURE__ */ _(o, {
176
+ message: "Couldn't load assessments for this course.",
177
+ onRetry: () => q.refetch()
178
+ }) : Z.length === 0 ? /* @__PURE__ */ _(a, {
179
+ 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.",
183
+ action: /* @__PURE__ */ v(y, {
184
+ onClick: Q,
185
+ children: [/* @__PURE__ */ _(g, { className: "mr-1.5 h-4 w-4" }), " New assessment"]
186
+ })
187
+ }) : /* @__PURE__ */ _(c, {
188
+ columns: oe,
189
+ rows: Z,
190
+ rowKey: (e) => e.id,
191
+ onRowClick: (e) => F(`assessments/${e.id}`),
192
+ defaultSort: {
193
+ key: "updatedAt",
194
+ dir: "desc"
195
+ }
196
+ }) : /* @__PURE__ */ _(a, {
197
+ illustration: "onboarding",
198
+ icon: /* @__PURE__ */ _(h, { className: "h-10 w-10" }),
199
+ title: "Pick a course to see its assessments",
200
+ description: "Assessments are scoped to a course. Choose a course above to view, filter and create its quizzes and exams."
201
+ }),
202
+ /* @__PURE__ */ _(S, {
203
+ open: B,
204
+ onOpenChange: (e) => {
205
+ e ? V(!0) : $();
206
+ },
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." })] }),
209
+ /* @__PURE__ */ v("div", {
210
+ className: "grid gap-4 py-2",
211
+ children: [
212
+ /* @__PURE__ */ v("div", {
213
+ className: "grid gap-1.5",
214
+ children: [/* @__PURE__ */ _(x, {
215
+ htmlFor: "assessmentTitle",
216
+ children: "Title *"
217
+ }), /* @__PURE__ */ _(b, {
218
+ id: "assessmentTitle",
219
+ value: H.title,
220
+ onChange: (e) => U({
221
+ ...H,
222
+ title: e.target.value
223
+ }),
224
+ placeholder: "e.g. Module 1 knowledge check"
225
+ })]
226
+ }),
227
+ /* @__PURE__ */ v("div", {
228
+ className: "grid gap-1.5",
229
+ children: [/* @__PURE__ */ _(x, {
230
+ htmlFor: "assessmentDescription",
231
+ children: "Description"
232
+ }), /* @__PURE__ */ _(ne, {
233
+ id: "assessmentDescription",
234
+ value: H.description,
235
+ onChange: (e) => U({
236
+ ...H,
237
+ description: e.target.value
238
+ }),
239
+ placeholder: "What this assessment covers and how it's graded.",
240
+ rows: 2
241
+ })]
242
+ }),
243
+ /* @__PURE__ */ v("div", {
244
+ className: "grid gap-2 sm:grid-cols-2",
245
+ children: [/* @__PURE__ */ v("div", {
246
+ className: "grid gap-1.5",
247
+ children: [/* @__PURE__ */ _(x, {
248
+ htmlFor: "assessmentType",
249
+ children: "Type"
250
+ }), /* @__PURE__ */ v(O, {
251
+ value: H.type,
252
+ onValueChange: (e) => U({
253
+ ...H,
254
+ type: e
255
+ }),
256
+ children: [/* @__PURE__ */ _(j, {
257
+ id: "assessmentType",
258
+ children: /* @__PURE__ */ _(M, {})
259
+ }), /* @__PURE__ */ _(k, { children: f.map((e) => /* @__PURE__ */ _(A, {
260
+ value: e,
261
+ children: n(e)
262
+ }, e)) })]
263
+ })]
264
+ }), /* @__PURE__ */ v("div", {
265
+ className: "grid gap-1.5",
266
+ children: [/* @__PURE__ */ _(x, {
267
+ htmlFor: "passingScore",
268
+ children: "Passing score (%)"
269
+ }), /* @__PURE__ */ _(b, {
270
+ id: "passingScore",
271
+ type: "number",
272
+ min: "0",
273
+ max: "100",
274
+ step: "1",
275
+ value: H.passingScore,
276
+ onChange: (e) => U({
277
+ ...H,
278
+ passingScore: e.target.value
279
+ }),
280
+ placeholder: "70"
281
+ })]
282
+ })]
283
+ }),
284
+ /* @__PURE__ */ v("div", {
285
+ className: "grid gap-2 sm:grid-cols-2",
286
+ children: [/* @__PURE__ */ v("div", {
287
+ className: "grid gap-1.5",
288
+ children: [/* @__PURE__ */ _(x, {
289
+ htmlFor: "maxAttempts",
290
+ children: "Max attempts"
291
+ }), /* @__PURE__ */ _(b, {
292
+ id: "maxAttempts",
293
+ type: "number",
294
+ min: "1",
295
+ step: "1",
296
+ value: H.maxAttempts,
297
+ onChange: (e) => U({
298
+ ...H,
299
+ maxAttempts: e.target.value
300
+ }),
301
+ placeholder: "1"
302
+ })]
303
+ }), /* @__PURE__ */ v("div", {
304
+ className: "grid gap-1.5",
305
+ children: [/* @__PURE__ */ _(x, {
306
+ htmlFor: "timeLimitMin",
307
+ children: "Time limit (minutes)"
308
+ }), /* @__PURE__ */ _(b, {
309
+ id: "timeLimitMin",
310
+ type: "number",
311
+ min: "0",
312
+ step: "1",
313
+ value: H.timeLimitMin,
314
+ onChange: (e) => U({
315
+ ...H,
316
+ timeLimitMin: e.target.value
317
+ }),
318
+ placeholder: "0 = no limit"
319
+ })]
320
+ })]
321
+ }),
322
+ /* @__PURE__ */ v("div", {
323
+ className: "flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface px-3 py-2.5",
324
+ children: [/* @__PURE__ */ v("div", {
325
+ className: "min-w-0",
326
+ children: [/* @__PURE__ */ _(x, {
327
+ htmlFor: "isGraded",
328
+ className: "cursor-pointer",
329
+ children: "Graded"
330
+ }), /* @__PURE__ */ _("p", {
331
+ className: "text-xs text-text-secondary",
332
+ children: "Contributes to the learner's score and pass/fail outcome."
333
+ })]
334
+ }), /* @__PURE__ */ _(N, {
335
+ id: "isGraded",
336
+ checked: H.isGraded,
337
+ onCheckedChange: (e) => U({
338
+ ...H,
339
+ isGraded: e
340
+ })
341
+ })]
342
+ }),
343
+ W && /* @__PURE__ */ _("p", {
344
+ className: "text-sm text-status-error-text",
345
+ children: W
346
+ })
347
+ ]
348
+ }),
349
+ /* @__PURE__ */ v(T, { children: [/* @__PURE__ */ _(y, {
350
+ variant: "outline",
351
+ onClick: $,
352
+ children: "Cancel"
353
+ }), /* @__PURE__ */ _(y, {
354
+ onClick: async () => {
355
+ if (!I) {
356
+ G("Pick a course first.");
357
+ return;
358
+ }
359
+ if (!H.title.trim()) {
360
+ G("Title is required.");
361
+ return;
362
+ }
363
+ 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
373
+ });
374
+ $(), F(`assessments/${e.id}`);
375
+ } catch (e) {
376
+ G(e instanceof Error ? e.message : "Failed to create assessment.");
377
+ }
378
+ },
379
+ disabled: J.isPending,
380
+ children: J.isPending ? "Creating…" : "Create assessment"
381
+ })] })
382
+ ] })
383
+ })
384
+ ]
385
+ });
386
+ };
387
+ //#endregion
388
+ export { F as AssessmentsPage };
389
+
390
+ //# sourceMappingURL=AssessmentsPage.js.map
@@ -0,0 +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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"}