@hydralms/components 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/dist/StudentProfile-BVfZMbnV.cjs +1 -0
  2. package/dist/StudentProfile-DeMxdrL3.js +3275 -0
  3. package/dist/assessment-toolbar/question-navigator.d.ts +1 -1
  4. package/dist/assessment-toolbar/timer-display.d.ts +1 -1
  5. package/dist/common/index.d.ts +2 -1
  6. package/dist/common/pagination.d.ts +26 -0
  7. package/dist/common/types.d.ts +1 -0
  8. package/dist/components.css +1 -1
  9. package/dist/content/audio-player.d.ts +22 -0
  10. package/dist/content/code-block.d.ts +30 -0
  11. package/dist/content/embed-block.d.ts +28 -0
  12. package/dist/content/index.d.ts +6 -0
  13. package/dist/content/types.d.ts +24 -0
  14. package/dist/curriculum/course-card.d.ts +51 -0
  15. package/dist/curriculum/index.d.ts +2 -0
  16. package/dist/curriculum/types.d.ts +2 -2
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.js +494 -444
  20. package/dist/license/HydraContext.d.ts +16 -0
  21. package/dist/license/ProBadge.d.ts +6 -0
  22. package/dist/license/index.d.ts +7 -0
  23. package/dist/license/tiers.d.ts +3 -0
  24. package/dist/license/useHydraLicense.d.ts +6 -0
  25. package/dist/license/validate.d.ts +13 -0
  26. package/dist/license/withProGate.d.ts +6 -0
  27. package/dist/modules/AssignmentModule/AssignmentModule.d.ts +4 -7
  28. package/dist/modules/AssignmentModule/types.d.ts +5 -1
  29. package/dist/modules/CertificateModule/CertificateModule.d.ts +4 -8
  30. package/dist/modules/CertificateModule/types.d.ts +6 -4
  31. package/dist/modules/CourseCatalogModule/CourseCatalogModule.d.ts +5 -0
  32. package/dist/modules/CourseCatalogModule/types.d.ts +43 -0
  33. package/dist/modules/CoursePlayer/CoursePlayer.d.ts +4 -1
  34. package/dist/modules/DiscussionModule/DiscussionModule.d.ts +4 -7
  35. package/dist/modules/ExamModule/ExamModule.d.ts +4 -7
  36. package/dist/modules/ExamModule/types.d.ts +5 -14
  37. package/dist/modules/FlashcardLab/FlashcardLab.d.ts +4 -1
  38. package/dist/modules/FlashcardLab/types.d.ts +2 -0
  39. package/dist/modules/GradeCenterModule/GradeCenterModule.d.ts +4 -8
  40. package/dist/modules/GradeCenterModule/types.d.ts +2 -0
  41. package/dist/modules/QuizModule/QuizModule.d.ts +4 -1
  42. package/dist/modules/QuizModule/types.d.ts +5 -14
  43. package/dist/modules/StudentDashboardModule/StudentDashboardModule.d.ts +5 -0
  44. package/dist/modules/StudentDashboardModule/types.d.ts +54 -0
  45. package/dist/modules/StudentProfileModule/StudentProfileModule.d.ts +5 -0
  46. package/dist/modules/StudentProfileModule/types.d.ts +43 -0
  47. package/dist/modules/SurveyModule/SurveyModule.d.ts +4 -6
  48. package/dist/modules/SurveyModule/types.d.ts +2 -0
  49. package/dist/modules/_shared/assessment-intro.d.ts +16 -0
  50. package/dist/modules/_shared/assessment-results.d.ts +23 -0
  51. package/dist/modules/_shared/types.d.ts +10 -0
  52. package/dist/modules/_shared/use-timer.d.ts +9 -0
  53. package/dist/modules/index.d.ts +6 -0
  54. package/dist/modules.cjs +1 -1
  55. package/dist/modules.js +1266 -854
  56. package/dist/progress/types.d.ts +2 -0
  57. package/dist/provider/HydraProvider.d.ts +5 -1
  58. package/dist/questions/choice.d.ts +1 -1
  59. package/dist/questions/confidence-indicator.d.ts +37 -0
  60. package/dist/questions/essay.d.ts +1 -1
  61. package/dist/questions/fill-in-the-blank.d.ts +1 -1
  62. package/dist/questions/hotspot.d.ts +1 -1
  63. package/dist/questions/index.d.ts +2 -0
  64. package/dist/questions/inline-choice.d.ts +1 -1
  65. package/dist/questions/matching.d.ts +1 -1
  66. package/dist/questions/multiple-choice.d.ts +1 -1
  67. package/dist/questions/numeric.d.ts +1 -1
  68. package/dist/questions/ordering.d.ts +1 -1
  69. package/dist/questions/question-renderer.d.ts +1 -1
  70. package/dist/questions/scenario.d.ts +1 -1
  71. package/dist/questions/spreadsheet.d.ts +1 -1
  72. package/dist/questions/true-false.d.ts +1 -1
  73. package/dist/sections/AnnouncementFeed/AnnouncementFeed.d.ts +1 -1
  74. package/dist/sections/AnnouncementFeed/types.d.ts +15 -1
  75. package/dist/sections/AssessmentReview/AssessmentReview.d.ts +1 -1
  76. package/dist/sections/AssessmentReview/types.d.ts +6 -0
  77. package/dist/sections/AssignmentSubmission/AssignmentSubmission.d.ts +1 -1
  78. package/dist/sections/AssignmentSubmission/types.d.ts +6 -0
  79. package/dist/sections/CertificateViewer/CertificateViewer.d.ts +1 -1
  80. package/dist/sections/CertificateViewer/certificate-variants.d.ts +42 -0
  81. package/dist/sections/CertificateViewer/types.d.ts +6 -0
  82. package/dist/sections/CourseCatalog/CourseCatalog.d.ts +2 -0
  83. package/dist/sections/CourseCatalog/types.d.ts +80 -0
  84. package/dist/sections/CourseOutline/CourseOutline.d.ts +1 -1
  85. package/dist/sections/CourseOutline/types.d.ts +6 -0
  86. package/dist/sections/DiscussionThread/DiscussionThread.d.ts +1 -1
  87. package/dist/sections/DiscussionThread/types.d.ts +6 -0
  88. package/dist/sections/EnrollmentWizard/EnrollmentWizard.d.ts +2 -0
  89. package/dist/sections/EnrollmentWizard/types.d.ts +66 -0
  90. package/dist/sections/ExamSession/ExamSession.d.ts +1 -1
  91. package/dist/sections/ExamSession/types.d.ts +6 -0
  92. package/dist/sections/FlashcardStudySession/FlashcardStudySession.d.ts +1 -1
  93. package/dist/sections/FlashcardStudySession/types.d.ts +6 -0
  94. package/dist/sections/ForumBoard/ForumBoard.d.ts +1 -1
  95. package/dist/sections/ForumBoard/types.d.ts +14 -0
  96. package/dist/sections/GradebookTable/GradebookTable.d.ts +1 -1
  97. package/dist/sections/GradebookTable/types.d.ts +14 -0
  98. package/dist/sections/LecturePlayer/LecturePlayer.d.ts +1 -1
  99. package/dist/sections/LecturePlayer/types.d.ts +8 -0
  100. package/dist/sections/LessonPage/LessonPage.d.ts +1 -1
  101. package/dist/sections/LessonPage/types.d.ts +6 -0
  102. package/dist/sections/PracticeQuiz/PracticeQuiz.d.ts +1 -1
  103. package/dist/sections/PracticeQuiz/types.d.ts +6 -0
  104. package/dist/sections/ProgressDashboard/ProgressDashboard.d.ts +1 -1
  105. package/dist/sections/ProgressDashboard/types.d.ts +6 -0
  106. package/dist/sections/QuizSession/QuizSession.d.ts +1 -1
  107. package/dist/sections/QuizSession/types.d.ts +6 -0
  108. package/dist/sections/RequirementsChecklist/RequirementsChecklist.d.ts +1 -1
  109. package/dist/sections/RequirementsChecklist/types.d.ts +6 -0
  110. package/dist/sections/ResourceLibrary/ResourceLibrary.d.ts +1 -1
  111. package/dist/sections/ResourceLibrary/types.d.ts +15 -1
  112. package/dist/sections/RubricView/RubricView.d.ts +1 -1
  113. package/dist/sections/RubricView/types.d.ts +6 -0
  114. package/dist/sections/ScrollableQuiz/ScrollableQuiz.d.ts +1 -1
  115. package/dist/sections/ScrollableQuiz/types.d.ts +6 -0
  116. package/dist/sections/StudentProfile/StudentProfile.d.ts +2 -0
  117. package/dist/sections/StudentProfile/types.d.ts +98 -0
  118. package/dist/sections/SurveyForm/SurveyForm.d.ts +1 -1
  119. package/dist/sections/SurveyForm/types.d.ts +6 -0
  120. package/dist/sections/_shared/merge-answers.d.ts +9 -0
  121. package/dist/sections/_shared/section-shell.d.ts +20 -0
  122. package/dist/sections/_shared/use-assessment-session.d.ts +30 -0
  123. package/dist/sections/index.d.ts +6 -0
  124. package/dist/sections.cjs +1 -1
  125. package/dist/sections.js +268 -307
  126. package/dist/tabs-BsfVo2Bl.cjs +173 -0
  127. package/dist/{tabs-Wf3h_Cx3.js → tabs-BuY1iNJE.js} +7532 -6807
  128. package/dist/ui/badge.d.ts +1 -1
  129. package/dist/ui/index.d.ts +2 -0
  130. package/dist/ui/progress.d.ts +1 -1
  131. package/dist/ui/rich-text-editor.d.ts +3 -1
  132. package/dist/ui/toast.d.ts +43 -0
  133. package/dist/utils/debounce.d.ts +5 -1
  134. package/dist/utils/pick-palette-color.d.ts +19 -0
  135. package/dist/video/types.d.ts +15 -0
  136. package/dist/video/video-player.d.ts +1 -1
  137. package/dist/withProGate-BWqcKdPM.js +137 -0
  138. package/dist/withProGate-DX6XqKLp.cjs +1 -0
  139. package/package.json +34 -220
  140. package/src/assessment-toolbar/question-navigator.tsx +10 -5
  141. package/src/assessment-toolbar/timer-display.tsx +4 -3
  142. package/src/assessment-toolbar/use-countdown.ts +1 -1
  143. package/src/common/empty-state.tsx +1 -0
  144. package/src/common/index.ts +2 -0
  145. package/src/common/pagination.tsx +135 -0
  146. package/src/common/search-input.tsx +2 -1
  147. package/src/common/types.ts +2 -0
  148. package/src/content/attachment-list.tsx +2 -0
  149. package/src/content/audio-player.tsx +196 -0
  150. package/src/content/code-block.tsx +113 -0
  151. package/src/content/content-block.tsx +64 -0
  152. package/src/content/embed-block.tsx +78 -0
  153. package/src/content/file-upload-zone.tsx +10 -0
  154. package/src/content/index.ts +6 -0
  155. package/src/content/types.ts +5 -0
  156. package/src/curriculum/course-card.tsx +199 -0
  157. package/src/curriculum/curriculum-item.tsx +3 -3
  158. package/src/curriculum/curriculum-tree.tsx +20 -13
  159. package/src/curriculum/index.ts +2 -0
  160. package/src/curriculum/types.ts +2 -2
  161. package/src/flashcards/flashcard.tsx +28 -8
  162. package/src/index.ts +3 -0
  163. package/src/license/HydraContext.tsx +62 -0
  164. package/src/license/ProBadge.tsx +43 -0
  165. package/src/license/index.ts +7 -0
  166. package/src/license/tiers.ts +24 -0
  167. package/src/license/useHydraLicense.ts +10 -0
  168. package/src/license/validate.ts +90 -0
  169. package/src/license/withProGate.tsx +21 -0
  170. package/src/modules/AssignmentModule/AssignmentModule.tsx +17 -8
  171. package/src/modules/AssignmentModule/types.ts +5 -1
  172. package/src/modules/CertificateModule/CertificateModule.tsx +21 -9
  173. package/src/modules/CertificateModule/types.ts +6 -4
  174. package/src/modules/CourseCatalogModule/CourseCatalogModule.tsx +126 -0
  175. package/src/modules/CourseCatalogModule/types.ts +47 -0
  176. package/src/modules/CoursePlayer/CoursePlayer.tsx +37 -22
  177. package/src/modules/DiscussionModule/DiscussionModule.tsx +57 -22
  178. package/src/modules/ExamModule/ExamModule.tsx +64 -198
  179. package/src/modules/ExamModule/types.ts +5 -14
  180. package/src/modules/FlashcardLab/FlashcardLab.tsx +10 -5
  181. package/src/modules/FlashcardLab/types.ts +2 -0
  182. package/src/modules/GradeCenterModule/GradeCenterModule.tsx +7 -2
  183. package/src/modules/GradeCenterModule/types.ts +2 -0
  184. package/src/modules/QuizModule/QuizModule.tsx +49 -169
  185. package/src/modules/QuizModule/types.ts +5 -15
  186. package/src/modules/StudentDashboardModule/StudentDashboardModule.tsx +117 -0
  187. package/src/modules/StudentDashboardModule/types.ts +56 -0
  188. package/src/modules/StudentProfileModule/StudentProfileModule.tsx +289 -0
  189. package/src/modules/StudentProfileModule/types.ts +45 -0
  190. package/src/modules/SurveyModule/SurveyModule.tsx +9 -4
  191. package/src/modules/SurveyModule/types.ts +2 -0
  192. package/src/modules/_shared/assessment-intro.tsx +75 -0
  193. package/src/modules/_shared/assessment-results.tsx +133 -0
  194. package/src/modules/_shared/types.ts +11 -0
  195. package/src/modules/_shared/use-timer.ts +49 -0
  196. package/src/modules/index.ts +9 -0
  197. package/src/progress/achievement-badge.tsx +3 -3
  198. package/src/progress/grade-indicator.tsx +9 -1
  199. package/src/progress/progress-ring.tsx +2 -1
  200. package/src/progress/stat-card.tsx +8 -1
  201. package/src/progress/types.ts +2 -0
  202. package/src/provider/HydraProvider.tsx +15 -6
  203. package/src/questions/choice.tsx +13 -6
  204. package/src/questions/confidence-indicator.tsx +107 -0
  205. package/src/questions/essay.tsx +6 -4
  206. package/src/questions/fill-in-the-blank.tsx +8 -4
  207. package/src/questions/hotspot.tsx +4 -4
  208. package/src/questions/index.ts +2 -0
  209. package/src/questions/inline-choice.tsx +5 -4
  210. package/src/questions/matching.tsx +5 -4
  211. package/src/questions/multiple-choice.tsx +13 -6
  212. package/src/questions/numeric.tsx +8 -4
  213. package/src/questions/ordering.tsx +12 -4
  214. package/src/questions/question-renderer.tsx +3 -2
  215. package/src/questions/scenario.tsx +4 -4
  216. package/src/questions/spreadsheet.tsx +5 -4
  217. package/src/questions/true-false.tsx +13 -6
  218. package/src/sections/AnnouncementFeed/AnnouncementFeed.tsx +64 -8
  219. package/src/sections/AnnouncementFeed/types.ts +15 -1
  220. package/src/sections/AssessmentReview/AssessmentReview.tsx +37 -0
  221. package/src/sections/AssessmentReview/types.ts +6 -0
  222. package/src/sections/AssignmentSubmission/AssignmentSubmission.tsx +37 -1
  223. package/src/sections/AssignmentSubmission/types.ts +6 -0
  224. package/src/sections/CertificateViewer/CertificateViewer.tsx +29 -227
  225. package/src/sections/CertificateViewer/certificate-variants.tsx +170 -0
  226. package/src/sections/CertificateViewer/types.ts +6 -0
  227. package/src/sections/CourseCatalog/CourseCatalog.tsx +220 -0
  228. package/src/sections/CourseCatalog/types.ts +76 -0
  229. package/src/sections/CourseOutline/CourseOutline.tsx +41 -0
  230. package/src/sections/CourseOutline/types.ts +6 -0
  231. package/src/sections/DiscussionThread/DiscussionThread.tsx +42 -1
  232. package/src/sections/DiscussionThread/types.ts +6 -0
  233. package/src/sections/EnrollmentWizard/EnrollmentWizard.tsx +343 -0
  234. package/src/sections/EnrollmentWizard/types.ts +65 -0
  235. package/src/sections/ExamSession/ExamSession.tsx +100 -94
  236. package/src/sections/ExamSession/types.ts +6 -0
  237. package/src/sections/FlashcardStudySession/FlashcardStudySession.tsx +53 -36
  238. package/src/sections/FlashcardStudySession/types.ts +6 -0
  239. package/src/sections/ForumBoard/ForumBoard.tsx +59 -1
  240. package/src/sections/ForumBoard/types.ts +14 -0
  241. package/src/sections/GradebookTable/GradebookTable.tsx +54 -1
  242. package/src/sections/GradebookTable/types.ts +14 -0
  243. package/src/sections/LecturePlayer/LecturePlayer.tsx +63 -37
  244. package/src/sections/LecturePlayer/types.ts +8 -0
  245. package/src/sections/LessonPage/LessonPage.tsx +36 -5
  246. package/src/sections/LessonPage/types.ts +6 -0
  247. package/src/sections/PracticeQuiz/PracticeQuiz.tsx +106 -74
  248. package/src/sections/PracticeQuiz/types.ts +6 -0
  249. package/src/sections/ProgressDashboard/ProgressDashboard.tsx +64 -10
  250. package/src/sections/ProgressDashboard/types.ts +6 -0
  251. package/src/sections/QuizSession/QuizSession.tsx +71 -82
  252. package/src/sections/QuizSession/types.ts +6 -0
  253. package/src/sections/RequirementsChecklist/RequirementsChecklist.tsx +41 -1
  254. package/src/sections/RequirementsChecklist/types.ts +6 -0
  255. package/src/sections/ResourceLibrary/ResourceLibrary.tsx +64 -8
  256. package/src/sections/ResourceLibrary/types.ts +15 -1
  257. package/src/sections/RubricView/RubricView.tsx +37 -1
  258. package/src/sections/RubricView/types.ts +6 -0
  259. package/src/sections/ScrollableQuiz/ScrollableQuiz.tsx +36 -15
  260. package/src/sections/ScrollableQuiz/types.ts +6 -0
  261. package/src/sections/StudentProfile/StudentProfile.tsx +279 -0
  262. package/src/sections/StudentProfile/types.ts +99 -0
  263. package/src/sections/SurveyForm/SurveyForm.tsx +32 -5
  264. package/src/sections/SurveyForm/types.ts +6 -0
  265. package/src/sections/_shared/merge-answers.ts +22 -0
  266. package/src/sections/_shared/section-shell.tsx +64 -0
  267. package/src/sections/_shared/use-assessment-session.ts +125 -0
  268. package/src/sections/index.ts +22 -0
  269. package/src/social/user-avatar.tsx +9 -5
  270. package/src/styles/globals.css +39 -41
  271. package/src/ui/badge.tsx +8 -0
  272. package/src/ui/index.ts +2 -0
  273. package/src/ui/progress.tsx +4 -0
  274. package/src/ui/rich-text-editor.tsx +10 -0
  275. package/src/ui/rich-text-toolbar.tsx +2 -1
  276. package/src/ui/toast.tsx +170 -0
  277. package/src/utils/debounce.ts +8 -2
  278. package/src/utils/pick-palette-color.ts +33 -0
  279. package/src/video/types.ts +16 -0
  280. package/src/video/video-player.tsx +13 -1
  281. package/dist/ForumBoard-CHXU3mjC.js +0 -2207
  282. package/dist/ForumBoard-d1w5-r6n.cjs +0 -1
  283. package/dist/tabs-DRM2Iq_J.cjs +0 -172
