@tinyweb_dev/oe-exam-sdk 0.1.3 → 0.1.5

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 (371) hide show
  1. package/README.md +112 -13
  2. package/dist/api/contest-rooms.d.ts +13 -0
  3. package/dist/api/contest-rooms.js +1 -0
  4. package/dist/api/contest-rooms.types.d.ts +47 -0
  5. package/dist/api/contest-rooms.types.js +1 -0
  6. package/dist/api/exam-entry.d.ts +14 -0
  7. package/dist/api/exam-entry.js +1 -0
  8. package/dist/api/exam-entry.types.d.ts +93 -0
  9. package/dist/api/exam-entry.types.js +1 -0
  10. package/dist/api/index.d.ts +2 -0
  11. package/dist/api/index.js +1 -1
  12. package/dist/api/result-review.d.ts +2 -1
  13. package/dist/api/result-review.js +1 -1
  14. package/dist/api/result-review.types.d.ts +69 -3
  15. package/dist/api/result-review.types.js +1 -1
  16. package/dist/components/exams/entry/EntryRestartDialog.d.ts +12 -0
  17. package/dist/components/exams/entry/EntryRestartDialog.js +1 -0
  18. package/dist/components/exams/entry/StudentExamEntryPageContainer.d.ts +31 -0
  19. package/dist/components/exams/entry/StudentExamEntryPageContainer.js +1 -0
  20. package/dist/components/exams/entry/exam-entry.states.d.ts +22 -0
  21. package/dist/components/exams/entry/exam-entry.states.js +1 -0
  22. package/dist/components/exams/entry/exam-entry.utils.d.ts +16 -0
  23. package/dist/components/exams/entry/exam-entry.utils.js +1 -0
  24. package/dist/components/exams/entry/fullscreen-loading.d.ts +5 -0
  25. package/dist/components/exams/entry/fullscreen-loading.js +1 -0
  26. package/dist/components/exams/entry/index.d.ts +7 -0
  27. package/dist/components/exams/entry/index.js +1 -0
  28. package/dist/components/exams/index.d.ts +8 -0
  29. package/dist/components/exams/index.js +1 -1
  30. package/dist/components/exams/rooms/StudentContestRoomsPageContainer.d.ts +18 -0
  31. package/dist/components/exams/rooms/StudentContestRoomsPageContainer.js +1 -0
  32. package/dist/components/exams/rooms/contest-rooms.utils.d.ts +32 -0
  33. package/dist/components/exams/rooms/contest-rooms.utils.js +1 -0
  34. package/dist/components/exams/rooms/index.d.ts +3 -0
  35. package/dist/components/exams/rooms/index.js +1 -0
  36. package/dist/components/exams/take/ExamTakingApiContext.d.ts +10 -0
  37. package/dist/components/exams/take/ExamTakingApiContext.js +1 -0
  38. package/dist/components/exams/take/ExamTakingPageContainer.d.ts +28 -4
  39. package/dist/components/exams/take/ExamTakingPageContainer.js +1 -1
  40. package/dist/components/exams/take/components/QuestionRenderer.d.ts +25 -0
  41. package/dist/components/exams/take/components/QuestionRenderer.js +1 -0
  42. package/dist/components/exams/take/components/index.d.ts +10 -0
  43. package/dist/components/exams/take/components/index.js +1 -0
  44. package/dist/components/exams/take/components/question-renderers/ArticlesViewer.d.ts +7 -0
  45. package/dist/components/exams/take/components/question-renderers/ArticlesViewer.js +1 -0
  46. package/dist/components/exams/take/components/question-renderers/MoversAnswerTheQuestionRenderer.d.ts +22 -0
  47. package/dist/components/exams/take/components/question-renderers/MoversAnswerTheQuestionRenderer.js +1 -0
  48. package/dist/components/exams/take/components/question-renderers/MoversChooseAdjectiveRenderer.d.ts +14 -0
  49. package/dist/components/exams/take/components/question-renderers/MoversChooseAdjectiveRenderer.js +1 -0
  50. package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.d.ts +2 -0
  51. package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.js +1 -0
  52. package/dist/components/exams/take/components/question-renderers/MoversColoringRenderer.d.ts +3 -0
  53. package/dist/components/exams/take/components/question-renderers/MoversColoringRenderer.js +1 -0
  54. package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.d.ts +2 -0
  55. package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.js +1 -0
  56. package/dist/components/exams/take/components/question-renderers/MoversGridFillRenderer.d.ts +2 -0
  57. package/dist/components/exams/take/components/question-renderers/MoversGridFillRenderer.js +1 -0
  58. package/dist/components/exams/take/components/question-renderers/MoversLabelThePictureRenderer.d.ts +2 -0
  59. package/dist/components/exams/take/components/question-renderers/MoversLabelThePictureRenderer.js +1 -0
  60. package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.d.ts +21 -0
  61. package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.js +1 -0
  62. package/dist/components/exams/take/components/question-renderers/MoversMatchByWritingAnswerRenderer.d.ts +19 -0
  63. package/dist/components/exams/take/components/question-renderers/MoversMatchByWritingAnswerRenderer.js +1 -0
  64. package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.d.ts +2 -0
  65. package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.js +1 -0
  66. package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.d.ts +2 -0
  67. package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.js +1 -0
  68. package/dist/components/exams/take/components/question-renderers/MoversReadingPassageRenderer.d.ts +2 -0
  69. package/dist/components/exams/take/components/question-renderers/MoversReadingPassageRenderer.js +1 -0
  70. package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.d.ts +20 -0
  71. package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.js +1 -0
  72. package/dist/components/exams/take/components/question-renderers/MoversWordFillParagraphRenderer.d.ts +32 -0
  73. package/dist/components/exams/take/components/question-renderers/MoversWordFillParagraphRenderer.js +1 -0
  74. package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.d.ts +18 -0
  75. package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.js +1 -0
  76. package/dist/components/exams/take/components/question-renderers/MoversWordOrderingRenderer.d.ts +19 -0
  77. package/dist/components/exams/take/components/question-renderers/MoversWordOrderingRenderer.js +1 -0
  78. package/dist/components/exams/take/components/question-renderers/MoversWriteSentencesRenderer.d.ts +22 -0
  79. package/dist/components/exams/take/components/question-renderers/MoversWriteSentencesRenderer.js +1 -0
  80. package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.d.ts +18 -0
  81. package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.js +1 -0
  82. package/dist/components/exams/take/components/question-renderers/index.d.ts +19 -0
  83. package/dist/components/exams/take/components/question-renderers/index.js +1 -0
  84. package/dist/components/exams/take/components/speaking/FindObjectInPicture.module.css +133 -0
  85. package/dist/components/exams/take/components/speaking/SpeakingAudioPlayer.d.ts +9 -0
  86. package/dist/components/exams/take/components/speaking/SpeakingAudioPlayer.js +1 -0
  87. package/dist/components/exams/take/components/speaking/SpeakingCompareImages.module.css +153 -0
  88. package/dist/components/exams/take/components/speaking/SpeakingContentFrame.d.ts +7 -0
  89. package/dist/components/exams/take/components/speaking/SpeakingContentFrame.js +1 -0
  90. package/dist/components/exams/take/components/speaking/SpeakingDragObjects.module.css +238 -0
  91. package/dist/components/exams/take/components/speaking/SpeakingExamLayout.d.ts +27 -0
  92. package/dist/components/exams/take/components/speaking/SpeakingExamLayout.js +1 -0
  93. package/dist/components/exams/take/components/speaking/SpeakingHeader.d.ts +6 -0
  94. package/dist/components/exams/take/components/speaking/SpeakingHeader.js +1 -0
  95. package/dist/components/exams/take/components/speaking/SpeakingInfoExchange.module.css +193 -0
  96. package/dist/components/exams/take/components/speaking/SpeakingInfoExchangeSummerSky.module.css +238 -0
  97. package/dist/components/exams/take/components/speaking/SpeakingInstructionBar.d.ts +5 -0
  98. package/dist/components/exams/take/components/speaking/SpeakingInstructionBar.js +1 -0
  99. package/dist/components/exams/take/components/speaking/SpeakingMicButton.d.ts +14 -0
  100. package/dist/components/exams/take/components/speaking/SpeakingMicButton.js +1 -0
  101. package/dist/components/exams/take/components/speaking/SpeakingNavButton.d.ts +7 -0
  102. package/dist/components/exams/take/components/speaking/SpeakingNavButton.js +1 -0
  103. package/dist/components/exams/take/components/speaking/SpeakingPartBadge.d.ts +6 -0
  104. package/dist/components/exams/take/components/speaking/SpeakingPartBadge.js +1 -0
  105. package/dist/components/exams/take/components/speaking/SpeakingReadDisplayedContent.module.css +115 -0
  106. package/dist/components/exams/take/components/speaking/SpeakingRecordingPreview.d.ts +11 -0
  107. package/dist/components/exams/take/components/speaking/SpeakingRecordingPreview.js +1 -0
  108. package/dist/components/exams/take/components/speaking/SpeakingReportErrorButton.d.ts +1 -0
  109. package/dist/components/exams/take/components/speaking/SpeakingReportErrorButton.js +1 -0
  110. package/dist/components/exams/take/components/speaking/SpeakingStoryImages.module.css +231 -0
  111. package/dist/components/exams/take/components/speaking/SpeakingVideoIntro.d.ts +13 -0
  112. package/dist/components/exams/take/components/speaking/SpeakingVideoIntro.js +1 -0
  113. package/dist/components/exams/take/components/speaking/index.d.ts +1 -0
  114. package/dist/components/exams/take/components/speaking/index.js +1 -0
  115. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseAnswerGroupRenderer.d.ts +16 -0
  116. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseAnswerGroupRenderer.js +1 -0
  117. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseObjectsRenderer.d.ts +16 -0
  118. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseObjectsRenderer.js +1 -0
  119. package/dist/components/exams/take/components/speaking/renderers/SpeakingCompareImagesRenderer.d.ts +17 -0
  120. package/dist/components/exams/take/components/speaking/renderers/SpeakingCompareImagesRenderer.js +1 -0
  121. package/dist/components/exams/take/components/speaking/renderers/SpeakingConversationRenderer.d.ts +16 -0
  122. package/dist/components/exams/take/components/speaking/renderers/SpeakingConversationRenderer.js +1 -0
  123. package/dist/components/exams/take/components/speaking/renderers/SpeakingCueCardRenderer.d.ts +17 -0
  124. package/dist/components/exams/take/components/speaking/renderers/SpeakingCueCardRenderer.js +1 -0
  125. package/dist/components/exams/take/components/speaking/renderers/SpeakingDescribeImageRenderer.d.ts +18 -0
  126. package/dist/components/exams/take/components/speaking/renderers/SpeakingDescribeImageRenderer.js +1 -0
  127. package/dist/components/exams/take/components/speaking/renderers/SpeakingDragObjectsRenderer.d.ts +16 -0
  128. package/dist/components/exams/take/components/speaking/renderers/SpeakingDragObjectsRenderer.js +1 -0
  129. package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.d.ts +16 -0
  130. package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.js +1 -0
  131. package/dist/components/exams/take/components/speaking/renderers/SpeakingInfoExchangeRenderer.d.ts +16 -0
  132. package/dist/components/exams/take/components/speaking/renderers/SpeakingInfoExchangeRenderer.js +1 -0
  133. package/dist/components/exams/take/components/speaking/renderers/SpeakingListenAndSpeakAnswerRenderer.d.ts +16 -0
  134. package/dist/components/exams/take/components/speaking/renderers/SpeakingListenAndSpeakAnswerRenderer.js +1 -0
  135. package/dist/components/exams/take/components/speaking/renderers/SpeakingOddOneOutRenderer.d.ts +16 -0
  136. package/dist/components/exams/take/components/speaking/renderers/SpeakingOddOneOutRenderer.js +1 -0
  137. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionListRenderer.d.ts +26 -0
  138. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionListRenderer.js +1 -0
  139. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.d.ts +32 -0
  140. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.js +1 -0
  141. package/dist/components/exams/take/components/speaking/renderers/SpeakingReadDisplayedContentRenderer.d.ts +17 -0
  142. package/dist/components/exams/take/components/speaking/renderers/SpeakingReadDisplayedContentRenderer.js +1 -0
  143. package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQARenderer.d.ts +17 -0
  144. package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQARenderer.js +1 -0
  145. package/dist/components/exams/take/components/speaking/renderers/SpeakingStoryImagesRenderer.d.ts +17 -0
  146. package/dist/components/exams/take/components/speaking/renderers/SpeakingStoryImagesRenderer.js +1 -0
  147. package/dist/components/exams/take/components/speaking/renderers/index.d.ts +13 -0
  148. package/dist/components/exams/take/components/speaking/renderers/index.js +1 -0
  149. package/dist/components/exams/take/hooks/index.d.ts +2 -0
  150. package/dist/components/exams/take/hooks/index.js +1 -0
  151. package/dist/components/exams/take/hooks/useAnswerAutosave.d.ts +27 -0
  152. package/dist/components/exams/take/hooks/useAnswerAutosave.js +1 -0
  153. package/dist/components/exams/take/hooks/useAttemptSubmit.d.ts +29 -0
  154. package/dist/components/exams/take/hooks/useAttemptSubmit.js +1 -0
  155. package/dist/components/exams/take/hooks/useAutoSave.d.ts +20 -0
  156. package/dist/components/exams/take/hooks/useAutoSave.js +1 -0
  157. package/dist/components/exams/take/hooks/useExamCountdown.d.ts +22 -0
  158. package/dist/components/exams/take/hooks/useExamCountdown.js +1 -0
  159. package/dist/components/exams/take/hooks/useExamTimer.d.ts +21 -0
  160. package/dist/components/exams/take/hooks/useExamTimer.js +1 -0
  161. package/dist/components/exams/take/hooks/useProctoringCamera.d.ts +19 -0
  162. package/dist/components/exams/take/hooks/useProctoringCamera.js +1 -0
  163. package/dist/components/exams/take/hooks/useProctoringSnapshot.d.ts +25 -0
  164. package/dist/components/exams/take/hooks/useProctoringSnapshot.js +1 -0
  165. package/dist/components/exams/take/hooks/useSpeakingConversationAudio.d.ts +19 -0
  166. package/dist/components/exams/take/hooks/useSpeakingConversationAudio.js +1 -0
  167. package/dist/components/exams/take/hooks/useSpeakingNavigation.d.ts +37 -0
  168. package/dist/components/exams/take/hooks/useSpeakingNavigation.js +1 -0
  169. package/dist/components/exams/take/hooks/useSpeakingRecorder.d.ts +45 -5
  170. package/dist/components/exams/take/hooks/useSpeakingRecorder.js +1 -1
  171. package/dist/components/exams/take/hooks/useSpeakingRendererSetup.d.ts +39 -0
  172. package/dist/components/exams/take/hooks/useSpeakingRendererSetup.js +1 -0
  173. package/dist/components/exams/take/hooks/useToeicAudio.d.ts +17 -0
  174. package/dist/components/exams/take/hooks/useToeicAudio.js +1 -0
  175. package/dist/components/exams/take/index.d.ts +9 -1
  176. package/dist/components/exams/take/index.js +1 -1
  177. package/dist/components/exams/take/types/speaking-cue-card.types.d.ts +10 -0
  178. package/dist/components/exams/take/types/speaking-cue-card.types.js +1 -0
  179. package/dist/components/exams/take/types/speaking.types.d.ts +153 -0
  180. package/dist/components/exams/take/types/speaking.types.js +1 -0
  181. package/dist/components/exams/take/types.d.ts +286 -1
  182. package/dist/components/exams/take/utils/answer-transformers.d.ts +26 -0
  183. package/dist/components/exams/take/utils/answer-transformers.js +1 -0
  184. package/dist/components/exams/take/utils/coloring-assignments.d.ts +5 -0
  185. package/dist/components/exams/take/utils/coloring-assignments.js +1 -0
  186. package/dist/components/exams/take/utils/question-transformers.d.ts +362 -0
  187. package/dist/components/exams/take/utils/question-transformers.js +1 -0
  188. package/dist/components/features/exam-entry/entry-state-cards.d.ts +19 -0
  189. package/dist/components/features/exam-entry/entry-state-cards.js +1 -0
  190. package/dist/components/features/exam-entry/index.d.ts +2 -0
  191. package/dist/components/features/exam-entry/index.js +1 -0
  192. package/dist/components/features/exam-entry/themed/CambridgeYleWaitingRoom.d.ts +12 -0
  193. package/dist/components/features/exam-entry/themed/CambridgeYleWaitingRoom.js +1 -0
  194. package/dist/components/features/exam-entry/themed/ThemedWaitingRoom.d.ts +14 -0
  195. package/dist/components/features/exam-entry/themed/ThemedWaitingRoom.js +1 -0
  196. package/dist/components/features/exam-entry/themed/ToeicWaitingRoom.d.ts +16 -0
  197. package/dist/components/features/exam-entry/themed/ToeicWaitingRoom.js +1 -0
  198. package/dist/components/features/exam-entry/themed/components/CloseButton.d.ts +9 -0
  199. package/dist/components/features/exam-entry/themed/components/CloseButton.js +1 -0
  200. package/dist/components/features/exam-entry/themed/components/ExamInfoPanel.d.ts +13 -0
  201. package/dist/components/features/exam-entry/themed/components/ExamInfoPanel.js +1 -0
  202. package/dist/components/features/exam-entry/themed/components/ModeSelector.d.ts +7 -0
  203. package/dist/components/features/exam-entry/themed/components/ModeSelector.js +1 -0
  204. package/dist/components/features/exam-entry/themed/components/StartButton.d.ts +11 -0
  205. package/dist/components/features/exam-entry/themed/components/StartButton.js +1 -0
  206. package/dist/components/features/exam-entry/themed/components/index.d.ts +4 -0
  207. package/dist/components/features/exam-entry/themed/components/index.js +1 -0
  208. package/dist/components/features/exam-entry/themed/index.d.ts +1 -0
  209. package/dist/components/features/exam-entry/themed/index.js +1 -0
  210. package/dist/components/results/ResultReviewPageContainer.d.ts +16 -2
  211. package/dist/components/results/ResultReviewPageContainer.js +1 -1
  212. package/dist/components/results/ReviewQuestionRenderer.d.ts +11 -1
  213. package/dist/components/results/ReviewQuestionRenderer.js +1 -1
  214. package/dist/components/results/hooks/useResultReviewPolling.d.ts +37 -0
  215. package/dist/components/results/hooks/useResultReviewPolling.js +1 -0
  216. package/dist/components/results/index.d.ts +36 -1
  217. package/dist/components/results/index.js +1 -1
  218. package/dist/components/results/renderers/QuestionExplanations.d.ts +22 -0
  219. package/dist/components/results/renderers/QuestionExplanations.js +1 -0
  220. package/dist/components/results/renderers/ReviewChooseAdjectiveRenderer.d.ts +13 -0
  221. package/dist/components/results/renderers/ReviewChooseAdjectiveRenderer.js +1 -0
  222. package/dist/components/results/renderers/ReviewChooseBestAnswerRenderer.d.ts +22 -0
  223. package/dist/components/results/renderers/ReviewChooseBestAnswerRenderer.js +1 -0
  224. package/dist/components/results/renderers/ReviewColoringRenderer.d.ts +16 -0
  225. package/dist/components/results/renderers/ReviewColoringRenderer.js +1 -0
  226. package/dist/components/results/renderers/ReviewListenAndWriteRenderer.d.ts +18 -0
  227. package/dist/components/results/renderers/ReviewListenAndWriteRenderer.js +1 -0
  228. package/dist/components/results/renderers/ReviewListenChooseAnswerGroupRenderer.d.ts +25 -0
  229. package/dist/components/results/renderers/ReviewListenChooseAnswerGroupRenderer.js +1 -0
  230. package/dist/components/results/renderers/ReviewListenChooseObjectsRenderer.d.ts +25 -0
  231. package/dist/components/results/renderers/ReviewListenChooseObjectsRenderer.js +1 -0
  232. package/dist/components/results/renderers/ReviewListenDragObjectsRenderer.d.ts +25 -0
  233. package/dist/components/results/renderers/ReviewListenDragObjectsRenderer.js +1 -0
  234. package/dist/components/results/renderers/ReviewListeningHeader.d.ts +44 -0
  235. package/dist/components/results/renderers/ReviewListeningHeader.js +1 -0
  236. package/dist/components/results/renderers/ReviewSpeakingAIPanel.d.ts +17 -0
  237. package/dist/components/results/renderers/ReviewSpeakingAIPanel.js +1 -0
  238. package/dist/components/results/renderers/ReviewSpeakingMedia.d.ts +39 -0
  239. package/dist/components/results/renderers/ReviewSpeakingMedia.js +1 -0
  240. package/dist/components/results/renderers/ReviewSpeakingQuestionItem.d.ts +5 -0
  241. package/dist/components/results/renderers/ReviewSpeakingQuestionItem.js +1 -0
  242. package/dist/components/results/renderers/ReviewSpeakingRenderer.d.ts +3 -0
  243. package/dist/components/results/renderers/ReviewSpeakingRenderer.js +1 -0
  244. package/dist/components/results/renderers/ReviewSpeakingRenderer.types.d.ts +80 -0
  245. package/dist/components/results/renderers/ReviewSpeakingRenderer.types.js +1 -0
  246. package/dist/components/results/renderers/review-question-body-dedicated.d.ts +15 -0
  247. package/dist/components/results/renderers/review-question-body-dedicated.js +1 -0
  248. package/dist/components/results/renderers/review-question-body-movers.d.ts +17 -0
  249. package/dist/components/results/renderers/review-question-body-movers.js +1 -0
  250. package/dist/components/results/renderers/review-speaking-map.d.ts +7 -0
  251. package/dist/components/results/renderers/review-speaking-map.js +1 -0
  252. package/dist/components/results/report/BadgeTitle.d.ts +5 -0
  253. package/dist/components/results/report/BadgeTitle.js +1 -0
  254. package/dist/components/results/report/ExamSkillRow.d.ts +14 -0
  255. package/dist/components/results/report/ExamSkillRow.js +1 -0
  256. package/dist/components/results/report/OceanEduExamReport.d.ts +31 -0
  257. package/dist/components/results/report/OceanEduExamReport.js +1 -0
  258. package/dist/components/results/report/OceanEduSpeakingReport.d.ts +26 -0
  259. package/dist/components/results/report/OceanEduSpeakingReport.js +1 -0
  260. package/dist/components/results/report/OverallAssessmentSection.d.ts +24 -0
  261. package/dist/components/results/report/OverallAssessmentSection.js +1 -0
  262. package/dist/components/results/report/ResultErrorState.d.ts +14 -0
  263. package/dist/components/results/report/ResultErrorState.js +1 -0
  264. package/dist/components/results/report/ResultLoadingState.d.ts +11 -0
  265. package/dist/components/results/report/ResultLoadingState.js +1 -0
  266. package/dist/components/results/report/ResultNotPublicState.d.ts +16 -0
  267. package/dist/components/results/report/ResultNotPublicState.js +1 -0
  268. package/dist/components/results/report/SpeakingReportParts.d.ts +4 -0
  269. package/dist/components/results/report/SpeakingReportParts.js +1 -0
  270. package/dist/components/results/report/SpeakingReportShared.d.ts +36 -0
  271. package/dist/components/results/report/SpeakingReportShared.js +1 -0
  272. package/dist/components/results/report/SpeakingRubricSection.d.ts +21 -0
  273. package/dist/components/results/report/SpeakingRubricSection.js +1 -0
  274. package/dist/components/results/report/assets/dofu2.png +0 -0
  275. package/dist/components/results/report/assets/dofu4.png +0 -0
  276. package/dist/components/results/report/assets/logo-ocean.png +0 -0
  277. package/dist/components/results/report/assets/penguin-main.png +0 -0
  278. package/dist/components/results/report/assets/penguin-small.png +0 -0
  279. package/dist/components/results/report/speaking-report.utils.d.ts +37 -0
  280. package/dist/components/results/report/speaking-report.utils.js +1 -0
  281. package/dist/components/results/review-data.d.ts +1 -0
  282. package/dist/components/results/review-data.js +1 -1
  283. package/dist/components/results/review-status.utils.d.ts +12 -0
  284. package/dist/components/results/review-status.utils.js +1 -0
  285. package/dist/components/results/review-types.d.ts +14 -0
  286. package/dist/components/results/speaking/SpeakingResultAudioPlayer.d.ts +17 -0
  287. package/dist/components/results/speaking/SpeakingResultAudioPlayer.js +1 -0
  288. package/dist/components/results/speaking/SpeakingReviewResult.d.ts +30 -0
  289. package/dist/components/results/speaking/SpeakingReviewResult.js +1 -0
  290. package/dist/components/results/utils/review-score.utils.d.ts +21 -0
  291. package/dist/components/results/utils/review-score.utils.js +1 -0
  292. package/dist/components/results/utils/speaking-summary.d.ts +41 -0
  293. package/dist/components/results/utils/speaking-summary.js +1 -0
  294. package/dist/components/results/utils/transform-speaking-review.d.ts +62 -0
  295. package/dist/components/results/utils/transform-speaking-review.js +1 -0
  296. package/dist/components/shared/audio/SpeakingAudioPlayer.d.ts +12 -0
  297. package/dist/components/shared/audio/SpeakingAudioPlayer.js +1 -0
  298. package/dist/components/shared/audio/SpeakingAudioPlayer.module.css +115 -0
  299. package/dist/components/shared/audio/assets/fr-image-part1-border.png +0 -0
  300. package/dist/components/shared/audio/assets/ic-speaker.webp +0 -0
  301. package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.d.ts +11 -3
  302. package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.js +1 -1
  303. package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.d.ts +5 -1
  304. package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.js +1 -1
  305. package/dist/components/themes/index.d.ts +11 -0
  306. package/dist/components/themes/index.js +1 -1
  307. package/dist/components/themes/spaceship/SpaceshipAudioPlayer.d.ts +8 -0
  308. package/dist/components/themes/spaceship/SpaceshipAudioPlayer.js +1 -0
  309. package/dist/components/themes/spaceship/SpaceshipLayout.d.ts +2 -0
  310. package/dist/components/themes/spaceship/SpaceshipLayout.js +1 -0
  311. package/dist/components/themes/spaceship/assets/images/X-sunset.png +0 -0
  312. package/dist/components/themes/spaceship/assets/images/X.webp +0 -0
  313. package/dist/components/themes/spaceship/assets/images/audio-bar.webp +0 -0
  314. package/dist/components/themes/spaceship/assets/images/background.webp +0 -0
  315. package/dist/components/themes/spaceship/assets/images/bg_sunset.png +0 -0
  316. package/dist/components/themes/spaceship/assets/images/big-blue-badge-sunset.png +0 -0
  317. package/dist/components/themes/spaceship/assets/images/big-blue-badge.png +0 -0
  318. package/dist/components/themes/spaceship/assets/images/big-blue-badge.webp +0 -0
  319. package/dist/components/themes/spaceship/assets/images/bingo.webp +0 -0
  320. package/dist/components/themes/spaceship/assets/images/blue-badge-sunset.png +0 -0
  321. package/dist/components/themes/spaceship/assets/images/blue-badge.png +0 -0
  322. package/dist/components/themes/spaceship/assets/images/blue-wrapper-sunset.png +0 -0
  323. package/dist/components/themes/spaceship/assets/images/blue-wrapper.webp +0 -0
  324. package/dist/components/themes/spaceship/assets/images/board_red.png +0 -0
  325. package/dist/components/themes/spaceship/assets/images/button_feedback_vi.png +0 -0
  326. package/dist/components/themes/spaceship/assets/images/circle-btn-right-sunset.png +0 -0
  327. package/dist/components/themes/spaceship/assets/images/circle-btn-right.png +0 -0
  328. package/dist/components/themes/spaceship/assets/images/circle-btn-sunset.png +0 -0
  329. package/dist/components/themes/spaceship/assets/images/circle-btn.webp +0 -0
  330. package/dist/components/themes/spaceship/assets/images/focus-vector.webp +0 -0
  331. package/dist/components/themes/spaceship/assets/images/head-phone_red.png +0 -0
  332. package/dist/components/themes/spaceship/assets/images/ic-mute-sunset.png +0 -0
  333. package/dist/components/themes/spaceship/assets/images/ic-mute.png +0 -0
  334. package/dist/components/themes/spaceship/assets/images/ic-play-sunset.png +0 -0
  335. package/dist/components/themes/spaceship/assets/images/ic-play-violet.webp +0 -0
  336. package/dist/components/themes/spaceship/assets/images/ic-play.webp +0 -0
  337. package/dist/components/themes/spaceship/assets/images/micro.png +0 -0
  338. package/dist/components/themes/spaceship/assets/images/next-small.webp +0 -0
  339. package/dist/components/themes/spaceship/assets/images/next-sunset.png +0 -0
  340. package/dist/components/themes/spaceship/assets/images/next.webp +0 -0
  341. package/dist/components/themes/spaceship/assets/images/purple-circle.webp +0 -0
  342. package/dist/components/themes/spaceship/assets/images/question-badge-sunset.png +0 -0
  343. package/dist/components/themes/spaceship/assets/images/question-badge.webp +0 -0
  344. package/dist/components/themes/spaceship/assets/images/red-badge-sunset.png +0 -0
  345. package/dist/components/themes/spaceship/assets/images/red-badge.webp +0 -0
  346. package/dist/components/themes/spaceship/assets/images/red-wrapper-sunset.png +0 -0
  347. package/dist/components/themes/spaceship/assets/images/red-wrapper.webp +0 -0
  348. package/dist/components/themes/spaceship/assets/images/robot-avatar.png +0 -0
  349. package/dist/components/themes/spaceship/assets/images/sound_red.png +0 -0
  350. package/dist/components/themes/spaceship/assets/images/student-avatar.png +0 -0
  351. package/dist/components/themes/spaceship/assets/images/teacher-play-sunset.png +0 -0
  352. package/dist/components/themes/spaceship/assets/images/teacher-play.webp +0 -0
  353. package/dist/components/themes/spaceship/assets/images/timer-badge.png +0 -0
  354. package/dist/components/themes/spaceship/assets/styles/SpaceshipLayout.module.css +347 -0
  355. package/dist/components/themes/spaceship/assets/styles/SpaceshipWaitingRoom.module.css +395 -0
  356. package/dist/components/ui/badge.d.ts +1 -1
  357. package/dist/index.d.ts +4 -4
  358. package/dist/index.js +1 -1
  359. package/dist/shared/lib/stores/examTakingStore.d.ts +54 -0
  360. package/dist/shared/lib/stores/examTakingStore.js +1 -0
  361. package/dist/shared/lib/stores/gradingTransientStore.d.ts +23 -0
  362. package/dist/shared/lib/stores/gradingTransientStore.js +1 -0
  363. package/dist/shared/lib/themes/config/starters.config.d.ts +3 -0
  364. package/dist/shared/lib/themes/config/starters.config.js +1 -0
  365. package/dist/shared/lib/themes/index.d.ts +18 -0
  366. package/dist/shared/lib/themes/index.js +1 -0
  367. package/dist/shared/lib/themes/types.d.ts +39 -0
  368. package/dist/shared/lib/themes/types.js +1 -0
  369. package/dist/shared/lib/toast.d.ts +19 -0
  370. package/dist/shared/lib/toast.js +1 -0
  371. package/package.json +12 -2
