@hydralms/components 0.1.3 → 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 (344) hide show
  1. package/dist/StudentProfile-BVfZMbnV.cjs +1 -0
  2. package/dist/StudentProfile-DeMxdrL3.js +3275 -0
  3. package/dist/assessment-toolbar/assessment-toolbar.d.ts +1 -1
  4. package/dist/assessment-toolbar/index.d.ts +5 -1
  5. package/dist/assessment-toolbar/question-header-bar.d.ts +2 -0
  6. package/dist/assessment-toolbar/question-materials-drawer.d.ts +2 -0
  7. package/dist/assessment-toolbar/question-navigator.d.ts +1 -1
  8. package/dist/assessment-toolbar/timer-display.d.ts +1 -1
  9. package/dist/assessment-toolbar/types.d.ts +52 -4
  10. package/dist/assessment-toolbar/use-countdown.d.ts +43 -0
  11. package/dist/common/index.d.ts +3 -1
  12. package/dist/common/pagination.d.ts +26 -0
  13. package/dist/common/stepper.d.ts +6 -0
  14. package/dist/common/types.d.ts +38 -0
  15. package/dist/components.css +1 -1
  16. package/dist/content/attachment-list.d.ts +6 -0
  17. package/dist/content/audio-player.d.ts +22 -0
  18. package/dist/content/code-block.d.ts +30 -0
  19. package/dist/content/content-block.d.ts +1 -1
  20. package/dist/content/embed-block.d.ts +28 -0
  21. package/dist/content/index.d.ts +8 -1
  22. package/dist/content/types.d.ts +63 -0
  23. package/dist/curriculum/course-card.d.ts +51 -0
  24. package/dist/curriculum/curriculum-item.d.ts +1 -1
  25. package/dist/curriculum/index.d.ts +2 -0
  26. package/dist/curriculum/types.d.ts +2 -2
  27. package/dist/index.cjs +1 -1
  28. package/dist/index.d.ts +1 -0
  29. package/dist/index.js +597 -308
  30. package/dist/license/HydraContext.d.ts +16 -0
  31. package/dist/license/ProBadge.d.ts +6 -0
  32. package/dist/license/index.d.ts +7 -0
  33. package/dist/license/tiers.d.ts +3 -0
  34. package/dist/license/useHydraLicense.d.ts +6 -0
  35. package/dist/license/validate.d.ts +13 -0
  36. package/dist/license/withProGate.d.ts +6 -0
  37. package/dist/modules/AssignmentModule/AssignmentModule.d.ts +5 -0
  38. package/dist/modules/AssignmentModule/types.d.ts +69 -0
  39. package/dist/modules/CertificateModule/CertificateModule.d.ts +5 -0
  40. package/dist/modules/CertificateModule/types.d.ts +51 -0
  41. package/dist/modules/CourseCatalogModule/CourseCatalogModule.d.ts +5 -0
  42. package/dist/modules/CourseCatalogModule/types.d.ts +43 -0
  43. package/dist/modules/CoursePlayer/CoursePlayer.d.ts +4 -1
  44. package/dist/modules/DiscussionModule/DiscussionModule.d.ts +5 -0
  45. package/dist/modules/DiscussionModule/types.d.ts +47 -0
  46. package/dist/modules/ExamModule/ExamModule.d.ts +5 -0
  47. package/dist/modules/ExamModule/types.d.ts +55 -0
  48. package/dist/modules/FlashcardLab/FlashcardLab.d.ts +4 -1
  49. package/dist/modules/FlashcardLab/types.d.ts +2 -0
  50. package/dist/modules/GradeCenterModule/GradeCenterModule.d.ts +5 -0
  51. package/dist/modules/GradeCenterModule/types.d.ts +56 -0
  52. package/dist/modules/QuizModule/QuizModule.d.ts +4 -1
  53. package/dist/modules/QuizModule/types.d.ts +10 -14
  54. package/dist/modules/StudentDashboardModule/StudentDashboardModule.d.ts +5 -0
  55. package/dist/modules/StudentDashboardModule/types.d.ts +54 -0
  56. package/dist/modules/StudentProfileModule/StudentProfileModule.d.ts +5 -0
  57. package/dist/modules/StudentProfileModule/types.d.ts +43 -0
  58. package/dist/modules/SurveyModule/SurveyModule.d.ts +5 -0
  59. package/dist/modules/SurveyModule/types.d.ts +51 -0
  60. package/dist/modules/_shared/assessment-intro.d.ts +16 -0
  61. package/dist/modules/_shared/assessment-results.d.ts +23 -0
  62. package/dist/modules/_shared/types.d.ts +10 -0
  63. package/dist/modules/_shared/use-timer.d.ts +9 -0
  64. package/dist/modules/index.d.ts +18 -0
  65. package/dist/modules.cjs +1 -0
  66. package/dist/modules.js +1834 -0
  67. package/dist/progress/achievement-badge.d.ts +6 -0
  68. package/dist/progress/activity-timeline.d.ts +6 -0
  69. package/dist/progress/index.d.ts +4 -1
  70. package/dist/progress/stat-card.d.ts +1 -1
  71. package/dist/progress/streak-badge.d.ts +6 -0
  72. package/dist/progress/types.d.ts +99 -0
  73. package/dist/provider/HydraProvider.d.ts +5 -1
  74. package/dist/questions/choice.d.ts +1 -1
  75. package/dist/questions/confidence-indicator.d.ts +37 -0
  76. package/dist/questions/essay.d.ts +2 -2
  77. package/dist/questions/fill-in-the-blank.d.ts +1 -1
  78. package/dist/questions/hotspot.d.ts +21 -0
  79. package/dist/questions/index.d.ts +11 -1
  80. package/dist/questions/inline-choice.d.ts +21 -0
  81. package/dist/questions/matching.d.ts +22 -0
  82. package/dist/questions/multiple-choice.d.ts +1 -1
  83. package/dist/questions/numeric.d.ts +11 -0
  84. package/dist/questions/ordering.d.ts +12 -0
  85. package/dist/questions/question-renderer.d.ts +1 -1
  86. package/dist/questions/scenario.d.ts +23 -0
  87. package/dist/questions/scoring.d.ts +22 -0
  88. package/dist/questions/spreadsheet.d.ts +29 -0
  89. package/dist/questions/true-false.d.ts +1 -1
  90. package/dist/questions/types.d.ts +106 -1
  91. package/dist/questions/use-drag-reorder.d.ts +17 -0
  92. package/dist/sections/AnnouncementFeed/AnnouncementFeed.d.ts +1 -1
  93. package/dist/sections/AnnouncementFeed/types.d.ts +15 -1
  94. package/dist/sections/AssessmentReview/AssessmentReview.d.ts +1 -1
  95. package/dist/sections/AssessmentReview/types.d.ts +6 -0
  96. package/dist/sections/AssignmentSubmission/AssignmentSubmission.d.ts +1 -1
  97. package/dist/sections/AssignmentSubmission/types.d.ts +6 -0
  98. package/dist/sections/CertificateViewer/CertificateViewer.d.ts +1 -1
  99. package/dist/sections/CertificateViewer/certificate-variants.d.ts +42 -0
  100. package/dist/sections/CertificateViewer/types.d.ts +13 -5
  101. package/dist/sections/CourseCatalog/CourseCatalog.d.ts +2 -0
  102. package/dist/sections/CourseCatalog/types.d.ts +80 -0
  103. package/dist/sections/CourseOutline/CourseOutline.d.ts +1 -1
  104. package/dist/sections/CourseOutline/types.d.ts +6 -0
  105. package/dist/sections/DiscussionThread/DiscussionThread.d.ts +1 -1
  106. package/dist/sections/DiscussionThread/types.d.ts +6 -0
  107. package/dist/sections/EnrollmentWizard/EnrollmentWizard.d.ts +2 -0
  108. package/dist/sections/EnrollmentWizard/types.d.ts +66 -0
  109. package/dist/sections/ExamSession/ExamSession.d.ts +1 -1
  110. package/dist/sections/ExamSession/types.d.ts +12 -1
  111. package/dist/sections/FlashcardStudySession/FlashcardStudySession.d.ts +1 -1
  112. package/dist/sections/FlashcardStudySession/types.d.ts +6 -0
  113. package/dist/sections/ForumBoard/ForumBoard.d.ts +8 -0
  114. package/dist/sections/ForumBoard/types.d.ts +78 -0
  115. package/dist/sections/GradebookTable/GradebookTable.d.ts +1 -1
  116. package/dist/sections/GradebookTable/types.d.ts +14 -0
  117. package/dist/sections/LecturePlayer/LecturePlayer.d.ts +1 -1
  118. package/dist/sections/LecturePlayer/types.d.ts +8 -0
  119. package/dist/sections/LessonPage/LessonPage.d.ts +1 -1
  120. package/dist/sections/LessonPage/types.d.ts +6 -0
  121. package/dist/sections/PracticeQuiz/PracticeQuiz.d.ts +1 -1
  122. package/dist/sections/PracticeQuiz/types.d.ts +6 -0
  123. package/dist/sections/ProgressDashboard/ProgressDashboard.d.ts +1 -1
  124. package/dist/sections/ProgressDashboard/types.d.ts +6 -0
  125. package/dist/sections/QuizSession/QuizSession.d.ts +1 -1
  126. package/dist/sections/QuizSession/types.d.ts +12 -1
  127. package/dist/sections/RequirementsChecklist/RequirementsChecklist.d.ts +8 -0
  128. package/dist/sections/RequirementsChecklist/types.d.ts +43 -0
  129. package/dist/sections/ResourceLibrary/ResourceLibrary.d.ts +1 -1
  130. package/dist/sections/ResourceLibrary/types.d.ts +15 -1
  131. package/dist/sections/RubricView/RubricView.d.ts +9 -0
  132. package/dist/sections/RubricView/types.d.ts +56 -0
  133. package/dist/sections/ScrollableQuiz/ScrollableQuiz.d.ts +1 -1
  134. package/dist/sections/ScrollableQuiz/types.d.ts +6 -0
  135. package/dist/sections/StudentProfile/StudentProfile.d.ts +2 -0
  136. package/dist/sections/StudentProfile/types.d.ts +98 -0
  137. package/dist/sections/SurveyForm/SurveyForm.d.ts +1 -1
  138. package/dist/sections/SurveyForm/types.d.ts +6 -0
  139. package/dist/sections/_shared/merge-answers.d.ts +9 -0
  140. package/dist/sections/_shared/section-shell.d.ts +20 -0
  141. package/dist/sections/_shared/use-assessment-session.d.ts +30 -0
  142. package/dist/sections/index.d.ts +13 -1
  143. package/dist/sections.cjs +1 -1
  144. package/dist/sections.js +282 -1786
  145. package/dist/social/post-card.d.ts +1 -1
  146. package/dist/tabs-BsfVo2Bl.cjs +173 -0
  147. package/dist/tabs-BuY1iNJE.js +22305 -0
  148. package/dist/ui/alert.d.ts +1 -1
  149. package/dist/ui/badge.d.ts +1 -1
  150. package/dist/ui/button.d.ts +1 -1
  151. package/dist/ui/drawer.d.ts +84 -0
  152. package/dist/ui/index.d.ts +5 -0
  153. package/dist/ui/progress.d.ts +1 -1
  154. package/dist/ui/rich-text-editor.d.ts +32 -0
  155. package/dist/ui/rich-text-toolbar.d.ts +8 -0
  156. package/dist/ui/toast.d.ts +43 -0
  157. package/dist/utils/array-utils.d.ts +4 -0
  158. package/dist/utils/debounce.d.ts +5 -1
  159. package/dist/utils/flatten-leaves.d.ts +6 -0
  160. package/dist/utils/format-file-size.d.ts +1 -0
  161. package/dist/utils/format-timestamp.d.ts +1 -0
  162. package/dist/utils/is-empty-html.d.ts +5 -0
  163. package/dist/utils/pick-palette-color.d.ts +19 -0
  164. package/dist/utils/shuffle.d.ts +1 -0
  165. package/dist/utils/string-utils.d.ts +12 -0
  166. package/dist/video/types.d.ts +15 -0
  167. package/dist/video/video-bookmark.d.ts +1 -1
  168. package/dist/video/video-player.d.ts +1 -1
  169. package/dist/video/video-playlist-item.d.ts +1 -1
  170. package/dist/withProGate-BWqcKdPM.js +137 -0
  171. package/dist/withProGate-DX6XqKLp.cjs +1 -0
  172. package/package.json +40 -137
  173. package/src/assessment-toolbar/assessment-toolbar.tsx +54 -49
  174. package/src/assessment-toolbar/index.ts +6 -0
  175. package/src/assessment-toolbar/question-header-bar.tsx +61 -0
  176. package/src/assessment-toolbar/question-materials-drawer.tsx +55 -0
  177. package/src/assessment-toolbar/question-navigator.tsx +13 -36
  178. package/src/assessment-toolbar/timer-display.tsx +6 -5
  179. package/src/assessment-toolbar/types.ts +54 -4
  180. package/src/assessment-toolbar/use-countdown.ts +153 -0
  181. package/src/common/empty-state.tsx +1 -0
  182. package/src/common/index.ts +5 -0
  183. package/src/common/pagination.tsx +135 -0
  184. package/src/common/search-input.tsx +8 -6
  185. package/src/common/stepper.tsx +100 -0
  186. package/src/common/types.ts +41 -0
  187. package/src/content/attachment-list.tsx +92 -0
  188. package/src/content/audio-player.tsx +196 -0
  189. package/src/content/code-block.tsx +113 -0
  190. package/src/content/content-block.tsx +68 -2
  191. package/src/content/embed-block.tsx +78 -0
  192. package/src/content/file-upload-zone.tsx +11 -6
  193. package/src/content/index.ts +9 -0
  194. package/src/content/types.ts +46 -0
  195. package/src/curriculum/course-card.tsx +199 -0
  196. package/src/curriculum/curriculum-item.tsx +9 -5
  197. package/src/curriculum/curriculum-tree.tsx +20 -13
  198. package/src/curriculum/index.ts +2 -0
  199. package/src/curriculum/types.ts +2 -2
  200. package/src/feedback/feedback-banner.tsx +12 -14
  201. package/src/flashcards/flashcard-deck.tsx +1 -9
  202. package/src/flashcards/flashcard.tsx +29 -9
  203. package/src/index.ts +3 -0
  204. package/src/license/HydraContext.tsx +62 -0
  205. package/src/license/ProBadge.tsx +43 -0
  206. package/src/license/index.ts +7 -0
  207. package/src/license/tiers.ts +24 -0
  208. package/src/license/useHydraLicense.ts +10 -0
  209. package/src/license/validate.ts +90 -0
  210. package/src/license/withProGate.tsx +21 -0
  211. package/src/modules/AssignmentModule/AssignmentModule.tsx +314 -0
  212. package/src/modules/AssignmentModule/types.ts +77 -0
  213. package/src/modules/CertificateModule/CertificateModule.tsx +173 -0
  214. package/src/modules/CertificateModule/types.ts +49 -0
  215. package/src/modules/CourseCatalogModule/CourseCatalogModule.tsx +126 -0
  216. package/src/modules/CourseCatalogModule/types.ts +47 -0
  217. package/src/modules/CoursePlayer/CoursePlayer.tsx +80 -69
  218. package/src/modules/DiscussionModule/DiscussionModule.tsx +145 -0
  219. package/src/modules/DiscussionModule/types.ts +54 -0
  220. package/src/modules/ExamModule/ExamModule.tsx +151 -0
  221. package/src/modules/ExamModule/types.ts +57 -0
  222. package/src/modules/FlashcardLab/FlashcardLab.tsx +39 -21
  223. package/src/modules/FlashcardLab/types.ts +2 -0
  224. package/src/modules/GradeCenterModule/GradeCenterModule.tsx +174 -0
  225. package/src/modules/GradeCenterModule/types.ts +65 -0
  226. package/src/modules/QuizModule/QuizModule.tsx +58 -178
  227. package/src/modules/QuizModule/types.ts +10 -15
  228. package/src/modules/StudentDashboardModule/StudentDashboardModule.tsx +117 -0
  229. package/src/modules/StudentDashboardModule/types.ts +56 -0
  230. package/src/modules/StudentProfileModule/StudentProfileModule.tsx +289 -0
  231. package/src/modules/StudentProfileModule/types.ts +45 -0
  232. package/src/modules/SurveyModule/SurveyModule.tsx +185 -0
  233. package/src/modules/SurveyModule/types.ts +53 -0
  234. package/src/modules/_shared/assessment-intro.tsx +75 -0
  235. package/src/modules/_shared/assessment-results.tsx +133 -0
  236. package/src/modules/_shared/types.ts +11 -0
  237. package/src/modules/_shared/use-timer.ts +49 -0
  238. package/src/modules/index.ts +33 -0
  239. package/src/progress/achievement-badge.tsx +52 -0
  240. package/src/progress/activity-timeline.tsx +84 -0
  241. package/src/progress/grade-indicator.tsx +9 -1
  242. package/src/progress/index.ts +7 -0
  243. package/src/progress/progress-ring.tsx +2 -1
  244. package/src/progress/stat-card.tsx +37 -18
  245. package/src/progress/streak-badge.tsx +35 -0
  246. package/src/progress/types.ts +103 -0
  247. package/src/provider/HydraProvider.tsx +15 -6
  248. package/src/questions/choice.tsx +19 -14
  249. package/src/questions/confidence-indicator.tsx +107 -0
  250. package/src/questions/essay.tsx +28 -28
  251. package/src/questions/fill-in-the-blank.tsx +20 -19
  252. package/src/questions/hotspot.tsx +154 -0
  253. package/src/questions/index.ts +18 -0
  254. package/src/questions/inline-choice.tsx +152 -0
  255. package/src/questions/matching.tsx +229 -0
  256. package/src/questions/multiple-choice.tsx +19 -14
  257. package/src/questions/numeric.tsx +106 -0
  258. package/src/questions/ordering.tsx +167 -0
  259. package/src/questions/question-renderer.tsx +24 -2
  260. package/src/questions/scenario.tsx +140 -0
  261. package/src/questions/scoring.ts +201 -0
  262. package/src/questions/spreadsheet.tsx +260 -0
  263. package/src/questions/true-false.tsx +19 -14
  264. package/src/questions/types.ts +123 -1
  265. package/src/questions/use-drag-reorder.ts +80 -0
  266. package/src/sections/AnnouncementFeed/AnnouncementFeed.tsx +66 -23
  267. package/src/sections/AnnouncementFeed/types.ts +15 -1
  268. package/src/sections/AssessmentReview/AssessmentReview.tsx +50 -2
  269. package/src/sections/AssessmentReview/types.ts +6 -0
  270. package/src/sections/AssignmentSubmission/AssignmentSubmission.tsx +44 -6
  271. package/src/sections/AssignmentSubmission/types.ts +6 -0
  272. package/src/sections/CertificateViewer/CertificateViewer.tsx +215 -60
  273. package/src/sections/CertificateViewer/certificate-variants.tsx +170 -0
  274. package/src/sections/CertificateViewer/types.ts +19 -5
  275. package/src/sections/CourseCatalog/CourseCatalog.tsx +220 -0
  276. package/src/sections/CourseCatalog/types.ts +76 -0
  277. package/src/sections/CourseOutline/CourseOutline.tsx +45 -14
  278. package/src/sections/CourseOutline/types.ts +6 -0
  279. package/src/sections/DiscussionThread/DiscussionThread.tsx +55 -11
  280. package/src/sections/DiscussionThread/types.ts +6 -0
  281. package/src/sections/EnrollmentWizard/EnrollmentWizard.tsx +343 -0
  282. package/src/sections/EnrollmentWizard/types.ts +65 -0
  283. package/src/sections/ExamSession/ExamSession.tsx +125 -82
  284. package/src/sections/ExamSession/types.ts +12 -1
  285. package/src/sections/FlashcardStudySession/FlashcardStudySession.tsx +53 -36
  286. package/src/sections/FlashcardStudySession/types.ts +6 -0
  287. package/src/sections/ForumBoard/ForumBoard.tsx +342 -0
  288. package/src/sections/ForumBoard/types.ts +81 -0
  289. package/src/sections/GradebookTable/GradebookTable.tsx +55 -2
  290. package/src/sections/GradebookTable/types.ts +14 -0
  291. package/src/sections/LecturePlayer/LecturePlayer.tsx +63 -37
  292. package/src/sections/LecturePlayer/types.ts +8 -0
  293. package/src/sections/LessonPage/LessonPage.tsx +40 -13
  294. package/src/sections/LessonPage/types.ts +6 -0
  295. package/src/sections/PracticeQuiz/PracticeQuiz.tsx +119 -98
  296. package/src/sections/PracticeQuiz/types.ts +6 -0
  297. package/src/sections/ProgressDashboard/ProgressDashboard.tsx +121 -67
  298. package/src/sections/ProgressDashboard/types.ts +6 -0
  299. package/src/sections/QuizSession/QuizSession.tsx +115 -67
  300. package/src/sections/QuizSession/types.ts +12 -1
  301. package/src/sections/RequirementsChecklist/RequirementsChecklist.tsx +147 -0
  302. package/src/sections/RequirementsChecklist/types.ts +44 -0
  303. package/src/sections/ResourceLibrary/ResourceLibrary.tsx +68 -17
  304. package/src/sections/ResourceLibrary/types.ts +15 -1
  305. package/src/sections/RubricView/RubricView.tsx +174 -0
  306. package/src/sections/RubricView/types.ts +58 -0
  307. package/src/sections/ScrollableQuiz/ScrollableQuiz.tsx +58 -23
  308. package/src/sections/ScrollableQuiz/types.ts +6 -0
  309. package/src/sections/StudentProfile/StudentProfile.tsx +279 -0
  310. package/src/sections/StudentProfile/types.ts +99 -0
  311. package/src/sections/SurveyForm/SurveyForm.tsx +40 -10
  312. package/src/sections/SurveyForm/types.ts +6 -0
  313. package/src/sections/_shared/merge-answers.ts +22 -0
  314. package/src/sections/_shared/section-shell.tsx +64 -0
  315. package/src/sections/_shared/use-assessment-session.ts +125 -0
  316. package/src/sections/index.ts +42 -1
  317. package/src/social/post-card.tsx +8 -19
  318. package/src/social/user-avatar.tsx +10 -5
  319. package/src/styles/globals.css +52 -41
  320. package/src/ui/badge.tsx +8 -0
  321. package/src/ui/drawer.tsx +600 -0
  322. package/src/ui/index.ts +21 -0
  323. package/src/ui/progress.tsx +4 -0
  324. package/src/ui/rich-text-editor.tsx +119 -0
  325. package/src/ui/rich-text-toolbar.tsx +157 -0
  326. package/src/ui/toast.tsx +170 -0
  327. package/src/utils/array-utils.ts +17 -0
  328. package/src/utils/debounce.ts +8 -2
  329. package/src/utils/flatten-leaves.ts +17 -0
  330. package/src/utils/format-file-size.ts +5 -0
  331. package/src/utils/format-timestamp.ts +13 -0
  332. package/src/utils/is-empty-html.ts +7 -0
  333. package/src/utils/pick-palette-color.ts +33 -0
  334. package/src/utils/shuffle.ts +8 -0
  335. package/src/utils/string-utils.ts +30 -0
  336. package/src/video/types.ts +16 -0
  337. package/src/video/video-bookmark.tsx +4 -3
  338. package/src/video/video-chapter-list.tsx +9 -4
  339. package/src/video/video-player.tsx +24 -5
  340. package/src/video/video-playlist-item.tsx +8 -3
  341. package/src/video/video-thumbnail-card.tsx +4 -0
  342. package/src/video/video-transcript.tsx +8 -5
  343. package/dist/table-BrS5cDQu.js +0 -2510
  344. package/dist/table-D6AkBBEo.cjs +0 -1
