@hydralms/components 0.2.0 → 0.3.0

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 (283) hide show
  1. package/dist/StudentProfile-BVfZMbnV.cjs +1 -0
  2. package/dist/StudentProfile-DeMxdrL3.js +3275 -0
  3. package/dist/assessment-toolbar/question-navigator.d.ts +1 -1
  4. package/dist/assessment-toolbar/timer-display.d.ts +1 -1
  5. package/dist/common/index.d.ts +2 -1
  6. package/dist/common/pagination.d.ts +26 -0
  7. package/dist/common/types.d.ts +1 -0
  8. package/dist/components.css +1 -1
  9. package/dist/content/audio-player.d.ts +22 -0
  10. package/dist/content/code-block.d.ts +30 -0
  11. package/dist/content/embed-block.d.ts +28 -0
  12. package/dist/content/index.d.ts +6 -0
  13. package/dist/content/types.d.ts +24 -0
  14. package/dist/curriculum/course-card.d.ts +51 -0
  15. package/dist/curriculum/index.d.ts +2 -0
  16. package/dist/curriculum/types.d.ts +2 -2
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.js +494 -444
  20. package/dist/license/HydraContext.d.ts +16 -0
  21. package/dist/license/ProBadge.d.ts +6 -0
  22. package/dist/license/index.d.ts +7 -0
  23. package/dist/license/tiers.d.ts +3 -0
  24. package/dist/license/useHydraLicense.d.ts +6 -0
  25. package/dist/license/validate.d.ts +13 -0
  26. package/dist/license/withProGate.d.ts +6 -0
  27. package/dist/modules/AssignmentModule/AssignmentModule.d.ts +4 -7
  28. package/dist/modules/AssignmentModule/types.d.ts +5 -1
  29. package/dist/modules/CertificateModule/CertificateModule.d.ts +4 -8
  30. package/dist/modules/CertificateModule/types.d.ts +6 -4
  31. package/dist/modules/CourseCatalogModule/CourseCatalogModule.d.ts +5 -0
  32. package/dist/modules/CourseCatalogModule/types.d.ts +43 -0
  33. package/dist/modules/CoursePlayer/CoursePlayer.d.ts +4 -1
  34. package/dist/modules/DiscussionModule/DiscussionModule.d.ts +4 -7
  35. package/dist/modules/ExamModule/ExamModule.d.ts +4 -7
  36. package/dist/modules/ExamModule/types.d.ts +5 -14
  37. package/dist/modules/FlashcardLab/FlashcardLab.d.ts +4 -1
  38. package/dist/modules/FlashcardLab/types.d.ts +2 -0
  39. package/dist/modules/GradeCenterModule/GradeCenterModule.d.ts +4 -8
  40. package/dist/modules/GradeCenterModule/types.d.ts +2 -0
  41. package/dist/modules/QuizModule/QuizModule.d.ts +4 -1
  42. package/dist/modules/QuizModule/types.d.ts +5 -14
  43. package/dist/modules/StudentDashboardModule/StudentDashboardModule.d.ts +5 -0
  44. package/dist/modules/StudentDashboardModule/types.d.ts +54 -0
  45. package/dist/modules/StudentProfileModule/StudentProfileModule.d.ts +5 -0
  46. package/dist/modules/StudentProfileModule/types.d.ts +43 -0
  47. package/dist/modules/SurveyModule/SurveyModule.d.ts +4 -6
  48. package/dist/modules/SurveyModule/types.d.ts +2 -0
  49. package/dist/modules/_shared/assessment-intro.d.ts +16 -0
  50. package/dist/modules/_shared/assessment-results.d.ts +23 -0
  51. package/dist/modules/_shared/types.d.ts +10 -0
  52. package/dist/modules/_shared/use-timer.d.ts +9 -0
  53. package/dist/modules/index.d.ts +6 -0
  54. package/dist/modules.cjs +1 -1
  55. package/dist/modules.js +1266 -854
  56. package/dist/progress/types.d.ts +2 -0
  57. package/dist/provider/HydraProvider.d.ts +5 -1
  58. package/dist/questions/choice.d.ts +1 -1
  59. package/dist/questions/confidence-indicator.d.ts +37 -0
  60. package/dist/questions/essay.d.ts +1 -1
  61. package/dist/questions/fill-in-the-blank.d.ts +1 -1
  62. package/dist/questions/hotspot.d.ts +1 -1
  63. package/dist/questions/index.d.ts +2 -0
  64. package/dist/questions/inline-choice.d.ts +1 -1
  65. package/dist/questions/matching.d.ts +1 -1
  66. package/dist/questions/multiple-choice.d.ts +1 -1
  67. package/dist/questions/numeric.d.ts +1 -1
  68. package/dist/questions/ordering.d.ts +1 -1
  69. package/dist/questions/question-renderer.d.ts +1 -1
  70. package/dist/questions/scenario.d.ts +1 -1
  71. package/dist/questions/spreadsheet.d.ts +1 -1
  72. package/dist/questions/true-false.d.ts +1 -1
  73. package/dist/sections/AnnouncementFeed/AnnouncementFeed.d.ts +1 -1
  74. package/dist/sections/AnnouncementFeed/types.d.ts +15 -1
  75. package/dist/sections/AssessmentReview/AssessmentReview.d.ts +1 -1
  76. package/dist/sections/AssessmentReview/types.d.ts +6 -0
  77. package/dist/sections/AssignmentSubmission/AssignmentSubmission.d.ts +1 -1
  78. package/dist/sections/AssignmentSubmission/types.d.ts +6 -0
  79. package/dist/sections/CertificateViewer/CertificateViewer.d.ts +1 -1
  80. package/dist/sections/CertificateViewer/certificate-variants.d.ts +42 -0
  81. package/dist/sections/CertificateViewer/types.d.ts +6 -0
  82. package/dist/sections/CourseCatalog/CourseCatalog.d.ts +2 -0
  83. package/dist/sections/CourseCatalog/types.d.ts +80 -0
  84. package/dist/sections/CourseOutline/CourseOutline.d.ts +1 -1
  85. package/dist/sections/CourseOutline/types.d.ts +6 -0
  86. package/dist/sections/DiscussionThread/DiscussionThread.d.ts +1 -1
  87. package/dist/sections/DiscussionThread/types.d.ts +6 -0
  88. package/dist/sections/EnrollmentWizard/EnrollmentWizard.d.ts +2 -0
  89. package/dist/sections/EnrollmentWizard/types.d.ts +66 -0
  90. package/dist/sections/ExamSession/ExamSession.d.ts +1 -1
  91. package/dist/sections/ExamSession/types.d.ts +6 -0
  92. package/dist/sections/FlashcardStudySession/FlashcardStudySession.d.ts +1 -1
  93. package/dist/sections/FlashcardStudySession/types.d.ts +6 -0
  94. package/dist/sections/ForumBoard/ForumBoard.d.ts +1 -1
  95. package/dist/sections/ForumBoard/types.d.ts +14 -0
  96. package/dist/sections/GradebookTable/GradebookTable.d.ts +1 -1
  97. package/dist/sections/GradebookTable/types.d.ts +14 -0
  98. package/dist/sections/LecturePlayer/LecturePlayer.d.ts +1 -1
  99. package/dist/sections/LecturePlayer/types.d.ts +8 -0
  100. package/dist/sections/LessonPage/LessonPage.d.ts +1 -1
  101. package/dist/sections/LessonPage/types.d.ts +6 -0
  102. package/dist/sections/PracticeQuiz/PracticeQuiz.d.ts +1 -1
  103. package/dist/sections/PracticeQuiz/types.d.ts +6 -0
  104. package/dist/sections/ProgressDashboard/ProgressDashboard.d.ts +1 -1
  105. package/dist/sections/ProgressDashboard/types.d.ts +6 -0
  106. package/dist/sections/QuizSession/QuizSession.d.ts +1 -1
  107. package/dist/sections/QuizSession/types.d.ts +6 -0
  108. package/dist/sections/RequirementsChecklist/RequirementsChecklist.d.ts +1 -1
  109. package/dist/sections/RequirementsChecklist/types.d.ts +6 -0
  110. package/dist/sections/ResourceLibrary/ResourceLibrary.d.ts +1 -1
  111. package/dist/sections/ResourceLibrary/types.d.ts +15 -1
  112. package/dist/sections/RubricView/RubricView.d.ts +1 -1
  113. package/dist/sections/RubricView/types.d.ts +6 -0
  114. package/dist/sections/ScrollableQuiz/ScrollableQuiz.d.ts +1 -1
  115. package/dist/sections/ScrollableQuiz/types.d.ts +6 -0
  116. package/dist/sections/StudentProfile/StudentProfile.d.ts +2 -0
  117. package/dist/sections/StudentProfile/types.d.ts +98 -0
  118. package/dist/sections/SurveyForm/SurveyForm.d.ts +1 -1
  119. package/dist/sections/SurveyForm/types.d.ts +6 -0
  120. package/dist/sections/_shared/merge-answers.d.ts +9 -0
  121. package/dist/sections/_shared/section-shell.d.ts +20 -0
  122. package/dist/sections/_shared/use-assessment-session.d.ts +30 -0
  123. package/dist/sections/index.d.ts +6 -0
  124. package/dist/sections.cjs +1 -1
  125. package/dist/sections.js +268 -307
  126. package/dist/tabs-BsfVo2Bl.cjs +173 -0
  127. package/dist/{tabs-Wf3h_Cx3.js → tabs-BuY1iNJE.js} +7532 -6807
  128. package/dist/ui/badge.d.ts +1 -1
  129. package/dist/ui/index.d.ts +2 -0
  130. package/dist/ui/progress.d.ts +1 -1
  131. package/dist/ui/rich-text-editor.d.ts +3 -1
  132. package/dist/ui/toast.d.ts +43 -0
  133. package/dist/utils/debounce.d.ts +5 -1
  134. package/dist/utils/pick-palette-color.d.ts +19 -0
  135. package/dist/video/types.d.ts +15 -0
  136. package/dist/video/video-player.d.ts +1 -1
  137. package/dist/withProGate-BWqcKdPM.js +137 -0
  138. package/dist/withProGate-DX6XqKLp.cjs +1 -0
  139. package/package.json +34 -220
  140. package/src/assessment-toolbar/question-navigator.tsx +10 -5
  141. package/src/assessment-toolbar/timer-display.tsx +4 -3
  142. package/src/assessment-toolbar/use-countdown.ts +1 -1
  143. package/src/common/empty-state.tsx +1 -0
  144. package/src/common/index.ts +2 -0
  145. package/src/common/pagination.tsx +135 -0
  146. package/src/common/search-input.tsx +2 -1
  147. package/src/common/types.ts +2 -0
  148. package/src/content/attachment-list.tsx +2 -0
  149. package/src/content/audio-player.tsx +196 -0
  150. package/src/content/code-block.tsx +113 -0
  151. package/src/content/content-block.tsx +64 -0
  152. package/src/content/embed-block.tsx +78 -0
  153. package/src/content/file-upload-zone.tsx +10 -0
  154. package/src/content/index.ts +6 -0
  155. package/src/content/types.ts +5 -0
  156. package/src/curriculum/course-card.tsx +199 -0
  157. package/src/curriculum/curriculum-item.tsx +3 -3
  158. package/src/curriculum/curriculum-tree.tsx +20 -13
  159. package/src/curriculum/index.ts +2 -0
  160. package/src/curriculum/types.ts +2 -2
  161. package/src/flashcards/flashcard.tsx +28 -8
  162. package/src/index.ts +3 -0
  163. package/src/license/HydraContext.tsx +62 -0
  164. package/src/license/ProBadge.tsx +43 -0
  165. package/src/license/index.ts +7 -0
  166. package/src/license/tiers.ts +24 -0
  167. package/src/license/useHydraLicense.ts +10 -0
  168. package/src/license/validate.ts +90 -0
  169. package/src/license/withProGate.tsx +21 -0
  170. package/src/modules/AssignmentModule/AssignmentModule.tsx +17 -8
  171. package/src/modules/AssignmentModule/types.ts +5 -1
  172. package/src/modules/CertificateModule/CertificateModule.tsx +21 -9
  173. package/src/modules/CertificateModule/types.ts +6 -4
  174. package/src/modules/CourseCatalogModule/CourseCatalogModule.tsx +126 -0
  175. package/src/modules/CourseCatalogModule/types.ts +47 -0
  176. package/src/modules/CoursePlayer/CoursePlayer.tsx +37 -22
  177. package/src/modules/DiscussionModule/DiscussionModule.tsx +57 -22
  178. package/src/modules/ExamModule/ExamModule.tsx +64 -198
  179. package/src/modules/ExamModule/types.ts +5 -14
  180. package/src/modules/FlashcardLab/FlashcardLab.tsx +10 -5
  181. package/src/modules/FlashcardLab/types.ts +2 -0
  182. package/src/modules/GradeCenterModule/GradeCenterModule.tsx +7 -2
  183. package/src/modules/GradeCenterModule/types.ts +2 -0
  184. package/src/modules/QuizModule/QuizModule.tsx +49 -169
  185. package/src/modules/QuizModule/types.ts +5 -15
  186. package/src/modules/StudentDashboardModule/StudentDashboardModule.tsx +117 -0
  187. package/src/modules/StudentDashboardModule/types.ts +56 -0
  188. package/src/modules/StudentProfileModule/StudentProfileModule.tsx +289 -0
  189. package/src/modules/StudentProfileModule/types.ts +45 -0
  190. package/src/modules/SurveyModule/SurveyModule.tsx +9 -4
  191. package/src/modules/SurveyModule/types.ts +2 -0
  192. package/src/modules/_shared/assessment-intro.tsx +75 -0
  193. package/src/modules/_shared/assessment-results.tsx +133 -0
  194. package/src/modules/_shared/types.ts +11 -0
  195. package/src/modules/_shared/use-timer.ts +49 -0
  196. package/src/modules/index.ts +9 -0
  197. package/src/progress/achievement-badge.tsx +3 -3
  198. package/src/progress/grade-indicator.tsx +9 -1
  199. package/src/progress/progress-ring.tsx +2 -1
  200. package/src/progress/stat-card.tsx +8 -1
  201. package/src/progress/types.ts +2 -0
  202. package/src/provider/HydraProvider.tsx +15 -6
  203. package/src/questions/choice.tsx +13 -6
  204. package/src/questions/confidence-indicator.tsx +107 -0
  205. package/src/questions/essay.tsx +6 -4
  206. package/src/questions/fill-in-the-blank.tsx +8 -4
  207. package/src/questions/hotspot.tsx +4 -4
  208. package/src/questions/index.ts +2 -0
  209. package/src/questions/inline-choice.tsx +5 -4
  210. package/src/questions/matching.tsx +5 -4
  211. package/src/questions/multiple-choice.tsx +13 -6
  212. package/src/questions/numeric.tsx +8 -4
  213. package/src/questions/ordering.tsx +12 -4
  214. package/src/questions/question-renderer.tsx +3 -2
  215. package/src/questions/scenario.tsx +4 -4
  216. package/src/questions/spreadsheet.tsx +5 -4
  217. package/src/questions/true-false.tsx +13 -6
  218. package/src/sections/AnnouncementFeed/AnnouncementFeed.tsx +64 -8
  219. package/src/sections/AnnouncementFeed/types.ts +15 -1
  220. package/src/sections/AssessmentReview/AssessmentReview.tsx +37 -0
  221. package/src/sections/AssessmentReview/types.ts +6 -0
  222. package/src/sections/AssignmentSubmission/AssignmentSubmission.tsx +37 -1
  223. package/src/sections/AssignmentSubmission/types.ts +6 -0
  224. package/src/sections/CertificateViewer/CertificateViewer.tsx +29 -227
  225. package/src/sections/CertificateViewer/certificate-variants.tsx +170 -0
  226. package/src/sections/CertificateViewer/types.ts +6 -0
  227. package/src/sections/CourseCatalog/CourseCatalog.tsx +220 -0
  228. package/src/sections/CourseCatalog/types.ts +76 -0
  229. package/src/sections/CourseOutline/CourseOutline.tsx +41 -0
  230. package/src/sections/CourseOutline/types.ts +6 -0
  231. package/src/sections/DiscussionThread/DiscussionThread.tsx +42 -1
  232. package/src/sections/DiscussionThread/types.ts +6 -0
  233. package/src/sections/EnrollmentWizard/EnrollmentWizard.tsx +343 -0
  234. package/src/sections/EnrollmentWizard/types.ts +65 -0
  235. package/src/sections/ExamSession/ExamSession.tsx +100 -94
  236. package/src/sections/ExamSession/types.ts +6 -0
  237. package/src/sections/FlashcardStudySession/FlashcardStudySession.tsx +53 -36
  238. package/src/sections/FlashcardStudySession/types.ts +6 -0
  239. package/src/sections/ForumBoard/ForumBoard.tsx +59 -1
  240. package/src/sections/ForumBoard/types.ts +14 -0
  241. package/src/sections/GradebookTable/GradebookTable.tsx +54 -1
  242. package/src/sections/GradebookTable/types.ts +14 -0
  243. package/src/sections/LecturePlayer/LecturePlayer.tsx +63 -37
  244. package/src/sections/LecturePlayer/types.ts +8 -0
  245. package/src/sections/LessonPage/LessonPage.tsx +36 -5
  246. package/src/sections/LessonPage/types.ts +6 -0
  247. package/src/sections/PracticeQuiz/PracticeQuiz.tsx +106 -74
  248. package/src/sections/PracticeQuiz/types.ts +6 -0
  249. package/src/sections/ProgressDashboard/ProgressDashboard.tsx +64 -10
  250. package/src/sections/ProgressDashboard/types.ts +6 -0
  251. package/src/sections/QuizSession/QuizSession.tsx +71 -82
  252. package/src/sections/QuizSession/types.ts +6 -0
  253. package/src/sections/RequirementsChecklist/RequirementsChecklist.tsx +41 -1
  254. package/src/sections/RequirementsChecklist/types.ts +6 -0
  255. package/src/sections/ResourceLibrary/ResourceLibrary.tsx +64 -8
  256. package/src/sections/ResourceLibrary/types.ts +15 -1
  257. package/src/sections/RubricView/RubricView.tsx +37 -1
  258. package/src/sections/RubricView/types.ts +6 -0
  259. package/src/sections/ScrollableQuiz/ScrollableQuiz.tsx +36 -15
  260. package/src/sections/ScrollableQuiz/types.ts +6 -0
  261. package/src/sections/StudentProfile/StudentProfile.tsx +279 -0
  262. package/src/sections/StudentProfile/types.ts +99 -0
  263. package/src/sections/SurveyForm/SurveyForm.tsx +32 -5
  264. package/src/sections/SurveyForm/types.ts +6 -0
  265. package/src/sections/_shared/merge-answers.ts +22 -0
  266. package/src/sections/_shared/section-shell.tsx +64 -0
  267. package/src/sections/_shared/use-assessment-session.ts +125 -0
  268. package/src/sections/index.ts +22 -0
  269. package/src/social/user-avatar.tsx +9 -5
  270. package/src/styles/globals.css +39 -41
  271. package/src/ui/badge.tsx +8 -0
  272. package/src/ui/index.ts +2 -0
  273. package/src/ui/progress.tsx +4 -0
  274. package/src/ui/rich-text-editor.tsx +10 -0
  275. package/src/ui/rich-text-toolbar.tsx +2 -1
  276. package/src/ui/toast.tsx +170 -0
  277. package/src/utils/debounce.ts +8 -2
  278. package/src/utils/pick-palette-color.ts +33 -0
  279. package/src/video/types.ts +16 -0
  280. package/src/video/video-player.tsx +13 -1
  281. package/dist/ForumBoard-CHXU3mjC.js +0 -2207
  282. package/dist/ForumBoard-d1w5-r6n.cjs +0 -1
  283. package/dist/tabs-DRM2Iq_J.cjs +0 -172
