@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.
- package/dist/buildmyiq/BuildmyiqRoot.js +123 -0
- package/dist/buildmyiq/BuildmyiqRoot.js.map +1 -0
- package/dist/buildmyiq/BuildmyiqRoutes.js +84 -0
- package/dist/buildmyiq/BuildmyiqRoutes.js.map +1 -0
- package/dist/buildmyiq/components/BuiDiscussion.js +109 -0
- package/dist/buildmyiq/components/BuiDiscussion.js.map +1 -0
- package/dist/buildmyiq/components/BuiTags.js +149 -0
- package/dist/buildmyiq/components/BuiTags.js.map +1 -0
- package/dist/buildmyiq/components/DataTable.js +71 -0
- package/dist/buildmyiq/components/DataTable.js.map +1 -0
- package/dist/buildmyiq/components/EmptyState.js +35 -0
- package/dist/buildmyiq/components/EmptyState.js.map +1 -0
- package/dist/buildmyiq/components/EvidenceUpload.js +93 -0
- package/dist/buildmyiq/components/EvidenceUpload.js.map +1 -0
- package/dist/buildmyiq/components/FileLink.js +36 -0
- package/dist/buildmyiq/components/FileLink.js.map +1 -0
- package/dist/buildmyiq/components/FilterTabs.js +27 -0
- package/dist/buildmyiq/components/FilterTabs.js.map +1 -0
- package/dist/buildmyiq/components/MetricsCard.js +64 -0
- package/dist/buildmyiq/components/MetricsCard.js.map +1 -0
- package/dist/buildmyiq/components/MiniBar.js +22 -0
- package/dist/buildmyiq/components/MiniBar.js.map +1 -0
- package/dist/buildmyiq/components/PageLayout.js +38 -0
- package/dist/buildmyiq/components/PageLayout.js.map +1 -0
- package/dist/buildmyiq/components/Pagination.js +50 -0
- package/dist/buildmyiq/components/Pagination.js.map +1 -0
- package/dist/buildmyiq/components/StateViews.js +49 -0
- package/dist/buildmyiq/components/StateViews.js.map +1 -0
- package/dist/buildmyiq/components/StatusBadge.js +60 -0
- package/dist/buildmyiq/components/StatusBadge.js.map +1 -0
- package/dist/buildmyiq/components/Tabs.js +31 -0
- package/dist/buildmyiq/components/Tabs.js.map +1 -0
- package/dist/buildmyiq/components/index.js +14 -0
- package/dist/buildmyiq/context/BuildmyiqContext.js +85 -0
- package/dist/buildmyiq/context/BuildmyiqContext.js.map +1 -0
- package/dist/buildmyiq/context/index.js +1 -0
- package/dist/buildmyiq/hooks/index.js +5 -0
- package/dist/buildmyiq/hooks/useBuiComments.js +45 -0
- package/dist/buildmyiq/hooks/useBuiComments.js.map +1 -0
- package/dist/buildmyiq/hooks/useBuiFiles.js +81 -0
- package/dist/buildmyiq/hooks/useBuiFiles.js.map +1 -0
- package/dist/buildmyiq/hooks/useBuiTags.js +89 -0
- package/dist/buildmyiq/hooks/useBuiTags.js.map +1 -0
- package/dist/buildmyiq/hooks/useBuildmyiqApi.js +412 -0
- package/dist/buildmyiq/hooks/useBuildmyiqApi.js.map +1 -0
- package/dist/buildmyiq/hooks/useCursorPager.js +25 -0
- package/dist/buildmyiq/hooks/useCursorPager.js.map +1 -0
- package/dist/buildmyiq/index.js +6 -3
- package/dist/buildmyiq/pages/DashboardPage.js +134 -247
- package/dist/buildmyiq/pages/DashboardPage.js.map +1 -1
- package/dist/buildmyiq/pages/_shared/CourseCard.js +74 -0
- package/dist/buildmyiq/pages/_shared/CourseCard.js.map +1 -0
- package/dist/buildmyiq/pages/_shared/index.js +1 -0
- package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.js +499 -0
- package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.js.map +1 -0
- package/dist/buildmyiq/pages/assessments/AssessmentsPage.js +390 -0
- package/dist/buildmyiq/pages/assessments/AssessmentsPage.js.map +1 -0
- package/dist/buildmyiq/pages/authoring/AuthoringPage.js +252 -0
- package/dist/buildmyiq/pages/authoring/AuthoringPage.js.map +1 -0
- package/dist/buildmyiq/pages/authoring/CourseBuilderPage.js +680 -0
- package/dist/buildmyiq/pages/authoring/CourseBuilderPage.js.map +1 -0
- package/dist/buildmyiq/pages/authoring/_forms.js +54 -0
- package/dist/buildmyiq/pages/authoring/_forms.js.map +1 -0
- package/dist/buildmyiq/pages/catalog/CatalogPage.js +97 -0
- package/dist/buildmyiq/pages/catalog/CatalogPage.js.map +1 -0
- package/dist/buildmyiq/pages/catalog/CourseDetailPage.js +354 -0
- package/dist/buildmyiq/pages/catalog/CourseDetailPage.js.map +1 -0
- package/dist/buildmyiq/pages/certificates/CertificatesPage.js +363 -0
- package/dist/buildmyiq/pages/certificates/CertificatesPage.js.map +1 -0
- package/dist/buildmyiq/pages/cohorts/CohortsPage.js +339 -0
- package/dist/buildmyiq/pages/cohorts/CohortsPage.js.map +1 -0
- package/dist/buildmyiq/pages/learning/LessonPlayerPage.js +303 -0
- package/dist/buildmyiq/pages/learning/LessonPlayerPage.js.map +1 -0
- package/dist/buildmyiq/pages/learning/MyLearningPage.js +187 -0
- package/dist/buildmyiq/pages/learning/MyLearningPage.js.map +1 -0
- package/dist/buildmyiq/pages/skills/SkillsPage.js +230 -0
- package/dist/buildmyiq/pages/skills/SkillsPage.js.map +1 -0
- package/dist/buildmyiq/pages/submissions/SubmissionsPage.js +433 -0
- package/dist/buildmyiq/pages/submissions/SubmissionsPage.js.map +1 -0
- package/dist/buildmyiq/types/index.js +44 -0
- package/dist/buildmyiq/types/index.js.map +1 -0
- package/dist/buildmyiq/utils/cn.js +10 -0
- package/dist/buildmyiq/utils/cn.js.map +1 -0
- package/dist/buildmyiq/utils/formatters.js +62 -0
- package/dist/buildmyiq/utils/formatters.js.map +1 -0
- package/dist/buildmyiq/utils/navigation.js +2 -1
- package/dist/buildmyiq/utils/navigation.js.map +1 -1
- package/dist/index.js +6 -4
- package/dist/node_modules/clsx/dist/clsx.js +18 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/package.json +3 -3
- package/dist/buildmyiq/BuildMyIQRoot.js +0 -329
- package/dist/buildmyiq/BuildMyIQRoot.js.map +0 -1
- package/dist/buildmyiq/BuildMyIQRoutes.js +0 -171
- package/dist/buildmyiq/BuildMyIQRoutes.js.map +0 -1
- package/dist/buildmyiq/pages/AdminAdminAnalyticsPagePage.js +0 -271
- package/dist/buildmyiq/pages/AdminAdminAnalyticsPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AdminAdminCoursesPagePage.js +0 -212
- package/dist/buildmyiq/pages/AdminAdminCoursesPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AdminAdminUsersPagePage.js +0 -235
- package/dist/buildmyiq/pages/AdminAdminUsersPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AdminIndexPage.js +0 -274
- package/dist/buildmyiq/pages/AdminIndexPage.js.map +0 -1
- package/dist/buildmyiq/pages/AiAichatPagePage.js +0 -209
- package/dist/buildmyiq/pages/AiAichatPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AiAicontentGenerationPagePage.js +0 -318
- package/dist/buildmyiq/pages/AiAicontentGenerationPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AiAitutoringPagePage.js +0 -290
- package/dist/buildmyiq/pages/AiAitutoringPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AiIndexPage.js +0 -191
- package/dist/buildmyiq/pages/AiIndexPage.js.map +0 -1
- package/dist/buildmyiq/pages/AssessmentsAssessmentBuilderPagePage.js +0 -290
- package/dist/buildmyiq/pages/AssessmentsAssessmentBuilderPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AssessmentsAssessmentGradingPagePage.js +0 -215
- package/dist/buildmyiq/pages/AssessmentsAssessmentGradingPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AssessmentsAssessmentResultsPagePage.js +0 -224
- package/dist/buildmyiq/pages/AssessmentsAssessmentResultsPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AssessmentsAssessmentTakePagePage.js +0 -174
- package/dist/buildmyiq/pages/AssessmentsAssessmentTakePagePage.js.map +0 -1
- package/dist/buildmyiq/pages/AssessmentsIndexPage.js +0 -174
- package/dist/buildmyiq/pages/AssessmentsIndexPage.js.map +0 -1
- package/dist/buildmyiq/pages/CalendarPage.js +0 -242
- package/dist/buildmyiq/pages/CalendarPage.js.map +0 -1
- package/dist/buildmyiq/pages/CommunicationAnnouncementsPagePage.js +0 -180
- package/dist/buildmyiq/pages/CommunicationAnnouncementsPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/CommunicationForumsPagePage.js +0 -154
- package/dist/buildmyiq/pages/CommunicationForumsPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/CommunicationIndexPage.js +0 -191
- package/dist/buildmyiq/pages/CommunicationIndexPage.js.map +0 -1
- package/dist/buildmyiq/pages/CommunicationMessagesPagePage.js +0 -261
- package/dist/buildmyiq/pages/CommunicationMessagesPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/CoursesCourseContentPagePage.js +0 -164
- package/dist/buildmyiq/pages/CoursesCourseContentPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/CoursesCourseCreatePagePage.js +0 -239
- package/dist/buildmyiq/pages/CoursesCourseCreatePagePage.js.map +0 -1
- package/dist/buildmyiq/pages/CoursesCourseDashboardPagePage.js +0 -368
- package/dist/buildmyiq/pages/CoursesCourseDashboardPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/CoursesCourseDetailPagePage.js +0 -219
- package/dist/buildmyiq/pages/CoursesCourseDetailPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/CoursesCourseListPagePage.js +0 -153
- package/dist/buildmyiq/pages/CoursesCourseListPagePage.js.map +0 -1
- package/dist/buildmyiq/pages/CoursesIndexPage.js +0 -138
- package/dist/buildmyiq/pages/CoursesIndexPage.js.map +0 -1
- package/dist/buildmyiq/pages/MessagesPage.js +0 -261
- package/dist/buildmyiq/pages/MessagesPage.js.map +0 -1
- package/dist/buildmyiq/pages/ProfileProgressPage.js +0 -194
- package/dist/buildmyiq/pages/ProfileProgressPage.js.map +0 -1
- package/dist/buildmyiq/pages/TeachingAnalyticsPage.js +0 -243
- package/dist/buildmyiq/pages/TeachingAnalyticsPage.js.map +0 -1
- package/dist/buildmyiq/pages/TeachingContentPage.js +0 -165
- package/dist/buildmyiq/pages/TeachingContentPage.js.map +0 -1
- package/dist/buildmyiq/pages/TeachingCoursesPage.js +0 -151
- package/dist/buildmyiq/pages/TeachingCoursesPage.js.map +0 -1
- package/dist/buildmyiq/pages/TeachingGradingPage.js +0 -204
- package/dist/buildmyiq/pages/TeachingGradingPage.js.map +0 -1
- package/dist/buildmyiq/pages/TeachingIndexPage.js +0 -220
- package/dist/buildmyiq/pages/TeachingIndexPage.js.map +0 -1
- package/dist/buildmyiq/pages/TeachingLessonPlansPage.js +0 -157
- package/dist/buildmyiq/pages/TeachingLessonPlansPage.js.map +0 -1
- package/dist/buildmyiq/pages/TeachingQuestionsPage.js +0 -184
- package/dist/buildmyiq/pages/TeachingQuestionsPage.js.map +0 -1
- package/dist/buildmyiq/pages/TeachingStudentsPage.js +0 -204
- package/dist/buildmyiq/pages/TeachingStudentsPage.js.map +0 -1
- package/dist/buildmyiq/providers/BuildMyIQProvider.js +0 -27
- package/dist/buildmyiq/providers/BuildMyIQProvider.js.map +0 -1
- package/dist/buildmyiq/store/buildmyiqStore.js +0 -1160
- 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'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'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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"}
|