@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.
- package/dist/StudentProfile-BVfZMbnV.cjs +1 -0
- package/dist/StudentProfile-DeMxdrL3.js +3275 -0
- package/dist/assessment-toolbar/assessment-toolbar.d.ts +1 -1
- package/dist/assessment-toolbar/index.d.ts +5 -1
- package/dist/assessment-toolbar/question-header-bar.d.ts +2 -0
- package/dist/assessment-toolbar/question-materials-drawer.d.ts +2 -0
- package/dist/assessment-toolbar/question-navigator.d.ts +1 -1
- package/dist/assessment-toolbar/timer-display.d.ts +1 -1
- package/dist/assessment-toolbar/types.d.ts +52 -4
- package/dist/assessment-toolbar/use-countdown.d.ts +43 -0
- package/dist/common/index.d.ts +3 -1
- package/dist/common/pagination.d.ts +26 -0
- package/dist/common/stepper.d.ts +6 -0
- package/dist/common/types.d.ts +38 -0
- package/dist/components.css +1 -1
- package/dist/content/attachment-list.d.ts +6 -0
- package/dist/content/audio-player.d.ts +22 -0
- package/dist/content/code-block.d.ts +30 -0
- package/dist/content/content-block.d.ts +1 -1
- package/dist/content/embed-block.d.ts +28 -0
- package/dist/content/index.d.ts +8 -1
- package/dist/content/types.d.ts +63 -0
- package/dist/curriculum/course-card.d.ts +51 -0
- package/dist/curriculum/curriculum-item.d.ts +1 -1
- package/dist/curriculum/index.d.ts +2 -0
- package/dist/curriculum/types.d.ts +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +597 -308
- package/dist/license/HydraContext.d.ts +16 -0
- package/dist/license/ProBadge.d.ts +6 -0
- package/dist/license/index.d.ts +7 -0
- package/dist/license/tiers.d.ts +3 -0
- package/dist/license/useHydraLicense.d.ts +6 -0
- package/dist/license/validate.d.ts +13 -0
- package/dist/license/withProGate.d.ts +6 -0
- package/dist/modules/AssignmentModule/AssignmentModule.d.ts +5 -0
- package/dist/modules/AssignmentModule/types.d.ts +69 -0
- package/dist/modules/CertificateModule/CertificateModule.d.ts +5 -0
- package/dist/modules/CertificateModule/types.d.ts +51 -0
- package/dist/modules/CourseCatalogModule/CourseCatalogModule.d.ts +5 -0
- package/dist/modules/CourseCatalogModule/types.d.ts +43 -0
- package/dist/modules/CoursePlayer/CoursePlayer.d.ts +4 -1
- package/dist/modules/DiscussionModule/DiscussionModule.d.ts +5 -0
- package/dist/modules/DiscussionModule/types.d.ts +47 -0
- package/dist/modules/ExamModule/ExamModule.d.ts +5 -0
- package/dist/modules/ExamModule/types.d.ts +55 -0
- package/dist/modules/FlashcardLab/FlashcardLab.d.ts +4 -1
- package/dist/modules/FlashcardLab/types.d.ts +2 -0
- package/dist/modules/GradeCenterModule/GradeCenterModule.d.ts +5 -0
- package/dist/modules/GradeCenterModule/types.d.ts +56 -0
- package/dist/modules/QuizModule/QuizModule.d.ts +4 -1
- package/dist/modules/QuizModule/types.d.ts +10 -14
- package/dist/modules/StudentDashboardModule/StudentDashboardModule.d.ts +5 -0
- package/dist/modules/StudentDashboardModule/types.d.ts +54 -0
- package/dist/modules/StudentProfileModule/StudentProfileModule.d.ts +5 -0
- package/dist/modules/StudentProfileModule/types.d.ts +43 -0
- package/dist/modules/SurveyModule/SurveyModule.d.ts +5 -0
- package/dist/modules/SurveyModule/types.d.ts +51 -0
- package/dist/modules/_shared/assessment-intro.d.ts +16 -0
- package/dist/modules/_shared/assessment-results.d.ts +23 -0
- package/dist/modules/_shared/types.d.ts +10 -0
- package/dist/modules/_shared/use-timer.d.ts +9 -0
- package/dist/modules/index.d.ts +18 -0
- package/dist/modules.cjs +1 -0
- package/dist/modules.js +1834 -0
- package/dist/progress/achievement-badge.d.ts +6 -0
- package/dist/progress/activity-timeline.d.ts +6 -0
- package/dist/progress/index.d.ts +4 -1
- package/dist/progress/stat-card.d.ts +1 -1
- package/dist/progress/streak-badge.d.ts +6 -0
- package/dist/progress/types.d.ts +99 -0
- package/dist/provider/HydraProvider.d.ts +5 -1
- package/dist/questions/choice.d.ts +1 -1
- package/dist/questions/confidence-indicator.d.ts +37 -0
- package/dist/questions/essay.d.ts +2 -2
- package/dist/questions/fill-in-the-blank.d.ts +1 -1
- package/dist/questions/hotspot.d.ts +21 -0
- package/dist/questions/index.d.ts +11 -1
- package/dist/questions/inline-choice.d.ts +21 -0
- package/dist/questions/matching.d.ts +22 -0
- package/dist/questions/multiple-choice.d.ts +1 -1
- package/dist/questions/numeric.d.ts +11 -0
- package/dist/questions/ordering.d.ts +12 -0
- package/dist/questions/question-renderer.d.ts +1 -1
- package/dist/questions/scenario.d.ts +23 -0
- package/dist/questions/scoring.d.ts +22 -0
- package/dist/questions/spreadsheet.d.ts +29 -0
- package/dist/questions/true-false.d.ts +1 -1
- package/dist/questions/types.d.ts +106 -1
- package/dist/questions/use-drag-reorder.d.ts +17 -0
- package/dist/sections/AnnouncementFeed/AnnouncementFeed.d.ts +1 -1
- package/dist/sections/AnnouncementFeed/types.d.ts +15 -1
- package/dist/sections/AssessmentReview/AssessmentReview.d.ts +1 -1
- package/dist/sections/AssessmentReview/types.d.ts +6 -0
- package/dist/sections/AssignmentSubmission/AssignmentSubmission.d.ts +1 -1
- package/dist/sections/AssignmentSubmission/types.d.ts +6 -0
- package/dist/sections/CertificateViewer/CertificateViewer.d.ts +1 -1
- package/dist/sections/CertificateViewer/certificate-variants.d.ts +42 -0
- package/dist/sections/CertificateViewer/types.d.ts +13 -5
- package/dist/sections/CourseCatalog/CourseCatalog.d.ts +2 -0
- package/dist/sections/CourseCatalog/types.d.ts +80 -0
- package/dist/sections/CourseOutline/CourseOutline.d.ts +1 -1
- package/dist/sections/CourseOutline/types.d.ts +6 -0
- package/dist/sections/DiscussionThread/DiscussionThread.d.ts +1 -1
- package/dist/sections/DiscussionThread/types.d.ts +6 -0
- package/dist/sections/EnrollmentWizard/EnrollmentWizard.d.ts +2 -0
- package/dist/sections/EnrollmentWizard/types.d.ts +66 -0
- package/dist/sections/ExamSession/ExamSession.d.ts +1 -1
- package/dist/sections/ExamSession/types.d.ts +12 -1
- package/dist/sections/FlashcardStudySession/FlashcardStudySession.d.ts +1 -1
- package/dist/sections/FlashcardStudySession/types.d.ts +6 -0
- package/dist/sections/ForumBoard/ForumBoard.d.ts +8 -0
- package/dist/sections/ForumBoard/types.d.ts +78 -0
- package/dist/sections/GradebookTable/GradebookTable.d.ts +1 -1
- package/dist/sections/GradebookTable/types.d.ts +14 -0
- package/dist/sections/LecturePlayer/LecturePlayer.d.ts +1 -1
- package/dist/sections/LecturePlayer/types.d.ts +8 -0
- package/dist/sections/LessonPage/LessonPage.d.ts +1 -1
- package/dist/sections/LessonPage/types.d.ts +6 -0
- package/dist/sections/PracticeQuiz/PracticeQuiz.d.ts +1 -1
- package/dist/sections/PracticeQuiz/types.d.ts +6 -0
- package/dist/sections/ProgressDashboard/ProgressDashboard.d.ts +1 -1
- package/dist/sections/ProgressDashboard/types.d.ts +6 -0
- package/dist/sections/QuizSession/QuizSession.d.ts +1 -1
- package/dist/sections/QuizSession/types.d.ts +12 -1
- package/dist/sections/RequirementsChecklist/RequirementsChecklist.d.ts +8 -0
- package/dist/sections/RequirementsChecklist/types.d.ts +43 -0
- package/dist/sections/ResourceLibrary/ResourceLibrary.d.ts +1 -1
- package/dist/sections/ResourceLibrary/types.d.ts +15 -1
- package/dist/sections/RubricView/RubricView.d.ts +9 -0
- package/dist/sections/RubricView/types.d.ts +56 -0
- package/dist/sections/ScrollableQuiz/ScrollableQuiz.d.ts +1 -1
- package/dist/sections/ScrollableQuiz/types.d.ts +6 -0
- package/dist/sections/StudentProfile/StudentProfile.d.ts +2 -0
- package/dist/sections/StudentProfile/types.d.ts +98 -0
- package/dist/sections/SurveyForm/SurveyForm.d.ts +1 -1
- package/dist/sections/SurveyForm/types.d.ts +6 -0
- package/dist/sections/_shared/merge-answers.d.ts +9 -0
- package/dist/sections/_shared/section-shell.d.ts +20 -0
- package/dist/sections/_shared/use-assessment-session.d.ts +30 -0
- package/dist/sections/index.d.ts +13 -1
- package/dist/sections.cjs +1 -1
- package/dist/sections.js +282 -1786
- package/dist/social/post-card.d.ts +1 -1
- package/dist/tabs-BsfVo2Bl.cjs +173 -0
- package/dist/tabs-BuY1iNJE.js +22305 -0
- package/dist/ui/alert.d.ts +1 -1
- package/dist/ui/badge.d.ts +1 -1
- package/dist/ui/button.d.ts +1 -1
- package/dist/ui/drawer.d.ts +84 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/progress.d.ts +1 -1
- package/dist/ui/rich-text-editor.d.ts +32 -0
- package/dist/ui/rich-text-toolbar.d.ts +8 -0
- package/dist/ui/toast.d.ts +43 -0
- package/dist/utils/array-utils.d.ts +4 -0
- package/dist/utils/debounce.d.ts +5 -1
- package/dist/utils/flatten-leaves.d.ts +6 -0
- package/dist/utils/format-file-size.d.ts +1 -0
- package/dist/utils/format-timestamp.d.ts +1 -0
- package/dist/utils/is-empty-html.d.ts +5 -0
- package/dist/utils/pick-palette-color.d.ts +19 -0
- package/dist/utils/shuffle.d.ts +1 -0
- package/dist/utils/string-utils.d.ts +12 -0
- package/dist/video/types.d.ts +15 -0
- package/dist/video/video-bookmark.d.ts +1 -1
- package/dist/video/video-player.d.ts +1 -1
- package/dist/video/video-playlist-item.d.ts +1 -1
- package/dist/withProGate-BWqcKdPM.js +137 -0
- package/dist/withProGate-DX6XqKLp.cjs +1 -0
- package/package.json +40 -137
- package/src/assessment-toolbar/assessment-toolbar.tsx +54 -49
- package/src/assessment-toolbar/index.ts +6 -0
- package/src/assessment-toolbar/question-header-bar.tsx +61 -0
- package/src/assessment-toolbar/question-materials-drawer.tsx +55 -0
- package/src/assessment-toolbar/question-navigator.tsx +13 -36
- package/src/assessment-toolbar/timer-display.tsx +6 -5
- package/src/assessment-toolbar/types.ts +54 -4
- package/src/assessment-toolbar/use-countdown.ts +153 -0
- package/src/common/empty-state.tsx +1 -0
- package/src/common/index.ts +5 -0
- package/src/common/pagination.tsx +135 -0
- package/src/common/search-input.tsx +8 -6
- package/src/common/stepper.tsx +100 -0
- package/src/common/types.ts +41 -0
- package/src/content/attachment-list.tsx +92 -0
- package/src/content/audio-player.tsx +196 -0
- package/src/content/code-block.tsx +113 -0
- package/src/content/content-block.tsx +68 -2
- package/src/content/embed-block.tsx +78 -0
- package/src/content/file-upload-zone.tsx +11 -6
- package/src/content/index.ts +9 -0
- package/src/content/types.ts +46 -0
- package/src/curriculum/course-card.tsx +199 -0
- package/src/curriculum/curriculum-item.tsx +9 -5
- package/src/curriculum/curriculum-tree.tsx +20 -13
- package/src/curriculum/index.ts +2 -0
- package/src/curriculum/types.ts +2 -2
- package/src/feedback/feedback-banner.tsx +12 -14
- package/src/flashcards/flashcard-deck.tsx +1 -9
- package/src/flashcards/flashcard.tsx +29 -9
- package/src/index.ts +3 -0
- package/src/license/HydraContext.tsx +62 -0
- package/src/license/ProBadge.tsx +43 -0
- package/src/license/index.ts +7 -0
- package/src/license/tiers.ts +24 -0
- package/src/license/useHydraLicense.ts +10 -0
- package/src/license/validate.ts +90 -0
- package/src/license/withProGate.tsx +21 -0
- package/src/modules/AssignmentModule/AssignmentModule.tsx +314 -0
- package/src/modules/AssignmentModule/types.ts +77 -0
- package/src/modules/CertificateModule/CertificateModule.tsx +173 -0
- package/src/modules/CertificateModule/types.ts +49 -0
- package/src/modules/CourseCatalogModule/CourseCatalogModule.tsx +126 -0
- package/src/modules/CourseCatalogModule/types.ts +47 -0
- package/src/modules/CoursePlayer/CoursePlayer.tsx +80 -69
- package/src/modules/DiscussionModule/DiscussionModule.tsx +145 -0
- package/src/modules/DiscussionModule/types.ts +54 -0
- package/src/modules/ExamModule/ExamModule.tsx +151 -0
- package/src/modules/ExamModule/types.ts +57 -0
- package/src/modules/FlashcardLab/FlashcardLab.tsx +39 -21
- package/src/modules/FlashcardLab/types.ts +2 -0
- package/src/modules/GradeCenterModule/GradeCenterModule.tsx +174 -0
- package/src/modules/GradeCenterModule/types.ts +65 -0
- package/src/modules/QuizModule/QuizModule.tsx +58 -178
- package/src/modules/QuizModule/types.ts +10 -15
- package/src/modules/StudentDashboardModule/StudentDashboardModule.tsx +117 -0
- package/src/modules/StudentDashboardModule/types.ts +56 -0
- package/src/modules/StudentProfileModule/StudentProfileModule.tsx +289 -0
- package/src/modules/StudentProfileModule/types.ts +45 -0
- package/src/modules/SurveyModule/SurveyModule.tsx +185 -0
- package/src/modules/SurveyModule/types.ts +53 -0
- package/src/modules/_shared/assessment-intro.tsx +75 -0
- package/src/modules/_shared/assessment-results.tsx +133 -0
- package/src/modules/_shared/types.ts +11 -0
- package/src/modules/_shared/use-timer.ts +49 -0
- package/src/modules/index.ts +33 -0
- package/src/progress/achievement-badge.tsx +52 -0
- package/src/progress/activity-timeline.tsx +84 -0
- package/src/progress/grade-indicator.tsx +9 -1
- package/src/progress/index.ts +7 -0
- package/src/progress/progress-ring.tsx +2 -1
- package/src/progress/stat-card.tsx +37 -18
- package/src/progress/streak-badge.tsx +35 -0
- package/src/progress/types.ts +103 -0
- package/src/provider/HydraProvider.tsx +15 -6
- package/src/questions/choice.tsx +19 -14
- package/src/questions/confidence-indicator.tsx +107 -0
- package/src/questions/essay.tsx +28 -28
- package/src/questions/fill-in-the-blank.tsx +20 -19
- package/src/questions/hotspot.tsx +154 -0
- package/src/questions/index.ts +18 -0
- package/src/questions/inline-choice.tsx +152 -0
- package/src/questions/matching.tsx +229 -0
- package/src/questions/multiple-choice.tsx +19 -14
- package/src/questions/numeric.tsx +106 -0
- package/src/questions/ordering.tsx +167 -0
- package/src/questions/question-renderer.tsx +24 -2
- package/src/questions/scenario.tsx +140 -0
- package/src/questions/scoring.ts +201 -0
- package/src/questions/spreadsheet.tsx +260 -0
- package/src/questions/true-false.tsx +19 -14
- package/src/questions/types.ts +123 -1
- package/src/questions/use-drag-reorder.ts +80 -0
- package/src/sections/AnnouncementFeed/AnnouncementFeed.tsx +66 -23
- package/src/sections/AnnouncementFeed/types.ts +15 -1
- package/src/sections/AssessmentReview/AssessmentReview.tsx +50 -2
- package/src/sections/AssessmentReview/types.ts +6 -0
- package/src/sections/AssignmentSubmission/AssignmentSubmission.tsx +44 -6
- package/src/sections/AssignmentSubmission/types.ts +6 -0
- package/src/sections/CertificateViewer/CertificateViewer.tsx +215 -60
- package/src/sections/CertificateViewer/certificate-variants.tsx +170 -0
- package/src/sections/CertificateViewer/types.ts +19 -5
- package/src/sections/CourseCatalog/CourseCatalog.tsx +220 -0
- package/src/sections/CourseCatalog/types.ts +76 -0
- package/src/sections/CourseOutline/CourseOutline.tsx +45 -14
- package/src/sections/CourseOutline/types.ts +6 -0
- package/src/sections/DiscussionThread/DiscussionThread.tsx +55 -11
- package/src/sections/DiscussionThread/types.ts +6 -0
- package/src/sections/EnrollmentWizard/EnrollmentWizard.tsx +343 -0
- package/src/sections/EnrollmentWizard/types.ts +65 -0
- package/src/sections/ExamSession/ExamSession.tsx +125 -82
- package/src/sections/ExamSession/types.ts +12 -1
- package/src/sections/FlashcardStudySession/FlashcardStudySession.tsx +53 -36
- package/src/sections/FlashcardStudySession/types.ts +6 -0
- package/src/sections/ForumBoard/ForumBoard.tsx +342 -0
- package/src/sections/ForumBoard/types.ts +81 -0
- package/src/sections/GradebookTable/GradebookTable.tsx +55 -2
- package/src/sections/GradebookTable/types.ts +14 -0
- package/src/sections/LecturePlayer/LecturePlayer.tsx +63 -37
- package/src/sections/LecturePlayer/types.ts +8 -0
- package/src/sections/LessonPage/LessonPage.tsx +40 -13
- package/src/sections/LessonPage/types.ts +6 -0
- package/src/sections/PracticeQuiz/PracticeQuiz.tsx +119 -98
- package/src/sections/PracticeQuiz/types.ts +6 -0
- package/src/sections/ProgressDashboard/ProgressDashboard.tsx +121 -67
- package/src/sections/ProgressDashboard/types.ts +6 -0
- package/src/sections/QuizSession/QuizSession.tsx +115 -67
- package/src/sections/QuizSession/types.ts +12 -1
- package/src/sections/RequirementsChecklist/RequirementsChecklist.tsx +147 -0
- package/src/sections/RequirementsChecklist/types.ts +44 -0
- package/src/sections/ResourceLibrary/ResourceLibrary.tsx +68 -17
- package/src/sections/ResourceLibrary/types.ts +15 -1
- package/src/sections/RubricView/RubricView.tsx +174 -0
- package/src/sections/RubricView/types.ts +58 -0
- package/src/sections/ScrollableQuiz/ScrollableQuiz.tsx +58 -23
- package/src/sections/ScrollableQuiz/types.ts +6 -0
- package/src/sections/StudentProfile/StudentProfile.tsx +279 -0
- package/src/sections/StudentProfile/types.ts +99 -0
- package/src/sections/SurveyForm/SurveyForm.tsx +40 -10
- package/src/sections/SurveyForm/types.ts +6 -0
- package/src/sections/_shared/merge-answers.ts +22 -0
- package/src/sections/_shared/section-shell.tsx +64 -0
- package/src/sections/_shared/use-assessment-session.ts +125 -0
- package/src/sections/index.ts +42 -1
- package/src/social/post-card.tsx +8 -19
- package/src/social/user-avatar.tsx +10 -5
- package/src/styles/globals.css +52 -41
- package/src/ui/badge.tsx +8 -0
- package/src/ui/drawer.tsx +600 -0
- package/src/ui/index.ts +21 -0
- package/src/ui/progress.tsx +4 -0
- package/src/ui/rich-text-editor.tsx +119 -0
- package/src/ui/rich-text-toolbar.tsx +157 -0
- package/src/ui/toast.tsx +170 -0
- package/src/utils/array-utils.ts +17 -0
- package/src/utils/debounce.ts +8 -2
- package/src/utils/flatten-leaves.ts +17 -0
- package/src/utils/format-file-size.ts +5 -0
- package/src/utils/format-timestamp.ts +13 -0
- package/src/utils/is-empty-html.ts +7 -0
- package/src/utils/pick-palette-color.ts +33 -0
- package/src/utils/shuffle.ts +8 -0
- package/src/utils/string-utils.ts +30 -0
- package/src/video/types.ts +16 -0
- package/src/video/video-bookmark.tsx +4 -3
- package/src/video/video-chapter-list.tsx +9 -4
- package/src/video/video-player.tsx +24 -5
- package/src/video/video-playlist-item.tsx +8 -3
- package/src/video/video-thumbnail-card.tsx +4 -0
- package/src/video/video-transcript.tsx +8 -5
- package/dist/table-BrS5cDQu.js +0 -2510
- package/dist/table-D6AkBBEo.cjs +0 -1
|
@@ -20,7 +20,7 @@ export interface ResourceLibraryProps {
|
|
|
20
20
|
label: string;
|
|
21
21
|
}[];
|
|
22
22
|
/** Called when the user clicks a resource */
|
|
23
|
-
onResourceClick
|
|
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 */
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { RubricViewProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* RubricView — displays a grading rubric with criteria rows and proficiency level columns.
|
|
4
|
+
*
|
|
5
|
+
* When `selectedLevels` is provided, highlights the scored level per criterion and
|
|
6
|
+
* shows an overall score. Useful inside AssignmentModule for showing grading criteria
|
|
7
|
+
* and results.
|
|
8
|
+
*/
|
|
9
|
+
export declare function RubricView({ criteria, selectedLevels, totalScore, maxScore, feedback, isLoading, error, onRetry, className, style, }: RubricViewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RubricView section — displays a grading rubric with criteria and proficiency levels.
|
|
3
|
+
*
|
|
4
|
+
* Shows criteria as rows with level columns. When `selectedLevels` is provided,
|
|
5
|
+
* highlights the scored level per criterion and shows total score.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* <RubricView
|
|
9
|
+
* criteria={rubricCriteria}
|
|
10
|
+
* selectedLevels={{ "c1": "l2", "c2": "l3" }}
|
|
11
|
+
* totalScore={85}
|
|
12
|
+
* maxScore={100}
|
|
13
|
+
* />
|
|
14
|
+
*/
|
|
15
|
+
export interface RubricViewProps {
|
|
16
|
+
/** Rubric criteria (rows) */
|
|
17
|
+
criteria: RubricCriterion[];
|
|
18
|
+
/** Selected level UID per criterion UID — highlights scored cells */
|
|
19
|
+
selectedLevels?: Record<string, string>;
|
|
20
|
+
/** Overall rubric score (sum of selected levels) */
|
|
21
|
+
totalScore?: number;
|
|
22
|
+
/** Maximum possible score */
|
|
23
|
+
maxScore?: number;
|
|
24
|
+
/** Instructor feedback text */
|
|
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;
|
|
32
|
+
/** CSS class name for the root element */
|
|
33
|
+
className?: string;
|
|
34
|
+
/** Inline styles for the root element */
|
|
35
|
+
style?: React.CSSProperties;
|
|
36
|
+
}
|
|
37
|
+
export interface RubricCriterion {
|
|
38
|
+
/** Unique identifier */
|
|
39
|
+
uid: string;
|
|
40
|
+
/** Criterion name (e.g. "Organization", "Evidence") */
|
|
41
|
+
name: string;
|
|
42
|
+
/** Optional description of what this criterion evaluates */
|
|
43
|
+
description?: string;
|
|
44
|
+
/** Proficiency levels from lowest to highest */
|
|
45
|
+
levels: RubricLevel[];
|
|
46
|
+
}
|
|
47
|
+
export interface RubricLevel {
|
|
48
|
+
/** Unique identifier */
|
|
49
|
+
uid: string;
|
|
50
|
+
/** Level label (e.g. "Excellent", "Good", "Needs Work") */
|
|
51
|
+
label: string;
|
|
52
|
+
/** Description of what this level looks like */
|
|
53
|
+
description: string;
|
|
54
|
+
/** Point value for this level */
|
|
55
|
+
points: number;
|
|
56
|
+
}
|
|
@@ -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
|
+
};
|
package/dist/sections/index.d.ts
CHANGED
|
@@ -31,4 +31,16 @@ export type { GradebookTableProps, GradeItem, GradeCategory, OverallGrade, } fro
|
|
|
31
31
|
export { ProgressDashboard } from './ProgressDashboard/ProgressDashboard';
|
|
32
32
|
export type { ProgressDashboardProps, ModuleProgress, ActivityItem, Achievement, } from './ProgressDashboard/types';
|
|
33
33
|
export { CertificateViewer } from './CertificateViewer/CertificateViewer';
|
|
34
|
-
export type { CertificateViewerProps } from './CertificateViewer/types';
|
|
34
|
+
export type { CertificateViewerProps, CertificateVariant, } from './CertificateViewer/types';
|
|
35
|
+
export { RubricView } from './RubricView/RubricView';
|
|
36
|
+
export type { RubricViewProps, RubricCriterion, RubricLevel, } from './RubricView/types';
|
|
37
|
+
export { RequirementsChecklist } from './RequirementsChecklist/RequirementsChecklist';
|
|
38
|
+
export type { RequirementsChecklistProps, Requirement, } from './RequirementsChecklist/types';
|
|
39
|
+
export { ForumBoard } from './ForumBoard/ForumBoard';
|
|
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 e=require("react/jsx-runtime"),p=require("react"),t=require("./table-D6AkBBEo.cjs"),M=require("lucide-react");function W({questions:n,initialAnswers:r=[],onSubmit:a,onAnswerChange:d,timeElapsedSeconds:f,timeLimitSeconds:l,isSubmitting:m=!1,readOnly:i=!1,className:w,style:C}){const[c,b]=p.useState(0),[D,u]=p.useState(r),[z,N]=p.useState(new Set),T=n[c],j=p.useMemo(()=>n.map((S,h)=>({uid:S.uid,sequence:h+1,isFlagged:z.has(S.uid),isAnswered:D.some(x=>x.uid===S.uid),isSkipped:!1})),[n,D,z]);function k(S){if(!T)return;const h=T.uid,x=S.map(v=>({uid:h,answerUid:v.uid,content:v.content}));u(v=>{const y=[...v.filter(A=>A.uid!==h),...x];return d==null||d(y),y})}function s(S){const h=n.findIndex(x=>x.uid===S);h!==-1&&b(h)}function o(S){N(h=>{const x=new Set(h);return x.has(S)?x.delete(S):x.add(S),x})}function g(){a(D)}return e.jsxs("div",{className:t.cn(w),style:C,children:[e.jsx(t.AssessmentToolbar,{currentQuestionIndex:c,totalQuestions:n.length,hasNext:c<n.length-1,hasPrevious:c>0,onNext:()=>b(S=>Math.min(S+1,n.length-1)),onPrevious:()=>b(S=>Math.max(S-1,0)),onSubmit:g,timeElapsedSeconds:f,timeLimitSeconds:l,questions:j,onNavigateToQuestion:s,onToggleFlag:o,currentQuestionUid:T==null?void 0:T.uid,isSubmitting:m,readOnly:i}),T&&e.jsx(t.Card,{className:"mt-3",children:e.jsx(t.CardContent,{className:"pt-6",children:e.jsx(t.QuestionRenderer,{question:T,sessionAnswers:D.filter(S=>S.uid===T.uid),onAnswer:k,readOnly:i})})})]})}function X({video:n,notes:r,layout:a="horizontal",notesPanelWidth:d="340px",notesPanelHeight:f="240px",className:l,style:m}){const i=a==="horizontal";return r?e.jsxs("div",{className:t.cn("flex overflow-hidden",i?"flex-row":"flex-col",l),style:m,children:[e.jsx("div",{className:"flex-1 min-w-0 min-h-0",children:e.jsx(t.VideoPlayer,{...n})}),e.jsxs(t.Card,{className:t.cn("overflow-auto shrink-0 rounded-none border-0",i?"border-l border-border":"border-t border-border w-full"),style:{width:i?d:void 0,height:i?void 0:f},children:[e.jsx(t.CardHeader,{children:e.jsx(t.CardTitle,{children:"Notes"})}),e.jsx(t.CardContent,{children:typeof r=="string"?e.jsx("span",{className:"text-sm text-foreground",children:r}):r})]})]}):e.jsx("div",{className:l,style:m,children:e.jsx(t.VideoPlayer,{...n})})}function O({cards:n,title:r,description:a,shuffled:d=!1,onComplete:f,readOnly:l=!1,className:m,style:i}){const[w,C]=p.useState(!1),c={totalCards:n.length,wasShuffled:d};function b(){C(!0),f==null||f(c)}function D(){C(!1)}return w?e.jsx("div",{className:t.cn("flex flex-col items-center",m),style:i,children:e.jsx(t.Card,{children:e.jsxs(t.CardContent,{className:"pt-6 text-center flex flex-col items-center gap-2",children:[e.jsx(M.CheckCircle,{size:48,className:"text-success"}),e.jsx("span",{className:"text-xl font-bold text-foreground",children:"Deck complete!"}),r&&e.jsxs("span",{className:"text-muted-foreground",children:["You finished ",e.jsx("strong",{children:r})]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[c.totalCards," card",c.totalCards!==1?"s":""," studied",c.wasShuffled?" (shuffled)":""]}),e.jsx(t.Button,{className:"mt-2",onClick:D,children:"Study Again"})]})})}):e.jsx("div",{className:t.cn("flex flex-col items-center",m),style:i,children:e.jsx(t.FlashcardDeck,{cards:n,deckName:r,deckDescription:a,shuffled:d,showProgress:!0,onComplete:b,readOnly:l})})}function q({score:n}){const r=n.percentage!==void 0?n.percentage:n.total>0?Math.round(n.correct/n.total*100):0;return e.jsx(t.Card,{className:"mb-3",children:e.jsx(t.CardContent,{className:"pt-6",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("div",{children:[e.jsxs("span",{className:"text-2xl font-bold leading-none text-foreground",children:[r,"%"]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[n.correct," of ",n.total," correct"]})]}),n.passed!==void 0&&e.jsx(t.Badge,{variant:n.passed?"success":"destructive",children:n.passed?"Passed":"Failed"}),n.passingScore!==void 0&&e.jsxs("span",{className:"text-sm text-muted-foreground",children:["Passing score: ",n.passingScore,"%"]})]})})})}function V({questions:n,sessionAnswers:r,showCorrectAnswers:a}){return e.jsx("div",{className:"flex flex-col gap-3",children:n.map((d,f)=>e.jsxs(t.Card,{className:"overflow-hidden",children:[e.jsx("div",{className:"px-2 py-1 bg-muted",children:e.jsxs("span",{className:"text-xs text-muted-foreground font-semibold",children:["Question ",f+1]})}),e.jsx(t.Separator,{}),e.jsx(t.CardContent,{className:"pt-4 pb-4",children:e.jsx(t.QuestionRenderer,{question:d,sessionAnswers:r.filter(l=>l.uid===d.uid),readOnly:!0,showCorrectAnswers:a})})]},d.uid))})}function ee(n,r,a,d){const f=new Map(n.map(i=>[i.uid,i])),l=new Set(a.flatMap(i=>i.questionUids)),m=n.filter(i=>!l.has(i.uid));return e.jsxs("div",{className:"flex flex-col gap-4",children:[a.map(i=>{const w=i.questionUids.map(C=>f.get(C)).filter(Boolean);return e.jsxs("div",{children:[e.jsx("span",{className:"uppercase text-xs tracking-wide text-muted-foreground font-semibold",children:i.label}),e.jsx(t.Separator,{className:"mb-2"}),e.jsx(V,{questions:w,sessionAnswers:r,showCorrectAnswers:d})]},i.label)}),m.length>0&&e.jsx("div",{children:e.jsx(V,{questions:m,sessionAnswers:r,showCorrectAnswers:d})})]})}function te({questions:n,sessionAnswers:r,score:a,questionGroups:d,showCorrectAnswers:f=!0,className:l,style:m}){return e.jsxs("div",{className:t.cn(l),style:m,children:[a&&e.jsx(q,{score:a}),d&&d.length>0?ee(n,r,d,f):e.jsx(V,{questions:n,sessionAnswers:r,showCorrectAnswers:f})]})}function G(n){const r=[];for(const a of n)!a.children||a.children.length===0?r.push(a.uid):r.push(...G(a.children));return r}function se({items:n,progress:r,courseTitle:a,activeItemUid:d,onItemClick:f,showOverallProgress:l=!0,showDuration:m=!0,showIcons:i=!0,readOnly:w=!1,className:C,style:c}){const{completedCount:b,totalCount:D,percentage:u}=p.useMemo(()=>{const z=G(n),N=z.length,T=r?z.filter(j=>r.some(k=>k.resourceUid===j&&k.isCompleted)).length:0;return{completedCount:T,totalCount:N,percentage:N>0?Math.round(T/N*100):0}},[n,r]);return e.jsxs("div",{className:t.cn(C),style:c,children:[(a||l)&&e.jsxs("div",{className:"px-2 pt-2 pb-1",children:[a&&e.jsx("p",{className:t.cn("font-semibold text-sm text-foreground",l&&"mb-1"),children:a}),l&&e.jsxs("div",{children:[e.jsx(t.Progress,{value:u,size:"sm"}),e.jsxs("span",{className:"text-xs text-muted-foreground mt-0.5 block",children:[b," of ",D," completed"]})]})]}),e.jsx(t.CurriculumTree,{items:n,progress:r,activeItemUid:d,onItemClick:f,readOnly:w,showDuration:m,showIcons:i,showProgress:!0})]})}function ne({questions:n,initialAnswers:r=[],onSubmit:a,onAnswerChange:d,showNavigator:f=!0,showQuestionNumbers:l=!0,questionGroups:m,isSubmitting:i=!1,readOnly:w=!1,className:C,style:c}){var S;const[b,D]=p.useState(r),[u,z]=p.useState(((S=n[0])==null?void 0:S.uid)??null),N=p.useRef(new Map),T=p.useMemo(()=>{const h=new Set(b.map(x=>x.uid));return n.filter(x=>h.has(x.uid)).length},[n,b]);p.useEffect(()=>{const h=new IntersectionObserver(x=>{for(const v of x)v.isIntersecting&&z(v.target.getAttribute("data-question-uid"))},{rootMargin:"-20% 0px -60% 0px"});return N.current.forEach(x=>h.observe(x)),()=>h.disconnect()},[n]);const j=p.useCallback((h,x)=>{x?N.current.set(h,x):N.current.delete(h)},[]);function k(h,x){const v=x.map(U=>({uid:h,answerUid:U.uid,content:U.content}));D(U=>{const A=[...U.filter(F=>F.uid!==h),...v];return d==null||d(A),A})}function s(h){var x;(x=N.current.get(h))==null||x.scrollIntoView({behavior:"smooth",block:"center"})}const o=p.useMemo(()=>{if(!m)return[{label:null,questions:n}];const h=m.map(U=>({label:U.label,questions:U.questionUids.map(y=>n.find(A=>A.uid===y)).filter(Boolean)})),x=new Set(m.flatMap(U=>U.questionUids)),v=n.filter(U=>!x.has(U.uid));return v.length>0&&h.push({label:null,questions:v}),h},[n,m]);let g=0;return e.jsxs("div",{className:t.cn("flex gap-3",C),style:c,children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[o.map((h,x)=>e.jsxs("div",{children:[h.label&&e.jsx("p",{className:t.cn("text-lg font-semibold mb-2 text-foreground",x>0&&"mt-4"),children:h.label}),h.questions.map(v=>{const U=g++;return e.jsx(t.Card,{ref:y=>j(v.uid,y),"data-question-uid":v.uid,className:"mb-2",children:e.jsxs(t.CardContent,{className:"pt-6",children:[l&&e.jsxs("p",{className:"font-semibold text-sm text-muted-foreground mb-1",children:["Question ",U+1]}),e.jsx(t.QuestionRenderer,{question:v,sessionAnswers:b.filter(y=>y.uid===v.uid),onAnswer:y=>k(v.uid,y),readOnly:w})]})},v.uid)})]},x)),e.jsxs("div",{className:"mt-3 flex justify-between items-center",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[T," of ",n.length," answered"]}),e.jsx(t.Button,{onClick:()=>a(b),disabled:i||w,children:i?"Submitting...":"Submit"})]})]}),f&&e.jsxs(t.Card,{className:"hidden md:block w-50 shrink-0 sticky top-4 self-start 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:n.map((h,x)=>{const v=b.some(y=>y.uid===h.uid),U=u===h.uid;return e.jsx("button",{type:"button",className:t.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",U?"bg-primary border-primary text-primary-foreground":v?"border-success text-success bg-transparent":"border-border text-foreground bg-transparent hover:bg-muted"),onClick:()=>s(h.uid),children:x+1},h.uid)})})]})]})}function re(n){const r=[...n];for(let a=r.length-1;a>0;a--){const d=Math.floor(Math.random()*(a+1));[r[a],r[d]]=[r[d],r[a]]}return r}function le({questions:n,instantFeedback:r=!0,allowRetry:a=!0,onComplete:d,shuffled:f=!1,readOnly:l=!1,className:m,style:i}){const w=p.useMemo(()=>f?re(n):n,[n,f]),[C,c]=p.useState(0),[b,D]=p.useState(new Set),[u,z]=p.useState(new Map),[N,T]=p.useState(new Set),[j,k]=p.useState(null),[s,o]=p.useState(!1),g=w[C],S=g?b.has(g.uid):!1;function h(){var $;if(!g||!j)return;const y=(u.get(g.uid)??0)+1;z(R=>new Map(R).set(g.uid,y)),D(R=>new Set(R).add(g.uid));const A=new Set((($=g.answers)==null?void 0:$.filter(R=>R.isCorrect).map(R=>R.uid))??[]),F=new Set(j.map(R=>R.uid));A.size===F.size&&[...A].every(R=>F.has(R))&&y===1&&T(R=>new Set(R).add(g.uid))}function x(){g&&(D(y=>{const A=new Set(y);return A.delete(g.uid),A}),k(null))}function v(){if(C<w.length-1)c(y=>y+1),k(null);else{const y={totalQuestions:w.length,correctOnFirstAttempt:N.size,totalAttempts:Array.from(u.values()).reduce((A,F)=>A+F,0)};o(!0),d==null||d(y)}}const U=p.useMemo(()=>{var F;if(!g||!j)return!1;const y=new Set(((F=g.answers)==null?void 0:F.filter(I=>I.isCorrect).map(I=>I.uid))??[]),A=new Set(j.map(I=>I.uid));return y.size===A.size&&[...y].every(I=>A.has(I))},[g,j]);if(s){const y=w.length>0?Math.round(N.size/w.length*100):0;return e.jsx(t.Card,{className:m,style:i,children:e.jsxs(t.CardContent,{className:"pt-6 text-center",children:[e.jsx(M.CheckCircle,{size:48,className:"text-success mx-auto mb-4"}),e.jsx("p",{className:"text-xl font-bold mb-1 text-foreground",children:"Practice Complete!"}),e.jsxs("p",{className:"text-muted-foreground mb-2",children:[N.size," of ",w.length," correct on first attempt (",y,"%)"]}),e.jsx("div",{className:"flex justify-center",children:e.jsx(t.Button,{variant:"outline",onClick:()=>{c(0),D(new Set),z(new Map),T(new Set),k(null),o(!1)},children:"Practice Again"})})]})})}return e.jsxs("div",{className:m,style:i,children:[e.jsxs("div",{className:"flex justify-between items-center mb-2",children:[e.jsxs("span",{className:"font-semibold text-sm text-foreground",children:["Question ",C+1," of ",w.length]}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[N.size," correct on first try"]})]}),e.jsx(t.Progress,{value:C+(S?1:0),max:w.length,size:"sm",className:"mb-3"}),g&&e.jsx(t.Card,{children:e.jsxs(t.CardContent,{className:"pt-6",children:[e.jsx(t.QuestionRenderer,{question:g,sessionAnswers:(j==null?void 0:j.map(y=>({uid:g.uid,answerUid:y.uid,content:y.content})))??[],onAnswer:y=>k(y),readOnly:l||S,showCorrectAnswers:S}),r&&S&&e.jsx(t.FeedbackBanner,{isCorrect:U,explanation:g.explanation,onRetry:a&&!U?x:void 0}),e.jsxs("div",{className:"flex justify-end gap-2 mt-2",children:[!S&&r&&e.jsx(t.Button,{onClick:h,disabled:!j||j.length===0||l,children:"Check Answer"}),(!r||S)&&e.jsx(t.Button,{onClick:v,disabled:l,children:C<w.length-1?"Next Question":"Finish"})]})]})})]})}function ae({questions:n,initialAnswers:r=[],onSubmit:a,onAnswerChange:d,timeLimitSeconds:f,timeElapsedSeconds:l,autoSubmitOnTimeout:m=!0,timeWarningThreshold:i=300,allowBackNavigation:w=!0,confirmBeforeSubmit:C=!0,examTitle:c,instructions:b,isSubmitting:D=!1,readOnly:u=!1,className:z,style:N}){const[T,j]=p.useState(0),[k,s]=p.useState(r),[o,g]=p.useState(new Set),[S,h]=p.useState(!1),[x,v]=p.useState(!1),U=p.useRef(!1),y=n[T],A=f-l;p.useEffect(()=>{A<=i&&A>0&&v(!0)},[A,i]),p.useEffect(()=>{m&&A<=0&&!U.current&&(U.current=!0,_(!0))},[A,m]);const F=p.useMemo(()=>n.map((B,P)=>({uid:B.uid,sequence:P+1,isFlagged:o.has(B.uid),isAnswered:k.some(L=>L.uid===B.uid),isSkipped:!1})),[n,k,o]);function I(B){if(!y)return;const P=y.uid,L=B.map(Q=>({uid:P,answerUid:Q.uid,content:Q.content}));s(Q=>{const H=[...Q.filter(K=>K.uid!==P),...L];return d==null||d(H),H})}function $(B){const P=n.findIndex(L=>L.uid===B);P!==-1&&j(P)}function R(B){g(P=>{const L=new Set(P);return L.has(B)?L.delete(B):L.add(B),L})}function J(){C?h(!0):_(!1)}function _(B){const P=new Set(k.map(Q=>Q.uid)),L={timeElapsedSeconds:l,wasAutoSubmitted:B,answeredCount:n.filter(Q=>P.has(Q.uid)).length,totalQuestions:n.length};a(k,L)}return e.jsxs("div",{className:t.cn(z),style:N,children:[c&&e.jsx("p",{className:"text-xl font-bold mb-2 text-foreground",children:c}),x&&A>0&&A<=i&&e.jsx(t.Alert,{variant:"warning",className:"mb-2",children:e.jsxs(t.AlertDescription,{children:[Math.ceil(A/60)," minute",Math.ceil(A/60)!==1?"s":""," remaining"]})}),e.jsx(t.AssessmentToolbar,{currentQuestionIndex:T,totalQuestions:n.length,hasNext:T<n.length-1,hasPrevious:w&&T>0,onNext:()=>j(B=>Math.min(B+1,n.length-1)),onPrevious:()=>w&&j(B=>Math.max(B-1,0)),onSubmit:J,timeElapsedSeconds:l,timeLimitSeconds:f,questions:F,onNavigateToQuestion:$,onToggleFlag:R,currentQuestionUid:y==null?void 0:y.uid,isSubmitting:D,readOnly:u}),b&&T===0&&e.jsx(t.Card,{className:"mt-3",children:e.jsx(t.CardContent,{className:"pt-6",children:b})}),y&&e.jsx(t.Card,{className:"mt-3",children:e.jsx(t.CardContent,{className:"pt-6",children:e.jsx(t.QuestionRenderer,{question:y,sessionAnswers:k.filter(B=>B.uid===y.uid),onAnswer:I,readOnly:u})})}),e.jsx(t.ConfirmDialog,{open:S,title:"Submit Exam?",message:`You have answered ${F.filter(B=>B.isAnswered).length} of ${n.length} questions. Once submitted, you cannot change your answers.`,confirmLabel:"Submit Exam",cancelLabel:"Continue Exam",confirmColor:"primary",onConfirm:()=>{h(!1),_(!1)},onCancel:()=>h(!1),isLoading:D})]})}function ie({title:n,description:r,questions:a,initialAnswers:d=[],onSubmit:f,onAnswerChange:l,showProgress:m=!0,requireAll:i=!1,submitLabel:w="Submit Survey",isSubmitting:C=!1,readOnly:c=!1,className:b,style:D}){const[u,z]=p.useState(d),N=p.useMemo(()=>{const s=new Set(u.map(o=>o.questionUid));return a.filter(o=>s.has(o.uid)).length},[a,u]),T=!i||N===a.length;function j(s,o){z(g=>{const h=[...g.filter(x=>x.questionUid!==s),{questionUid:s,value:o}];return l==null||l(h),h})}function k(s){return u.find(o=>o.questionUid===s)}return e.jsxs("div",{className:b,style:D,children:[e.jsx("p",{className:"text-xl font-bold text-foreground mb-2",children:n}),r&&e.jsx("div",{className:"mb-2 text-muted-foreground text-sm",children:typeof r=="string"?e.jsx("span",{children:r}):r}),m&&e.jsxs("div",{className:"mb-3",children:[e.jsx(t.Progress,{value:N/a.length*100}),e.jsxs("span",{className:"block text-xs text-muted-foreground mt-0.5",children:[N," of ",a.length," answered"]})]}),a.map((s,o)=>{var S,h;const g=k(s.uid);return e.jsx(t.Card,{className:"mb-2",children:e.jsxs(t.CardContent,{className:"pt-6",children:[e.jsxs("p",{className:"font-medium text-foreground mb-2",children:[o+1,". ",s.content,s.required&&e.jsx("span",{className:"text-destructive ml-0.5",children:"*"})]}),s.type==="likert"&&e.jsx(t.LikertScale,{value:g?Number(g.value):null,onChange:x=>j(s.uid,x),points:s.scalePoints,lowLabel:(S=s.scaleLabels)==null?void 0:S.low,highLabel:(h=s.scaleLabels)==null?void 0:h.high,readOnly:c}),s.type==="rating"&&e.jsx(t.StarRating,{value:g?Number(g.value):0,onChange:x=>j(s.uid,x),readOnly:c}),s.type==="open_text"&&e.jsx(t.Textarea,{placeholder:"Type your response...",value:(g==null?void 0:g.value)??"",onChange:x=>j(s.uid,x.target.value),disabled:c,className:"min-h-24"}),s.type==="choice"&&s.answers&&e.jsx("div",{className:"flex flex-col gap-2",children:s.answers.map(x=>e.jsxs("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:[e.jsx("input",{type:"radio",className:"accent-primary m-0 shrink-0",name:`survey-q-${s.uid}`,value:x.uid,checked:(g==null?void 0:g.value)===x.uid,onChange:()=>j(s.uid,x.uid),disabled:c}),e.jsx("span",{children:x.content})]},x.uid))}),s.type==="multiple_choice"&&s.answers&&e.jsx("div",{className:"flex flex-col gap-2",children:s.answers.map(x=>{const v=u.filter(U=>U.questionUid===s.uid).map(U=>String(U.value));return e.jsxs("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:[e.jsx("input",{type:"checkbox",className:"accent-primary m-0 shrink-0",checked:v.includes(x.uid),disabled:c,onChange:U=>{const y=u.filter(F=>F.questionUid===s.uid);let A;U.target.checked?A=[...y,{questionUid:s.uid,value:x.uid}]:A=y.filter(F=>String(F.value)!==x.uid),z(F=>[...F.filter(I=>I.questionUid!==s.uid),...A]),l==null||l([...u.filter(F=>F.questionUid!==s.uid),...A])}}),e.jsx("span",{children:x.content})]},x.uid)})})]})},s.uid)}),e.jsxs("div",{className:"flex justify-between items-center mt-3",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[N," of ",a.length," answered"]}),e.jsx(t.Button,{onClick:()=>f(u),disabled:!T||C||c,children:C?"Submitting...":w})]})]})}function ce({title:n,blocks:r,isCompleted:a=!1,onMarkComplete:d,onNextLesson:f,nextLessonTitle:l,estimatedDuration:m,showDuration:i=!0,readOnly:w=!1,className:C,style:c}){const[b,D]=p.useState(a),[,u]=p.useState(new Map);function z(T,j){u(k=>new Map(k).set(T,j))}function N(){D(!0),d==null||d()}return e.jsxs("div",{className:t.cn(C),style:c,children:[e.jsxs("div",{className:"mb-3",children:[e.jsx("p",{className:"text-2xl font-bold mb-0.5 text-foreground",children:n}),i&&m!=null&&e.jsxs("div",{className:"flex items-center gap-0.5 text-muted-foreground",children:[e.jsx(M.Clock,{size:16}),e.jsx("span",{className:"text-sm",children:t.formatDuration(m)})]})]}),e.jsx(t.Separator,{className:"mb-3"}),e.jsx("div",{className:"flex flex-col gap-3",children:r.map((T,j)=>e.jsx(t.ContentBlock,{block:T,onQuestionAnswer:z,readOnly:w},j))}),e.jsx("div",{className:"border border-border rounded-md px-4 py-3 mt-4 sticky bottom-0 bg-background z-10",children:e.jsxs("div",{className:"flex justify-between items-center",children:[b?e.jsxs("div",{className:"flex items-center gap-1 text-success",children:[e.jsx(M.Check,{size:20}),e.jsx("span",{className:"text-sm font-semibold",children:"Lesson Complete"})]}):e.jsxs(t.Button,{onClick:N,disabled:w,children:[e.jsx(M.Check,{size:18})," Mark Complete"]}),f&&e.jsxs(t.Button,{variant:b?"default":"outline",onClick:f,children:[l?`Next: ${l}`:"Next Lesson"," ",e.jsx(M.ChevronRight,{size:18})]})]})})]})}function Y(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}const Z={pdf:"document",document:"document",video:"video",link:"link",image:"document",archive:"document",other:"document"};function de({resources:n,categories:r,onResourceClick:a,onDownload:d,viewMode:f="list",allowViewToggle:l=!0,showSearch:m=!0,emptyMessage:i="No resources found",readOnly:w=!1,className:C,style:c}){const[b,D]=p.useState(""),[u,z]=p.useState(null),[N,T]=p.useState(f),j=p.useMemo(()=>{let s=n;if(u&&(s=s.filter(o=>o.categoryUid===u)),b.trim()){const o=b.toLowerCase();s=s.filter(g=>{var S;return g.name.toLowerCase().includes(o)||((S=g.description)==null?void 0:S.toLowerCase().includes(o))})}return s},[n,u,b]);function k(s){const o=Z[s.type]??"document";return e.jsxs("div",{className:t.cn("flex items-center gap-3 px-3 py-2",!w&&"cursor-pointer hover:bg-muted",w&&"opacity-70"),onClick:()=>!w&&a(s),children:[e.jsx("div",{className:"min-w-10",children:e.jsx(t.LearningObjectIcon,{type:o,size:20})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("span",{className:"text-sm text-foreground",children:s.name}),(s.description||s.fileSize!=null)&&e.jsx("span",{className:"text-sm text-muted-foreground",children:[s.description,s.fileSize!=null&&Y(s.fileSize)].filter(Boolean).join(" · ")})]}),d&&e.jsxs(t.Tooltip,{children:[e.jsx(t.TooltipTrigger,{children:e.jsx(t.Button,{variant:"ghost",size:"icon-xs","aria-label":"Download",onClick:g=>{g.stopPropagation(),d(s)},children:e.jsx(M.Download,{size:16})})}),e.jsx(t.TooltipContent,{children:"Download"})]})]},s.uid)}return e.jsxs("div",{className:C,style:c,children:[e.jsxs("div",{className:"flex gap-2 items-center mb-2",children:[m&&e.jsx("div",{className:"flex-1 max-w-80",children:e.jsx(t.SearchInput,{value:b,onChange:D,placeholder:"Search resources...",size:"small"})}),l&&e.jsxs("div",{className:"flex gap-0.5",children:[e.jsxs(t.Tooltip,{children:[e.jsx(t.TooltipTrigger,{children:e.jsx(t.Button,{variant:"ghost",size:"icon-xs","aria-label":"List view",className:t.cn(N==="list"&&"text-primary"),onClick:()=>T("list"),children:e.jsx(M.List,{size:18})})}),e.jsx(t.TooltipContent,{children:"List view"})]}),e.jsxs(t.Tooltip,{children:[e.jsx(t.TooltipTrigger,{children:e.jsx(t.Button,{variant:"ghost",size:"icon-xs","aria-label":"Grid view",className:t.cn(N==="grid"&&"text-primary"),onClick:()=>T("grid"),children:e.jsx(M.Grid,{size:18})})}),e.jsx(t.TooltipContent,{children:"Grid view"})]})]})]}),r&&r.length>0&&e.jsx(t.Tabs,{value:u??"all",onValueChange:s=>z(s==="all"?null:s),className:"mb-2",children:e.jsxs(t.TabsList,{children:[e.jsx(t.TabsTrigger,{value:"all",children:"All"}),r.map(s=>e.jsx(t.TabsTrigger,{value:s.uid,children:s.label},s.uid))]})}),j.length===0?e.jsx(t.EmptyState,{title:i,description:"Try adjusting your search or filter."}):N==="list"?e.jsx(t.Card,{children:j.map(k)}):e.jsx("div",{className:"grid grid-cols-[repeat(auto-fill,minmax(240px,1fr))] gap-2",children:j.map(s=>e.jsx(t.Card,{className:t.cn("transition-colors",!w&&"cursor-pointer hover:border-primary"),onClick:()=>!w&&a(s),children:e.jsxs(t.CardContent,{className:"pt-4 pb-4",children:[e.jsxs("div",{className:"flex gap-1 items-center mb-1",children:[e.jsx(t.LearningObjectIcon,{type:Z[s.type]??"document",size:20}),e.jsx("span",{className:"font-semibold text-sm text-foreground truncate",children:s.name})]}),s.description&&e.jsx("p",{className:"text-sm text-muted-foreground mb-1 truncate",children:s.description}),s.fileSize!=null&&e.jsx("span",{className:"text-xs text-muted-foreground",children:Y(s.fileSize)})]})},s.uid))})]})}function oe(n){const r=new Date(n),d=new Date().getTime()-r.getTime(),f=Math.floor(d/6e4);if(f<1)return"Just now";if(f<60)return`${f}m ago`;const l=Math.floor(f/60);if(l<24)return`${l}h ago`;const m=Math.floor(l/24);return m<7?`${m}d ago`:r.toLocaleDateString()}function ue({announcements:n,onMarkRead:r,onSelect:a,showAvatars:d=!0,previewLines:f=3,emptyMessage:l="No announcements yet",readOnly:m=!1,className:i,style:w}){const[C,c]=p.useState(new Set),b=p.useMemo(()=>{const u=n.filter(N=>N.isPinned),z=n.filter(N=>!N.isPinned);return[...u,...z]},[n]);function D(u){c(N=>{const T=new Set(N);return T.has(u)?T.delete(u):T.add(u),T});const z=n.find(N=>N.uid===u);z&&!z.isRead&&(r==null||r(u))}return b.length===0?e.jsx("div",{className:i,style:w,children:e.jsx(t.EmptyState,{title:l})}):e.jsx("div",{className:t.cn("flex flex-col gap-2",i),style:w,children:b.map(u=>{const z=C.has(u.uid);return e.jsx(t.Card,{className:t.cn(u.isRead&&"opacity-85",a&&"cursor-pointer",u.isPinned&&"border-l-4 border-l-warning"),onClick:()=>a&&!m?a(u):D(u.uid),children:e.jsx(t.CardContent,{className:"pt-4 pb-4",children:e.jsxs("div",{className:"flex gap-1.5 items-start",children:[d&&e.jsx(t.UserAvatar,{displayName:u.author.displayName,avatarUrl:u.author.avatarUrl,role:u.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:[u.isPinned&&e.jsx(M.Pin,{size:14}),e.jsx("span",{className:t.cn("text-foreground",u.isRead?"font-normal":"font-semibold"),children:u.title}),!u.isRead&&e.jsx(t.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:[u.author.displayName," · ",oe(u.createdAt)]}),e.jsx("span",{className:t.cn("text-sm text-foreground",!z&&"line-clamp-(--preview-lines) overflow-hidden"),style:z?void 0:{"--preview-lines":f},children:u.content}),!z&&u.content.length>200&&e.jsx(t.Button,{variant:"link",size:"xs",className:"px-0 mt-0.5 h-auto",onClick:N=>{N.stopPropagation(),D(u.uid)},children:"Read more"})]})]})})},u.uid)})})}function xe({title:n,rootPost:r,replies:a,currentUser:d,onReply:f,onToggleLike:l,onMarkAnswer:m,maxDepth:i=3,allowReplies:w=!0,sortOrder:C="oldest",readOnly:c=!1,className:b,style:D}){const[u,z]=p.useState(null),[N,T]=p.useState(""),j=p.useMemo(()=>{const o=new Map;for(const g of a){const S=g.parentUid??r.uid,h=o.get(S)??[];h.push(g),o.set(S,h)}for(const[,g]of o)g.sort((S,h)=>C==="newest"?new Date(h.createdAt).getTime()-new Date(S.createdAt).getTime():C==="most_liked"?h.likeCount-S.likeCount:new Date(S.createdAt).getTime()-new Date(h.createdAt).getTime());return o},[a,r.uid,C]);function k(o){N.trim()&&(f(o,N.trim()),T(""),z(null))}function s(o,g){const S=j.get(o.uid)??[],h=Math.min(g,i),x=e.jsxs("div",{className:"flex items-center gap-1",children:[l&&!c&&e.jsxs(t.Tooltip,{children:[e.jsx(t.TooltipTrigger,{children:e.jsxs(t.Button,{variant:"ghost",size:"sm","aria-label":o.isLikedByCurrentUser?"Unlike":"Like",className:t.cn(o.isLikedByCurrentUser&&"text-destructive"),onClick:()=>l(o.uid),children:[e.jsx(M.Heart,{size:14,fill:o.isLikedByCurrentUser?"currentColor":"none"}),o.likeCount>0?o.likeCount:"Like"]})}),e.jsx(t.TooltipContent,{children:o.isLikedByCurrentUser?"Unlike":"Like"})]}),w&&!c&&e.jsxs(t.Tooltip,{children:[e.jsx(t.TooltipTrigger,{children:e.jsxs(t.Button,{variant:"ghost",size:"sm","aria-label":"Reply",onClick:()=>z(o.uid),children:[e.jsx(M.Reply,{size:14}),"Reply"]})}),e.jsx(t.TooltipContent,{children:"Reply"})]}),m&&!c&&d.role!=="student"&&!o.isAnswer&&e.jsxs(t.Tooltip,{children:[e.jsx(t.TooltipTrigger,{children:e.jsxs(t.Button,{variant:"ghost",size:"sm","aria-label":"Mark as answer",className:"text-success",onClick:()=>m(o.uid),children:[e.jsx(M.CheckCircle,{size:14}),"Mark Answer"]})}),e.jsx(t.TooltipContent,{children:"Mark as answer"})]})]});return e.jsxs("div",{children:[e.jsx(t.PostCard,{author:o.author,content:o.content,createdAt:o.createdAt,updatedAt:o.updatedAt,actions:x,highlight:o.isAnswer?"answer":"none",indentLevel:h,className:"mb-2"}),u===o.uid&&e.jsx(t.Card,{className:"mb-2",style:{marginLeft:`${(h+1)*16}px`},children:e.jsxs(t.CardContent,{className:"pt-4 pb-4",children:[e.jsx(t.Textarea,{className:"min-h-15 mb-2",placeholder:"Write a reply...",value:N,onChange:v=>T(v.target.value)}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(t.Button,{size:"sm",onClick:()=>k(o.uid),disabled:!N.trim(),children:"Post Reply"}),e.jsx(t.Button,{variant:"ghost",size:"sm",onClick:()=>{z(null),T("")},children:"Cancel"})]})]})}),S.map(v=>s(v,g+1))]},o.uid)}return e.jsxs("div",{className:b,style:D,children:[e.jsxs("div",{className:"flex items-center gap-1 mb-2",children:[e.jsx(M.MessageSquare,{size:20,className:"text-foreground shrink-0"}),e.jsx("span",{className:"text-lg font-semibold text-foreground",children:n}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[a.length," ",a.length===1?"reply":"replies"]})]}),e.jsx(t.Separator,{className:"mb-2"}),s(r,0)]})}function me({title:n,instructions:r,dueDate:a,maxScore:d,status:f,submissionTypes:l,existingSubmission:m,fileConstraints:i,onSubmit:w,onSaveDraft:C,grade:c,isSubmitting:b=!1,readOnly:D=!1,className:u,style:z}){const[N,T]=p.useState((m==null?void 0:m.textContent)??""),[j,k]=p.useState((m==null?void 0:m.files)??[]),[s,o]=p.useState((m==null?void 0:m.url)??""),[g,S]=p.useState(l[0]),h=!D&&!["submitted","graded"].includes(f);function x(){return{textContent:l.includes("text")?N:void 0,files:l.includes("file")?j:void 0,url:l.includes("url")?s:void 0}}return e.jsxs("div",{className:u,style:z,children:[e.jsx("div",{className:"flex justify-between items-start mb-2",children:e.jsxs("div",{children:[e.jsx("div",{className:"text-xl font-bold text-foreground mb-0.5",children:n}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(t.StatusBadge,{status:f}),a&&e.jsx(t.DueDateDisplay,{dueDate:a,size:"small"}),d!=null&&e.jsxs("span",{className:"text-sm text-muted-foreground",children:[d," points"]})]})]})}),e.jsx(t.Card,{className:"mb-3",children:e.jsxs(t.CardContent,{className:"pt-6",children:[e.jsx("div",{className:"font-semibold text-sm text-foreground mb-1",children:"Instructions"}),e.jsx("div",{className:"text-muted-foreground text-sm",children:typeof r=="string"?e.jsx("span",{children:r}):r})]})}),c&&e.jsx(t.Alert,{variant:"success",className:"mb-3",children:e.jsxs(t.AlertDescription,{children:[e.jsxs("div",{className:"font-semibold text-sm mb-1",children:["Grade: ",c.score,d!=null?` / ${d}`:""]}),c.feedback&&e.jsx("div",{children:c.feedback})]})}),h&&e.jsxs(e.Fragment,{children:[l.length>1?e.jsxs(t.Tabs,{value:g,onValueChange:v=>S(v),children:[e.jsxs(t.TabsList,{children:[l.includes("text")&&e.jsx(t.TabsTrigger,{value:"text",children:"Text"}),l.includes("file")&&e.jsx(t.TabsTrigger,{value:"file",children:"File Upload"}),l.includes("url")&&e.jsx(t.TabsTrigger,{value:"url",children:"URL"})]}),l.includes("text")&&e.jsx(t.TabsContent,{value:"text",children:e.jsx(t.Textarea,{className:"min-h-45",placeholder:"Type your submission...",value:N,onChange:v=>T(v.target.value)})}),l.includes("file")&&e.jsx(t.TabsContent,{value:"file",children:e.jsx(t.FileUploadZone,{files:j,onFilesAdded:v=>k(U=>[...U,...v]),onFileRemove:v=>k(U=>U.filter((y,A)=>A!==v)),accept:i==null?void 0:i.acceptedTypes,maxFiles:i==null?void 0:i.maxFiles,maxSizeMB:i==null?void 0:i.maxSizeMB})}),l.includes("url")&&e.jsx(t.TabsContent,{value:"url",children:e.jsx(t.Input,{placeholder:"https://...",value:s,onChange:v=>o(v.target.value)})})]}):e.jsxs(e.Fragment,{children:[l.includes("text")&&e.jsx(t.Textarea,{className:"min-h-45 mb-2",placeholder:"Type your submission...",value:N,onChange:v=>T(v.target.value)}),l.includes("file")&&e.jsx("div",{className:"mb-2",children:e.jsx(t.FileUploadZone,{files:j,onFilesAdded:v=>k(U=>[...U,...v]),onFileRemove:v=>k(U=>U.filter((y,A)=>A!==v)),accept:i==null?void 0:i.acceptedTypes,maxFiles:i==null?void 0:i.maxFiles,maxSizeMB:i==null?void 0:i.maxSizeMB})}),l.includes("url")&&e.jsx(t.Input,{className:"mb-2",placeholder:"https://...",value:s,onChange:v=>o(v.target.value)})]}),e.jsx(t.Separator,{className:"my-2"}),e.jsxs("div",{className:"flex gap-2 justify-end",children:[C&&e.jsxs(t.Button,{variant:"outline",onClick:()=>C(x()),disabled:b,children:[e.jsx(M.Save,{size:16}),"Save Draft"]}),e.jsxs(t.Button,{onClick:()=>w(x()),disabled:b,children:[e.jsx(M.Send,{size:16}),b?"Submitting...":"Submit"]})]})]})]})}function E({label:n,field:r,sortField:a,sortDir:d,onSort:f,textAlign:l}){const m=a===r;return e.jsx(t.TableHead,{className:t.cn("cursor-pointer select-none hover:bg-muted",l==="right"&&"text-right"),onClick:()=>f(r),children:e.jsxs("div",{className:t.cn("flex items-center gap-1",l==="right"&&"justify-end"),children:[e.jsx("span",{className:t.cn(m?"text-foreground":"text-muted-foreground"),children:n}),m&&(d==="asc"?e.jsx(M.ArrowUp,{size:14}):e.jsx(M.ArrowDown,{size:14}))]})})}function he({items:n,categories:r,overallGrade:a,showWeights:d=!0,showCategoryTotals:f=!0,onItemClick:l,readOnly:m=!1,className:i,style:w}){const[C,c]=p.useState("dueDate"),[b,D]=p.useState("asc");function u(j){C===j?D(k=>k==="asc"?"desc":"asc"):(c(j),D("asc"))}const z=p.useMemo(()=>{const j=[...n];return j.sort((k,s)=>{let o=0;switch(C){case"name":o=k.name.localeCompare(s.name);break;case"score":o=(k.score??-1)-(s.score??-1);break;case"dueDate":o=(k.dueDate??"").localeCompare(s.dueDate??"");break;case"status":o=k.status.localeCompare(s.status);break}return b==="asc"?o:-o}),j},[n,C,b]),N=p.useMemo(()=>{if(!r||r.length===0)return[{category:null,items:z}];const j=r.map(s=>({category:s,items:z.filter(o=>o.categoryUid===s.uid)})),k=z.filter(s=>!s.categoryUid);return k.length>0&&j.push({category:null,items:k}),j},[z,r]),T=d?5:4;return e.jsxs("div",{className:i,style:w,children:[a&&e.jsx(t.Card,{className:"mb-3",children:e.jsx(t.CardContent,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(t.GradeIndicator,{percentage:a.percentage,letterGrade:a.letterGrade,size:"large",passingThreshold:60}),e.jsxs("div",{children:[e.jsx("div",{className:"text-lg font-semibold text-foreground",children:"Overall Grade"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[a.pointsEarned," / ",a.pointsPossible," points"]})]})]})})}),e.jsx(t.Card,{children:e.jsxs(t.Table,{children:[e.jsx(t.TableHeader,{children:e.jsxs(t.TableRow,{children:[e.jsx(E,{label:"Assignment",field:"name",sortField:C,sortDir:b,onSort:u}),e.jsx(E,{label:"Status",field:"status",sortField:C,sortDir:b,onSort:u}),e.jsx(E,{label:"Due Date",field:"dueDate",sortField:C,sortDir:b,onSort:u}),e.jsx(E,{label:"Score",field:"score",sortField:C,sortDir:b,onSort:u,textAlign:"right"}),d&&e.jsx(t.TableHead,{className:"text-right text-muted-foreground",children:"Weight"})]})}),e.jsx(t.TableBody,{children:N.map((j,k)=>e.jsxs(p.Fragment,{children:[j.category&&f&&e.jsx(t.TableRow,{className:"bg-muted hover:bg-muted",children:e.jsx(t.TableCell,{colSpan:T,children:e.jsxs("span",{className:"font-semibold text-sm text-foreground",children:[j.category.name,j.category.weight!=null&&` (${j.category.weight}%)`]})})}),j.items.map(s=>e.jsxs(t.TableRow,{className:t.cn(l&&!m&&"cursor-pointer"),onClick:()=>l&&!m?l(s):void 0,children:[e.jsx(t.TableCell,{children:s.name}),e.jsx(t.TableCell,{children:e.jsx(t.StatusBadge,{status:s.status,size:"small"})}),e.jsx(t.TableCell,{children:s.dueDate?e.jsx(t.DueDateDisplay,{dueDate:s.dueDate,submittedDate:s.submittedDate,size:"small"}):"—"}),e.jsx(t.TableCell,{className:"text-right",children:s.score!=null?e.jsxs("span",{className:"text-sm font-semibold text-foreground",children:[s.score," / ",s.maxScore]}):s.status==="excused"?e.jsx("span",{className:"text-sm text-muted-foreground",children:"Excused"}):e.jsx("span",{className:"text-sm text-muted-foreground",children:"—"})}),d&&e.jsx(t.TableCell,{className:"text-right",children:s.weight!=null?`${s.weight}%`:"—"})]},s.uid))]},k))})]})})]})}const fe={lesson_completed:M.BookOpen,quiz_passed:M.CheckCircle,assignment_submitted:M.Send,badge_earned:M.Award};function je({overallProgress:n,totalTimeSpent:r,modules:a,recentActivity:d,streak:f,achievements:l,recentActivityLimit:m=5,onModuleClick:i,className:w,style:C}){return e.jsxs("div",{className:w,style:C,children:[e.jsxs("div",{className:"grid grid-cols-[repeat(auto-fit,minmax(160px,1fr))] gap-2 mb-3",children:[e.jsx(t.Card,{className:"p-2 flex justify-center",children:e.jsx(t.ProgressRing,{value:n,size:100})}),e.jsx(t.StatCard,{icon:e.jsx(M.Clock,{size:24}),label:"Time Spent",value:t.formatDuration(r)}),f&&e.jsx(t.StatCard,{icon:e.jsx(M.Flame,{size:24}),label:"Current Streak",value:`${f.currentDays} days`,subtitle:`Longest: ${f.longestDays} days`}),e.jsx(t.StatCard,{icon:e.jsx(M.BookOpen,{size:24}),label:"Modules",value:`${a.filter(c=>c.completedItems===c.totalItems).length} / ${a.length}`,subtitle:"completed"})]}),e.jsx("p",{className:"text-lg font-semibold mb-2 text-foreground",children:"Module Progress"}),e.jsx("div",{className:"flex flex-col gap-2 mb-3",children:a.map(c=>{const b=c.totalItems>0?c.completedItems/c.totalItems*100:0;return e.jsxs(t.Card,{className:t.cn("p-2 transition-colors",i&&"cursor-pointer hover:border-primary"),onClick:()=>i==null?void 0:i(c.uid),children:[e.jsxs("div",{className:"flex justify-between items-center mb-0.5",children:[e.jsx("span",{className:"font-semibold text-sm text-foreground",children:c.name}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[c.completedItems," / ",c.totalItems]})]}),e.jsx(t.Progress,{value:b,size:"sm"})]},c.uid)})}),d&&d.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-lg font-semibold mb-2 text-foreground",children:"Recent Activity"}),e.jsx("div",{className:"flex flex-col gap-1.5 mb-3",children:d.slice(0,m).map(c=>{const b=fe[c.type]??M.CheckCircle;return e.jsxs("div",{className:"flex gap-1.5 items-center",children:[e.jsx(b,{size:16}),e.jsx("span",{className:"flex-1 text-sm text-foreground",children:c.description}),e.jsx("span",{className:"text-xs text-muted-foreground",children:new Date(c.timestamp).toLocaleDateString()})]},c.uid)})})]}),l&&l.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-lg font-semibold mb-2 text-foreground",children:"Achievements"}),e.jsx("div",{className:"grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-2",children:l.map(c=>e.jsxs(t.Card,{className:"p-2 text-center",children:[c.iconUrl?e.jsx("img",{src:c.iconUrl,alt:c.name,className:"w-12 h-12 mb-1 mx-auto"}):e.jsx(M.Trophy,{size:32,className:"mx-auto mb-2 text-warning"}),e.jsx("p",{className:"font-semibold text-sm text-foreground",children:c.name}),e.jsx("p",{className:"text-xs text-muted-foreground",children:c.description})]},c.uid))})]})]})}const pe={classic:"border-[3px] border-double border-warning bg-linear-to-br from-[#fffbe6] to-[#fff8e1]",modern:"border border-primary bg-linear-to-br from-[#fff5f5] to-[#fee2e2]",minimal:"border border-border"};function ge({recipientName:n,courseTitle:r,completionDate:a,organizationName:d,organizationLogo:f,signatory:l,certificateId:m,variant:i="classic",showActions:w=!0,onPrint:C,onDownload:c,className:b,style:D}){const u=(()=>{try{return new Date(a).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}catch{return a}})();function z(){C?C():window.print()}return e.jsxs("div",{className:b,style:D,children:[e.jsxs("div",{className:t.cn("p-3 sm:p-5 md:p-6 text-center max-w-200 mx-auto rounded-md",pe[i]),children:[f?e.jsx("img",{src:f,alt:d,className:"h-15 mb-2 mx-auto block"}):e.jsx(M.Award,{size:48,className:t.cn("mx-auto mb-4",i==="classic"&&"text-warning")}),e.jsx("p",{className:"uppercase tracking-[3px] text-sm text-foreground/70",children:"Certificate of Completion"}),e.jsx(t.Separator,{className:"my-2 mx-auto max-w-50"}),e.jsx("p",{className:"text-sm text-foreground mb-1",children:"This is to certify that"}),e.jsx("p",{className:t.cn("text-2xl font-bold mb-2 text-foreground",i==="classic"&&"font-serif"),children:n}),e.jsx("p",{className:"text-sm text-foreground mb-1",children:"has successfully completed"}),e.jsx("p",{className:"text-xl font-bold mb-2 text-primary",children:r}),e.jsxs("p",{className:"text-sm text-foreground mb-3",children:["Issued by ",d," on ",u]}),l&&e.jsxs("div",{className:"mt-4 mb-2",children:[e.jsx(t.Separator,{className:"my-2 mx-auto max-w-50"}),e.jsx("p",{className:"font-semibold text-sm text-foreground",children:l.name}),e.jsx("p",{className:"text-xs text-muted-foreground",children:l.title})]}),m&&e.jsxs("span",{className:"block text-xs text-muted-foreground mt-2",children:["Certificate ID: ",m]})]}),w&&e.jsxs("div",{className:"flex justify-center gap-2 mt-3",children:[e.jsxs(t.Button,{variant:"outline",onClick:z,children:[e.jsx(M.Printer,{size:16})," Print"]}),c&&e.jsxs(t.Button,{variant:"outline",onClick:c,children:[e.jsx(M.Download,{size:16})," Download"]})]})]})}exports.AnnouncementFeed=ue;exports.AssessmentReview=te;exports.AssignmentSubmission=me;exports.CertificateViewer=ge;exports.CourseOutline=se;exports.DiscussionThread=xe;exports.ExamSession=ae;exports.FlashcardStudySession=O;exports.GradebookTable=he;exports.LecturePlayer=X;exports.LessonPage=ce;exports.PracticeQuiz=le;exports.ProgressDashboard=je;exports.QuizSession=W;exports.ResourceLibrary=de;exports.ScrollableQuiz=ne;exports.SurveyForm=ie;
|
|
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;
|