@@ -1,2207 +0,0 @@
1
- import { jsxs as t, jsx as e, Fragment as W } from "react/jsx-runtime";
2
- import { useState as A, useMemo as j, useRef as We, useEffect as Ne, Fragment as Ye } from "react";
3
- import { ChevronLeft as Ze, ChevronRight as ue, Send as Se, CheckCircle as he, Clock as ze, Check as be, MessageSquare as fe, Heart as Le, Reply as Ke, Save as Xe, ArrowUp as Je, ArrowDown as qe, BookOpen as et, Award as tt, Printer as at, Download as nt, CheckCircle2 as pe, Circle as rt, Plus as st, ArrowUpDown as lt, Pin as it } from "lucide-react";
4
- import { t as Ae, C as B, z as ge, ag as Ue, w as Q, aj as ae, B as P, ah as De, c as U, aL as ve, D as dt, a3 as ct, u as G, an as E, P as K, I as ot, aV as mt, aR as we, $ as ut, e as Fe, g as Te, F as ht, a9 as ft, ap as pt, ak as Z, a as Re, G as gt, aG as se, aI as le, aH as ie, ae as xt, ar as Ie, Y as Me, aB as Nt, aD as bt, aE as de, aC as ce, a0 as ye, a7 as oe, a4 as vt, at as Pe, az as Be, aA as Y, ay as ee, au as Qe, aw as V, af as wt, aq as ke, as as yt, d as kt, A as Ct, am as St, Z as zt, aK as Lt, aT as At } from "./tabs-Wf3h_Cx3.js";
5
- import { cva as je } from "class-variance-authority";
6
- function Kt({
7
- questions: a,
8
- initialAnswers: r = [],
9
- onSubmit: i,
10
- onAnswerChange: o,
11
- timeElapsedSeconds: h,
12
- timeLimitSeconds: s,
13
- questionMaterials: c,
14
- isSubmitting: n = !1,
15
- readOnly: b = !1,
16
- className: p,
17
- style: m
18
- }) {
19
- const [x, y] = A(0), [v, L] = A(r), [w, R] = A(/* @__PURE__ */ new Set()), [g, C] = A(!1), l = a[x], d = j(
20
- () => l ? v.filter((u) => u.uid === l.uid) : [],
21
- [v, l]
22
- ), f = j(
23
- () => (c == null ? void 0 : c.filter((u) => u.questionUid === (l == null ? void 0 : l.uid))) ?? [],
24
- [c, l]
25
- ), F = j(
26
- () => a.map((u, N) => ({
27
- uid: u.uid,
28
- sequence: N,
29
- isFlagged: w.has(u.uid),
30
- isAnswered: v.some((k) => k.uid === u.uid),
31
- isSkipped: !1
32
- })),
33
- [a, v, w]
34
- );
35
- function T(u) {
36
- if (!l) return;
37
- const N = l.uid, k = u.map((S) => ({
38
- uid: N,
39
- answerUid: S.uid,
40
- content: S.content
41
- }));
42
- L((S) => {
43
- const X = [...S.filter((J) => J.uid !== N), ...k];
44
- return o == null || o(X), X;
45
- });
46
- }
47
- function z(u) {
48
- const N = a.findIndex((k) => k.uid === u);
49
- N !== -1 && y(N);
50
- }
51
- function D(u) {
52
- R((N) => {
53
- const k = new Set(N);
54
- return k.has(u) ? k.delete(u) : k.add(u), k;
55
- });
56
- }
57
- function I() {
58
- i(v);
59
- }
60
- return /* @__PURE__ */ t("div", { className: U(p), style: m, children: [
61
- /* @__PURE__ */ e(
62
- Ae,
63
- {
64
- currentQuestionIndex: x,
65
- totalQuestions: a.length,
66
- hasNext: x < a.length - 1,
67
- hasPrevious: x > 0,
68
- onNext: () => y((u) => Math.min(u + 1, a.length - 1)),
69
- onPrevious: () => y((u) => Math.max(u - 1, 0)),
70
- onSubmit: I,
71
- timeElapsedSeconds: h,
72
- timeLimitSeconds: s,
73
- questions: F,
74
- onNavigateToQuestion: z,
75
- currentQuestionUid: l == null ? void 0 : l.uid,
76
- isSubmitting: n,
77
- readOnly: b
78
- }
79
- ),
80
- l && /* @__PURE__ */ t(B, { className: "mt-3", children: [
81
- /* @__PURE__ */ e(ge, { className: "pb-0", children: /* @__PURE__ */ e(
82
- Ue,
83
- {
84
- questionNumber: x + 1,
85
- totalQuestions: a.length,
86
- isFlagged: w.has(l.uid),
87
- onToggleFlag: () => D(l.uid),
88
- hasMaterials: f.length > 0,
89
- onOpenMaterials: () => C(!0),
90
- readOnly: b
91
- }
92
- ) }),
93
- /* @__PURE__ */ e(Q, { children: /* @__PURE__ */ e(
94
- ae,
95
- {
96
- question: l,
97
- sessionAnswers: d,
98
- onAnswer: T,
99
- readOnly: b
100
- }
101
- ) })
102
- ] }),
103
- !b && /* @__PURE__ */ t("div", { className: "flex items-center justify-between gap-3 mt-3", children: [
104
- /* @__PURE__ */ t(
105
- P,
106
- {
107
- variant: "outline",
108
- disabled: x <= 0,
109
- onClick: () => y((u) => Math.max(u - 1, 0)),
110
- children: [
111
- /* @__PURE__ */ e(Ze, { className: "size-4 mr-1" }),
112
- "Previous"
113
- ]
114
- }
115
- ),
116
- x < a.length - 1 ? /* @__PURE__ */ t(
117
- P,
118
- {
119
- onClick: () => y((u) => Math.min(u + 1, a.length - 1)),
120
- children: [
121
- "Next",
122
- /* @__PURE__ */ e(ue, { className: "size-4 ml-1" })
123
- ]
124
- }
125
- ) : /* @__PURE__ */ t(P, { onClick: I, disabled: n, children: [
126
- n ? "Submitting..." : "Submit Quiz",
127
- !n && /* @__PURE__ */ e(Se, { className: "size-4 ml-1" })
128
- ] })
129
- ] }),
130
- /* @__PURE__ */ e(
131
- De,
132
- {
133
- open: g,
134
- onOpenChange: C,
135
- materials: f,
136
- questionNumber: x + 1
137
- }
138
- )
139
- ] });
140
- }
141
- function Xt({
142
- video: a,
143
- notes: r,
144
- layout: i = "horizontal",
145
- notesPanelWidth: o = "340px",
146
- notesPanelHeight: h = "240px",
147
- className: s,
148
- style: c
149
- }) {
150
- const n = i === "horizontal";
151
- return r ? /* @__PURE__ */ t(
152
- "div",
153
- {
154
- className: U(
155
- "flex overflow-hidden gap-4",
156
- n ? "flex-row" : "flex-col",
157
- s
158
- ),
159
- style: c,
160
- children: [
161
- /* @__PURE__ */ e("div", { className: "flex-1 min-w-0 min-h-0", children: /* @__PURE__ */ e(ve, { ...a }) }),
162
- /* @__PURE__ */ t(
163
- B,
164
- {
165
- className: U(
166
- "overflow-auto shrink-0 rounded-none border-0",
167
- n ? "border-l border-border" : "border-t border-border w-full"
168
- ),
169
- style: {
170
- width: n ? o : void 0,
171
- height: n ? void 0 : h
172
- },
173
- children: [
174
- /* @__PURE__ */ e(ge, { children: /* @__PURE__ */ e(dt, { children: "Notes" }) }),
175
- /* @__PURE__ */ e(Q, { children: typeof r == "string" ? /* @__PURE__ */ e("span", { className: "text-sm text-foreground", children: r }) : r })
176
- ]
177
- }
178
- )
179
- ]
180
- }
181
- ) : /* @__PURE__ */ e("div", { className: s, style: c, children: /* @__PURE__ */ e(ve, { ...a }) });
182
- }
183
- function Jt({
184
- cards: a,
185
- title: r,
186
- description: i,
187
- shuffled: o = !1,
188
- onComplete: h,
189
- readOnly: s = !1,
190
- className: c,
191
- style: n
192
- }) {
193
- const [b, p] = A(!1), m = {
194
- totalCards: a.length,
195
- wasShuffled: o
196
- };
197
- function x() {
198
- p(!0), h == null || h(m);
199
- }
200
- function y() {
201
- p(!1);
202
- }
203
- return b ? /* @__PURE__ */ e("div", { className: U("flex flex-col items-center", c), style: n, children: /* @__PURE__ */ e(B, { children: /* @__PURE__ */ t(Q, { className: "pt-6 text-center flex flex-col items-center gap-2", children: [
204
- /* @__PURE__ */ e(he, { size: 48, className: "text-success" }),
205
- /* @__PURE__ */ e("span", { className: "text-xl font-bold text-foreground", children: "Deck complete!" }),
206
- r && /* @__PURE__ */ t("span", { className: "text-muted-foreground", children: [
207
- "You finished ",
208
- /* @__PURE__ */ e("strong", { children: r })
209
- ] }),
210
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
211
- m.totalCards,
212
- " card",
213
- m.totalCards !== 1 ? "s" : "",
214
- " studied",
215
- m.wasShuffled ? " (shuffled)" : ""
216
- ] }),
217
- /* @__PURE__ */ e(P, { className: "mt-2", onClick: y, children: "Study Again" })
218
- ] }) }) }) : /* @__PURE__ */ e("div", { className: U("flex flex-col items-center", c), style: n, children: /* @__PURE__ */ e(
219
- ct,
220
- {
221
- cards: a,
222
- deckName: r,
223
- deckDescription: i,
224
- shuffled: o,
225
- showProgress: !0,
226
- onComplete: x,
227
- readOnly: s
228
- }
229
- ) });
230
- }
231
- function Ut({
232
- score: a
233
- }) {
234
- const r = a.percentage !== void 0 ? a.percentage : a.total > 0 ? Math.round(a.correct / a.total * 100) : 0;
235
- return /* @__PURE__ */ e(B, { className: "mb-3", children: /* @__PURE__ */ e(Q, { className: "pt-6", children: /* @__PURE__ */ t("div", { className: "flex flex-wrap items-center gap-2", children: [
236
- /* @__PURE__ */ t("div", { className: "flex items-baseline gap-2", children: [
237
- /* @__PURE__ */ t("span", { className: "text-2xl font-bold leading-none text-foreground", children: [
238
- r,
239
- "%"
240
- ] }),
241
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
242
- a.correct,
243
- " of ",
244
- a.total,
245
- " correct"
246
- ] })
247
- ] }),
248
- a.passed !== void 0 && /* @__PURE__ */ e(G, { variant: a.passed ? "success" : "destructive", children: a.passed ? "Passed" : "Failed" }),
249
- a.passingScore !== void 0 && /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
250
- "Passing score: ",
251
- a.passingScore,
252
- "%"
253
- ] })
254
- ] }) }) });
255
- }
256
- function me({
257
- questions: a,
258
- sessionAnswers: r,
259
- showCorrectAnswers: i
260
- }) {
261
- const o = j(() => {
262
- const h = /* @__PURE__ */ new Map();
263
- for (const s of r) {
264
- const c = h.get(s.uid);
265
- c ? c.push(s) : h.set(s.uid, [s]);
266
- }
267
- return h;
268
- }, [r]);
269
- return /* @__PURE__ */ e("div", { className: "flex flex-col gap-3", children: a.map((h, s) => /* @__PURE__ */ t(B, { className: "overflow-hidden", children: [
270
- /* @__PURE__ */ e("div", { className: "px-2 py-1 bg-muted", children: /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground font-semibold", children: [
271
- "Question ",
272
- s + 1
273
- ] }) }),
274
- /* @__PURE__ */ e(E, {}),
275
- /* @__PURE__ */ e(Q, { className: "pt-4 pb-4", children: /* @__PURE__ */ e(
276
- ae,
277
- {
278
- question: h,
279
- sessionAnswers: o.get(h.uid) ?? [],
280
- readOnly: !0,
281
- showCorrectAnswers: i
282
- }
283
- ) })
284
- ] }, h.uid)) });
285
- }
286
- function Dt(a, r, i, o) {
287
- const h = new Map(a.map((n) => [n.uid, n])), s = new Set(i.flatMap((n) => n.questionUids)), c = a.filter((n) => !s.has(n.uid));
288
- return /* @__PURE__ */ t("div", { className: "flex flex-col gap-4", children: [
289
- i.map((n) => {
290
- const b = n.questionUids.map((p) => h.get(p)).filter(Boolean);
291
- return /* @__PURE__ */ t("div", { children: [
292
- /* @__PURE__ */ e("span", { className: "uppercase text-xs tracking-wide text-muted-foreground font-semibold", children: n.label }),
293
- /* @__PURE__ */ e(E, { className: "mb-2" }),
294
- /* @__PURE__ */ e(
295
- me,
296
- {
297
- questions: b,
298
- sessionAnswers: r,
299
- showCorrectAnswers: o
300
- }
301
- )
302
- ] }, n.label);
303
- }),
304
- c.length > 0 && /* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(
305
- me,
306
- {
307
- questions: c,
308
- sessionAnswers: r,
309
- showCorrectAnswers: o
310
- }
311
- ) })
312
- ] });
313
- }
314
- function qt({
315
- questions: a,
316
- sessionAnswers: r,
317
- score: i,
318
- questionGroups: o,
319
- showCorrectAnswers: h = !0,
320
- className: s,
321
- style: c
322
- }) {
323
- return /* @__PURE__ */ t("div", { className: U(s), style: c, children: [
324
- i && /* @__PURE__ */ e(Ut, { score: i }),
325
- o && o.length > 0 ? Dt(a, r, o, h) : /* @__PURE__ */ e(
326
- me,
327
- {
328
- questions: a,
329
- sessionAnswers: r,
330
- showCorrectAnswers: h
331
- }
332
- )
333
- ] });
334
- }
335
- function _e(a) {
336
- const r = [];
337
- for (const i of a)
338
- !i.children || i.children.length === 0 ? r.push(i.uid) : r.push(..._e(i.children));
339
- return r;
340
- }
341
- function ea({
342
- items: a,
343
- progress: r,
344
- courseTitle: i,
345
- activeItemUid: o,
346
- onItemClick: h,
347
- showOverallProgress: s = !0,
348
- showDuration: c = !0,
349
- showIcons: n = !0,
350
- readOnly: b = !1,
351
- className: p,
352
- style: m
353
- }) {
354
- const { completedCount: x, totalCount: y, percentage: v } = j(() => {
355
- const L = _e(a), w = L.length, R = r ? L.filter(
356
- (g) => r.some((C) => C.resourceUid === g && C.isCompleted)
357
- ).length : 0;
358
- return {
359
- completedCount: R,
360
- totalCount: w,
361
- percentage: w > 0 ? Math.round(R / w * 100) : 0
362
- };
363
- }, [a, r]);
364
- return /* @__PURE__ */ t("div", { className: U(p), style: m, children: [
365
- (i || s) && /* @__PURE__ */ t("div", { className: "px-2 pt-2 pb-2", children: [
366
- i && /* @__PURE__ */ e("p", { className: U("font-semibold text-sm text-foreground", s && "mb-1"), children: i }),
367
- s && /* @__PURE__ */ t("div", { children: [
368
- /* @__PURE__ */ e(K, { value: v, size: "sm" }),
369
- /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground mt-0.5 block", children: [
370
- x,
371
- " of ",
372
- y,
373
- " completed"
374
- ] })
375
- ] })
376
- ] }),
377
- (i || s) && /* @__PURE__ */ e(E, {}),
378
- /* @__PURE__ */ e(
379
- ot,
380
- {
381
- items: a,
382
- progress: r,
383
- activeItemUid: o,
384
- onItemClick: h,
385
- readOnly: b,
386
- showDuration: c,
387
- showIcons: n,
388
- showProgress: !0
389
- }
390
- )
391
- ] });
392
- }
393
- function ta({
394
- questions: a,
395
- instantFeedback: r = !0,
396
- allowRetry: i = !0,
397
- onComplete: o,
398
- shuffled: h = !1,
399
- readOnly: s = !1,
400
- className: c,
401
- style: n
402
- }) {
403
- const b = j(
404
- () => h ? mt(a) : a,
405
- // eslint-disable-next-line react-hooks/exhaustive-deps
406
- [a, h]
407
- ), [p, m] = A(0), [x, y] = A(/* @__PURE__ */ new Set()), [v, L] = A(/* @__PURE__ */ new Map()), [w, R] = A(/* @__PURE__ */ new Set()), [g, C] = A(null), [l, d] = A(!1), f = b[p], F = f ? x.has(f.uid) : !1;
408
- function T() {
409
- if (!f || !g) return;
410
- const u = (v.get(f.uid) ?? 0) + 1;
411
- L((S) => new Map(S).set(f.uid, u)), y((S) => new Set(S).add(f.uid));
412
- const N = g.map((S) => ({
413
- uid: f.uid,
414
- answerUid: S.uid,
415
- content: S.content
416
- }));
417
- we(f, N) === !0 && u === 1 && R((S) => new Set(S).add(f.uid));
418
- }
419
- function z() {
420
- f && (y((u) => {
421
- const N = new Set(u);
422
- return N.delete(f.uid), N;
423
- }), C(null));
424
- }
425
- function D() {
426
- if (p < b.length - 1)
427
- m((u) => u + 1), C(null);
428
- else {
429
- const u = {
430
- totalQuestions: b.length,
431
- correctOnFirstAttempt: w.size,
432
- totalAttempts: Array.from(v.values()).reduce((N, k) => N + k, 0)
433
- };
434
- d(!0), o == null || o(u);
435
- }
436
- }
437
- const I = j(() => {
438
- if (!f || !g) return !1;
439
- const u = g.map((N) => ({
440
- uid: f.uid,
441
- answerUid: N.uid,
442
- content: N.content
443
- }));
444
- return we(f, u) === !0;
445
- }, [f, g]);
446
- if (l) {
447
- const u = b.length > 0 ? Math.round(w.size / b.length * 100) : 0;
448
- return /* @__PURE__ */ e(B, { className: c, style: n, children: /* @__PURE__ */ t(Q, { className: "pt-6 text-center", children: [
449
- /* @__PURE__ */ e(he, { size: 48, className: "text-success mx-auto mb-4" }),
450
- /* @__PURE__ */ e("p", { className: "text-xl font-bold mb-1 text-foreground", children: "Practice Complete!" }),
451
- /* @__PURE__ */ t("p", { className: "text-muted-foreground mb-2", children: [
452
- w.size,
453
- " of ",
454
- b.length,
455
- " correct on first attempt (",
456
- u,
457
- "%)"
458
- ] }),
459
- /* @__PURE__ */ e("div", { className: "flex justify-center", children: /* @__PURE__ */ e(
460
- P,
461
- {
462
- variant: "outline",
463
- onClick: () => {
464
- m(0), y(/* @__PURE__ */ new Set()), L(/* @__PURE__ */ new Map()), R(/* @__PURE__ */ new Set()), C(null), d(!1);
465
- },
466
- children: "Practice Again"
467
- }
468
- ) })
469
- ] }) });
470
- }
471
- return /* @__PURE__ */ t("div", { className: c, style: n, children: [
472
- /* @__PURE__ */ t("div", { className: "flex justify-between items-center mb-2", children: [
473
- /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-foreground", children: [
474
- "Question ",
475
- p + 1,
476
- " of ",
477
- b.length
478
- ] }),
479
- /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: [
480
- w.size,
481
- " correct on first try"
482
- ] })
483
- ] }),
484
- /* @__PURE__ */ e(
485
- K,
486
- {
487
- value: p + (F ? 1 : 0),
488
- max: b.length,
489
- size: "sm",
490
- className: "mb-3"
491
- }
492
- ),
493
- f && /* @__PURE__ */ e(B, { children: /* @__PURE__ */ t(Q, { className: "pt-6", children: [
494
- /* @__PURE__ */ e(
495
- ae,
496
- {
497
- question: f,
498
- sessionAnswers: (g == null ? void 0 : g.map((u) => ({
499
- uid: f.uid,
500
- answerUid: u.uid,
501
- content: u.content
502
- }))) ?? [],
503
- onAnswer: (u) => C(u),
504
- readOnly: s || F,
505
- showCorrectAnswers: F
506
- }
507
- ),
508
- r && F && /* @__PURE__ */ e(
509
- ut,
510
- {
511
- isCorrect: I,
512
- explanation: f.explanation,
513
- onRetry: i && !I ? z : void 0
514
- }
515
- ),
516
- /* @__PURE__ */ t("div", { className: "flex justify-end gap-2 mt-2", children: [
517
- !F && r && /* @__PURE__ */ e(
518
- P,
519
- {
520
- onClick: T,
521
- disabled: !g || g.length === 0 || s,
522
- children: "Check Answer"
523
- }
524
- ),
525
- (!r || F) && /* @__PURE__ */ e(
526
- P,
527
- {
528
- onClick: D,
529
- disabled: s,
530
- children: p < b.length - 1 ? "Next Question" : "Finish"
531
- }
532
- )
533
- ] })
534
- ] }) })
535
- ] });
536
- }
537
- function aa({
538
- questions: a,
539
- initialAnswers: r = [],
540
- onSubmit: i,
541
- onAnswerChange: o,
542
- timeLimitSeconds: h,
543
- timeElapsedSeconds: s,
544
- autoSubmitOnTimeout: c = !0,
545
- timeWarningThreshold: n = 300,
546
- allowBackNavigation: b = !0,
547
- confirmBeforeSubmit: p = !0,
548
- examTitle: m,
549
- instructions: x,
550
- questionMaterials: y,
551
- isSubmitting: v = !1,
552
- readOnly: L = !1,
553
- className: w,
554
- style: R
555
- }) {
556
- const [g, C] = A(0), [l, d] = A(r), [f, F] = A(/* @__PURE__ */ new Set()), [T, z] = A(!1), [D, I] = A(!1), [u, N] = A(!1), k = We(!1), S = a[g], O = h - s, X = j(
557
- () => S ? l.filter((M) => M.uid === S.uid) : [],
558
- [l, S]
559
- ), J = j(
560
- () => (y == null ? void 0 : y.filter((M) => M.questionUid === (S == null ? void 0 : S.uid))) ?? [],
561
- [y, S]
562
- );
563
- Ne(() => {
564
- O <= n && O > 0 && I(!0);
565
- }, [O, n]), Ne(() => {
566
- c && O <= 0 && !k.current && (k.current = !0, re(!0));
567
- }, [O, c]);
568
- const ne = j(
569
- () => a.map((M, $) => ({
570
- uid: M.uid,
571
- sequence: $,
572
- isFlagged: f.has(M.uid),
573
- isAnswered: l.some((_) => _.uid === M.uid),
574
- isSkipped: !1
575
- })),
576
- [a, l, f]
577
- ), Ee = j(
578
- () => ne.filter((M) => M.isAnswered).length,
579
- [ne]
580
- );
581
- function $e(M) {
582
- if (!S) return;
583
- const $ = S.uid, _ = M.map((H) => ({
584
- uid: $,
585
- answerUid: H.uid,
586
- content: H.content
587
- }));
588
- d((H) => {
589
- const xe = [...H.filter((Ge) => Ge.uid !== $), ..._];
590
- return o == null || o(xe), xe;
591
- });
592
- }
593
- function Oe(M) {
594
- const $ = a.findIndex((_) => _.uid === M);
595
- $ !== -1 && C($);
596
- }
597
- function He(M) {
598
- F(($) => {
599
- const _ = new Set($);
600
- return _.has(M) ? _.delete(M) : _.add(M), _;
601
- });
602
- }
603
- function Ve() {
604
- p ? z(!0) : re(!1);
605
- }
606
- function re(M) {
607
- const $ = new Set(l.map((H) => H.uid)), _ = {
608
- timeElapsedSeconds: s,
609
- wasAutoSubmitted: M,
610
- answeredCount: a.filter((H) => $.has(H.uid)).length,
611
- totalQuestions: a.length
612
- };
613
- i(l, _);
614
- }
615
- return /* @__PURE__ */ t("div", { className: U(w), style: R, children: [
616
- m && /* @__PURE__ */ e("p", { className: "text-xl font-bold mb-2 text-foreground", children: m }),
617
- D && O > 0 && O <= n && /* @__PURE__ */ e(Fe, { variant: "warning", className: "mb-2", children: /* @__PURE__ */ t(Te, { children: [
618
- Math.ceil(O / 60),
619
- " minute",
620
- Math.ceil(O / 60) !== 1 ? "s" : "",
621
- " remaining"
622
- ] }) }),
623
- /* @__PURE__ */ e(
624
- Ae,
625
- {
626
- currentQuestionIndex: g,
627
- totalQuestions: a.length,
628
- hasNext: g < a.length - 1,
629
- hasPrevious: b && g > 0,
630
- onNext: () => C((M) => Math.min(M + 1, a.length - 1)),
631
- onPrevious: () => b && C((M) => Math.max(M - 1, 0)),
632
- onSubmit: Ve,
633
- timeElapsedSeconds: s,
634
- timeLimitSeconds: h,
635
- questions: ne,
636
- onNavigateToQuestion: Oe,
637
- currentQuestionUid: S == null ? void 0 : S.uid,
638
- isSubmitting: v,
639
- readOnly: L
640
- }
641
- ),
642
- x && g === 0 && /* @__PURE__ */ e(B, { className: "mt-3", children: /* @__PURE__ */ e(Q, { className: "pt-6", children: x }) }),
643
- S && /* @__PURE__ */ t(B, { className: "mt-3", children: [
644
- /* @__PURE__ */ e(ge, { className: "pb-0", children: /* @__PURE__ */ e(
645
- Ue,
646
- {
647
- questionNumber: g + 1,
648
- totalQuestions: a.length,
649
- isFlagged: f.has(S.uid),
650
- onToggleFlag: () => He(S.uid),
651
- hasMaterials: J.length > 0,
652
- onOpenMaterials: () => N(!0),
653
- readOnly: L
654
- }
655
- ) }),
656
- /* @__PURE__ */ e(Q, { children: /* @__PURE__ */ e(
657
- ae,
658
- {
659
- question: S,
660
- sessionAnswers: X,
661
- onAnswer: $e,
662
- readOnly: L
663
- }
664
- ) })
665
- ] }),
666
- /* @__PURE__ */ e(
667
- De,
668
- {
669
- open: u,
670
- onOpenChange: N,
671
- materials: J,
672
- questionNumber: g + 1
673
- }
674
- ),
675
- /* @__PURE__ */ e(
676
- ht,
677
- {
678
- open: T,
679
- title: "Submit Exam?",
680
- message: `You have answered ${Ee} of ${a.length} questions. Once submitted, you cannot change your answers.`,
681
- confirmLabel: "Submit Exam",
682
- cancelLabel: "Continue Exam",
683
- confirmColor: "primary",
684
- onConfirm: () => {
685
- z(!1), re(!1);
686
- },
687
- onCancel: () => z(!1),
688
- isLoading: v
689
- }
690
- )
691
- ] });
692
- }
693
- function na({
694
- title: a,
695
- description: r,
696
- questions: i,
697
- initialAnswers: o = [],
698
- onSubmit: h,
699
- onAnswerChange: s,
700
- showProgress: c = !0,
701
- requireAll: n = !1,
702
- submitLabel: b = "Submit Survey",
703
- isSubmitting: p = !1,
704
- readOnly: m = !1,
705
- className: x,
706
- style: y
707
- }) {
708
- const [v, L] = A(o), w = j(() => {
709
- const l = new Set(v.map((d) => d.questionUid));
710
- return i.filter((d) => l.has(d.uid)).length;
711
- }, [i, v]), R = !n || w === i.length;
712
- function g(l, d) {
713
- L((f) => {
714
- const T = [...f.filter((z) => z.questionUid !== l), { questionUid: l, value: d }];
715
- return s == null || s(T), T;
716
- });
717
- }
718
- function C(l) {
719
- return v.find((d) => d.questionUid === l);
720
- }
721
- return /* @__PURE__ */ t("div", { className: x, style: y, children: [
722
- /* @__PURE__ */ e("p", { className: "text-xl font-bold text-foreground mb-2", children: a }),
723
- r && /* @__PURE__ */ e("div", { className: "mb-2 text-muted-foreground text-sm", children: typeof r == "string" ? /* @__PURE__ */ e("span", { children: r }) : r }),
724
- c && /* @__PURE__ */ t("div", { className: "mb-3", children: [
725
- /* @__PURE__ */ e(K, { value: w / i.length * 100 }),
726
- /* @__PURE__ */ t("span", { className: "block text-xs text-muted-foreground mt-0.5", children: [
727
- w,
728
- " of ",
729
- i.length,
730
- " answered"
731
- ] })
732
- ] }),
733
- i.map((l, d) => {
734
- var F, T;
735
- const f = C(l.uid);
736
- return /* @__PURE__ */ e(B, { className: "mb-2", children: /* @__PURE__ */ t(Q, { className: "pt-6", children: [
737
- /* @__PURE__ */ t("p", { className: "font-medium text-foreground mb-2", children: [
738
- d + 1,
739
- ". ",
740
- l.content,
741
- l.required && /* @__PURE__ */ e("span", { className: "text-destructive ml-0.5", children: "*" })
742
- ] }),
743
- l.type === "likert" && /* @__PURE__ */ e(
744
- ft,
745
- {
746
- value: f ? Number(f.value) : null,
747
- onChange: (z) => g(l.uid, z),
748
- points: l.scalePoints,
749
- lowLabel: (F = l.scaleLabels) == null ? void 0 : F.low,
750
- highLabel: (T = l.scaleLabels) == null ? void 0 : T.high,
751
- readOnly: m
752
- }
753
- ),
754
- l.type === "rating" && /* @__PURE__ */ e(
755
- pt,
756
- {
757
- value: f ? Number(f.value) : 0,
758
- onChange: (z) => g(l.uid, z),
759
- readOnly: m
760
- }
761
- ),
762
- l.type === "open_text" && /* @__PURE__ */ e(
763
- Z,
764
- {
765
- placeholder: "Type your response...",
766
- value: (f == null ? void 0 : f.value) ?? "",
767
- onChange: (z) => g(l.uid, z),
768
- readOnly: m,
769
- className: "min-h-24",
770
- variant: "minimal"
771
- }
772
- ),
773
- l.type === "choice" && l.answers && /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: l.answers.map((z) => /* @__PURE__ */ t("label", { className: "flex items-center gap-2 cursor-pointer py-1 text-sm text-foreground has-[input:disabled]:cursor-default has-[input:disabled]:opacity-60", children: [
774
- /* @__PURE__ */ e(
775
- "input",
776
- {
777
- type: "radio",
778
- className: "accent-primary m-0 shrink-0",
779
- name: `survey-q-${l.uid}`,
780
- value: z.uid,
781
- checked: (f == null ? void 0 : f.value) === z.uid,
782
- onChange: () => g(l.uid, z.uid),
783
- disabled: m
784
- }
785
- ),
786
- /* @__PURE__ */ e("span", { children: z.content })
787
- ] }, z.uid)) }),
788
- l.type === "multiple_choice" && l.answers && /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: l.answers.map((z) => {
789
- const D = v.filter((I) => I.questionUid === l.uid).map((I) => String(I.value));
790
- return /* @__PURE__ */ t("label", { className: "flex items-center gap-2 cursor-pointer py-1 text-sm text-foreground has-[input:disabled]:cursor-default has-[input:disabled]:opacity-60", children: [
791
- /* @__PURE__ */ e(
792
- "input",
793
- {
794
- type: "checkbox",
795
- className: "accent-primary m-0 shrink-0",
796
- checked: D.includes(z.uid),
797
- disabled: m,
798
- onChange: (I) => {
799
- const u = v.filter((k) => k.questionUid === l.uid);
800
- let N;
801
- I.target.checked ? N = [...u, { questionUid: l.uid, value: z.uid }] : N = u.filter((k) => String(k.value) !== z.uid), L((k) => [
802
- ...k.filter((S) => S.questionUid !== l.uid),
803
- ...N
804
- ]), s == null || s([
805
- ...v.filter((k) => k.questionUid !== l.uid),
806
- ...N
807
- ]);
808
- }
809
- }
810
- ),
811
- /* @__PURE__ */ e("span", { children: z.content })
812
- ] }, z.uid);
813
- }) })
814
- ] }) }, l.uid);
815
- }),
816
- /* @__PURE__ */ e(E, { className: "my-3" }),
817
- /* @__PURE__ */ t("div", { className: "flex justify-between items-center", children: [
818
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
819
- w,
820
- " of ",
821
- i.length,
822
- " answered"
823
- ] }),
824
- /* @__PURE__ */ e(
825
- P,
826
- {
827
- onClick: () => h(v),
828
- disabled: !R || p || m,
829
- children: p ? "Submitting..." : b
830
- }
831
- )
832
- ] })
833
- ] });
834
- }
835
- function ra({
836
- title: a,
837
- blocks: r,
838
- isCompleted: i = !1,
839
- onMarkComplete: o,
840
- onNextLesson: h,
841
- nextLessonTitle: s,
842
- estimatedDuration: c,
843
- showDuration: n = !0,
844
- readOnly: b = !1,
845
- className: p,
846
- style: m
847
- }) {
848
- const [x, y] = A(i);
849
- function v() {
850
- y(!0), o == null || o();
851
- }
852
- return /* @__PURE__ */ t("div", { className: U(p), style: m, children: [
853
- /* @__PURE__ */ t("div", { className: "mb-3", children: [
854
- /* @__PURE__ */ e("p", { className: "text-2xl font-bold mb-0.5 text-foreground", children: a }),
855
- n && c != null && /* @__PURE__ */ t("div", { className: "flex items-center gap-0.5 text-muted-foreground", children: [
856
- /* @__PURE__ */ e(ze, { size: 16 }),
857
- /* @__PURE__ */ e("span", { className: "text-sm", children: Re(c) })
858
- ] })
859
- ] }),
860
- /* @__PURE__ */ e(E, { className: "mb-3" }),
861
- /* @__PURE__ */ e("div", { className: "flex flex-col gap-3", children: r.map((L, w) => /* @__PURE__ */ e(
862
- gt,
863
- {
864
- block: L,
865
- readOnly: b
866
- },
867
- w
868
- )) }),
869
- /* @__PURE__ */ e(B, { className: "mt-4 sticky bottom-0 z-10", children: /* @__PURE__ */ e(Q, { className: "px-4 py-3", children: /* @__PURE__ */ t("div", { className: "flex justify-between items-center", children: [
870
- x ? /* @__PURE__ */ t("div", { className: "flex items-center gap-1 text-success", children: [
871
- /* @__PURE__ */ e(be, { size: 20 }),
872
- /* @__PURE__ */ e("span", { className: "text-sm font-semibold", children: "Lesson Complete" })
873
- ] }) : /* @__PURE__ */ t(
874
- P,
875
- {
876
- onClick: v,
877
- disabled: b,
878
- children: [
879
- /* @__PURE__ */ e(be, { size: 18 }),
880
- " Mark Complete"
881
- ]
882
- }
883
- ),
884
- h && /* @__PURE__ */ t(
885
- P,
886
- {
887
- variant: x ? "default" : "outline",
888
- onClick: h,
889
- children: [
890
- s ? `Next: ${s}` : "Next Lesson",
891
- " ",
892
- /* @__PURE__ */ e(ue, { size: 18 })
893
- ]
894
- }
895
- )
896
- ] }) }) })
897
- ] });
898
- }
899
- function te(a) {
900
- return a.replace(/<[^>]*>/g, "").trim().length === 0;
901
- }
902
- function sa({
903
- title: a,
904
- rootPost: r,
905
- replies: i,
906
- currentUser: o,
907
- onReply: h,
908
- onToggleLike: s,
909
- onMarkAnswer: c,
910
- maxDepth: n = 3,
911
- allowReplies: b = !0,
912
- sortOrder: p = "oldest",
913
- readOnly: m = !1,
914
- className: x,
915
- style: y
916
- }) {
917
- const [v, L] = A(null), [w, R] = A(""), g = j(() => {
918
- const d = /* @__PURE__ */ new Map();
919
- for (const f of i) {
920
- const F = f.parentUid ?? r.uid, T = d.get(F) ?? [];
921
- T.push(f), d.set(F, T);
922
- }
923
- for (const [, f] of d)
924
- f.sort((F, T) => p === "newest" ? new Date(T.createdAt).getTime() - new Date(F.createdAt).getTime() : p === "most_liked" ? T.likeCount - F.likeCount : new Date(F.createdAt).getTime() - new Date(T.createdAt).getTime());
925
- return d;
926
- }, [i, r.uid, p]);
927
- function C(d) {
928
- te(w) || (h(d, w), R(""), L(null));
929
- }
930
- function l(d, f) {
931
- const F = g.get(d.uid) ?? [], T = Math.min(f, n), z = /* @__PURE__ */ t("div", { className: "flex items-center gap-1", children: [
932
- s && !m && /* @__PURE__ */ t(se, { children: [
933
- /* @__PURE__ */ e(le, { children: /* @__PURE__ */ t(
934
- P,
935
- {
936
- variant: "ghost",
937
- size: "sm",
938
- "aria-label": d.isLikedByCurrentUser ? "Unlike" : "Like",
939
- className: U(d.isLikedByCurrentUser && "text-destructive"),
940
- onClick: () => s(d.uid),
941
- children: [
942
- /* @__PURE__ */ e(Le, { size: 14, fill: d.isLikedByCurrentUser ? "currentColor" : "none" }),
943
- d.likeCount > 0 ? d.likeCount : "Like"
944
- ]
945
- }
946
- ) }),
947
- /* @__PURE__ */ e(ie, { children: d.isLikedByCurrentUser ? "Unlike" : "Like" })
948
- ] }),
949
- b && !m && /* @__PURE__ */ t(se, { children: [
950
- /* @__PURE__ */ e(le, { children: /* @__PURE__ */ t(
951
- P,
952
- {
953
- variant: "ghost",
954
- size: "sm",
955
- "aria-label": "Reply",
956
- onClick: () => L(d.uid),
957
- children: [
958
- /* @__PURE__ */ e(Ke, { size: 14 }),
959
- "Reply"
960
- ]
961
- }
962
- ) }),
963
- /* @__PURE__ */ e(ie, { children: "Reply" })
964
- ] }),
965
- c && !m && o.role !== "student" && !d.isAnswer && /* @__PURE__ */ t(se, { children: [
966
- /* @__PURE__ */ e(le, { children: /* @__PURE__ */ t(
967
- P,
968
- {
969
- variant: "ghost",
970
- size: "sm",
971
- "aria-label": "Mark as answer",
972
- className: "text-success",
973
- onClick: () => c(d.uid),
974
- children: [
975
- /* @__PURE__ */ e(he, { size: 14 }),
976
- "Mark Answer"
977
- ]
978
- }
979
- ) }),
980
- /* @__PURE__ */ e(ie, { children: "Mark as answer" })
981
- ] })
982
- ] });
983
- return /* @__PURE__ */ t("div", { children: [
984
- /* @__PURE__ */ e(
985
- xt,
986
- {
987
- author: d.author,
988
- content: d.content,
989
- createdAt: d.createdAt,
990
- updatedAt: d.updatedAt,
991
- actions: z,
992
- highlight: d.isAnswer ? "answer" : "none",
993
- indentLevel: T,
994
- className: "mb-2"
995
- }
996
- ),
997
- v === d.uid && /* @__PURE__ */ e(
998
- B,
999
- {
1000
- className: "mb-2",
1001
- style: { marginLeft: `${(T + 1) * 16}px` },
1002
- children: /* @__PURE__ */ t(Q, { className: "py-4", children: [
1003
- /* @__PURE__ */ e(
1004
- Z,
1005
- {
1006
- className: "min-h-15 mb-2",
1007
- placeholder: "Write a reply...",
1008
- value: w,
1009
- onChange: (D) => R(D),
1010
- variant: "minimal"
1011
- }
1012
- ),
1013
- /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
1014
- /* @__PURE__ */ e(
1015
- P,
1016
- {
1017
- size: "sm",
1018
- onClick: () => C(d.uid),
1019
- disabled: te(w),
1020
- children: "Post Reply"
1021
- }
1022
- ),
1023
- /* @__PURE__ */ e(
1024
- P,
1025
- {
1026
- variant: "ghost",
1027
- size: "sm",
1028
- onClick: () => {
1029
- L(null), R("");
1030
- },
1031
- children: "Cancel"
1032
- }
1033
- )
1034
- ] })
1035
- ] })
1036
- }
1037
- ),
1038
- F.map((D) => l(D, f + 1))
1039
- ] }, d.uid);
1040
- }
1041
- return /* @__PURE__ */ t("div", { className: x, style: y, children: [
1042
- /* @__PURE__ */ t("div", { className: "flex items-center gap-2 mb-2", children: [
1043
- /* @__PURE__ */ e(fe, { size: 20, className: "text-foreground shrink-0" }),
1044
- /* @__PURE__ */ e("span", { className: "text-lg font-semibold text-foreground", children: a }),
1045
- /* @__PURE__ */ t(G, { variant: "muted", className: "text-xs", children: [
1046
- i.length,
1047
- " ",
1048
- i.length === 1 ? "reply" : "replies"
1049
- ] })
1050
- ] }),
1051
- /* @__PURE__ */ e(E, { className: "mb-2" }),
1052
- l(r, 0)
1053
- ] });
1054
- }
1055
- function la({
1056
- title: a,
1057
- instructions: r,
1058
- dueDate: i,
1059
- maxScore: o,
1060
- status: h,
1061
- submissionTypes: s,
1062
- existingSubmission: c,
1063
- fileConstraints: n,
1064
- onSubmit: b,
1065
- onSaveDraft: p,
1066
- grade: m,
1067
- isSubmitting: x = !1,
1068
- readOnly: y = !1,
1069
- className: v,
1070
- style: L
1071
- }) {
1072
- const [w, R] = A((c == null ? void 0 : c.textContent) ?? ""), [g, C] = A((c == null ? void 0 : c.files) ?? []), [l, d] = A((c == null ? void 0 : c.url) ?? ""), [f, F] = A(s[0]), T = !y && !["submitted", "graded"].includes(h);
1073
- function z() {
1074
- return {
1075
- textContent: s.includes("text") ? w : void 0,
1076
- files: s.includes("file") ? g : void 0,
1077
- url: s.includes("url") ? l : void 0
1078
- };
1079
- }
1080
- return /* @__PURE__ */ t("div", { className: v, style: L, children: [
1081
- /* @__PURE__ */ e("div", { className: "flex justify-between items-start mb-2", children: /* @__PURE__ */ t("div", { children: [
1082
- /* @__PURE__ */ e("div", { className: "text-xl font-bold text-foreground mb-0.5", children: a }),
1083
- /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
1084
- /* @__PURE__ */ e(Ie, { status: h }),
1085
- i && /* @__PURE__ */ e(Me, { dueDate: i, size: "small" }),
1086
- o != null && /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
1087
- o,
1088
- " points"
1089
- ] })
1090
- ] })
1091
- ] }) }),
1092
- /* @__PURE__ */ e(B, { className: "mb-3", children: /* @__PURE__ */ t(Q, { className: "pt-6", children: [
1093
- /* @__PURE__ */ e("div", { className: "font-semibold text-sm text-foreground mb-1", children: "Instructions" }),
1094
- /* @__PURE__ */ e("div", { className: "text-muted-foreground text-sm", children: typeof r == "string" ? /* @__PURE__ */ e("span", { children: r }) : r })
1095
- ] }) }),
1096
- m && /* @__PURE__ */ e(Fe, { variant: "success", className: "mb-3", children: /* @__PURE__ */ t(Te, { children: [
1097
- /* @__PURE__ */ t("div", { className: "font-semibold text-sm mb-1", children: [
1098
- "Grade: ",
1099
- m.score,
1100
- o != null ? ` / ${o}` : ""
1101
- ] }),
1102
- m.feedback && /* @__PURE__ */ e("div", { children: m.feedback })
1103
- ] }) }),
1104
- T && /* @__PURE__ */ t(W, { children: [
1105
- s.length > 1 ? /* @__PURE__ */ t(Nt, { value: f, onValueChange: (D) => F(D), children: [
1106
- /* @__PURE__ */ t(bt, { children: [
1107
- s.includes("text") && /* @__PURE__ */ e(de, { value: "text", children: "Text" }),
1108
- s.includes("file") && /* @__PURE__ */ e(de, { value: "file", children: "File Upload" }),
1109
- s.includes("url") && /* @__PURE__ */ e(de, { value: "url", children: "URL" })
1110
- ] }),
1111
- s.includes("text") && /* @__PURE__ */ e(ce, { value: "text", children: /* @__PURE__ */ e(
1112
- Z,
1113
- {
1114
- className: "min-h-45",
1115
- placeholder: "Type your submission...",
1116
- value: w,
1117
- onChange: (D) => R(D),
1118
- variant: "default"
1119
- }
1120
- ) }),
1121
- s.includes("file") && /* @__PURE__ */ e(ce, { value: "file", children: /* @__PURE__ */ e(
1122
- ye,
1123
- {
1124
- files: g,
1125
- onFilesAdded: (D) => C((I) => [...I, ...D]),
1126
- onFileRemove: (D) => C((I) => I.filter((u, N) => N !== D)),
1127
- accept: n == null ? void 0 : n.acceptedTypes,
1128
- maxFiles: n == null ? void 0 : n.maxFiles,
1129
- maxSizeMB: n == null ? void 0 : n.maxSizeMB
1130
- }
1131
- ) }),
1132
- s.includes("url") && /* @__PURE__ */ e(ce, { value: "url", children: /* @__PURE__ */ e(
1133
- oe,
1134
- {
1135
- placeholder: "https://...",
1136
- value: l,
1137
- onChange: (D) => d(D.target.value)
1138
- }
1139
- ) })
1140
- ] }) : /* @__PURE__ */ t(W, { children: [
1141
- s.includes("text") && /* @__PURE__ */ e(
1142
- Z,
1143
- {
1144
- className: "min-h-45 mb-2",
1145
- placeholder: "Type your submission...",
1146
- value: w,
1147
- onChange: (D) => R(D),
1148
- variant: "default"
1149
- }
1150
- ),
1151
- s.includes("file") && /* @__PURE__ */ e("div", { className: "mb-2", children: /* @__PURE__ */ e(
1152
- ye,
1153
- {
1154
- files: g,
1155
- onFilesAdded: (D) => C((I) => [...I, ...D]),
1156
- onFileRemove: (D) => C((I) => I.filter((u, N) => N !== D)),
1157
- accept: n == null ? void 0 : n.acceptedTypes,
1158
- maxFiles: n == null ? void 0 : n.maxFiles,
1159
- maxSizeMB: n == null ? void 0 : n.maxSizeMB
1160
- }
1161
- ) }),
1162
- s.includes("url") && /* @__PURE__ */ e(
1163
- oe,
1164
- {
1165
- className: "mb-2",
1166
- placeholder: "https://...",
1167
- value: l,
1168
- onChange: (D) => d(D.target.value)
1169
- }
1170
- )
1171
- ] }),
1172
- /* @__PURE__ */ e(E, { className: "my-2" }),
1173
- /* @__PURE__ */ t("div", { className: "flex gap-2 justify-end", children: [
1174
- p && /* @__PURE__ */ t(
1175
- P,
1176
- {
1177
- variant: "outline",
1178
- onClick: () => p(z()),
1179
- disabled: x,
1180
- children: [
1181
- /* @__PURE__ */ e(Xe, { size: 16 }),
1182
- "Save Draft"
1183
- ]
1184
- }
1185
- ),
1186
- /* @__PURE__ */ t(
1187
- P,
1188
- {
1189
- onClick: () => b(z()),
1190
- disabled: x,
1191
- children: [
1192
- /* @__PURE__ */ e(Se, { size: 16 }),
1193
- x ? "Submitting..." : "Submit"
1194
- ]
1195
- }
1196
- )
1197
- ] })
1198
- ] })
1199
- ] });
1200
- }
1201
- function q({
1202
- label: a,
1203
- field: r,
1204
- sortField: i,
1205
- sortDir: o,
1206
- onSort: h,
1207
- textAlign: s
1208
- }) {
1209
- const c = i === r;
1210
- return /* @__PURE__ */ e(
1211
- ee,
1212
- {
1213
- className: U(
1214
- "cursor-pointer select-none hover:bg-muted",
1215
- s === "right" && "text-right"
1216
- ),
1217
- onClick: () => h(r),
1218
- children: /* @__PURE__ */ t("div", { className: U("flex items-center gap-1", s === "right" && "justify-end"), children: [
1219
- /* @__PURE__ */ e("span", { className: U(c ? "text-foreground" : "text-muted-foreground"), children: a }),
1220
- c && (o === "asc" ? /* @__PURE__ */ e(Je, { size: 14 }) : /* @__PURE__ */ e(qe, { size: 14 }))
1221
- ] })
1222
- }
1223
- );
1224
- }
1225
- function ia({
1226
- items: a,
1227
- categories: r,
1228
- overallGrade: i,
1229
- showWeights: o = !0,
1230
- showCategoryTotals: h = !0,
1231
- onItemClick: s,
1232
- readOnly: c = !1,
1233
- className: n,
1234
- style: b
1235
- }) {
1236
- const [p, m] = A("dueDate"), [x, y] = A("asc");
1237
- function v(g) {
1238
- p === g ? y((C) => C === "asc" ? "desc" : "asc") : (m(g), y("asc"));
1239
- }
1240
- const L = j(() => {
1241
- const g = [...a];
1242
- return g.sort((C, l) => {
1243
- let d = 0;
1244
- switch (p) {
1245
- case "name":
1246
- d = C.name.localeCompare(l.name);
1247
- break;
1248
- case "score":
1249
- d = (C.score ?? -1) - (l.score ?? -1);
1250
- break;
1251
- case "dueDate":
1252
- d = (C.dueDate ?? "").localeCompare(l.dueDate ?? "");
1253
- break;
1254
- case "status":
1255
- d = C.status.localeCompare(l.status);
1256
- break;
1257
- }
1258
- return x === "asc" ? d : -d;
1259
- }), g;
1260
- }, [a, p, x]), w = j(() => {
1261
- if (!r || r.length === 0) return [{ category: null, items: L }];
1262
- const g = r.map((l) => ({
1263
- category: l,
1264
- items: L.filter((d) => d.categoryUid === l.uid)
1265
- })), C = L.filter((l) => !l.categoryUid);
1266
- return C.length > 0 && g.push({ category: null, items: C }), g;
1267
- }, [L, r]), R = o ? 5 : 4;
1268
- return /* @__PURE__ */ t("div", { className: n, style: b, children: [
1269
- i && /* @__PURE__ */ e(B, { className: "mb-3", children: /* @__PURE__ */ e(Q, { className: "pt-6", children: /* @__PURE__ */ t("div", { className: "flex items-center gap-3", children: [
1270
- /* @__PURE__ */ e(
1271
- vt,
1272
- {
1273
- percentage: i.percentage,
1274
- letterGrade: i.letterGrade,
1275
- size: "large",
1276
- passingThreshold: 60
1277
- }
1278
- ),
1279
- /* @__PURE__ */ t("div", { children: [
1280
- /* @__PURE__ */ e("div", { className: "text-lg font-semibold text-foreground", children: "Overall Grade" }),
1281
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
1282
- i.pointsEarned,
1283
- " / ",
1284
- i.pointsPossible,
1285
- " points"
1286
- ] })
1287
- ] })
1288
- ] }) }) }),
1289
- /* @__PURE__ */ e(B, { children: /* @__PURE__ */ t(Pe, { children: [
1290
- /* @__PURE__ */ e(Be, { children: /* @__PURE__ */ t(Y, { children: [
1291
- /* @__PURE__ */ e(
1292
- q,
1293
- {
1294
- label: "Assignment",
1295
- field: "name",
1296
- sortField: p,
1297
- sortDir: x,
1298
- onSort: v
1299
- }
1300
- ),
1301
- /* @__PURE__ */ e(
1302
- q,
1303
- {
1304
- label: "Status",
1305
- field: "status",
1306
- sortField: p,
1307
- sortDir: x,
1308
- onSort: v
1309
- }
1310
- ),
1311
- /* @__PURE__ */ e(
1312
- q,
1313
- {
1314
- label: "Due Date",
1315
- field: "dueDate",
1316
- sortField: p,
1317
- sortDir: x,
1318
- onSort: v
1319
- }
1320
- ),
1321
- /* @__PURE__ */ e(
1322
- q,
1323
- {
1324
- label: "Score",
1325
- field: "score",
1326
- sortField: p,
1327
- sortDir: x,
1328
- onSort: v,
1329
- textAlign: "right"
1330
- }
1331
- ),
1332
- o && /* @__PURE__ */ e(ee, { className: "text-right text-muted-foreground", children: "Weight" })
1333
- ] }) }),
1334
- /* @__PURE__ */ e(Qe, { children: w.map((g, C) => {
1335
- var l;
1336
- return /* @__PURE__ */ t(Ye, { children: [
1337
- g.category && h && /* @__PURE__ */ e(Y, { className: "bg-muted hover:bg-muted", children: /* @__PURE__ */ e(V, { colSpan: R, children: /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-foreground", children: [
1338
- g.category.name,
1339
- g.category.weight != null && ` (${g.category.weight}%)`
1340
- ] }) }) }),
1341
- g.items.map((d) => /* @__PURE__ */ t(
1342
- Y,
1343
- {
1344
- className: U(s && !c && "cursor-pointer"),
1345
- onClick: () => s && !c ? s(d) : void 0,
1346
- children: [
1347
- /* @__PURE__ */ e(V, { children: d.name }),
1348
- /* @__PURE__ */ e(V, { children: /* @__PURE__ */ e(Ie, { status: d.status, size: "small" }) }),
1349
- /* @__PURE__ */ e(V, { children: d.dueDate ? /* @__PURE__ */ e(
1350
- Me,
1351
- {
1352
- dueDate: d.dueDate,
1353
- submittedDate: d.submittedDate,
1354
- size: "small"
1355
- }
1356
- ) : "—" }),
1357
- /* @__PURE__ */ e(V, { className: "text-right", children: d.score != null ? /* @__PURE__ */ t("span", { className: "text-sm font-semibold text-foreground", children: [
1358
- d.score,
1359
- " / ",
1360
- d.maxScore
1361
- ] }) : d.status === "excused" ? /* @__PURE__ */ e("span", { className: "text-sm text-muted-foreground", children: "Excused" }) : /* @__PURE__ */ e("span", { className: "text-sm text-muted-foreground", children: "—" }) }),
1362
- o && /* @__PURE__ */ e(V, { className: "text-right", children: d.weight != null ? `${d.weight}%` : "—" })
1363
- ]
1364
- },
1365
- d.uid
1366
- ))
1367
- ] }, ((l = g.category) == null ? void 0 : l.uid) ?? `ungrouped-${C}`);
1368
- }) })
1369
- ] }) })
1370
- ] });
1371
- }
1372
- function da({
1373
- overallProgress: a,
1374
- totalTimeSpent: r,
1375
- modules: i,
1376
- recentActivity: o,
1377
- streak: h,
1378
- achievements: s,
1379
- recentActivityLimit: c = 5,
1380
- onModuleClick: n,
1381
- className: b,
1382
- style: p
1383
- }) {
1384
- return /* @__PURE__ */ t("div", { className: b, style: p, children: [
1385
- /* @__PURE__ */ t("div", { className: "grid grid-cols-[repeat(auto-fit,minmax(160px,1fr))] gap-3 mb-4", children: [
1386
- /* @__PURE__ */ e(B, { children: /* @__PURE__ */ e(Q, { className: "p-3 flex justify-center", children: /* @__PURE__ */ e(wt, { value: a, size: 100 }) }) }),
1387
- /* @__PURE__ */ e(
1388
- ke,
1389
- {
1390
- icon: /* @__PURE__ */ e(ze, { size: 24 }),
1391
- label: "Time Spent",
1392
- description: "Total learning time",
1393
- value: Re(r)
1394
- }
1395
- ),
1396
- h && /* @__PURE__ */ e(B, { children: /* @__PURE__ */ e(Q, { className: "p-4 flex items-center", children: /* @__PURE__ */ e(
1397
- yt,
1398
- {
1399
- currentStreak: h.currentDays,
1400
- longestStreak: h.longestDays,
1401
- showLongest: !0
1402
- }
1403
- ) }) }),
1404
- /* @__PURE__ */ e(
1405
- ke,
1406
- {
1407
- icon: /* @__PURE__ */ e(et, { size: 24 }),
1408
- label: "Modules",
1409
- description: "Course progress",
1410
- value: `${i.filter((m) => m.completedItems === m.totalItems).length} / ${i.length}`,
1411
- subtitle: "completed"
1412
- }
1413
- )
1414
- ] }),
1415
- /* @__PURE__ */ e(E, { className: "mb-3" }),
1416
- /* @__PURE__ */ e("p", { className: "text-lg font-semibold mb-2 text-foreground", children: "Module Progress" }),
1417
- /* @__PURE__ */ e("div", { className: "flex flex-col gap-2 mb-4", children: i.map((m) => {
1418
- const x = m.totalItems > 0 ? m.completedItems / m.totalItems * 100 : 0;
1419
- return /* @__PURE__ */ e(
1420
- B,
1421
- {
1422
- className: U(
1423
- "transition-colors",
1424
- n && "cursor-pointer hover:border-primary"
1425
- ),
1426
- onClick: () => n == null ? void 0 : n(m.uid),
1427
- children: /* @__PURE__ */ t(Q, { className: "p-3", children: [
1428
- /* @__PURE__ */ t("div", { className: "flex justify-between items-center mb-0.5", children: [
1429
- /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-foreground", children: m.name }),
1430
- /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: [
1431
- m.completedItems,
1432
- " / ",
1433
- m.totalItems
1434
- ] })
1435
- ] }),
1436
- /* @__PURE__ */ e(K, { value: x, size: "sm" })
1437
- ] })
1438
- },
1439
- m.uid
1440
- );
1441
- }) }),
1442
- o && o.length > 0 && /* @__PURE__ */ t(W, { children: [
1443
- /* @__PURE__ */ e(E, { className: "mb-3" }),
1444
- /* @__PURE__ */ e("p", { className: "text-lg font-semibold mb-2 text-foreground", children: "Recent Activity" }),
1445
- /* @__PURE__ */ e("div", { className: "mb-4", children: /* @__PURE__ */ e(
1446
- kt,
1447
- {
1448
- events: o.map((m) => ({
1449
- uid: m.uid,
1450
- type: m.type,
1451
- title: m.description,
1452
- timestamp: m.timestamp
1453
- })),
1454
- limit: c
1455
- }
1456
- ) })
1457
- ] }),
1458
- s && s.length > 0 && /* @__PURE__ */ t(W, { children: [
1459
- /* @__PURE__ */ e(E, { className: "mb-3" }),
1460
- /* @__PURE__ */ e("p", { className: "text-lg font-semibold mb-2 text-foreground", children: "Achievements" }),
1461
- /* @__PURE__ */ e("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-2", children: s.map((m) => /* @__PURE__ */ e(
1462
- Ct,
1463
- {
1464
- title: m.name,
1465
- description: m.description,
1466
- icon: m.iconUrl ? /* @__PURE__ */ e(
1467
- "img",
1468
- {
1469
- src: m.iconUrl,
1470
- alt: m.name,
1471
- className: "w-12 h-12"
1472
- }
1473
- ) : void 0,
1474
- earnedDate: m.earnedAt
1475
- },
1476
- m.uid
1477
- )) })
1478
- ] })
1479
- ] });
1480
- }
1481
- const Ft = je("mx-auto max-w-4xl", {
1482
- variants: {
1483
- variant: {
1484
- classic: "border-[3px] border-double border-warning/50 rounded-lg p-1.5",
1485
- modern: "rounded-lg",
1486
- elegant: "border border-foreground/15 rounded-lg p-2.5 dark:border-foreground/10",
1487
- academic: "border-2 border-info/30 rounded-lg p-1.5",
1488
- minimal: "rounded-lg",
1489
- bold: "rounded-lg"
1490
- }
1491
- },
1492
- defaultVariants: { variant: "classic" }
1493
- }), Tt = je(
1494
- "relative text-center p-8 sm:p-12 md:p-16 overflow-hidden",
1495
- {
1496
- variants: {
1497
- variant: {
1498
- classic: "border border-warning/25 rounded bg-warning/5",
1499
- modern: "border border-primary/20 rounded-lg bg-linear-to-br from-primary/5 to-primary/8 border-t-[3px] border-t-primary/60",
1500
- elegant: "border border-foreground/8 rounded bg-linear-to-b from-background to-muted/20 dark:border-foreground/5 dark:to-muted/10",
1501
- academic: "border border-info/15 rounded bg-info/3",
1502
- minimal: "border border-border rounded-lg bg-background",
1503
- bold: "border-[3px] border-primary rounded-lg bg-linear-to-br from-primary/8 to-purple/8"
1504
- }
1505
- },
1506
- defaultVariants: { variant: "classic" }
1507
- }
1508
- ), Rt = {
1509
- classic: {
1510
- size: 40,
1511
- paths: [
1512
- { d: "M 2 38 L 2 10 Q 2 2 10 2 L 38 2", strokeWidth: 1.5 },
1513
- { d: "M 7 38 L 7 13 Q 7 7 13 7 L 38 7", strokeWidth: 0.75 }
1514
- ],
1515
- color: "text-warning/50"
1516
- },
1517
- modern: null,
1518
- elegant: {
1519
- size: 32,
1520
- paths: [{ d: "M 0 30 L 0 0 L 30 0", strokeWidth: 0.5 }],
1521
- dots: [{ cx: 2.5, cy: 2.5, r: 1.5 }],
1522
- color: "text-foreground/20"
1523
- },
1524
- academic: {
1525
- size: 36,
1526
- paths: [
1527
- { d: "M 0 36 L 0 0 L 36 0", strokeWidth: 2 },
1528
- { d: "M 5 36 L 5 5 L 36 5", strokeWidth: 1 }
1529
- ],
1530
- color: "text-info/35"
1531
- },
1532
- minimal: null,
1533
- bold: {
1534
- size: 20,
1535
- paths: [],
1536
- dots: [{ cx: 5, cy: 5, r: 5 }],
1537
- color: "text-primary/40"
1538
- }
1539
- }, It = [
1540
- { key: "tl", pos: "top-3 left-3", transform: void 0 },
1541
- { key: "tr", pos: "top-3 right-3", transform: "scaleX(-1)" },
1542
- { key: "bl", pos: "bottom-3 left-3", transform: "scaleY(-1)" },
1543
- { key: "br", pos: "bottom-3 right-3", transform: "scale(-1)" }
1544
- ];
1545
- function Mt({ variant: a }) {
1546
- const r = Rt[a];
1547
- return r ? /* @__PURE__ */ e(W, { children: It.map(({ key: i, pos: o, transform: h }) => {
1548
- var s;
1549
- return /* @__PURE__ */ t(
1550
- "svg",
1551
- {
1552
- className: U("absolute pointer-events-none", o, r.color),
1553
- width: r.size,
1554
- height: r.size,
1555
- viewBox: `0 0 ${r.size} ${r.size}`,
1556
- fill: "none",
1557
- stroke: "currentColor",
1558
- style: h ? { transform: h } : void 0,
1559
- "aria-hidden": "true",
1560
- children: [
1561
- r.paths.map((c, n) => /* @__PURE__ */ e("path", { d: c.d, strokeWidth: c.strokeWidth }, n)),
1562
- (s = r.dots) == null ? void 0 : s.map((c, n) => /* @__PURE__ */ e(
1563
- "circle",
1564
- {
1565
- cx: c.cx,
1566
- cy: c.cy,
1567
- r: c.r,
1568
- fill: "currentColor",
1569
- stroke: "none"
1570
- },
1571
- `d${n}`
1572
- ))
1573
- ]
1574
- },
1575
- i
1576
- );
1577
- }) }) : null;
1578
- }
1579
- const Pt = {
1580
- classic: {
1581
- lineColor: "bg-warning/30",
1582
- motif: /* @__PURE__ */ e(
1583
- "svg",
1584
- {
1585
- width: "12",
1586
- height: "12",
1587
- viewBox: "0 0 12 12",
1588
- className: "text-warning/50 shrink-0",
1589
- "aria-hidden": "true",
1590
- children: /* @__PURE__ */ e("path", { d: "M6 0 L12 6 L6 12 L0 6 Z", fill: "currentColor" })
1591
- }
1592
- )
1593
- },
1594
- modern: {
1595
- lineColor: "bg-primary/20",
1596
- motif: /* @__PURE__ */ e(
1597
- "svg",
1598
- {
1599
- width: "8",
1600
- height: "8",
1601
- viewBox: "0 0 8 8",
1602
- className: "text-primary/40 shrink-0",
1603
- "aria-hidden": "true",
1604
- children: /* @__PURE__ */ e("circle", { cx: "4", cy: "4", r: "3", fill: "currentColor" })
1605
- }
1606
- )
1607
- },
1608
- elegant: {
1609
- lineColor: "bg-foreground/10",
1610
- motif: /* @__PURE__ */ e(
1611
- "svg",
1612
- {
1613
- width: "10",
1614
- height: "10",
1615
- viewBox: "0 0 10 10",
1616
- className: "text-foreground/15 shrink-0",
1617
- "aria-hidden": "true",
1618
- children: /* @__PURE__ */ e(
1619
- "path",
1620
- {
1621
- d: "M5 0 L6 4 L10 5 L6 6 L5 10 L4 6 L0 5 L4 4 Z",
1622
- fill: "currentColor"
1623
- }
1624
- )
1625
- }
1626
- )
1627
- },
1628
- academic: {
1629
- lineColor: "bg-info/25",
1630
- motif: /* @__PURE__ */ e(
1631
- "svg",
1632
- {
1633
- width: "10",
1634
- height: "10",
1635
- viewBox: "0 0 10 10",
1636
- className: "text-info/40 shrink-0",
1637
- "aria-hidden": "true",
1638
- children: /* @__PURE__ */ e(
1639
- "path",
1640
- {
1641
- d: "M4 0 L6 0 L6 4 L10 4 L10 6 L6 6 L6 10 L4 10 L4 6 L0 6 L0 4 L4 4 Z",
1642
- fill: "currentColor"
1643
- }
1644
- )
1645
- }
1646
- )
1647
- },
1648
- minimal: {
1649
- lineColor: "bg-border",
1650
- motif: null
1651
- },
1652
- bold: {
1653
- lineColor: "bg-primary/40",
1654
- motif: /* @__PURE__ */ e(
1655
- "svg",
1656
- {
1657
- width: "10",
1658
- height: "10",
1659
- viewBox: "0 0 10 10",
1660
- className: "text-primary/50 shrink-0",
1661
- "aria-hidden": "true",
1662
- children: /* @__PURE__ */ e("rect", { x: "1", y: "1", width: "8", height: "8", fill: "currentColor" })
1663
- }
1664
- )
1665
- }
1666
- };
1667
- function Ce({
1668
- variant: a,
1669
- className: r
1670
- }) {
1671
- const i = Pt[a];
1672
- return /* @__PURE__ */ t(
1673
- "div",
1674
- {
1675
- className: U(
1676
- "flex items-center justify-center gap-3 my-5 mx-auto max-w-70",
1677
- r
1678
- ),
1679
- role: "separator",
1680
- "aria-hidden": "true",
1681
- children: [
1682
- /* @__PURE__ */ e("span", { className: U("flex-1 h-px", i.lineColor) }),
1683
- i.motif,
1684
- /* @__PURE__ */ e("span", { className: U("flex-1 h-px", i.lineColor) })
1685
- ]
1686
- }
1687
- );
1688
- }
1689
- const Bt = {
1690
- classic: {
1691
- background: "radial-gradient(ellipse at center, var(--color-warning) 0%, transparent 65%)",
1692
- opacity: 0.06
1693
- },
1694
- modern: null,
1695
- elegant: {
1696
- background: "radial-gradient(ellipse at center, var(--color-foreground) 0%, transparent 70%)",
1697
- opacity: 0.03
1698
- },
1699
- academic: {
1700
- background: "radial-gradient(ellipse at center, var(--color-info) 0%, transparent 65%)",
1701
- opacity: 0.05
1702
- },
1703
- minimal: null,
1704
- bold: {
1705
- background: "radial-gradient(ellipse at 30% 50%, var(--color-primary) 0%, transparent 50%), radial-gradient(ellipse at 70% 50%, var(--color-purple) 0%, transparent 50%)",
1706
- opacity: 0.06
1707
- }
1708
- }, Qt = {
1709
- classic: "text-warning",
1710
- modern: "text-primary",
1711
- elegant: "text-foreground/60",
1712
- academic: "text-info",
1713
- minimal: "text-muted-foreground",
1714
- bold: "text-primary"
1715
- }, jt = {
1716
- classic: "uppercase tracking-[4px] text-base font-medium text-foreground/80 font-serif",
1717
- modern: "uppercase tracking-[3px] text-base font-medium text-primary/80",
1718
- elegant: "uppercase tracking-[5px] text-sm font-light text-foreground/50",
1719
- academic: "uppercase tracking-[3px] text-base font-semibold text-info/80",
1720
- minimal: "uppercase tracking-[2px] text-sm font-normal text-muted-foreground",
1721
- bold: "uppercase tracking-[3px] text-lg font-black text-primary"
1722
- }, _t = {
1723
- classic: "text-warning",
1724
- modern: "text-primary",
1725
- elegant: "text-foreground/80",
1726
- academic: "text-info",
1727
- minimal: "text-foreground",
1728
- bold: "text-primary"
1729
- }, Et = /* @__PURE__ */ new Set([
1730
- "classic",
1731
- "elegant",
1732
- "academic"
1733
- ]);
1734
- function ca({
1735
- recipientName: a,
1736
- courseTitle: r,
1737
- completionDate: i,
1738
- organizationName: o,
1739
- organizationLogo: h,
1740
- signatory: s,
1741
- certificateId: c,
1742
- variant: n = "classic",
1743
- showActions: b = !0,
1744
- onPrint: p,
1745
- onDownload: m,
1746
- className: x,
1747
- style: y
1748
- }) {
1749
- const v = (() => {
1750
- try {
1751
- return new Date(i).toLocaleDateString("en-US", {
1752
- year: "numeric",
1753
- month: "long",
1754
- day: "numeric"
1755
- });
1756
- } catch {
1757
- return i;
1758
- }
1759
- })();
1760
- function L() {
1761
- p ? p() : window.print();
1762
- }
1763
- const w = Bt[n];
1764
- return /* @__PURE__ */ t("div", { className: x, style: y, children: [
1765
- /* @__PURE__ */ e("div", { className: Ft({ variant: n }), children: /* @__PURE__ */ t("div", { className: Tt({ variant: n }), children: [
1766
- /* @__PURE__ */ e(Mt, { variant: n }),
1767
- w && /* @__PURE__ */ e(
1768
- "div",
1769
- {
1770
- className: "absolute inset-0 pointer-events-none rounded-[inherit]",
1771
- style: w,
1772
- "aria-hidden": "true"
1773
- }
1774
- ),
1775
- /* @__PURE__ */ t("div", { className: "relative", children: [
1776
- h ? /* @__PURE__ */ e(
1777
- "img",
1778
- {
1779
- src: h,
1780
- alt: o,
1781
- className: "h-20 mb-4 mx-auto block"
1782
- }
1783
- ) : /* @__PURE__ */ e(
1784
- tt,
1785
- {
1786
- size: 64,
1787
- className: U("mx-auto mb-6", Qt[n])
1788
- }
1789
- ),
1790
- /* @__PURE__ */ e("p", { className: U("mb-2", jt[n]), children: "Certificate of Completion" }),
1791
- /* @__PURE__ */ e(Ce, { variant: n }),
1792
- /* @__PURE__ */ e("p", { className: "text-base text-foreground/70 mb-2", children: "This is to certify that" }),
1793
- /* @__PURE__ */ e(
1794
- "p",
1795
- {
1796
- className: U(
1797
- "text-4xl font-bold mb-4 text-foreground",
1798
- Et.has(n) && "font-serif"
1799
- ),
1800
- children: a
1801
- }
1802
- ),
1803
- /* @__PURE__ */ e("p", { className: "text-base text-foreground/70 mb-2", children: "has successfully completed" }),
1804
- /* @__PURE__ */ e(
1805
- "p",
1806
- {
1807
- className: U(
1808
- "text-2xl font-semibold mb-4",
1809
- _t[n]
1810
- ),
1811
- children: r
1812
- }
1813
- ),
1814
- /* @__PURE__ */ t("p", { className: "text-base text-foreground/60 mb-6", children: [
1815
- "Issued by ",
1816
- o,
1817
- " on ",
1818
- v
1819
- ] }),
1820
- s && /* @__PURE__ */ t("div", { className: "mt-6 mb-4", children: [
1821
- /* @__PURE__ */ e(Ce, { variant: n }),
1822
- /* @__PURE__ */ e("p", { className: "font-semibold text-base text-foreground", children: s.name }),
1823
- /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: s.title })
1824
- ] }),
1825
- c && /* @__PURE__ */ t("span", { className: "block text-xs text-muted-foreground mt-4", children: [
1826
- "Certificate ID: ",
1827
- c
1828
- ] })
1829
- ] })
1830
- ] }) }),
1831
- b && /* @__PURE__ */ t("div", { className: "flex justify-center gap-3 mt-6", children: [
1832
- /* @__PURE__ */ t(P, { variant: "outline", onClick: L, children: [
1833
- /* @__PURE__ */ e(at, { size: 16 }),
1834
- " Print"
1835
- ] }),
1836
- m && /* @__PURE__ */ t(P, { variant: "outline", onClick: m, children: [
1837
- /* @__PURE__ */ e(nt, { size: 16 }),
1838
- " Download"
1839
- ] })
1840
- ] })
1841
- ] });
1842
- }
1843
- function oa({
1844
- criteria: a,
1845
- selectedLevels: r,
1846
- totalScore: i,
1847
- maxScore: o,
1848
- feedback: h,
1849
- className: s,
1850
- style: c
1851
- }) {
1852
- var b;
1853
- const n = r && Object.keys(r).length > 0;
1854
- return /* @__PURE__ */ t("div", { className: U("flex flex-col gap-4", s), style: c, children: [
1855
- n && i !== void 0 && o !== void 0 && /* @__PURE__ */ t("div", { className: "flex items-center justify-between", children: [
1856
- /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-foreground", children: "Rubric" }),
1857
- /* @__PURE__ */ t(G, { variant: i >= o * 0.7 ? "success" : "destructive", children: [
1858
- i,
1859
- " / ",
1860
- o,
1861
- " pts"
1862
- ] })
1863
- ] }),
1864
- !n && /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-foreground", children: "Grading Rubric" }),
1865
- /* @__PURE__ */ e(B, { children: /* @__PURE__ */ e(Q, { className: "p-0", children: /* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ t(Pe, { className: "text-sm", children: [
1866
- /* @__PURE__ */ e(Be, { children: /* @__PURE__ */ t(Y, { className: "bg-muted/50", children: [
1867
- /* @__PURE__ */ e(ee, { className: "text-left font-medium text-muted-foreground w-1/5", children: "Criterion" }),
1868
- (b = a[0]) == null ? void 0 : b.levels.map((p) => /* @__PURE__ */ t(
1869
- ee,
1870
- {
1871
- className: "text-center font-medium text-muted-foreground",
1872
- children: [
1873
- /* @__PURE__ */ e("div", { children: p.label }),
1874
- /* @__PURE__ */ t("div", { className: "text-xs font-normal mt-0.5", children: [
1875
- p.points,
1876
- " pts"
1877
- ] })
1878
- ]
1879
- },
1880
- p.uid
1881
- ))
1882
- ] }) }),
1883
- /* @__PURE__ */ e(Qe, { children: a.map((p, m) => {
1884
- const x = r == null ? void 0 : r[p.uid];
1885
- return /* @__PURE__ */ t(
1886
- Y,
1887
- {
1888
- className: U(m % 2 === 1 && "bg-muted/20"),
1889
- children: [
1890
- /* @__PURE__ */ t(V, { className: "align-top", children: [
1891
- /* @__PURE__ */ e("div", { className: "font-medium text-foreground", children: p.name }),
1892
- p.description && /* @__PURE__ */ e("div", { className: "text-xs text-muted-foreground mt-0.5", children: p.description })
1893
- ] }),
1894
- p.levels.map((y) => {
1895
- const v = x === y.uid;
1896
- return /* @__PURE__ */ t(
1897
- V,
1898
- {
1899
- className: U(
1900
- "align-top text-center",
1901
- v && "bg-primary/10 ring-2 ring-primary/30 ring-inset rounded-sm"
1902
- ),
1903
- children: [
1904
- /* @__PURE__ */ e("div", { className: "text-xs text-muted-foreground", children: y.description }),
1905
- v && /* @__PURE__ */ e("div", { className: "mt-1.5 flex justify-center", children: /* @__PURE__ */ e(pe, { className: "size-4 text-primary" }) })
1906
- ]
1907
- },
1908
- y.uid
1909
- );
1910
- })
1911
- ]
1912
- },
1913
- p.uid
1914
- );
1915
- }) })
1916
- ] }) }) }) }),
1917
- h && /* @__PURE__ */ t(W, { children: [
1918
- /* @__PURE__ */ e(E, {}),
1919
- /* @__PURE__ */ t("div", { children: [
1920
- /* @__PURE__ */ e("h4", { className: "text-sm font-medium text-foreground mb-1", children: "Instructor Feedback" }),
1921
- /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground whitespace-pre-wrap", children: h })
1922
- ] })
1923
- ] })
1924
- ] });
1925
- }
1926
- function ma({
1927
- title: a,
1928
- requirements: r,
1929
- onRequirementClick: i,
1930
- className: o,
1931
- style: h
1932
- }) {
1933
- const s = j(
1934
- () => r.filter((n) => n.completed).length,
1935
- [r]
1936
- ), c = r.length > 0 ? Math.round(s / r.length * 100) : 0;
1937
- return /* @__PURE__ */ t("div", { className: U("flex flex-col gap-4", o), style: h, children: [
1938
- a && /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-foreground", children: a }),
1939
- /* @__PURE__ */ t("div", { className: "flex flex-col gap-1.5", children: [
1940
- /* @__PURE__ */ t("div", { className: "flex items-center justify-between text-sm", children: [
1941
- /* @__PURE__ */ t("span", { className: "text-muted-foreground", children: [
1942
- s,
1943
- " of ",
1944
- r.length,
1945
- " complete"
1946
- ] }),
1947
- /* @__PURE__ */ t("span", { className: "font-medium text-foreground", children: [
1948
- c,
1949
- "%"
1950
- ] })
1951
- ] }),
1952
- /* @__PURE__ */ e(K, { value: c })
1953
- ] }),
1954
- /* @__PURE__ */ e("ul", { className: "flex flex-col gap-1", children: r.map((n) => /* @__PURE__ */ e("li", { children: /* @__PURE__ */ t(
1955
- "button",
1956
- {
1957
- type: "button",
1958
- className: U(
1959
- "w-full flex items-start gap-3 p-3 rounded-lg text-left transition-colors",
1960
- n.completed ? "bg-success/5" : i ? "hover:bg-muted/50 cursor-pointer" : "cursor-default"
1961
- ),
1962
- onClick: () => {
1963
- !n.completed && i && i(n.uid);
1964
- },
1965
- disabled: n.completed,
1966
- children: [
1967
- n.completed ? /* @__PURE__ */ e(pe, { className: "size-5 text-success shrink-0 mt-0.5" }) : /* @__PURE__ */ e(rt, { className: "size-5 text-muted-foreground shrink-0 mt-0.5" }),
1968
- /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
1969
- /* @__PURE__ */ e(
1970
- "div",
1971
- {
1972
- className: U(
1973
- "text-sm font-medium",
1974
- n.completed ? "text-muted-foreground line-through" : "text-foreground"
1975
- ),
1976
- children: n.label
1977
- }
1978
- ),
1979
- n.description && /* @__PURE__ */ e("div", { className: "text-xs text-muted-foreground mt-0.5", children: n.description })
1980
- ] }),
1981
- !n.completed && i && /* @__PURE__ */ t("div", { className: "shrink-0 flex items-center gap-1 text-xs text-primary mt-0.5", children: [
1982
- n.actionLabel && /* @__PURE__ */ e("span", { children: n.actionLabel }),
1983
- /* @__PURE__ */ e(ue, { className: "size-4" })
1984
- ] })
1985
- ]
1986
- }
1987
- ) }, n.uid)) })
1988
- ] });
1989
- }
1990
- const $t = {
1991
- newest: "Newest",
1992
- oldest: "Oldest",
1993
- most_replies: "Most Replies",
1994
- most_liked: "Most Liked"
1995
- };
1996
- function ua({
1997
- title: a,
1998
- topics: r,
1999
- onTopicClick: i,
2000
- onCreateTopic: o,
2001
- sortOrder: h = "newest",
2002
- onSortChange: s,
2003
- searchQuery: c = "",
2004
- onSearchChange: n,
2005
- readOnly: b,
2006
- className: p,
2007
- style: m
2008
- }) {
2009
- const [x, y] = A(!1), [v, L] = A(""), [w, R] = A(""), [g, C] = A(c), [l, d] = A(h), f = n !== void 0 ? c : g, F = s !== void 0 ? h : l;
2010
- function T(u) {
2011
- n ? n(u) : C(u);
2012
- }
2013
- function z() {
2014
- const u = [
2015
- "newest",
2016
- "oldest",
2017
- "most_replies",
2018
- "most_liked"
2019
- ], N = u.indexOf(F), k = u[(N + 1) % u.length];
2020
- s ? s(k) : d(k);
2021
- }
2022
- function D() {
2023
- !v.trim() || te(w) || (o == null || o(v.trim(), w), L(""), R(""), y(!1));
2024
- }
2025
- const I = j(() => [...r.filter((N) => {
2026
- var S;
2027
- if (!f) return !0;
2028
- const k = f.toLowerCase();
2029
- return N.title.toLowerCase().includes(k) || ((S = N.preview) == null ? void 0 : S.toLowerCase().includes(k)) || N.author.displayName.toLowerCase().includes(k);
2030
- })].sort((N, k) => {
2031
- if (N.isPinned && !k.isPinned) return -1;
2032
- if (!N.isPinned && k.isPinned) return 1;
2033
- switch (F) {
2034
- case "oldest":
2035
- return new Date(N.createdAt).getTime() - new Date(k.createdAt).getTime();
2036
- case "most_replies":
2037
- return k.replyCount - N.replyCount;
2038
- case "most_liked":
2039
- return k.likeCount - N.likeCount;
2040
- case "newest":
2041
- default:
2042
- return new Date(k.createdAt).getTime() - new Date(N.createdAt).getTime();
2043
- }
2044
- }), [r, f, F]);
2045
- return /* @__PURE__ */ t("div", { className: U("flex flex-col gap-4", p), style: m, children: [
2046
- /* @__PURE__ */ t("div", { className: "flex items-center justify-between gap-4", children: [
2047
- a && /* @__PURE__ */ e("h2", { className: "text-xl font-bold text-foreground", children: a }),
2048
- !b && o && /* @__PURE__ */ t(
2049
- P,
2050
- {
2051
- size: "sm",
2052
- onClick: () => y(!x),
2053
- children: [
2054
- /* @__PURE__ */ e(st, { className: "size-4 mr-1.5" }),
2055
- "New Topic"
2056
- ]
2057
- }
2058
- )
2059
- ] }),
2060
- /* @__PURE__ */ e(E, {}),
2061
- x && /* @__PURE__ */ e(B, { children: /* @__PURE__ */ t(Q, { className: "pt-4 space-y-3", children: [
2062
- /* @__PURE__ */ e(
2063
- oe,
2064
- {
2065
- placeholder: "Topic title",
2066
- value: v,
2067
- onChange: (u) => L(u.target.value)
2068
- }
2069
- ),
2070
- /* @__PURE__ */ e(
2071
- Z,
2072
- {
2073
- placeholder: "What would you like to discuss?",
2074
- value: w,
2075
- onChange: (u) => R(u),
2076
- variant: "minimal"
2077
- }
2078
- ),
2079
- /* @__PURE__ */ t("div", { className: "flex justify-end gap-2", children: [
2080
- /* @__PURE__ */ e(
2081
- P,
2082
- {
2083
- variant: "outline",
2084
- size: "sm",
2085
- onClick: () => {
2086
- y(!1), L(""), R("");
2087
- },
2088
- children: "Cancel"
2089
- }
2090
- ),
2091
- /* @__PURE__ */ e(
2092
- P,
2093
- {
2094
- size: "sm",
2095
- onClick: D,
2096
- disabled: !v.trim() || te(w),
2097
- children: "Post Topic"
2098
- }
2099
- )
2100
- ] })
2101
- ] }) }),
2102
- /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
2103
- /* @__PURE__ */ e("div", { className: "flex-1", children: /* @__PURE__ */ e(
2104
- St,
2105
- {
2106
- value: f,
2107
- onChange: T,
2108
- placeholder: "Search topics..."
2109
- }
2110
- ) }),
2111
- /* @__PURE__ */ t(P, { variant: "outline", size: "sm", onClick: z, children: [
2112
- /* @__PURE__ */ e(lt, { className: "size-3.5 mr-1.5" }),
2113
- $t[F]
2114
- ] })
2115
- ] }),
2116
- I.length === 0 ? /* @__PURE__ */ e(
2117
- zt,
2118
- {
2119
- icon: /* @__PURE__ */ e(fe, { className: "size-10 text-muted-foreground" }),
2120
- title: "No topics found",
2121
- description: f ? "Try a different search term." : "Be the first to start a discussion!"
2122
- }
2123
- ) : /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: I.map((u) => /* @__PURE__ */ e(
2124
- Ot,
2125
- {
2126
- topic: u,
2127
- onClick: () => i(u.uid)
2128
- },
2129
- u.uid
2130
- )) })
2131
- ] });
2132
- }
2133
- function Ot({
2134
- topic: a,
2135
- onClick: r
2136
- }) {
2137
- return /* @__PURE__ */ e(
2138
- "button",
2139
- {
2140
- type: "button",
2141
- className: "w-full text-left",
2142
- onClick: r,
2143
- children: /* @__PURE__ */ e(
2144
- B,
2145
- {
2146
- className: U(
2147
- "transition-colors hover:bg-muted/30",
2148
- a.isPinned && "border-l-2 border-l-warning"
2149
- ),
2150
- children: /* @__PURE__ */ e(Q, { className: "py-3 px-4", children: /* @__PURE__ */ t("div", { className: "flex items-start gap-3", children: [
2151
- /* @__PURE__ */ e(
2152
- Lt,
2153
- {
2154
- displayName: a.author.displayName,
2155
- avatarUrl: a.author.avatarUrl,
2156
- size: "small"
2157
- }
2158
- ),
2159
- /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
2160
- /* @__PURE__ */ t("div", { className: "flex items-center gap-2 mb-0.5", children: [
2161
- /* @__PURE__ */ e("span", { className: "font-medium text-foreground text-sm truncate", children: a.title }),
2162
- a.isPinned && /* @__PURE__ */ e(it, { className: "size-3 text-warning shrink-0" }),
2163
- a.isAnswered && /* @__PURE__ */ t(G, { variant: "success", className: "text-xs shrink-0", children: [
2164
- /* @__PURE__ */ e(pe, { className: "size-3 mr-0.5" }),
2165
- "Answered"
2166
- ] })
2167
- ] }),
2168
- a.preview && /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground line-clamp-1", children: a.preview }),
2169
- /* @__PURE__ */ t("div", { className: "flex items-center gap-3 mt-1.5 text-xs text-muted-foreground", children: [
2170
- /* @__PURE__ */ e("span", { children: a.author.displayName }),
2171
- /* @__PURE__ */ e("span", { children: At(a.createdAt) }),
2172
- /* @__PURE__ */ t(G, { variant: "muted", className: "gap-0.5 text-xs px-1.5 py-0", children: [
2173
- /* @__PURE__ */ e(fe, { className: "size-3" }),
2174
- a.replyCount
2175
- ] }),
2176
- /* @__PURE__ */ t(G, { variant: "muted", className: "gap-0.5 text-xs px-1.5 py-0", children: [
2177
- /* @__PURE__ */ e(Le, { className: "size-3" }),
2178
- a.likeCount
2179
- ] })
2180
- ] })
2181
- ] })
2182
- ] }) })
2183
- }
2184
- )
2185
- }
2186
- );
2187
- }
2188
- export {
2189
- qt as A,
2190
- ca as C,
2191
- sa as D,
2192
- aa as E,
2193
- Jt as F,
2194
- ia as G,
2195
- Xt as L,
2196
- ta as P,
2197
- Kt as Q,
2198
- ma as R,
2199
- na as S,
2200
- la as a,
2201
- ea as b,
2202
- ua as c,
2203
- ra as d,
2204
- da as e,
2205
- oa as f,
2206
- _e as g
2207
- };