@@ -0,0 +1,3275 @@
1
+ import { jsx as e, Fragment as O, jsxs as t } from "react/jsx-runtime";
2
+ import { useState as F, useRef as J, useEffect as oe, useMemo as B, useCallback as Z, Fragment as At } from "react";
3
+ import { AlertCircle as q, ChevronLeft as Lt, ChevronRight as Re, Send as Ye, CheckCircle as De, Clock as xe, Check as Qe, Pin as Ze, MessageSquare as Te, Heart as Je, Reply as Ut, Save as Rt, ArrowUp as Dt, ArrowDown as Tt, BookOpen as me, Award as Se, Printer as It, Download as Mt, CheckCircle2 as ue, Circle as Ft, Plus as Pt, ArrowUpDown as _t, XCircle as $e, Loader2 as Et, Grid as jt, List as Bt, GraduationCap as ze, Calendar as Qt } from "lucide-react";
4
+ import { c as k, a1 as $, v as D, s as Ke, C as _, D as Ie, al as Xe, x as E, ao as be, am as qe, at as f, aS as Ve, E as $t, a7 as Vt, B as X, as as H, P as pe, L as Ht, b1 as Gt, aY as He, a3 as Wt, d as et, e as tt, H as Ot, ad as Yt, av as Zt, ap as he, a as lt, I as Jt, aR as fe, b0 as Me, ai as we, aN as se, aP as ie, aO as re, aj as Kt, ax as at, $ as nt, aI as st, aK as it, aL as ce, aJ as ke, a4 as Ge, ab as Ae, a8 as Xt, aA as rt, aG as ct, aH as de, aF as Ne, aB as dt, aD as le, ak as ot, aw as Le, az as qt, b as el, A as mt, ar as ut, ay as tl, J as We } from "./tabs-BuY1iNJE.js";
5
+ import { cva as ht } from "class-variance-authority";
6
+ function ll(l, a, i, o) {
7
+ const p = i.map((s) => ({
8
+ uid: a,
9
+ answerUid: s.uid,
10
+ content: s.content
11
+ })), m = [...l.filter((s) => s.uid !== a), ...p];
12
+ return o == null || o(m), m;
13
+ }
14
+ function ft({
15
+ questions: l,
16
+ initialAnswers: a = [],
17
+ onAnswerChange: i,
18
+ questionMaterials: o
19
+ }) {
20
+ const [p, r] = F(0), [m, s] = F(a), [v, b] = F(/* @__PURE__ */ new Set()), [h, w] = F(!1), N = J(null), C = J(!0), S = J(l);
21
+ S.current = l;
22
+ const c = J(p);
23
+ c.current = p;
24
+ const z = J(i);
25
+ z.current = i;
26
+ const U = l[p];
27
+ oe(() => {
28
+ var n;
29
+ if (C.current) {
30
+ C.current = !1;
31
+ return;
32
+ }
33
+ (n = N.current) == null || n.focus();
34
+ }, [p]);
35
+ const u = B(
36
+ () => U ? m.filter((n) => n.uid === U.uid) : [],
37
+ [m, U]
38
+ ), M = B(
39
+ () => (o == null ? void 0 : o.filter((n) => n.questionUid === (U == null ? void 0 : U.uid))) ?? [],
40
+ [o, U]
41
+ ), x = B(
42
+ () => l.map((n, g) => ({
43
+ uid: n.uid,
44
+ sequence: g,
45
+ isFlagged: v.has(n.uid),
46
+ isAnswered: m.some((R) => R.uid === n.uid),
47
+ isSkipped: !1
48
+ })),
49
+ [l, m, v]
50
+ ), A = Z(
51
+ (n) => {
52
+ const g = S.current[c.current];
53
+ g && s(
54
+ (R) => ll(R, g.uid, n, z.current)
55
+ );
56
+ },
57
+ []
58
+ ), d = Z(
59
+ (n) => {
60
+ const g = l.findIndex((R) => R.uid === n);
61
+ g !== -1 && r(g);
62
+ },
63
+ [l]
64
+ ), y = Z((n) => {
65
+ b((g) => {
66
+ const R = new Set(g);
67
+ return R.has(n) ? R.delete(n) : R.add(n), R;
68
+ });
69
+ }, []), L = Z(() => {
70
+ r((n) => Math.min(n + 1, S.current.length - 1));
71
+ }, []), T = Z(() => {
72
+ r((n) => Math.max(n - 1, 0));
73
+ }, []);
74
+ return {
75
+ currentIndex: p,
76
+ currentQuestion: U,
77
+ sessionAnswers: m,
78
+ flaggedUids: v,
79
+ materialsOpen: h,
80
+ setMaterialsOpen: w,
81
+ questionAreaRef: N,
82
+ currentQuestionAnswers: u,
83
+ currentMaterials: M,
84
+ navigatorItems: x,
85
+ handleAnswer: A,
86
+ handleNavigate: d,
87
+ handleToggleFlag: y,
88
+ goNext: L,
89
+ goPrevious: T,
90
+ hasNext: p < l.length - 1,
91
+ hasPrevious: p > 0
92
+ };
93
+ }
94
+ function te({
95
+ isLoading: l,
96
+ error: a,
97
+ onRetry: i,
98
+ skeleton: o,
99
+ loadingClassName: p = "space-y-4",
100
+ className: r,
101
+ style: m,
102
+ children: s
103
+ }) {
104
+ return l ? /* @__PURE__ */ e("div", { className: k(p, r), style: m, children: o }) : a ? /* @__PURE__ */ e("div", { className: k("py-12", r), style: m, children: /* @__PURE__ */ e(
105
+ $,
106
+ {
107
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
108
+ title: "Something went wrong",
109
+ description: a,
110
+ action: i ? /* @__PURE__ */ e(D, { variant: "outline", onClick: i, children: "Retry" }) : void 0
111
+ }
112
+ ) }) : /* @__PURE__ */ e(O, { children: s });
113
+ }
114
+ function Sl({
115
+ questions: l,
116
+ initialAnswers: a = [],
117
+ onSubmit: i,
118
+ onAnswerChange: o,
119
+ timeElapsedSeconds: p,
120
+ timeLimitSeconds: r,
121
+ questionMaterials: m,
122
+ isSubmitting: s = !1,
123
+ readOnly: v = !1,
124
+ isLoading: b,
125
+ error: h,
126
+ onRetry: w,
127
+ className: N,
128
+ style: C
129
+ }) {
130
+ const {
131
+ currentIndex: S,
132
+ currentQuestion: c,
133
+ sessionAnswers: z,
134
+ flaggedUids: U,
135
+ materialsOpen: u,
136
+ setMaterialsOpen: M,
137
+ questionAreaRef: x,
138
+ currentQuestionAnswers: A,
139
+ currentMaterials: d,
140
+ navigatorItems: y,
141
+ handleAnswer: L,
142
+ handleNavigate: T,
143
+ handleToggleFlag: n,
144
+ goNext: g,
145
+ goPrevious: R,
146
+ hasNext: P,
147
+ hasPrevious: Y
148
+ } = ft({ questions: l, initialAnswers: a, onAnswerChange: o, questionMaterials: m }), V = J(z);
149
+ V.current = z;
150
+ const G = J(i);
151
+ G.current = i;
152
+ const K = Z(() => {
153
+ G.current(V.current);
154
+ }, []), I = J(c == null ? void 0 : c.uid);
155
+ I.current = c == null ? void 0 : c.uid;
156
+ const j = Z(() => {
157
+ const W = I.current;
158
+ W && n(W);
159
+ }, [n]), Q = Z(() => M(!0), [M]);
160
+ return /* @__PURE__ */ e(
161
+ te,
162
+ {
163
+ isLoading: b,
164
+ error: h,
165
+ onRetry: w,
166
+ className: N,
167
+ style: C,
168
+ skeleton: /* @__PURE__ */ t(O, { children: [
169
+ /* @__PURE__ */ e(f, { className: "h-10 w-full" }),
170
+ /* @__PURE__ */ e(f, { className: "h-48 w-full" }),
171
+ /* @__PURE__ */ e(f, { className: "h-12 w-full" })
172
+ ] }),
173
+ children: /* @__PURE__ */ t("div", { children: [
174
+ /* @__PURE__ */ e(
175
+ Ke,
176
+ {
177
+ currentQuestionIndex: S,
178
+ totalQuestions: l.length,
179
+ hasNext: P,
180
+ hasPrevious: Y,
181
+ onNext: g,
182
+ onPrevious: R,
183
+ onSubmit: K,
184
+ timeElapsedSeconds: p,
185
+ timeLimitSeconds: r,
186
+ questions: y,
187
+ onNavigateToQuestion: T,
188
+ currentQuestionUid: c == null ? void 0 : c.uid,
189
+ isSubmitting: s,
190
+ readOnly: v
191
+ }
192
+ ),
193
+ /* @__PURE__ */ t("span", { className: "sr-only", "aria-live": "polite", children: [
194
+ "Question ",
195
+ S + 1,
196
+ " of ",
197
+ l.length
198
+ ] }),
199
+ c && /* @__PURE__ */ t(_, { className: "mt-3", ref: x, tabIndex: -1, children: [
200
+ /* @__PURE__ */ e(Ie, { className: "pb-0", children: /* @__PURE__ */ e(
201
+ Xe,
202
+ {
203
+ questionNumber: S + 1,
204
+ totalQuestions: l.length,
205
+ isFlagged: U.has(c.uid),
206
+ onToggleFlag: j,
207
+ hasMaterials: d.length > 0,
208
+ onOpenMaterials: Q,
209
+ readOnly: v
210
+ }
211
+ ) }),
212
+ /* @__PURE__ */ e(E, { children: /* @__PURE__ */ e(
213
+ be,
214
+ {
215
+ question: c,
216
+ sessionAnswers: A,
217
+ onAnswer: L,
218
+ readOnly: v
219
+ }
220
+ ) })
221
+ ] }),
222
+ !v && /* @__PURE__ */ t("div", { className: "flex items-center justify-between gap-3 mt-3", children: [
223
+ /* @__PURE__ */ t(
224
+ D,
225
+ {
226
+ variant: "outline",
227
+ disabled: !Y,
228
+ onClick: R,
229
+ children: [
230
+ /* @__PURE__ */ e(Lt, { className: "size-4 mr-1" }),
231
+ "Previous"
232
+ ]
233
+ }
234
+ ),
235
+ P ? /* @__PURE__ */ t(D, { onClick: g, children: [
236
+ "Next",
237
+ /* @__PURE__ */ e(Re, { className: "size-4 ml-1" })
238
+ ] }) : /* @__PURE__ */ t(D, { onClick: K, disabled: s, children: [
239
+ s ? "Submitting..." : "Submit Quiz",
240
+ !s && /* @__PURE__ */ e(Ye, { className: "size-4 ml-1" })
241
+ ] })
242
+ ] }),
243
+ /* @__PURE__ */ e(
244
+ qe,
245
+ {
246
+ open: u,
247
+ onOpenChange: M,
248
+ materials: d,
249
+ questionNumber: S + 1
250
+ }
251
+ )
252
+ ] })
253
+ }
254
+ );
255
+ }
256
+ function zl({
257
+ video: l,
258
+ notes: a,
259
+ layout: i = "horizontal",
260
+ notesPanelWidth: o = "340px",
261
+ notesPanelHeight: p = "240px",
262
+ isLoading: r,
263
+ error: m,
264
+ onRetry: s,
265
+ onComplete: v,
266
+ className: b,
267
+ style: h
268
+ }) {
269
+ const w = i === "horizontal", N = Z(() => {
270
+ var C;
271
+ (C = l.onEnded) == null || C.call(l), v == null || v();
272
+ }, [l, v]);
273
+ return /* @__PURE__ */ e(
274
+ te,
275
+ {
276
+ isLoading: r,
277
+ error: m,
278
+ onRetry: s,
279
+ className: b,
280
+ style: h,
281
+ skeleton: /* @__PURE__ */ t(O, { children: [
282
+ /* @__PURE__ */ e(f, { className: "aspect-video w-full rounded-lg" }),
283
+ a !== void 0 && /* @__PURE__ */ e(f, { className: "h-32 w-full rounded-lg" })
284
+ ] }),
285
+ children: a ? /* @__PURE__ */ t(
286
+ "div",
287
+ {
288
+ className: k(
289
+ "flex overflow-hidden gap-4",
290
+ w ? "flex-row" : "flex-col",
291
+ b
292
+ ),
293
+ style: h,
294
+ children: [
295
+ /* @__PURE__ */ e("div", { className: "flex-1 min-w-0 min-h-0", children: /* @__PURE__ */ e(Ve, { ...l, onEnded: N }) }),
296
+ /* @__PURE__ */ t(
297
+ _,
298
+ {
299
+ className: k(
300
+ "overflow-auto shrink-0 rounded-none border-0",
301
+ w ? "border-l border-border" : "border-t border-border w-full"
302
+ ),
303
+ style: {
304
+ width: w ? o : void 0,
305
+ height: w ? void 0 : p
306
+ },
307
+ children: [
308
+ /* @__PURE__ */ e(Ie, { children: /* @__PURE__ */ e($t, { children: "Notes" }) }),
309
+ /* @__PURE__ */ e(E, { children: typeof a == "string" ? /* @__PURE__ */ e("span", { className: "text-sm text-foreground", children: a }) : a })
310
+ ]
311
+ }
312
+ )
313
+ ]
314
+ }
315
+ ) : /* @__PURE__ */ e("div", { className: b, style: h, children: /* @__PURE__ */ e(Ve, { ...l, onEnded: N }) })
316
+ }
317
+ );
318
+ }
319
+ function Al({
320
+ cards: l,
321
+ title: a,
322
+ description: i,
323
+ shuffled: o = !1,
324
+ onComplete: p,
325
+ readOnly: r = !1,
326
+ isLoading: m,
327
+ error: s,
328
+ onRetry: v,
329
+ className: b,
330
+ style: h
331
+ }) {
332
+ const [w, N] = F(!1), C = {
333
+ totalCards: l.length,
334
+ wasShuffled: o
335
+ };
336
+ function S() {
337
+ N(!0), p == null || p(C);
338
+ }
339
+ function c() {
340
+ N(!1);
341
+ }
342
+ return /* @__PURE__ */ e(
343
+ te,
344
+ {
345
+ isLoading: m,
346
+ error: s,
347
+ onRetry: v,
348
+ className: b,
349
+ style: h,
350
+ skeleton: /* @__PURE__ */ t(O, { children: [
351
+ /* @__PURE__ */ e(f, { className: "h-6 w-48" }),
352
+ /* @__PURE__ */ e(f, { className: "h-64 w-full rounded-lg" })
353
+ ] }),
354
+ children: w ? /* @__PURE__ */ e("div", { className: k("flex flex-col items-center", b), style: h, children: /* @__PURE__ */ e(_, { children: /* @__PURE__ */ t(E, { className: "pt-6 text-center flex flex-col items-center gap-2", children: [
355
+ /* @__PURE__ */ e(De, { size: 48, className: "text-success" }),
356
+ /* @__PURE__ */ e("span", { className: "text-xl font-bold text-foreground", children: "Deck complete!" }),
357
+ a && /* @__PURE__ */ t("span", { className: "text-muted-foreground", children: [
358
+ "You finished ",
359
+ /* @__PURE__ */ e("strong", { children: a })
360
+ ] }),
361
+ /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
362
+ C.totalCards,
363
+ " card",
364
+ C.totalCards !== 1 ? "s" : "",
365
+ " studied",
366
+ C.wasShuffled ? " (shuffled)" : ""
367
+ ] }),
368
+ /* @__PURE__ */ e(D, { className: "mt-2", onClick: c, children: "Study Again" })
369
+ ] }) }) }) : /* @__PURE__ */ e("div", { className: k("flex flex-col items-center", b), style: h, children: /* @__PURE__ */ e(
370
+ Vt,
371
+ {
372
+ cards: l,
373
+ deckName: a,
374
+ deckDescription: i,
375
+ shuffled: o,
376
+ showProgress: !0,
377
+ onComplete: S,
378
+ readOnly: r
379
+ }
380
+ ) })
381
+ }
382
+ );
383
+ }
384
+ function al({
385
+ score: l
386
+ }) {
387
+ const a = l.percentage !== void 0 ? l.percentage : l.total > 0 ? Math.round(l.correct / l.total * 100) : 0;
388
+ return /* @__PURE__ */ e(_, { className: "mb-3", children: /* @__PURE__ */ e(E, { className: "pt-6", children: /* @__PURE__ */ t("div", { className: "flex flex-wrap items-center gap-2", children: [
389
+ /* @__PURE__ */ t("div", { className: "flex items-baseline gap-2", children: [
390
+ /* @__PURE__ */ t("span", { className: "text-2xl font-bold leading-none text-foreground", children: [
391
+ a,
392
+ "%"
393
+ ] }),
394
+ /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
395
+ l.correct,
396
+ " of ",
397
+ l.total,
398
+ " correct"
399
+ ] })
400
+ ] }),
401
+ l.passed !== void 0 && /* @__PURE__ */ e(X, { variant: l.passed ? "success" : "destructive", children: l.passed ? "Passed" : "Failed" }),
402
+ l.passingScore !== void 0 && /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
403
+ "Passing score: ",
404
+ l.passingScore,
405
+ "%"
406
+ ] })
407
+ ] }) }) });
408
+ }
409
+ function Ue({
410
+ questions: l,
411
+ sessionAnswers: a,
412
+ showCorrectAnswers: i
413
+ }) {
414
+ const o = B(() => {
415
+ const p = /* @__PURE__ */ new Map();
416
+ for (const r of a) {
417
+ const m = p.get(r.uid);
418
+ m ? m.push(r) : p.set(r.uid, [r]);
419
+ }
420
+ return p;
421
+ }, [a]);
422
+ return /* @__PURE__ */ e("div", { className: "flex flex-col gap-3", children: l.map((p, r) => /* @__PURE__ */ t(_, { className: "overflow-hidden", children: [
423
+ /* @__PURE__ */ e("div", { className: "px-2 py-1 bg-muted", children: /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground font-semibold", children: [
424
+ "Question ",
425
+ r + 1
426
+ ] }) }),
427
+ /* @__PURE__ */ e(H, {}),
428
+ /* @__PURE__ */ e(E, { className: "pt-4 pb-4", children: /* @__PURE__ */ e(
429
+ be,
430
+ {
431
+ question: p,
432
+ sessionAnswers: o.get(p.uid) ?? [],
433
+ readOnly: !0,
434
+ showCorrectAnswers: i
435
+ }
436
+ ) })
437
+ ] }, p.uid)) });
438
+ }
439
+ function nl(l, a, i, o) {
440
+ const p = new Map(l.map((s) => [s.uid, s])), r = new Set(i.flatMap((s) => s.questionUids)), m = l.filter((s) => !r.has(s.uid));
441
+ return /* @__PURE__ */ t("div", { className: "flex flex-col gap-4", children: [
442
+ i.map((s) => {
443
+ const v = s.questionUids.map((b) => p.get(b)).filter(Boolean);
444
+ return /* @__PURE__ */ t("div", { children: [
445
+ /* @__PURE__ */ e("span", { className: "uppercase text-xs tracking-wide text-muted-foreground font-semibold", children: s.label }),
446
+ /* @__PURE__ */ e(H, { className: "mb-2" }),
447
+ /* @__PURE__ */ e(
448
+ Ue,
449
+ {
450
+ questions: v,
451
+ sessionAnswers: a,
452
+ showCorrectAnswers: o
453
+ }
454
+ )
455
+ ] }, s.label);
456
+ }),
457
+ m.length > 0 && /* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(
458
+ Ue,
459
+ {
460
+ questions: m,
461
+ sessionAnswers: a,
462
+ showCorrectAnswers: o
463
+ }
464
+ ) })
465
+ ] });
466
+ }
467
+ function Ll({
468
+ questions: l,
469
+ sessionAnswers: a,
470
+ score: i,
471
+ questionGroups: o,
472
+ showCorrectAnswers: p = !0,
473
+ isLoading: r,
474
+ error: m,
475
+ onRetry: s,
476
+ className: v,
477
+ style: b
478
+ }) {
479
+ return r ? /* @__PURE__ */ t("div", { className: k("space-y-4", v), style: b, children: [
480
+ /* @__PURE__ */ e(f, { className: "h-16 w-full" }),
481
+ /* @__PURE__ */ e(f, { className: "h-24 w-full" }),
482
+ /* @__PURE__ */ e(f, { className: "h-24 w-full" }),
483
+ /* @__PURE__ */ e(f, { className: "h-24 w-full" })
484
+ ] }) : m ? /* @__PURE__ */ e("div", { className: k("py-12", v), style: b, children: /* @__PURE__ */ e(
485
+ $,
486
+ {
487
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
488
+ title: "Something went wrong",
489
+ description: m,
490
+ action: s ? /* @__PURE__ */ e(D, { variant: "outline", onClick: s, children: "Retry" }) : void 0
491
+ }
492
+ ) }) : /* @__PURE__ */ t("div", { className: k(v), style: b, children: [
493
+ i && /* @__PURE__ */ e(al, { score: i }),
494
+ o && o.length > 0 ? nl(l, a, o, p) : /* @__PURE__ */ e(
495
+ Ue,
496
+ {
497
+ questions: l,
498
+ sessionAnswers: a,
499
+ showCorrectAnswers: p
500
+ }
501
+ )
502
+ ] });
503
+ }
504
+ function pt(l) {
505
+ const a = [];
506
+ for (const i of l)
507
+ !i.children || i.children.length === 0 ? a.push(i.uid) : a.push(...pt(i.children));
508
+ return a;
509
+ }
510
+ function Ul({
511
+ items: l,
512
+ progress: a,
513
+ courseTitle: i,
514
+ activeItemUid: o,
515
+ onItemClick: p,
516
+ showOverallProgress: r = !0,
517
+ showDuration: m = !0,
518
+ showIcons: s = !0,
519
+ readOnly: v = !1,
520
+ isLoading: b,
521
+ error: h,
522
+ onRetry: w,
523
+ className: N,
524
+ style: C
525
+ }) {
526
+ const { completedCount: S, totalCount: c, percentage: z } = B(() => {
527
+ const U = pt(l), u = U.length, M = a ? U.filter(
528
+ (x) => a.some((A) => A.resourceUid === x && A.isCompleted)
529
+ ).length : 0;
530
+ return {
531
+ completedCount: M,
532
+ totalCount: u,
533
+ percentage: u > 0 ? Math.round(M / u * 100) : 0
534
+ };
535
+ }, [l, a]);
536
+ return b ? /* @__PURE__ */ t("div", { className: k("space-y-4", N), style: C, children: [
537
+ /* @__PURE__ */ e(f, { className: "h-6 w-48" }),
538
+ /* @__PURE__ */ e(f, { className: "h-2 w-full" }),
539
+ /* @__PURE__ */ e(f, { className: "h-8 w-full" }),
540
+ /* @__PURE__ */ e(f, { className: "h-8 w-full ml-6" }),
541
+ /* @__PURE__ */ e(f, { className: "h-8 w-full ml-6" }),
542
+ /* @__PURE__ */ e(f, { className: "h-8 w-full" }),
543
+ /* @__PURE__ */ e(f, { className: "h-8 w-full ml-6" }),
544
+ /* @__PURE__ */ e(f, { className: "h-8 w-full" })
545
+ ] }) : h ? /* @__PURE__ */ e("div", { className: k("py-12", N), style: C, children: /* @__PURE__ */ e(
546
+ $,
547
+ {
548
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
549
+ title: "Something went wrong",
550
+ description: h,
551
+ action: w ? /* @__PURE__ */ e(D, { variant: "outline", onClick: w, children: "Retry" }) : void 0
552
+ }
553
+ ) }) : /* @__PURE__ */ t("div", { className: k(N), style: C, children: [
554
+ (i || r) && /* @__PURE__ */ t("div", { className: "px-2 pt-2 pb-2", children: [
555
+ i && /* @__PURE__ */ e("p", { className: k("font-semibold text-sm text-foreground", r && "mb-1"), children: i }),
556
+ r && /* @__PURE__ */ t("div", { children: [
557
+ /* @__PURE__ */ e(pe, { value: z, size: "sm" }),
558
+ /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground mt-0.5 block", children: [
559
+ S,
560
+ " of ",
561
+ c,
562
+ " completed"
563
+ ] })
564
+ ] })
565
+ ] }),
566
+ (i || r) && /* @__PURE__ */ e(H, {}),
567
+ /* @__PURE__ */ e(
568
+ Ht,
569
+ {
570
+ items: l,
571
+ progress: a,
572
+ activeItemUid: o,
573
+ onItemClick: p,
574
+ readOnly: v,
575
+ showDuration: m,
576
+ showIcons: s,
577
+ showProgress: !0
578
+ }
579
+ )
580
+ ] });
581
+ }
582
+ function Rl({
583
+ questions: l,
584
+ instantFeedback: a = !0,
585
+ allowRetry: i = !0,
586
+ onComplete: o,
587
+ shuffled: p = !1,
588
+ readOnly: r = !1,
589
+ isLoading: m,
590
+ error: s,
591
+ onRetry: v,
592
+ className: b,
593
+ style: h
594
+ }) {
595
+ const w = B(
596
+ () => {
597
+ const I = l ?? [];
598
+ return p ? Gt(I) : I;
599
+ },
600
+ // eslint-disable-next-line react-hooks/exhaustive-deps
601
+ [l, p]
602
+ ), [N, C] = F(0), [S, c] = F(/* @__PURE__ */ new Set()), [z, U] = F(/* @__PURE__ */ new Map()), [u, M] = F(/* @__PURE__ */ new Set()), [x, A] = F(null), [d, y] = F(!1), L = J(null), T = J(!0);
603
+ oe(() => {
604
+ var I;
605
+ if (T.current) {
606
+ T.current = !1;
607
+ return;
608
+ }
609
+ (I = L.current) == null || I.focus();
610
+ }, [N]);
611
+ const n = w[N], g = n ? S.has(n.uid) : !1;
612
+ function R() {
613
+ if (!n || !x) return;
614
+ const I = (z.get(n.uid) ?? 0) + 1;
615
+ U((W) => new Map(W).set(n.uid, I)), c((W) => new Set(W).add(n.uid));
616
+ const j = x.map((W) => ({
617
+ uid: n.uid,
618
+ answerUid: W.uid,
619
+ content: W.content
620
+ }));
621
+ He(n, j) === !0 && I === 1 && M((W) => new Set(W).add(n.uid));
622
+ }
623
+ function P() {
624
+ n && (c((I) => {
625
+ const j = new Set(I);
626
+ return j.delete(n.uid), j;
627
+ }), A(null));
628
+ }
629
+ function Y() {
630
+ if (N < w.length - 1)
631
+ C((I) => I + 1), A(null);
632
+ else {
633
+ const I = {
634
+ totalQuestions: w.length,
635
+ correctOnFirstAttempt: u.size,
636
+ totalAttempts: Array.from(z.values()).reduce((j, Q) => j + Q, 0)
637
+ };
638
+ y(!0), o == null || o(I);
639
+ }
640
+ }
641
+ const V = B(() => !n || !x ? [] : x.map((I) => ({
642
+ uid: n.uid,
643
+ answerUid: I.uid,
644
+ content: I.content
645
+ })), [n, x]), G = B(
646
+ () => n ? He(n, V) === !0 : !1,
647
+ [n, V]
648
+ ), K = w.length > 0 ? Math.round(u.size / w.length * 100) : 0;
649
+ return /* @__PURE__ */ e(
650
+ te,
651
+ {
652
+ isLoading: m,
653
+ error: s,
654
+ onRetry: v,
655
+ className: b,
656
+ style: h,
657
+ skeleton: /* @__PURE__ */ t(O, { children: [
658
+ /* @__PURE__ */ e(f, { className: "h-2 w-full" }),
659
+ /* @__PURE__ */ e(f, { className: "h-48 w-full" })
660
+ ] }),
661
+ children: d ? /* @__PURE__ */ e(_, { className: b, style: h, children: /* @__PURE__ */ t(E, { className: "pt-6 text-center", children: [
662
+ /* @__PURE__ */ e(De, { size: 48, className: "text-success mx-auto mb-4" }),
663
+ /* @__PURE__ */ e("p", { className: "text-xl font-bold mb-1 text-foreground", children: "Practice Complete!" }),
664
+ /* @__PURE__ */ t("p", { className: "text-muted-foreground mb-2", children: [
665
+ u.size,
666
+ " of ",
667
+ w.length,
668
+ " correct on first attempt (",
669
+ K,
670
+ "%)"
671
+ ] }),
672
+ /* @__PURE__ */ e("div", { className: "flex justify-center", children: /* @__PURE__ */ e(
673
+ D,
674
+ {
675
+ variant: "outline",
676
+ onClick: () => {
677
+ C(0), c(/* @__PURE__ */ new Set()), U(/* @__PURE__ */ new Map()), M(/* @__PURE__ */ new Set()), A(null), y(!1);
678
+ },
679
+ children: "Practice Again"
680
+ }
681
+ ) })
682
+ ] }) }) : /* @__PURE__ */ t("div", { className: b, style: h, children: [
683
+ /* @__PURE__ */ t("div", { className: "flex justify-between items-center mb-2", children: [
684
+ /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-foreground", children: [
685
+ "Question ",
686
+ N + 1,
687
+ " of ",
688
+ w.length
689
+ ] }),
690
+ /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: [
691
+ u.size,
692
+ " correct on first try"
693
+ ] })
694
+ ] }),
695
+ /* @__PURE__ */ e(
696
+ pe,
697
+ {
698
+ value: N + (g ? 1 : 0),
699
+ max: w.length,
700
+ size: "sm",
701
+ className: "mb-3"
702
+ }
703
+ ),
704
+ /* @__PURE__ */ t("span", { className: "sr-only", "aria-live": "polite", children: [
705
+ "Question ",
706
+ N + 1,
707
+ " of ",
708
+ w.length
709
+ ] }),
710
+ n && /* @__PURE__ */ e(_, { ref: L, tabIndex: -1, children: /* @__PURE__ */ t(E, { className: "pt-6", children: [
711
+ /* @__PURE__ */ e(
712
+ be,
713
+ {
714
+ question: n,
715
+ sessionAnswers: V,
716
+ onAnswer: A,
717
+ readOnly: r || g,
718
+ showCorrectAnswers: g
719
+ }
720
+ ),
721
+ a && g && /* @__PURE__ */ e(
722
+ Wt,
723
+ {
724
+ isCorrect: G,
725
+ explanation: n.explanation,
726
+ onRetry: i && !G ? P : void 0
727
+ }
728
+ ),
729
+ /* @__PURE__ */ t("div", { className: "flex justify-end gap-2 mt-2", children: [
730
+ !g && a && /* @__PURE__ */ e(
731
+ D,
732
+ {
733
+ onClick: R,
734
+ disabled: !x || x.length === 0 || r,
735
+ children: "Check Answer"
736
+ }
737
+ ),
738
+ (!a || g) && /* @__PURE__ */ e(
739
+ D,
740
+ {
741
+ onClick: Y,
742
+ disabled: r,
743
+ children: N < w.length - 1 ? "Next Question" : "Finish"
744
+ }
745
+ )
746
+ ] })
747
+ ] }) })
748
+ ] })
749
+ }
750
+ );
751
+ }
752
+ function Dl({
753
+ questions: l = [],
754
+ initialAnswers: a = [],
755
+ onSubmit: i,
756
+ onAnswerChange: o,
757
+ timeLimitSeconds: p,
758
+ timeElapsedSeconds: r,
759
+ autoSubmitOnTimeout: m = !0,
760
+ timeWarningThreshold: s = 300,
761
+ allowBackNavigation: v = !0,
762
+ confirmBeforeSubmit: b = !0,
763
+ examTitle: h,
764
+ instructions: w,
765
+ questionMaterials: N,
766
+ isSubmitting: C = !1,
767
+ readOnly: S = !1,
768
+ isLoading: c,
769
+ error: z,
770
+ onRetry: U,
771
+ className: u,
772
+ style: M
773
+ }) {
774
+ const {
775
+ currentIndex: x,
776
+ currentQuestion: A,
777
+ sessionAnswers: d,
778
+ flaggedUids: y,
779
+ materialsOpen: L,
780
+ setMaterialsOpen: T,
781
+ questionAreaRef: n,
782
+ currentQuestionAnswers: g,
783
+ currentMaterials: R,
784
+ navigatorItems: P,
785
+ handleAnswer: Y,
786
+ handleNavigate: V,
787
+ handleToggleFlag: G,
788
+ goNext: K,
789
+ goPrevious: I,
790
+ hasNext: j
791
+ } = ft({ questions: l, initialAnswers: a, onAnswerChange: o, questionMaterials: N }), [Q, W] = F(!1), [gt, xt] = F(!1), Fe = J(!1), Pe = J(d);
792
+ Pe.current = d;
793
+ const _e = J(i);
794
+ _e.current = i;
795
+ const Ee = J(r);
796
+ Ee.current = r;
797
+ const je = J(A == null ? void 0 : A.uid);
798
+ je.current = A == null ? void 0 : A.uid;
799
+ const ee = p - r, Nt = B(
800
+ () => P.filter((ne) => ne.isAnswered).length,
801
+ [P]
802
+ ), ae = Z((ne) => {
803
+ const Be = Pe.current, St = new Set(Be.map((ye) => ye.uid)), zt = {
804
+ timeElapsedSeconds: Ee.current,
805
+ wasAutoSubmitted: ne,
806
+ answeredCount: l.filter((ye) => St.has(ye.uid)).length,
807
+ totalQuestions: l.length
808
+ };
809
+ _e.current(Be, zt);
810
+ }, [l]);
811
+ oe(() => {
812
+ ee <= s && ee > 0 && xt(!0);
813
+ }, [ee, s]), oe(() => {
814
+ m && ee <= 0 && !Fe.current && (Fe.current = !0, ae(!0));
815
+ }, [ee, m, ae]);
816
+ const vt = Z(() => {
817
+ b ? W(!0) : ae(!1);
818
+ }, [b, ae]), bt = Z(() => {
819
+ v && I();
820
+ }, [v, I]), wt = Z(() => {
821
+ const ne = je.current;
822
+ ne && G(ne);
823
+ }, [G]), yt = Z(() => T(!0), [T]), kt = Z(() => {
824
+ W(!1), ae(!1);
825
+ }, [ae]), Ct = Z(() => W(!1), []);
826
+ return /* @__PURE__ */ e(
827
+ te,
828
+ {
829
+ isLoading: c,
830
+ error: z,
831
+ onRetry: U,
832
+ className: u,
833
+ style: M,
834
+ skeleton: /* @__PURE__ */ t(O, { children: [
835
+ /* @__PURE__ */ e(f, { className: "h-10 w-full" }),
836
+ /* @__PURE__ */ e(f, { className: "h-48 w-full" }),
837
+ /* @__PURE__ */ e(f, { className: "h-12 w-full" })
838
+ ] }),
839
+ children: /* @__PURE__ */ t("div", { children: [
840
+ h && /* @__PURE__ */ e("p", { className: "text-xl font-bold mb-2 text-foreground", children: h }),
841
+ gt && ee > 0 && ee <= s && /* @__PURE__ */ e(et, { variant: "warning", className: "mb-2", children: /* @__PURE__ */ t(tt, { children: [
842
+ Math.ceil(ee / 60),
843
+ " minute",
844
+ Math.ceil(ee / 60) !== 1 ? "s" : "",
845
+ " remaining"
846
+ ] }) }),
847
+ /* @__PURE__ */ e(
848
+ Ke,
849
+ {
850
+ currentQuestionIndex: x,
851
+ totalQuestions: l.length,
852
+ hasNext: j,
853
+ hasPrevious: v && x > 0,
854
+ onNext: K,
855
+ onPrevious: bt,
856
+ onSubmit: vt,
857
+ timeElapsedSeconds: r,
858
+ timeLimitSeconds: p,
859
+ questions: P,
860
+ onNavigateToQuestion: V,
861
+ currentQuestionUid: A == null ? void 0 : A.uid,
862
+ isSubmitting: C,
863
+ readOnly: S
864
+ }
865
+ ),
866
+ w && x === 0 && /* @__PURE__ */ e(_, { className: "mt-3", children: /* @__PURE__ */ e(E, { className: "pt-6", children: w }) }),
867
+ /* @__PURE__ */ t("span", { className: "sr-only", "aria-live": "polite", children: [
868
+ "Question ",
869
+ x + 1,
870
+ " of ",
871
+ l.length
872
+ ] }),
873
+ A && /* @__PURE__ */ t(_, { className: "mt-3", ref: n, tabIndex: -1, children: [
874
+ /* @__PURE__ */ e(Ie, { className: "pb-0", children: /* @__PURE__ */ e(
875
+ Xe,
876
+ {
877
+ questionNumber: x + 1,
878
+ totalQuestions: l.length,
879
+ isFlagged: y.has(A.uid),
880
+ onToggleFlag: wt,
881
+ hasMaterials: R.length > 0,
882
+ onOpenMaterials: yt,
883
+ readOnly: S
884
+ }
885
+ ) }),
886
+ /* @__PURE__ */ e(E, { children: /* @__PURE__ */ e(
887
+ be,
888
+ {
889
+ question: A,
890
+ sessionAnswers: g,
891
+ onAnswer: Y,
892
+ readOnly: S
893
+ }
894
+ ) })
895
+ ] }),
896
+ /* @__PURE__ */ e(
897
+ qe,
898
+ {
899
+ open: L,
900
+ onOpenChange: T,
901
+ materials: R,
902
+ questionNumber: x + 1
903
+ }
904
+ ),
905
+ /* @__PURE__ */ e(
906
+ Ot,
907
+ {
908
+ open: Q,
909
+ title: "Submit Exam?",
910
+ message: `You have answered ${Nt} of ${l.length} questions. Once submitted, you cannot change your answers.`,
911
+ confirmLabel: "Submit Exam",
912
+ cancelLabel: "Continue Exam",
913
+ confirmColor: "primary",
914
+ onConfirm: kt,
915
+ onCancel: Ct,
916
+ isLoading: C
917
+ }
918
+ )
919
+ ] })
920
+ }
921
+ );
922
+ }
923
+ function Tl({
924
+ title: l,
925
+ description: a,
926
+ questions: i = [],
927
+ initialAnswers: o = [],
928
+ onSubmit: p,
929
+ onAnswerChange: r,
930
+ showProgress: m = !0,
931
+ requireAll: s = !1,
932
+ submitLabel: v = "Submit Survey",
933
+ isSubmitting: b = !1,
934
+ readOnly: h = !1,
935
+ isLoading: w,
936
+ error: N,
937
+ onRetry: C,
938
+ className: S,
939
+ style: c
940
+ }) {
941
+ const [z, U] = F(o), u = B(() => {
942
+ const d = new Set(z.map((y) => y.questionUid));
943
+ return i.filter((y) => d.has(y.uid)).length;
944
+ }, [i, z]), M = !s || u === i.length;
945
+ function x(d, y) {
946
+ U((L) => {
947
+ const n = [...L.filter((g) => g.questionUid !== d), { questionUid: d, value: y }];
948
+ return r == null || r(n), n;
949
+ });
950
+ }
951
+ const A = B(() => {
952
+ const d = /* @__PURE__ */ new Map();
953
+ for (const y of z)
954
+ d.set(y.questionUid, y);
955
+ return d;
956
+ }, [z]);
957
+ return /* @__PURE__ */ e(
958
+ te,
959
+ {
960
+ isLoading: w,
961
+ error: N,
962
+ onRetry: C,
963
+ className: S,
964
+ style: c,
965
+ skeleton: /* @__PURE__ */ t(O, { children: [
966
+ /* @__PURE__ */ e(f, { className: "h-6 w-48" }),
967
+ /* @__PURE__ */ e(f, { className: "h-2 w-full" }),
968
+ /* @__PURE__ */ e(f, { className: "h-16 w-full" }),
969
+ /* @__PURE__ */ e(f, { className: "h-16 w-full" }),
970
+ /* @__PURE__ */ e(f, { className: "h-16 w-full" })
971
+ ] }),
972
+ children: /* @__PURE__ */ t("div", { className: S, style: c, children: [
973
+ /* @__PURE__ */ e("p", { className: "text-xl font-bold text-foreground mb-2", children: l }),
974
+ a && /* @__PURE__ */ e("div", { className: "mb-2 text-muted-foreground text-sm", children: typeof a == "string" ? /* @__PURE__ */ e("span", { children: a }) : a }),
975
+ m && /* @__PURE__ */ t("div", { className: "mb-3", children: [
976
+ /* @__PURE__ */ e(pe, { value: u / i.length * 100 }),
977
+ /* @__PURE__ */ t("span", { className: "block text-xs text-muted-foreground mt-0.5", children: [
978
+ u,
979
+ " of ",
980
+ i.length,
981
+ " answered"
982
+ ] })
983
+ ] }),
984
+ i.map((d, y) => {
985
+ var T, n;
986
+ const L = A.get(d.uid);
987
+ return /* @__PURE__ */ e(_, { className: "mb-2", children: /* @__PURE__ */ t(E, { className: "pt-6", children: [
988
+ /* @__PURE__ */ t("p", { className: "font-medium text-foreground mb-2", children: [
989
+ y + 1,
990
+ ". ",
991
+ d.content,
992
+ d.required && /* @__PURE__ */ e("span", { className: "text-destructive ml-0.5", children: "*" })
993
+ ] }),
994
+ d.type === "likert" && /* @__PURE__ */ e(
995
+ Yt,
996
+ {
997
+ value: L ? Number(L.value) : null,
998
+ onChange: (g) => x(d.uid, g),
999
+ points: d.scalePoints,
1000
+ lowLabel: (T = d.scaleLabels) == null ? void 0 : T.low,
1001
+ highLabel: (n = d.scaleLabels) == null ? void 0 : n.high,
1002
+ readOnly: h
1003
+ }
1004
+ ),
1005
+ d.type === "rating" && /* @__PURE__ */ e(
1006
+ Zt,
1007
+ {
1008
+ value: L ? Number(L.value) : 0,
1009
+ onChange: (g) => x(d.uid, g),
1010
+ readOnly: h
1011
+ }
1012
+ ),
1013
+ d.type === "open_text" && /* @__PURE__ */ e(
1014
+ he,
1015
+ {
1016
+ placeholder: "Type your response...",
1017
+ value: (L == null ? void 0 : L.value) ?? "",
1018
+ onChange: (g) => x(d.uid, g),
1019
+ readOnly: h,
1020
+ className: "min-h-24",
1021
+ variant: "minimal"
1022
+ }
1023
+ ),
1024
+ d.type === "choice" && d.answers && /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: d.answers.map((g) => /* @__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: [
1025
+ /* @__PURE__ */ e(
1026
+ "input",
1027
+ {
1028
+ type: "radio",
1029
+ className: "accent-primary m-0 shrink-0",
1030
+ name: `survey-q-${d.uid}`,
1031
+ value: g.uid,
1032
+ checked: (L == null ? void 0 : L.value) === g.uid,
1033
+ onChange: () => x(d.uid, g.uid),
1034
+ disabled: h
1035
+ }
1036
+ ),
1037
+ /* @__PURE__ */ e("span", { children: g.content })
1038
+ ] }, g.uid)) }),
1039
+ d.type === "multiple_choice" && d.answers && /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: d.answers.map((g) => {
1040
+ const R = z.filter((P) => P.questionUid === d.uid).map((P) => String(P.value));
1041
+ 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: [
1042
+ /* @__PURE__ */ e(
1043
+ "input",
1044
+ {
1045
+ type: "checkbox",
1046
+ className: "accent-primary m-0 shrink-0",
1047
+ checked: R.includes(g.uid),
1048
+ disabled: h,
1049
+ onChange: (P) => {
1050
+ const Y = z.filter((G) => G.questionUid === d.uid);
1051
+ let V;
1052
+ P.target.checked ? V = [...Y, { questionUid: d.uid, value: g.uid }] : V = Y.filter((G) => String(G.value) !== g.uid), U((G) => [
1053
+ ...G.filter((K) => K.questionUid !== d.uid),
1054
+ ...V
1055
+ ]), r == null || r([
1056
+ ...z.filter((G) => G.questionUid !== d.uid),
1057
+ ...V
1058
+ ]);
1059
+ }
1060
+ }
1061
+ ),
1062
+ /* @__PURE__ */ e("span", { children: g.content })
1063
+ ] }, g.uid);
1064
+ }) })
1065
+ ] }) }, d.uid);
1066
+ }),
1067
+ /* @__PURE__ */ e(H, { className: "my-3" }),
1068
+ /* @__PURE__ */ t("div", { className: "flex justify-between items-center", children: [
1069
+ /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
1070
+ u,
1071
+ " of ",
1072
+ i.length,
1073
+ " answered"
1074
+ ] }),
1075
+ /* @__PURE__ */ e(
1076
+ D,
1077
+ {
1078
+ onClick: () => p(z),
1079
+ disabled: !M || b || h,
1080
+ children: b ? "Submitting..." : v
1081
+ }
1082
+ )
1083
+ ] })
1084
+ ] })
1085
+ }
1086
+ );
1087
+ }
1088
+ function Il({
1089
+ title: l,
1090
+ blocks: a,
1091
+ isCompleted: i = !1,
1092
+ onMarkComplete: o,
1093
+ onNextLesson: p,
1094
+ nextLessonTitle: r,
1095
+ estimatedDuration: m,
1096
+ showDuration: s = !0,
1097
+ readOnly: v = !1,
1098
+ isLoading: b,
1099
+ error: h,
1100
+ onRetry: w,
1101
+ className: N,
1102
+ style: C
1103
+ }) {
1104
+ const [S, c] = F(i);
1105
+ oe(() => {
1106
+ c(i);
1107
+ }, [i]);
1108
+ function z() {
1109
+ c(!0), o == null || o();
1110
+ }
1111
+ return /* @__PURE__ */ e(
1112
+ te,
1113
+ {
1114
+ isLoading: b,
1115
+ error: h,
1116
+ onRetry: w,
1117
+ className: N,
1118
+ style: C,
1119
+ skeleton: /* @__PURE__ */ t(O, { children: [
1120
+ /* @__PURE__ */ e(f, { className: "h-8 w-64" }),
1121
+ /* @__PURE__ */ e(f, { className: "h-24 w-full" }),
1122
+ /* @__PURE__ */ e(f, { className: "h-16 w-full" }),
1123
+ /* @__PURE__ */ e(f, { className: "h-32 w-full" })
1124
+ ] }),
1125
+ children: /* @__PURE__ */ t("div", { children: [
1126
+ /* @__PURE__ */ t("div", { className: "mb-3", children: [
1127
+ /* @__PURE__ */ e("p", { className: "text-2xl font-bold mb-0.5 text-foreground", children: l }),
1128
+ s && m != null && /* @__PURE__ */ t("div", { className: "flex items-center gap-0.5 text-muted-foreground", children: [
1129
+ /* @__PURE__ */ e(xe, { size: 16 }),
1130
+ /* @__PURE__ */ e("span", { className: "text-sm", children: lt(m) })
1131
+ ] })
1132
+ ] }),
1133
+ /* @__PURE__ */ e(H, { className: "mb-3" }),
1134
+ /* @__PURE__ */ e("div", { className: "flex flex-col gap-3", children: a != null && a.length ? a.map((U, u) => /* @__PURE__ */ e(
1135
+ Jt,
1136
+ {
1137
+ block: U,
1138
+ readOnly: v
1139
+ },
1140
+ u
1141
+ )) : /* @__PURE__ */ e(
1142
+ $,
1143
+ {
1144
+ title: "No content yet",
1145
+ description: "This lesson doesn't have any content blocks."
1146
+ }
1147
+ ) }),
1148
+ /* @__PURE__ */ e(_, { className: "mt-4 sticky bottom-0 z-10", children: /* @__PURE__ */ e(E, { className: "px-4 py-3", children: /* @__PURE__ */ t("div", { className: "flex justify-between items-center", children: [
1149
+ S ? /* @__PURE__ */ t("div", { className: "flex items-center gap-1 text-success", children: [
1150
+ /* @__PURE__ */ e(Qe, { size: 20 }),
1151
+ /* @__PURE__ */ e("span", { className: "text-sm font-semibold", children: "Lesson Complete" })
1152
+ ] }) : /* @__PURE__ */ t(
1153
+ D,
1154
+ {
1155
+ onClick: z,
1156
+ disabled: v,
1157
+ children: [
1158
+ /* @__PURE__ */ e(Qe, { size: 18 }),
1159
+ " Mark Complete"
1160
+ ]
1161
+ }
1162
+ ),
1163
+ p && /* @__PURE__ */ t(
1164
+ D,
1165
+ {
1166
+ variant: S ? "default" : "outline",
1167
+ onClick: p,
1168
+ children: [
1169
+ r ? `Next: ${r}` : "Next Lesson",
1170
+ " ",
1171
+ /* @__PURE__ */ e(Re, { size: 18 })
1172
+ ]
1173
+ }
1174
+ )
1175
+ ] }) }) })
1176
+ ] })
1177
+ }
1178
+ );
1179
+ }
1180
+ function Ml({
1181
+ announcements: l,
1182
+ onMarkRead: a,
1183
+ onSelect: i,
1184
+ showAvatars: o = !0,
1185
+ previewLines: p = 3,
1186
+ emptyMessage: r = "No announcements yet",
1187
+ readOnly: m = !1,
1188
+ isLoading: s,
1189
+ error: v,
1190
+ onRetry: b,
1191
+ pageSize: h,
1192
+ currentPage: w = 1,
1193
+ totalItems: N,
1194
+ onPageChange: C,
1195
+ className: S,
1196
+ style: c
1197
+ }) {
1198
+ const [z, U] = F(/* @__PURE__ */ new Set()), u = B(() => {
1199
+ const x = l.filter((d) => d.isPinned), A = l.filter((d) => !d.isPinned);
1200
+ return [...x, ...A];
1201
+ }, [l]);
1202
+ function M(x) {
1203
+ U((d) => {
1204
+ const y = new Set(d);
1205
+ return y.has(x) ? y.delete(x) : y.add(x), y;
1206
+ });
1207
+ const A = l.find((d) => d.uid === x);
1208
+ A && !A.isRead && (a == null || a(x));
1209
+ }
1210
+ return s ? /* @__PURE__ */ e("div", { className: k("space-y-4", S), style: c, children: Array.from({ length: 3 }).map((x, A) => /* @__PURE__ */ t("div", { className: "flex gap-3 items-start", children: [
1211
+ /* @__PURE__ */ e(f, { className: "h-10 w-10 rounded-full shrink-0" }),
1212
+ /* @__PURE__ */ t("div", { className: "flex-1 space-y-2", children: [
1213
+ /* @__PURE__ */ e(f, { className: "h-5 w-48" }),
1214
+ /* @__PURE__ */ e(f, { className: "h-4 w-full" }),
1215
+ /* @__PURE__ */ e(f, { className: "h-4 w-full" })
1216
+ ] })
1217
+ ] }, A)) }) : v ? /* @__PURE__ */ e("div", { className: k("py-12", S), style: c, children: /* @__PURE__ */ e(
1218
+ $,
1219
+ {
1220
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
1221
+ title: "Something went wrong",
1222
+ description: v,
1223
+ action: b ? /* @__PURE__ */ e(D, { variant: "outline", onClick: b, children: "Retry" }) : void 0
1224
+ }
1225
+ ) }) : u.length === 0 ? /* @__PURE__ */ e("div", { className: S, style: c, children: /* @__PURE__ */ e($, { title: r }) }) : /* @__PURE__ */ t("div", { className: k("flex flex-col gap-2", S), style: c, children: [
1226
+ (C && h ? u.slice((w - 1) * h, w * h) : u).map((x) => {
1227
+ const A = z.has(x.uid);
1228
+ return /* @__PURE__ */ e(
1229
+ _,
1230
+ {
1231
+ className: k(
1232
+ x.isRead && "opacity-85",
1233
+ i && "cursor-pointer",
1234
+ x.isPinned && "border-l-4 border-l-warning"
1235
+ ),
1236
+ onClick: () => i && !m ? i(x) : M(x.uid),
1237
+ children: /* @__PURE__ */ e(E, { className: "py-4", children: /* @__PURE__ */ t("div", { className: "flex gap-1.5 items-start", children: [
1238
+ o && /* @__PURE__ */ e(
1239
+ fe,
1240
+ {
1241
+ displayName: x.author.displayName,
1242
+ avatarUrl: x.author.avatarUrl,
1243
+ role: x.author.role,
1244
+ size: "medium"
1245
+ }
1246
+ ),
1247
+ /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
1248
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-1 mb-0.5", children: [
1249
+ x.isPinned && /* @__PURE__ */ e(Ze, { size: 14 }),
1250
+ /* @__PURE__ */ e(
1251
+ "span",
1252
+ {
1253
+ className: k("text-foreground", x.isRead ? "font-normal" : "font-semibold"),
1254
+ children: x.title
1255
+ }
1256
+ ),
1257
+ !x.isRead && /* @__PURE__ */ e(X, { variant: "destructive", className: "text-[10px] px-1.5 py-0", children: "New" })
1258
+ ] }),
1259
+ /* @__PURE__ */ t("span", { className: "block text-xs text-muted-foreground mb-1", children: [
1260
+ x.author.displayName,
1261
+ " · ",
1262
+ Me(x.createdAt)
1263
+ ] }),
1264
+ /* @__PURE__ */ e(
1265
+ "div",
1266
+ {
1267
+ className: k(
1268
+ "text-sm text-foreground [&_p]:mb-2 [&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5",
1269
+ !A && "line-clamp-(--preview-lines) overflow-hidden"
1270
+ ),
1271
+ style: A ? void 0 : { "--preview-lines": p },
1272
+ dangerouslySetInnerHTML: { __html: x.content }
1273
+ }
1274
+ ),
1275
+ !A && x.content.replace(/<[^>]*>/g, "").length > 200 && /* @__PURE__ */ e(
1276
+ D,
1277
+ {
1278
+ variant: "link",
1279
+ size: "xs",
1280
+ className: "px-0 mt-0.5 h-auto",
1281
+ onClick: (d) => {
1282
+ d.stopPropagation(), M(x.uid);
1283
+ },
1284
+ children: "Read more"
1285
+ }
1286
+ )
1287
+ ] })
1288
+ ] }) })
1289
+ },
1290
+ x.uid
1291
+ );
1292
+ }),
1293
+ C && h && u.length > 0 && /* @__PURE__ */ e(
1294
+ we,
1295
+ {
1296
+ currentPage: w,
1297
+ totalPages: Math.ceil((N ?? u.length) / h),
1298
+ onPageChange: C,
1299
+ className: "mt-4"
1300
+ }
1301
+ )
1302
+ ] });
1303
+ }
1304
+ function ve(l) {
1305
+ return l.replace(/<[^>]*>/g, "").trim().length === 0;
1306
+ }
1307
+ function Fl({
1308
+ title: l,
1309
+ rootPost: a,
1310
+ replies: i,
1311
+ currentUser: o,
1312
+ onReply: p,
1313
+ onToggleLike: r,
1314
+ onMarkAnswer: m,
1315
+ maxDepth: s = 3,
1316
+ allowReplies: v = !0,
1317
+ sortOrder: b = "oldest",
1318
+ readOnly: h = !1,
1319
+ isLoading: w,
1320
+ error: N,
1321
+ onRetry: C,
1322
+ className: S,
1323
+ style: c
1324
+ }) {
1325
+ const [z, U] = F(null), [u, M] = F(""), x = B(() => {
1326
+ const y = /* @__PURE__ */ new Map();
1327
+ for (const L of i) {
1328
+ const T = L.parentUid ?? a.uid, n = y.get(T) ?? [];
1329
+ n.push(L), y.set(T, n);
1330
+ }
1331
+ for (const [, L] of y)
1332
+ L.sort((T, n) => b === "newest" ? new Date(n.createdAt).getTime() - new Date(T.createdAt).getTime() : b === "most_liked" ? n.likeCount - T.likeCount : new Date(T.createdAt).getTime() - new Date(n.createdAt).getTime());
1333
+ return y;
1334
+ }, [i, a.uid, b]);
1335
+ if (w)
1336
+ return /* @__PURE__ */ t("div", { className: k("space-y-4", S), style: c, children: [
1337
+ /* @__PURE__ */ e(f, { className: "h-7 w-64" }),
1338
+ /* @__PURE__ */ t("div", { className: "flex items-start gap-3", children: [
1339
+ /* @__PURE__ */ e(f, { className: "h-8 w-8 rounded-full shrink-0" }),
1340
+ /* @__PURE__ */ e(f, { className: "h-32 w-full" })
1341
+ ] }),
1342
+ Array.from({ length: 2 }).map((y, L) => /* @__PURE__ */ e("div", { className: "ml-8", children: /* @__PURE__ */ e(f, { className: "h-20 w-full" }) }, L))
1343
+ ] });
1344
+ if (N)
1345
+ return /* @__PURE__ */ e("div", { className: k("py-12", S), style: c, children: /* @__PURE__ */ e(
1346
+ $,
1347
+ {
1348
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
1349
+ title: "Something went wrong",
1350
+ description: N,
1351
+ action: C ? /* @__PURE__ */ e(D, { variant: "outline", onClick: C, children: "Retry" }) : void 0
1352
+ }
1353
+ ) });
1354
+ function A(y) {
1355
+ ve(u) || (p(y, u), M(""), U(null));
1356
+ }
1357
+ function d(y, L) {
1358
+ const T = x.get(y.uid) ?? [], n = Math.min(L, s), g = /* @__PURE__ */ t("div", { className: "flex items-center gap-1", children: [
1359
+ r && !h && /* @__PURE__ */ t(se, { children: [
1360
+ /* @__PURE__ */ e(ie, { children: /* @__PURE__ */ t(
1361
+ D,
1362
+ {
1363
+ variant: "ghost",
1364
+ size: "sm",
1365
+ "aria-label": y.isLikedByCurrentUser ? "Unlike" : "Like",
1366
+ className: k(y.isLikedByCurrentUser && "text-destructive"),
1367
+ onClick: () => r(y.uid),
1368
+ children: [
1369
+ /* @__PURE__ */ e(Je, { size: 14, fill: y.isLikedByCurrentUser ? "currentColor" : "none" }),
1370
+ y.likeCount > 0 ? y.likeCount : "Like"
1371
+ ]
1372
+ }
1373
+ ) }),
1374
+ /* @__PURE__ */ e(re, { children: y.isLikedByCurrentUser ? "Unlike" : "Like" })
1375
+ ] }),
1376
+ v && !h && /* @__PURE__ */ t(se, { children: [
1377
+ /* @__PURE__ */ e(ie, { children: /* @__PURE__ */ t(
1378
+ D,
1379
+ {
1380
+ variant: "ghost",
1381
+ size: "sm",
1382
+ "aria-label": "Reply",
1383
+ onClick: () => U(y.uid),
1384
+ children: [
1385
+ /* @__PURE__ */ e(Ut, { size: 14 }),
1386
+ "Reply"
1387
+ ]
1388
+ }
1389
+ ) }),
1390
+ /* @__PURE__ */ e(re, { children: "Reply" })
1391
+ ] }),
1392
+ m && !h && o.role !== "student" && !y.isAnswer && /* @__PURE__ */ t(se, { children: [
1393
+ /* @__PURE__ */ e(ie, { children: /* @__PURE__ */ t(
1394
+ D,
1395
+ {
1396
+ variant: "ghost",
1397
+ size: "sm",
1398
+ "aria-label": "Mark as answer",
1399
+ className: "text-success",
1400
+ onClick: () => m(y.uid),
1401
+ children: [
1402
+ /* @__PURE__ */ e(De, { size: 14 }),
1403
+ "Mark Answer"
1404
+ ]
1405
+ }
1406
+ ) }),
1407
+ /* @__PURE__ */ e(re, { children: "Mark as answer" })
1408
+ ] })
1409
+ ] });
1410
+ return /* @__PURE__ */ t("div", { children: [
1411
+ /* @__PURE__ */ e(
1412
+ Kt,
1413
+ {
1414
+ author: y.author,
1415
+ content: y.content,
1416
+ createdAt: y.createdAt,
1417
+ updatedAt: y.updatedAt,
1418
+ actions: g,
1419
+ highlight: y.isAnswer ? "answer" : "none",
1420
+ indentLevel: n,
1421
+ className: "mb-2"
1422
+ }
1423
+ ),
1424
+ z === y.uid && /* @__PURE__ */ e(
1425
+ _,
1426
+ {
1427
+ className: "mb-2",
1428
+ style: { marginLeft: `${(n + 1) * 16}px` },
1429
+ children: /* @__PURE__ */ t(E, { className: "py-4", children: [
1430
+ /* @__PURE__ */ e(
1431
+ he,
1432
+ {
1433
+ className: "min-h-15 mb-2",
1434
+ placeholder: "Write a reply...",
1435
+ value: u,
1436
+ onChange: (R) => M(R),
1437
+ variant: "minimal"
1438
+ }
1439
+ ),
1440
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
1441
+ /* @__PURE__ */ e(
1442
+ D,
1443
+ {
1444
+ size: "sm",
1445
+ onClick: () => A(y.uid),
1446
+ disabled: ve(u),
1447
+ children: "Post Reply"
1448
+ }
1449
+ ),
1450
+ /* @__PURE__ */ e(
1451
+ D,
1452
+ {
1453
+ variant: "ghost",
1454
+ size: "sm",
1455
+ onClick: () => {
1456
+ U(null), M("");
1457
+ },
1458
+ children: "Cancel"
1459
+ }
1460
+ )
1461
+ ] })
1462
+ ] })
1463
+ }
1464
+ ),
1465
+ T.map((R) => d(R, L + 1))
1466
+ ] }, y.uid);
1467
+ }
1468
+ return /* @__PURE__ */ t("div", { className: S, style: c, children: [
1469
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2 mb-2", children: [
1470
+ /* @__PURE__ */ e(Te, { size: 20, className: "text-foreground shrink-0" }),
1471
+ /* @__PURE__ */ e("span", { className: "text-lg font-semibold text-foreground", children: l }),
1472
+ /* @__PURE__ */ t(X, { variant: "muted", className: "text-xs", children: [
1473
+ i.length,
1474
+ " ",
1475
+ i.length === 1 ? "reply" : "replies"
1476
+ ] })
1477
+ ] }),
1478
+ /* @__PURE__ */ e(H, { className: "mb-2" }),
1479
+ d(a, 0)
1480
+ ] });
1481
+ }
1482
+ function Pl({
1483
+ title: l,
1484
+ instructions: a,
1485
+ dueDate: i,
1486
+ maxScore: o,
1487
+ status: p,
1488
+ submissionTypes: r,
1489
+ existingSubmission: m,
1490
+ fileConstraints: s,
1491
+ onSubmit: v,
1492
+ onSaveDraft: b,
1493
+ grade: h,
1494
+ isSubmitting: w = !1,
1495
+ readOnly: N = !1,
1496
+ isLoading: C,
1497
+ error: S,
1498
+ onRetry: c,
1499
+ className: z,
1500
+ style: U
1501
+ }) {
1502
+ const [u, M] = F((m == null ? void 0 : m.textContent) ?? ""), [x, A] = F((m == null ? void 0 : m.files) ?? []), [d, y] = F((m == null ? void 0 : m.url) ?? ""), [L, T] = F(r[0]);
1503
+ if (C)
1504
+ return /* @__PURE__ */ t("div", { className: k("space-y-4", z), style: U, children: [
1505
+ /* @__PURE__ */ e(f, { className: "h-8 w-64" }),
1506
+ /* @__PURE__ */ e(f, { className: "h-6 w-20" }),
1507
+ /* @__PURE__ */ e(f, { className: "h-32 w-full" }),
1508
+ /* @__PURE__ */ e(f, { className: "h-10 w-32" })
1509
+ ] });
1510
+ if (S)
1511
+ return /* @__PURE__ */ e("div", { className: k("py-12", z), style: U, children: /* @__PURE__ */ e(
1512
+ $,
1513
+ {
1514
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
1515
+ title: "Something went wrong",
1516
+ description: S,
1517
+ action: c ? /* @__PURE__ */ e(D, { variant: "outline", onClick: c, children: "Retry" }) : void 0
1518
+ }
1519
+ ) });
1520
+ const n = !N && !["submitted", "graded"].includes(p);
1521
+ function g() {
1522
+ return {
1523
+ textContent: r.includes("text") ? u : void 0,
1524
+ files: r.includes("file") ? x : void 0,
1525
+ url: r.includes("url") ? d : void 0
1526
+ };
1527
+ }
1528
+ return /* @__PURE__ */ t("div", { className: z, style: U, children: [
1529
+ /* @__PURE__ */ e("div", { className: "flex justify-between items-start mb-2", children: /* @__PURE__ */ t("div", { children: [
1530
+ /* @__PURE__ */ e("div", { className: "text-xl font-bold text-foreground mb-0.5", children: l }),
1531
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
1532
+ /* @__PURE__ */ e(at, { status: p }),
1533
+ i && /* @__PURE__ */ e(nt, { dueDate: i, size: "small" }),
1534
+ o != null && /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
1535
+ o,
1536
+ " points"
1537
+ ] })
1538
+ ] })
1539
+ ] }) }),
1540
+ /* @__PURE__ */ e(_, { className: "mb-3", children: /* @__PURE__ */ t(E, { className: "pt-6", children: [
1541
+ /* @__PURE__ */ e("div", { className: "font-semibold text-sm text-foreground mb-1", children: "Instructions" }),
1542
+ /* @__PURE__ */ e("div", { className: "text-muted-foreground text-sm", children: typeof a == "string" ? /* @__PURE__ */ e("span", { children: a }) : a })
1543
+ ] }) }),
1544
+ h && /* @__PURE__ */ e(et, { variant: "success", className: "mb-3", children: /* @__PURE__ */ t(tt, { children: [
1545
+ /* @__PURE__ */ t("div", { className: "font-semibold text-sm mb-1", children: [
1546
+ "Grade: ",
1547
+ h.score,
1548
+ o != null ? ` / ${o}` : ""
1549
+ ] }),
1550
+ h.feedback && /* @__PURE__ */ e("div", { children: h.feedback })
1551
+ ] }) }),
1552
+ n && /* @__PURE__ */ t(O, { children: [
1553
+ r.length > 1 ? /* @__PURE__ */ t(st, { value: L, onValueChange: (R) => T(R), children: [
1554
+ /* @__PURE__ */ t(it, { children: [
1555
+ r.includes("text") && /* @__PURE__ */ e(ce, { value: "text", children: "Text" }),
1556
+ r.includes("file") && /* @__PURE__ */ e(ce, { value: "file", children: "File Upload" }),
1557
+ r.includes("url") && /* @__PURE__ */ e(ce, { value: "url", children: "URL" })
1558
+ ] }),
1559
+ r.includes("text") && /* @__PURE__ */ e(ke, { value: "text", children: /* @__PURE__ */ e(
1560
+ he,
1561
+ {
1562
+ className: "min-h-45",
1563
+ placeholder: "Type your submission...",
1564
+ value: u,
1565
+ onChange: (R) => M(R),
1566
+ variant: "default"
1567
+ }
1568
+ ) }),
1569
+ r.includes("file") && /* @__PURE__ */ e(ke, { value: "file", children: /* @__PURE__ */ e(
1570
+ Ge,
1571
+ {
1572
+ files: x,
1573
+ onFilesAdded: (R) => A((P) => [...P, ...R]),
1574
+ onFileRemove: (R) => A((P) => P.filter((Y, V) => V !== R)),
1575
+ accept: s == null ? void 0 : s.acceptedTypes,
1576
+ maxFiles: s == null ? void 0 : s.maxFiles,
1577
+ maxSizeMB: s == null ? void 0 : s.maxSizeMB
1578
+ }
1579
+ ) }),
1580
+ r.includes("url") && /* @__PURE__ */ e(ke, { value: "url", children: /* @__PURE__ */ e(
1581
+ Ae,
1582
+ {
1583
+ placeholder: "https://...",
1584
+ value: d,
1585
+ onChange: (R) => y(R.target.value)
1586
+ }
1587
+ ) })
1588
+ ] }) : /* @__PURE__ */ t(O, { children: [
1589
+ r.includes("text") && /* @__PURE__ */ e(
1590
+ he,
1591
+ {
1592
+ className: "min-h-45 mb-2",
1593
+ placeholder: "Type your submission...",
1594
+ value: u,
1595
+ onChange: (R) => M(R),
1596
+ variant: "default"
1597
+ }
1598
+ ),
1599
+ r.includes("file") && /* @__PURE__ */ e("div", { className: "mb-2", children: /* @__PURE__ */ e(
1600
+ Ge,
1601
+ {
1602
+ files: x,
1603
+ onFilesAdded: (R) => A((P) => [...P, ...R]),
1604
+ onFileRemove: (R) => A((P) => P.filter((Y, V) => V !== R)),
1605
+ accept: s == null ? void 0 : s.acceptedTypes,
1606
+ maxFiles: s == null ? void 0 : s.maxFiles,
1607
+ maxSizeMB: s == null ? void 0 : s.maxSizeMB
1608
+ }
1609
+ ) }),
1610
+ r.includes("url") && /* @__PURE__ */ e(
1611
+ Ae,
1612
+ {
1613
+ className: "mb-2",
1614
+ placeholder: "https://...",
1615
+ value: d,
1616
+ onChange: (R) => y(R.target.value)
1617
+ }
1618
+ )
1619
+ ] }),
1620
+ /* @__PURE__ */ e(H, { className: "my-2" }),
1621
+ /* @__PURE__ */ t("div", { className: "flex gap-2 justify-end", children: [
1622
+ b && /* @__PURE__ */ t(
1623
+ D,
1624
+ {
1625
+ variant: "outline",
1626
+ onClick: () => b(g()),
1627
+ disabled: w,
1628
+ children: [
1629
+ /* @__PURE__ */ e(Rt, { size: 16 }),
1630
+ "Save Draft"
1631
+ ]
1632
+ }
1633
+ ),
1634
+ /* @__PURE__ */ t(
1635
+ D,
1636
+ {
1637
+ onClick: () => v(g()),
1638
+ disabled: w,
1639
+ children: [
1640
+ /* @__PURE__ */ e(Ye, { size: 16 }),
1641
+ w ? "Submitting..." : "Submit"
1642
+ ]
1643
+ }
1644
+ )
1645
+ ] })
1646
+ ] })
1647
+ ] });
1648
+ }
1649
+ function ge({
1650
+ label: l,
1651
+ field: a,
1652
+ sortField: i,
1653
+ sortDir: o,
1654
+ onSort: p,
1655
+ textAlign: r
1656
+ }) {
1657
+ const m = i === a;
1658
+ return /* @__PURE__ */ e(
1659
+ Ne,
1660
+ {
1661
+ className: k(
1662
+ "cursor-pointer select-none hover:bg-muted",
1663
+ r === "right" && "text-right"
1664
+ ),
1665
+ onClick: () => p(a),
1666
+ children: /* @__PURE__ */ t("div", { className: k("flex items-center gap-1", r === "right" && "justify-end"), children: [
1667
+ /* @__PURE__ */ e("span", { className: k(m ? "text-foreground" : "text-muted-foreground"), children: l }),
1668
+ m && (o === "asc" ? /* @__PURE__ */ e(Dt, { size: 14 }) : /* @__PURE__ */ e(Tt, { size: 14 }))
1669
+ ] })
1670
+ }
1671
+ );
1672
+ }
1673
+ function _l({
1674
+ items: l,
1675
+ categories: a,
1676
+ overallGrade: i,
1677
+ showWeights: o = !0,
1678
+ showCategoryTotals: p = !0,
1679
+ onItemClick: r,
1680
+ readOnly: m = !1,
1681
+ isLoading: s,
1682
+ error: v,
1683
+ onRetry: b,
1684
+ pageSize: h,
1685
+ currentPage: w = 1,
1686
+ totalItems: N,
1687
+ onPageChange: C,
1688
+ className: S,
1689
+ style: c
1690
+ }) {
1691
+ const [z, U] = F("dueDate"), [u, M] = F("asc");
1692
+ function x(L) {
1693
+ z === L ? M((T) => T === "asc" ? "desc" : "asc") : (U(L), M("asc"));
1694
+ }
1695
+ const A = B(() => {
1696
+ const L = [...l];
1697
+ return L.sort((T, n) => {
1698
+ let g = 0;
1699
+ switch (z) {
1700
+ case "name":
1701
+ g = T.name.localeCompare(n.name);
1702
+ break;
1703
+ case "score":
1704
+ g = (T.score ?? -1) - (n.score ?? -1);
1705
+ break;
1706
+ case "dueDate":
1707
+ g = (T.dueDate ?? "").localeCompare(n.dueDate ?? "");
1708
+ break;
1709
+ case "status":
1710
+ g = T.status.localeCompare(n.status);
1711
+ break;
1712
+ }
1713
+ return u === "asc" ? g : -g;
1714
+ }), L;
1715
+ }, [l, z, u]), d = B(() => {
1716
+ if (!a || a.length === 0) return [{ category: null, items: A }];
1717
+ const L = a.map((n) => ({
1718
+ category: n,
1719
+ items: A.filter((g) => g.categoryUid === n.uid)
1720
+ })), T = A.filter((n) => !n.categoryUid);
1721
+ return T.length > 0 && L.push({ category: null, items: T }), L;
1722
+ }, [A, a]), y = o ? 5 : 4;
1723
+ return s ? /* @__PURE__ */ t("div", { className: k("space-y-4", S), style: c, children: [
1724
+ /* @__PURE__ */ e(f, { className: "h-20 w-full" }),
1725
+ /* @__PURE__ */ e(f, { className: "h-10 w-full" }),
1726
+ /* @__PURE__ */ e(f, { className: "h-12 w-full" }),
1727
+ /* @__PURE__ */ e(f, { className: "h-12 w-full" }),
1728
+ /* @__PURE__ */ e(f, { className: "h-12 w-full" }),
1729
+ /* @__PURE__ */ e(f, { className: "h-12 w-full" }),
1730
+ /* @__PURE__ */ e(f, { className: "h-12 w-full" })
1731
+ ] }) : v ? /* @__PURE__ */ e("div", { className: k("py-12", S), style: c, children: /* @__PURE__ */ e(
1732
+ $,
1733
+ {
1734
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
1735
+ title: "Something went wrong",
1736
+ description: v,
1737
+ action: b ? /* @__PURE__ */ e(D, { variant: "outline", onClick: b, children: "Retry" }) : void 0
1738
+ }
1739
+ ) }) : /* @__PURE__ */ t("div", { className: S, style: c, children: [
1740
+ i && /* @__PURE__ */ e(_, { className: "mb-3", children: /* @__PURE__ */ e(E, { className: "pt-6", children: /* @__PURE__ */ t("div", { className: "flex items-center gap-3", children: [
1741
+ /* @__PURE__ */ e(
1742
+ Xt,
1743
+ {
1744
+ percentage: i.percentage,
1745
+ letterGrade: i.letterGrade,
1746
+ size: "large",
1747
+ passingThreshold: 60
1748
+ }
1749
+ ),
1750
+ /* @__PURE__ */ t("div", { children: [
1751
+ /* @__PURE__ */ e("div", { className: "text-lg font-semibold text-foreground", children: "Overall Grade" }),
1752
+ /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
1753
+ i.pointsEarned,
1754
+ " / ",
1755
+ i.pointsPossible,
1756
+ " points"
1757
+ ] })
1758
+ ] })
1759
+ ] }) }) }),
1760
+ /* @__PURE__ */ e(_, { children: /* @__PURE__ */ t(rt, { children: [
1761
+ /* @__PURE__ */ e(ct, { children: /* @__PURE__ */ t(de, { children: [
1762
+ /* @__PURE__ */ e(
1763
+ ge,
1764
+ {
1765
+ label: "Assignment",
1766
+ field: "name",
1767
+ sortField: z,
1768
+ sortDir: u,
1769
+ onSort: x
1770
+ }
1771
+ ),
1772
+ /* @__PURE__ */ e(
1773
+ ge,
1774
+ {
1775
+ label: "Status",
1776
+ field: "status",
1777
+ sortField: z,
1778
+ sortDir: u,
1779
+ onSort: x
1780
+ }
1781
+ ),
1782
+ /* @__PURE__ */ e(
1783
+ ge,
1784
+ {
1785
+ label: "Due Date",
1786
+ field: "dueDate",
1787
+ sortField: z,
1788
+ sortDir: u,
1789
+ onSort: x
1790
+ }
1791
+ ),
1792
+ /* @__PURE__ */ e(
1793
+ ge,
1794
+ {
1795
+ label: "Score",
1796
+ field: "score",
1797
+ sortField: z,
1798
+ sortDir: u,
1799
+ onSort: x,
1800
+ textAlign: "right"
1801
+ }
1802
+ ),
1803
+ o && /* @__PURE__ */ e(Ne, { className: "text-right text-muted-foreground", children: "Weight" })
1804
+ ] }) }),
1805
+ /* @__PURE__ */ e(dt, { children: d.map((L, T) => {
1806
+ var n;
1807
+ return /* @__PURE__ */ t(At, { children: [
1808
+ L.category && p && /* @__PURE__ */ e(de, { className: "bg-muted hover:bg-muted", children: /* @__PURE__ */ e(le, { colSpan: y, children: /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-foreground", children: [
1809
+ L.category.name,
1810
+ L.category.weight != null && ` (${L.category.weight}%)`
1811
+ ] }) }) }),
1812
+ L.items.map((g) => /* @__PURE__ */ t(
1813
+ de,
1814
+ {
1815
+ className: k(r && !m && "cursor-pointer"),
1816
+ onClick: () => r && !m ? r(g) : void 0,
1817
+ children: [
1818
+ /* @__PURE__ */ e(le, { children: g.name }),
1819
+ /* @__PURE__ */ e(le, { children: /* @__PURE__ */ e(at, { status: g.status, size: "small" }) }),
1820
+ /* @__PURE__ */ e(le, { children: g.dueDate ? /* @__PURE__ */ e(
1821
+ nt,
1822
+ {
1823
+ dueDate: g.dueDate,
1824
+ submittedDate: g.submittedDate,
1825
+ size: "small"
1826
+ }
1827
+ ) : "—" }),
1828
+ /* @__PURE__ */ e(le, { className: "text-right", children: g.score != null ? /* @__PURE__ */ t("span", { className: "text-sm font-semibold text-foreground", children: [
1829
+ g.score,
1830
+ " / ",
1831
+ g.maxScore
1832
+ ] }) : g.status === "excused" ? /* @__PURE__ */ e("span", { className: "text-sm text-muted-foreground", children: "Excused" }) : /* @__PURE__ */ e("span", { className: "text-sm text-muted-foreground", children: "—" }) }),
1833
+ o && /* @__PURE__ */ e(le, { className: "text-right", children: g.weight != null ? `${g.weight}%` : "—" })
1834
+ ]
1835
+ },
1836
+ g.uid
1837
+ ))
1838
+ ] }, ((n = L.category) == null ? void 0 : n.uid) ?? `ungrouped-${T}`);
1839
+ }) })
1840
+ ] }) }),
1841
+ C && h && /* @__PURE__ */ e(
1842
+ we,
1843
+ {
1844
+ currentPage: w,
1845
+ totalPages: Math.ceil((N ?? l.length) / h),
1846
+ onPageChange: C,
1847
+ className: "mt-4"
1848
+ }
1849
+ )
1850
+ ] });
1851
+ }
1852
+ const sl = [
1853
+ "var(--palette-0)",
1854
+ "var(--palette-1)",
1855
+ "var(--palette-2)",
1856
+ "var(--palette-3)"
1857
+ ], Ce = sl.length;
1858
+ function il(l) {
1859
+ return `palette${(l % Ce + Ce) % Ce}`;
1860
+ }
1861
+ function El({
1862
+ overallProgress: l,
1863
+ totalTimeSpent: a,
1864
+ modules: i,
1865
+ recentActivity: o,
1866
+ streak: p,
1867
+ achievements: r,
1868
+ recentActivityLimit: m = 5,
1869
+ onModuleClick: s,
1870
+ isLoading: v,
1871
+ error: b,
1872
+ onRetry: h,
1873
+ className: w,
1874
+ style: N
1875
+ }) {
1876
+ const C = B(
1877
+ () => i.filter((c) => c.completedItems === c.totalItems).length,
1878
+ [i]
1879
+ ), S = B(
1880
+ () => (o == null ? void 0 : o.map((c) => ({
1881
+ uid: c.uid,
1882
+ type: c.type,
1883
+ title: c.description,
1884
+ timestamp: c.timestamp
1885
+ }))) ?? [],
1886
+ [o]
1887
+ );
1888
+ return v ? /* @__PURE__ */ t("div", { className: k("space-y-4", w), style: N, children: [
1889
+ /* @__PURE__ */ t("div", { className: "grid grid-cols-3 gap-3", children: [
1890
+ /* @__PURE__ */ e(f, { className: "h-24" }),
1891
+ /* @__PURE__ */ e(f, { className: "h-24" }),
1892
+ /* @__PURE__ */ e(f, { className: "h-24" })
1893
+ ] }),
1894
+ /* @__PURE__ */ e(f, { className: "h-32 w-32 rounded-full mx-auto" }),
1895
+ /* @__PURE__ */ e(f, { className: "h-8 w-full" }),
1896
+ /* @__PURE__ */ e(f, { className: "h-8 w-full" }),
1897
+ /* @__PURE__ */ e(f, { className: "h-8 w-full" })
1898
+ ] }) : b ? /* @__PURE__ */ e("div", { className: k("py-12", w), style: N, children: /* @__PURE__ */ e(
1899
+ $,
1900
+ {
1901
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
1902
+ title: "Something went wrong",
1903
+ description: b,
1904
+ action: h ? /* @__PURE__ */ e(D, { variant: "outline", onClick: h, children: "Retry" }) : void 0
1905
+ }
1906
+ ) }) : /* @__PURE__ */ t("div", { className: w, style: N, children: [
1907
+ /* @__PURE__ */ t("div", { className: "grid grid-cols-[repeat(auto-fit,minmax(160px,1fr))] gap-3 mb-4", children: [
1908
+ /* @__PURE__ */ e(_, { children: /* @__PURE__ */ e(E, { className: "p-3 flex justify-center", children: /* @__PURE__ */ e(ot, { value: l, size: 100 }) }) }),
1909
+ /* @__PURE__ */ e(
1910
+ Le,
1911
+ {
1912
+ icon: /* @__PURE__ */ e(xe, { size: 24 }),
1913
+ label: "Time Spent",
1914
+ description: "Total learning time",
1915
+ value: lt(a)
1916
+ }
1917
+ ),
1918
+ p && /* @__PURE__ */ e(_, { children: /* @__PURE__ */ e(E, { className: "p-4 flex items-center", children: /* @__PURE__ */ e(
1919
+ qt,
1920
+ {
1921
+ currentStreak: p.currentDays,
1922
+ longestStreak: p.longestDays,
1923
+ showLongest: !0
1924
+ }
1925
+ ) }) }),
1926
+ /* @__PURE__ */ e(
1927
+ Le,
1928
+ {
1929
+ icon: /* @__PURE__ */ e(me, { size: 24 }),
1930
+ label: "Modules",
1931
+ description: "Course progress",
1932
+ value: `${C} / ${i.length}`,
1933
+ subtitle: "completed"
1934
+ }
1935
+ )
1936
+ ] }),
1937
+ /* @__PURE__ */ e(H, { className: "mb-3" }),
1938
+ /* @__PURE__ */ e("p", { className: "text-lg font-semibold mb-2 text-foreground", children: "Module Progress" }),
1939
+ /* @__PURE__ */ e("div", { className: "flex flex-col gap-2 mb-4", children: i.map((c, z) => {
1940
+ const U = c.totalItems > 0 ? c.completedItems / c.totalItems * 100 : 0;
1941
+ return /* @__PURE__ */ e(
1942
+ _,
1943
+ {
1944
+ className: k(
1945
+ "transition-colors",
1946
+ s && "cursor-pointer hover:border-primary"
1947
+ ),
1948
+ onClick: () => s == null ? void 0 : s(c.uid),
1949
+ children: /* @__PURE__ */ t(E, { className: "p-3", children: [
1950
+ /* @__PURE__ */ t("div", { className: "flex justify-between items-center mb-0.5", children: [
1951
+ /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-foreground", children: c.name }),
1952
+ /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: [
1953
+ c.completedItems,
1954
+ " / ",
1955
+ c.totalItems
1956
+ ] })
1957
+ ] }),
1958
+ /* @__PURE__ */ e(pe, { value: U, size: "sm", variant: U >= 100 ? "success" : il(z) })
1959
+ ] })
1960
+ },
1961
+ c.uid
1962
+ );
1963
+ }) }),
1964
+ o && o.length > 0 && /* @__PURE__ */ t(O, { children: [
1965
+ /* @__PURE__ */ e(H, { className: "mb-3" }),
1966
+ /* @__PURE__ */ e("p", { className: "text-lg font-semibold mb-2 text-foreground", children: "Recent Activity" }),
1967
+ /* @__PURE__ */ e("div", { className: "mb-4", children: /* @__PURE__ */ e(
1968
+ el,
1969
+ {
1970
+ events: S,
1971
+ limit: m
1972
+ }
1973
+ ) })
1974
+ ] }),
1975
+ r && r.length > 0 && /* @__PURE__ */ t(O, { children: [
1976
+ /* @__PURE__ */ e(H, { className: "mb-3" }),
1977
+ /* @__PURE__ */ e("p", { className: "text-lg font-semibold mb-2 text-foreground", children: "Achievements" }),
1978
+ /* @__PURE__ */ e("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-2", children: r.map((c) => /* @__PURE__ */ e(
1979
+ mt,
1980
+ {
1981
+ title: c.name,
1982
+ description: c.description,
1983
+ icon: c.iconUrl ? /* @__PURE__ */ e(
1984
+ "img",
1985
+ {
1986
+ src: c.iconUrl,
1987
+ alt: c.name,
1988
+ className: "w-12 h-12"
1989
+ }
1990
+ ) : void 0,
1991
+ earnedDate: c.earnedAt
1992
+ },
1993
+ c.uid
1994
+ )) })
1995
+ ] })
1996
+ ] });
1997
+ }
1998
+ const rl = {
1999
+ classic: {
2000
+ size: 40,
2001
+ paths: [
2002
+ { d: "M 2 38 L 2 10 Q 2 2 10 2 L 38 2", strokeWidth: 1.5 },
2003
+ { d: "M 7 38 L 7 13 Q 7 7 13 7 L 38 7", strokeWidth: 0.75 }
2004
+ ],
2005
+ color: "text-warning/50"
2006
+ },
2007
+ modern: null,
2008
+ elegant: {
2009
+ size: 32,
2010
+ paths: [{ d: "M 0 30 L 0 0 L 30 0", strokeWidth: 0.5 }],
2011
+ dots: [{ cx: 2.5, cy: 2.5, r: 1.5 }],
2012
+ color: "text-foreground/20"
2013
+ },
2014
+ academic: {
2015
+ size: 36,
2016
+ paths: [
2017
+ { d: "M 0 36 L 0 0 L 36 0", strokeWidth: 2 },
2018
+ { d: "M 5 36 L 5 5 L 36 5", strokeWidth: 1 }
2019
+ ],
2020
+ color: "text-info/35"
2021
+ },
2022
+ minimal: null,
2023
+ bold: {
2024
+ size: 20,
2025
+ paths: [],
2026
+ dots: [{ cx: 5, cy: 5, r: 5 }],
2027
+ color: "text-primary/40"
2028
+ }
2029
+ }, cl = [
2030
+ { key: "tl", pos: "top-3 left-3", transform: void 0 },
2031
+ { key: "tr", pos: "top-3 right-3", transform: "scaleX(-1)" },
2032
+ { key: "bl", pos: "bottom-3 left-3", transform: "scaleY(-1)" },
2033
+ { key: "br", pos: "bottom-3 right-3", transform: "scale(-1)" }
2034
+ ], dl = {
2035
+ classic: {
2036
+ lineColor: "bg-warning/30",
2037
+ motif: /* @__PURE__ */ e("svg", { width: "12", height: "12", viewBox: "0 0 12 12", className: "text-warning/50 shrink-0", "aria-hidden": "true", children: /* @__PURE__ */ e("path", { d: "M6 0 L12 6 L6 12 L0 6 Z", fill: "currentColor" }) })
2038
+ },
2039
+ modern: {
2040
+ lineColor: "bg-primary/20",
2041
+ motif: /* @__PURE__ */ e("svg", { width: "8", height: "8", viewBox: "0 0 8 8", className: "text-primary/40 shrink-0", "aria-hidden": "true", children: /* @__PURE__ */ e("circle", { cx: "4", cy: "4", r: "3", fill: "currentColor" }) })
2042
+ },
2043
+ elegant: {
2044
+ lineColor: "bg-foreground/10",
2045
+ motif: /* @__PURE__ */ e("svg", { width: "10", height: "10", viewBox: "0 0 10 10", className: "text-foreground/15 shrink-0", "aria-hidden": "true", children: /* @__PURE__ */ e("path", { d: "M5 0 L6 4 L10 5 L6 6 L5 10 L4 6 L0 5 L4 4 Z", fill: "currentColor" }) })
2046
+ },
2047
+ academic: {
2048
+ lineColor: "bg-info/25",
2049
+ motif: /* @__PURE__ */ e("svg", { width: "10", height: "10", viewBox: "0 0 10 10", className: "text-info/40 shrink-0", "aria-hidden": "true", children: /* @__PURE__ */ e("path", { 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", fill: "currentColor" }) })
2050
+ },
2051
+ minimal: {
2052
+ lineColor: "bg-border",
2053
+ motif: null
2054
+ },
2055
+ bold: {
2056
+ lineColor: "bg-primary/40",
2057
+ motif: /* @__PURE__ */ e("svg", { width: "10", height: "10", viewBox: "0 0 10 10", className: "text-primary/50 shrink-0", "aria-hidden": "true", children: /* @__PURE__ */ e("rect", { x: "1", y: "1", width: "8", height: "8", fill: "currentColor" }) })
2058
+ }
2059
+ }, ol = {
2060
+ classic: {
2061
+ background: "radial-gradient(ellipse at center, var(--color-warning) 0%, transparent 65%)",
2062
+ opacity: 0.06
2063
+ },
2064
+ modern: null,
2065
+ elegant: {
2066
+ background: "radial-gradient(ellipse at center, var(--color-foreground) 0%, transparent 70%)",
2067
+ opacity: 0.03
2068
+ },
2069
+ academic: {
2070
+ background: "radial-gradient(ellipse at center, var(--color-info) 0%, transparent 65%)",
2071
+ opacity: 0.05
2072
+ },
2073
+ minimal: null,
2074
+ bold: {
2075
+ background: "radial-gradient(ellipse at 30% 50%, var(--color-primary) 0%, transparent 50%), radial-gradient(ellipse at 70% 50%, var(--color-palette-0) 0%, transparent 50%)",
2076
+ opacity: 0.06
2077
+ }
2078
+ }, ml = {
2079
+ classic: "text-warning",
2080
+ modern: "text-primary",
2081
+ elegant: "text-foreground/60",
2082
+ academic: "text-info",
2083
+ minimal: "text-muted-foreground",
2084
+ bold: "text-primary"
2085
+ }, ul = {
2086
+ classic: "uppercase tracking-[4px] text-base font-medium text-foreground/80 font-serif",
2087
+ modern: "uppercase tracking-[3px] text-base font-medium text-primary/80",
2088
+ elegant: "uppercase tracking-[5px] text-sm font-light text-foreground/50",
2089
+ academic: "uppercase tracking-[3px] text-base font-semibold text-info/80",
2090
+ minimal: "uppercase tracking-[2px] text-sm font-normal text-muted-foreground",
2091
+ bold: "uppercase tracking-[3px] text-lg font-black text-primary"
2092
+ }, hl = {
2093
+ classic: "text-warning",
2094
+ modern: "text-primary",
2095
+ elegant: "text-foreground/80",
2096
+ academic: "text-info",
2097
+ minimal: "text-foreground",
2098
+ bold: "text-primary"
2099
+ }, fl = /* @__PURE__ */ new Set([
2100
+ "classic",
2101
+ "elegant",
2102
+ "academic"
2103
+ ]), pl = ht("mx-auto max-w-4xl", {
2104
+ variants: {
2105
+ variant: {
2106
+ classic: "border-[3px] border-double border-warning/50 rounded-lg p-1.5",
2107
+ modern: "rounded-lg",
2108
+ elegant: "border border-foreground/15 rounded-lg p-2.5 dark:border-foreground/10",
2109
+ academic: "border-2 border-info/30 rounded-lg p-1.5",
2110
+ minimal: "rounded-lg",
2111
+ bold: "rounded-lg"
2112
+ }
2113
+ },
2114
+ defaultVariants: { variant: "classic" }
2115
+ }), gl = ht(
2116
+ "relative text-center p-8 sm:p-12 md:p-16 overflow-hidden",
2117
+ {
2118
+ variants: {
2119
+ variant: {
2120
+ classic: "border border-warning/25 rounded bg-warning/5",
2121
+ modern: "border border-primary/20 rounded-lg bg-linear-to-br from-primary/5 to-primary/8 border-t-[3px] border-t-primary/60",
2122
+ elegant: "border border-foreground/8 rounded bg-linear-to-b from-background to-muted/20 dark:border-foreground/5 dark:to-muted/10",
2123
+ academic: "border border-info/15 rounded bg-info/3",
2124
+ minimal: "border border-border rounded-lg bg-background",
2125
+ bold: "border-[3px] border-primary rounded-lg bg-linear-to-br from-primary/8 to-palette-0/8"
2126
+ }
2127
+ },
2128
+ defaultVariants: { variant: "classic" }
2129
+ }
2130
+ );
2131
+ function xl({ variant: l }) {
2132
+ const a = rl[l];
2133
+ return a ? /* @__PURE__ */ e(O, { children: cl.map(({ key: i, pos: o, transform: p }) => {
2134
+ var r;
2135
+ return /* @__PURE__ */ t(
2136
+ "svg",
2137
+ {
2138
+ className: k("absolute pointer-events-none", o, a.color),
2139
+ width: a.size,
2140
+ height: a.size,
2141
+ viewBox: `0 0 ${a.size} ${a.size}`,
2142
+ fill: "none",
2143
+ stroke: "currentColor",
2144
+ style: p ? { transform: p } : void 0,
2145
+ "aria-hidden": "true",
2146
+ children: [
2147
+ a.paths.map((m, s) => /* @__PURE__ */ e("path", { d: m.d, strokeWidth: m.strokeWidth }, s)),
2148
+ (r = a.dots) == null ? void 0 : r.map((m, s) => /* @__PURE__ */ e(
2149
+ "circle",
2150
+ {
2151
+ cx: m.cx,
2152
+ cy: m.cy,
2153
+ r: m.r,
2154
+ fill: "currentColor",
2155
+ stroke: "none"
2156
+ },
2157
+ `d${s}`
2158
+ ))
2159
+ ]
2160
+ },
2161
+ i
2162
+ );
2163
+ }) }) : null;
2164
+ }
2165
+ function Oe({
2166
+ variant: l,
2167
+ className: a
2168
+ }) {
2169
+ const i = dl[l];
2170
+ return /* @__PURE__ */ t(
2171
+ "div",
2172
+ {
2173
+ className: k(
2174
+ "flex items-center justify-center gap-3 my-5 mx-auto max-w-70",
2175
+ a
2176
+ ),
2177
+ role: "separator",
2178
+ "aria-hidden": "true",
2179
+ children: [
2180
+ /* @__PURE__ */ e("span", { className: k("flex-1 h-px", i.lineColor) }),
2181
+ i.motif,
2182
+ /* @__PURE__ */ e("span", { className: k("flex-1 h-px", i.lineColor) })
2183
+ ]
2184
+ }
2185
+ );
2186
+ }
2187
+ function jl({
2188
+ recipientName: l,
2189
+ courseTitle: a,
2190
+ completionDate: i,
2191
+ organizationName: o,
2192
+ organizationLogo: p,
2193
+ signatory: r,
2194
+ certificateId: m,
2195
+ variant: s = "classic",
2196
+ showActions: v = !0,
2197
+ onPrint: b,
2198
+ onDownload: h,
2199
+ isLoading: w,
2200
+ error: N,
2201
+ onRetry: C,
2202
+ className: S,
2203
+ style: c
2204
+ }) {
2205
+ const z = B(() => {
2206
+ try {
2207
+ return new Date(i).toLocaleDateString("en-US", {
2208
+ year: "numeric",
2209
+ month: "long",
2210
+ day: "numeric"
2211
+ });
2212
+ } catch {
2213
+ return i;
2214
+ }
2215
+ }, [i]);
2216
+ function U() {
2217
+ b ? b() : window.print();
2218
+ }
2219
+ const u = ol[s];
2220
+ return /* @__PURE__ */ e(
2221
+ te,
2222
+ {
2223
+ isLoading: w,
2224
+ error: N,
2225
+ onRetry: C,
2226
+ className: S,
2227
+ style: c,
2228
+ skeleton: /* @__PURE__ */ e(f, { className: "h-80 w-full rounded-lg border" }),
2229
+ children: /* @__PURE__ */ t("div", { className: S, style: c, children: [
2230
+ /* @__PURE__ */ e("div", { className: pl({ variant: s }), children: /* @__PURE__ */ t("div", { className: gl({ variant: s }), children: [
2231
+ /* @__PURE__ */ e(xl, { variant: s }),
2232
+ u && /* @__PURE__ */ e(
2233
+ "div",
2234
+ {
2235
+ className: "absolute inset-0 pointer-events-none rounded-[inherit]",
2236
+ style: u,
2237
+ "aria-hidden": "true"
2238
+ }
2239
+ ),
2240
+ /* @__PURE__ */ t("div", { className: "relative", children: [
2241
+ p ? /* @__PURE__ */ e(
2242
+ "img",
2243
+ {
2244
+ src: p,
2245
+ alt: o,
2246
+ className: "h-20 mb-4 mx-auto block"
2247
+ }
2248
+ ) : /* @__PURE__ */ e(
2249
+ Se,
2250
+ {
2251
+ size: 64,
2252
+ className: k("mx-auto mb-6", ml[s])
2253
+ }
2254
+ ),
2255
+ /* @__PURE__ */ e("p", { className: k("mb-2", ul[s]), children: "Certificate of Completion" }),
2256
+ /* @__PURE__ */ e(Oe, { variant: s }),
2257
+ /* @__PURE__ */ e("p", { className: "text-base text-foreground/70 mb-2", children: "This is to certify that" }),
2258
+ /* @__PURE__ */ e(
2259
+ "p",
2260
+ {
2261
+ className: k(
2262
+ "text-4xl font-bold mb-4 text-foreground",
2263
+ fl.has(s) && "font-serif"
2264
+ ),
2265
+ children: l
2266
+ }
2267
+ ),
2268
+ /* @__PURE__ */ e("p", { className: "text-base text-foreground/70 mb-2", children: "has successfully completed" }),
2269
+ /* @__PURE__ */ e(
2270
+ "p",
2271
+ {
2272
+ className: k(
2273
+ "text-2xl font-semibold mb-4",
2274
+ hl[s]
2275
+ ),
2276
+ children: a
2277
+ }
2278
+ ),
2279
+ /* @__PURE__ */ t("p", { className: "text-base text-foreground/60 mb-6", children: [
2280
+ "Issued by ",
2281
+ o,
2282
+ " on ",
2283
+ z
2284
+ ] }),
2285
+ r && /* @__PURE__ */ t("div", { className: "mt-6 mb-4", children: [
2286
+ /* @__PURE__ */ e(Oe, { variant: s }),
2287
+ /* @__PURE__ */ e("p", { className: "font-semibold text-base text-foreground", children: r.name }),
2288
+ /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: r.title })
2289
+ ] }),
2290
+ m && /* @__PURE__ */ t("span", { className: "block text-xs text-muted-foreground mt-4", children: [
2291
+ "Certificate ID: ",
2292
+ m
2293
+ ] })
2294
+ ] })
2295
+ ] }) }),
2296
+ v && /* @__PURE__ */ t("div", { className: "flex justify-center gap-3 mt-6", children: [
2297
+ /* @__PURE__ */ t(D, { variant: "outline", onClick: U, children: [
2298
+ /* @__PURE__ */ e(It, { size: 16 }),
2299
+ " Print"
2300
+ ] }),
2301
+ h && /* @__PURE__ */ t(D, { variant: "outline", onClick: h, children: [
2302
+ /* @__PURE__ */ e(Mt, { size: 16 }),
2303
+ " Download"
2304
+ ] })
2305
+ ] })
2306
+ ] })
2307
+ }
2308
+ );
2309
+ }
2310
+ function Bl({
2311
+ criteria: l,
2312
+ selectedLevels: a,
2313
+ totalScore: i,
2314
+ maxScore: o,
2315
+ feedback: p,
2316
+ isLoading: r,
2317
+ error: m,
2318
+ onRetry: s,
2319
+ className: v,
2320
+ style: b
2321
+ }) {
2322
+ var w;
2323
+ const h = a && Object.keys(a).length > 0;
2324
+ return r ? /* @__PURE__ */ t("div", { className: k("space-y-4", v), style: b, children: [
2325
+ /* @__PURE__ */ e(f, { className: "h-10 w-full" }),
2326
+ Array.from({ length: 3 }).map((N, C) => /* @__PURE__ */ e(f, { className: "h-16 w-full" }, C))
2327
+ ] }) : m ? /* @__PURE__ */ e("div", { className: k("py-12", v), style: b, children: /* @__PURE__ */ e(
2328
+ $,
2329
+ {
2330
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
2331
+ title: "Something went wrong",
2332
+ description: m,
2333
+ action: s ? /* @__PURE__ */ e(D, { variant: "outline", onClick: s, children: "Retry" }) : void 0
2334
+ }
2335
+ ) }) : /* @__PURE__ */ t("div", { className: k("flex flex-col gap-4", v), style: b, children: [
2336
+ h && i !== void 0 && o !== void 0 && /* @__PURE__ */ t("div", { className: "flex items-center justify-between", children: [
2337
+ /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-foreground", children: "Rubric" }),
2338
+ /* @__PURE__ */ t(X, { variant: i >= o * 0.7 ? "success" : "destructive", children: [
2339
+ i,
2340
+ " / ",
2341
+ o,
2342
+ " pts"
2343
+ ] })
2344
+ ] }),
2345
+ !h && /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-foreground", children: "Grading Rubric" }),
2346
+ /* @__PURE__ */ e(_, { children: /* @__PURE__ */ e(E, { className: "p-0", children: /* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ t(rt, { className: "text-sm", children: [
2347
+ /* @__PURE__ */ e(ct, { children: /* @__PURE__ */ t(de, { className: "bg-muted/50", children: [
2348
+ /* @__PURE__ */ e(Ne, { className: "text-left font-medium text-muted-foreground w-1/5", children: "Criterion" }),
2349
+ (w = l[0]) == null ? void 0 : w.levels.map((N) => /* @__PURE__ */ t(
2350
+ Ne,
2351
+ {
2352
+ className: "text-center font-medium text-muted-foreground",
2353
+ children: [
2354
+ /* @__PURE__ */ e("div", { children: N.label }),
2355
+ /* @__PURE__ */ t("div", { className: "text-xs font-normal mt-0.5", children: [
2356
+ N.points,
2357
+ " pts"
2358
+ ] })
2359
+ ]
2360
+ },
2361
+ N.uid
2362
+ ))
2363
+ ] }) }),
2364
+ /* @__PURE__ */ e(dt, { children: l.map((N, C) => {
2365
+ const S = a == null ? void 0 : a[N.uid];
2366
+ return /* @__PURE__ */ t(
2367
+ de,
2368
+ {
2369
+ className: k(C % 2 === 1 && "bg-muted/20"),
2370
+ children: [
2371
+ /* @__PURE__ */ t(le, { className: "align-top", children: [
2372
+ /* @__PURE__ */ e("div", { className: "font-medium text-foreground", children: N.name }),
2373
+ N.description && /* @__PURE__ */ e("div", { className: "text-xs text-muted-foreground mt-0.5", children: N.description })
2374
+ ] }),
2375
+ N.levels.map((c) => {
2376
+ const z = S === c.uid;
2377
+ return /* @__PURE__ */ t(
2378
+ le,
2379
+ {
2380
+ className: k(
2381
+ "align-top text-center",
2382
+ z && "bg-primary/10 ring-2 ring-primary/30 ring-inset rounded-sm"
2383
+ ),
2384
+ children: [
2385
+ /* @__PURE__ */ e("div", { className: "text-xs text-muted-foreground", children: c.description }),
2386
+ z && /* @__PURE__ */ e("div", { className: "mt-1.5 flex justify-center", children: /* @__PURE__ */ e(ue, { className: "size-4 text-primary" }) })
2387
+ ]
2388
+ },
2389
+ c.uid
2390
+ );
2391
+ })
2392
+ ]
2393
+ },
2394
+ N.uid
2395
+ );
2396
+ }) })
2397
+ ] }) }) }) }),
2398
+ p && /* @__PURE__ */ t(O, { children: [
2399
+ /* @__PURE__ */ e(H, {}),
2400
+ /* @__PURE__ */ t("div", { children: [
2401
+ /* @__PURE__ */ e("h4", { className: "text-sm font-medium text-foreground mb-1", children: "Instructor Feedback" }),
2402
+ /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground whitespace-pre-wrap", children: p })
2403
+ ] })
2404
+ ] })
2405
+ ] });
2406
+ }
2407
+ function Ql({
2408
+ title: l,
2409
+ requirements: a,
2410
+ onRequirementClick: i,
2411
+ isLoading: o,
2412
+ error: p,
2413
+ onRetry: r,
2414
+ className: m,
2415
+ style: s
2416
+ }) {
2417
+ const v = B(
2418
+ () => a.filter((h) => h.completed).length,
2419
+ [a]
2420
+ ), b = a.length > 0 ? Math.round(v / a.length * 100) : 0;
2421
+ return o ? /* @__PURE__ */ t("div", { className: k("space-y-4", m), style: s, children: [
2422
+ /* @__PURE__ */ e(f, { className: "h-6 w-48" }),
2423
+ /* @__PURE__ */ e(f, { className: "h-2 w-full" }),
2424
+ Array.from({ length: 4 }).map((h, w) => /* @__PURE__ */ t("div", { className: "flex items-center gap-3", children: [
2425
+ /* @__PURE__ */ e(f, { className: "h-5 w-5 rounded-full" }),
2426
+ /* @__PURE__ */ e(f, { className: "h-4 w-3/4" })
2427
+ ] }, w))
2428
+ ] }) : p ? /* @__PURE__ */ e("div", { className: k("py-12", m), style: s, children: /* @__PURE__ */ e(
2429
+ $,
2430
+ {
2431
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
2432
+ title: "Something went wrong",
2433
+ description: p,
2434
+ action: r ? /* @__PURE__ */ e(D, { variant: "outline", onClick: r, children: "Retry" }) : void 0
2435
+ }
2436
+ ) }) : /* @__PURE__ */ t("div", { className: k("flex flex-col gap-4", m), style: s, children: [
2437
+ l && /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-foreground", children: l }),
2438
+ /* @__PURE__ */ t("div", { className: "flex flex-col gap-1.5", children: [
2439
+ /* @__PURE__ */ t("div", { className: "flex items-center justify-between text-sm", children: [
2440
+ /* @__PURE__ */ t("span", { className: "text-muted-foreground", children: [
2441
+ v,
2442
+ " of ",
2443
+ a.length,
2444
+ " complete"
2445
+ ] }),
2446
+ /* @__PURE__ */ t("span", { className: "font-medium text-foreground", children: [
2447
+ b,
2448
+ "%"
2449
+ ] })
2450
+ ] }),
2451
+ /* @__PURE__ */ e(pe, { value: b })
2452
+ ] }),
2453
+ /* @__PURE__ */ e("ul", { className: "flex flex-col gap-1", children: a.map((h) => /* @__PURE__ */ e("li", { children: /* @__PURE__ */ t(
2454
+ "button",
2455
+ {
2456
+ type: "button",
2457
+ className: k(
2458
+ "w-full flex items-start gap-3 p-3 rounded-lg text-left transition-colors",
2459
+ h.completed ? "bg-success/5" : i ? "hover:bg-muted/50 cursor-pointer" : "cursor-default"
2460
+ ),
2461
+ onClick: () => {
2462
+ !h.completed && i && i(h.uid);
2463
+ },
2464
+ disabled: h.completed,
2465
+ children: [
2466
+ h.completed ? /* @__PURE__ */ e(ue, { className: "size-5 text-success shrink-0 mt-0.5" }) : /* @__PURE__ */ e(Ft, { className: "size-5 text-muted-foreground shrink-0 mt-0.5" }),
2467
+ /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
2468
+ /* @__PURE__ */ e(
2469
+ "div",
2470
+ {
2471
+ className: k(
2472
+ "text-sm font-medium",
2473
+ h.completed ? "text-muted-foreground line-through" : "text-foreground"
2474
+ ),
2475
+ children: h.label
2476
+ }
2477
+ ),
2478
+ h.description && /* @__PURE__ */ e("div", { className: "text-xs text-muted-foreground mt-0.5", children: h.description })
2479
+ ] }),
2480
+ !h.completed && i && /* @__PURE__ */ t("div", { className: "shrink-0 flex items-center gap-1 text-xs text-primary mt-0.5", children: [
2481
+ h.actionLabel && /* @__PURE__ */ e("span", { children: h.actionLabel }),
2482
+ /* @__PURE__ */ e(Re, { className: "size-4" })
2483
+ ] })
2484
+ ]
2485
+ }
2486
+ ) }, h.uid)) })
2487
+ ] });
2488
+ }
2489
+ const Nl = {
2490
+ newest: "Newest",
2491
+ oldest: "Oldest",
2492
+ most_replies: "Most Replies",
2493
+ most_liked: "Most Liked"
2494
+ };
2495
+ function $l({
2496
+ title: l,
2497
+ topics: a,
2498
+ onTopicClick: i,
2499
+ onCreateTopic: o,
2500
+ sortOrder: p = "newest",
2501
+ onSortChange: r,
2502
+ searchQuery: m = "",
2503
+ onSearchChange: s,
2504
+ readOnly: v,
2505
+ isLoading: b,
2506
+ error: h,
2507
+ onRetry: w,
2508
+ pageSize: N,
2509
+ currentPage: C = 1,
2510
+ totalItems: S,
2511
+ onPageChange: c,
2512
+ className: z,
2513
+ style: U
2514
+ }) {
2515
+ const [u, M] = F(!1), [x, A] = F(""), [d, y] = F(""), [L, T] = F(m), [n, g] = F(p), R = s !== void 0 ? m : L, P = r !== void 0 ? p : n;
2516
+ function Y(I) {
2517
+ s ? s(I) : T(I);
2518
+ }
2519
+ function V() {
2520
+ const I = [
2521
+ "newest",
2522
+ "oldest",
2523
+ "most_replies",
2524
+ "most_liked"
2525
+ ], j = I.indexOf(P), Q = I[(j + 1) % I.length];
2526
+ r ? r(Q) : g(Q);
2527
+ }
2528
+ function G() {
2529
+ !x.trim() || ve(d) || (o == null || o(x.trim(), d), A(""), y(""), M(!1));
2530
+ }
2531
+ const K = B(() => [...a.filter((j) => {
2532
+ var W;
2533
+ if (!R) return !0;
2534
+ const Q = R.toLowerCase();
2535
+ return j.title.toLowerCase().includes(Q) || ((W = j.preview) == null ? void 0 : W.toLowerCase().includes(Q)) || j.author.displayName.toLowerCase().includes(Q);
2536
+ })].sort((j, Q) => {
2537
+ if (j.isPinned && !Q.isPinned) return -1;
2538
+ if (!j.isPinned && Q.isPinned) return 1;
2539
+ switch (P) {
2540
+ case "oldest":
2541
+ return new Date(j.createdAt).getTime() - new Date(Q.createdAt).getTime();
2542
+ case "most_replies":
2543
+ return Q.replyCount - j.replyCount;
2544
+ case "most_liked":
2545
+ return Q.likeCount - j.likeCount;
2546
+ case "newest":
2547
+ default:
2548
+ return new Date(Q.createdAt).getTime() - new Date(j.createdAt).getTime();
2549
+ }
2550
+ }), [a, R, P]);
2551
+ return b ? /* @__PURE__ */ t("div", { className: k("space-y-4", z), style: U, children: [
2552
+ /* @__PURE__ */ e(f, { className: "h-9 w-full" }),
2553
+ Array.from({ length: 4 }).map((I, j) => /* @__PURE__ */ t("div", { className: "flex items-center gap-3", children: [
2554
+ /* @__PURE__ */ e(f, { className: "h-8 w-8 rounded-full" }),
2555
+ /* @__PURE__ */ t("div", { className: "flex-1 space-y-2", children: [
2556
+ /* @__PURE__ */ e(f, { className: "h-5 w-64" }),
2557
+ /* @__PURE__ */ e(f, { className: "h-4 w-32" })
2558
+ ] })
2559
+ ] }, j))
2560
+ ] }) : h ? /* @__PURE__ */ e("div", { className: k("py-12", z), style: U, children: /* @__PURE__ */ e(
2561
+ $,
2562
+ {
2563
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
2564
+ title: "Something went wrong",
2565
+ description: h,
2566
+ action: w ? /* @__PURE__ */ e(D, { variant: "outline", onClick: w, children: "Retry" }) : void 0
2567
+ }
2568
+ ) }) : /* @__PURE__ */ t("div", { className: k("flex flex-col gap-4", z), style: U, children: [
2569
+ /* @__PURE__ */ t("div", { className: "flex items-center justify-between gap-4", children: [
2570
+ l && /* @__PURE__ */ e("h2", { className: "text-xl font-bold text-foreground", children: l }),
2571
+ !v && o && /* @__PURE__ */ t(
2572
+ D,
2573
+ {
2574
+ size: "sm",
2575
+ onClick: () => M(!u),
2576
+ children: [
2577
+ /* @__PURE__ */ e(Pt, { className: "size-4 mr-1.5" }),
2578
+ "New Topic"
2579
+ ]
2580
+ }
2581
+ )
2582
+ ] }),
2583
+ /* @__PURE__ */ e(H, {}),
2584
+ u && /* @__PURE__ */ e(_, { children: /* @__PURE__ */ t(E, { className: "pt-4 space-y-3", children: [
2585
+ /* @__PURE__ */ e(
2586
+ Ae,
2587
+ {
2588
+ placeholder: "Topic title",
2589
+ value: x,
2590
+ onChange: (I) => A(I.target.value)
2591
+ }
2592
+ ),
2593
+ /* @__PURE__ */ e(
2594
+ he,
2595
+ {
2596
+ placeholder: "What would you like to discuss?",
2597
+ value: d,
2598
+ onChange: (I) => y(I),
2599
+ variant: "minimal"
2600
+ }
2601
+ ),
2602
+ /* @__PURE__ */ t("div", { className: "flex justify-end gap-2", children: [
2603
+ /* @__PURE__ */ e(
2604
+ D,
2605
+ {
2606
+ variant: "outline",
2607
+ size: "sm",
2608
+ onClick: () => {
2609
+ M(!1), A(""), y("");
2610
+ },
2611
+ children: "Cancel"
2612
+ }
2613
+ ),
2614
+ /* @__PURE__ */ e(
2615
+ D,
2616
+ {
2617
+ size: "sm",
2618
+ onClick: G,
2619
+ disabled: !x.trim() || ve(d),
2620
+ children: "Post Topic"
2621
+ }
2622
+ )
2623
+ ] })
2624
+ ] }) }),
2625
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
2626
+ /* @__PURE__ */ e("div", { className: "flex-1", children: /* @__PURE__ */ e(
2627
+ ut,
2628
+ {
2629
+ value: R,
2630
+ onChange: Y,
2631
+ placeholder: "Search topics..."
2632
+ }
2633
+ ) }),
2634
+ /* @__PURE__ */ t(D, { variant: "outline", size: "sm", onClick: V, children: [
2635
+ /* @__PURE__ */ e(_t, { className: "size-3.5 mr-1.5" }),
2636
+ Nl[P]
2637
+ ] })
2638
+ ] }),
2639
+ K.length === 0 ? /* @__PURE__ */ e(
2640
+ $,
2641
+ {
2642
+ icon: /* @__PURE__ */ e(Te, { className: "size-10 text-muted-foreground" }),
2643
+ title: "No topics found",
2644
+ description: R ? "Try a different search term." : "Be the first to start a discussion!"
2645
+ }
2646
+ ) : /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: (c && N ? K.slice((C - 1) * N, C * N) : K).map((I) => /* @__PURE__ */ e(
2647
+ vl,
2648
+ {
2649
+ topic: I,
2650
+ onClick: () => i(I.uid)
2651
+ },
2652
+ I.uid
2653
+ )) }),
2654
+ c && N && K.length > 0 && /* @__PURE__ */ e(
2655
+ we,
2656
+ {
2657
+ currentPage: C,
2658
+ totalPages: Math.ceil((S ?? K.length) / N),
2659
+ onPageChange: c,
2660
+ className: "mt-4"
2661
+ }
2662
+ )
2663
+ ] });
2664
+ }
2665
+ function vl({
2666
+ topic: l,
2667
+ onClick: a
2668
+ }) {
2669
+ return /* @__PURE__ */ e(
2670
+ "button",
2671
+ {
2672
+ type: "button",
2673
+ className: "w-full text-left",
2674
+ onClick: a,
2675
+ children: /* @__PURE__ */ e(
2676
+ _,
2677
+ {
2678
+ className: k(
2679
+ "transition-colors hover:bg-muted/30",
2680
+ l.isPinned && "border-l-2 border-l-warning"
2681
+ ),
2682
+ children: /* @__PURE__ */ e(E, { className: "py-3 px-4", children: /* @__PURE__ */ t("div", { className: "flex items-start gap-3", children: [
2683
+ /* @__PURE__ */ e(
2684
+ fe,
2685
+ {
2686
+ displayName: l.author.displayName,
2687
+ avatarUrl: l.author.avatarUrl,
2688
+ size: "small"
2689
+ }
2690
+ ),
2691
+ /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
2692
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2 mb-0.5", children: [
2693
+ /* @__PURE__ */ e("span", { className: "font-medium text-foreground text-sm truncate", children: l.title }),
2694
+ l.isPinned && /* @__PURE__ */ e(Ze, { className: "size-3 text-warning shrink-0" }),
2695
+ l.isAnswered && /* @__PURE__ */ t(X, { variant: "success", className: "text-xs shrink-0", children: [
2696
+ /* @__PURE__ */ e(ue, { className: "size-3 mr-0.5" }),
2697
+ "Answered"
2698
+ ] })
2699
+ ] }),
2700
+ l.preview && /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground line-clamp-1", children: l.preview }),
2701
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-3 mt-1.5 text-xs text-muted-foreground", children: [
2702
+ /* @__PURE__ */ e("span", { children: l.author.displayName }),
2703
+ /* @__PURE__ */ e("span", { children: Me(l.createdAt) }),
2704
+ /* @__PURE__ */ t(X, { variant: "muted", className: "gap-0.5 text-xs px-1.5 py-0", children: [
2705
+ /* @__PURE__ */ e(Te, { className: "size-3" }),
2706
+ l.replyCount
2707
+ ] }),
2708
+ /* @__PURE__ */ t(X, { variant: "muted", className: "gap-0.5 text-xs px-1.5 py-0", children: [
2709
+ /* @__PURE__ */ e(Je, { className: "size-3" }),
2710
+ l.likeCount
2711
+ ] })
2712
+ ] })
2713
+ ] })
2714
+ ] }) })
2715
+ }
2716
+ )
2717
+ }
2718
+ );
2719
+ }
2720
+ function Vl({
2721
+ course: l,
2722
+ prerequisites: a,
2723
+ onEnroll: i,
2724
+ onCancel: o,
2725
+ enrollLabel: p = "Enroll Now",
2726
+ isEnrolling: r = !1,
2727
+ isLoading: m,
2728
+ error: s,
2729
+ onRetry: v,
2730
+ className: b,
2731
+ style: h
2732
+ }) {
2733
+ const w = Array.isArray(a) && a.length > 0, [N, C] = F("details"), S = B(
2734
+ () => w ? [
2735
+ { key: "details", label: "Course Details" },
2736
+ { key: "prerequisites", label: "Prerequisites" },
2737
+ { key: "confirmation", label: "Confirmation" }
2738
+ ] : [
2739
+ { key: "details", label: "Course Details" },
2740
+ { key: "confirmation", label: "Confirmation" }
2741
+ ],
2742
+ [w]
2743
+ );
2744
+ if (m)
2745
+ return /* @__PURE__ */ t("div", { className: k("space-y-4", b), style: h, children: [
2746
+ /* @__PURE__ */ e(f, { className: "h-8 w-48" }),
2747
+ /* @__PURE__ */ e(f, { className: "h-48 w-full" }),
2748
+ /* @__PURE__ */ e(f, { className: "h-10 w-32" })
2749
+ ] });
2750
+ if (s)
2751
+ return /* @__PURE__ */ e("div", { className: k("py-12", b), style: h, children: /* @__PURE__ */ e(
2752
+ $,
2753
+ {
2754
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
2755
+ title: "Something went wrong",
2756
+ description: s,
2757
+ action: v ? /* @__PURE__ */ e(D, { variant: "outline", onClick: v, children: "Retry" }) : void 0
2758
+ }
2759
+ ) });
2760
+ const c = S.findIndex((d) => d.key === N), z = !w || a.every((d) => d.isMet);
2761
+ function U() {
2762
+ const d = c + 1;
2763
+ d < S.length && C(S[d].key);
2764
+ }
2765
+ function u() {
2766
+ const d = c - 1;
2767
+ d >= 0 && C(S[d].key);
2768
+ }
2769
+ function M() {
2770
+ return /* @__PURE__ */ e(_, { children: /* @__PURE__ */ t(E, { className: "pt-6", children: [
2771
+ l.thumbnailUrl ? /* @__PURE__ */ e(
2772
+ "img",
2773
+ {
2774
+ src: l.thumbnailUrl,
2775
+ alt: l.title,
2776
+ className: "w-full h-48 object-cover rounded-lg mb-4"
2777
+ }
2778
+ ) : /* @__PURE__ */ e("div", { className: "w-full h-48 rounded-lg mb-4 bg-muted flex items-center justify-center", children: /* @__PURE__ */ e(me, { className: "size-12 text-muted-foreground" }) }),
2779
+ /* @__PURE__ */ e("h2", { className: "text-xl font-bold text-foreground mb-1", children: l.title }),
2780
+ l.description && /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground mb-3", children: l.description }),
2781
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-3 mb-3", children: [
2782
+ l.instructor && /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
2783
+ /* @__PURE__ */ e(
2784
+ fe,
2785
+ {
2786
+ displayName: l.instructor.displayName,
2787
+ avatarUrl: l.instructor.avatarUrl,
2788
+ size: "small"
2789
+ }
2790
+ ),
2791
+ /* @__PURE__ */ e("span", { className: "text-sm text-foreground", children: l.instructor.displayName })
2792
+ ] }),
2793
+ l.duration && /* @__PURE__ */ t(X, { variant: "muted", children: [
2794
+ /* @__PURE__ */ e(xe, { className: "size-3 mr-1" }),
2795
+ l.duration
2796
+ ] })
2797
+ ] }),
2798
+ l.syllabus && l.syllabus.length > 0 && /* @__PURE__ */ t(O, { children: [
2799
+ /* @__PURE__ */ e(H, { className: "my-3" }),
2800
+ /* @__PURE__ */ e("div", { className: "mb-1 text-sm font-semibold text-foreground", children: "Syllabus" }),
2801
+ /* @__PURE__ */ e("ul", { className: "list-disc list-inside space-y-1", children: l.syllabus.map((d, y) => /* @__PURE__ */ e("li", { className: "text-sm text-muted-foreground", children: d }, y)) })
2802
+ ] }),
2803
+ /* @__PURE__ */ e(H, { className: "my-4" }),
2804
+ /* @__PURE__ */ t("div", { className: "flex justify-end gap-2", children: [
2805
+ o && /* @__PURE__ */ e(D, { variant: "outline", onClick: o, children: "Cancel" }),
2806
+ /* @__PURE__ */ e(D, { onClick: U, children: "Continue" })
2807
+ ] })
2808
+ ] }) });
2809
+ }
2810
+ function x() {
2811
+ return /* @__PURE__ */ e(_, { children: /* @__PURE__ */ t(E, { className: "pt-6", children: [
2812
+ /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-foreground mb-3", children: "Prerequisites" }),
2813
+ /* @__PURE__ */ e("ul", { className: "space-y-3", children: a.map((d) => /* @__PURE__ */ t("li", { className: "flex items-start gap-2", children: [
2814
+ d.isMet ? /* @__PURE__ */ e(ue, { className: "size-4 text-success shrink-0 mt-0.5" }) : /* @__PURE__ */ e($e, { className: "size-4 text-destructive shrink-0 mt-0.5" }),
2815
+ /* @__PURE__ */ t("div", { children: [
2816
+ /* @__PURE__ */ e("span", { className: "text-sm font-medium text-foreground", children: d.label }),
2817
+ d.description && /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground mt-0.5", children: d.description })
2818
+ ] })
2819
+ ] }, d.uid)) }),
2820
+ /* @__PURE__ */ e(H, { className: "my-4" }),
2821
+ /* @__PURE__ */ t("div", { className: "flex justify-end gap-2", children: [
2822
+ /* @__PURE__ */ e(D, { variant: "outline", onClick: u, children: "Back" }),
2823
+ /* @__PURE__ */ e(D, { onClick: U, disabled: !z, children: "Continue" })
2824
+ ] })
2825
+ ] }) });
2826
+ }
2827
+ function A() {
2828
+ return /* @__PURE__ */ e(_, { children: /* @__PURE__ */ t(E, { className: "pt-6", children: [
2829
+ /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-foreground mb-3", children: "Confirm Enrollment" }),
2830
+ /* @__PURE__ */ t("div", { className: "space-y-2 mb-3", children: [
2831
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
2832
+ /* @__PURE__ */ e(me, { className: "size-4 text-muted-foreground" }),
2833
+ /* @__PURE__ */ e("span", { className: "text-sm font-medium text-foreground", children: l.title })
2834
+ ] }),
2835
+ l.instructor && /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
2836
+ /* @__PURE__ */ e(
2837
+ fe,
2838
+ {
2839
+ displayName: l.instructor.displayName,
2840
+ avatarUrl: l.instructor.avatarUrl,
2841
+ size: "small"
2842
+ }
2843
+ ),
2844
+ /* @__PURE__ */ e("span", { className: "text-sm text-muted-foreground", children: l.instructor.displayName })
2845
+ ] }),
2846
+ l.duration && /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
2847
+ /* @__PURE__ */ e(xe, { className: "size-4 text-muted-foreground" }),
2848
+ /* @__PURE__ */ e("span", { className: "text-sm text-muted-foreground", children: l.duration })
2849
+ ] })
2850
+ ] }),
2851
+ w && /* @__PURE__ */ e("div", { className: "mb-3", children: z ? /* @__PURE__ */ t(X, { variant: "success", children: [
2852
+ /* @__PURE__ */ e(ue, { className: "size-3 mr-1" }),
2853
+ "All prerequisites met"
2854
+ ] }) : /* @__PURE__ */ t(X, { variant: "warning", children: [
2855
+ /* @__PURE__ */ e($e, { className: "size-3 mr-1" }),
2856
+ "Some prerequisites not met"
2857
+ ] }) }),
2858
+ /* @__PURE__ */ e(H, { className: "my-4" }),
2859
+ /* @__PURE__ */ t("div", { className: "flex justify-end gap-2", children: [
2860
+ /* @__PURE__ */ e(D, { variant: "outline", onClick: u, children: "Back" }),
2861
+ /* @__PURE__ */ t(
2862
+ D,
2863
+ {
2864
+ onClick: () => i(l.uid),
2865
+ disabled: r,
2866
+ children: [
2867
+ r && /* @__PURE__ */ e(Et, { className: "size-4 mr-1 animate-spin" }),
2868
+ p
2869
+ ]
2870
+ }
2871
+ )
2872
+ ] })
2873
+ ] }) });
2874
+ }
2875
+ return /* @__PURE__ */ t("div", { className: b, style: h, children: [
2876
+ /* @__PURE__ */ e(
2877
+ tl,
2878
+ {
2879
+ steps: S.map((d) => ({ label: d.label })),
2880
+ currentStep: c,
2881
+ className: "mb-6"
2882
+ }
2883
+ ),
2884
+ N === "details" && M(),
2885
+ N === "prerequisites" && x(),
2886
+ N === "confirmation" && A()
2887
+ ] });
2888
+ }
2889
+ function Hl({
2890
+ courses: l = [],
2891
+ categories: a,
2892
+ onCourseClick: i,
2893
+ onEnroll: o,
2894
+ viewMode: p = "grid",
2895
+ allowViewToggle: r = !0,
2896
+ showSearch: m = !0,
2897
+ emptyMessage: s = "No courses found",
2898
+ readOnly: v = !1,
2899
+ isLoading: b,
2900
+ error: h,
2901
+ onRetry: w,
2902
+ pageSize: N,
2903
+ currentPage: C = 1,
2904
+ totalItems: S,
2905
+ onPageChange: c,
2906
+ className: z,
2907
+ style: U
2908
+ }) {
2909
+ const [u, M] = F(""), [x, A] = F(null), [d, y] = F(p), L = B(() => {
2910
+ let n = l;
2911
+ if (x && (n = n.filter((g) => g.categoryUid === x)), u.trim()) {
2912
+ const g = u.toLowerCase();
2913
+ n = n.filter(
2914
+ (R) => {
2915
+ var P, Y;
2916
+ return R.title.toLowerCase().includes(g) || ((P = R.description) == null ? void 0 : P.toLowerCase().includes(g)) || ((Y = R.instructor) == null ? void 0 : Y.displayName.toLowerCase().includes(g));
2917
+ }
2918
+ );
2919
+ }
2920
+ return n;
2921
+ }, [l, x, u]);
2922
+ if (b)
2923
+ return /* @__PURE__ */ t("div", { className: k("space-y-4", z), style: U, children: [
2924
+ /* @__PURE__ */ e(f, { className: "h-9 w-full" }),
2925
+ /* @__PURE__ */ e("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: Array.from({ length: 6 }).map((n, g) => /* @__PURE__ */ e(f, { className: "h-64 w-full rounded-lg" }, g)) })
2926
+ ] });
2927
+ if (h)
2928
+ return /* @__PURE__ */ e("div", { className: k("py-12", z), style: U, children: /* @__PURE__ */ e(
2929
+ $,
2930
+ {
2931
+ icon: /* @__PURE__ */ e(q, { className: "size-10 text-destructive" }),
2932
+ title: "Something went wrong",
2933
+ description: h,
2934
+ action: w ? /* @__PURE__ */ e(D, { variant: "outline", onClick: w, children: "Retry" }) : void 0
2935
+ }
2936
+ ) });
2937
+ const T = c && N ? L.slice((C - 1) * N, C * N) : L;
2938
+ return /* @__PURE__ */ t("div", { className: z, style: U, children: [
2939
+ /* @__PURE__ */ t("div", { className: "flex gap-2 items-center mb-2", children: [
2940
+ m && /* @__PURE__ */ e("div", { className: "flex-1 max-w-80", children: /* @__PURE__ */ e(
2941
+ ut,
2942
+ {
2943
+ value: u,
2944
+ onChange: M,
2945
+ placeholder: "Search courses...",
2946
+ size: "small"
2947
+ }
2948
+ ) }),
2949
+ r && /* @__PURE__ */ t("div", { className: "flex gap-0.5", children: [
2950
+ /* @__PURE__ */ t(se, { children: [
2951
+ /* @__PURE__ */ e(ie, { children: /* @__PURE__ */ e(
2952
+ D,
2953
+ {
2954
+ variant: "ghost",
2955
+ size: "icon-xs",
2956
+ "aria-label": "Grid view",
2957
+ className: k(d === "grid" && "text-primary"),
2958
+ onClick: () => y("grid"),
2959
+ children: /* @__PURE__ */ e(jt, { size: 18 })
2960
+ }
2961
+ ) }),
2962
+ /* @__PURE__ */ e(re, { children: "Grid view" })
2963
+ ] }),
2964
+ /* @__PURE__ */ t(se, { children: [
2965
+ /* @__PURE__ */ e(ie, { children: /* @__PURE__ */ e(
2966
+ D,
2967
+ {
2968
+ variant: "ghost",
2969
+ size: "icon-xs",
2970
+ "aria-label": "List view",
2971
+ className: k(d === "list" && "text-primary"),
2972
+ onClick: () => y("list"),
2973
+ children: /* @__PURE__ */ e(Bt, { size: 18 })
2974
+ }
2975
+ ) }),
2976
+ /* @__PURE__ */ e(re, { children: "List view" })
2977
+ ] })
2978
+ ] })
2979
+ ] }),
2980
+ a && a.length > 0 && /* @__PURE__ */ e(
2981
+ st,
2982
+ {
2983
+ value: x ?? "all",
2984
+ onValueChange: (n) => A(n === "all" ? null : n),
2985
+ className: "mb-2",
2986
+ children: /* @__PURE__ */ t(it, { children: [
2987
+ /* @__PURE__ */ e(ce, { value: "all", children: "All" }),
2988
+ a.map((n) => /* @__PURE__ */ e(ce, { value: n.uid, children: n.label }, n.uid))
2989
+ ] })
2990
+ }
2991
+ ),
2992
+ L.length === 0 ? /* @__PURE__ */ e(
2993
+ $,
2994
+ {
2995
+ icon: /* @__PURE__ */ e(ze, {}),
2996
+ title: s,
2997
+ description: "Try adjusting your search or filter."
2998
+ }
2999
+ ) : d === "grid" ? /* @__PURE__ */ e("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: T.map((n) => /* @__PURE__ */ e(
3000
+ We,
3001
+ {
3002
+ uid: n.uid,
3003
+ title: n.title,
3004
+ description: n.description,
3005
+ thumbnailUrl: n.thumbnailUrl,
3006
+ instructor: n.instructor,
3007
+ progress: n.progress,
3008
+ enrollmentStatus: n.enrollmentStatus,
3009
+ studentCount: n.studentCount,
3010
+ duration: n.duration,
3011
+ layout: "vertical",
3012
+ onClick: v ? void 0 : () => i(n),
3013
+ onEnroll: o && !v ? () => o(n) : void 0,
3014
+ className: k(v && "opacity-70")
3015
+ },
3016
+ n.uid
3017
+ )) }) : /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: T.map((n) => /* @__PURE__ */ e(
3018
+ We,
3019
+ {
3020
+ uid: n.uid,
3021
+ title: n.title,
3022
+ description: n.description,
3023
+ thumbnailUrl: n.thumbnailUrl,
3024
+ instructor: n.instructor,
3025
+ progress: n.progress,
3026
+ enrollmentStatus: n.enrollmentStatus,
3027
+ studentCount: n.studentCount,
3028
+ duration: n.duration,
3029
+ layout: "horizontal",
3030
+ onClick: v ? void 0 : () => i(n),
3031
+ onEnroll: o && !v ? () => o(n) : void 0,
3032
+ className: k(v && "opacity-70")
3033
+ },
3034
+ n.uid
3035
+ )) }),
3036
+ c && N && L.length > 0 && /* @__PURE__ */ e(
3037
+ we,
3038
+ {
3039
+ currentPage: C,
3040
+ totalPages: Math.ceil((S ?? L.length) / N),
3041
+ onPageChange: c,
3042
+ className: "mt-4"
3043
+ }
3044
+ )
3045
+ ] });
3046
+ }
3047
+ function Gl({
3048
+ student: l,
3049
+ enrolledCourses: a = [],
3050
+ achievements: i = [],
3051
+ certificates: o = [],
3052
+ stats: p,
3053
+ showCourses: r = !0,
3054
+ showAchievements: m = !0,
3055
+ onCourseClick: s,
3056
+ onCertificateClick: v,
3057
+ readOnly: b = !1,
3058
+ isLoading: h,
3059
+ error: w,
3060
+ onRetry: N,
3061
+ className: C,
3062
+ style: S
3063
+ }) {
3064
+ const c = a.filter((u) => u.progress >= 100), z = [
3065
+ {
3066
+ label: "Enrolled",
3067
+ value: String(a.length),
3068
+ icon: /* @__PURE__ */ e(me, { size: 24 })
3069
+ },
3070
+ {
3071
+ label: "Completed",
3072
+ value: String(c.length),
3073
+ icon: /* @__PURE__ */ e(ze, { size: 24 })
3074
+ }
3075
+ ], U = p ?? z;
3076
+ return /* @__PURE__ */ e(
3077
+ te,
3078
+ {
3079
+ isLoading: h,
3080
+ error: w,
3081
+ onRetry: N,
3082
+ className: C,
3083
+ style: S,
3084
+ skeleton: /* @__PURE__ */ t(O, { children: [
3085
+ /* @__PURE__ */ e(_, { children: /* @__PURE__ */ t(E, { className: "p-4 flex items-center gap-4", children: [
3086
+ /* @__PURE__ */ e(f, { className: "size-12 rounded-full" }),
3087
+ /* @__PURE__ */ t("div", { className: "flex-1 space-y-2", children: [
3088
+ /* @__PURE__ */ e(f, { className: "h-5 w-40" }),
3089
+ /* @__PURE__ */ e(f, { className: "h-4 w-56" })
3090
+ ] })
3091
+ ] }) }),
3092
+ /* @__PURE__ */ t("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-3", children: [
3093
+ /* @__PURE__ */ e(f, { className: "h-24" }),
3094
+ /* @__PURE__ */ e(f, { className: "h-24" }),
3095
+ /* @__PURE__ */ e(f, { className: "h-24" }),
3096
+ /* @__PURE__ */ e(f, { className: "h-24" })
3097
+ ] }),
3098
+ /* @__PURE__ */ e(f, { className: "h-8 w-full" }),
3099
+ /* @__PURE__ */ e(f, { className: "h-8 w-full" }),
3100
+ /* @__PURE__ */ e(f, { className: "h-8 w-full" })
3101
+ ] }),
3102
+ children: /* @__PURE__ */ t("div", { className: k("space-y-4", C), style: S, children: [
3103
+ /* @__PURE__ */ e(_, { children: /* @__PURE__ */ t(E, { className: "p-4 flex items-start gap-4", children: [
3104
+ /* @__PURE__ */ e(
3105
+ fe,
3106
+ {
3107
+ displayName: l.displayName,
3108
+ avatarUrl: l.avatarUrl,
3109
+ size: "large"
3110
+ }
3111
+ ),
3112
+ /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
3113
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2 flex-wrap", children: [
3114
+ /* @__PURE__ */ e("h2", { className: "text-xl font-bold text-foreground", children: l.displayName }),
3115
+ l.role && /* @__PURE__ */ e(X, { variant: "secondary", children: l.role })
3116
+ ] }),
3117
+ l.email && /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: l.email }),
3118
+ l.bio && /* @__PURE__ */ e("p", { className: "text-sm text-foreground mt-1", children: l.bio }),
3119
+ l.joinedAt && /* @__PURE__ */ t("p", { className: "text-xs text-muted-foreground mt-1 flex items-center gap-1", children: [
3120
+ /* @__PURE__ */ e(Qt, { size: 12 }),
3121
+ "Joined ",
3122
+ new Date(l.joinedAt).toLocaleDateString()
3123
+ ] })
3124
+ ] })
3125
+ ] }) }),
3126
+ /* @__PURE__ */ e("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-3", children: U.map((u) => /* @__PURE__ */ e(
3127
+ Le,
3128
+ {
3129
+ icon: u.icon,
3130
+ label: u.label,
3131
+ value: u.value
3132
+ },
3133
+ u.label
3134
+ )) }),
3135
+ r && /* @__PURE__ */ t(O, { children: [
3136
+ /* @__PURE__ */ e(H, {}),
3137
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2 mb-2", children: [
3138
+ /* @__PURE__ */ e("p", { className: "text-lg font-semibold text-foreground", children: "Enrolled Courses" }),
3139
+ /* @__PURE__ */ e(X, { variant: "secondary", children: a.length })
3140
+ ] }),
3141
+ a.length > 0 ? /* @__PURE__ */ e(_, { children: /* @__PURE__ */ e(E, { className: "p-0 divide-y divide-border", children: a.map((u) => /* @__PURE__ */ t(
3142
+ "div",
3143
+ {
3144
+ className: k(
3145
+ "flex items-center gap-3 px-4 py-3 transition-colors",
3146
+ !b && s && "cursor-pointer hover:bg-muted/50"
3147
+ ),
3148
+ onClick: !b && s ? () => s(u.uid) : void 0,
3149
+ children: [
3150
+ /* @__PURE__ */ e(ot, { value: u.progress, size: 32, strokeWidth: 3 }),
3151
+ /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
3152
+ /* @__PURE__ */ e("p", { className: "text-sm font-medium text-foreground truncate", children: u.title }),
3153
+ u.lastAccessedAt && /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground", children: Me(u.lastAccessedAt) })
3154
+ ] }),
3155
+ /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground whitespace-nowrap", children: [
3156
+ Math.round(u.progress),
3157
+ "%"
3158
+ ] })
3159
+ ]
3160
+ },
3161
+ u.uid
3162
+ )) }) }) : /* @__PURE__ */ e(
3163
+ $,
3164
+ {
3165
+ icon: /* @__PURE__ */ e(me, {}),
3166
+ title: "No courses yet",
3167
+ description: "This student has not enrolled in any courses."
3168
+ }
3169
+ )
3170
+ ] }),
3171
+ m && /* @__PURE__ */ t(O, { children: [
3172
+ /* @__PURE__ */ e(H, {}),
3173
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2 mb-2", children: [
3174
+ /* @__PURE__ */ e("p", { className: "text-lg font-semibold text-foreground", children: "Achievements" }),
3175
+ /* @__PURE__ */ e(X, { variant: "secondary", children: i.length })
3176
+ ] }),
3177
+ i.length > 0 ? /* @__PURE__ */ e("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-2", children: i.map((u) => /* @__PURE__ */ e(
3178
+ mt,
3179
+ {
3180
+ title: u.name,
3181
+ description: u.description,
3182
+ icon: u.iconUrl ? /* @__PURE__ */ e(
3183
+ "img",
3184
+ {
3185
+ src: u.iconUrl,
3186
+ alt: u.name,
3187
+ className: "w-12 h-12"
3188
+ }
3189
+ ) : void 0,
3190
+ earnedDate: u.earnedAt
3191
+ },
3192
+ u.uid
3193
+ )) }) : /* @__PURE__ */ e(
3194
+ $,
3195
+ {
3196
+ icon: /* @__PURE__ */ e(Se, {}),
3197
+ title: "No achievements yet",
3198
+ description: "Achievements will appear here as they are earned."
3199
+ }
3200
+ )
3201
+ ] }),
3202
+ /* @__PURE__ */ e(H, {}),
3203
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2 mb-2", children: [
3204
+ /* @__PURE__ */ e("p", { className: "text-lg font-semibold text-foreground", children: "Certificates" }),
3205
+ /* @__PURE__ */ e(X, { variant: "secondary", children: o.length })
3206
+ ] }),
3207
+ o.length > 0 ? /* @__PURE__ */ e(_, { children: /* @__PURE__ */ e(E, { className: "p-0 divide-y divide-border", children: o.map((u) => /* @__PURE__ */ t(
3208
+ "div",
3209
+ {
3210
+ className: k(
3211
+ "flex items-center gap-3 px-4 py-3 transition-colors",
3212
+ !b && v && "cursor-pointer hover:bg-muted/50"
3213
+ ),
3214
+ onClick: !b && v ? () => v(u.uid) : void 0,
3215
+ children: [
3216
+ /* @__PURE__ */ e("div", { className: "w-9 h-9 rounded-lg bg-primary/10 flex items-center justify-center text-primary", children: /* @__PURE__ */ e(Se, { size: 20 }) }),
3217
+ /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
3218
+ /* @__PURE__ */ e("p", { className: "text-sm font-medium text-foreground truncate", children: u.courseName }),
3219
+ /* @__PURE__ */ t("p", { className: "text-xs text-muted-foreground", children: [
3220
+ "Issued ",
3221
+ new Date(u.issuedAt).toLocaleDateString()
3222
+ ] })
3223
+ ] }),
3224
+ u.certificateUrl && !b && /* @__PURE__ */ e(
3225
+ D,
3226
+ {
3227
+ variant: "outline",
3228
+ size: "sm",
3229
+ onClick: (M) => {
3230
+ M.stopPropagation(), window.open(u.certificateUrl, "_blank");
3231
+ },
3232
+ children: "View"
3233
+ }
3234
+ )
3235
+ ]
3236
+ },
3237
+ u.uid
3238
+ )) }) }) : /* @__PURE__ */ e(
3239
+ $,
3240
+ {
3241
+ icon: /* @__PURE__ */ e(ze, {}),
3242
+ title: "No certificates yet",
3243
+ description: "Certificates will appear here once courses are completed."
3244
+ }
3245
+ )
3246
+ ] })
3247
+ }
3248
+ );
3249
+ }
3250
+ export {
3251
+ Ml as A,
3252
+ jl as C,
3253
+ Fl as D,
3254
+ Vl as E,
3255
+ Al as F,
3256
+ _l as G,
3257
+ zl as L,
3258
+ Rl as P,
3259
+ Sl as Q,
3260
+ Ql as R,
3261
+ te as S,
3262
+ Ll as a,
3263
+ Pl as b,
3264
+ Hl as c,
3265
+ Ul as d,
3266
+ Dl as e,
3267
+ $l as f,
3268
+ Il as g,
3269
+ El as h,
3270
+ Bl as i,
3271
+ Gl as j,
3272
+ Tl as k,
3273
+ pt as l,
3274
+ ll as m
3275
+ };