@@ -0,0 +1,395 @@
1
+ .waitingRoomContainer {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ justify-content: flex-start;
6
+ width: 100%;
7
+ height: 100%;
8
+ }
9
+
10
+ .introBoard {
11
+ display: flex;
12
+ flex-direction: column;
13
+ align-items: center;
14
+ position: relative;
15
+ height: 100%;
16
+ width: 100%;
17
+ }
18
+
19
+ .title {
20
+ margin-top: 20px;
21
+ text-transform: uppercase;
22
+ font-family: var(--font-nunito-theme), 'Open Sans', system-ui, sans-serif;
23
+ font-size: 42px;
24
+ text-align: center;
25
+ font-weight: 800;
26
+ letter-spacing: 1.5px;
27
+ line-height: 1.25;
28
+ color: #E6635D;
29
+ margin-bottom: 50px;
30
+ text-shadow: 2px 3px 0px rgba(230, 99, 93, 0.15);
31
+ }
32
+
33
+ .instructionIconsWrap {
34
+ display: flex;
35
+ justify-content: space-between;
36
+ gap: 4px;
37
+ width: 100%;
38
+ padding: 0 100px;
39
+ margin-bottom: 2rem;
40
+ }
41
+
42
+ .instructionIconItem {
43
+ display: flex;
44
+ gap: 4px;
45
+ align-items: center;
46
+ }
47
+
48
+ .instructionIconImg {
49
+ width: 120px;
50
+ height: 120px;
51
+ }
52
+
53
+ .instructionIconText {
54
+ color: #541F0C;
55
+ font-size: 22px;
56
+ line-height: 26px;
57
+ font-weight: 400;
58
+ width: 210px;
59
+ }
60
+
61
+ .aiBanner {
62
+ margin: 0 116px 2.5rem;
63
+ padding: 20px 36px;
64
+ background: linear-gradient(135deg, #fff5f4 0%, #fceae9 100%);
65
+ border: 2px solid #e6635d;
66
+ border-radius: 16px;
67
+ display: flex;
68
+ align-items: center;
69
+ gap: 20px;
70
+ box-shadow: 0 4px 16px rgba(230, 99, 93, 0.12);
71
+ }
72
+
73
+ .aiBannerIcon {
74
+ flex-shrink: 0;
75
+ width: 60px;
76
+ height: 60px;
77
+ background: white;
78
+ border-radius: 50%;
79
+ display: flex;
80
+ align-items: center;
81
+ justify-content: center;
82
+ box-shadow: 0 2px 10px rgba(230, 99, 93, 0.2);
83
+ }
84
+
85
+ .aiBannerContent {
86
+ display: flex;
87
+ flex-direction: column;
88
+ gap: 4px;
89
+ }
90
+
91
+ .aiBannerTitle {
92
+ color: #E6635D;
93
+ font-size: 20px;
94
+ font-weight: 700;
95
+ text-transform: uppercase;
96
+ letter-spacing: 0.5px;
97
+ margin: 0;
98
+ line-height: 1.2;
99
+ }
100
+
101
+ .aiBannerDesc {
102
+ color: #541F0C;
103
+ font-size: 18px;
104
+ font-weight: 400;
105
+ line-height: 1.5;
106
+ margin: 0;
107
+ }
108
+
109
+ .stepButtonContainer {
110
+ display: flex;
111
+ justify-content: center;
112
+ margin-bottom: 30px;
113
+ }
114
+
115
+ .btnAction {
116
+ position: relative;
117
+ display: flex;
118
+ cursor: pointer;
119
+ }
120
+
121
+ .btnActionBg {
122
+ z-index: 0;
123
+ height: 57px;
124
+ width: 258px;
125
+ }
126
+
127
+ .btnActionInner {
128
+ position: absolute;
129
+ inset: 0;
130
+ cursor: pointer;
131
+ display: flex;
132
+ justify-content: center;
133
+ align-items: center;
134
+ padding-top: 12px;
135
+ }
136
+
137
+ .btnActionText {
138
+ color: white;
139
+ line-height: 1.25;
140
+ font-family: var(--font-nunito-theme), 'Open Sans', system-ui, sans-serif;
141
+ font-weight: 800;
142
+ letter-spacing: 0.5px;
143
+ text-align: center;
144
+ margin: 0;
145
+ width: 100%;
146
+ user-select: none;
147
+ }
148
+
149
+ .btnActionTextInner {
150
+ font-size: 22px;
151
+ text-transform: uppercase;
152
+ display: block;
153
+ text-shadow: rgba(0, 0, 0, 0.25) 0px 3px 0px;
154
+ }
155
+
156
+ .spacer {
157
+ height: 60px;
158
+ }
159
+
160
+ /* Mic Test */
161
+ .micTestTitle {
162
+ margin-top: 20px;
163
+ text-transform: uppercase;
164
+ font-family: var(--font-nunito-theme), 'Open Sans', system-ui, sans-serif;
165
+ font-size: 42px;
166
+ text-align: center;
167
+ font-weight: 800;
168
+ letter-spacing: 1.5px;
169
+ line-height: 1.25;
170
+ color: #E6635D;
171
+ margin-bottom: 50px;
172
+ text-shadow: 2px 3px 0px rgba(230, 99, 93, 0.15);
173
+ }
174
+
175
+ .micTestContainer {
176
+ background-color: #FCEAE9;
177
+ border-radius: 10px;
178
+ width: 1031px;
179
+ display: flex;
180
+ flex-direction: column;
181
+ justify-content: center;
182
+ align-items: center;
183
+ padding-top: 35px;
184
+ padding-bottom: 44px;
185
+ margin-bottom: 43px;
186
+ }
187
+
188
+ @media (max-width: 1536px) {
189
+ .micTestContainer {
190
+ width: 80%;
191
+ }
192
+ }
193
+
194
+ .micTestSubTitle {
195
+ color: #E6635D;
196
+ text-align: center;
197
+ font-size: 16px;
198
+ font-weight: 400;
199
+ line-height: 25px;
200
+ width: 550px;
201
+ }
202
+
203
+ .micTestInstructionWrap {
204
+ margin: 0 auto 30px auto;
205
+ width: fit-content;
206
+ max-width: 700px;
207
+ text-align: left;
208
+ color: #E6635D;
209
+ font-size: 16px;
210
+ line-height: 1.6;
211
+ }
212
+
213
+ .micTestInstructionWrap p {
214
+ font-weight: 700;
215
+ margin: 0 0 10px 0;
216
+ font-size: 17px;
217
+ text-transform: uppercase;
218
+ }
219
+
220
+ .micTestList {
221
+ list-style-type: decimal;
222
+ padding-left: 36px;
223
+ margin: 0;
224
+ }
225
+
226
+ .micTestList li {
227
+ margin-bottom: 12px;
228
+ padding-left: 4px;
229
+ }
230
+
231
+ .micTestBarWrap {
232
+ position: relative;
233
+ width: 693px;
234
+ height: 54px;
235
+ margin-top: 0px;
236
+ }
237
+
238
+ .audioBarImg {
239
+ z-index: 0;
240
+ filter: hue-rotate(140deg) brightness(0.9) saturate(1.5);
241
+ width: 100%;
242
+ }
243
+
244
+ .micTestBarInner {
245
+ position: absolute;
246
+ inset: 0;
247
+ }
248
+
249
+ .relativeFull {
250
+ position: relative;
251
+ width: 100%;
252
+ height: 100%;
253
+ }
254
+
255
+ .micTestIconWrap {
256
+ position: absolute;
257
+ top: -20px;
258
+ left: -10px;
259
+ width: 94px;
260
+ height: 94px;
261
+ cursor: pointer;
262
+ }
263
+
264
+ .purpleCircleImg {
265
+ z-index: 0;
266
+ filter: hue-rotate(90deg) brightness(1.1) saturate(1.2);
267
+ }
268
+
269
+ .micTestIconInner {
270
+ position: absolute;
271
+ inset: 0;
272
+ display: flex;
273
+ align-items: center;
274
+ justify-content: center;
275
+ }
276
+
277
+ .focusVectorImg {
278
+ position: absolute;
279
+ top: -40px;
280
+ filter: hue-rotate(120deg) saturate(2);
281
+ }
282
+
283
+ .microImg {
284
+ transition: transform 0.2s;
285
+ }
286
+
287
+ .microImg:hover {
288
+ transform: scale(1.1);
289
+ }
290
+
291
+ .micTestTrackWrap {
292
+ margin-left: 97px;
293
+ height: 100%;
294
+ display: flex;
295
+ align-items: center;
296
+ gap: 7px;
297
+ padding-top: 4px;
298
+ padding-right: 24px;
299
+ }
300
+
301
+ .micTestTime {
302
+ color: white;
303
+ font-size: 14px;
304
+ font-weight: 700;
305
+ transform: translateY(2px);
306
+ white-space: nowrap;
307
+ padding-right: 8px;
308
+ }
309
+
310
+ .micTestTrack {
311
+ border-radius: 2px;
312
+ height: 10px;
313
+ background-color: #541F0C;
314
+ overflow: hidden;
315
+ flex-grow: 1;
316
+ box-shadow: rgba(0, 0, 0, 0.5) 0px 0.587px 0px 0px;
317
+ }
318
+
319
+ .micTestFill {
320
+ height: 100%;
321
+ border-radius: 1px;
322
+ background-color: #FFDC30;
323
+ box-shadow: rgb(247, 171, 22) 0px -4px 0px 0px inset;
324
+ transition: width 0.05s linear;
325
+ }
326
+
327
+ /* ===== Teacher Floating (Phương án B) ===== */
328
+ .teacherFloating {
329
+ position: fixed;
330
+ bottom: 0;
331
+ left: clamp(0px, calc(50vw - 950px), 24px);
332
+ z-index: 90;
333
+ display: flex;
334
+ flex-direction: column;
335
+ align-items: center;
336
+ animation: teacherSlideIn 1s cubic-bezier(0.16, 1, 0.3, 1) both;
337
+ animation-delay: 0.3s;
338
+ }
339
+
340
+ .teacherVideo {
341
+ width: clamp(120px, calc(50vw - 750px), 280px);
342
+ height: auto;
343
+ display: block;
344
+ filter: drop-shadow(0 4px 24px rgba(230, 99, 93, 0.35));
345
+ pointer-events: none;
346
+ }
347
+
348
+ .teacherGlow {
349
+ position: absolute;
350
+ bottom: 8px;
351
+ left: 50%;
352
+ transform: translateX(-50%);
353
+ width: clamp(80px, calc(50vw - 780px), 200px);
354
+ height: clamp(20px, calc(10vw - 150px), 50px);
355
+ background: radial-gradient(ellipse, rgba(230, 99, 93, 0.3) 0%, transparent 70%);
356
+ border-radius: 50%;
357
+ animation: glowPulse 3s ease-in-out infinite;
358
+ pointer-events: none;
359
+ }
360
+
361
+ @keyframes teacherSlideIn {
362
+ 0% {
363
+ opacity: 0;
364
+ transform: translateY(50px);
365
+ }
366
+
367
+ 100% {
368
+ opacity: 1;
369
+ transform: translateY(0);
370
+ }
371
+ }
372
+
373
+ @keyframes glowPulse {
374
+
375
+ 0%,
376
+ 100% {
377
+ opacity: 0.3;
378
+ }
379
+
380
+ 50% {
381
+ opacity: 0.7;
382
+ }
383
+ }
384
+
385
+ @media (prefers-reduced-motion: reduce) {
386
+ .teacherFloating {
387
+ animation: none;
388
+ opacity: 1;
389
+ }
390
+
391
+ .teacherGlow {
392
+ animation: none;
393
+ opacity: 0.5;
394
+ }
395
+ }
@@ -7,7 +7,7 @@ import { type VariantProps } from 'class-variance-authority';
7
7
  * No border by default
8
8
  */
9
9
  declare const badgeVariants: (props?: {
10
- variant?: "default" | "destructive" | "outline" | "secondary" | "success" | "info" | "warning" | "dark";
10
+ variant?: "default" | "destructive" | "outline" | "secondary" | "warning" | "success" | "info" | "dark";
11
11
  } & import("class-variance-authority/types").ClassProp) => string;
12
12
  export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
13
13
  }
