@hydralms/components 0.1.2 → 0.2.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/ForumBoard-CHXU3mjC.js +2207 -0
- package/dist/ForumBoard-d1w5-r6n.cjs +1 -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/types.d.ts +52 -4
- package/dist/assessment-toolbar/use-countdown.d.ts +43 -0
- package/dist/common/index.d.ts +2 -1
- package/dist/common/stepper.d.ts +6 -0
- package/dist/common/types.d.ts +37 -0
- package/dist/components.css +1 -1
- package/dist/content/attachment-list.d.ts +6 -0
- package/dist/content/content-block.d.ts +1 -1
- package/dist/content/index.d.ts +2 -1
- package/dist/content/types.d.ts +39 -0
- package/dist/curriculum/curriculum-item.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +551 -312
- package/dist/modules/AssignmentModule/AssignmentModule.d.ts +8 -0
- package/dist/modules/AssignmentModule/types.d.ts +65 -0
- package/dist/modules/CertificateModule/CertificateModule.d.ts +9 -0
- package/dist/modules/CertificateModule/types.d.ts +49 -0
- package/dist/modules/DiscussionModule/DiscussionModule.d.ts +8 -0
- package/dist/modules/DiscussionModule/types.d.ts +47 -0
- package/dist/modules/ExamModule/ExamModule.d.ts +8 -0
- package/dist/modules/ExamModule/types.d.ts +64 -0
- package/dist/modules/GradeCenterModule/GradeCenterModule.d.ts +9 -0
- package/dist/modules/GradeCenterModule/types.d.ts +54 -0
- package/dist/modules/QuizModule/QuizModule.d.ts +1 -1
- package/dist/modules/QuizModule/types.d.ts +6 -1
- package/dist/modules/SurveyModule/SurveyModule.d.ts +7 -0
- package/dist/modules/SurveyModule/types.d.ts +49 -0
- package/dist/modules/index.d.ts +12 -0
- package/dist/modules.cjs +1 -0
- package/dist/modules.js +1422 -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 +97 -0
- package/dist/questions/essay.d.ts +1 -1
- package/dist/questions/hotspot.d.ts +21 -0
- package/dist/questions/index.d.ts +9 -1
- package/dist/questions/inline-choice.d.ts +21 -0
- package/dist/questions/matching.d.ts +22 -0
- package/dist/questions/numeric.d.ts +11 -0
- package/dist/questions/ordering.d.ts +12 -0
- 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/types.d.ts +106 -1
- package/dist/questions/use-drag-reorder.d.ts +17 -0
- package/dist/sections/CertificateViewer/types.d.ts +7 -5
- package/dist/sections/ExamSession/ExamSession.d.ts +1 -1
- package/dist/sections/ExamSession/types.d.ts +6 -1
- package/dist/sections/ForumBoard/ForumBoard.d.ts +8 -0
- package/dist/sections/ForumBoard/types.d.ts +64 -0
- package/dist/sections/QuizSession/QuizSession.d.ts +1 -1
- package/dist/sections/QuizSession/types.d.ts +6 -1
- package/dist/sections/RequirementsChecklist/RequirementsChecklist.d.ts +8 -0
- package/dist/sections/RequirementsChecklist/types.d.ts +37 -0
- package/dist/sections/RubricView/RubricView.d.ts +9 -0
- package/dist/sections/RubricView/types.d.ts +50 -0
- package/dist/sections/index.d.ts +7 -1
- package/dist/sections.cjs +1 -1
- package/dist/sections.js +250 -1715
- package/dist/social/post-card.d.ts +1 -1
- package/dist/tabs-DRM2Iq_J.cjs +172 -0
- package/dist/tabs-Wf3h_Cx3.js +21580 -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 +3 -0
- package/dist/ui/progress.d.ts +1 -1
- package/dist/ui/rich-text-editor.d.ts +30 -0
- package/dist/ui/rich-text-toolbar.d.ts +8 -0
- package/dist/utils/array-utils.d.ts +4 -0
- 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/shuffle.d.ts +1 -0
- package/dist/utils/string-utils.d.ts +12 -0
- package/dist/video/video-bookmark.d.ts +1 -1
- package/dist/video/video-playlist-item.d.ts +1 -1
- package/package.json +141 -3
- 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 +3 -31
- package/src/assessment-toolbar/timer-display.tsx +2 -2
- package/src/assessment-toolbar/types.ts +54 -4
- package/src/assessment-toolbar/use-countdown.ts +153 -0
- package/src/common/index.ts +3 -0
- package/src/common/search-input.tsx +7 -6
- package/src/common/stepper.tsx +100 -0
- package/src/common/types.ts +39 -0
- package/src/content/attachment-list.tsx +90 -0
- package/src/content/content-block.tsx +4 -2
- package/src/content/file-upload-zone.tsx +1 -6
- package/src/content/index.ts +3 -0
- package/src/content/types.ts +41 -0
- package/src/curriculum/curriculum-item.tsx +7 -3
- package/src/feedback/feedback-banner.tsx +12 -14
- package/src/flashcards/flashcard-deck.tsx +1 -9
- package/src/flashcards/flashcard.tsx +1 -1
- package/src/modules/AssignmentModule/AssignmentModule.tsx +305 -0
- package/src/modules/AssignmentModule/types.ts +73 -0
- package/src/modules/CertificateModule/CertificateModule.tsx +161 -0
- package/src/modules/CertificateModule/types.ts +47 -0
- package/src/modules/CoursePlayer/CoursePlayer.tsx +44 -48
- package/src/modules/DiscussionModule/DiscussionModule.tsx +110 -0
- package/src/modules/DiscussionModule/types.ts +54 -0
- package/src/modules/ExamModule/ExamModule.tsx +285 -0
- package/src/modules/ExamModule/types.ts +66 -0
- package/src/modules/FlashcardLab/FlashcardLab.tsx +29 -16
- package/src/modules/GradeCenterModule/GradeCenterModule.tsx +169 -0
- package/src/modules/GradeCenterModule/types.ts +63 -0
- package/src/modules/QuizModule/QuizModule.tsx +88 -88
- package/src/modules/QuizModule/types.ts +6 -1
- package/src/modules/SurveyModule/SurveyModule.tsx +180 -0
- package/src/modules/SurveyModule/types.ts +51 -0
- package/src/modules/index.ts +24 -0
- package/src/progress/achievement-badge.tsx +52 -0
- package/src/progress/activity-timeline.tsx +84 -0
- package/src/progress/index.ts +7 -0
- package/src/progress/stat-card.tsx +30 -18
- package/src/progress/streak-badge.tsx +35 -0
- package/src/progress/types.ts +101 -0
- package/src/questions/choice.tsx +7 -9
- package/src/questions/essay.tsx +23 -25
- package/src/questions/fill-in-the-blank.tsx +13 -16
- package/src/questions/hotspot.tsx +154 -0
- package/src/questions/index.ts +16 -0
- package/src/questions/inline-choice.tsx +151 -0
- package/src/questions/matching.tsx +228 -0
- package/src/questions/multiple-choice.tsx +7 -9
- package/src/questions/numeric.tsx +102 -0
- package/src/questions/ordering.tsx +159 -0
- package/src/questions/question-renderer.tsx +21 -0
- package/src/questions/scenario.tsx +140 -0
- package/src/questions/scoring.ts +201 -0
- package/src/questions/spreadsheet.tsx +259 -0
- package/src/questions/true-false.tsx +7 -9
- package/src/questions/types.ts +123 -1
- package/src/questions/use-drag-reorder.ts +80 -0
- package/src/sections/AnnouncementFeed/AnnouncementFeed.tsx +2 -15
- package/src/sections/AssessmentReview/AssessmentReview.tsx +13 -2
- package/src/sections/AssignmentSubmission/AssignmentSubmission.tsx +7 -5
- package/src/sections/CertificateViewer/CertificateViewer.tsx +409 -56
- package/src/sections/CertificateViewer/types.ts +13 -5
- package/src/sections/CourseOutline/CourseOutline.tsx +4 -14
- package/src/sections/DiscussionThread/DiscussionThread.tsx +13 -10
- package/src/sections/ExamSession/ExamSession.tsx +44 -7
- package/src/sections/ExamSession/types.ts +6 -1
- package/src/sections/ForumBoard/ForumBoard.tsx +284 -0
- package/src/sections/ForumBoard/types.ts +67 -0
- package/src/sections/GradebookTable/GradebookTable.tsx +1 -1
- package/src/sections/LecturePlayer/LecturePlayer.tsx +1 -1
- package/src/sections/LessonPage/LessonPage.tsx +5 -9
- package/src/sections/PracticeQuiz/PracticeQuiz.tsx +15 -26
- package/src/sections/ProgressDashboard/ProgressDashboard.tsx +65 -65
- package/src/sections/QuizSession/QuizSession.tsx +67 -8
- package/src/sections/QuizSession/types.ts +6 -1
- package/src/sections/RequirementsChecklist/RequirementsChecklist.tsx +107 -0
- package/src/sections/RequirementsChecklist/types.ts +38 -0
- package/src/sections/ResourceLibrary/ResourceLibrary.tsx +4 -9
- package/src/sections/RubricView/RubricView.tsx +138 -0
- package/src/sections/RubricView/types.ts +52 -0
- package/src/sections/ScrollableQuiz/ScrollableQuiz.tsx +23 -9
- package/src/sections/SurveyForm/SurveyForm.tsx +8 -5
- package/src/sections/index.ts +20 -1
- package/src/social/post-card.tsx +8 -19
- package/src/social/user-avatar.tsx +1 -0
- package/src/styles/globals.css +13 -0
- package/src/ui/drawer.tsx +600 -0
- package/src/ui/index.ts +19 -0
- package/src/ui/rich-text-editor.tsx +109 -0
- package/src/ui/rich-text-toolbar.tsx +156 -0
- package/src/utils/array-utils.ts +17 -0
- 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/shuffle.ts +8 -0
- package/src/utils/string-utils.ts +30 -0
- package/src/video/video-bookmark.tsx +4 -3
- package/src/video/video-chapter-list.tsx +9 -4
- package/src/video/video-player.tsx +11 -4
- 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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const e=require("react/jsx-runtime"),p=require("react"),L=require("lucide-react"),s=require("./tabs-DRM2Iq_J.cjs"),K=require("class-variance-authority");function ne({questions:t,initialAnswers:r=[],onSubmit:i,onAnswerChange:o,timeElapsedSeconds:m,timeLimitSeconds:a,questionMaterials:c,isSubmitting:n=!1,readOnly:N=!1,className:f,style:u}){const[g,w]=p.useState(0),[v,z]=p.useState(r),[C,U]=p.useState(new Set),[j,S]=p.useState(!1),l=t[g],d=p.useMemo(()=>l?v.filter(x=>x.uid===l.uid):[],[v,l]),h=p.useMemo(()=>(c==null?void 0:c.filter(x=>x.questionUid===(l==null?void 0:l.uid)))??[],[c,l]),B=p.useMemo(()=>t.map((x,b)=>({uid:x.uid,sequence:b,isFlagged:C.has(x.uid),isAnswered:v.some(y=>y.uid===x.uid),isSkipped:!1})),[t,v,C]);function R(x){if(!l)return;const b=l.uid,y=x.map(k=>({uid:b,answerUid:k.uid,content:k.content}));z(k=>{const E=[...k.filter(_=>_.uid!==b),...y];return o==null||o(E),E})}function T(x){const b=t.findIndex(y=>y.uid===x);b!==-1&&w(b)}function A(x){U(b=>{const y=new Set(b);return y.has(x)?y.delete(x):y.add(x),y})}function D(){i(v)}return e.jsxs("div",{className:s.cn(f),style:u,children:[e.jsx(s.AssessmentToolbar,{currentQuestionIndex:g,totalQuestions:t.length,hasNext:g<t.length-1,hasPrevious:g>0,onNext:()=>w(x=>Math.min(x+1,t.length-1)),onPrevious:()=>w(x=>Math.max(x-1,0)),onSubmit:D,timeElapsedSeconds:m,timeLimitSeconds:a,questions:B,onNavigateToQuestion:T,currentQuestionUid:l==null?void 0:l.uid,isSubmitting:n,readOnly:N}),l&&e.jsxs(s.Card,{className:"mt-3",children:[e.jsx(s.CardHeader,{className:"pb-0",children:e.jsx(s.QuestionHeaderBar,{questionNumber:g+1,totalQuestions:t.length,isFlagged:C.has(l.uid),onToggleFlag:()=>A(l.uid),hasMaterials:h.length>0,onOpenMaterials:()=>S(!0),readOnly:N})}),e.jsx(s.CardContent,{children:e.jsx(s.QuestionRenderer,{question:l,sessionAnswers:d,onAnswer:R,readOnly:N})})]}),!N&&e.jsxs("div",{className:"flex items-center justify-between gap-3 mt-3",children:[e.jsxs(s.Button,{variant:"outline",disabled:g<=0,onClick:()=>w(x=>Math.max(x-1,0)),children:[e.jsx(L.ChevronLeft,{className:"size-4 mr-1"}),"Previous"]}),g<t.length-1?e.jsxs(s.Button,{onClick:()=>w(x=>Math.min(x+1,t.length-1)),children:["Next",e.jsx(L.ChevronRight,{className:"size-4 ml-1"})]}):e.jsxs(s.Button,{onClick:D,disabled:n,children:[n?"Submitting...":"Submit Quiz",!n&&e.jsx(L.Send,{className:"size-4 ml-1"})]})]}),e.jsx(s.QuestionMaterialsDrawer,{open:j,onOpenChange:S,materials:h,questionNumber:g+1})]})}function re({video:t,notes:r,layout:i="horizontal",notesPanelWidth:o="340px",notesPanelHeight:m="240px",className:a,style:c}){const n=i==="horizontal";return r?e.jsxs("div",{className:s.cn("flex overflow-hidden gap-4",n?"flex-row":"flex-col",a),style:c,children:[e.jsx("div",{className:"flex-1 min-w-0 min-h-0",children:e.jsx(s.VideoPlayer,{...t})}),e.jsxs(s.Card,{className:s.cn("overflow-auto shrink-0 rounded-none border-0",n?"border-l border-border":"border-t border-border w-full"),style:{width:n?o:void 0,height:n?void 0:m},children:[e.jsx(s.CardHeader,{children:e.jsx(s.CardTitle,{children:"Notes"})}),e.jsx(s.CardContent,{children:typeof r=="string"?e.jsx("span",{className:"text-sm text-foreground",children:r}):r})]})]}):e.jsx("div",{className:a,style:c,children:e.jsx(s.VideoPlayer,{...t})})}function ae({cards:t,title:r,description:i,shuffled:o=!1,onComplete:m,readOnly:a=!1,className:c,style:n}){const[N,f]=p.useState(!1),u={totalCards:t.length,wasShuffled:o};function g(){f(!0),m==null||m(u)}function w(){f(!1)}return N?e.jsx("div",{className:s.cn("flex flex-col items-center",c),style:n,children:e.jsx(s.Card,{children:e.jsxs(s.CardContent,{className:"pt-6 text-center flex flex-col items-center gap-2",children:[e.jsx(L.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:[u.totalCards," card",u.totalCards!==1?"s":""," studied",u.wasShuffled?" (shuffled)":""]}),e.jsx(s.Button,{className:"mt-2",onClick:w,children:"Study Again"})]})})}):e.jsx("div",{className:s.cn("flex flex-col items-center",c),style:n,children:e.jsx(s.FlashcardDeck,{cards:t,deckName:r,deckDescription:i,shuffled:o,showProgress:!0,onComplete:g,readOnly:a})})}function le({score:t}){const r=t.percentage!==void 0?t.percentage:t.total>0?Math.round(t.correct/t.total*100):0;return e.jsx(s.Card,{className:"mb-3",children:e.jsx(s.CardContent,{className:"pt-6",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("div",{className:"flex items-baseline gap-2",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:[t.correct," of ",t.total," correct"]})]}),t.passed!==void 0&&e.jsx(s.Badge,{variant:t.passed?"success":"destructive",children:t.passed?"Passed":"Failed"}),t.passingScore!==void 0&&e.jsxs("span",{className:"text-sm text-muted-foreground",children:["Passing score: ",t.passingScore,"%"]})]})})})}function W({questions:t,sessionAnswers:r,showCorrectAnswers:i}){const o=p.useMemo(()=>{const m=new Map;for(const a of r){const c=m.get(a.uid);c?c.push(a):m.set(a.uid,[a])}return m},[r]);return e.jsx("div",{className:"flex flex-col gap-3",children:t.map((m,a)=>e.jsxs(s.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 ",a+1]})}),e.jsx(s.Separator,{}),e.jsx(s.CardContent,{className:"pt-4 pb-4",children:e.jsx(s.QuestionRenderer,{question:m,sessionAnswers:o.get(m.uid)??[],readOnly:!0,showCorrectAnswers:i})})]},m.uid))})}function ie(t,r,i,o){const m=new Map(t.map(n=>[n.uid,n])),a=new Set(i.flatMap(n=>n.questionUids)),c=t.filter(n=>!a.has(n.uid));return e.jsxs("div",{className:"flex flex-col gap-4",children:[i.map(n=>{const N=n.questionUids.map(f=>m.get(f)).filter(Boolean);return e.jsxs("div",{children:[e.jsx("span",{className:"uppercase text-xs tracking-wide text-muted-foreground font-semibold",children:n.label}),e.jsx(s.Separator,{className:"mb-2"}),e.jsx(W,{questions:N,sessionAnswers:r,showCorrectAnswers:o})]},n.label)}),c.length>0&&e.jsx("div",{children:e.jsx(W,{questions:c,sessionAnswers:r,showCorrectAnswers:o})})]})}function de({questions:t,sessionAnswers:r,score:i,questionGroups:o,showCorrectAnswers:m=!0,className:a,style:c}){return e.jsxs("div",{className:s.cn(a),style:c,children:[i&&e.jsx(le,{score:i}),o&&o.length>0?ie(t,r,o,m):e.jsx(W,{questions:t,sessionAnswers:r,showCorrectAnswers:m})]})}function G(t){const r=[];for(const i of t)!i.children||i.children.length===0?r.push(i.uid):r.push(...G(i.children));return r}function ce({items:t,progress:r,courseTitle:i,activeItemUid:o,onItemClick:m,showOverallProgress:a=!0,showDuration:c=!0,showIcons:n=!0,readOnly:N=!1,className:f,style:u}){const{completedCount:g,totalCount:w,percentage:v}=p.useMemo(()=>{const z=G(t),C=z.length,U=r?z.filter(j=>r.some(S=>S.resourceUid===j&&S.isCompleted)).length:0;return{completedCount:U,totalCount:C,percentage:C>0?Math.round(U/C*100):0}},[t,r]);return e.jsxs("div",{className:s.cn(f),style:u,children:[(i||a)&&e.jsxs("div",{className:"px-2 pt-2 pb-2",children:[i&&e.jsx("p",{className:s.cn("font-semibold text-sm text-foreground",a&&"mb-1"),children:i}),a&&e.jsxs("div",{children:[e.jsx(s.Progress,{value:v,size:"sm"}),e.jsxs("span",{className:"text-xs text-muted-foreground mt-0.5 block",children:[g," of ",w," completed"]})]})]}),(i||a)&&e.jsx(s.Separator,{}),e.jsx(s.CurriculumTree,{items:t,progress:r,activeItemUid:o,onItemClick:m,readOnly:N,showDuration:c,showIcons:n,showProgress:!0})]})}function oe({questions:t,instantFeedback:r=!0,allowRetry:i=!0,onComplete:o,shuffled:m=!1,readOnly:a=!1,className:c,style:n}){const N=p.useMemo(()=>m?s.shuffle(t):t,[t,m]),[f,u]=p.useState(0),[g,w]=p.useState(new Set),[v,z]=p.useState(new Map),[C,U]=p.useState(new Set),[j,S]=p.useState(null),[l,d]=p.useState(!1),h=N[f],B=h?g.has(h.uid):!1;function R(){if(!h||!j)return;const x=(v.get(h.uid)??0)+1;z(k=>new Map(k).set(h.uid,x)),w(k=>new Set(k).add(h.uid));const b=j.map(k=>({uid:h.uid,answerUid:k.uid,content:k.content}));s.scoreQuestion(h,b)===!0&&x===1&&U(k=>new Set(k).add(h.uid))}function T(){h&&(w(x=>{const b=new Set(x);return b.delete(h.uid),b}),S(null))}function A(){if(f<N.length-1)u(x=>x+1),S(null);else{const x={totalQuestions:N.length,correctOnFirstAttempt:C.size,totalAttempts:Array.from(v.values()).reduce((b,y)=>b+y,0)};d(!0),o==null||o(x)}}const D=p.useMemo(()=>{if(!h||!j)return!1;const x=j.map(b=>({uid:h.uid,answerUid:b.uid,content:b.content}));return s.scoreQuestion(h,x)===!0},[h,j]);if(l){const x=N.length>0?Math.round(C.size/N.length*100):0;return e.jsx(s.Card,{className:c,style:n,children:e.jsxs(s.CardContent,{className:"pt-6 text-center",children:[e.jsx(L.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:[C.size," of ",N.length," correct on first attempt (",x,"%)"]}),e.jsx("div",{className:"flex justify-center",children:e.jsx(s.Button,{variant:"outline",onClick:()=>{u(0),w(new Set),z(new Map),U(new Set),S(null),d(!1)},children:"Practice Again"})})]})})}return e.jsxs("div",{className:c,style:n,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 ",f+1," of ",N.length]}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[C.size," correct on first try"]})]}),e.jsx(s.Progress,{value:f+(B?1:0),max:N.length,size:"sm",className:"mb-3"}),h&&e.jsx(s.Card,{children:e.jsxs(s.CardContent,{className:"pt-6",children:[e.jsx(s.QuestionRenderer,{question:h,sessionAnswers:(j==null?void 0:j.map(x=>({uid:h.uid,answerUid:x.uid,content:x.content})))??[],onAnswer:x=>S(x),readOnly:a||B,showCorrectAnswers:B}),r&&B&&e.jsx(s.FeedbackBanner,{isCorrect:D,explanation:h.explanation,onRetry:i&&!D?T:void 0}),e.jsxs("div",{className:"flex justify-end gap-2 mt-2",children:[!B&&r&&e.jsx(s.Button,{onClick:R,disabled:!j||j.length===0||a,children:"Check Answer"}),(!r||B)&&e.jsx(s.Button,{onClick:A,disabled:a,children:f<N.length-1?"Next Question":"Finish"})]})]})})]})}function ue({questions:t,initialAnswers:r=[],onSubmit:i,onAnswerChange:o,timeLimitSeconds:m,timeElapsedSeconds:a,autoSubmitOnTimeout:c=!0,timeWarningThreshold:n=300,allowBackNavigation:N=!0,confirmBeforeSubmit:f=!0,examTitle:u,instructions:g,questionMaterials:w,isSubmitting:v=!1,readOnly:z=!1,className:C,style:U}){const[j,S]=p.useState(0),[l,d]=p.useState(r),[h,B]=p.useState(new Set),[R,T]=p.useState(!1),[A,D]=p.useState(!1),[x,b]=p.useState(!1),y=p.useRef(!1),k=t[j],P=m-a,E=p.useMemo(()=>k?l.filter(M=>M.uid===k.uid):[],[l,k]),_=p.useMemo(()=>(w==null?void 0:w.filter(M=>M.questionUid===(k==null?void 0:k.uid)))??[],[w,k]);p.useEffect(()=>{P<=n&&P>0&&D(!0)},[P,n]),p.useEffect(()=>{c&&P<=0&&!y.current&&(y.current=!0,O(!0))},[P,c]);const $=p.useMemo(()=>t.map((M,I)=>({uid:M.uid,sequence:I,isFlagged:h.has(M.uid),isAnswered:l.some(F=>F.uid===M.uid),isSkipped:!1})),[t,l,h]),X=p.useMemo(()=>$.filter(M=>M.isAnswered).length,[$]);function J(M){if(!k)return;const I=k.uid,F=M.map(Q=>({uid:I,answerUid:Q.uid,content:Q.content}));d(Q=>{const Z=[...Q.filter(te=>te.uid!==I),...F];return o==null||o(Z),Z})}function q(M){const I=t.findIndex(F=>F.uid===M);I!==-1&&S(I)}function ee(M){B(I=>{const F=new Set(I);return F.has(M)?F.delete(M):F.add(M),F})}function se(){f?T(!0):O(!1)}function O(M){const I=new Set(l.map(Q=>Q.uid)),F={timeElapsedSeconds:a,wasAutoSubmitted:M,answeredCount:t.filter(Q=>I.has(Q.uid)).length,totalQuestions:t.length};i(l,F)}return e.jsxs("div",{className:s.cn(C),style:U,children:[u&&e.jsx("p",{className:"text-xl font-bold mb-2 text-foreground",children:u}),A&&P>0&&P<=n&&e.jsx(s.Alert,{variant:"warning",className:"mb-2",children:e.jsxs(s.AlertDescription,{children:[Math.ceil(P/60)," minute",Math.ceil(P/60)!==1?"s":""," remaining"]})}),e.jsx(s.AssessmentToolbar,{currentQuestionIndex:j,totalQuestions:t.length,hasNext:j<t.length-1,hasPrevious:N&&j>0,onNext:()=>S(M=>Math.min(M+1,t.length-1)),onPrevious:()=>N&&S(M=>Math.max(M-1,0)),onSubmit:se,timeElapsedSeconds:a,timeLimitSeconds:m,questions:$,onNavigateToQuestion:q,currentQuestionUid:k==null?void 0:k.uid,isSubmitting:v,readOnly:z}),g&&j===0&&e.jsx(s.Card,{className:"mt-3",children:e.jsx(s.CardContent,{className:"pt-6",children:g})}),k&&e.jsxs(s.Card,{className:"mt-3",children:[e.jsx(s.CardHeader,{className:"pb-0",children:e.jsx(s.QuestionHeaderBar,{questionNumber:j+1,totalQuestions:t.length,isFlagged:h.has(k.uid),onToggleFlag:()=>ee(k.uid),hasMaterials:_.length>0,onOpenMaterials:()=>b(!0),readOnly:z})}),e.jsx(s.CardContent,{children:e.jsx(s.QuestionRenderer,{question:k,sessionAnswers:E,onAnswer:J,readOnly:z})})]}),e.jsx(s.QuestionMaterialsDrawer,{open:x,onOpenChange:b,materials:_,questionNumber:j+1}),e.jsx(s.ConfirmDialog,{open:R,title:"Submit Exam?",message:`You have answered ${X} of ${t.length} questions. Once submitted, you cannot change your answers.`,confirmLabel:"Submit Exam",cancelLabel:"Continue Exam",confirmColor:"primary",onConfirm:()=>{T(!1),O(!1)},onCancel:()=>T(!1),isLoading:v})]})}function xe({title:t,description:r,questions:i,initialAnswers:o=[],onSubmit:m,onAnswerChange:a,showProgress:c=!0,requireAll:n=!1,submitLabel:N="Submit Survey",isSubmitting:f=!1,readOnly:u=!1,className:g,style:w}){const[v,z]=p.useState(o),C=p.useMemo(()=>{const l=new Set(v.map(d=>d.questionUid));return i.filter(d=>l.has(d.uid)).length},[i,v]),U=!n||C===i.length;function j(l,d){z(h=>{const R=[...h.filter(T=>T.questionUid!==l),{questionUid:l,value:d}];return a==null||a(R),R})}function S(l){return v.find(d=>d.questionUid===l)}return e.jsxs("div",{className:g,style:w,children:[e.jsx("p",{className:"text-xl font-bold text-foreground mb-2",children:t}),r&&e.jsx("div",{className:"mb-2 text-muted-foreground text-sm",children:typeof r=="string"?e.jsx("span",{children:r}):r}),c&&e.jsxs("div",{className:"mb-3",children:[e.jsx(s.Progress,{value:C/i.length*100}),e.jsxs("span",{className:"block text-xs text-muted-foreground mt-0.5",children:[C," of ",i.length," answered"]})]}),i.map((l,d)=>{var B,R;const h=S(l.uid);return e.jsx(s.Card,{className:"mb-2",children:e.jsxs(s.CardContent,{className:"pt-6",children:[e.jsxs("p",{className:"font-medium text-foreground mb-2",children:[d+1,". ",l.content,l.required&&e.jsx("span",{className:"text-destructive ml-0.5",children:"*"})]}),l.type==="likert"&&e.jsx(s.LikertScale,{value:h?Number(h.value):null,onChange:T=>j(l.uid,T),points:l.scalePoints,lowLabel:(B=l.scaleLabels)==null?void 0:B.low,highLabel:(R=l.scaleLabels)==null?void 0:R.high,readOnly:u}),l.type==="rating"&&e.jsx(s.StarRating,{value:h?Number(h.value):0,onChange:T=>j(l.uid,T),readOnly:u}),l.type==="open_text"&&e.jsx(s.RichTextEditor,{placeholder:"Type your response...",value:(h==null?void 0:h.value)??"",onChange:T=>j(l.uid,T),readOnly:u,className:"min-h-24",variant:"minimal"}),l.type==="choice"&&l.answers&&e.jsx("div",{className:"flex flex-col gap-2",children:l.answers.map(T=>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-${l.uid}`,value:T.uid,checked:(h==null?void 0:h.value)===T.uid,onChange:()=>j(l.uid,T.uid),disabled:u}),e.jsx("span",{children:T.content})]},T.uid))}),l.type==="multiple_choice"&&l.answers&&e.jsx("div",{className:"flex flex-col gap-2",children:l.answers.map(T=>{const A=v.filter(D=>D.questionUid===l.uid).map(D=>String(D.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:A.includes(T.uid),disabled:u,onChange:D=>{const x=v.filter(y=>y.questionUid===l.uid);let b;D.target.checked?b=[...x,{questionUid:l.uid,value:T.uid}]:b=x.filter(y=>String(y.value)!==T.uid),z(y=>[...y.filter(k=>k.questionUid!==l.uid),...b]),a==null||a([...v.filter(y=>y.questionUid!==l.uid),...b])}}),e.jsx("span",{children:T.content})]},T.uid)})})]})},l.uid)}),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:[C," of ",i.length," answered"]}),e.jsx(s.Button,{onClick:()=>m(v),disabled:!U||f||u,children:f?"Submitting...":N})]})]})}function me({title:t,blocks:r,isCompleted:i=!1,onMarkComplete:o,onNextLesson:m,nextLessonTitle:a,estimatedDuration:c,showDuration:n=!0,readOnly:N=!1,className:f,style:u}){const[g,w]=p.useState(i);function v(){w(!0),o==null||o()}return e.jsxs("div",{className:s.cn(f),style:u,children:[e.jsxs("div",{className:"mb-3",children:[e.jsx("p",{className:"text-2xl font-bold mb-0.5 text-foreground",children:t}),n&&c!=null&&e.jsxs("div",{className:"flex items-center gap-0.5 text-muted-foreground",children:[e.jsx(L.Clock,{size:16}),e.jsx("span",{className:"text-sm",children:s.formatDuration(c)})]})]}),e.jsx(s.Separator,{className:"mb-3"}),e.jsx("div",{className:"flex flex-col gap-3",children:r.map((z,C)=>e.jsx(s.ContentBlock,{block:z,readOnly:N},C))}),e.jsx(s.Card,{className:"mt-4 sticky bottom-0 z-10",children:e.jsx(s.CardContent,{className:"px-4 py-3",children:e.jsxs("div",{className:"flex justify-between items-center",children:[g?e.jsxs("div",{className:"flex items-center gap-1 text-success",children:[e.jsx(L.Check,{size:20}),e.jsx("span",{className:"text-sm font-semibold",children:"Lesson Complete"})]}):e.jsxs(s.Button,{onClick:v,disabled:N,children:[e.jsx(L.Check,{size:18})," Mark Complete"]}),m&&e.jsxs(s.Button,{variant:g?"default":"outline",onClick:m,children:[a?`Next: ${a}`:"Next Lesson"," ",e.jsx(L.ChevronRight,{size:18})]})]})})})]})}function V(t){return t.replace(/<[^>]*>/g,"").trim().length===0}function he({title:t,rootPost:r,replies:i,currentUser:o,onReply:m,onToggleLike:a,onMarkAnswer:c,maxDepth:n=3,allowReplies:N=!0,sortOrder:f="oldest",readOnly:u=!1,className:g,style:w}){const[v,z]=p.useState(null),[C,U]=p.useState(""),j=p.useMemo(()=>{const d=new Map;for(const h of i){const B=h.parentUid??r.uid,R=d.get(B)??[];R.push(h),d.set(B,R)}for(const[,h]of d)h.sort((B,R)=>f==="newest"?new Date(R.createdAt).getTime()-new Date(B.createdAt).getTime():f==="most_liked"?R.likeCount-B.likeCount:new Date(B.createdAt).getTime()-new Date(R.createdAt).getTime());return d},[i,r.uid,f]);function S(d){V(C)||(m(d,C),U(""),z(null))}function l(d,h){const B=j.get(d.uid)??[],R=Math.min(h,n),T=e.jsxs("div",{className:"flex items-center gap-1",children:[a&&!u&&e.jsxs(s.Tooltip,{children:[e.jsx(s.TooltipTrigger,{children:e.jsxs(s.Button,{variant:"ghost",size:"sm","aria-label":d.isLikedByCurrentUser?"Unlike":"Like",className:s.cn(d.isLikedByCurrentUser&&"text-destructive"),onClick:()=>a(d.uid),children:[e.jsx(L.Heart,{size:14,fill:d.isLikedByCurrentUser?"currentColor":"none"}),d.likeCount>0?d.likeCount:"Like"]})}),e.jsx(s.TooltipContent,{children:d.isLikedByCurrentUser?"Unlike":"Like"})]}),N&&!u&&e.jsxs(s.Tooltip,{children:[e.jsx(s.TooltipTrigger,{children:e.jsxs(s.Button,{variant:"ghost",size:"sm","aria-label":"Reply",onClick:()=>z(d.uid),children:[e.jsx(L.Reply,{size:14}),"Reply"]})}),e.jsx(s.TooltipContent,{children:"Reply"})]}),c&&!u&&o.role!=="student"&&!d.isAnswer&&e.jsxs(s.Tooltip,{children:[e.jsx(s.TooltipTrigger,{children:e.jsxs(s.Button,{variant:"ghost",size:"sm","aria-label":"Mark as answer",className:"text-success",onClick:()=>c(d.uid),children:[e.jsx(L.CheckCircle,{size:14}),"Mark Answer"]})}),e.jsx(s.TooltipContent,{children:"Mark as answer"})]})]});return e.jsxs("div",{children:[e.jsx(s.PostCard,{author:d.author,content:d.content,createdAt:d.createdAt,updatedAt:d.updatedAt,actions:T,highlight:d.isAnswer?"answer":"none",indentLevel:R,className:"mb-2"}),v===d.uid&&e.jsx(s.Card,{className:"mb-2",style:{marginLeft:`${(R+1)*16}px`},children:e.jsxs(s.CardContent,{className:"py-4",children:[e.jsx(s.RichTextEditor,{className:"min-h-15 mb-2",placeholder:"Write a reply...",value:C,onChange:A=>U(A),variant:"minimal"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s.Button,{size:"sm",onClick:()=>S(d.uid),disabled:V(C),children:"Post Reply"}),e.jsx(s.Button,{variant:"ghost",size:"sm",onClick:()=>{z(null),U("")},children:"Cancel"})]})]})}),B.map(A=>l(A,h+1))]},d.uid)}return e.jsxs("div",{className:g,style:w,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(L.MessageSquare,{size:20,className:"text-foreground shrink-0"}),e.jsx("span",{className:"text-lg font-semibold text-foreground",children:t}),e.jsxs(s.Badge,{variant:"muted",className:"text-xs",children:[i.length," ",i.length===1?"reply":"replies"]})]}),e.jsx(s.Separator,{className:"mb-2"}),l(r,0)]})}function fe({title:t,instructions:r,dueDate:i,maxScore:o,status:m,submissionTypes:a,existingSubmission:c,fileConstraints:n,onSubmit:N,onSaveDraft:f,grade:u,isSubmitting:g=!1,readOnly:w=!1,className:v,style:z}){const[C,U]=p.useState((c==null?void 0:c.textContent)??""),[j,S]=p.useState((c==null?void 0:c.files)??[]),[l,d]=p.useState((c==null?void 0:c.url)??""),[h,B]=p.useState(a[0]),R=!w&&!["submitted","graded"].includes(m);function T(){return{textContent:a.includes("text")?C:void 0,files:a.includes("file")?j:void 0,url:a.includes("url")?l:void 0}}return e.jsxs("div",{className:v,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:t}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s.StatusBadge,{status:m}),i&&e.jsx(s.DueDateDisplay,{dueDate:i,size:"small"}),o!=null&&e.jsxs("span",{className:"text-sm text-muted-foreground",children:[o," points"]})]})]})}),e.jsx(s.Card,{className:"mb-3",children:e.jsxs(s.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})]})}),u&&e.jsx(s.Alert,{variant:"success",className:"mb-3",children:e.jsxs(s.AlertDescription,{children:[e.jsxs("div",{className:"font-semibold text-sm mb-1",children:["Grade: ",u.score,o!=null?` / ${o}`:""]}),u.feedback&&e.jsx("div",{children:u.feedback})]})}),R&&e.jsxs(e.Fragment,{children:[a.length>1?e.jsxs(s.Tabs,{value:h,onValueChange:A=>B(A),children:[e.jsxs(s.TabsList,{children:[a.includes("text")&&e.jsx(s.TabsTrigger,{value:"text",children:"Text"}),a.includes("file")&&e.jsx(s.TabsTrigger,{value:"file",children:"File Upload"}),a.includes("url")&&e.jsx(s.TabsTrigger,{value:"url",children:"URL"})]}),a.includes("text")&&e.jsx(s.TabsContent,{value:"text",children:e.jsx(s.RichTextEditor,{className:"min-h-45",placeholder:"Type your submission...",value:C,onChange:A=>U(A),variant:"default"})}),a.includes("file")&&e.jsx(s.TabsContent,{value:"file",children:e.jsx(s.FileUploadZone,{files:j,onFilesAdded:A=>S(D=>[...D,...A]),onFileRemove:A=>S(D=>D.filter((x,b)=>b!==A)),accept:n==null?void 0:n.acceptedTypes,maxFiles:n==null?void 0:n.maxFiles,maxSizeMB:n==null?void 0:n.maxSizeMB})}),a.includes("url")&&e.jsx(s.TabsContent,{value:"url",children:e.jsx(s.Input,{placeholder:"https://...",value:l,onChange:A=>d(A.target.value)})})]}):e.jsxs(e.Fragment,{children:[a.includes("text")&&e.jsx(s.RichTextEditor,{className:"min-h-45 mb-2",placeholder:"Type your submission...",value:C,onChange:A=>U(A),variant:"default"}),a.includes("file")&&e.jsx("div",{className:"mb-2",children:e.jsx(s.FileUploadZone,{files:j,onFilesAdded:A=>S(D=>[...D,...A]),onFileRemove:A=>S(D=>D.filter((x,b)=>b!==A)),accept:n==null?void 0:n.acceptedTypes,maxFiles:n==null?void 0:n.maxFiles,maxSizeMB:n==null?void 0:n.maxSizeMB})}),a.includes("url")&&e.jsx(s.Input,{className:"mb-2",placeholder:"https://...",value:l,onChange:A=>d(A.target.value)})]}),e.jsx(s.Separator,{className:"my-2"}),e.jsxs("div",{className:"flex gap-2 justify-end",children:[f&&e.jsxs(s.Button,{variant:"outline",onClick:()=>f(T()),disabled:g,children:[e.jsx(L.Save,{size:16}),"Save Draft"]}),e.jsxs(s.Button,{onClick:()=>N(T()),disabled:g,children:[e.jsx(L.Send,{size:16}),g?"Submitting...":"Submit"]})]})]})]})}function H({label:t,field:r,sortField:i,sortDir:o,onSort:m,textAlign:a}){const c=i===r;return e.jsx(s.TableHead,{className:s.cn("cursor-pointer select-none hover:bg-muted",a==="right"&&"text-right"),onClick:()=>m(r),children:e.jsxs("div",{className:s.cn("flex items-center gap-1",a==="right"&&"justify-end"),children:[e.jsx("span",{className:s.cn(c?"text-foreground":"text-muted-foreground"),children:t}),c&&(o==="asc"?e.jsx(L.ArrowUp,{size:14}):e.jsx(L.ArrowDown,{size:14}))]})})}function pe({items:t,categories:r,overallGrade:i,showWeights:o=!0,showCategoryTotals:m=!0,onItemClick:a,readOnly:c=!1,className:n,style:N}){const[f,u]=p.useState("dueDate"),[g,w]=p.useState("asc");function v(j){f===j?w(S=>S==="asc"?"desc":"asc"):(u(j),w("asc"))}const z=p.useMemo(()=>{const j=[...t];return j.sort((S,l)=>{let d=0;switch(f){case"name":d=S.name.localeCompare(l.name);break;case"score":d=(S.score??-1)-(l.score??-1);break;case"dueDate":d=(S.dueDate??"").localeCompare(l.dueDate??"");break;case"status":d=S.status.localeCompare(l.status);break}return g==="asc"?d:-d}),j},[t,f,g]),C=p.useMemo(()=>{if(!r||r.length===0)return[{category:null,items:z}];const j=r.map(l=>({category:l,items:z.filter(d=>d.categoryUid===l.uid)})),S=z.filter(l=>!l.categoryUid);return S.length>0&&j.push({category:null,items:S}),j},[z,r]),U=o?5:4;return e.jsxs("div",{className:n,style:N,children:[i&&e.jsx(s.Card,{className:"mb-3",children:e.jsx(s.CardContent,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(s.GradeIndicator,{percentage:i.percentage,letterGrade:i.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:[i.pointsEarned," / ",i.pointsPossible," points"]})]})]})})}),e.jsx(s.Card,{children:e.jsxs(s.Table,{children:[e.jsx(s.TableHeader,{children:e.jsxs(s.TableRow,{children:[e.jsx(H,{label:"Assignment",field:"name",sortField:f,sortDir:g,onSort:v}),e.jsx(H,{label:"Status",field:"status",sortField:f,sortDir:g,onSort:v}),e.jsx(H,{label:"Due Date",field:"dueDate",sortField:f,sortDir:g,onSort:v}),e.jsx(H,{label:"Score",field:"score",sortField:f,sortDir:g,onSort:v,textAlign:"right"}),o&&e.jsx(s.TableHead,{className:"text-right text-muted-foreground",children:"Weight"})]})}),e.jsx(s.TableBody,{children:C.map((j,S)=>{var l;return e.jsxs(p.Fragment,{children:[j.category&&m&&e.jsx(s.TableRow,{className:"bg-muted hover:bg-muted",children:e.jsx(s.TableCell,{colSpan:U,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(d=>e.jsxs(s.TableRow,{className:s.cn(a&&!c&&"cursor-pointer"),onClick:()=>a&&!c?a(d):void 0,children:[e.jsx(s.TableCell,{children:d.name}),e.jsx(s.TableCell,{children:e.jsx(s.StatusBadge,{status:d.status,size:"small"})}),e.jsx(s.TableCell,{children:d.dueDate?e.jsx(s.DueDateDisplay,{dueDate:d.dueDate,submittedDate:d.submittedDate,size:"small"}):"—"}),e.jsx(s.TableCell,{className:"text-right",children:d.score!=null?e.jsxs("span",{className:"text-sm font-semibold text-foreground",children:[d.score," / ",d.maxScore]}):d.status==="excused"?e.jsx("span",{className:"text-sm text-muted-foreground",children:"Excused"}):e.jsx("span",{className:"text-sm text-muted-foreground",children:"—"})}),o&&e.jsx(s.TableCell,{className:"text-right",children:d.weight!=null?`${d.weight}%`:"—"})]},d.uid))]},((l=j.category)==null?void 0:l.uid)??`ungrouped-${S}`)})})]})})]})}function je({overallProgress:t,totalTimeSpent:r,modules:i,recentActivity:o,streak:m,achievements:a,recentActivityLimit:c=5,onModuleClick:n,className:N,style:f}){return e.jsxs("div",{className:N,style:f,children:[e.jsxs("div",{className:"grid grid-cols-[repeat(auto-fit,minmax(160px,1fr))] gap-3 mb-4",children:[e.jsx(s.Card,{children:e.jsx(s.CardContent,{className:"p-3 flex justify-center",children:e.jsx(s.ProgressRing,{value:t,size:100})})}),e.jsx(s.StatCard,{icon:e.jsx(L.Clock,{size:24}),label:"Time Spent",description:"Total learning time",value:s.formatDuration(r)}),m&&e.jsx(s.Card,{children:e.jsx(s.CardContent,{className:"p-4 flex items-center",children:e.jsx(s.StreakBadge,{currentStreak:m.currentDays,longestStreak:m.longestDays,showLongest:!0})})}),e.jsx(s.StatCard,{icon:e.jsx(L.BookOpen,{size:24}),label:"Modules",description:"Course progress",value:`${i.filter(u=>u.completedItems===u.totalItems).length} / ${i.length}`,subtitle:"completed"})]}),e.jsx(s.Separator,{className:"mb-3"}),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-4",children:i.map(u=>{const g=u.totalItems>0?u.completedItems/u.totalItems*100:0;return e.jsx(s.Card,{className:s.cn("transition-colors",n&&"cursor-pointer hover:border-primary"),onClick:()=>n==null?void 0:n(u.uid),children:e.jsxs(s.CardContent,{className:"p-3",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:u.name}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[u.completedItems," / ",u.totalItems]})]}),e.jsx(s.Progress,{value:g,size:"sm"})]})},u.uid)})}),o&&o.length>0&&e.jsxs(e.Fragment,{children:[e.jsx(s.Separator,{className:"mb-3"}),e.jsx("p",{className:"text-lg font-semibold mb-2 text-foreground",children:"Recent Activity"}),e.jsx("div",{className:"mb-4",children:e.jsx(s.ActivityTimeline,{events:o.map(u=>({uid:u.uid,type:u.type,title:u.description,timestamp:u.timestamp})),limit:c})})]}),a&&a.length>0&&e.jsxs(e.Fragment,{children:[e.jsx(s.Separator,{className:"mb-3"}),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:a.map(u=>e.jsx(s.AchievementBadge,{title:u.name,description:u.description,icon:u.iconUrl?e.jsx("img",{src:u.iconUrl,alt:u.name,className:"w-12 h-12"}):void 0,earnedDate:u.earnedAt},u.uid))})]})]})}const ge=K.cva("mx-auto max-w-4xl",{variants:{variant:{classic:"border-[3px] border-double border-warning/50 rounded-lg p-1.5",modern:"rounded-lg",elegant:"border border-foreground/15 rounded-lg p-2.5 dark:border-foreground/10",academic:"border-2 border-info/30 rounded-lg p-1.5",minimal:"rounded-lg",bold:"rounded-lg"}},defaultVariants:{variant:"classic"}}),be=K.cva("relative text-center p-8 sm:p-12 md:p-16 overflow-hidden",{variants:{variant:{classic:"border border-warning/25 rounded bg-warning/5",modern:"border border-primary/20 rounded-lg bg-linear-to-br from-primary/5 to-primary/8 border-t-[3px] border-t-primary/60",elegant:"border border-foreground/8 rounded bg-linear-to-b from-background to-muted/20 dark:border-foreground/5 dark:to-muted/10",academic:"border border-info/15 rounded bg-info/3",minimal:"border border-border rounded-lg bg-background",bold:"border-[3px] border-primary rounded-lg bg-linear-to-br from-primary/8 to-purple/8"}},defaultVariants:{variant:"classic"}}),Ne={classic:{size:40,paths:[{d:"M 2 38 L 2 10 Q 2 2 10 2 L 38 2",strokeWidth:1.5},{d:"M 7 38 L 7 13 Q 7 7 13 7 L 38 7",strokeWidth:.75}],color:"text-warning/50"},modern:null,elegant:{size:32,paths:[{d:"M 0 30 L 0 0 L 30 0",strokeWidth:.5}],dots:[{cx:2.5,cy:2.5,r:1.5}],color:"text-foreground/20"},academic:{size:36,paths:[{d:"M 0 36 L 0 0 L 36 0",strokeWidth:2},{d:"M 5 36 L 5 5 L 36 5",strokeWidth:1}],color:"text-info/35"},minimal:null,bold:{size:20,paths:[],dots:[{cx:5,cy:5,r:5}],color:"text-primary/40"}},ve=[{key:"tl",pos:"top-3 left-3",transform:void 0},{key:"tr",pos:"top-3 right-3",transform:"scaleX(-1)"},{key:"bl",pos:"bottom-3 left-3",transform:"scaleY(-1)"},{key:"br",pos:"bottom-3 right-3",transform:"scale(-1)"}];function Ce({variant:t}){const r=Ne[t];return r?e.jsx(e.Fragment,{children:ve.map(({key:i,pos:o,transform:m})=>{var a;return e.jsxs("svg",{className:s.cn("absolute pointer-events-none",o,r.color),width:r.size,height:r.size,viewBox:`0 0 ${r.size} ${r.size}`,fill:"none",stroke:"currentColor",style:m?{transform:m}:void 0,"aria-hidden":"true",children:[r.paths.map((c,n)=>e.jsx("path",{d:c.d,strokeWidth:c.strokeWidth},n)),(a=r.dots)==null?void 0:a.map((c,n)=>e.jsx("circle",{cx:c.cx,cy:c.cy,r:c.r,fill:"currentColor",stroke:"none"},`d${n}`))]},i)})}):null}const we={classic:{lineColor:"bg-warning/30",motif:e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",className:"text-warning/50 shrink-0","aria-hidden":"true",children:e.jsx("path",{d:"M6 0 L12 6 L6 12 L0 6 Z",fill:"currentColor"})})},modern:{lineColor:"bg-primary/20",motif:e.jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",className:"text-primary/40 shrink-0","aria-hidden":"true",children:e.jsx("circle",{cx:"4",cy:"4",r:"3",fill:"currentColor"})})},elegant:{lineColor:"bg-foreground/10",motif:e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",className:"text-foreground/15 shrink-0","aria-hidden":"true",children:e.jsx("path",{d:"M5 0 L6 4 L10 5 L6 6 L5 10 L4 6 L0 5 L4 4 Z",fill:"currentColor"})})},academic:{lineColor:"bg-info/25",motif:e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",className:"text-info/40 shrink-0","aria-hidden":"true",children:e.jsx("path",{d:"M4 0 L6 0 L6 4 L10 4 L10 6 L6 6 L6 10 L4 10 L4 6 L0 6 L0 4 L4 4 Z",fill:"currentColor"})})},minimal:{lineColor:"bg-border",motif:null},bold:{lineColor:"bg-primary/40",motif:e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",className:"text-primary/50 shrink-0","aria-hidden":"true",children:e.jsx("rect",{x:"1",y:"1",width:"8",height:"8",fill:"currentColor"})})}};function Y({variant:t,className:r}){const i=we[t];return e.jsxs("div",{className:s.cn("flex items-center justify-center gap-3 my-5 mx-auto max-w-70",r),role:"separator","aria-hidden":"true",children:[e.jsx("span",{className:s.cn("flex-1 h-px",i.lineColor)}),i.motif,e.jsx("span",{className:s.cn("flex-1 h-px",i.lineColor)})]})}const ye={classic:{background:"radial-gradient(ellipse at center, var(--color-warning) 0%, transparent 65%)",opacity:.06},modern:null,elegant:{background:"radial-gradient(ellipse at center, var(--color-foreground) 0%, transparent 70%)",opacity:.03},academic:{background:"radial-gradient(ellipse at center, var(--color-info) 0%, transparent 65%)",opacity:.05},minimal:null,bold:{background:"radial-gradient(ellipse at 30% 50%, var(--color-primary) 0%, transparent 50%), radial-gradient(ellipse at 70% 50%, var(--color-purple) 0%, transparent 50%)",opacity:.06}},Se={classic:"text-warning",modern:"text-primary",elegant:"text-foreground/60",academic:"text-info",minimal:"text-muted-foreground",bold:"text-primary"},ke={classic:"uppercase tracking-[4px] text-base font-medium text-foreground/80 font-serif",modern:"uppercase tracking-[3px] text-base font-medium text-primary/80",elegant:"uppercase tracking-[5px] text-sm font-light text-foreground/50",academic:"uppercase tracking-[3px] text-base font-semibold text-info/80",minimal:"uppercase tracking-[2px] text-sm font-normal text-muted-foreground",bold:"uppercase tracking-[3px] text-lg font-black text-primary"},Te={classic:"text-warning",modern:"text-primary",elegant:"text-foreground/80",academic:"text-info",minimal:"text-foreground",bold:"text-primary"},ze=new Set(["classic","elegant","academic"]);function Le({recipientName:t,courseTitle:r,completionDate:i,organizationName:o,organizationLogo:m,signatory:a,certificateId:c,variant:n="classic",showActions:N=!0,onPrint:f,onDownload:u,className:g,style:w}){const v=(()=>{try{return new Date(i).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}catch{return i}})();function z(){f?f():window.print()}const C=ye[n];return e.jsxs("div",{className:g,style:w,children:[e.jsx("div",{className:ge({variant:n}),children:e.jsxs("div",{className:be({variant:n}),children:[e.jsx(Ce,{variant:n}),C&&e.jsx("div",{className:"absolute inset-0 pointer-events-none rounded-[inherit]",style:C,"aria-hidden":"true"}),e.jsxs("div",{className:"relative",children:[m?e.jsx("img",{src:m,alt:o,className:"h-20 mb-4 mx-auto block"}):e.jsx(L.Award,{size:64,className:s.cn("mx-auto mb-6",Se[n])}),e.jsx("p",{className:s.cn("mb-2",ke[n]),children:"Certificate of Completion"}),e.jsx(Y,{variant:n}),e.jsx("p",{className:"text-base text-foreground/70 mb-2",children:"This is to certify that"}),e.jsx("p",{className:s.cn("text-4xl font-bold mb-4 text-foreground",ze.has(n)&&"font-serif"),children:t}),e.jsx("p",{className:"text-base text-foreground/70 mb-2",children:"has successfully completed"}),e.jsx("p",{className:s.cn("text-2xl font-semibold mb-4",Te[n]),children:r}),e.jsxs("p",{className:"text-base text-foreground/60 mb-6",children:["Issued by ",o," on ",v]}),a&&e.jsxs("div",{className:"mt-6 mb-4",children:[e.jsx(Y,{variant:n}),e.jsx("p",{className:"font-semibold text-base text-foreground",children:a.name}),e.jsx("p",{className:"text-sm text-muted-foreground",children:a.title})]}),c&&e.jsxs("span",{className:"block text-xs text-muted-foreground mt-4",children:["Certificate ID: ",c]})]})]})}),N&&e.jsxs("div",{className:"flex justify-center gap-3 mt-6",children:[e.jsxs(s.Button,{variant:"outline",onClick:z,children:[e.jsx(L.Printer,{size:16})," Print"]}),u&&e.jsxs(s.Button,{variant:"outline",onClick:u,children:[e.jsx(L.Download,{size:16})," Download"]})]})]})}function Ae({criteria:t,selectedLevels:r,totalScore:i,maxScore:o,feedback:m,className:a,style:c}){var N;const n=r&&Object.keys(r).length>0;return e.jsxs("div",{className:s.cn("flex flex-col gap-4",a),style:c,children:[n&&i!==void 0&&o!==void 0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground",children:"Rubric"}),e.jsxs(s.Badge,{variant:i>=o*.7?"success":"destructive",children:[i," / ",o," pts"]})]}),!n&&e.jsx("h3",{className:"text-lg font-semibold text-foreground",children:"Grading Rubric"}),e.jsx(s.Card,{children:e.jsx(s.CardContent,{className:"p-0",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(s.Table,{className:"text-sm",children:[e.jsx(s.TableHeader,{children:e.jsxs(s.TableRow,{className:"bg-muted/50",children:[e.jsx(s.TableHead,{className:"text-left font-medium text-muted-foreground w-1/5",children:"Criterion"}),(N=t[0])==null?void 0:N.levels.map(f=>e.jsxs(s.TableHead,{className:"text-center font-medium text-muted-foreground",children:[e.jsx("div",{children:f.label}),e.jsxs("div",{className:"text-xs font-normal mt-0.5",children:[f.points," pts"]})]},f.uid))]})}),e.jsx(s.TableBody,{children:t.map((f,u)=>{const g=r==null?void 0:r[f.uid];return e.jsxs(s.TableRow,{className:s.cn(u%2===1&&"bg-muted/20"),children:[e.jsxs(s.TableCell,{className:"align-top",children:[e.jsx("div",{className:"font-medium text-foreground",children:f.name}),f.description&&e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:f.description})]}),f.levels.map(w=>{const v=g===w.uid;return e.jsxs(s.TableCell,{className:s.cn("align-top text-center",v&&"bg-primary/10 ring-2 ring-primary/30 ring-inset rounded-sm"),children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:w.description}),v&&e.jsx("div",{className:"mt-1.5 flex justify-center",children:e.jsx(L.CheckCircle2,{className:"size-4 text-primary"})})]},w.uid)})]},f.uid)})})]})})})}),m&&e.jsxs(e.Fragment,{children:[e.jsx(s.Separator,{}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-foreground mb-1",children:"Instructor Feedback"}),e.jsx("p",{className:"text-sm text-muted-foreground whitespace-pre-wrap",children:m})]})]})]})}function Be({title:t,requirements:r,onRequirementClick:i,className:o,style:m}){const a=p.useMemo(()=>r.filter(n=>n.completed).length,[r]),c=r.length>0?Math.round(a/r.length*100):0;return e.jsxs("div",{className:s.cn("flex flex-col gap-4",o),style:m,children:[t&&e.jsx("h3",{className:"text-lg font-semibold text-foreground",children:t}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:[a," of ",r.length," complete"]}),e.jsxs("span",{className:"font-medium text-foreground",children:[c,"%"]})]}),e.jsx(s.Progress,{value:c})]}),e.jsx("ul",{className:"flex flex-col gap-1",children:r.map(n=>e.jsx("li",{children:e.jsxs("button",{type:"button",className:s.cn("w-full flex items-start gap-3 p-3 rounded-lg text-left transition-colors",n.completed?"bg-success/5":i?"hover:bg-muted/50 cursor-pointer":"cursor-default"),onClick:()=>{!n.completed&&i&&i(n.uid)},disabled:n.completed,children:[n.completed?e.jsx(L.CheckCircle2,{className:"size-5 text-success shrink-0 mt-0.5"}):e.jsx(L.Circle,{className:"size-5 text-muted-foreground shrink-0 mt-0.5"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:s.cn("text-sm font-medium",n.completed?"text-muted-foreground line-through":"text-foreground"),children:n.label}),n.description&&e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:n.description})]}),!n.completed&&i&&e.jsxs("div",{className:"shrink-0 flex items-center gap-1 text-xs text-primary mt-0.5",children:[n.actionLabel&&e.jsx("span",{children:n.actionLabel}),e.jsx(L.ChevronRight,{className:"size-4"})]})]})},n.uid))})]})}const Re={newest:"Newest",oldest:"Oldest",most_replies:"Most Replies",most_liked:"Most Liked"};function Ue({title:t,topics:r,onTopicClick:i,onCreateTopic:o,sortOrder:m="newest",onSortChange:a,searchQuery:c="",onSearchChange:n,readOnly:N,className:f,style:u}){const[g,w]=p.useState(!1),[v,z]=p.useState(""),[C,U]=p.useState(""),[j,S]=p.useState(c),[l,d]=p.useState(m),h=n!==void 0?c:j,B=a!==void 0?m:l;function R(x){n?n(x):S(x)}function T(){const x=["newest","oldest","most_replies","most_liked"],b=x.indexOf(B),y=x[(b+1)%x.length];a?a(y):d(y)}function A(){!v.trim()||V(C)||(o==null||o(v.trim(),C),z(""),U(""),w(!1))}const D=p.useMemo(()=>[...r.filter(b=>{var k;if(!h)return!0;const y=h.toLowerCase();return b.title.toLowerCase().includes(y)||((k=b.preview)==null?void 0:k.toLowerCase().includes(y))||b.author.displayName.toLowerCase().includes(y)})].sort((b,y)=>{if(b.isPinned&&!y.isPinned)return-1;if(!b.isPinned&&y.isPinned)return 1;switch(B){case"oldest":return new Date(b.createdAt).getTime()-new Date(y.createdAt).getTime();case"most_replies":return y.replyCount-b.replyCount;case"most_liked":return y.likeCount-b.likeCount;case"newest":default:return new Date(y.createdAt).getTime()-new Date(b.createdAt).getTime()}}),[r,h,B]);return e.jsxs("div",{className:s.cn("flex flex-col gap-4",f),style:u,children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[t&&e.jsx("h2",{className:"text-xl font-bold text-foreground",children:t}),!N&&o&&e.jsxs(s.Button,{size:"sm",onClick:()=>w(!g),children:[e.jsx(L.Plus,{className:"size-4 mr-1.5"}),"New Topic"]})]}),e.jsx(s.Separator,{}),g&&e.jsx(s.Card,{children:e.jsxs(s.CardContent,{className:"pt-4 space-y-3",children:[e.jsx(s.Input,{placeholder:"Topic title",value:v,onChange:x=>z(x.target.value)}),e.jsx(s.RichTextEditor,{placeholder:"What would you like to discuss?",value:C,onChange:x=>U(x),variant:"minimal"}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(s.Button,{variant:"outline",size:"sm",onClick:()=>{w(!1),z(""),U("")},children:"Cancel"}),e.jsx(s.Button,{size:"sm",onClick:A,disabled:!v.trim()||V(C),children:"Post Topic"})]})]})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"flex-1",children:e.jsx(s.SearchInput,{value:h,onChange:R,placeholder:"Search topics..."})}),e.jsxs(s.Button,{variant:"outline",size:"sm",onClick:T,children:[e.jsx(L.ArrowUpDown,{className:"size-3.5 mr-1.5"}),Re[B]]})]}),D.length===0?e.jsx(s.EmptyState,{icon:e.jsx(L.MessageSquare,{className:"size-10 text-muted-foreground"}),title:"No topics found",description:h?"Try a different search term.":"Be the first to start a discussion!"}):e.jsx("div",{className:"flex flex-col gap-2",children:D.map(x=>e.jsx(De,{topic:x,onClick:()=>i(x.uid)},x.uid))})]})}function De({topic:t,onClick:r}){return e.jsx("button",{type:"button",className:"w-full text-left",onClick:r,children:e.jsx(s.Card,{className:s.cn("transition-colors hover:bg-muted/30",t.isPinned&&"border-l-2 border-l-warning"),children:e.jsx(s.CardContent,{className:"py-3 px-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(s.UserAvatar,{displayName:t.author.displayName,avatarUrl:t.author.avatarUrl,size:"small"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-0.5",children:[e.jsx("span",{className:"font-medium text-foreground text-sm truncate",children:t.title}),t.isPinned&&e.jsx(L.Pin,{className:"size-3 text-warning shrink-0"}),t.isAnswered&&e.jsxs(s.Badge,{variant:"success",className:"text-xs shrink-0",children:[e.jsx(L.CheckCircle2,{className:"size-3 mr-0.5"}),"Answered"]})]}),t.preview&&e.jsx("p",{className:"text-xs text-muted-foreground line-clamp-1",children:t.preview}),e.jsxs("div",{className:"flex items-center gap-3 mt-1.5 text-xs text-muted-foreground",children:[e.jsx("span",{children:t.author.displayName}),e.jsx("span",{children:s.formatTimestamp(t.createdAt)}),e.jsxs(s.Badge,{variant:"muted",className:"gap-0.5 text-xs px-1.5 py-0",children:[e.jsx(L.MessageSquare,{className:"size-3"}),t.replyCount]}),e.jsxs(s.Badge,{variant:"muted",className:"gap-0.5 text-xs px-1.5 py-0",children:[e.jsx(L.Heart,{className:"size-3"}),t.likeCount]})]})]})]})})})})}exports.AssessmentReview=de;exports.AssignmentSubmission=fe;exports.CertificateViewer=Le;exports.CourseOutline=ce;exports.DiscussionThread=he;exports.ExamSession=ue;exports.FlashcardStudySession=ae;exports.ForumBoard=Ue;exports.GradebookTable=pe;exports.LecturePlayer=re;exports.LessonPage=me;exports.PracticeQuiz=oe;exports.ProgressDashboard=je;exports.QuizSession=ne;exports.RequirementsChecklist=Be;exports.RubricView=Ae;exports.SurveyForm=xe;exports.flattenLeaves=G;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { AssessmentToolbarProps } from './types';
|
|
2
|
-
export declare const AssessmentToolbar: ({ currentQuestionIndex, totalQuestions, hasNext, hasPrevious, onNext, onPrevious, onSubmit, timeElapsedSeconds, timeLimitSeconds, questions, onNavigateToQuestion,
|
|
2
|
+
export declare const AssessmentToolbar: ({ currentQuestionIndex, totalQuestions, hasNext, hasPrevious, onNext, onPrevious, onSubmit, timeElapsedSeconds, timeLimitSeconds, questions, onNavigateToQuestion, currentQuestionUid, isCompleted, isSubmitting, readOnly, }: AssessmentToolbarProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export { AssessmentToolbar } from './assessment-toolbar';
|
|
2
2
|
export { TimerDisplay } from './timer-display';
|
|
3
3
|
export { QuestionNavigator } from './question-navigator';
|
|
4
|
-
export
|
|
4
|
+
export { QuestionHeaderBar } from './question-header-bar';
|
|
5
|
+
export { QuestionMaterialsDrawer } from './question-materials-drawer';
|
|
6
|
+
export { useCountdown } from './use-countdown';
|
|
7
|
+
export type { AssessmentToolbarProps, TimerDisplayProps, QuestionNavigatorProps, QuestionNavigatorItem, QuestionHeaderBarProps, QuestionMaterialsDrawerProps, } from './types';
|
|
8
|
+
export type { UseCountdownOptions, UseCountdownReturn } from './use-countdown';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { QuestionNavigatorProps } from './types';
|
|
2
|
-
export declare const QuestionNavigator: ({ questions, currentQuestionUid, onNavigate,
|
|
2
|
+
export declare const QuestionNavigator: ({ questions, currentQuestionUid, onNavigate, readOnly, }: QuestionNavigatorProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -37,8 +37,6 @@ export interface AssessmentToolbarProps {
|
|
|
37
37
|
questions?: QuestionNavigatorItem[];
|
|
38
38
|
/** Called when the user navigates to a specific question via the navigator */
|
|
39
39
|
onNavigateToQuestion?: (questionUid: string) => void;
|
|
40
|
-
/** Called when the user flags or unflags a question */
|
|
41
|
-
onToggleFlag?: (questionUid: string) => void;
|
|
42
40
|
/** UID of the currently active question */
|
|
43
41
|
currentQuestionUid?: string;
|
|
44
42
|
/** Whether the assessment has been completed/submitted */
|
|
@@ -70,14 +68,12 @@ export interface TimerDisplayProps {
|
|
|
70
68
|
* questions={questions}
|
|
71
69
|
* currentQuestionUid={currentUid}
|
|
72
70
|
* onNavigate={handleNavigate}
|
|
73
|
-
* onToggleFlag={handleFlag}
|
|
74
71
|
* />
|
|
75
72
|
*/
|
|
76
73
|
export interface QuestionNavigatorProps {
|
|
77
74
|
questions: QuestionNavigatorItem[];
|
|
78
75
|
currentQuestionUid?: string;
|
|
79
76
|
onNavigate?: (questionUid: string) => void;
|
|
80
|
-
onToggleFlag?: (questionUid: string) => void;
|
|
81
77
|
readOnly?: boolean;
|
|
82
78
|
}
|
|
83
79
|
export interface QuestionNavigatorItem {
|
|
@@ -87,3 +83,55 @@ export interface QuestionNavigatorItem {
|
|
|
87
83
|
isAnswered: boolean;
|
|
88
84
|
isSkipped: boolean;
|
|
89
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* QuestionHeaderBar displays question number, flag toggle, and optional
|
|
88
|
+
* materials button inside the question Card above the QuestionRenderer.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* <QuestionHeaderBar
|
|
92
|
+
* questionNumber={3}
|
|
93
|
+
* totalQuestions={10}
|
|
94
|
+
* isFlagged={false}
|
|
95
|
+
* onToggleFlag={() => toggleFlag(questionUid)}
|
|
96
|
+
* hasMaterials
|
|
97
|
+
* onOpenMaterials={() => setDrawerOpen(true)}
|
|
98
|
+
* />
|
|
99
|
+
*/
|
|
100
|
+
export interface QuestionHeaderBarProps {
|
|
101
|
+
/** 1-based question number */
|
|
102
|
+
questionNumber: number;
|
|
103
|
+
/** Total number of questions */
|
|
104
|
+
totalQuestions: number;
|
|
105
|
+
/** Whether this question is currently flagged */
|
|
106
|
+
isFlagged: boolean;
|
|
107
|
+
/** Called when the user toggles the flag */
|
|
108
|
+
onToggleFlag?: () => void;
|
|
109
|
+
/** Whether the current question has related materials available */
|
|
110
|
+
hasMaterials?: boolean;
|
|
111
|
+
/** Called when the user clicks the materials button */
|
|
112
|
+
onOpenMaterials?: () => void;
|
|
113
|
+
/** When true, hides interactive elements */
|
|
114
|
+
readOnly?: boolean;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* QuestionMaterialsDrawer renders a slide-in panel with content blocks
|
|
118
|
+
* linked to the current question for open-book reference.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* <QuestionMaterialsDrawer
|
|
122
|
+
* open={open}
|
|
123
|
+
* onOpenChange={setOpen}
|
|
124
|
+
* materials={currentMaterials}
|
|
125
|
+
* questionNumber={3}
|
|
126
|
+
* />
|
|
127
|
+
*/
|
|
128
|
+
export interface QuestionMaterialsDrawerProps {
|
|
129
|
+
/** Whether the drawer is open */
|
|
130
|
+
open: boolean;
|
|
131
|
+
/** Called when the drawer should open or close */
|
|
132
|
+
onOpenChange: (open: boolean) => void;
|
|
133
|
+
/** One or more material groups to display in the drawer */
|
|
134
|
+
materials: import('../questions/types').QuestionMaterial[];
|
|
135
|
+
/** Question number for the title display */
|
|
136
|
+
questionNumber?: number;
|
|
137
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface UseCountdownOptions {
|
|
2
|
+
/** Total countdown duration in seconds */
|
|
3
|
+
durationSeconds: number;
|
|
4
|
+
/** Seconds remaining at which to trigger warning state. @default 60 */
|
|
5
|
+
warningThresholdSeconds?: number;
|
|
6
|
+
/** Called once when the countdown reaches zero */
|
|
7
|
+
onExpire?: () => void;
|
|
8
|
+
/** Called once when the countdown enters warning territory */
|
|
9
|
+
onWarning?: () => void;
|
|
10
|
+
/** Whether to start the countdown immediately. @default false */
|
|
11
|
+
autoStart?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface UseCountdownReturn {
|
|
14
|
+
/** Seconds remaining in the countdown */
|
|
15
|
+
timeRemaining: number;
|
|
16
|
+
/** Whether the countdown is actively running */
|
|
17
|
+
isRunning: boolean;
|
|
18
|
+
/** Whether the countdown has been paused */
|
|
19
|
+
isPaused: boolean;
|
|
20
|
+
/** Whether the countdown has reached zero */
|
|
21
|
+
isExpired: boolean;
|
|
22
|
+
/** Whether the countdown is within the warning threshold */
|
|
23
|
+
isWarning: boolean;
|
|
24
|
+
/** Start or restart the countdown */
|
|
25
|
+
start: () => void;
|
|
26
|
+
/** Pause the countdown */
|
|
27
|
+
pause: () => void;
|
|
28
|
+
/** Resume after pausing */
|
|
29
|
+
resume: () => void;
|
|
30
|
+
/** Reset to the original duration, stopped */
|
|
31
|
+
reset: () => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* useCountdown manages a countdown timer lifecycle with warning and expiry callbacks.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* const { timeRemaining, isWarning, start } = useCountdown({
|
|
38
|
+
* durationSeconds: 300,
|
|
39
|
+
* warningThresholdSeconds: 60,
|
|
40
|
+
* onExpire: () => handleAutoSubmit(),
|
|
41
|
+
* });
|
|
42
|
+
*/
|
|
43
|
+
export declare function useCountdown({ durationSeconds, warningThresholdSeconds, onExpire, onWarning, autoStart, }: UseCountdownOptions): UseCountdownReturn;
|
package/dist/common/index.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export { ConfirmDialog } from './confirm-dialog';
|
|
|
3
3
|
export { SearchInput } from './search-input';
|
|
4
4
|
export { StatusBadge } from './status-badge';
|
|
5
5
|
export { DueDateDisplay } from './due-date-display';
|
|
6
|
-
export
|
|
6
|
+
export { Stepper } from './stepper';
|
|
7
|
+
export type { EmptyStateProps, ConfirmDialogProps, SearchInputProps, StatusBadgeProps, DueDateDisplayProps, StepperProps, StepDefinition, } from './types';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { StepperProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Stepper renders a visual step indicator for multi-step flows,
|
|
4
|
+
* showing completed, current, and upcoming steps with labels.
|
|
5
|
+
*/
|
|
6
|
+
export declare function Stepper({ steps, currentStep, orientation, variant, className, style, }: StepperProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/common/types.d.ts
CHANGED
|
@@ -122,3 +122,40 @@ export interface DueDateDisplayProps {
|
|
|
122
122
|
/** Inline styles for the root element */
|
|
123
123
|
style?: React.CSSProperties;
|
|
124
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* A single step definition used by the Stepper component.
|
|
127
|
+
*/
|
|
128
|
+
export interface StepDefinition {
|
|
129
|
+
/** Step label text */
|
|
130
|
+
label: string;
|
|
131
|
+
/** Optional secondary description */
|
|
132
|
+
description?: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Stepper renders a visual step indicator for multi-step flows,
|
|
136
|
+
* showing completed, current, and upcoming steps with labels.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* <Stepper
|
|
140
|
+
* steps={[
|
|
141
|
+
* { label: "Setup" },
|
|
142
|
+
* { label: "Questions" },
|
|
143
|
+
* { label: "Results" },
|
|
144
|
+
* ]}
|
|
145
|
+
* currentStep={1}
|
|
146
|
+
* />
|
|
147
|
+
*/
|
|
148
|
+
export interface StepperProps {
|
|
149
|
+
/** Ordered list of steps to display */
|
|
150
|
+
steps: StepDefinition[];
|
|
151
|
+
/** Zero-based index of the currently active step */
|
|
152
|
+
currentStep: number;
|
|
153
|
+
/** Layout orientation. @default 'horizontal' */
|
|
154
|
+
orientation?: "horizontal" | "vertical";
|
|
155
|
+
/** Visual density variant. @default 'default' */
|
|
156
|
+
variant?: "default" | "compact";
|
|
157
|
+
/** CSS class name for the root element */
|
|
158
|
+
className?: string;
|
|
159
|
+
/** Inline styles for the root element */
|
|
160
|
+
style?: React.CSSProperties;
|
|
161
|
+
}
|