@hydralms/components 0.1.3 → 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.
Files changed (199) hide show
  1. package/dist/ForumBoard-CHXU3mjC.js +2207 -0
  2. package/dist/ForumBoard-d1w5-r6n.cjs +1 -0
  3. package/dist/assessment-toolbar/assessment-toolbar.d.ts +1 -1
  4. package/dist/assessment-toolbar/index.d.ts +5 -1
  5. package/dist/assessment-toolbar/question-header-bar.d.ts +2 -0
  6. package/dist/assessment-toolbar/question-materials-drawer.d.ts +2 -0
  7. package/dist/assessment-toolbar/question-navigator.d.ts +1 -1
  8. package/dist/assessment-toolbar/types.d.ts +52 -4
  9. package/dist/assessment-toolbar/use-countdown.d.ts +43 -0
  10. package/dist/common/index.d.ts +2 -1
  11. package/dist/common/stepper.d.ts +6 -0
  12. package/dist/common/types.d.ts +37 -0
  13. package/dist/components.css +1 -1
  14. package/dist/content/attachment-list.d.ts +6 -0
  15. package/dist/content/content-block.d.ts +1 -1
  16. package/dist/content/index.d.ts +2 -1
  17. package/dist/content/types.d.ts +39 -0
  18. package/dist/curriculum/curriculum-item.d.ts +1 -1
  19. package/dist/index.cjs +1 -1
  20. package/dist/index.js +551 -312
  21. package/dist/modules/AssignmentModule/AssignmentModule.d.ts +8 -0
  22. package/dist/modules/AssignmentModule/types.d.ts +65 -0
  23. package/dist/modules/CertificateModule/CertificateModule.d.ts +9 -0
  24. package/dist/modules/CertificateModule/types.d.ts +49 -0
  25. package/dist/modules/DiscussionModule/DiscussionModule.d.ts +8 -0
  26. package/dist/modules/DiscussionModule/types.d.ts +47 -0
  27. package/dist/modules/ExamModule/ExamModule.d.ts +8 -0
  28. package/dist/modules/ExamModule/types.d.ts +64 -0
  29. package/dist/modules/GradeCenterModule/GradeCenterModule.d.ts +9 -0
  30. package/dist/modules/GradeCenterModule/types.d.ts +54 -0
  31. package/dist/modules/QuizModule/QuizModule.d.ts +1 -1
  32. package/dist/modules/QuizModule/types.d.ts +6 -1
  33. package/dist/modules/SurveyModule/SurveyModule.d.ts +7 -0
  34. package/dist/modules/SurveyModule/types.d.ts +49 -0
  35. package/dist/modules/index.d.ts +12 -0
  36. package/dist/modules.cjs +1 -0
  37. package/dist/modules.js +1422 -0
  38. package/dist/progress/achievement-badge.d.ts +6 -0
  39. package/dist/progress/activity-timeline.d.ts +6 -0
  40. package/dist/progress/index.d.ts +4 -1
  41. package/dist/progress/stat-card.d.ts +1 -1
  42. package/dist/progress/streak-badge.d.ts +6 -0
  43. package/dist/progress/types.d.ts +97 -0
  44. package/dist/questions/essay.d.ts +1 -1
  45. package/dist/questions/hotspot.d.ts +21 -0
  46. package/dist/questions/index.d.ts +9 -1
  47. package/dist/questions/inline-choice.d.ts +21 -0
  48. package/dist/questions/matching.d.ts +22 -0
  49. package/dist/questions/numeric.d.ts +11 -0
  50. package/dist/questions/ordering.d.ts +12 -0
  51. package/dist/questions/scenario.d.ts +23 -0
  52. package/dist/questions/scoring.d.ts +22 -0
  53. package/dist/questions/spreadsheet.d.ts +29 -0
  54. package/dist/questions/types.d.ts +106 -1
  55. package/dist/questions/use-drag-reorder.d.ts +17 -0
  56. package/dist/sections/CertificateViewer/types.d.ts +7 -5
  57. package/dist/sections/ExamSession/ExamSession.d.ts +1 -1
  58. package/dist/sections/ExamSession/types.d.ts +6 -1
  59. package/dist/sections/ForumBoard/ForumBoard.d.ts +8 -0
  60. package/dist/sections/ForumBoard/types.d.ts +64 -0
  61. package/dist/sections/QuizSession/QuizSession.d.ts +1 -1
  62. package/dist/sections/QuizSession/types.d.ts +6 -1
  63. package/dist/sections/RequirementsChecklist/RequirementsChecklist.d.ts +8 -0
  64. package/dist/sections/RequirementsChecklist/types.d.ts +37 -0
  65. package/dist/sections/RubricView/RubricView.d.ts +9 -0
  66. package/dist/sections/RubricView/types.d.ts +50 -0
  67. package/dist/sections/index.d.ts +7 -1
  68. package/dist/sections.cjs +1 -1
  69. package/dist/sections.js +250 -1715
  70. package/dist/social/post-card.d.ts +1 -1
  71. package/dist/tabs-DRM2Iq_J.cjs +172 -0
  72. package/dist/tabs-Wf3h_Cx3.js +21580 -0
  73. package/dist/ui/alert.d.ts +1 -1
  74. package/dist/ui/badge.d.ts +1 -1
  75. package/dist/ui/button.d.ts +1 -1
  76. package/dist/ui/drawer.d.ts +84 -0
  77. package/dist/ui/index.d.ts +3 -0
  78. package/dist/ui/progress.d.ts +1 -1
  79. package/dist/ui/rich-text-editor.d.ts +30 -0
  80. package/dist/ui/rich-text-toolbar.d.ts +8 -0
  81. package/dist/utils/array-utils.d.ts +4 -0
  82. package/dist/utils/flatten-leaves.d.ts +6 -0
  83. package/dist/utils/format-file-size.d.ts +1 -0
  84. package/dist/utils/format-timestamp.d.ts +1 -0
  85. package/dist/utils/is-empty-html.d.ts +5 -0
  86. package/dist/utils/shuffle.d.ts +1 -0
  87. package/dist/utils/string-utils.d.ts +12 -0
  88. package/dist/video/video-bookmark.d.ts +1 -1
  89. package/dist/video/video-playlist-item.d.ts +1 -1
  90. package/package.json +92 -3
  91. package/src/assessment-toolbar/assessment-toolbar.tsx +54 -49
  92. package/src/assessment-toolbar/index.ts +6 -0
  93. package/src/assessment-toolbar/question-header-bar.tsx +61 -0
  94. package/src/assessment-toolbar/question-materials-drawer.tsx +55 -0
  95. package/src/assessment-toolbar/question-navigator.tsx +3 -31
  96. package/src/assessment-toolbar/timer-display.tsx +2 -2
  97. package/src/assessment-toolbar/types.ts +54 -4
  98. package/src/assessment-toolbar/use-countdown.ts +153 -0
  99. package/src/common/index.ts +3 -0
  100. package/src/common/search-input.tsx +7 -6
  101. package/src/common/stepper.tsx +100 -0
  102. package/src/common/types.ts +39 -0
  103. package/src/content/attachment-list.tsx +90 -0
  104. package/src/content/content-block.tsx +4 -2
  105. package/src/content/file-upload-zone.tsx +1 -6
  106. package/src/content/index.ts +3 -0
  107. package/src/content/types.ts +41 -0
  108. package/src/curriculum/curriculum-item.tsx +7 -3
  109. package/src/feedback/feedback-banner.tsx +12 -14
  110. package/src/flashcards/flashcard-deck.tsx +1 -9
  111. package/src/flashcards/flashcard.tsx +1 -1
  112. package/src/modules/AssignmentModule/AssignmentModule.tsx +305 -0
  113. package/src/modules/AssignmentModule/types.ts +73 -0
  114. package/src/modules/CertificateModule/CertificateModule.tsx +161 -0
  115. package/src/modules/CertificateModule/types.ts +47 -0
  116. package/src/modules/CoursePlayer/CoursePlayer.tsx +44 -48
  117. package/src/modules/DiscussionModule/DiscussionModule.tsx +110 -0
  118. package/src/modules/DiscussionModule/types.ts +54 -0
  119. package/src/modules/ExamModule/ExamModule.tsx +285 -0
  120. package/src/modules/ExamModule/types.ts +66 -0
  121. package/src/modules/FlashcardLab/FlashcardLab.tsx +29 -16
  122. package/src/modules/GradeCenterModule/GradeCenterModule.tsx +169 -0
  123. package/src/modules/GradeCenterModule/types.ts +63 -0
  124. package/src/modules/QuizModule/QuizModule.tsx +88 -88
  125. package/src/modules/QuizModule/types.ts +6 -1
  126. package/src/modules/SurveyModule/SurveyModule.tsx +180 -0
  127. package/src/modules/SurveyModule/types.ts +51 -0
  128. package/src/modules/index.ts +24 -0
  129. package/src/progress/achievement-badge.tsx +52 -0
  130. package/src/progress/activity-timeline.tsx +84 -0
  131. package/src/progress/index.ts +7 -0
  132. package/src/progress/stat-card.tsx +30 -18
  133. package/src/progress/streak-badge.tsx +35 -0
  134. package/src/progress/types.ts +101 -0
  135. package/src/questions/choice.tsx +7 -9
  136. package/src/questions/essay.tsx +23 -25
  137. package/src/questions/fill-in-the-blank.tsx +13 -16
  138. package/src/questions/hotspot.tsx +154 -0
  139. package/src/questions/index.ts +16 -0
  140. package/src/questions/inline-choice.tsx +151 -0
  141. package/src/questions/matching.tsx +228 -0
  142. package/src/questions/multiple-choice.tsx +7 -9
  143. package/src/questions/numeric.tsx +102 -0
  144. package/src/questions/ordering.tsx +159 -0
  145. package/src/questions/question-renderer.tsx +21 -0
  146. package/src/questions/scenario.tsx +140 -0
  147. package/src/questions/scoring.ts +201 -0
  148. package/src/questions/spreadsheet.tsx +259 -0
  149. package/src/questions/true-false.tsx +7 -9
  150. package/src/questions/types.ts +123 -1
  151. package/src/questions/use-drag-reorder.ts +80 -0
  152. package/src/sections/AnnouncementFeed/AnnouncementFeed.tsx +2 -15
  153. package/src/sections/AssessmentReview/AssessmentReview.tsx +13 -2
  154. package/src/sections/AssignmentSubmission/AssignmentSubmission.tsx +7 -5
  155. package/src/sections/CertificateViewer/CertificateViewer.tsx +409 -56
  156. package/src/sections/CertificateViewer/types.ts +13 -5
  157. package/src/sections/CourseOutline/CourseOutline.tsx +4 -14
  158. package/src/sections/DiscussionThread/DiscussionThread.tsx +13 -10
  159. package/src/sections/ExamSession/ExamSession.tsx +44 -7
  160. package/src/sections/ExamSession/types.ts +6 -1
  161. package/src/sections/ForumBoard/ForumBoard.tsx +284 -0
  162. package/src/sections/ForumBoard/types.ts +67 -0
  163. package/src/sections/GradebookTable/GradebookTable.tsx +1 -1
  164. package/src/sections/LecturePlayer/LecturePlayer.tsx +1 -1
  165. package/src/sections/LessonPage/LessonPage.tsx +5 -9
  166. package/src/sections/PracticeQuiz/PracticeQuiz.tsx +15 -26
  167. package/src/sections/ProgressDashboard/ProgressDashboard.tsx +65 -65
  168. package/src/sections/QuizSession/QuizSession.tsx +67 -8
  169. package/src/sections/QuizSession/types.ts +6 -1
  170. package/src/sections/RequirementsChecklist/RequirementsChecklist.tsx +107 -0
  171. package/src/sections/RequirementsChecklist/types.ts +38 -0
  172. package/src/sections/ResourceLibrary/ResourceLibrary.tsx +4 -9
  173. package/src/sections/RubricView/RubricView.tsx +138 -0
  174. package/src/sections/RubricView/types.ts +52 -0
  175. package/src/sections/ScrollableQuiz/ScrollableQuiz.tsx +23 -9
  176. package/src/sections/SurveyForm/SurveyForm.tsx +8 -5
  177. package/src/sections/index.ts +20 -1
  178. package/src/social/post-card.tsx +8 -19
  179. package/src/social/user-avatar.tsx +1 -0
  180. package/src/styles/globals.css +13 -0
  181. package/src/ui/drawer.tsx +600 -0
  182. package/src/ui/index.ts +19 -0
  183. package/src/ui/rich-text-editor.tsx +109 -0
  184. package/src/ui/rich-text-toolbar.tsx +156 -0
  185. package/src/utils/array-utils.ts +17 -0
  186. package/src/utils/flatten-leaves.ts +17 -0
  187. package/src/utils/format-file-size.ts +5 -0
  188. package/src/utils/format-timestamp.ts +13 -0
  189. package/src/utils/is-empty-html.ts +7 -0
  190. package/src/utils/shuffle.ts +8 -0
  191. package/src/utils/string-utils.ts +30 -0
  192. package/src/video/video-bookmark.tsx +4 -3
  193. package/src/video/video-chapter-list.tsx +9 -4
  194. package/src/video/video-player.tsx +11 -4
  195. package/src/video/video-playlist-item.tsx +8 -3
  196. package/src/video/video-thumbnail-card.tsx +4 -0
  197. package/src/video/video-transcript.tsx +8 -5
  198. package/dist/table-BrS5cDQu.js +0 -2510
  199. package/dist/table-D6AkBBEo.cjs +0 -1