@@ -33,6 +33,12 @@ export interface LessonPageProps {
33
33
  showDuration?: boolean;
34
34
  /** When true, disables interactive elements */
35
35
  readOnly?: boolean;
36
+ /** Render skeleton placeholders instead of content */
37
+ isLoading?: boolean;
38
+ /** Error message — renders an error state with optional retry */
39
+ error?: string | null;
40
+ /** Called when the user clicks retry in the error state */
41
+ onRetry?: () => void;
36
42
  /** CSS class name for the root element */
37
43
  className?: string;
38
44
  /** Inline styles for the root element */
@@ -1,2 +1,2 @@
1
1
  import { PracticeQuizProps } from './types';
2
- export declare function PracticeQuiz({ questions: questionsProp, instantFeedback, allowRetry, onComplete, shuffled, readOnly, className, style, }: PracticeQuizProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function PracticeQuiz({ questions: questionsProp, instantFeedback, allowRetry, onComplete, shuffled, readOnly, isLoading, error, onRetry, className, style, }: PracticeQuizProps): import("react/jsx-runtime").JSX.Element;
@@ -27,6 +27,12 @@ export interface PracticeQuizProps {
27
27
  shuffled?: boolean;
28
28
  /** When true, all inputs are disabled */
29
29
  readOnly?: boolean;
30
+ /** Render skeleton placeholders instead of content */
31
+ isLoading?: boolean;
32
+ /** Error message — renders an error state with optional retry */
33
+ error?: string | null;
34
+ /** Called when the user clicks retry in the error state */
35
+ onRetry?: () => void;
30
36
  /** CSS class name for the root element */
31
37
  className?: string;
32
38
  /** Inline styles for the root element */
@@ -1,2 +1,2 @@
1
1
  import { ProgressDashboardProps } from './types';
2
- export declare function ProgressDashboard({ overallProgress, totalTimeSpent, modules, recentActivity, streak, achievements, recentActivityLimit, onModuleClick, className, style, }: ProgressDashboardProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function ProgressDashboard({ overallProgress, totalTimeSpent, modules, recentActivity, streak, achievements, recentActivityLimit, onModuleClick, isLoading, error, onRetry, className, style, }: ProgressDashboardProps): import("react/jsx-runtime").JSX.Element;
@@ -32,6 +32,12 @@ export interface ProgressDashboardProps {
32
32
  recentActivityLimit?: number;
33
33
  /** Called when the user clicks a module */
34
34
  onModuleClick?: (moduleUid: string) => void;
35
+ /** Render skeleton placeholders instead of content */
36
+ isLoading?: boolean;
37
+ /** Error message — renders an error state with optional retry */
38
+ error?: string | null;
39
+ /** Called when the user clicks retry in the error state */
40
+ onRetry?: () => void;
35
41
  /** CSS class name for the root element */
36
42
  className?: string;
37
43
  /** Inline styles for the root element */
@@ -1,2 +1,2 @@
1
1
  import { QuizSessionProps } from './types';
2
- export declare function QuizSession({ questions, initialAnswers, onSubmit, onAnswerChange, timeElapsedSeconds, timeLimitSeconds, questionMaterials, isSubmitting, readOnly, className, style, }: QuizSessionProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function QuizSession({ questions, initialAnswers, onSubmit, onAnswerChange, timeElapsedSeconds, timeLimitSeconds, questionMaterials, isSubmitting, readOnly, isLoading, error, onRetry, className, style, }: QuizSessionProps): import("react/jsx-runtime").JSX.Element;
@@ -44,6 +44,12 @@ export interface QuizSessionProps {
44
44
  questionMaterials?: QuestionMaterial[];
45
45
  /** When true, all inputs are disabled (e.g. after submission) */
46
46
  readOnly?: boolean;
47
+ /** Render skeleton placeholders instead of content */
48
+ isLoading?: boolean;
49
+ /** Error message — renders an error state with optional retry */
50
+ error?: string | null;
51
+ /** Called when the user clicks retry in the error state */
52
+ onRetry?: () => void;
47
53
  /** CSS class name for the root element */
48
54
  className?: string;
49
55
  /** Inline styles for the root element */
@@ -5,4 +5,4 @@ import { RequirementsChecklistProps } from './types';
5
5
  * Displays a vertical list of requirements with an overall progress bar.
6
6
  * Incomplete items can be clicked to navigate to the relevant content.
7
7
  */
8
- export declare function RequirementsChecklist({ title, requirements, onRequirementClick, className, style, }: RequirementsChecklistProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare function RequirementsChecklist({ title, requirements, onRequirementClick, isLoading, error, onRetry, className, style, }: RequirementsChecklistProps): import("react/jsx-runtime").JSX.Element;
@@ -18,6 +18,12 @@ export interface RequirementsChecklistProps {
18
18
  requirements: Requirement[];
19
19
  /** Called when the user clicks an incomplete requirement */
20
20
  onRequirementClick?: (uid: string) => void;
21
+ /** Render skeleton placeholders instead of content */
22
+ isLoading?: boolean;
23
+ /** Error message — renders an error state with optional retry */
24
+ error?: string | null;
25
+ /** Called when the user clicks retry in the error state */
26
+ onRetry?: () => void;
21
27
  /** CSS class name for the root element */
22
28
  className?: string;
23
29
  /** Inline styles for the root element */
@@ -1,2 +1,2 @@
1
1
  import { ResourceLibraryProps } from './types';
2
- export declare function ResourceLibrary({ resources, categories, onResourceClick, onDownload, viewMode: initialViewMode, allowViewToggle, showSearch, emptyMessage, readOnly, className, style, }: ResourceLibraryProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function ResourceLibrary({ resources, categories, onResourceClick, onDownload, viewMode: initialViewMode, allowViewToggle, showSearch, emptyMessage, readOnly, isLoading, error, onRetry, pageSize, currentPage, totalItems, onPageChange, className, style, }: ResourceLibraryProps): import("react/jsx-runtime").JSX.Element;
@@ -20,7 +20,7 @@ export interface ResourceLibraryProps {
20
20
  label: string;
21
21
  }[];
22
22
  /** Called when the user clicks a resource */
23
- onResourceClick: (resource: Resource) => void;
23
+ onResourceClick?: (resource: Resource) => void;
24
24
  /** Called when the user downloads a resource */
25
25
  onDownload?: (resource: Resource) => void;
26
26
  /** Layout view mode */
@@ -33,6 +33,20 @@ export interface ResourceLibraryProps {
33
33
  emptyMessage?: string;
34
34
  /** When true, disables interactions */
35
35
  readOnly?: boolean;
36
+ /** Render skeleton placeholders instead of content */
37
+ isLoading?: boolean;
38
+ /** Error message — renders an error state with optional retry */
39
+ error?: string | null;
40
+ /** Called when the user clicks retry in the error state */
41
+ onRetry?: () => void;
42
+ /** Number of items per page (enables pagination when set with onPageChange) */
43
+ pageSize?: number;
44
+ /** Current page (1-indexed) */
45
+ currentPage?: number;
46
+ /** Total number of items (for server-side pagination) */
47
+ totalItems?: number;
48
+ /** Called when the user navigates to a different page */
49
+ onPageChange?: (page: number) => void;
36
50
  /** CSS class name for the root element */
37
51
  className?: string;
38
52
  /** Inline styles for the root element */
@@ -6,4 +6,4 @@ import { RubricViewProps } from './types';
6
6
  * shows an overall score. Useful inside AssignmentModule for showing grading criteria
7
7
  * and results.
8
8
  */
9
- export declare function RubricView({ criteria, selectedLevels, totalScore, maxScore, feedback, className, style, }: RubricViewProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function RubricView({ criteria, selectedLevels, totalScore, maxScore, feedback, isLoading, error, onRetry, className, style, }: RubricViewProps): import("react/jsx-runtime").JSX.Element;
@@ -23,6 +23,12 @@ export interface RubricViewProps {
23
23
  maxScore?: number;
24
24
  /** Instructor feedback text */
25
25
  feedback?: string;
26
+ /** Render skeleton placeholders instead of content */
27
+ isLoading?: boolean;
28
+ /** Error message — renders an error state with optional retry */
29
+ error?: string | null;
30
+ /** Called when the user clicks retry in the error state */
31
+ onRetry?: () => void;
26
32
  /** CSS class name for the root element */
27
33
  className?: string;
28
34
  /** Inline styles for the root element */
@@ -1,2 +1,2 @@
1
1
  import { ScrollableQuizProps } from './types';
2
- export declare function ScrollableQuiz({ questions, initialAnswers, onSubmit, onAnswerChange, showNavigator, showQuestionNumbers, questionGroups, isSubmitting, readOnly, className, style, }: ScrollableQuizProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function ScrollableQuiz({ questions, initialAnswers, onSubmit, onAnswerChange, showNavigator, showQuestionNumbers, questionGroups, isSubmitting, readOnly, isLoading, error, onRetry, className, style, }: ScrollableQuizProps): import("react/jsx-runtime").JSX.Element;
@@ -35,6 +35,12 @@ export interface ScrollableQuizProps {
35
35
  isSubmitting?: boolean;
36
36
  /** When true, all inputs are disabled */
37
37
  readOnly?: boolean;
38
+ /** Render skeleton placeholders instead of content */
39
+ isLoading?: boolean;
40
+ /** Error message — renders an error state with optional retry */
41
+ error?: string | null;
42
+ /** Called when the user clicks retry in the error state */
43
+ onRetry?: () => void;
38
44
  /** CSS class name for the root element */
39
45
  className?: string;
40
46
  /** Inline styles for the root element */
@@ -0,0 +1,2 @@
1
+ import { StudentProfileProps } from './types';
2
+ export declare function StudentProfile({ student, enrolledCourses, achievements, certificates, stats, showCourses, showAchievements, onCourseClick, onCertificateClick, readOnly, isLoading, error, onRetry, className, style, }: StudentProfileProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * StudentProfile section — a student profile overview.
3
+ *
4
+ * Displays student info header, stat cards, enrolled courses list,
5
+ * achievements grid, and certificates list.
6
+ *
7
+ * @example
8
+ * <StudentProfile
9
+ * student={{ uid: "s1", displayName: "Jane Doe", email: "jane@example.com" }}
10
+ * enrolledCourses={courses}
11
+ * achievements={badges}
12
+ * onCourseClick={(uid) => navigate(`/courses/${uid}`)}
13
+ * />
14
+ */
15
+ export interface StudentProfileProps {
16
+ /** Student information */
17
+ student: StudentInfo;
18
+ /** Enrolled courses */
19
+ enrolledCourses?: EnrolledCourse[];
20
+ /** Earned achievements */
21
+ achievements?: ProfileAchievement[];
22
+ /** Earned certificates */
23
+ certificates?: ProfileCertificate[];
24
+ /** Custom stat cards to display */
25
+ stats?: {
26
+ label: string;
27
+ value: string;
28
+ icon?: React.ReactNode;
29
+ }[];
30
+ /** When false, hides the Enrolled Courses section. @default true */
31
+ showCourses?: boolean;
32
+ /** When false, hides the Achievements section. @default true */
33
+ showAchievements?: boolean;
34
+ /** Called when a course is clicked */
35
+ onCourseClick?: (courseUid: string) => void;
36
+ /** Called when a certificate is clicked */
37
+ onCertificateClick?: (certificateUid: string) => void;
38
+ /** When true, disables interactions */
39
+ readOnly?: boolean;
40
+ /** Render skeleton placeholders instead of content */
41
+ isLoading?: boolean;
42
+ /** Error message — renders an error state with optional retry */
43
+ error?: string | null;
44
+ /** Called when the user clicks retry in the error state */
45
+ onRetry?: () => void;
46
+ /** CSS class name for the root element */
47
+ className?: string;
48
+ /** Inline styles for the root element */
49
+ style?: React.CSSProperties;
50
+ }
51
+ export interface StudentInfo {
52
+ /** Unique identifier */
53
+ uid: string;
54
+ /** Display name */
55
+ displayName: string;
56
+ /** Avatar URL */
57
+ avatarUrl?: string;
58
+ /** Email address */
59
+ email?: string;
60
+ /** Short bio */
61
+ bio?: string;
62
+ /** Join date as ISO string */
63
+ joinedAt?: string;
64
+ /** Role label */
65
+ role?: string;
66
+ }
67
+ export interface EnrolledCourse {
68
+ /** Course UID */
69
+ uid: string;
70
+ /** Course title */
71
+ title: string;
72
+ /** Progress percentage (0-100) */
73
+ progress: number;
74
+ /** Last accessed as ISO string */
75
+ lastAccessedAt?: string;
76
+ }
77
+ export interface ProfileAchievement {
78
+ /** Unique identifier */
79
+ uid: string;
80
+ /** Achievement name */
81
+ name: string;
82
+ /** Achievement description */
83
+ description: string;
84
+ /** Icon URL */
85
+ iconUrl?: string;
86
+ /** Date earned as ISO string */
87
+ earnedAt: string;
88
+ }
89
+ export interface ProfileCertificate {
90
+ /** Unique identifier */
91
+ uid: string;
92
+ /** Course name */
93
+ courseName: string;
94
+ /** Date issued as ISO string */
95
+ issuedAt: string;
96
+ /** Certificate URL */
97
+ certificateUrl?: string;
98
+ }
@@ -1,2 +1,2 @@
1
1
  import { SurveyFormProps } from './types';
2
- export declare function SurveyForm({ title, description, questions, initialAnswers, onSubmit, onAnswerChange, showProgress, requireAll, submitLabel, isSubmitting, readOnly, className, style, }: SurveyFormProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function SurveyForm({ title, description, questions, initialAnswers, onSubmit, onAnswerChange, showProgress, requireAll, submitLabel, isSubmitting, readOnly, isLoading, error, onRetry, className, style, }: SurveyFormProps): import("react/jsx-runtime").JSX.Element;
@@ -37,6 +37,12 @@ export interface SurveyFormProps {
37
37
  isSubmitting?: boolean;
38
38
  /** When true, all inputs are disabled */
39
39
  readOnly?: boolean;
40
+ /** Render skeleton placeholders instead of content */
41
+ isLoading?: boolean;
42
+ /** Error message — renders an error state with optional retry */
43
+ error?: string | null;
44
+ /** Called when the user clicks retry in the error state */
45
+ onRetry?: () => void;
40
46
  /** CSS class name for the root element */
41
47
  className?: string;
42
48
  /** Inline styles for the root element */
@@ -0,0 +1,9 @@
1
+ import { SessionAnswer } from '../../questions/types';
2
+ /**
3
+ * Replaces all existing answers for `questionUid` with `rawAnswers`,
4
+ * then invokes an optional change callback with the merged array.
5
+ */
6
+ export declare function mergeSessionAnswers(prev: SessionAnswer[], questionUid: string, rawAnswers: {
7
+ uid: string;
8
+ content?: string;
9
+ }[], onChange?: (merged: SessionAnswer[]) => void): SessionAnswer[];
@@ -0,0 +1,20 @@
1
+ import { ReactNode } from 'react';
2
+ export interface SectionShellProps {
3
+ isLoading?: boolean;
4
+ error?: string | null;
5
+ onRetry?: () => void;
6
+ /** Skeleton placeholder rendered when `isLoading` is true. */
7
+ skeleton?: ReactNode;
8
+ /** Extra class merged into the loading wrapper (default `"space-y-4"`). */
9
+ loadingClassName?: string;
10
+ className?: string;
11
+ style?: React.CSSProperties;
12
+ children: ReactNode;
13
+ }
14
+ /**
15
+ * Shared wrapper that handles loading skeleton and error states
16
+ * so individual sections don't repeat the same early-return blocks.
17
+ *
18
+ * When neither loading nor error, renders children directly (no extra wrapper).
19
+ */
20
+ export declare function SectionShell({ isLoading, error, onRetry, skeleton, loadingClassName, className, style, children, }: SectionShellProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,30 @@
1
+ import { QuestionNavigatorItem } from '../../assessment-toolbar/types';
2
+ import { QuestionData, QuestionMaterial, SessionAnswer } from '../../questions/types';
3
+ export interface UseAssessmentSessionOptions {
4
+ questions: QuestionData[];
5
+ initialAnswers?: SessionAnswer[];
6
+ onAnswerChange?: (answers: SessionAnswer[]) => void;
7
+ questionMaterials?: QuestionMaterial[];
8
+ }
9
+ export declare function useAssessmentSession({ questions, initialAnswers, onAnswerChange, questionMaterials, }: UseAssessmentSessionOptions): {
10
+ currentIndex: number;
11
+ currentQuestion: QuestionData;
12
+ sessionAnswers: SessionAnswer[];
13
+ flaggedUids: Set<string>;
14
+ materialsOpen: boolean;
15
+ setMaterialsOpen: import('react').Dispatch<import('react').SetStateAction<boolean>>;
16
+ questionAreaRef: import('react').RefObject<HTMLDivElement | null>;
17
+ currentQuestionAnswers: SessionAnswer[];
18
+ currentMaterials: QuestionMaterial[];
19
+ navigatorItems: QuestionNavigatorItem[];
20
+ handleAnswer: (rawAnswers: {
21
+ uid: string;
22
+ content?: string;
23
+ }[]) => void;
24
+ handleNavigate: (uid: string) => void;
25
+ handleToggleFlag: (uid: string) => void;
26
+ goNext: () => void;
27
+ goPrevious: () => void;
28
+ hasNext: boolean;
29
+ hasPrevious: boolean;
30
+ };
@@ -38,3 +38,9 @@ export { RequirementsChecklist } from './RequirementsChecklist/RequirementsCheck
38
38
  export type { RequirementsChecklistProps, Requirement, } from './RequirementsChecklist/types';
39
39
  export { ForumBoard } from './ForumBoard/ForumBoard';
40
40
  export type { ForumBoardProps, ForumTopic, ForumSortOrder } from './ForumBoard/types';
41
+ export { EnrollmentWizard } from './EnrollmentWizard/EnrollmentWizard';
42
+ export type { EnrollmentWizardProps, EnrollmentCourse, Prerequisite, } from './EnrollmentWizard/types';
43
+ export { CourseCatalog } from './CourseCatalog/CourseCatalog';
44
+ export type { CourseCatalogProps, CourseInfo, } from './CourseCatalog/types';
45
+ export { StudentProfile } from './StudentProfile/StudentProfile';
46
+ export type { StudentProfileProps, StudentInfo, EnrolledCourse, ProfileAchievement, ProfileCertificate, } from './StudentProfile/types';
package/dist/sections.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./ForumBoard-d1w5-r6n.cjs"),e=require("react/jsx-runtime"),u=require("react"),s=require("./tabs-DRM2Iq_J.cjs"),L=require("lucide-react");function E({questions:a,initialAnswers:h=[],onSubmit:j,onAnswerChange:b,showNavigator:C=!0,showQuestionNumbers:T=!0,questionGroups:g,isSubmitting:N=!1,readOnly:p=!1,className:z,style:k}){var U;const[f,w]=u.useState(h),[i,m]=u.useState(((U=a[0])==null?void 0:U.uid)??null),o=u.useRef(new Map),x=u.useMemo(()=>{const n=new Map;for(const r of f){const l=n.get(r.uid);l?l.push(r):n.set(r.uid,[r])}return n},[f]),P=u.useMemo(()=>a.filter(n=>x.has(n.uid)).length,[a,x]);u.useEffect(()=>{const n=new IntersectionObserver(r=>{for(const l of r)l.isIntersecting&&m(l.target.getAttribute("data-question-uid"))},{rootMargin:"-20% 0px -60% 0px"});return o.current.forEach(r=>n.observe(r)),()=>n.disconnect()},[a]);const Q=u.useCallback((n,r)=>{r?o.current.set(n,r):o.current.delete(n)},[]);function t(n,r){const l=r.map(c=>({uid:n,answerUid:c.uid,content:c.content}));w(c=>{const R=[...c.filter(F=>F.uid!==n),...l];return b==null||b(R),R})}function v(n){var r;(r=o.current.get(n))==null||r.scrollIntoView({behavior:"smooth",block:"center"})}const y=u.useMemo(()=>{if(!g)return[{label:null,questions:a}];const n=g.map(c=>({label:c.label,questions:c.questionUids.map(S=>a.find(R=>R.uid===S)).filter(Boolean)})),r=new Set(g.flatMap(c=>c.questionUids)),l=a.filter(c=>!r.has(c.uid));return l.length>0&&n.push({label:null,questions:l}),n},[a,g]);let A=0;return e.jsxs("div",{className:s.cn("flex gap-3",z),style:k,children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[y.map((n,r)=>e.jsxs("div",{children:[n.label&&e.jsx("p",{className:s.cn("text-lg font-semibold mb-2 text-foreground",r>0&&"mt-4"),children:n.label}),n.questions.map(l=>{const c=A++;return e.jsx(s.Card,{ref:S=>Q(l.uid,S),"data-question-uid":l.uid,className:"mb-2",children:e.jsxs(s.CardContent,{className:"pt-6",children:[T&&e.jsxs("p",{className:"font-semibold text-sm text-muted-foreground mb-1",children:["Question ",c+1]}),e.jsx(s.QuestionRenderer,{question:l,sessionAnswers:x.get(l.uid)??[],onAnswer:S=>t(l.uid,S),readOnly:p})]})},l.uid)})]},n.label??`ungrouped-${r}`)),e.jsx(s.Separator,{className:"my-3"}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[P," of ",a.length," answered"]}),e.jsx(s.Button,{onClick:()=>j(f),disabled:N||p,children:N?"Submitting...":"Submit"})]})]}),C&&e.jsx(s.Card,{className:"hidden md:block w-50 shrink-0 sticky top-4 self-start",children:e.jsxs(s.CardContent,{className:"p-3",children:[e.jsx("p",{className:"font-semibold text-sm mb-1 text-foreground",children:"Questions"}),e.jsx("div",{className:"flex flex-wrap gap-1",children:a.map((n,r)=>{const l=x.has(n.uid),c=i===n.uid;return e.jsx("button",{type:"button",className:s.cn("inline-flex items-center justify-center text-xs font-medium min-w-9 px-1 py-0.5 rounded-full cursor-pointer border transition-colors",c?"bg-primary border-primary text-primary-foreground":l?"border-success text-success bg-transparent":"border-border text-foreground bg-transparent hover:bg-muted"),onClick:()=>v(n.uid),children:r+1},n.uid)})})]})})]})}const B={pdf:"document",document:"document",video:"video",link:"link",image:"document",archive:"document",other:"document"};function I({resources:a,categories:h,onResourceClick:j,onDownload:b,viewMode:C="list",allowViewToggle:T=!0,showSearch:g=!0,emptyMessage:N="No resources found",readOnly:p=!1,className:z,style:k}){const[f,w]=u.useState(""),[i,m]=u.useState(null),[o,x]=u.useState(C),P=u.useMemo(()=>{let t=a;if(i&&(t=t.filter(v=>v.categoryUid===i)),f.trim()){const v=f.toLowerCase();t=t.filter(y=>{var A;return y.name.toLowerCase().includes(v)||((A=y.description)==null?void 0:A.toLowerCase().includes(v))})}return t},[a,i,f]);function Q(t){const v=B[t.type]??"document";return e.jsxs("div",{className:s.cn("flex items-center gap-3 px-3 py-2",!p&&"cursor-pointer hover:bg-muted",p&&"opacity-70"),onClick:()=>!p&&j(t),children:[e.jsx("div",{className:"min-w-10",children:e.jsx(s.LearningObjectIcon,{type:v,size:20})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("span",{className:"text-sm text-foreground",children:t.name}),(t.description||t.fileSize!=null)&&e.jsx("span",{className:"block text-xs text-muted-foreground",children:[t.description,t.fileSize!=null&&s.formatFileSize(t.fileSize)].filter(Boolean).join(" · ")})]}),b&&e.jsxs(s.Tooltip,{children:[e.jsx(s.TooltipTrigger,{children:e.jsx(s.Button,{variant:"ghost",size:"icon-xs","aria-label":"Download",onClick:y=>{y.stopPropagation(),b(t)},children:e.jsx(L.Download,{size:16})})}),e.jsx(s.TooltipContent,{children:"Download"})]})]},t.uid)}return e.jsxs("div",{className:z,style:k,children:[e.jsxs("div",{className:"flex gap-2 items-center mb-2",children:[g&&e.jsx("div",{className:"flex-1 max-w-80",children:e.jsx(s.SearchInput,{value:f,onChange:w,placeholder:"Search resources...",size:"small"})}),T&&e.jsxs("div",{className:"flex gap-0.5",children:[e.jsxs(s.Tooltip,{children:[e.jsx(s.TooltipTrigger,{children:e.jsx(s.Button,{variant:"ghost",size:"icon-xs","aria-label":"List view",className:s.cn(o==="list"&&"text-primary"),onClick:()=>x("list"),children:e.jsx(L.List,{size:18})})}),e.jsx(s.TooltipContent,{children:"List view"})]}),e.jsxs(s.Tooltip,{children:[e.jsx(s.TooltipTrigger,{children:e.jsx(s.Button,{variant:"ghost",size:"icon-xs","aria-label":"Grid view",className:s.cn(o==="grid"&&"text-primary"),onClick:()=>x("grid"),children:e.jsx(L.Grid,{size:18})})}),e.jsx(s.TooltipContent,{children:"Grid view"})]})]})]}),h&&h.length>0&&e.jsx(s.Tabs,{value:i??"all",onValueChange:t=>m(t==="all"?null:t),className:"mb-2",children:e.jsxs(s.TabsList,{children:[e.jsx(s.TabsTrigger,{value:"all",children:"All"}),h.map(t=>e.jsx(s.TabsTrigger,{value:t.uid,children:t.label},t.uid))]})}),P.length===0?e.jsx(s.EmptyState,{title:N,description:"Try adjusting your search or filter."}):o==="list"?e.jsx(s.Card,{children:P.map(Q)}):e.jsx("div",{className:"grid grid-cols-[repeat(auto-fill,minmax(240px,1fr))] gap-2",children:P.map(t=>e.jsx(s.Card,{className:s.cn("transition-colors",!p&&"cursor-pointer hover:border-primary"),onClick:()=>!p&&j(t),children:e.jsxs(s.CardContent,{className:"pt-4 pb-4",children:[e.jsxs("div",{className:"flex gap-1 items-center mb-1",children:[e.jsx(s.LearningObjectIcon,{type:B[t.type]??"document",size:20}),e.jsx("span",{className:"font-semibold text-sm text-foreground truncate",children:t.name})]}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground mb-1 truncate",children:t.description}),t.fileSize!=null&&e.jsx("span",{className:"text-xs text-muted-foreground",children:s.formatFileSize(t.fileSize)})]})},t.uid))})]})}function M({announcements:a,onMarkRead:h,onSelect:j,showAvatars:b=!0,previewLines:C=3,emptyMessage:T="No announcements yet",readOnly:g=!1,className:N,style:p}){const[z,k]=u.useState(new Set),f=u.useMemo(()=>{const i=a.filter(o=>o.isPinned),m=a.filter(o=>!o.isPinned);return[...i,...m]},[a]);function w(i){k(o=>{const x=new Set(o);return x.has(i)?x.delete(i):x.add(i),x});const m=a.find(o=>o.uid===i);m&&!m.isRead&&(h==null||h(i))}return f.length===0?e.jsx("div",{className:N,style:p,children:e.jsx(s.EmptyState,{title:T})}):e.jsx("div",{className:s.cn("flex flex-col gap-2",N),style:p,children:f.map(i=>{const m=z.has(i.uid);return e.jsx(s.Card,{className:s.cn(i.isRead&&"opacity-85",j&&"cursor-pointer",i.isPinned&&"border-l-4 border-l-warning"),onClick:()=>j&&!g?j(i):w(i.uid),children:e.jsx(s.CardContent,{className:"py-4",children:e.jsxs("div",{className:"flex gap-1.5 items-start",children:[b&&e.jsx(s.UserAvatar,{displayName:i.author.displayName,avatarUrl:i.author.avatarUrl,role:i.author.role,size:"medium"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1 mb-0.5",children:[i.isPinned&&e.jsx(L.Pin,{size:14}),e.jsx("span",{className:s.cn("text-foreground",i.isRead?"font-normal":"font-semibold"),children:i.title}),!i.isRead&&e.jsx(s.Badge,{variant:"destructive",className:"text-[10px] px-1.5 py-0",children:"New"})]}),e.jsxs("span",{className:"block text-xs text-muted-foreground mb-1",children:[i.author.displayName," · ",s.formatTimestamp(i.createdAt)]}),e.jsx("span",{className:s.cn("text-sm text-foreground",!m&&"line-clamp-(--preview-lines) overflow-hidden"),style:m?void 0:{"--preview-lines":C},children:i.content}),!m&&i.content.length>200&&e.jsx(s.Button,{variant:"link",size:"xs",className:"px-0 mt-0.5 h-auto",onClick:o=>{o.stopPropagation(),w(i.uid)},children:"Read more"})]})]})})},i.uid)})})}exports.AssessmentReview=d.AssessmentReview;exports.AssignmentSubmission=d.AssignmentSubmission;exports.CertificateViewer=d.CertificateViewer;exports.CourseOutline=d.CourseOutline;exports.DiscussionThread=d.DiscussionThread;exports.ExamSession=d.ExamSession;exports.FlashcardStudySession=d.FlashcardStudySession;exports.ForumBoard=d.ForumBoard;exports.GradebookTable=d.GradebookTable;exports.LecturePlayer=d.LecturePlayer;exports.LessonPage=d.LessonPage;exports.PracticeQuiz=d.PracticeQuiz;exports.ProgressDashboard=d.ProgressDashboard;exports.QuizSession=d.QuizSession;exports.RequirementsChecklist=d.RequirementsChecklist;exports.RubricView=d.RubricView;exports.SurveyForm=d.SurveyForm;exports.AnnouncementFeed=M;exports.ResourceLibrary=I;exports.ScrollableQuiz=E;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./StudentProfile-BVfZMbnV.cjs"),e=require("react/jsx-runtime"),a=require("react"),s=require("./tabs-BsfVo2Bl.cjs"),Q=require("lucide-react"),V=[];function D({questions:o,initialAnswers:S=[],onSubmit:d,onAnswerChange:N,showNavigator:E=!0,showQuestionNumbers:F=!0,questionGroups:j,isSubmitting:z=!1,readOnly:f=!1,isLoading:B,error:k,onRetry:L,className:u,style:p}){var c;const[y,b]=a.useState(S),[T,C]=a.useState(((c=o[0])==null?void 0:c.uid)??null),x=a.useRef(new Map),g=a.useMemo(()=>{const i=new Map;for(const n of y){const l=i.get(n.uid);l?l.push(n):i.set(n.uid,[n])}return i},[y]),v=a.useMemo(()=>o.filter(i=>g.has(i.uid)).length,[o,g]);a.useEffect(()=>{const i=new IntersectionObserver(n=>{for(const l of n)l.isIntersecting&&C(l.target.getAttribute("data-question-uid"))},{rootMargin:"-20% 0px -60% 0px"});return x.current.forEach(n=>i.observe(n)),()=>i.disconnect()},[o]);const P=a.useCallback((i,n)=>{n?x.current.set(i,n):x.current.delete(i)},[]),w=a.useRef(N);w.current=N;const M=a.useCallback((i,n)=>{b(l=>r.mergeSessionAnswers(l,i,n,w.current))},[]);function h(i){var n;(n=x.current.get(i))==null||n.scrollIntoView({behavior:"smooth",block:"center"})}const I=a.useMemo(()=>{if(!j)return[{label:null,questions:o}];const i=j.map(m=>({label:m.label,questions:m.questionUids.map(A=>o.find(R=>R.uid===A)).filter(Boolean)})),n=new Set(j.flatMap(m=>m.questionUids)),l=o.filter(m=>!n.has(m.uid));return l.length>0&&i.push({label:null,questions:l}),i},[o,j]);let t=0;return e.jsx(r.SectionShell,{isLoading:B,error:k,onRetry:L,className:u,style:p,skeleton:e.jsxs(e.Fragment,{children:[e.jsx(s.Skeleton,{className:"h-32 w-full"}),e.jsx(s.Skeleton,{className:"h-32 w-full"}),e.jsx(s.Skeleton,{className:"h-32 w-full"})]}),children:e.jsxs("div",{className:"flex gap-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[I.map((i,n)=>e.jsxs("div",{children:[i.label&&e.jsx("p",{className:s.cn("text-lg font-semibold mb-2 text-foreground",n>0&&"mt-4"),children:i.label}),i.questions.map(l=>{const m=t++;return e.jsx(s.Card,{ref:A=>P(l.uid,A),"data-question-uid":l.uid,className:"mb-2",children:e.jsxs(s.CardContent,{className:"pt-6",children:[F&&e.jsxs("p",{className:"font-semibold text-sm text-muted-foreground mb-1",children:["Question ",m+1]}),e.jsx(s.QuestionRenderer,{question:l,sessionAnswers:g.get(l.uid)??V,onAnswer:A=>M(l.uid,A),readOnly:f})]})},l.uid)})]},i.label??`ungrouped-${n}`)),e.jsx(s.Separator,{className:"my-3"}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[v," of ",o.length," answered"]}),e.jsx(s.Button,{onClick:()=>d(y),disabled:z||f,children:z?"Submitting...":"Submit"})]})]}),E&&e.jsx(s.Card,{className:"hidden md:block w-50 shrink-0 sticky top-4 self-start",children:e.jsxs(s.CardContent,{className:"p-3",children:[e.jsx("p",{className:"font-semibold text-sm mb-1 text-foreground",children:"Questions"}),e.jsx("div",{className:"flex flex-wrap gap-1",children:o.map((i,n)=>{const l=g.has(i.uid),m=T===i.uid;return e.jsx("button",{type:"button",className:s.cn("inline-flex items-center justify-center text-xs font-medium min-w-9 px-1 py-0.5 rounded-full cursor-pointer border transition-colors",m?"bg-primary border-primary text-primary-foreground":l?"border-success text-success bg-transparent":"border-border text-foreground bg-transparent hover:bg-muted"),onClick:()=>h(i.uid),children:n+1},i.uid)})})]})})]})})}const U={pdf:"document",document:"document",video:"video",link:"link",image:"document",archive:"document",other:"document"};function _({resources:o,categories:S,onResourceClick:d,onDownload:N,viewMode:E="list",allowViewToggle:F=!0,showSearch:j=!0,emptyMessage:z="No resources found",readOnly:f=!1,isLoading:B,error:k,onRetry:L,pageSize:u,currentPage:p=1,totalItems:y,onPageChange:b,className:T,style:C}){const[x,g]=a.useState(""),[v,P]=a.useState(null),[w,M]=a.useState(E),h=a.useMemo(()=>{let t=o;if(v&&(t=t.filter(c=>c.categoryUid===v)),x.trim()){const c=x.toLowerCase();t=t.filter(i=>{var n;return i.name.toLowerCase().includes(c)||((n=i.description)==null?void 0:n.toLowerCase().includes(c))})}return t},[o,v,x]);if(B)return e.jsxs("div",{className:s.cn("space-y-4",T),style:C,children:[e.jsx(s.Skeleton,{className:"h-9 w-full"}),e.jsx("div",{className:"grid grid-cols-3 gap-4",children:Array.from({length:6}).map((t,c)=>e.jsx(s.Skeleton,{className:"h-32 w-full rounded-lg"},c))})]});if(k)return e.jsx("div",{className:s.cn("py-12",T),style:C,children:e.jsx(s.EmptyState,{icon:e.jsx(Q.AlertCircle,{className:"size-10 text-destructive"}),title:"Something went wrong",description:k,action:L?e.jsx(s.Button,{variant:"outline",onClick:L,children:"Retry"}):void 0})});function I(t){const c=U[t.type]??"document";return e.jsxs("div",{className:s.cn("flex items-center gap-3 px-3 py-2",!f&&d&&"cursor-pointer hover:bg-muted",(f||!d)&&"opacity-70"),onClick:()=>!f&&(d==null?void 0:d(t)),children:[e.jsx("div",{className:"min-w-10",children:e.jsx(s.LearningObjectIcon,{type:c,size:20})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("span",{className:"text-sm text-foreground",children:t.name}),(t.description||t.fileSize!=null)&&e.jsx("span",{className:"block text-xs text-muted-foreground",children:[t.description,t.fileSize!=null&&s.formatFileSize(t.fileSize)].filter(Boolean).join(" · ")})]}),N&&e.jsxs(s.Tooltip,{children:[e.jsx(s.TooltipTrigger,{children:e.jsx(s.Button,{variant:"ghost",size:"icon-xs","aria-label":"Download",onClick:i=>{i.stopPropagation(),N(t)},children:e.jsx(Q.Download,{size:16})})}),e.jsx(s.TooltipContent,{children:"Download"})]})]},t.uid)}return e.jsxs("div",{className:T,style:C,children:[e.jsxs("div",{className:"flex gap-2 items-center mb-2",children:[j&&e.jsx("div",{className:"flex-1 max-w-80",children:e.jsx(s.SearchInput,{value:x,onChange:g,placeholder:"Search resources...",size:"small"})}),F&&e.jsxs("div",{className:"flex gap-0.5",children:[e.jsxs(s.Tooltip,{children:[e.jsx(s.TooltipTrigger,{children:e.jsx(s.Button,{variant:"ghost",size:"icon-xs","aria-label":"List view",className:s.cn(w==="list"&&"text-primary"),onClick:()=>M("list"),children:e.jsx(Q.List,{size:18})})}),e.jsx(s.TooltipContent,{children:"List view"})]}),e.jsxs(s.Tooltip,{children:[e.jsx(s.TooltipTrigger,{children:e.jsx(s.Button,{variant:"ghost",size:"icon-xs","aria-label":"Grid view",className:s.cn(w==="grid"&&"text-primary"),onClick:()=>M("grid"),children:e.jsx(Q.Grid,{size:18})})}),e.jsx(s.TooltipContent,{children:"Grid view"})]})]})]}),S&&S.length>0&&e.jsx(s.Tabs,{value:v??"all",onValueChange:t=>P(t==="all"?null:t),className:"mb-2",children:e.jsxs(s.TabsList,{children:[e.jsx(s.TabsTrigger,{value:"all",children:"All"}),S.map(t=>e.jsx(s.TabsTrigger,{value:t.uid,children:t.label},t.uid))]})}),h.length===0?e.jsx(s.EmptyState,{title:z,description:"Try adjusting your search or filter."}):w==="list"?e.jsx(s.Card,{children:(b&&u?h.slice((p-1)*u,p*u):h).map(I)}):e.jsx("div",{className:"grid grid-cols-[repeat(auto-fill,minmax(240px,1fr))] gap-2",children:(b&&u?h.slice((p-1)*u,p*u):h).map(t=>e.jsx(s.Card,{className:s.cn("transition-colors",!f&&d&&"cursor-pointer hover:border-primary"),onClick:()=>!f&&(d==null?void 0:d(t)),children:e.jsxs(s.CardContent,{className:"pt-4 pb-4",children:[e.jsxs("div",{className:"flex gap-1 items-center mb-1",children:[e.jsx(s.LearningObjectIcon,{type:U[t.type]??"document",size:20}),e.jsx("span",{className:"font-semibold text-sm text-foreground truncate",children:t.name})]}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground mb-1 truncate",children:t.description}),t.fileSize!=null&&e.jsx("span",{className:"text-xs text-muted-foreground",children:s.formatFileSize(t.fileSize)})]})},t.uid))}),b&&u&&h.length>0&&e.jsx(s.Pagination,{currentPage:p,totalPages:Math.ceil((y??h.length)/u),onPageChange:b,className:"mt-4"})]})}exports.AnnouncementFeed=r.AnnouncementFeed;exports.AssessmentReview=r.AssessmentReview;exports.AssignmentSubmission=r.AssignmentSubmission;exports.CertificateViewer=r.CertificateViewer;exports.CourseCatalog=r.CourseCatalog;exports.CourseOutline=r.CourseOutline;exports.DiscussionThread=r.DiscussionThread;exports.EnrollmentWizard=r.EnrollmentWizard;exports.ExamSession=r.ExamSession;exports.FlashcardStudySession=r.FlashcardStudySession;exports.ForumBoard=r.ForumBoard;exports.GradebookTable=r.GradebookTable;exports.LecturePlayer=r.LecturePlayer;exports.LessonPage=r.LessonPage;exports.PracticeQuiz=r.PracticeQuiz;exports.ProgressDashboard=r.ProgressDashboard;exports.QuizSession=r.QuizSession;exports.RequirementsChecklist=r.RequirementsChecklist;exports.RubricView=r.RubricView;exports.StudentProfile=r.StudentProfile;exports.SurveyForm=r.SurveyForm;exports.ResourceLibrary=_;exports.ScrollableQuiz=D;