package/dist/index.d.ts CHANGED
@@ -6,10 +6,10 @@ export * as Questions from './components/questions';
6
6
  export * as Results from './components/results';
7
7
  export * as Themes from './components/themes';
8
8
  export * as Shared from './shared';
9
- export { buildExamTemplatePayload, createExamCreateApi, createExamQuestionsApi, createExamQuestionsFetchApi, createExamTakingApi, createMockCreateExamApi, createMockExamQuestionsApi, createMockExamTakingApi, createMockResultReviewApi, createResultReviewApi } from './api';
10
- export type { AnswerGradingStatusItem, AnswersGradingStatusResult, CreateExamFetchApiOptions, CreateExamPayload, CreateExamSdkApi, ExamFormData, ExamLevelOption, ExamQuestionsSdkApi, ExamResponse, ExamTakingAnswerValue, ExamTakingAttempt, ExamTakingFetchApiOptions, ExamTakingQuestion, ExamTakingQuestionsResult, ExamTakingRoom, ExamTakingSdkApi, ExamTakingTemplatePart, ExamTemplatePayload, ExamWithTemplate, ExistingQuestionBank, FetchApiOptions, GradingSummary, QuestionSearchItem, SaveExamInput, SaveExamTakingAnswersInput, SaveQuestionInput, SaveQuestionResult, SearchQuestionBankInput, SearchQuestionBankResult, SubmitExamTakingAttemptResult, UpdateExamTemplateInput, UpdatePartAudioInput, UploadAudioAnswerResult } from './api';
11
- export { CreateExamPageContainer, ExamPreviewDialog, ExamQuestionsPageContainer, ExamTakingPageContainer, ExamViewDialog } from './components/exams';
12
- export type { CreateExamPageContainerProps, CreateExamTexts, ExamPreviewDialogProps, ExamQuestionsPageContainerProps, ExamTakingPageContainerProps, ExamViewDialogExam, ExamViewDialogProps } from './components/exams';
9
+ export { buildExamTemplatePayload, createContestRoomsApi, createExamCreateApi, createExamEntryApi, createExamQuestionsApi, createExamQuestionsFetchApi, createExamTakingApi, createMockContestRoomsApi, createMockCreateExamApi, createMockExamEntryApi, createMockExamQuestionsApi, createMockExamTakingApi, createMockResultReviewApi, createResultReviewApi } from './api';
10
+ export type { AnswerGradingStatusItem, AnswersGradingStatusResult, ContestRoomListItem, ContestRoomRegistrationStatus, ContestRoomVisibility, ContestRoomsContestDetail, ContestRoomsFetchApiOptions, ContestRoomsSdkApi, CreateExamFetchApiOptions, CreateExamPayload, CreateExamSdkApi, ExamFormData, ExamLevelOption, ExamQuestionsSdkApi, ExamResponse, ExamTakingAnswerValue, ExamTakingAttempt, ExamTakingFetchApiOptions, ExamTakingQuestion, ExamTakingQuestionsResult, ExamTakingRoom, ExamTakingSdkApi, ExamTakingTemplatePart, ExamTemplatePayload, ExamWithTemplate, ExistingQuestionBank, FetchApiOptions, GradingSummary, QuestionSearchItem, SaveExamInput, SaveExamTakingAnswersInput, SaveQuestionInput, SaveQuestionResult, SearchQuestionBankInput, SearchQuestionBankResult, SubmitExamTakingAttemptResult, UpdateExamTemplateInput, UpdatePartAudioInput, UploadAudioAnswerResult } from './api';
11
+ export { CreateExamPageContainer, ExamPreviewDialog, ExamQuestionsPageContainer, ExamTakingPageContainer, ExamViewDialog, StudentContestRoomsPageContainer, StudentExamEntryPageContainer } from './components/exams';
12
+ export type { CreateExamPageContainerProps, CreateExamTexts, ExamPreviewDialogProps, ExamQuestionsPageContainerProps, ExamTakingPageContainerProps, ExamViewDialogExam, ExamViewDialogProps, StudentContestRoomsPageContainerProps, StudentExamEntryPageContainerProps } from './components/exams';
13
13
  export { ResultReviewPageContainer } from './components/results';