package/dist/sections.js CHANGED
@@ -1,944 +1,144 @@
1
- import { jsxs as t, jsx as e, Fragment as ee } from "react/jsx-runtime";
2
- import { useState as I, useMemo as j, useRef as ge, useEffect as ie, useCallback as Qe, Fragment as Be } from "react";
3
- import { q as be, C as L, t as Q, X, c as F, ak as oe, w as je, x as $e, r as R, N as _e, B as Ne, Z as V, P as ne, F as Ee, J as He, A as ve, b as we, z as Ve, S as Ye, _ as Je, ad as te, a as ye, D as Ke, Y as Ze, af as J, ah as K, ag as Z, a9 as Se, ab as ke, ac as G, H as ze, R as ue, aj as Ge, U as Xe, a0 as Ce, G as Ue, aa as se, K as me, Q as he, O as We, a1 as Oe, a7 as qe, a8 as le, a6 as Ae, a2 as et, a4 as Y, V as tt, $ as ae } from "./table-BrS5cDQu.js";
4
- import { CheckCircle as W, Clock as De, Check as fe, ChevronRight as nt, List as rt, Grid as st, Download as Te, Pin as lt, MessageSquare as at, Heart as it, Reply as ct, Save as dt, Send as Ie, ArrowUp as ot, ArrowDown as ut, Flame as mt, BookOpen as Fe, Award as Le, Trophy as ht, Printer as ft } from "lucide-react";
5
- function Ct({
6
- questions: r,
7
- initialAnswers: s = [],
8
- onSubmit: a,
9
- onAnswerChange: d,
10
- timeElapsedSeconds: p,
11
- timeLimitSeconds: l,
12
- isSubmitting: h = !1,
13
- readOnly: i = !1,
14
- className: w,
15
- style: y
16
- }) {
17
- const [c, b] = I(0), [T, u] = I(s), [U, N] = I(/* @__PURE__ */ new Set()), z = r[c], x = j(
18
- () => r.map((S, f) => ({
19
- uid: S.uid,
20
- sequence: f + 1,
21
- isFlagged: U.has(S.uid),
22
- isAnswered: T.some((m) => m.uid === S.uid),
23
- isSkipped: !1
24
- })),
25
- [r, T, U]
26
- );
27
- function C(S) {
28
- if (!z) return;
29
- const f = z.uid, m = S.map((v) => ({
30
- uid: f,
31
- answerUid: v.uid,
32
- content: v.content
33
- }));
34
- u((v) => {
35
- const k = [...v.filter((D) => D.uid !== f), ...m];
36
- return d == null || d(k), k;
37
- });
38
- }
39
- function n(S) {
40
- const f = r.findIndex((m) => m.uid === S);
41
- f !== -1 && b(f);
42
- }
43
- function o(S) {
44
- N((f) => {
45
- const m = new Set(f);
46
- return m.has(S) ? m.delete(S) : m.add(S), m;
47
- });
48
- }
49
- function g() {
50
- a(T);
51
- }
52
- return /* @__PURE__ */ t("div", { className: F(w), style: y, children: [
53
- /* @__PURE__ */ e(
54
- be,
55
- {
56
- currentQuestionIndex: c,
57
- totalQuestions: r.length,
58
- hasNext: c < r.length - 1,
59
- hasPrevious: c > 0,
60
- onNext: () => b((S) => Math.min(S + 1, r.length - 1)),
61
- onPrevious: () => b((S) => Math.max(S - 1, 0)),
62
- onSubmit: g,
63
- timeElapsedSeconds: p,
64
- timeLimitSeconds: l,
65
- questions: x,
66
- onNavigateToQuestion: n,
67
- onToggleFlag: o,
68
- currentQuestionUid: z == null ? void 0 : z.uid,
69
- isSubmitting: h,
70
- readOnly: i
71
- }
72
- ),
73
- z && /* @__PURE__ */ e(L, { className: "mt-3", children: /* @__PURE__ */ e(Q, { className: "pt-6", children: /* @__PURE__ */ e(
74
- X,
75
- {
76
- question: z,
77
- sessionAnswers: T.filter(
78
- (S) => S.uid === z.uid
79
- ),
80
- onAnswer: C,
81
- readOnly: i
82
- }
83
- ) }) })
84
- ] });
85
- }
86
- function Ut({
87
- video: r,
88
- notes: s,
89
- layout: a = "horizontal",
90
- notesPanelWidth: d = "340px",
91
- notesPanelHeight: p = "240px",
92
- className: l,
93
- style: h
94
- }) {
95
- const i = a === "horizontal";
96
- return s ? /* @__PURE__ */ t(
97
- "div",
98
- {
99
- className: F(
100
- "flex overflow-hidden",
101
- i ? "flex-row" : "flex-col",
102
- l
103
- ),
104
- style: h,
105
- children: [
106
- /* @__PURE__ */ e("div", { className: "flex-1 min-w-0 min-h-0", children: /* @__PURE__ */ e(oe, { ...r }) }),
107
- /* @__PURE__ */ t(
108
- L,
109
- {
110
- className: F(
111
- "overflow-auto shrink-0 rounded-none border-0",
112
- i ? "border-l border-border" : "border-t border-border w-full"
113
- ),
114
- style: {
115
- width: i ? d : void 0,
116
- height: i ? void 0 : p
117
- },
118
- children: [
119
- /* @__PURE__ */ e(je, { children: /* @__PURE__ */ e($e, { children: "Notes" }) }),
120
- /* @__PURE__ */ e(Q, { children: typeof s == "string" ? /* @__PURE__ */ e("span", { className: "text-sm text-foreground", children: s }) : s })
121
- ]
122
- }
123
- )
124
- ]
125
- }
126
- ) : /* @__PURE__ */ e("div", { className: l, style: h, children: /* @__PURE__ */ e(oe, { ...r }) });
127
- }
128
- function At({
129
- cards: r,
130
- title: s,
131
- description: a,
132
- shuffled: d = !1,
133
- onComplete: p,
134
- readOnly: l = !1,
135
- className: h,
136
- style: i
1
+ import { A as be, a as ge, C as ve, b as Ne, D as we, E as ye, F as Ce, c as Se, G as ze, L as Te, d as ke, P as Ae, e as Pe, Q as Ue, R as Le, f as Qe, S as Ee } from "./ForumBoard-CHXU3mjC.js";
2
+ import { jsxs as r, jsx as e } from "react/jsx-runtime";
3
+ import { useState as S, useRef as Z, useMemo as U, useEffect as $, useCallback as J } from "react";
4
+ import { c as f, C as Q, w as I, aj as O, an as W, B as L, am as X, aG as B, aI as D, aH as F, aB as q, aD as ee, aE as M, Z as K, a8 as G, b as _, aK as te, u as ie, aT as se } from "./tabs-Wf3h_Cx3.js";
5
+ import { List as ne, Grid as re, Download as ae, Pin as le } from "lucide-react";
6
+ function ue({
7
+ questions: l,
8
+ initialAnswers: h = [],
9
+ onSubmit: x,
10
+ onAnswerChange: b,
11
+ showNavigator: z = !0,
12
+ showQuestionNumbers: T = !0,
13
+ questionGroups: g,
14
+ isSubmitting: N = !1,
15
+ readOnly: u = !1,
16
+ className: k,
17
+ style: A
137
18
  }) {
138
- const [w, y] = I(!1), c = {
139
- totalCards: r.length,
140
- wasShuffled: d
141
- };
142
- function b() {
143
- y(!0), p == null || p(c);
144
- }
145
- function T() {
146
- y(!1);
147
- }
148
- return w ? /* @__PURE__ */ e("div", { className: F("flex flex-col items-center", h), style: i, children: /* @__PURE__ */ e(L, { children: /* @__PURE__ */ t(Q, { className: "pt-6 text-center flex flex-col items-center gap-2", children: [
149
- /* @__PURE__ */ e(W, { size: 48, className: "text-success" }),
150
- /* @__PURE__ */ e("span", { className: "text-xl font-bold text-foreground", children: "Deck complete!" }),
151
- s && /* @__PURE__ */ t("span", { className: "text-muted-foreground", children: [
152
- "You finished ",
153
- /* @__PURE__ */ e("strong", { children: s })
154
- ] }),
155
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
156
- c.totalCards,
157
- " card",
158
- c.totalCards !== 1 ? "s" : "",
159
- " studied",
160
- c.wasShuffled ? " (shuffled)" : ""
161
- ] }),
162
- /* @__PURE__ */ e(R, { className: "mt-2", onClick: T, children: "Study Again" })
163
- ] }) }) }) : /* @__PURE__ */ e("div", { className: F("flex flex-col items-center", h), style: i, children: /* @__PURE__ */ e(
164
- _e,
165
- {
166
- cards: r,
167
- deckName: s,
168
- deckDescription: a,
169
- shuffled: d,
170
- showProgress: !0,
171
- onComplete: b,
172
- readOnly: l
19
+ var V;
20
+ const [p, w] = S(h), [i, c] = S(((V = l[0]) == null ? void 0 : V.uid) ?? null), d = Z(/* @__PURE__ */ new Map()), m = U(() => {
21
+ const s = /* @__PURE__ */ new Map();
22
+ for (const n of p) {
23
+ const a = s.get(n.uid);
24
+ a ? a.push(n) : s.set(n.uid, [n]);
173
25
  }
174
- ) });
175
- }
176
- function pt({
177
- score: r
178
- }) {
179
- const s = r.percentage !== void 0 ? r.percentage : r.total > 0 ? Math.round(r.correct / r.total * 100) : 0;
180
- return /* @__PURE__ */ e(L, { className: "mb-3", children: /* @__PURE__ */ e(Q, { className: "pt-6", children: /* @__PURE__ */ t("div", { className: "flex flex-wrap items-center gap-2", children: [
181
- /* @__PURE__ */ t("div", { children: [
182
- /* @__PURE__ */ t("span", { className: "text-2xl font-bold leading-none text-foreground", children: [
183
- s,
184
- "%"
185
- ] }),
186
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
187
- r.correct,
188
- " of ",
189
- r.total,
190
- " correct"
191
- ] })
192
- ] }),
193
- r.passed !== void 0 && /* @__PURE__ */ e(Ne, { variant: r.passed ? "success" : "destructive", children: r.passed ? "Passed" : "Failed" }),
194
- r.passingScore !== void 0 && /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
195
- "Passing score: ",
196
- r.passingScore,
197
- "%"
198
- ] })
199
- ] }) }) });
200
- }
201
- function ce({
202
- questions: r,
203
- sessionAnswers: s,
204
- showCorrectAnswers: a
205
- }) {
206
- return /* @__PURE__ */ e("div", { className: "flex flex-col gap-3", children: r.map((d, p) => /* @__PURE__ */ t(L, { className: "overflow-hidden", children: [
207
- /* @__PURE__ */ e("div", { className: "px-2 py-1 bg-muted", children: /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground font-semibold", children: [
208
- "Question ",
209
- p + 1
210
- ] }) }),
211
- /* @__PURE__ */ e(V, {}),
212
- /* @__PURE__ */ e(Q, { className: "pt-4 pb-4", children: /* @__PURE__ */ e(
213
- X,
214
- {
215
- question: d,
216
- sessionAnswers: s.filter((l) => l.uid === d.uid),
217
- readOnly: !0,
218
- showCorrectAnswers: a
219
- }
220
- ) })
221
- ] }, d.uid)) });
222
- }
223
- function xt(r, s, a, d) {
224
- const p = new Map(r.map((i) => [i.uid, i])), l = new Set(a.flatMap((i) => i.questionUids)), h = r.filter((i) => !l.has(i.uid));
225
- return /* @__PURE__ */ t("div", { className: "flex flex-col gap-4", children: [
226
- a.map((i) => {
227
- const w = i.questionUids.map((y) => p.get(y)).filter(Boolean);
228
- return /* @__PURE__ */ t("div", { children: [
229
- /* @__PURE__ */ e("span", { className: "uppercase text-xs tracking-wide text-muted-foreground font-semibold", children: i.label }),
230
- /* @__PURE__ */ e(V, { className: "mb-2" }),
231
- /* @__PURE__ */ e(
232
- ce,
233
- {
234
- questions: w,
235
- sessionAnswers: s,
236
- showCorrectAnswers: d
237
- }
238
- )
239
- ] }, i.label);
240
- }),
241
- h.length > 0 && /* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(
242
- ce,
243
- {
244
- questions: h,
245
- sessionAnswers: s,
246
- showCorrectAnswers: d
247
- }
248
- ) })
249
- ] });
250
- }
251
- function Dt({
252
- questions: r,
253
- sessionAnswers: s,
254
- score: a,
255
- questionGroups: d,
256
- showCorrectAnswers: p = !0,
257
- className: l,
258
- style: h
259
- }) {
260
- return /* @__PURE__ */ t("div", { className: F(l), style: h, children: [
261
- a && /* @__PURE__ */ e(pt, { score: a }),
262
- d && d.length > 0 ? xt(r, s, d, p) : /* @__PURE__ */ e(
263
- ce,
264
- {
265
- questions: r,
266
- sessionAnswers: s,
267
- showCorrectAnswers: p
268
- }
269
- )
270
- ] });
271
- }
272
- function Me(r) {
273
- const s = [];
274
- for (const a of r)
275
- !a.children || a.children.length === 0 ? s.push(a.uid) : s.push(...Me(a.children));
276
- return s;
277
- }
278
- function Tt({
279
- items: r,
280
- progress: s,
281
- courseTitle: a,
282
- activeItemUid: d,
283
- onItemClick: p,
284
- showOverallProgress: l = !0,
285
- showDuration: h = !0,
286
- showIcons: i = !0,
287
- readOnly: w = !1,
288
- className: y,
289
- style: c
290
- }) {
291
- const { completedCount: b, totalCount: T, percentage: u } = j(() => {
292
- const U = Me(r), N = U.length, z = s ? U.filter(
293
- (x) => s.some((C) => C.resourceUid === x && C.isCompleted)
294
- ).length : 0;
295
- return {
296
- completedCount: z,
297
- totalCount: N,
298
- percentage: N > 0 ? Math.round(z / N * 100) : 0
299
- };
300
- }, [r, s]);
301
- return /* @__PURE__ */ t("div", { className: F(y), style: c, children: [
302
- (a || l) && /* @__PURE__ */ t("div", { className: "px-2 pt-2 pb-1", children: [
303
- a && /* @__PURE__ */ e("p", { className: F("font-semibold text-sm text-foreground", l && "mb-1"), children: a }),
304
- l && /* @__PURE__ */ t("div", { children: [
305
- /* @__PURE__ */ e(ne, { value: u, size: "sm" }),
306
- /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground mt-0.5 block", children: [
307
- b,
308
- " of ",
309
- T,
310
- " completed"
311
- ] })
312
- ] })
313
- ] }),
314
- /* @__PURE__ */ e(
315
- Ee,
316
- {
317
- items: r,
318
- progress: s,
319
- activeItemUid: d,
320
- onItemClick: p,
321
- readOnly: w,
322
- showDuration: h,
323
- showIcons: i,
324
- showProgress: !0
325
- }
326
- )
327
- ] });
328
- }
329
- function It({
330
- questions: r,
331
- initialAnswers: s = [],
332
- onSubmit: a,
333
- onAnswerChange: d,
334
- showNavigator: p = !0,
335
- showQuestionNumbers: l = !0,
336
- questionGroups: h,
337
- isSubmitting: i = !1,
338
- readOnly: w = !1,
339
- className: y,
340
- style: c
341
- }) {
342
- var S;
343
- const [b, T] = I(s), [u, U] = I(((S = r[0]) == null ? void 0 : S.uid) ?? null), N = ge(/* @__PURE__ */ new Map()), z = j(() => {
344
- const f = new Set(b.map((m) => m.uid));
345
- return r.filter((m) => f.has(m.uid)).length;
346
- }, [r, b]);
347
- ie(() => {
348
- const f = new IntersectionObserver(
349
- (m) => {
350
- for (const v of m)
351
- v.isIntersecting && U(v.target.getAttribute("data-question-uid"));
26
+ return s;
27
+ }, [p]), P = U(
28
+ () => l.filter((s) => m.has(s.uid)).length,
29
+ [l, m]
30
+ );
31
+ $(() => {
32
+ const s = new IntersectionObserver(
33
+ (n) => {
34
+ for (const a of n)
35
+ a.isIntersecting && c(a.target.getAttribute("data-question-uid"));
352
36
  },
353
37
  { rootMargin: "-20% 0px -60% 0px" }
354
38
  );
355
- return N.current.forEach((m) => f.observe(m)), () => f.disconnect();
356
- }, [r]);
357
- const x = Qe((f, m) => {
358
- m ? N.current.set(f, m) : N.current.delete(f);
39
+ return d.current.forEach((n) => s.observe(n)), () => s.disconnect();
40
+ }, [l]);
41
+ const j = J((s, n) => {
42
+ n ? d.current.set(s, n) : d.current.delete(s);
359
43
  }, []);
360
- function C(f, m) {
361
- const v = m.map((A) => ({
362
- uid: f,
363
- answerUid: A.uid,
364
- content: A.content
44
+ function t(s, n) {
45
+ const a = n.map((o) => ({
46
+ uid: s,
47
+ answerUid: o.uid,
48
+ content: o.content
365
49
  }));
366
- T((A) => {
367
- const D = [...A.filter((P) => P.uid !== f), ...v];
368
- return d == null || d(D), D;
50
+ w((o) => {
51
+ const R = [...o.filter((Y) => Y.uid !== s), ...a];
52
+ return b == null || b(R), R;
369
53
  });
370
54
  }
371
- function n(f) {
372
- var m;
373
- (m = N.current.get(f)) == null || m.scrollIntoView({ behavior: "smooth", block: "center" });
55
+ function v(s) {
56
+ var n;
57
+ (n = d.current.get(s)) == null || n.scrollIntoView({ behavior: "smooth", block: "center" });
374
58
  }
375
- const o = j(() => {
376
- if (!h) return [{ label: null, questions: r }];
377
- const f = h.map(
378
- (A) => ({
379
- label: A.label,
380
- questions: A.questionUids.map((k) => r.find((D) => D.uid === k)).filter(Boolean)
59
+ const y = U(() => {
60
+ if (!g) return [{ label: null, questions: l }];
61
+ const s = g.map(
62
+ (o) => ({
63
+ label: o.label,
64
+ questions: o.questionUids.map((C) => l.find((R) => R.uid === C)).filter(Boolean)
381
65
  })
382
- ), m = new Set(h.flatMap((A) => A.questionUids)), v = r.filter((A) => !m.has(A.uid));
383
- return v.length > 0 && f.push({ label: null, questions: v }), f;
384
- }, [r, h]);
385
- let g = 0;
386
- return /* @__PURE__ */ t("div", { className: F("flex gap-3", y), style: c, children: [
387
- /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
388
- o.map((f, m) => /* @__PURE__ */ t("div", { children: [
389
- f.label && /* @__PURE__ */ e("p", { className: F("text-lg font-semibold mb-2 text-foreground", m > 0 && "mt-4"), children: f.label }),
390
- f.questions.map((v) => {
391
- const A = g++;
66
+ ), n = new Set(g.flatMap((o) => o.questionUids)), a = l.filter((o) => !n.has(o.uid));
67
+ return a.length > 0 && s.push({ label: null, questions: a }), s;
68
+ }, [l, g]);
69
+ let E = 0;
70
+ return /* @__PURE__ */ r("div", { className: f("flex gap-3", k), style: A, children: [
71
+ /* @__PURE__ */ r("div", { className: "flex-1 min-w-0", children: [
72
+ y.map((s, n) => /* @__PURE__ */ r("div", { children: [
73
+ s.label && /* @__PURE__ */ e("p", { className: f("text-lg font-semibold mb-2 text-foreground", n > 0 && "mt-4"), children: s.label }),
74
+ s.questions.map((a) => {
75
+ const o = E++;
392
76
  return /* @__PURE__ */ e(
393
- L,
77
+ Q,
394
78
  {
395
- ref: (k) => x(v.uid, k),
396
- "data-question-uid": v.uid,
79
+ ref: (C) => j(a.uid, C),
80
+ "data-question-uid": a.uid,
397
81
  className: "mb-2",
398
- children: /* @__PURE__ */ t(Q, { className: "pt-6", children: [
399
- l && /* @__PURE__ */ t("p", { className: "font-semibold text-sm text-muted-foreground mb-1", children: [
82
+ children: /* @__PURE__ */ r(I, { className: "pt-6", children: [
83
+ T && /* @__PURE__ */ r("p", { className: "font-semibold text-sm text-muted-foreground mb-1", children: [
400
84
  "Question ",
401
- A + 1
85
+ o + 1
402
86
  ] }),
403
87
  /* @__PURE__ */ e(
404
- X,
88
+ O,
405
89
  {
406
- question: v,
407
- sessionAnswers: b.filter((k) => k.uid === v.uid),
408
- onAnswer: (k) => C(v.uid, k),
409
- readOnly: w
90
+ question: a,
91
+ sessionAnswers: m.get(a.uid) ?? [],
92
+ onAnswer: (C) => t(a.uid, C),
93
+ readOnly: u
410
94
  }
411
95
  )
412
96
  ] })
413
97
  },
414
- v.uid
98
+ a.uid
415
99
  );
416
100
  })
417
- ] }, m)),
418
- /* @__PURE__ */ t("div", { className: "mt-3 flex justify-between items-center", children: [
419
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
420
- z,
101
+ ] }, s.label ?? `ungrouped-${n}`)),
102
+ /* @__PURE__ */ e(W, { className: "my-3" }),
103
+ /* @__PURE__ */ r("div", { className: "flex justify-between items-center", children: [
104
+ /* @__PURE__ */ r("span", { className: "text-sm text-muted-foreground", children: [
105
+ P,
421
106
  " of ",
422
- r.length,
107
+ l.length,
423
108
  " answered"
424
109
  ] }),
425
110
  /* @__PURE__ */ e(
426
- R,
111
+ L,
427
112
  {
428
- onClick: () => a(b),
429
- disabled: i || w,
430
- children: i ? "Submitting..." : "Submit"
113
+ onClick: () => x(p),
114
+ disabled: N || u,
115
+ children: N ? "Submitting..." : "Submit"
431
116
  }
432
117
  )
433
118
  ] })
434
119
  ] }),
435
- p && /* @__PURE__ */ t(L, { className: "hidden md:block w-50 shrink-0 sticky top-4 self-start p-3", children: [
120
+ z && /* @__PURE__ */ e(Q, { className: "hidden md:block w-50 shrink-0 sticky top-4 self-start", children: /* @__PURE__ */ r(I, { className: "p-3", children: [
436
121
  /* @__PURE__ */ e("p", { className: "font-semibold text-sm mb-1 text-foreground", children: "Questions" }),
437
- /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1", children: r.map((f, m) => {
438
- const v = b.some((k) => k.uid === f.uid), A = u === f.uid;
122
+ /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1", children: l.map((s, n) => {
123
+ const a = m.has(s.uid), o = i === s.uid;
439
124
  return /* @__PURE__ */ e(
440
125
  "button",
441
126
  {
442
127
  type: "button",
443
- className: F(
128
+ className: f(
444
129
  "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",
445
- A ? "bg-primary border-primary text-primary-foreground" : v ? "border-success text-success bg-transparent" : "border-border text-foreground bg-transparent hover:bg-muted"
130
+ o ? "bg-primary border-primary text-primary-foreground" : a ? "border-success text-success bg-transparent" : "border-border text-foreground bg-transparent hover:bg-muted"
446
131
  ),
447
- onClick: () => n(f.uid),
448
- children: m + 1
132
+ onClick: () => v(s.uid),
133
+ children: n + 1
449
134
  },
450
- f.uid
135
+ s.uid
451
136
  );
452
137
  }) })
453
- ] })
454
- ] });
455
- }
456
- function gt(r) {
457
- const s = [...r];
458
- for (let a = s.length - 1; a > 0; a--) {
459
- const d = Math.floor(Math.random() * (a + 1));
460
- [s[a], s[d]] = [s[d], s[a]];
461
- }
462
- return s;
463
- }
464
- function Ft({
465
- questions: r,
466
- instantFeedback: s = !0,
467
- allowRetry: a = !0,
468
- onComplete: d,
469
- shuffled: p = !1,
470
- readOnly: l = !1,
471
- className: h,
472
- style: i
473
- }) {
474
- const w = j(
475
- () => p ? gt(r) : r,
476
- // eslint-disable-next-line react-hooks/exhaustive-deps
477
- [r, p]
478
- ), [y, c] = I(0), [b, T] = I(/* @__PURE__ */ new Set()), [u, U] = I(/* @__PURE__ */ new Map()), [N, z] = I(/* @__PURE__ */ new Set()), [x, C] = I(null), [n, o] = I(!1), g = w[y], S = g ? b.has(g.uid) : !1;
479
- function f() {
480
- var O;
481
- if (!g || !x) return;
482
- const k = (u.get(g.uid) ?? 0) + 1;
483
- U((B) => new Map(B).set(g.uid, k)), T((B) => new Set(B).add(g.uid));
484
- const D = new Set(
485
- ((O = g.answers) == null ? void 0 : O.filter((B) => B.isCorrect).map((B) => B.uid)) ?? []
486
- ), P = new Set(x.map((B) => B.uid));
487
- D.size === P.size && [...D].every((B) => P.has(B)) && k === 1 && z((B) => new Set(B).add(g.uid));
488
- }
489
- function m() {
490
- g && (T((k) => {
491
- const D = new Set(k);
492
- return D.delete(g.uid), D;
493
- }), C(null));
494
- }
495
- function v() {
496
- if (y < w.length - 1)
497
- c((k) => k + 1), C(null);
498
- else {
499
- const k = {
500
- totalQuestions: w.length,
501
- correctOnFirstAttempt: N.size,
502
- totalAttempts: Array.from(u.values()).reduce((D, P) => D + P, 0)
503
- };
504
- o(!0), d == null || d(k);
505
- }
506
- }
507
- const A = j(() => {
508
- var P;
509
- if (!g || !x) return !1;
510
- const k = new Set(
511
- ((P = g.answers) == null ? void 0 : P.filter(($) => $.isCorrect).map(($) => $.uid)) ?? []
512
- ), D = new Set(x.map(($) => $.uid));
513
- return k.size === D.size && [...k].every(($) => D.has($));
514
- }, [g, x]);
515
- if (n) {
516
- const k = w.length > 0 ? Math.round(N.size / w.length * 100) : 0;
517
- return /* @__PURE__ */ e(L, { className: h, style: i, children: /* @__PURE__ */ t(Q, { className: "pt-6 text-center", children: [
518
- /* @__PURE__ */ e(W, { size: 48, className: "text-success mx-auto mb-4" }),
519
- /* @__PURE__ */ e("p", { className: "text-xl font-bold mb-1 text-foreground", children: "Practice Complete!" }),
520
- /* @__PURE__ */ t("p", { className: "text-muted-foreground mb-2", children: [
521
- N.size,
522
- " of ",
523
- w.length,
524
- " correct on first attempt (",
525
- k,
526
- "%)"
527
- ] }),
528
- /* @__PURE__ */ e("div", { className: "flex justify-center", children: /* @__PURE__ */ e(
529
- R,
530
- {
531
- variant: "outline",
532
- onClick: () => {
533
- c(0), T(/* @__PURE__ */ new Set()), U(/* @__PURE__ */ new Map()), z(/* @__PURE__ */ new Set()), C(null), o(!1);
534
- },
535
- children: "Practice Again"
536
- }
537
- ) })
538
- ] }) });
539
- }
540
- return /* @__PURE__ */ t("div", { className: h, style: i, children: [
541
- /* @__PURE__ */ t("div", { className: "flex justify-between items-center mb-2", children: [
542
- /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-foreground", children: [
543
- "Question ",
544
- y + 1,
545
- " of ",
546
- w.length
547
- ] }),
548
- /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: [
549
- N.size,
550
- " correct on first try"
551
- ] })
552
- ] }),
553
- /* @__PURE__ */ e(
554
- ne,
555
- {
556
- value: y + (S ? 1 : 0),
557
- max: w.length,
558
- size: "sm",
559
- className: "mb-3"
560
- }
561
- ),
562
- g && /* @__PURE__ */ e(L, { children: /* @__PURE__ */ t(Q, { className: "pt-6", children: [
563
- /* @__PURE__ */ e(
564
- X,
565
- {
566
- question: g,
567
- sessionAnswers: (x == null ? void 0 : x.map((k) => ({
568
- uid: g.uid,
569
- answerUid: k.uid,
570
- content: k.content
571
- }))) ?? [],
572
- onAnswer: (k) => C(k),
573
- readOnly: l || S,
574
- showCorrectAnswers: S
575
- }
576
- ),
577
- s && S && /* @__PURE__ */ e(
578
- He,
579
- {
580
- isCorrect: A,
581
- explanation: g.explanation,
582
- onRetry: a && !A ? m : void 0
583
- }
584
- ),
585
- /* @__PURE__ */ t("div", { className: "flex justify-end gap-2 mt-2", children: [
586
- !S && s && /* @__PURE__ */ e(
587
- R,
588
- {
589
- onClick: f,
590
- disabled: !x || x.length === 0 || l,
591
- children: "Check Answer"
592
- }
593
- ),
594
- (!s || S) && /* @__PURE__ */ e(
595
- R,
596
- {
597
- onClick: v,
598
- disabled: l,
599
- children: y < w.length - 1 ? "Next Question" : "Finish"
600
- }
601
- )
602
- ] })
603
138
  ] }) })
604
139
  ] });
605
140
  }
606
- function Lt({
607
- questions: r,
608
- initialAnswers: s = [],
609
- onSubmit: a,
610
- onAnswerChange: d,
611
- timeLimitSeconds: p,
612
- timeElapsedSeconds: l,
613
- autoSubmitOnTimeout: h = !0,
614
- timeWarningThreshold: i = 300,
615
- allowBackNavigation: w = !0,
616
- confirmBeforeSubmit: y = !0,
617
- examTitle: c,
618
- instructions: b,
619
- isSubmitting: T = !1,
620
- readOnly: u = !1,
621
- className: U,
622
- style: N
623
- }) {
624
- const [z, x] = I(0), [C, n] = I(s), [o, g] = I(/* @__PURE__ */ new Set()), [S, f] = I(!1), [m, v] = I(!1), A = ge(!1), k = r[z], D = p - l;
625
- ie(() => {
626
- D <= i && D > 0 && v(!0);
627
- }, [D, i]), ie(() => {
628
- h && D <= 0 && !A.current && (A.current = !0, re(!0));
629
- }, [D, h]);
630
- const P = j(
631
- () => r.map((M, E) => ({
632
- uid: M.uid,
633
- sequence: E + 1,
634
- isFlagged: o.has(M.uid),
635
- isAnswered: C.some((_) => _.uid === M.uid),
636
- isSkipped: !1
637
- })),
638
- [r, C, o]
639
- );
640
- function $(M) {
641
- if (!k) return;
642
- const E = k.uid, _ = M.map((H) => ({
643
- uid: E,
644
- answerUid: H.uid,
645
- content: H.content
646
- }));
647
- n((H) => {
648
- const de = [...H.filter((Pe) => Pe.uid !== E), ..._];
649
- return d == null || d(de), de;
650
- });
651
- }
652
- function O(M) {
653
- const E = r.findIndex((_) => _.uid === M);
654
- E !== -1 && x(E);
655
- }
656
- function B(M) {
657
- g((E) => {
658
- const _ = new Set(E);
659
- return _.has(M) ? _.delete(M) : _.add(M), _;
660
- });
661
- }
662
- function Re() {
663
- y ? f(!0) : re(!1);
664
- }
665
- function re(M) {
666
- const E = new Set(C.map((H) => H.uid)), _ = {
667
- timeElapsedSeconds: l,
668
- wasAutoSubmitted: M,
669
- answeredCount: r.filter((H) => E.has(H.uid)).length,
670
- totalQuestions: r.length
671
- };
672
- a(C, _);
673
- }
674
- return /* @__PURE__ */ t("div", { className: F(U), style: N, children: [
675
- c && /* @__PURE__ */ e("p", { className: "text-xl font-bold mb-2 text-foreground", children: c }),
676
- m && D > 0 && D <= i && /* @__PURE__ */ e(ve, { variant: "warning", className: "mb-2", children: /* @__PURE__ */ t(we, { children: [
677
- Math.ceil(D / 60),
678
- " minute",
679
- Math.ceil(D / 60) !== 1 ? "s" : "",
680
- " remaining"
681
- ] }) }),
682
- /* @__PURE__ */ e(
683
- be,
684
- {
685
- currentQuestionIndex: z,
686
- totalQuestions: r.length,
687
- hasNext: z < r.length - 1,
688
- hasPrevious: w && z > 0,
689
- onNext: () => x((M) => Math.min(M + 1, r.length - 1)),
690
- onPrevious: () => w && x((M) => Math.max(M - 1, 0)),
691
- onSubmit: Re,
692
- timeElapsedSeconds: l,
693
- timeLimitSeconds: p,
694
- questions: P,
695
- onNavigateToQuestion: O,
696
- onToggleFlag: B,
697
- currentQuestionUid: k == null ? void 0 : k.uid,
698
- isSubmitting: T,
699
- readOnly: u
700
- }
701
- ),
702
- b && z === 0 && /* @__PURE__ */ e(L, { className: "mt-3", children: /* @__PURE__ */ e(Q, { className: "pt-6", children: b }) }),
703
- k && /* @__PURE__ */ e(L, { className: "mt-3", children: /* @__PURE__ */ e(Q, { className: "pt-6", children: /* @__PURE__ */ e(
704
- X,
705
- {
706
- question: k,
707
- sessionAnswers: C.filter((M) => M.uid === k.uid),
708
- onAnswer: $,
709
- readOnly: u
710
- }
711
- ) }) }),
712
- /* @__PURE__ */ e(
713
- Ve,
714
- {
715
- open: S,
716
- title: "Submit Exam?",
717
- message: `You have answered ${P.filter((M) => M.isAnswered).length} of ${r.length} questions. Once submitted, you cannot change your answers.`,
718
- confirmLabel: "Submit Exam",
719
- cancelLabel: "Continue Exam",
720
- confirmColor: "primary",
721
- onConfirm: () => {
722
- f(!1), re(!1);
723
- },
724
- onCancel: () => f(!1),
725
- isLoading: T
726
- }
727
- )
728
- ] });
729
- }
730
- function Mt({
731
- title: r,
732
- description: s,
733
- questions: a,
734
- initialAnswers: d = [],
735
- onSubmit: p,
736
- onAnswerChange: l,
737
- showProgress: h = !0,
738
- requireAll: i = !1,
739
- submitLabel: w = "Submit Survey",
740
- isSubmitting: y = !1,
741
- readOnly: c = !1,
742
- className: b,
743
- style: T
744
- }) {
745
- const [u, U] = I(d), N = j(() => {
746
- const n = new Set(u.map((o) => o.questionUid));
747
- return a.filter((o) => n.has(o.uid)).length;
748
- }, [a, u]), z = !i || N === a.length;
749
- function x(n, o) {
750
- U((g) => {
751
- const f = [...g.filter((m) => m.questionUid !== n), { questionUid: n, value: o }];
752
- return l == null || l(f), f;
753
- });
754
- }
755
- function C(n) {
756
- return u.find((o) => o.questionUid === n);
757
- }
758
- return /* @__PURE__ */ t("div", { className: b, style: T, children: [
759
- /* @__PURE__ */ e("p", { className: "text-xl font-bold text-foreground mb-2", children: r }),
760
- s && /* @__PURE__ */ e("div", { className: "mb-2 text-muted-foreground text-sm", children: typeof s == "string" ? /* @__PURE__ */ e("span", { children: s }) : s }),
761
- h && /* @__PURE__ */ t("div", { className: "mb-3", children: [
762
- /* @__PURE__ */ e(ne, { value: N / a.length * 100 }),
763
- /* @__PURE__ */ t("span", { className: "block text-xs text-muted-foreground mt-0.5", children: [
764
- N,
765
- " of ",
766
- a.length,
767
- " answered"
768
- ] })
769
- ] }),
770
- a.map((n, o) => {
771
- var S, f;
772
- const g = C(n.uid);
773
- return /* @__PURE__ */ e(L, { className: "mb-2", children: /* @__PURE__ */ t(Q, { className: "pt-6", children: [
774
- /* @__PURE__ */ t("p", { className: "font-medium text-foreground mb-2", children: [
775
- o + 1,
776
- ". ",
777
- n.content,
778
- n.required && /* @__PURE__ */ e("span", { className: "text-destructive ml-0.5", children: "*" })
779
- ] }),
780
- n.type === "likert" && /* @__PURE__ */ e(
781
- Ye,
782
- {
783
- value: g ? Number(g.value) : null,
784
- onChange: (m) => x(n.uid, m),
785
- points: n.scalePoints,
786
- lowLabel: (S = n.scaleLabels) == null ? void 0 : S.low,
787
- highLabel: (f = n.scaleLabels) == null ? void 0 : f.high,
788
- readOnly: c
789
- }
790
- ),
791
- n.type === "rating" && /* @__PURE__ */ e(
792
- Je,
793
- {
794
- value: g ? Number(g.value) : 0,
795
- onChange: (m) => x(n.uid, m),
796
- readOnly: c
797
- }
798
- ),
799
- n.type === "open_text" && /* @__PURE__ */ e(
800
- te,
801
- {
802
- placeholder: "Type your response...",
803
- value: (g == null ? void 0 : g.value) ?? "",
804
- onChange: (m) => x(n.uid, m.target.value),
805
- disabled: c,
806
- className: "min-h-24"
807
- }
808
- ),
809
- n.type === "choice" && n.answers && /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: n.answers.map((m) => /* @__PURE__ */ t("label", { className: "flex items-center gap-2 cursor-pointer py-1 text-sm text-foreground has-[input:disabled]:cursor-default has-[input:disabled]:opacity-60", children: [
810
- /* @__PURE__ */ e(
811
- "input",
812
- {
813
- type: "radio",
814
- className: "accent-primary m-0 shrink-0",
815
- name: `survey-q-${n.uid}`,
816
- value: m.uid,
817
- checked: (g == null ? void 0 : g.value) === m.uid,
818
- onChange: () => x(n.uid, m.uid),
819
- disabled: c
820
- }
821
- ),
822
- /* @__PURE__ */ e("span", { children: m.content })
823
- ] }, m.uid)) }),
824
- n.type === "multiple_choice" && n.answers && /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: n.answers.map((m) => {
825
- const v = u.filter((A) => A.questionUid === n.uid).map((A) => String(A.value));
826
- return /* @__PURE__ */ t("label", { className: "flex items-center gap-2 cursor-pointer py-1 text-sm text-foreground has-[input:disabled]:cursor-default has-[input:disabled]:opacity-60", children: [
827
- /* @__PURE__ */ e(
828
- "input",
829
- {
830
- type: "checkbox",
831
- className: "accent-primary m-0 shrink-0",
832
- checked: v.includes(m.uid),
833
- disabled: c,
834
- onChange: (A) => {
835
- const k = u.filter((P) => P.questionUid === n.uid);
836
- let D;
837
- A.target.checked ? D = [...k, { questionUid: n.uid, value: m.uid }] : D = k.filter((P) => String(P.value) !== m.uid), U((P) => [
838
- ...P.filter(($) => $.questionUid !== n.uid),
839
- ...D
840
- ]), l == null || l([
841
- ...u.filter((P) => P.questionUid !== n.uid),
842
- ...D
843
- ]);
844
- }
845
- }
846
- ),
847
- /* @__PURE__ */ e("span", { children: m.content })
848
- ] }, m.uid);
849
- }) })
850
- ] }) }, n.uid);
851
- }),
852
- /* @__PURE__ */ t("div", { className: "flex justify-between items-center mt-3", children: [
853
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
854
- N,
855
- " of ",
856
- a.length,
857
- " answered"
858
- ] }),
859
- /* @__PURE__ */ e(
860
- R,
861
- {
862
- onClick: () => p(u),
863
- disabled: !z || y || c,
864
- children: y ? "Submitting..." : w
865
- }
866
- )
867
- ] })
868
- ] });
869
- }
870
- function Rt({
871
- title: r,
872
- blocks: s,
873
- isCompleted: a = !1,
874
- onMarkComplete: d,
875
- onNextLesson: p,
876
- nextLessonTitle: l,
877
- estimatedDuration: h,
878
- showDuration: i = !0,
879
- readOnly: w = !1,
880
- className: y,
881
- style: c
882
- }) {
883
- const [b, T] = I(a), [, u] = I(/* @__PURE__ */ new Map());
884
- function U(z, x) {
885
- u((C) => new Map(C).set(z, x));
886
- }
887
- function N() {
888
- T(!0), d == null || d();
889
- }
890
- return /* @__PURE__ */ t("div", { className: F(y), style: c, children: [
891
- /* @__PURE__ */ t("div", { className: "mb-3", children: [
892
- /* @__PURE__ */ e("p", { className: "text-2xl font-bold mb-0.5 text-foreground", children: r }),
893
- i && h != null && /* @__PURE__ */ t("div", { className: "flex items-center gap-0.5 text-muted-foreground", children: [
894
- /* @__PURE__ */ e(De, { size: 16 }),
895
- /* @__PURE__ */ e("span", { className: "text-sm", children: ye(h) })
896
- ] })
897
- ] }),
898
- /* @__PURE__ */ e(V, { className: "mb-3" }),
899
- /* @__PURE__ */ e("div", { className: "flex flex-col gap-3", children: s.map((z, x) => /* @__PURE__ */ e(
900
- Ke,
901
- {
902
- block: z,
903
- onQuestionAnswer: U,
904
- readOnly: w
905
- },
906
- x
907
- )) }),
908
- /* @__PURE__ */ e("div", { className: "border border-border rounded-md px-4 py-3 mt-4 sticky bottom-0 bg-background z-10", children: /* @__PURE__ */ t("div", { className: "flex justify-between items-center", children: [
909
- b ? /* @__PURE__ */ t("div", { className: "flex items-center gap-1 text-success", children: [
910
- /* @__PURE__ */ e(fe, { size: 20 }),
911
- /* @__PURE__ */ e("span", { className: "text-sm font-semibold", children: "Lesson Complete" })
912
- ] }) : /* @__PURE__ */ t(
913
- R,
914
- {
915
- onClick: N,
916
- disabled: w,
917
- children: [
918
- /* @__PURE__ */ e(fe, { size: 18 }),
919
- " Mark Complete"
920
- ]
921
- }
922
- ),
923
- p && /* @__PURE__ */ t(
924
- R,
925
- {
926
- variant: b ? "default" : "outline",
927
- onClick: p,
928
- children: [
929
- l ? `Next: ${l}` : "Next Lesson",
930
- " ",
931
- /* @__PURE__ */ e(nt, { size: 18 })
932
- ]
933
- }
934
- )
935
- ] }) })
936
- ] });
937
- }
938
- function pe(r) {
939
- return r < 1024 ? `${r} B` : r < 1024 * 1024 ? `${(r / 1024).toFixed(1)} KB` : `${(r / (1024 * 1024)).toFixed(1)} MB`;
940
- }
941
- const xe = {
141
+ const H = {
942
142
  pdf: "document",
943
143
  document: "document",
944
144
  video: "video",
@@ -947,236 +147,227 @@ const xe = {
947
147
  archive: "document",
948
148
  other: "document"
949
149
  };
950
- function Pt({
951
- resources: r,
952
- categories: s,
953
- onResourceClick: a,
954
- onDownload: d,
955
- viewMode: p = "list",
956
- allowViewToggle: l = !0,
957
- showSearch: h = !0,
958
- emptyMessage: i = "No resources found",
959
- readOnly: w = !1,
960
- className: y,
961
- style: c
150
+ function pe({
151
+ resources: l,
152
+ categories: h,
153
+ onResourceClick: x,
154
+ onDownload: b,
155
+ viewMode: z = "list",
156
+ allowViewToggle: T = !0,
157
+ showSearch: g = !0,
158
+ emptyMessage: N = "No resources found",
159
+ readOnly: u = !1,
160
+ className: k,
161
+ style: A
962
162
  }) {
963
- const [b, T] = I(""), [u, U] = I(null), [N, z] = I(p), x = j(() => {
964
- let n = r;
965
- if (u && (n = n.filter((o) => o.categoryUid === u)), b.trim()) {
966
- const o = b.toLowerCase();
967
- n = n.filter(
968
- (g) => {
969
- var S;
970
- return g.name.toLowerCase().includes(o) || ((S = g.description) == null ? void 0 : S.toLowerCase().includes(o));
163
+ const [p, w] = S(""), [i, c] = S(null), [d, m] = S(z), P = U(() => {
164
+ let t = l;
165
+ if (i && (t = t.filter((v) => v.categoryUid === i)), p.trim()) {
166
+ const v = p.toLowerCase();
167
+ t = t.filter(
168
+ (y) => {
169
+ var E;
170
+ return y.name.toLowerCase().includes(v) || ((E = y.description) == null ? void 0 : E.toLowerCase().includes(v));
971
171
  }
972
172
  );
973
173
  }
974
- return n;
975
- }, [r, u, b]);
976
- function C(n) {
977
- const o = xe[n.type] ?? "document";
978
- return /* @__PURE__ */ t(
174
+ return t;
175
+ }, [l, i, p]);
176
+ function j(t) {
177
+ const v = H[t.type] ?? "document";
178
+ return /* @__PURE__ */ r(
979
179
  "div",
980
180
  {
981
- className: F(
181
+ className: f(
982
182
  "flex items-center gap-3 px-3 py-2",
983
- !w && "cursor-pointer hover:bg-muted",
984
- w && "opacity-70"
183
+ !u && "cursor-pointer hover:bg-muted",
184
+ u && "opacity-70"
985
185
  ),
986
- onClick: () => !w && a(n),
186
+ onClick: () => !u && x(t),
987
187
  children: [
988
- /* @__PURE__ */ e("div", { className: "min-w-10", children: /* @__PURE__ */ e(ue, { type: o, size: 20 }) }),
989
- /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
990
- /* @__PURE__ */ e("span", { className: "text-sm text-foreground", children: n.name }),
991
- (n.description || n.fileSize != null) && /* @__PURE__ */ e("span", { className: "text-sm text-muted-foreground", children: [
992
- n.description,
993
- n.fileSize != null && pe(n.fileSize)
188
+ /* @__PURE__ */ e("div", { className: "min-w-10", children: /* @__PURE__ */ e(G, { type: v, size: 20 }) }),
189
+ /* @__PURE__ */ r("div", { className: "flex-1 min-w-0", children: [
190
+ /* @__PURE__ */ e("span", { className: "text-sm text-foreground", children: t.name }),
191
+ (t.description || t.fileSize != null) && /* @__PURE__ */ e("span", { className: "block text-xs text-muted-foreground", children: [
192
+ t.description,
193
+ t.fileSize != null && _(t.fileSize)
994
194
  ].filter(Boolean).join(" · ") })
995
195
  ] }),
996
- d && /* @__PURE__ */ t(J, { children: [
997
- /* @__PURE__ */ e(K, { children: /* @__PURE__ */ e(
998
- R,
196
+ b && /* @__PURE__ */ r(B, { children: [
197
+ /* @__PURE__ */ e(D, { children: /* @__PURE__ */ e(
198
+ L,
999
199
  {
1000
200
  variant: "ghost",
1001
201
  size: "icon-xs",
1002
202
  "aria-label": "Download",
1003
- onClick: (g) => {
1004
- g.stopPropagation(), d(n);
203
+ onClick: (y) => {
204
+ y.stopPropagation(), b(t);
1005
205
  },
1006
- children: /* @__PURE__ */ e(Te, { size: 16 })
206
+ children: /* @__PURE__ */ e(ae, { size: 16 })
1007
207
  }
1008
208
  ) }),
1009
- /* @__PURE__ */ e(Z, { children: "Download" })
209
+ /* @__PURE__ */ e(F, { children: "Download" })
1010
210
  ] })
1011
211
  ]
1012
212
  },
1013
- n.uid
213
+ t.uid
1014
214
  );
1015
215
  }
1016
- return /* @__PURE__ */ t("div", { className: y, style: c, children: [
1017
- /* @__PURE__ */ t("div", { className: "flex gap-2 items-center mb-2", children: [
1018
- h && /* @__PURE__ */ e("div", { className: "flex-1 max-w-80", children: /* @__PURE__ */ e(
1019
- Ze,
216
+ return /* @__PURE__ */ r("div", { className: k, style: A, children: [
217
+ /* @__PURE__ */ r("div", { className: "flex gap-2 items-center mb-2", children: [
218
+ g && /* @__PURE__ */ e("div", { className: "flex-1 max-w-80", children: /* @__PURE__ */ e(
219
+ X,
1020
220
  {
1021
- value: b,
1022
- onChange: T,
221
+ value: p,
222
+ onChange: w,
1023
223
  placeholder: "Search resources...",
1024
224
  size: "small"
1025
225
  }
1026
226
  ) }),
1027
- l && /* @__PURE__ */ t("div", { className: "flex gap-0.5", children: [
1028
- /* @__PURE__ */ t(J, { children: [
1029
- /* @__PURE__ */ e(K, { children: /* @__PURE__ */ e(
1030
- R,
227
+ T && /* @__PURE__ */ r("div", { className: "flex gap-0.5", children: [
228
+ /* @__PURE__ */ r(B, { children: [
229
+ /* @__PURE__ */ e(D, { children: /* @__PURE__ */ e(
230
+ L,
1031
231
  {
1032
232
  variant: "ghost",
1033
233
  size: "icon-xs",
1034
234
  "aria-label": "List view",
1035
- className: F(N === "list" && "text-primary"),
1036
- onClick: () => z("list"),
1037
- children: /* @__PURE__ */ e(rt, { size: 18 })
235
+ className: f(d === "list" && "text-primary"),
236
+ onClick: () => m("list"),
237
+ children: /* @__PURE__ */ e(ne, { size: 18 })
1038
238
  }
1039
239
  ) }),
1040
- /* @__PURE__ */ e(Z, { children: "List view" })
240
+ /* @__PURE__ */ e(F, { children: "List view" })
1041
241
  ] }),
1042
- /* @__PURE__ */ t(J, { children: [
1043
- /* @__PURE__ */ e(K, { children: /* @__PURE__ */ e(
1044
- R,
242
+ /* @__PURE__ */ r(B, { children: [
243
+ /* @__PURE__ */ e(D, { children: /* @__PURE__ */ e(
244
+ L,
1045
245
  {
1046
246
  variant: "ghost",
1047
247
  size: "icon-xs",
1048
248
  "aria-label": "Grid view",
1049
- className: F(N === "grid" && "text-primary"),
1050
- onClick: () => z("grid"),
1051
- children: /* @__PURE__ */ e(st, { size: 18 })
249
+ className: f(d === "grid" && "text-primary"),
250
+ onClick: () => m("grid"),
251
+ children: /* @__PURE__ */ e(re, { size: 18 })
1052
252
  }
1053
253
  ) }),
1054
- /* @__PURE__ */ e(Z, { children: "Grid view" })
254
+ /* @__PURE__ */ e(F, { children: "Grid view" })
1055
255
  ] })
1056
256
  ] })
1057
257
  ] }),
1058
- s && s.length > 0 && /* @__PURE__ */ e(
1059
- Se,
258
+ h && h.length > 0 && /* @__PURE__ */ e(
259
+ q,
1060
260
  {
1061
- value: u ?? "all",
1062
- onValueChange: (n) => U(n === "all" ? null : n),
261
+ value: i ?? "all",
262
+ onValueChange: (t) => c(t === "all" ? null : t),
1063
263
  className: "mb-2",
1064
- children: /* @__PURE__ */ t(ke, { children: [
1065
- /* @__PURE__ */ e(G, { value: "all", children: "All" }),
1066
- s.map((n) => /* @__PURE__ */ e(G, { value: n.uid, children: n.label }, n.uid))
264
+ children: /* @__PURE__ */ r(ee, { children: [
265
+ /* @__PURE__ */ e(M, { value: "all", children: "All" }),
266
+ h.map((t) => /* @__PURE__ */ e(M, { value: t.uid, children: t.label }, t.uid))
1067
267
  ] })
1068
268
  }
1069
269
  ),
1070
- x.length === 0 ? /* @__PURE__ */ e(ze, { title: i, description: "Try adjusting your search or filter." }) : N === "list" ? /* @__PURE__ */ e(L, { children: x.map(C) }) : /* @__PURE__ */ e("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(240px,1fr))] gap-2", children: x.map((n) => /* @__PURE__ */ e(
1071
- L,
270
+ P.length === 0 ? /* @__PURE__ */ e(K, { title: N, description: "Try adjusting your search or filter." }) : d === "list" ? /* @__PURE__ */ e(Q, { children: P.map(j) }) : /* @__PURE__ */ e("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(240px,1fr))] gap-2", children: P.map((t) => /* @__PURE__ */ e(
271
+ Q,
1072
272
  {
1073
- className: F(
273
+ className: f(
1074
274
  "transition-colors",
1075
- !w && "cursor-pointer hover:border-primary"
275
+ !u && "cursor-pointer hover:border-primary"
1076
276
  ),
1077
- onClick: () => !w && a(n),
1078
- children: /* @__PURE__ */ t(Q, { className: "pt-4 pb-4", children: [
1079
- /* @__PURE__ */ t("div", { className: "flex gap-1 items-center mb-1", children: [
1080
- /* @__PURE__ */ e(ue, { type: xe[n.type] ?? "document", size: 20 }),
1081
- /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-foreground truncate", children: n.name })
277
+ onClick: () => !u && x(t),
278
+ children: /* @__PURE__ */ r(I, { className: "pt-4 pb-4", children: [
279
+ /* @__PURE__ */ r("div", { className: "flex gap-1 items-center mb-1", children: [
280
+ /* @__PURE__ */ e(G, { type: H[t.type] ?? "document", size: 20 }),
281
+ /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-foreground truncate", children: t.name })
1082
282
  ] }),
1083
- n.description && /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground mb-1 truncate", children: n.description }),
1084
- n.fileSize != null && /* @__PURE__ */ e("span", { className: "text-xs text-muted-foreground", children: pe(n.fileSize) })
283
+ t.description && /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground mb-1 truncate", children: t.description }),
284
+ t.fileSize != null && /* @__PURE__ */ e("span", { className: "text-xs text-muted-foreground", children: _(t.fileSize) })
1085
285
  ] })
1086
286
  },
1087
- n.uid
287
+ t.uid
1088
288
  )) })
1089
289
  ] });
1090
290
  }
1091
- function bt(r) {
1092
- const s = new Date(r), d = (/* @__PURE__ */ new Date()).getTime() - s.getTime(), p = Math.floor(d / 6e4);
1093
- if (p < 1) return "Just now";
1094
- if (p < 60) return `${p}m ago`;
1095
- const l = Math.floor(p / 60);
1096
- if (l < 24) return `${l}h ago`;
1097
- const h = Math.floor(l / 24);
1098
- return h < 7 ? `${h}d ago` : s.toLocaleDateString();
1099
- }
1100
- function Qt({
1101
- announcements: r,
1102
- onMarkRead: s,
1103
- onSelect: a,
1104
- showAvatars: d = !0,
1105
- previewLines: p = 3,
1106
- emptyMessage: l = "No announcements yet",
1107
- readOnly: h = !1,
1108
- className: i,
1109
- style: w
291
+ function fe({
292
+ announcements: l,
293
+ onMarkRead: h,
294
+ onSelect: x,
295
+ showAvatars: b = !0,
296
+ previewLines: z = 3,
297
+ emptyMessage: T = "No announcements yet",
298
+ readOnly: g = !1,
299
+ className: N,
300
+ style: u
1110
301
  }) {
1111
- const [y, c] = I(/* @__PURE__ */ new Set()), b = j(() => {
1112
- const u = r.filter((N) => N.isPinned), U = r.filter((N) => !N.isPinned);
1113
- return [...u, ...U];
1114
- }, [r]);
1115
- function T(u) {
1116
- c((N) => {
1117
- const z = new Set(N);
1118
- return z.has(u) ? z.delete(u) : z.add(u), z;
302
+ const [k, A] = S(/* @__PURE__ */ new Set()), p = U(() => {
303
+ const i = l.filter((d) => d.isPinned), c = l.filter((d) => !d.isPinned);
304
+ return [...i, ...c];
305
+ }, [l]);
306
+ function w(i) {
307
+ A((d) => {
308
+ const m = new Set(d);
309
+ return m.has(i) ? m.delete(i) : m.add(i), m;
1119
310
  });
1120
- const U = r.find((N) => N.uid === u);
1121
- U && !U.isRead && (s == null || s(u));
311
+ const c = l.find((d) => d.uid === i);
312
+ c && !c.isRead && (h == null || h(i));
1122
313
  }
1123
- return b.length === 0 ? /* @__PURE__ */ e("div", { className: i, style: w, children: /* @__PURE__ */ e(ze, { title: l }) }) : /* @__PURE__ */ e("div", { className: F("flex flex-col gap-2", i), style: w, children: b.map((u) => {
1124
- const U = y.has(u.uid);
314
+ return p.length === 0 ? /* @__PURE__ */ e("div", { className: N, style: u, children: /* @__PURE__ */ e(K, { title: T }) }) : /* @__PURE__ */ e("div", { className: f("flex flex-col gap-2", N), style: u, children: p.map((i) => {
315
+ const c = k.has(i.uid);
1125
316
  return /* @__PURE__ */ e(
1126
- L,
317
+ Q,
1127
318
  {
1128
- className: F(
1129
- u.isRead && "opacity-85",
1130
- a && "cursor-pointer",
1131
- u.isPinned && "border-l-4 border-l-warning"
319
+ className: f(
320
+ i.isRead && "opacity-85",
321
+ x && "cursor-pointer",
322
+ i.isPinned && "border-l-4 border-l-warning"
1132
323
  ),
1133
- onClick: () => a && !h ? a(u) : T(u.uid),
1134
- children: /* @__PURE__ */ e(Q, { className: "pt-4 pb-4", children: /* @__PURE__ */ t("div", { className: "flex gap-1.5 items-start", children: [
1135
- d && /* @__PURE__ */ e(
1136
- Ge,
324
+ onClick: () => x && !g ? x(i) : w(i.uid),
325
+ children: /* @__PURE__ */ e(I, { className: "py-4", children: /* @__PURE__ */ r("div", { className: "flex gap-1.5 items-start", children: [
326
+ b && /* @__PURE__ */ e(
327
+ te,
1137
328
  {
1138
- displayName: u.author.displayName,
1139
- avatarUrl: u.author.avatarUrl,
1140
- role: u.author.role,
329
+ displayName: i.author.displayName,
330
+ avatarUrl: i.author.avatarUrl,
331
+ role: i.author.role,
1141
332
  size: "medium"
1142
333
  }
1143
334
  ),
1144
- /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: [
1145
- /* @__PURE__ */ t("div", { className: "flex items-center gap-1 mb-0.5", children: [
1146
- u.isPinned && /* @__PURE__ */ e(lt, { size: 14 }),
335
+ /* @__PURE__ */ r("div", { className: "flex-1 min-w-0", children: [
336
+ /* @__PURE__ */ r("div", { className: "flex items-center gap-1 mb-0.5", children: [
337
+ i.isPinned && /* @__PURE__ */ e(le, { size: 14 }),
1147
338
  /* @__PURE__ */ e(
1148
339
  "span",
1149
340
  {
1150
- className: F("text-foreground", u.isRead ? "font-normal" : "font-semibold"),
1151
- children: u.title
341
+ className: f("text-foreground", i.isRead ? "font-normal" : "font-semibold"),
342
+ children: i.title
1152
343
  }
1153
344
  ),
1154
- !u.isRead && /* @__PURE__ */ e(Ne, { variant: "destructive", className: "text-[10px] px-1.5 py-0", children: "New" })
345
+ !i.isRead && /* @__PURE__ */ e(ie, { variant: "destructive", className: "text-[10px] px-1.5 py-0", children: "New" })
1155
346
  ] }),
1156
- /* @__PURE__ */ t("span", { className: "block text-xs text-muted-foreground mb-1", children: [
1157
- u.author.displayName,
347
+ /* @__PURE__ */ r("span", { className: "block text-xs text-muted-foreground mb-1", children: [
348
+ i.author.displayName,
1158
349
  " · ",
1159
- bt(u.createdAt)
350
+ se(i.createdAt)
1160
351
  ] }),
1161
352
  /* @__PURE__ */ e(
1162
353
  "span",
1163
354
  {
1164
- className: F(
355
+ className: f(
1165
356
  "text-sm text-foreground",
1166
- !U && "line-clamp-(--preview-lines) overflow-hidden"
357
+ !c && "line-clamp-(--preview-lines) overflow-hidden"
1167
358
  ),
1168
- style: U ? void 0 : { "--preview-lines": p },
1169
- children: u.content
359
+ style: c ? void 0 : { "--preview-lines": z },
360
+ children: i.content
1170
361
  }
1171
362
  ),
1172
- !U && u.content.length > 200 && /* @__PURE__ */ e(
1173
- R,
363
+ !c && i.content.length > 200 && /* @__PURE__ */ e(
364
+ L,
1174
365
  {
1175
366
  variant: "link",
1176
367
  size: "xs",
1177
368
  className: "px-0 mt-0.5 h-auto",
1178
- onClick: (N) => {
1179
- N.stopPropagation(), T(u.uid);
369
+ onClick: (d) => {
370
+ d.stopPropagation(), w(i.uid);
1180
371
  },
1181
372
  children: "Read more"
1182
373
  }
@@ -1184,685 +375,29 @@ function Qt({
1184
375
  ] })
1185
376
  ] }) })
1186
377
  },
1187
- u.uid
378
+ i.uid
1188
379
  );
1189
380
  }) });
1190
381
  }
1191
- function Bt({
1192
- title: r,
1193
- rootPost: s,
1194
- replies: a,
1195
- currentUser: d,
1196
- onReply: p,
1197
- onToggleLike: l,
1198
- onMarkAnswer: h,
1199
- maxDepth: i = 3,
1200
- allowReplies: w = !0,
1201
- sortOrder: y = "oldest",
1202
- readOnly: c = !1,
1203
- className: b,
1204
- style: T
1205
- }) {
1206
- const [u, U] = I(null), [N, z] = I(""), x = j(() => {
1207
- const o = /* @__PURE__ */ new Map();
1208
- for (const g of a) {
1209
- const S = g.parentUid ?? s.uid, f = o.get(S) ?? [];
1210
- f.push(g), o.set(S, f);
1211
- }
1212
- for (const [, g] of o)
1213
- g.sort((S, f) => y === "newest" ? new Date(f.createdAt).getTime() - new Date(S.createdAt).getTime() : y === "most_liked" ? f.likeCount - S.likeCount : new Date(S.createdAt).getTime() - new Date(f.createdAt).getTime());
1214
- return o;
1215
- }, [a, s.uid, y]);
1216
- function C(o) {
1217
- N.trim() && (p(o, N.trim()), z(""), U(null));
1218
- }
1219
- function n(o, g) {
1220
- const S = x.get(o.uid) ?? [], f = Math.min(g, i), m = /* @__PURE__ */ t("div", { className: "flex items-center gap-1", children: [
1221
- l && !c && /* @__PURE__ */ t(J, { children: [
1222
- /* @__PURE__ */ e(K, { children: /* @__PURE__ */ t(
1223
- R,
1224
- {
1225
- variant: "ghost",
1226
- size: "sm",
1227
- "aria-label": o.isLikedByCurrentUser ? "Unlike" : "Like",
1228
- className: F(o.isLikedByCurrentUser && "text-destructive"),
1229
- onClick: () => l(o.uid),
1230
- children: [
1231
- /* @__PURE__ */ e(it, { size: 14, fill: o.isLikedByCurrentUser ? "currentColor" : "none" }),
1232
- o.likeCount > 0 ? o.likeCount : "Like"
1233
- ]
1234
- }
1235
- ) }),
1236
- /* @__PURE__ */ e(Z, { children: o.isLikedByCurrentUser ? "Unlike" : "Like" })
1237
- ] }),
1238
- w && !c && /* @__PURE__ */ t(J, { children: [
1239
- /* @__PURE__ */ e(K, { children: /* @__PURE__ */ t(
1240
- R,
1241
- {
1242
- variant: "ghost",
1243
- size: "sm",
1244
- "aria-label": "Reply",
1245
- onClick: () => U(o.uid),
1246
- children: [
1247
- /* @__PURE__ */ e(ct, { size: 14 }),
1248
- "Reply"
1249
- ]
1250
- }
1251
- ) }),
1252
- /* @__PURE__ */ e(Z, { children: "Reply" })
1253
- ] }),
1254
- h && !c && d.role !== "student" && !o.isAnswer && /* @__PURE__ */ t(J, { children: [
1255
- /* @__PURE__ */ e(K, { children: /* @__PURE__ */ t(
1256
- R,
1257
- {
1258
- variant: "ghost",
1259
- size: "sm",
1260
- "aria-label": "Mark as answer",
1261
- className: "text-success",
1262
- onClick: () => h(o.uid),
1263
- children: [
1264
- /* @__PURE__ */ e(W, { size: 14 }),
1265
- "Mark Answer"
1266
- ]
1267
- }
1268
- ) }),
1269
- /* @__PURE__ */ e(Z, { children: "Mark as answer" })
1270
- ] })
1271
- ] });
1272
- return /* @__PURE__ */ t("div", { children: [
1273
- /* @__PURE__ */ e(
1274
- Xe,
1275
- {
1276
- author: o.author,
1277
- content: o.content,
1278
- createdAt: o.createdAt,
1279
- updatedAt: o.updatedAt,
1280
- actions: m,
1281
- highlight: o.isAnswer ? "answer" : "none",
1282
- indentLevel: f,
1283
- className: "mb-2"
1284
- }
1285
- ),
1286
- u === o.uid && /* @__PURE__ */ e(
1287
- L,
1288
- {
1289
- className: "mb-2",
1290
- style: { marginLeft: `${(f + 1) * 16}px` },
1291
- children: /* @__PURE__ */ t(Q, { className: "pt-4 pb-4", children: [
1292
- /* @__PURE__ */ e(
1293
- te,
1294
- {
1295
- className: "min-h-15 mb-2",
1296
- placeholder: "Write a reply...",
1297
- value: N,
1298
- onChange: (v) => z(v.target.value)
1299
- }
1300
- ),
1301
- /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
1302
- /* @__PURE__ */ e(
1303
- R,
1304
- {
1305
- size: "sm",
1306
- onClick: () => C(o.uid),
1307
- disabled: !N.trim(),
1308
- children: "Post Reply"
1309
- }
1310
- ),
1311
- /* @__PURE__ */ e(
1312
- R,
1313
- {
1314
- variant: "ghost",
1315
- size: "sm",
1316
- onClick: () => {
1317
- U(null), z("");
1318
- },
1319
- children: "Cancel"
1320
- }
1321
- )
1322
- ] })
1323
- ] })
1324
- }
1325
- ),
1326
- S.map((v) => n(v, g + 1))
1327
- ] }, o.uid);
1328
- }
1329
- return /* @__PURE__ */ t("div", { className: b, style: T, children: [
1330
- /* @__PURE__ */ t("div", { className: "flex items-center gap-1 mb-2", children: [
1331
- /* @__PURE__ */ e(at, { size: 20, className: "text-foreground shrink-0" }),
1332
- /* @__PURE__ */ e("span", { className: "text-lg font-semibold text-foreground", children: r }),
1333
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
1334
- a.length,
1335
- " ",
1336
- a.length === 1 ? "reply" : "replies"
1337
- ] })
1338
- ] }),
1339
- /* @__PURE__ */ e(V, { className: "mb-2" }),
1340
- n(s, 0)
1341
- ] });
1342
- }
1343
- function jt({
1344
- title: r,
1345
- instructions: s,
1346
- dueDate: a,
1347
- maxScore: d,
1348
- status: p,
1349
- submissionTypes: l,
1350
- existingSubmission: h,
1351
- fileConstraints: i,
1352
- onSubmit: w,
1353
- onSaveDraft: y,
1354
- grade: c,
1355
- isSubmitting: b = !1,
1356
- readOnly: T = !1,
1357
- className: u,
1358
- style: U
1359
- }) {
1360
- const [N, z] = I((h == null ? void 0 : h.textContent) ?? ""), [x, C] = I((h == null ? void 0 : h.files) ?? []), [n, o] = I((h == null ? void 0 : h.url) ?? ""), [g, S] = I(l[0]), f = !T && !["submitted", "graded"].includes(p);
1361
- function m() {
1362
- return {
1363
- textContent: l.includes("text") ? N : void 0,
1364
- files: l.includes("file") ? x : void 0,
1365
- url: l.includes("url") ? n : void 0
1366
- };
1367
- }
1368
- return /* @__PURE__ */ t("div", { className: u, style: U, children: [
1369
- /* @__PURE__ */ e("div", { className: "flex justify-between items-start mb-2", children: /* @__PURE__ */ t("div", { children: [
1370
- /* @__PURE__ */ e("div", { className: "text-xl font-bold text-foreground mb-0.5", children: r }),
1371
- /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: [
1372
- /* @__PURE__ */ e(Ce, { status: p }),
1373
- a && /* @__PURE__ */ e(Ue, { dueDate: a, size: "small" }),
1374
- d != null && /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
1375
- d,
1376
- " points"
1377
- ] })
1378
- ] })
1379
- ] }) }),
1380
- /* @__PURE__ */ e(L, { className: "mb-3", children: /* @__PURE__ */ t(Q, { className: "pt-6", children: [
1381
- /* @__PURE__ */ e("div", { className: "font-semibold text-sm text-foreground mb-1", children: "Instructions" }),
1382
- /* @__PURE__ */ e("div", { className: "text-muted-foreground text-sm", children: typeof s == "string" ? /* @__PURE__ */ e("span", { children: s }) : s })
1383
- ] }) }),
1384
- c && /* @__PURE__ */ e(ve, { variant: "success", className: "mb-3", children: /* @__PURE__ */ t(we, { children: [
1385
- /* @__PURE__ */ t("div", { className: "font-semibold text-sm mb-1", children: [
1386
- "Grade: ",
1387
- c.score,
1388
- d != null ? ` / ${d}` : ""
1389
- ] }),
1390
- c.feedback && /* @__PURE__ */ e("div", { children: c.feedback })
1391
- ] }) }),
1392
- f && /* @__PURE__ */ t(ee, { children: [
1393
- l.length > 1 ? /* @__PURE__ */ t(Se, { value: g, onValueChange: (v) => S(v), children: [
1394
- /* @__PURE__ */ t(ke, { children: [
1395
- l.includes("text") && /* @__PURE__ */ e(G, { value: "text", children: "Text" }),
1396
- l.includes("file") && /* @__PURE__ */ e(G, { value: "file", children: "File Upload" }),
1397
- l.includes("url") && /* @__PURE__ */ e(G, { value: "url", children: "URL" })
1398
- ] }),
1399
- l.includes("text") && /* @__PURE__ */ e(se, { value: "text", children: /* @__PURE__ */ e(
1400
- te,
1401
- {
1402
- className: "min-h-45",
1403
- placeholder: "Type your submission...",
1404
- value: N,
1405
- onChange: (v) => z(v.target.value)
1406
- }
1407
- ) }),
1408
- l.includes("file") && /* @__PURE__ */ e(se, { value: "file", children: /* @__PURE__ */ e(
1409
- me,
1410
- {
1411
- files: x,
1412
- onFilesAdded: (v) => C((A) => [...A, ...v]),
1413
- onFileRemove: (v) => C((A) => A.filter((k, D) => D !== v)),
1414
- accept: i == null ? void 0 : i.acceptedTypes,
1415
- maxFiles: i == null ? void 0 : i.maxFiles,
1416
- maxSizeMB: i == null ? void 0 : i.maxSizeMB
1417
- }
1418
- ) }),
1419
- l.includes("url") && /* @__PURE__ */ e(se, { value: "url", children: /* @__PURE__ */ e(
1420
- he,
1421
- {
1422
- placeholder: "https://...",
1423
- value: n,
1424
- onChange: (v) => o(v.target.value)
1425
- }
1426
- ) })
1427
- ] }) : /* @__PURE__ */ t(ee, { children: [
1428
- l.includes("text") && /* @__PURE__ */ e(
1429
- te,
1430
- {
1431
- className: "min-h-45 mb-2",
1432
- placeholder: "Type your submission...",
1433
- value: N,
1434
- onChange: (v) => z(v.target.value)
1435
- }
1436
- ),
1437
- l.includes("file") && /* @__PURE__ */ e("div", { className: "mb-2", children: /* @__PURE__ */ e(
1438
- me,
1439
- {
1440
- files: x,
1441
- onFilesAdded: (v) => C((A) => [...A, ...v]),
1442
- onFileRemove: (v) => C((A) => A.filter((k, D) => D !== v)),
1443
- accept: i == null ? void 0 : i.acceptedTypes,
1444
- maxFiles: i == null ? void 0 : i.maxFiles,
1445
- maxSizeMB: i == null ? void 0 : i.maxSizeMB
1446
- }
1447
- ) }),
1448
- l.includes("url") && /* @__PURE__ */ e(
1449
- he,
1450
- {
1451
- className: "mb-2",
1452
- placeholder: "https://...",
1453
- value: n,
1454
- onChange: (v) => o(v.target.value)
1455
- }
1456
- )
1457
- ] }),
1458
- /* @__PURE__ */ e(V, { className: "my-2" }),
1459
- /* @__PURE__ */ t("div", { className: "flex gap-2 justify-end", children: [
1460
- y && /* @__PURE__ */ t(
1461
- R,
1462
- {
1463
- variant: "outline",
1464
- onClick: () => y(m()),
1465
- disabled: b,
1466
- children: [
1467
- /* @__PURE__ */ e(dt, { size: 16 }),
1468
- "Save Draft"
1469
- ]
1470
- }
1471
- ),
1472
- /* @__PURE__ */ t(
1473
- R,
1474
- {
1475
- onClick: () => w(m()),
1476
- disabled: b,
1477
- children: [
1478
- /* @__PURE__ */ e(Ie, { size: 16 }),
1479
- b ? "Submitting..." : "Submit"
1480
- ]
1481
- }
1482
- )
1483
- ] })
1484
- ] })
1485
- ] });
1486
- }
1487
- function q({
1488
- label: r,
1489
- field: s,
1490
- sortField: a,
1491
- sortDir: d,
1492
- onSort: p,
1493
- textAlign: l
1494
- }) {
1495
- const h = a === s;
1496
- return /* @__PURE__ */ e(
1497
- Ae,
1498
- {
1499
- className: F(
1500
- "cursor-pointer select-none hover:bg-muted",
1501
- l === "right" && "text-right"
1502
- ),
1503
- onClick: () => p(s),
1504
- children: /* @__PURE__ */ t("div", { className: F("flex items-center gap-1", l === "right" && "justify-end"), children: [
1505
- /* @__PURE__ */ e("span", { className: F(h ? "text-foreground" : "text-muted-foreground"), children: r }),
1506
- h && (d === "asc" ? /* @__PURE__ */ e(ot, { size: 14 }) : /* @__PURE__ */ e(ut, { size: 14 }))
1507
- ] })
1508
- }
1509
- );
1510
- }
1511
- function $t({
1512
- items: r,
1513
- categories: s,
1514
- overallGrade: a,
1515
- showWeights: d = !0,
1516
- showCategoryTotals: p = !0,
1517
- onItemClick: l,
1518
- readOnly: h = !1,
1519
- className: i,
1520
- style: w
1521
- }) {
1522
- const [y, c] = I("dueDate"), [b, T] = I("asc");
1523
- function u(x) {
1524
- y === x ? T((C) => C === "asc" ? "desc" : "asc") : (c(x), T("asc"));
1525
- }
1526
- const U = j(() => {
1527
- const x = [...r];
1528
- return x.sort((C, n) => {
1529
- let o = 0;
1530
- switch (y) {
1531
- case "name":
1532
- o = C.name.localeCompare(n.name);
1533
- break;
1534
- case "score":
1535
- o = (C.score ?? -1) - (n.score ?? -1);
1536
- break;
1537
- case "dueDate":
1538
- o = (C.dueDate ?? "").localeCompare(n.dueDate ?? "");
1539
- break;
1540
- case "status":
1541
- o = C.status.localeCompare(n.status);
1542
- break;
1543
- }
1544
- return b === "asc" ? o : -o;
1545
- }), x;
1546
- }, [r, y, b]), N = j(() => {
1547
- if (!s || s.length === 0) return [{ category: null, items: U }];
1548
- const x = s.map((n) => ({
1549
- category: n,
1550
- items: U.filter((o) => o.categoryUid === n.uid)
1551
- })), C = U.filter((n) => !n.categoryUid);
1552
- return C.length > 0 && x.push({ category: null, items: C }), x;
1553
- }, [U, s]), z = d ? 5 : 4;
1554
- return /* @__PURE__ */ t("div", { className: i, style: w, children: [
1555
- a && /* @__PURE__ */ e(L, { className: "mb-3", children: /* @__PURE__ */ e(Q, { className: "pt-6", children: /* @__PURE__ */ t("div", { className: "flex items-center gap-3", children: [
1556
- /* @__PURE__ */ e(
1557
- We,
1558
- {
1559
- percentage: a.percentage,
1560
- letterGrade: a.letterGrade,
1561
- size: "large",
1562
- passingThreshold: 60
1563
- }
1564
- ),
1565
- /* @__PURE__ */ t("div", { children: [
1566
- /* @__PURE__ */ e("div", { className: "text-lg font-semibold text-foreground", children: "Overall Grade" }),
1567
- /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: [
1568
- a.pointsEarned,
1569
- " / ",
1570
- a.pointsPossible,
1571
- " points"
1572
- ] })
1573
- ] })
1574
- ] }) }) }),
1575
- /* @__PURE__ */ e(L, { children: /* @__PURE__ */ t(Oe, { children: [
1576
- /* @__PURE__ */ e(qe, { children: /* @__PURE__ */ t(le, { children: [
1577
- /* @__PURE__ */ e(
1578
- q,
1579
- {
1580
- label: "Assignment",
1581
- field: "name",
1582
- sortField: y,
1583
- sortDir: b,
1584
- onSort: u
1585
- }
1586
- ),
1587
- /* @__PURE__ */ e(
1588
- q,
1589
- {
1590
- label: "Status",
1591
- field: "status",
1592
- sortField: y,
1593
- sortDir: b,
1594
- onSort: u
1595
- }
1596
- ),
1597
- /* @__PURE__ */ e(
1598
- q,
1599
- {
1600
- label: "Due Date",
1601
- field: "dueDate",
1602
- sortField: y,
1603
- sortDir: b,
1604
- onSort: u
1605
- }
1606
- ),
1607
- /* @__PURE__ */ e(
1608
- q,
1609
- {
1610
- label: "Score",
1611
- field: "score",
1612
- sortField: y,
1613
- sortDir: b,
1614
- onSort: u,
1615
- textAlign: "right"
1616
- }
1617
- ),
1618
- d && /* @__PURE__ */ e(Ae, { className: "text-right text-muted-foreground", children: "Weight" })
1619
- ] }) }),
1620
- /* @__PURE__ */ e(et, { children: N.map((x, C) => /* @__PURE__ */ t(Be, { children: [
1621
- x.category && p && /* @__PURE__ */ e(le, { className: "bg-muted hover:bg-muted", children: /* @__PURE__ */ e(Y, { colSpan: z, children: /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-foreground", children: [
1622
- x.category.name,
1623
- x.category.weight != null && ` (${x.category.weight}%)`
1624
- ] }) }) }),
1625
- x.items.map((n) => /* @__PURE__ */ t(
1626
- le,
1627
- {
1628
- className: F(l && !h && "cursor-pointer"),
1629
- onClick: () => l && !h ? l(n) : void 0,
1630
- children: [
1631
- /* @__PURE__ */ e(Y, { children: n.name }),
1632
- /* @__PURE__ */ e(Y, { children: /* @__PURE__ */ e(Ce, { status: n.status, size: "small" }) }),
1633
- /* @__PURE__ */ e(Y, { children: n.dueDate ? /* @__PURE__ */ e(
1634
- Ue,
1635
- {
1636
- dueDate: n.dueDate,
1637
- submittedDate: n.submittedDate,
1638
- size: "small"
1639
- }
1640
- ) : "—" }),
1641
- /* @__PURE__ */ e(Y, { className: "text-right", children: n.score != null ? /* @__PURE__ */ t("span", { className: "text-sm font-semibold text-foreground", children: [
1642
- n.score,
1643
- " / ",
1644
- n.maxScore
1645
- ] }) : n.status === "excused" ? /* @__PURE__ */ e("span", { className: "text-sm text-muted-foreground", children: "Excused" }) : /* @__PURE__ */ e("span", { className: "text-sm text-muted-foreground", children: "—" }) }),
1646
- d && /* @__PURE__ */ e(Y, { className: "text-right", children: n.weight != null ? `${n.weight}%` : "—" })
1647
- ]
1648
- },
1649
- n.uid
1650
- ))
1651
- ] }, C)) })
1652
- ] }) })
1653
- ] });
1654
- }
1655
- const Nt = {
1656
- lesson_completed: Fe,
1657
- quiz_passed: W,
1658
- assignment_submitted: Ie,
1659
- badge_earned: Le
1660
- };
1661
- function _t({
1662
- overallProgress: r,
1663
- totalTimeSpent: s,
1664
- modules: a,
1665
- recentActivity: d,
1666
- streak: p,
1667
- achievements: l,
1668
- recentActivityLimit: h = 5,
1669
- onModuleClick: i,
1670
- className: w,
1671
- style: y
1672
- }) {
1673
- return /* @__PURE__ */ t("div", { className: w, style: y, children: [
1674
- /* @__PURE__ */ t("div", { className: "grid grid-cols-[repeat(auto-fit,minmax(160px,1fr))] gap-2 mb-3", children: [
1675
- /* @__PURE__ */ e(L, { className: "p-2 flex justify-center", children: /* @__PURE__ */ e(tt, { value: r, size: 100 }) }),
1676
- /* @__PURE__ */ e(
1677
- ae,
1678
- {
1679
- icon: /* @__PURE__ */ e(De, { size: 24 }),
1680
- label: "Time Spent",
1681
- value: ye(s)
1682
- }
1683
- ),
1684
- p && /* @__PURE__ */ e(
1685
- ae,
1686
- {
1687
- icon: /* @__PURE__ */ e(mt, { size: 24 }),
1688
- label: "Current Streak",
1689
- value: `${p.currentDays} days`,
1690
- subtitle: `Longest: ${p.longestDays} days`
1691
- }
1692
- ),
1693
- /* @__PURE__ */ e(
1694
- ae,
1695
- {
1696
- icon: /* @__PURE__ */ e(Fe, { size: 24 }),
1697
- label: "Modules",
1698
- value: `${a.filter((c) => c.completedItems === c.totalItems).length} / ${a.length}`,
1699
- subtitle: "completed"
1700
- }
1701
- )
1702
- ] }),
1703
- /* @__PURE__ */ e("p", { className: "text-lg font-semibold mb-2 text-foreground", children: "Module Progress" }),
1704
- /* @__PURE__ */ e("div", { className: "flex flex-col gap-2 mb-3", children: a.map((c) => {
1705
- const b = c.totalItems > 0 ? c.completedItems / c.totalItems * 100 : 0;
1706
- return /* @__PURE__ */ t(
1707
- L,
1708
- {
1709
- className: F(
1710
- "p-2 transition-colors",
1711
- i && "cursor-pointer hover:border-primary"
1712
- ),
1713
- onClick: () => i == null ? void 0 : i(c.uid),
1714
- children: [
1715
- /* @__PURE__ */ t("div", { className: "flex justify-between items-center mb-0.5", children: [
1716
- /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-foreground", children: c.name }),
1717
- /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: [
1718
- c.completedItems,
1719
- " / ",
1720
- c.totalItems
1721
- ] })
1722
- ] }),
1723
- /* @__PURE__ */ e(ne, { value: b, size: "sm" })
1724
- ]
1725
- },
1726
- c.uid
1727
- );
1728
- }) }),
1729
- d && d.length > 0 && /* @__PURE__ */ t(ee, { children: [
1730
- /* @__PURE__ */ e("p", { className: "text-lg font-semibold mb-2 text-foreground", children: "Recent Activity" }),
1731
- /* @__PURE__ */ e("div", { className: "flex flex-col gap-1.5 mb-3", children: d.slice(0, h).map((c) => {
1732
- const b = Nt[c.type] ?? W;
1733
- return /* @__PURE__ */ t("div", { className: "flex gap-1.5 items-center", children: [
1734
- /* @__PURE__ */ e(b, { size: 16 }),
1735
- /* @__PURE__ */ e("span", { className: "flex-1 text-sm text-foreground", children: c.description }),
1736
- /* @__PURE__ */ e("span", { className: "text-xs text-muted-foreground", children: new Date(c.timestamp).toLocaleDateString() })
1737
- ] }, c.uid);
1738
- }) })
1739
- ] }),
1740
- l && l.length > 0 && /* @__PURE__ */ t(ee, { children: [
1741
- /* @__PURE__ */ e("p", { className: "text-lg font-semibold mb-2 text-foreground", children: "Achievements" }),
1742
- /* @__PURE__ */ e("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-2", children: l.map((c) => /* @__PURE__ */ t(L, { className: "p-2 text-center", children: [
1743
- c.iconUrl ? /* @__PURE__ */ e(
1744
- "img",
1745
- {
1746
- src: c.iconUrl,
1747
- alt: c.name,
1748
- className: "w-12 h-12 mb-1 mx-auto"
1749
- }
1750
- ) : /* @__PURE__ */ e(ht, { size: 32, className: "mx-auto mb-2 text-warning" }),
1751
- /* @__PURE__ */ e("p", { className: "font-semibold text-sm text-foreground", children: c.name }),
1752
- /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground", children: c.description })
1753
- ] }, c.uid)) })
1754
- ] })
1755
- ] });
1756
- }
1757
- const vt = {
1758
- classic: "border-[3px] border-double border-warning bg-linear-to-br from-[#fffbe6] to-[#fff8e1]",
1759
- modern: "border border-primary bg-linear-to-br from-[#fff5f5] to-[#fee2e2]",
1760
- minimal: "border border-border"
1761
- };
1762
- function Et({
1763
- recipientName: r,
1764
- courseTitle: s,
1765
- completionDate: a,
1766
- organizationName: d,
1767
- organizationLogo: p,
1768
- signatory: l,
1769
- certificateId: h,
1770
- variant: i = "classic",
1771
- showActions: w = !0,
1772
- onPrint: y,
1773
- onDownload: c,
1774
- className: b,
1775
- style: T
1776
- }) {
1777
- const u = (() => {
1778
- try {
1779
- return new Date(a).toLocaleDateString("en-US", {
1780
- year: "numeric",
1781
- month: "long",
1782
- day: "numeric"
1783
- });
1784
- } catch {
1785
- return a;
1786
- }
1787
- })();
1788
- function U() {
1789
- y ? y() : window.print();
1790
- }
1791
- return /* @__PURE__ */ t("div", { className: b, style: T, children: [
1792
- /* @__PURE__ */ t(
1793
- "div",
1794
- {
1795
- className: F(
1796
- "p-3 sm:p-5 md:p-6 text-center max-w-200 mx-auto rounded-md",
1797
- vt[i]
1798
- ),
1799
- children: [
1800
- p ? /* @__PURE__ */ e(
1801
- "img",
1802
- {
1803
- src: p,
1804
- alt: d,
1805
- className: "h-15 mb-2 mx-auto block"
1806
- }
1807
- ) : /* @__PURE__ */ e(
1808
- Le,
1809
- {
1810
- size: 48,
1811
- className: F("mx-auto mb-4", i === "classic" && "text-warning")
1812
- }
1813
- ),
1814
- /* @__PURE__ */ e("p", { className: "uppercase tracking-[3px] text-sm text-foreground/70", children: "Certificate of Completion" }),
1815
- /* @__PURE__ */ e(V, { className: "my-2 mx-auto max-w-50" }),
1816
- /* @__PURE__ */ e("p", { className: "text-sm text-foreground mb-1", children: "This is to certify that" }),
1817
- /* @__PURE__ */ e("p", { className: F("text-2xl font-bold mb-2 text-foreground", i === "classic" && "font-serif"), children: r }),
1818
- /* @__PURE__ */ e("p", { className: "text-sm text-foreground mb-1", children: "has successfully completed" }),
1819
- /* @__PURE__ */ e("p", { className: "text-xl font-bold mb-2 text-primary", children: s }),
1820
- /* @__PURE__ */ t("p", { className: "text-sm text-foreground mb-3", children: [
1821
- "Issued by ",
1822
- d,
1823
- " on ",
1824
- u
1825
- ] }),
1826
- l && /* @__PURE__ */ t("div", { className: "mt-4 mb-2", children: [
1827
- /* @__PURE__ */ e(V, { className: "my-2 mx-auto max-w-50" }),
1828
- /* @__PURE__ */ e("p", { className: "font-semibold text-sm text-foreground", children: l.name }),
1829
- /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground", children: l.title })
1830
- ] }),
1831
- h && /* @__PURE__ */ t("span", { className: "block text-xs text-muted-foreground mt-2", children: [
1832
- "Certificate ID: ",
1833
- h
1834
- ] })
1835
- ]
1836
- }
1837
- ),
1838
- w && /* @__PURE__ */ t("div", { className: "flex justify-center gap-2 mt-3", children: [
1839
- /* @__PURE__ */ t(R, { variant: "outline", onClick: U, children: [
1840
- /* @__PURE__ */ e(ft, { size: 16 }),
1841
- " Print"
1842
- ] }),
1843
- c && /* @__PURE__ */ t(R, { variant: "outline", onClick: c, children: [
1844
- /* @__PURE__ */ e(Te, { size: 16 }),
1845
- " Download"
1846
- ] })
1847
- ] })
1848
- ] });
1849
- }
1850
382
  export {
1851
- Qt as AnnouncementFeed,
1852
- Dt as AssessmentReview,
1853
- jt as AssignmentSubmission,
1854
- Et as CertificateViewer,
1855
- Tt as CourseOutline,
1856
- Bt as DiscussionThread,
1857
- Lt as ExamSession,
1858
- At as FlashcardStudySession,
1859
- $t as GradebookTable,
1860
- Ut as LecturePlayer,
1861
- Rt as LessonPage,
1862
- Ft as PracticeQuiz,
1863
- _t as ProgressDashboard,
1864
- Ct as QuizSession,
1865
- Pt as ResourceLibrary,
1866
- It as ScrollableQuiz,
1867
- Mt as SurveyForm
383
+ fe as AnnouncementFeed,
384
+ be as AssessmentReview,
385
+ ge as AssignmentSubmission,
386
+ ve as CertificateViewer,
387
+ Ne as CourseOutline,
388
+ we as DiscussionThread,
389
+ ye as ExamSession,
390
+ Ce as FlashcardStudySession,
391
+ Se as ForumBoard,
392
+ ze as GradebookTable,
393
+ Te as LecturePlayer,
394
+ ke as LessonPage,
395
+ Ae as PracticeQuiz,
396
+ Pe as ProgressDashboard,
397
+ Ue as QuizSession,
398
+ Le as RequirementsChecklist,
399
+ pe as ResourceLibrary,
400
+ Qe as RubricView,
401
+ ue as ScrollableQuiz,
402
+ Ee as SurveyForm
1868
403
  };