14
14
  export type { ResultReviewPageContainerProps } from './components/results';
15
15
  export { QuestionCreator } from './components/questions/creator/QuestionCreator';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export*as Api from"./api";export*as Components from"./components";export*as Mcp from"./mcp";export*as Exams from"./components/exams";export*as Questions from"./components/questions";export*as Results from"./components/results";export*as Themes from"./components/themes";export*as Shared from"./shared";export{buildExamTemplatePayload,createExamCreateApi,createExamQuestionsApi,createExamQuestionsFetchApi,createExamTakingApi,createMockCreateExamApi,createMockExamQuestionsApi,createMockExamTakingApi,createMockResultReviewApi,createResultReviewApi}from"./api";export{CreateExamPageContainer,ExamPreviewDialog,ExamQuestionsPageContainer,ExamTakingPageContainer,ExamViewDialog}from"./components/exams";export{ResultReviewPageContainer}from"./components/results";export{QuestionCreator}from"./components/questions/creator/QuestionCreator";export{QuestionGroupCreator}from"./components/questions/creator/QuestionGroupCreator";export{renderDedicatedComponent}from"./components/questions/creator/dedicated-component-router";export{questionTypeRegistry}from"./components/questions/creator/question-type-registry";export{QUESTION_TYPE_CONFIG,QUESTION_TYPES_WITH_DEDICATED_COMPONENTS}from"./components/questions/_shared/config/question-types.config";export{validateQuestion}from"./components/questions/_shared/utils/question-validation";export{buildAnswerPayload}from"./components/questions/_shared/utils/answer-builder";export*from"./components/questions/_shared/types";
1
+ export*as Api from"./api";export*as Components from"./components";export*as Mcp from"./mcp";export*as Exams from"./components/exams";export*as Questions from"./components/questions";export*as Results from"./components/results";export*as Themes from"./components/themes";export*as Shared from"./shared";export{buildExamTemplatePayload,createContestRoomsApi,createExamCreateApi,createExamEntryApi,createExamQuestionsApi,createExamQuestionsFetchApi,createExamTakingApi,createMockContestRoomsApi,createMockCreateExamApi,createMockExamEntryApi,createMockExamQuestionsApi,createMockExamTakingApi,createMockResultReviewApi,createResultReviewApi}from"./api";export{CreateExamPageContainer,ExamPreviewDialog,ExamQuestionsPageContainer,ExamTakingPageContainer,ExamViewDialog,StudentContestRoomsPageContainer,StudentExamEntryPageContainer}from"./components/exams";export{ResultReviewPageContainer}from"./components/results";export{QuestionCreator}from"./components/questions/creator/QuestionCreator";export{QuestionGroupCreator}from"./components/questions/creator/QuestionGroupCreator";export{renderDedicatedComponent}from"./components/questions/creator/dedicated-component-router";export{questionTypeRegistry}from"./components/questions/creator/question-type-registry";export{QUESTION_TYPE_CONFIG,QUESTION_TYPES_WITH_DEDICATED_COMPONENTS}from"./components/questions/_shared/config/question-types.config";export{validateQuestion}from"./components/questions/_shared/utils/question-validation";export{buildAnswerPayload}from"./components/questions/_shared/utils/answer-builder";export*from"./components/questions/_shared/types";
@@ -0,0 +1,54 @@
1
+ import type { StudentQuestion, InitializeData, StoreTemplatePart } from '../../types/exam-taking.types';
2
+ interface ExamTakingState {
3
+ attemptId: string | null;
4
+ examRoomId: string | null;
5
+ questions: StudentQuestion[];
6
+ answers: Record<string, any>;
7
+ currentIndex: number;
8
+ remainingSeconds: number;
9
+ endsAt: number | null;
10
+ isInitialized: boolean;
11
+ isDirty: boolean;
12
+ lastSavedAt: Date | null;
13
+ isSubmitting: boolean;
14
+ isNavDisabled: boolean;
15
+ flaggedQuestions: Set<string>;
16
+ currentPartIndex: number;
17
+ currentQuestionGlobalIndex: number;
18
+ playedIntroParts: Set<number>;
19
+ playedListeningAudioParts: Set<string>;
20
+ examType: string | null;
21
+ examTitle: string | null;
22
+ parts: StoreTemplatePart[];
23
+ hydrateFromServer: (data: InitializeData) => void;
24
+ setAnswer: (questionId: string, answer: any) => void;
25
+ nextQuestion: () => void;
26
+ prevQuestion: () => void;
27
+ goToQuestion: (index: number) => void;
28
+ syncRemainingSeconds: () => number;
29
+ markSaved: () => void;
30
+ setIsSubmitting: (value: boolean) => void;
31
+ setIsNavDisabled: (value: boolean) => void;
32
+ toggleFlag: (questionId: string) => void;
33
+ setCurrentPartIndex: (index: number) => void;
34
+ setCurrentQuestionGlobalIndex: (index: number) => void;
35
+ markIntroPlayed: (partIndex: number) => void;
36
+ markListeningAudioPlayed: (partId: string) => void;
37
+ setExamType: (type: string) => void;
38
+ setParts: (parts: StoreTemplatePart[]) => void;
39
+ reset: () => void;
40
+ }
41
+ export declare const useExamTakingStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<ExamTakingState>, "setState" | "persist"> & {
42
+ setState(partial: ExamTakingState | Partial<ExamTakingState> | ((state: ExamTakingState) => ExamTakingState | Partial<ExamTakingState>), replace?: false): unknown;
43
+ setState(state: ExamTakingState | ((state: ExamTakingState) => ExamTakingState), replace: true): unknown;
44
+ persist: {
45
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<ExamTakingState, unknown, unknown>>) => void;
46
+ clearStorage: () => void;
47
+ rehydrate: () => Promise<void> | void;
48
+ hasHydrated: () => boolean;
49
+ onHydrate: (fn: (state: ExamTakingState) => void) => () => void;
50
+ onFinishHydration: (fn: (state: ExamTakingState) => void) => () => void;
51
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<ExamTakingState, unknown, unknown>>;
52
+ };
53
+ }>;
54
+ export {};
@@ -0,0 +1 @@
1
+ import{create as e}from"zustand";import{persist as t,createJSONStorage as n}from"zustand/middleware";const a="__set__",r=n(()=>localStorage,{replacer:(e,t)=>t instanceof Set?{[a]:Array.from(t)}:t,reviver:(e,t)=>t&&"object"==typeof t&&Array.isArray(t[a])?new Set(t[a]):t});export const useExamTakingStore=e()(t((e,t)=>({attemptId:null,examRoomId:null,questions:[],answers:{},currentIndex:0,remainingSeconds:0,endsAt:null,isInitialized:!1,isDirty:!1,lastSavedAt:null,isSubmitting:!1,isNavDisabled:!1,flaggedQuestions:new Set,currentPartIndex:0,currentQuestionGlobalIndex:0,playedIntroParts:new Set,playedListeningAudioParts:new Set,examType:null,examTitle:null,parts:[],hydrateFromServer:n=>{const a=new Date(n.startedAt),r=60*n.durationMinutes*1e3,s=a.getTime()+r,i=Date.now(),d=Math.max(0,s-i),o=Math.floor(d/1e3),l=t(),u=l.attemptId===n.attemptId;e({attemptId:n.attemptId,examRoomId:n.examRoomId,questions:n.questions,remainingSeconds:o,endsAt:s,isInitialized:!0,isDirty:!1,lastSavedAt:null,isSubmitting:!1,isNavDisabled:!1,examType:n.examType??null,examTitle:n.examTitle??null,parts:n.parts??[],answers:u?l.answers:{},currentIndex:u?l.currentIndex:0,currentPartIndex:u?l.currentPartIndex:0,currentQuestionGlobalIndex:u?l.currentQuestionGlobalIndex:0,flaggedQuestions:u?l.flaggedQuestions:new Set,playedIntroParts:u?l.playedIntroParts:new Set,playedListeningAudioParts:u?l.playedListeningAudioParts:new Set})},setAnswer:(t,n)=>{e(e=>({answers:{...e.answers,[t]:n},isDirty:!0}))},nextQuestion:()=>{e(e=>{const t=e.currentIndex+1;return t<e.questions.length?{currentIndex:t}:e})},prevQuestion:()=>{e(e=>{const t=e.currentIndex-1;return t>=0?{currentIndex:t}:e})},goToQuestion:t=>{e(e=>t>=0&&t<e.questions.length?{currentIndex:t}:e)},syncRemainingSeconds:()=>{const{endsAt:n,remainingSeconds:a}=t();if(null==n)return a;const r=Math.max(0,Math.round((n-Date.now())/1e3));return e({remainingSeconds:r}),r},markSaved:()=>{e({isDirty:!1,lastSavedAt:new Date})},setIsSubmitting:t=>{e({isSubmitting:t})},setIsNavDisabled:t=>{e({isNavDisabled:t})},toggleFlag:t=>{e(e=>{const n=new Set(e.flaggedQuestions);return n.has(t)?n.delete(t):n.add(t),{flaggedQuestions:n}})},setCurrentPartIndex:t=>{e({currentPartIndex:t})},setCurrentQuestionGlobalIndex:t=>{e({currentQuestionGlobalIndex:t})},markIntroPlayed:t=>{e(e=>{if(e.playedIntroParts.has(t))return e;const n=new Set(e.playedIntroParts);return n.add(t),{playedIntroParts:n}})},markListeningAudioPlayed:t=>{e(e=>{if(e.playedListeningAudioParts.has(t))return e;const n=new Set(e.playedListeningAudioParts);return n.add(t),{playedListeningAudioParts:n}})},setExamType:t=>{e({examType:t})},setParts:t=>{e({parts:t})},reset:()=>{e({attemptId:null,examRoomId:null,questions:[],answers:{},currentIndex:0,remainingSeconds:0,endsAt:null,isInitialized:!1,isDirty:!1,lastSavedAt:null,isSubmitting:!1,isNavDisabled:!1,flaggedQuestions:new Set,currentPartIndex:0,currentQuestionGlobalIndex:0,playedIntroParts:new Set,playedListeningAudioParts:new Set,examType:null,examTitle:null,parts:[]}),useExamTakingStore.persist.clearStorage()}}),{name:"exam-taking-storage",storage:r,partialize:e=>({attemptId:e.attemptId,examRoomId:e.examRoomId,answers:e.answers,currentIndex:e.currentIndex,currentPartIndex:e.currentPartIndex,currentQuestionGlobalIndex:e.currentQuestionGlobalIndex,flaggedQuestions:e.flaggedQuestions,playedIntroParts:e.playedIntroParts,playedListeningAudioParts:e.playedListeningAudioParts,examType:e.examType,examTitle:e.examTitle})}));
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Transient (in-memory only) store for handing off `pendingAnswerIds`
3
+ * from the submit page to the result page after fire-and-forget submit.
4
+ *
5
+ * Why a store instead of query params or localStorage?
6
+ * - Query params: pollute URL, large lists overflow
7
+ * - localStorage: leaks across tabs/sessions, hard to invalidate
8
+ * - Zustand transient: cheap, auto-clears on tab close, scoped to this attempt
9
+ *
10
+ * Falls back to GET /grading-summary if user navigates directly to result page
11
+ * (e.g. refresh, deep link, new tab) and the store is empty.
12
+ */
13
+ interface GradingTransientState {
14
+ /** Map attemptId → pending answer IDs (just-submitted handoff) */
15
+ pendingByAttempt: Record<string, string[]>;
16
+ /** Last time setPending was called for an attempt (for TTL cleanup) */
17
+ setAtByAttempt: Record<string, number>;
18
+ setPending: (attemptId: string, answerIds: string[]) => void;
19
+ getPending: (attemptId: string) => string[] | undefined;
20
+ clear: (attemptId: string) => void;
21
+ }
22
+ export declare const useGradingTransientStore: import("zustand").UseBoundStore<import("zustand").StoreApi<GradingTransientState>>;
23
+ export {};
@@ -0,0 +1 @@
1
+ import{create as t}from"zustand";export const useGradingTransientStore=t((t,e)=>({pendingByAttempt:{},setAtByAttempt:{},setPending:(e,n)=>{t(t=>({pendingByAttempt:{...t.pendingByAttempt,[e]:n},setAtByAttempt:{...t.setAtByAttempt,[e]:Date.now()}}))},getPending:t=>{const n=e().setAtByAttempt[t];if(n){if(!(Date.now()-n>3e5))return e().pendingByAttempt[t];e().clear(t)}},clear:e=>{t(t=>{const{[e]:n,...p}=t.pendingByAttempt,{[e]:A,...m}=t.setAtByAttempt;return{pendingByAttempt:p,setAtByAttempt:m}})}}));
@@ -0,0 +1,3 @@
1
+ import type { ThemeConfig } from '../types';
2
+ export declare const startersTheme: ThemeConfig;
3
+ export declare const commonTheme: ThemeConfig;
@@ -0,0 +1 @@
1
+ import e from"../../../../components/themes/cambridge-yle/assets/images/background-ocean-edu-2.png";import r from"../../../../components/themes/cambridge-yle/assets/images/bg-title.png";import t from"../../../../components/themes/cambridge-yle/assets/images/border.png";import s from"../../../../components/themes/cambridge-yle/assets/images/close.png";import a from"../../../../components/themes/cambridge-yle/assets/images/rocket.png";import o from"../../../../components/themes/cambridge-yle/assets/images/icon-bottom-left.png";import c from"../../../../components/themes/cambridge-yle/assets/images/icon-bottom-right.png";import m from"../../../../components/themes/cambridge-yle/assets/images/button_feedback_vi.png";export const startersTheme={id:"starters",displayName:"STARTERS",colors:{primary:"#0473f9",secondary:"#0ea5e9",background:"#e0f2fe",text:"#002249",cardBg:"#0473f9",cardBorder:"#1d4ed8"},assets:{background:e.src,cardFrame:t.src,titleBar:r.src,logo:r.src,closeButton:s.src,startIcon:a.src,bottomLeft:o.src,bottomRight:c.src,feedbackButton:m.src},visuals:{backgroundFilter:"blur(2px) brightness(0.8) saturate(0.9)",backgroundOverlay:"linear-gradient(to bottom, rgba(23, 37, 84, 0.5), rgba(30, 58, 138, 0.4), rgba(23, 37, 84, 0.6))",cardBackground:"radial-gradient(60% 60% at 50% 40%, rgba(56, 189, 248, 0.90) 0%, rgba(4, 115, 249, 0.92) 100%)"}};export const commonTheme={id:"common",displayName:"NHIỆM VỤ ĐẦU",colors:{primary:"#0473f9",secondary:"#0ea5e9",background:"#e0f2fe",text:"#002249",cardBg:"#0473f9",cardBorder:"#1d4ed8"},assets:{background:e.src,cardFrame:t.src,titleBar:r.src,logo:r.src,closeButton:s.src,startIcon:a.src,bottomLeft:o.src,bottomRight:c.src,feedbackButton:m.src},visuals:{backgroundFilter:"blur(2px) brightness(0.8) saturate(0.9)",backgroundOverlay:"linear-gradient(to bottom, rgba(23, 37, 84, 0.5), rgba(30, 58, 138, 0.4), rgba(23, 37, 84, 0.6))",cardBackground:"radial-gradient(60% 60% at 50% 40%, rgba(56, 189, 248, 0.90) 0%, rgba(4, 115, 249, 0.92) 100%)"}};
@@ -0,0 +1,18 @@
1
+ import type { ThemeConfig } from './types';
2
+ export declare function normalizeExamTheme(theme?: string | null): string;
3
+ export declare function getThemeConfigByExamTheme(_theme?: string | null): ThemeConfig | null;
4
+ export declare function resolveThemeConfig(options: {
5
+ examTheme?: string | null;
6
+ templateTheme?: string | null;
7
+ level?: string | null;
8
+ }): ThemeConfig;
9
+ /**
10
+ * Get theme based on exam level string
11
+ * Maps Cambridge YLE levels to themes
12
+ */
13
+ export declare function getThemeForLevel(level?: string): ThemeConfig;
14
+ /**
15
+ * Get default theme (starters)
16
+ */
17
+ export declare function getTheme(): ThemeConfig;
18
+ export type { ThemeConfig, ExamTheme, ThemeColors, ThemeAssets, ThemeVisuals } from './types';
@@ -0,0 +1 @@
1
+ import{commonTheme as e,startersTheme as r}from"./config/starters.config";const t={common:e,starters:r,movers:r,flyers:r};export function normalizeExamTheme(e){return"string"==typeof e?e.trim().toUpperCase():""}export function getThemeConfigByExamTheme(e){return null}export function resolveThemeConfig(e){return getThemeConfigByExamTheme(e.examTheme)??getThemeConfigByExamTheme(e.templateTheme)??getThemeForLevel(e.level??void 0)}export function getThemeForLevel(r){if(!r)return e;const n=r.toLowerCase();return n.includes("pre-a1")||n.includes("a1")||n.includes("starter")?t.starters:n.includes("a2")||n.includes("mover")?t.movers:n.includes("b1")||n.includes("b2")||n.includes("flyer")?t.flyers:e}export function getTheme(){return r}
@@ -0,0 +1,39 @@
1
+ export type ExamTheme = 'common' | 'starters' | 'movers' | 'flyers';
2
+ export interface ThemeColors {
3
+ primary: string;
4
+ secondary: string;
5
+ background: string;
6
+ text: string;
7
+ cardBg: string;
8
+ cardBorder: string;
9
+ }
10
+ export interface ThemeAssets {
11
+ background: string;
12
+ cardFrame: string;
13
+ titleBar: string;
14
+ logo: string;
15
+ closeButton: string;
16
+ startIcon: string;
17
+ bottomLeft: string;
18
+ bottomRight: string;
19
+ feedbackButton?: string;
20
+ }
21
+ export interface ThemeVisuals {
22
+ /** CSS filter applied to the fullscreen background image */
23
+ backgroundFilter?: string;
24
+ /** CSS background value rendered above the fullscreen background image */
25
+ backgroundOverlay?: string;
26
+ /** CSS background value used for the main waiting-room card surface */
27
+ cardBackground?: string;
28
+ }
29
+ export interface ThemeConfig {
30
+ id: ExamTheme;
31
+ displayName: string;
32
+ colors: ThemeColors;
33
+ assets: ThemeAssets;
34
+ visuals?: ThemeVisuals;
35
+ /** CSS filter applied to the close button and card frame border images */
36
+ assetFilter?: string;
37
+ /** CSS filter applied specifically to the title bar image (may differ from assetFilter) */
38
+ titleBarFilter?: string;
39
+ }
@@ -0,0 +1 @@
1
+ export{};
@@ -0,0 +1,19 @@
1
+ export declare const toast: {
2
+ success: (message: string, description?: string) => string | number;
3
+ error: (message: string, description?: string) => string | number;
4
+ warning: (message: string, description?: string) => string | number;
5
+ info: (message: string, description?: string) => string | number;
6
+ loading: (message: string, description?: string) => string | number;
7
+ promise: <T>(promise: Promise<T>, { loading, success, error, }: {
8
+ loading: string;
9
+ success: string | ((data: T) => string);
10
+ error: string | ((error: any) => string);
11
+ }) => (string & {
12
+ unwrap: () => Promise<T>;
13
+ }) | (number & {
14
+ unwrap: () => Promise<T>;
15
+ }) | {
16
+ unwrap: () => Promise<T>;
17
+ };
18
+ dismiss: (id?: string | number) => string | number;
19
+ };
@@ -0,0 +1 @@
1
+ import{toast as s}from"sonner";export const toast={success:(i,r)=>s.success(i,{description:r,duration:3e3}),error:(i,r)=>s.error(i,{description:r,duration:4e3}),warning:(i,r)=>s.warning(i,{description:r,duration:3500}),info:(i,r)=>s.info(i,{description:r,duration:3e3}),loading:(i,r)=>s.loading(i,{description:r}),promise:(i,{loading:r,success:o,error:n})=>s.promise(i,{loading:r,success:o,error:n}),dismiss:i=>s.dismiss(i)};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinyweb_dev/oe-exam-sdk",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Reusable OceanEdu question components.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "build:compile": "tsc -p tsconfig.build.json",
22
22
  "build:alias": "tsc-alias -p tsconfig.build.json",
23
23
  "build:ts": "npm run build:compile && npm run build:assets && npm run build:alias",
24
- "build:assets": "for d in cambridge-yle english-certification summer-sky; do [ -d src/components/themes/$d/assets ] && cp -R src/components/themes/$d/assets dist/components/themes/$d/ || true; done && cp src/global.d.ts dist/global.d.ts",
24
+ "build:assets": "for d in cambridge-yle english-certification summer-sky spaceship; do [ -d src/components/themes/$d/assets ] && cp -R src/components/themes/$d/assets dist/components/themes/$d/ || true; done; [ -d src/components/shared/audio/assets ] && cp -R src/components/shared/audio/assets dist/components/shared/audio/ || true; [ -d src/components/results/report/assets ] && mkdir -p dist/components/results/report && cp -R src/components/results/report/assets dist/components/results/report/ || true; (cd src && find . -name '*.module.css' -exec cp --parents {} ../dist/ \\;); cp src/global.d.ts dist/global.d.ts",
25
25
  "minify:js": "find dist -name '*.js' -type f -exec sh -c 'for f do terser \"$f\" --compress directives=false --mangle --module --comments false --output \"$f\"; done' sh {} +",
26
26
  "build": "npm run clean && npm run build:ts && npm run minify:js",
27
27
  "pack:local": "npm pack",
@@ -57,6 +57,14 @@
57
57
  "types": "./dist/components/exams/take/index.d.ts",
58
58
  "import": "./dist/components/exams/take/index.js"
59
59
  },
60
+ "./components/exams/entry": {
61
+ "types": "./dist/components/exams/entry/index.d.ts",
62
+ "import": "./dist/components/exams/entry/index.js"
63
+ },
64
+ "./components/exams/rooms": {
65
+ "types": "./dist/components/exams/rooms/index.d.ts",
66
+ "import": "./dist/components/exams/rooms/index.js"
67
+ },
60
68
  "./components/questions": {
61
69
  "types": "./dist/components/questions/index.d.ts",
62
70
  "import": "./dist/components/questions/index.js"
@@ -101,6 +109,7 @@
101
109
  "@dnd-kit/core": "^6.3.1",
102
110
  "@dnd-kit/sortable": "^10.0.0",
103
111
  "@dnd-kit/utilities": "^3.2.2",
112
+ "@fortawesome/free-solid-svg-icons": "^7.3.1",
104
113
  "@fortawesome/react-fontawesome": "^3.3.1",
105
114
  "@hookform/resolvers": "^5.2.2",
106
115
  "@modelcontextprotocol/sdk": "^1.29.0",
@@ -131,6 +140,7 @@
131
140
  "@tiptap/pm": "^3.22.3",
132
141
  "@tiptap/react": "^3.22.3",
133
142
  "@tiptap/starter-kit": "^3.22.3",
143
+ "@types/qrcode": "^1.5.6",
134
144
  "@xyflow/react": "^12.8.6",
135
145
  "axios": "^1.12.2",
136
146
  "class-variance-authority": "^0.7.1",