@tinyweb_dev/oe-exam-sdk 0.1.28 → 0.1.29

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 (796) hide show
  1. package/README.md +4 -4
  2. package/dist/api/contest-rooms.js +54 -1
  3. package/dist/api/contest-rooms.types.js +1 -1
  4. package/dist/api/exam-create.js +179 -1
  5. package/dist/api/exam-create.types.js +1 -1
  6. package/dist/api/exam-entry.js +68 -1
  7. package/dist/api/exam-entry.types.js +1 -1
  8. package/dist/api/exam-questions.js +149 -1
  9. package/dist/api/exam-questions.types.js +1 -1
  10. package/dist/api/exam-taking.js +84 -1
  11. package/dist/api/exam-taking.types.d.ts +7 -0
  12. package/dist/api/exam-taking.types.js +1 -1
  13. package/dist/api/index.js +8 -1
  14. package/dist/api/result-review.js +62 -1
  15. package/dist/api/result-review.types.js +16 -1
  16. package/dist/components/CueCardEditor.js +58 -1
  17. package/dist/components/common/ResolvedImage.js +15 -1
  18. package/dist/components/exams/CompletionDialog.js +8 -1
  19. package/dist/components/exams/CreateExamInfoForm.js +84 -1
  20. package/dist/components/exams/CreateExamPageContainer.js +110 -1
  21. package/dist/components/exams/ExamCreator.js +287 -1
  22. package/dist/components/exams/ExamPartTabs.js +138 -1
  23. package/dist/components/exams/ExamPreviewDialog.d.ts +6 -7
  24. package/dist/components/exams/ExamPreviewDialog.js +121 -1
  25. package/dist/components/exams/ExamPreviewPartContent.d.ts +18 -0
  26. package/dist/components/exams/ExamPreviewPartContent.js +27 -0
  27. package/dist/components/exams/ExamPreviewSidebar.d.ts +17 -0
  28. package/dist/components/exams/ExamPreviewSidebar.js +37 -0
  29. package/dist/components/exams/ExamQuestionGrid.js +37 -1
  30. package/dist/components/exams/ExamQuestionsPageContainer.js +112 -1
  31. package/dist/components/exams/ExamViewDialog.js +61 -1
  32. package/dist/components/exams/PartAudioUploader.js +9 -1
  33. package/dist/components/exams/TemplateSelector.js +76 -1
  34. package/dist/components/exams/UnsavedChangesDialog.js +7 -1
  35. package/dist/components/exams/api.js +3 -1
  36. package/dist/components/exams/create-exam.texts.js +1 -1
  37. package/dist/components/exams/create-exam.validation.js +18 -1
  38. package/dist/components/exams/entry/EntryRestartDialog.js +11 -1
  39. package/dist/components/exams/entry/StudentExamEntryPageContainer.js +358 -1
  40. package/dist/components/exams/entry/exam-entry.states.js +26 -1
  41. package/dist/components/exams/entry/exam-entry.utils.js +55 -1
  42. package/dist/components/exams/entry/fullscreen-loading.js +18 -1
  43. package/dist/components/exams/entry/index.js +4 -1
  44. package/dist/components/exams/exam-preview.types.d.ts +30 -0
  45. package/dist/components/exams/exam-preview.types.js +62 -0
  46. package/dist/components/exams/exam-question-status.js +45 -1
  47. package/dist/components/exams/exam-template.utils.js +18 -1
  48. package/dist/components/exams/index.d.ts +1 -0
  49. package/dist/components/exams/index.js +19 -1
  50. package/dist/components/exams/rooms/StudentContestRoomsPageContainer.js +183 -1
  51. package/dist/components/exams/rooms/contest-rooms.utils.js +93 -1
  52. package/dist/components/exams/rooms/index.js +2 -1
  53. package/dist/components/exams/take/ExamTakingApiContext.js +25 -1
  54. package/dist/components/exams/take/ExamTakingPageContainer.js +955 -1
  55. package/dist/components/exams/take/GenericQuestionRenderer.js +14 -1
  56. package/dist/components/exams/take/components/QuestionRenderer.js +207 -1
  57. package/dist/components/exams/take/components/index.js +11 -1
  58. package/dist/components/exams/take/components/question-renderers/ArticlesViewer.js +8 -1
  59. package/dist/components/exams/take/components/question-renderers/MoversAnswerTheQuestionRenderer.js +30 -1
  60. package/dist/components/exams/take/components/question-renderers/MoversChooseAdjectiveRenderer.js +63 -1
  61. package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.js +136 -1
  62. package/dist/components/exams/take/components/question-renderers/MoversColoringRenderer.js +379 -1
  63. package/dist/components/exams/take/components/question-renderers/MoversCrossOutWordGroupRenderer.d.ts +20 -0
  64. package/dist/components/exams/take/components/question-renderers/MoversCrossOutWordGroupRenderer.js +141 -0
  65. package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.js +131 -1
  66. package/dist/components/exams/take/components/question-renderers/MoversGridFillRenderer.js +76 -1
  67. package/dist/components/exams/take/components/question-renderers/MoversLabelThePictureRenderer.js +68 -1
  68. package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.js +42 -1
  69. package/dist/components/exams/take/components/question-renderers/MoversMatchByWritingAnswerRenderer.js +131 -1
  70. package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.js +76 -1
  71. package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.js +68 -1
  72. package/dist/components/exams/take/components/question-renderers/MoversReadingPassageRenderer.js +62 -1
  73. package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.d.ts +1 -1
  74. package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.js +51 -1
  75. package/dist/components/exams/take/components/question-renderers/MoversWordFillParagraphRenderer.js +171 -1
  76. package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.js +198 -1
  77. package/dist/components/exams/take/components/question-renderers/MoversWordOrderAndMatchGroupRenderer.d.ts +15 -0
  78. package/dist/components/exams/take/components/question-renderers/MoversWordOrderAndMatchGroupRenderer.js +36 -0
  79. package/dist/components/exams/take/components/question-renderers/MoversWordOrderingRenderer.js +92 -1
  80. package/dist/components/exams/take/components/question-renderers/MoversWriteSentencesRenderer.js +11 -1
  81. package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.js +56 -1
  82. package/dist/components/exams/take/components/question-renderers/index.d.ts +2 -0
  83. package/dist/components/exams/take/components/question-renderers/index.js +25 -1
  84. package/dist/components/exams/take/components/speaking/SpeakingAudioPlayer.js +85 -1
  85. package/dist/components/exams/take/components/speaking/SpeakingContentFrame.js +10 -1
  86. package/dist/components/exams/take/components/speaking/SpeakingExamLayout.js +15 -1
  87. package/dist/components/exams/take/components/speaking/SpeakingHeader.js +6 -1
  88. package/dist/components/exams/take/components/speaking/SpeakingInstructionBar.js +8 -1
  89. package/dist/components/exams/take/components/speaking/SpeakingMicButton.js +59 -1
  90. package/dist/components/exams/take/components/speaking/SpeakingNavButton.js +7 -1
  91. package/dist/components/exams/take/components/speaking/SpeakingPartBadge.js +5 -1
  92. package/dist/components/exams/take/components/speaking/SpeakingReadDisplayedContent.module.css +120 -0
  93. package/dist/components/exams/take/components/speaking/SpeakingRecordingPreview.js +73 -1
  94. package/dist/components/exams/take/components/speaking/SpeakingReportErrorButton.js +8 -1
  95. package/dist/components/exams/take/components/speaking/SpeakingSpontaneousQA.module.css +344 -0
  96. package/dist/components/exams/take/components/speaking/SpeakingVideoIntro.js +32 -1
  97. package/dist/components/exams/take/components/speaking/index.js +1 -1
  98. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseAnswerGroupRenderer.js +63 -1
  99. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseObjectsRenderer.js +95 -1
  100. package/dist/components/exams/take/components/speaking/renderers/SpeakingCompareImagesRenderer.js +35 -1
  101. package/dist/components/exams/take/components/speaking/renderers/SpeakingConversationRenderer.js +147 -1
  102. package/dist/components/exams/take/components/speaking/renderers/SpeakingCueCardRenderer.js +232 -1
  103. package/dist/components/exams/take/components/speaking/renderers/SpeakingDescribeImageRenderer.js +193 -1
  104. package/dist/components/exams/take/components/speaking/renderers/SpeakingDragObjectsRenderer.js +155 -1
  105. package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.js +212 -1
  106. package/dist/components/exams/take/components/speaking/renderers/SpeakingInfoExchangeRenderer.js +77 -1
  107. package/dist/components/exams/take/components/speaking/renderers/SpeakingListenAndSpeakAnswerRenderer.js +64 -1
  108. package/dist/components/exams/take/components/speaking/renderers/SpeakingOddOneOutRenderer.js +69 -1
  109. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionListRenderer.js +64 -1
  110. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.js +92 -1
  111. package/dist/components/exams/take/components/speaking/renderers/SpeakingReadDisplayedContentRenderer.js +202 -1
  112. package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQARenderer.js +339 -1
  113. package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQaGroupRenderer.d.ts +19 -0
  114. package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQaGroupRenderer.js +76 -0
  115. package/dist/components/exams/take/components/speaking/renderers/SpeakingStoryImagesRenderer.js +56 -1
  116. package/dist/components/exams/take/components/speaking/renderers/SpontaneousQACambridgeLayout.d.ts +24 -0
  117. package/dist/components/exams/take/components/speaking/renderers/SpontaneousQACambridgeLayout.js +120 -0
  118. package/dist/components/exams/take/components/speaking/renderers/SpontaneousQAInlineAudioPlayer.d.ts +8 -0
  119. package/dist/components/exams/take/components/speaking/renderers/SpontaneousQAInlineAudioPlayer.js +94 -0
  120. package/dist/components/exams/take/components/speaking/renderers/SpontaneousQASummerSkyAudioPlayer.d.ts +8 -0
  121. package/dist/components/exams/take/components/speaking/renderers/SpontaneousQASummerSkyAudioPlayer.js +101 -0
  122. package/dist/components/exams/take/components/speaking/renderers/index.d.ts +1 -0
  123. package/dist/components/exams/take/components/speaking/renderers/index.js +14 -1
  124. package/dist/components/exams/take/exam-taking.utils.d.ts +13 -0
  125. package/dist/components/exams/take/exam-taking.utils.js +203 -1
  126. package/dist/components/exams/take/hooks/index.js +2 -1
  127. package/dist/components/exams/take/hooks/useAnswerAutosave.js +71 -1
  128. package/dist/components/exams/take/hooks/useAttemptSubmit.js +38 -1
  129. package/dist/components/exams/take/hooks/useAutoSave.js +83 -1
  130. package/dist/components/exams/take/hooks/useExamCountdown.js +35 -1
  131. package/dist/components/exams/take/hooks/useExamTimer.js +97 -1
  132. package/dist/components/exams/take/hooks/useProctoringCamera.js +118 -1
  133. package/dist/components/exams/take/hooks/useProctoringSnapshot.js +76 -1
  134. package/dist/components/exams/take/hooks/useSpeakingConversationAudio.js +178 -1
  135. package/dist/components/exams/take/hooks/useSpeakingNavigation.js +51 -1
  136. package/dist/components/exams/take/hooks/useSpeakingRecorder.js +406 -1
  137. package/dist/components/exams/take/hooks/useSpeakingRendererSetup.js +136 -1
  138. package/dist/components/exams/take/hooks/useSpontaneousQaGroupRecorder.d.ts +11 -0
  139. package/dist/components/exams/take/hooks/useSpontaneousQaGroupRecorder.js +352 -0
  140. package/dist/components/exams/take/hooks/useSpontaneousQaGroupRendererSetup.d.ts +42 -0
  141. package/dist/components/exams/take/hooks/useSpontaneousQaGroupRendererSetup.js +166 -0
  142. package/dist/components/exams/take/hooks/useToeicAudio.js +35 -1
  143. package/dist/components/exams/take/index.js +6 -1
  144. package/dist/components/exams/take/types/speaking-cue-card.types.js +1 -1
  145. package/dist/components/exams/take/types/speaking.types.js +7 -1
  146. package/dist/components/exams/take/types.js +4 -1
  147. package/dist/components/exams/take/utils/answer-transformers.js +452 -1
  148. package/dist/components/exams/take/utils/cambridge-yle-inline-speaking.d.ts +21 -0
  149. package/dist/components/exams/take/utils/cambridge-yle-inline-speaking.js +44 -0
  150. package/dist/components/exams/take/utils/coloring-assignments.js +40 -1
  151. package/dist/components/exams/take/utils/cross-out-word-group.transformer.d.ts +21 -0
  152. package/dist/components/exams/take/utils/cross-out-word-group.transformer.js +83 -0
  153. package/dist/components/exams/take/utils/question-transformers.d.ts +43 -2
  154. package/dist/components/exams/take/utils/question-transformers.js +1137 -1
  155. package/dist/components/features/exam-entry/entry-state-cards.js +19 -1
  156. package/dist/components/features/exam-entry/index.js +2 -1
  157. package/dist/components/features/exam-entry/themed/CambridgeYleWaitingRoom.js +121 -1
  158. package/dist/components/features/exam-entry/themed/ThemedWaitingRoom.js +37 -1
  159. package/dist/components/features/exam-entry/themed/ToeicWaitingRoom.js +15 -1
  160. package/dist/components/features/exam-entry/themed/cambridge-yle-waiting-parts.js +80 -1
  161. package/dist/components/features/exam-entry/themed/components/CloseButton.js +6 -1
  162. package/dist/components/features/exam-entry/themed/components/ExamInfoPanel.js +17 -1
  163. package/dist/components/features/exam-entry/themed/components/ModeSelector.js +6 -1
  164. package/dist/components/features/exam-entry/themed/components/StartButton.js +12 -1
  165. package/dist/components/features/exam-entry/themed/components/index.js +4 -1
  166. package/dist/components/features/exam-entry/themed/index.js +3 -1
  167. package/dist/components/index.d.ts +1 -0
  168. package/dist/components/index.js +43 -1
  169. package/dist/components/questions/_shared/config/question-types.config.js +362 -1
  170. package/dist/components/questions/_shared/constants/color-palette.js +21 -1
  171. package/dist/components/questions/_shared/hooks/useAnswerGroupQuestionGroup.js +105 -1
  172. package/dist/components/questions/_shared/hooks/useBasicQuestionGroup.js +222 -1
  173. package/dist/components/questions/_shared/hooks/useCompareImagesGroup.js +140 -1
  174. package/dist/components/questions/_shared/hooks/useImageQuestionGroup.js +123 -1
  175. package/dist/components/questions/_shared/hooks/useInfoExchangeGroup.js +50 -1
  176. package/dist/components/questions/_shared/hooks/useQuestionFormState.js +54 -1
  177. package/dist/components/questions/_shared/hooks/useQuestionInitialization.js +123 -1
  178. package/dist/components/questions/_shared/hooks/useQuestionListGroup.js +121 -1
  179. package/dist/components/questions/_shared/hooks/useQuestionOnChange.js +70 -1
  180. package/dist/components/questions/_shared/hooks/useSceneQuestionGroup.js +194 -1
  181. package/dist/components/questions/_shared/index.js +7 -1
  182. package/dist/components/questions/_shared/types/answer-the-question.type.js +1 -1
  183. package/dist/components/questions/_shared/types/arrange-letters-into-words.type.js +1 -1
  184. package/dist/components/questions/_shared/types/choose-correct-adjective.type.js +3 -1
  185. package/dist/components/questions/_shared/types/choose-the-correct-answer-group.type.d.ts +1 -0
  186. package/dist/components/questions/_shared/types/choose-the-correct-answer-group.type.js +1 -1
  187. package/dist/components/questions/_shared/types/color-region.config.js +1 -1
  188. package/dist/components/questions/_shared/types/cross-out-word-group.type.d.ts +2 -0
  189. package/dist/components/questions/_shared/types/cross-out-word-group.type.js +1 -1
  190. package/dist/components/questions/_shared/types/fill-in-blank.type.js +1 -1
  191. package/dist/components/questions/_shared/types/fill-missing-words-in-grid.type.js +1 -1
  192. package/dist/components/questions/_shared/types/gn-speaking-interview.type.js +1 -1
  193. package/dist/components/questions/_shared/types/index.d.ts +1 -0
  194. package/dist/components/questions/_shared/types/index.js +14 -1
  195. package/dist/components/questions/_shared/types/label-the-picture.type.js +1 -1
  196. package/dist/components/questions/_shared/types/listen-and-choose-from-answer-group.type.js +1 -1
  197. package/dist/components/questions/_shared/types/listen-and-choose-objects-in-scene.type.js +1 -1
  198. package/dist/components/questions/_shared/types/listen-and-drag-objects-into-scene.type.js +1 -1
  199. package/dist/components/questions/_shared/types/listen-and-speak-answer.type.js +1 -1
  200. package/dist/components/questions/_shared/types/listen-and-speak-compare-images.type.js +1 -1
  201. package/dist/components/questions/_shared/types/listen-and-speak-image-group.type.js +1 -1
  202. package/dist/components/questions/_shared/types/listen-and-speak-info-exchange.type.js +1 -1
  203. package/dist/components/questions/_shared/types/listen-and-speak-odd-one-out.type.js +3 -1
  204. package/dist/components/questions/_shared/types/listen-and-speak-question-list.type.js +1 -1
  205. package/dist/components/questions/_shared/types/listen-and-speak-with-story-images.type.js +3 -1
  206. package/dist/components/questions/_shared/types/listen-and-tick-answer.type.js +1 -1
  207. package/dist/components/questions/_shared/types/listening-drawline.type.js +1 -1
  208. package/dist/components/questions/_shared/types/look-and-choose-answer.type.js +1 -1
  209. package/dist/components/questions/_shared/types/look-picture-fill-word-hint.type.js +1 -1
  210. package/dist/components/questions/_shared/types/match-by-writing-answer.type.js +1 -1
  211. package/dist/components/questions/_shared/types/multiple-choice.type.d.ts +5 -0
  212. package/dist/components/questions/_shared/types/multiple-choice.type.js +1 -1
  213. package/dist/components/questions/_shared/types/question-group.type.js +11 -1
  214. package/dist/components/questions/_shared/types/read-and-color-objects.type.js +1 -1
  215. package/dist/components/questions/_shared/types/read-displayed-content.type.js +1 -1
  216. package/dist/components/questions/_shared/types/read-passage-and-answer-questions.type.js +1 -1
  217. package/dist/components/questions/_shared/types/speaking-describe-image.type.js +1 -1
  218. package/dist/components/questions/_shared/types/spontaneous-qa-group.type.d.ts +37 -0
  219. package/dist/components/questions/_shared/types/spontaneous-qa-group.type.js +1 -0
  220. package/dist/components/questions/_shared/types/spontaneous-qa.type.js +1 -1
  221. package/dist/components/questions/_shared/types/true-false-group.type.js +1 -1
  222. package/dist/components/questions/_shared/types/word-fill-paragraph-with-options.type.js +1 -1
  223. package/dist/components/questions/_shared/types/word-fill-paragraph.type.js +1 -1
  224. package/dist/components/questions/_shared/types/word-fill-structured-form.type.d.ts +20 -11
  225. package/dist/components/questions/_shared/types/word-fill-structured-form.type.js +1 -1
  226. package/dist/components/questions/_shared/types/word-order-and-match-group.type.d.ts +38 -0
  227. package/dist/components/questions/_shared/types/word-order-and-match-group.type.js +1 -0
  228. package/dist/components/questions/_shared/types/word-ordering.type.js +1 -1
  229. package/dist/components/questions/_shared/types/write-a-short-letter.type.js +1 -1
  230. package/dist/components/questions/_shared/types/write-correct-verb-form.type.js +3 -1
  231. package/dist/components/questions/_shared/types/write-sentences.type.js +1 -1
  232. package/dist/components/questions/_shared/types/write-short-paragraph.type.js +1 -1
  233. package/dist/components/questions/_shared/utils/answer-builder.js +79 -1
  234. package/dist/components/questions/_shared/utils/createColorRegionRegistration.js +39 -1
  235. package/dist/components/questions/_shared/utils/id-generator.js +3 -1
  236. package/dist/components/questions/_shared/utils/parseFillBlankStem.d.ts +30 -0
  237. package/dist/components/questions/_shared/utils/parseFillBlankStem.js +69 -0
  238. package/dist/components/questions/_shared/utils/question-validation.js +21 -1
  239. package/dist/components/questions/components/ColorNode.js +85 -1
  240. package/dist/components/questions/components/ColorRegionClient.js +545 -1
  241. package/dist/components/questions/components/ColorRegionCreator.js +420 -1
  242. package/dist/components/questions/components/ColorRegionNode.js +59 -1
  243. package/dist/components/questions/components/CreatorGuide.js +103 -1
  244. package/dist/components/questions/components/NameNode.js +26 -1
  245. package/dist/components/questions/components/QuestionBankOption.js +46 -1
  246. package/dist/components/questions/components/QuestionBasicInfoForm.js +9 -1
  247. package/dist/components/questions/components/QuestionCommonFields.js +33 -1
  248. package/dist/components/questions/components/QuestionSearchDropdown.js +258 -1
  249. package/dist/components/questions/components/QuestionTypeSelector.js +32 -1
  250. package/dist/components/questions/components/QuestionTypeSpecificForms.js +6 -1
  251. package/dist/components/questions/components/RegionNode.js +94 -1
  252. package/dist/components/questions/components/index.js +14 -1
  253. package/dist/components/questions/creator/QuestionCreator.js +90 -1
  254. package/dist/components/questions/creator/QuestionGroupCreator.js +119 -1
  255. package/dist/components/questions/creator/dedicated-component-router.js +79 -1
  256. package/dist/components/questions/creator/index.js +3 -1
  257. package/dist/components/questions/creator/question-type-registry.js +90 -1
  258. package/dist/components/questions/groups/ArticlesGroupCard.js +121 -1
  259. package/dist/components/questions/groups/BasicQuestionGroupCard.js +50 -1
  260. package/dist/components/questions/groups/DocumentGroupCard.js +114 -1
  261. package/dist/components/questions/groups/MatchAnswerGroupCard.js +25 -1
  262. package/dist/components/questions/index.d.ts +1 -0
  263. package/dist/components/questions/index.js +11 -1
  264. package/dist/components/questions/question-bank/EditQuestionBankDialog.d.ts +2 -0
  265. package/dist/components/questions/question-bank/EditQuestionBankDialog.js +114 -0
  266. package/dist/components/questions/question-bank/QuestionEditorRenderer.d.ts +23 -0
  267. package/dist/components/questions/question-bank/QuestionEditorRenderer.js +75 -0
  268. package/dist/components/questions/question-bank/difficulty.d.ts +15 -0
  269. package/dist/components/questions/question-bank/difficulty.js +33 -0
  270. package/dist/components/questions/question-bank/editor-adapters/choice-adapters.d.ts +5 -0
  271. package/dist/components/questions/question-bank/editor-adapters/choice-adapters.js +101 -0
  272. package/dist/components/questions/question-bank/editor-adapters/index.d.ts +5 -0
  273. package/dist/components/questions/question-bank/editor-adapters/index.js +4 -0
  274. package/dist/components/questions/question-bank/editor-adapters/media-adapters.d.ts +6 -0
  275. package/dist/components/questions/question-bank/editor-adapters/media-adapters.js +140 -0
  276. package/dist/components/questions/question-bank/editor-adapters/types.d.ts +1 -0
  277. package/dist/components/questions/question-bank/editor-adapters/types.js +1 -0
  278. package/dist/components/questions/question-bank/editor-adapters/unsupported-fallback.d.ts +8 -0
  279. package/dist/components/questions/question-bank/editor-adapters/unsupported-fallback.js +6 -0
  280. package/dist/components/questions/question-bank/editor-adapters/writing-adapters.d.ts +5 -0
  281. package/dist/components/questions/question-bank/editor-adapters/writing-adapters.js +114 -0
  282. package/dist/components/questions/question-bank/index.d.ts +4 -0
  283. package/dist/components/questions/question-bank/index.js +3 -0
  284. package/dist/components/questions/question-bank/types.d.ts +59 -0
  285. package/dist/components/questions/question-bank/types.js +1 -0
  286. package/dist/components/questions/types/answer-the-question/AnswerTheQuestionClient.js +37 -1
  287. package/dist/components/questions/types/answer-the-question/AnswerTheQuestionCreator.js +351 -1
  288. package/dist/components/questions/types/answer-the-question/register.js +67 -1
  289. package/dist/components/questions/types/answer-the-question/transform.js +36 -1
  290. package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsClient.js +141 -1
  291. package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsCreator.js +118 -1
  292. package/dist/components/questions/types/arrange-letters-into-words/index.js +2 -1
  293. package/dist/components/questions/types/arrange-letters-into-words/register.js +4 -1
  294. package/dist/components/questions/types/arrange-letters-into-words/transform.js +24 -1
  295. package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveClient.js +74 -1
  296. package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveCreator.js +169 -1
  297. package/dist/components/questions/types/choose-correct-adjective/index.js +2 -1
  298. package/dist/components/questions/types/choose-correct-adjective/register.js +55 -1
  299. package/dist/components/questions/types/choose-correct-adjective/transform.js +16 -1
  300. package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerClient.js +149 -1
  301. package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerCreator.js +568 -1
  302. package/dist/components/questions/types/choose-the-correct-answer/index.js +3 -1
  303. package/dist/components/questions/types/choose-the-correct-answer/normalize.d.ts +9 -0
  304. package/dist/components/questions/types/choose-the-correct-answer/normalize.js +88 -1
  305. package/dist/components/questions/types/choose-the-correct-answer/register.js +99 -1
  306. package/dist/components/questions/types/choose-the-correct-answer/transform.js +70 -1
  307. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupClient.js +22 -1
  308. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupCreator.js +163 -1
  309. package/dist/components/questions/types/choose-the-correct-answer-group/index.js +3 -1
  310. package/dist/components/questions/types/choose-the-correct-answer-group/map-choose-the-correct-answer-group-data.js +94 -1
  311. package/dist/components/questions/types/choose-the-correct-answer-group/register.js +36 -1
  312. package/dist/components/questions/types/choose-the-correct-answer-group/transform.js +55 -1
  313. package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupClient.js +27 -1
  314. package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupCreator.js +231 -1
  315. package/dist/components/questions/types/cross-out-word-group/index.js +5 -1
  316. package/dist/components/questions/types/cross-out-word-group/map-cross-out-word-group-data.d.ts +1 -1
  317. package/dist/components/questions/types/cross-out-word-group/map-cross-out-word-group-data.js +110 -1
  318. package/dist/components/questions/types/cross-out-word-group/register.js +36 -1
  319. package/dist/components/questions/types/cross-out-word-group/transform.js +67 -1
  320. package/dist/components/questions/types/fill-in-blank/FillInBlankClient.js +275 -1
  321. package/dist/components/questions/types/fill-in-blank/FillInBlankCreator.js +464 -1
  322. package/dist/components/questions/types/fill-in-blank/index.js +2 -1
  323. package/dist/components/questions/types/fill-in-blank/register.js +148 -1
  324. package/dist/components/questions/types/fill-in-blank/transform.js +88 -1
  325. package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridClient.js +117 -1
  326. package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridCreator.js +671 -1
  327. package/dist/components/questions/types/fill-missing-words-in-grid/index.js +2 -1
  328. package/dist/components/questions/types/fill-missing-words-in-grid/register.js +37 -1
  329. package/dist/components/questions/types/fill-missing-words-in-grid/transform.js +15 -1
  330. package/dist/components/questions/types/gn-speaking-interview/GNSpeakingInterviewCreator.js +262 -1
  331. package/dist/components/questions/types/gn-speaking-interview/register.js +121 -1
  332. package/dist/components/questions/types/gn-speaking-interview/transform.js +48 -1
  333. package/dist/components/questions/types/image-object-matching/ImageObjectMatchingClient.js +16 -1
  334. package/dist/components/questions/types/image-object-matching/ImageObjectMatchingCreator.js +27 -1
  335. package/dist/components/questions/types/image-object-matching/index.js +2 -1
  336. package/dist/components/questions/types/image-object-matching/register.js +3 -1
  337. package/dist/components/questions/types/image-object-matching/transform.js +2 -1
  338. package/dist/components/questions/types/label-the-picture/LabelThePictureClient.js +102 -1
  339. package/dist/components/questions/types/label-the-picture/LabelThePictureCreator.js +344 -1
  340. package/dist/components/questions/types/label-the-picture/index.js +2 -1
  341. package/dist/components/questions/types/label-the-picture/register.js +54 -1
  342. package/dist/components/questions/types/label-the-picture/transform.js +28 -1
  343. package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupClient.js +78 -1
  344. package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupCreator.js +232 -1
  345. package/dist/components/questions/types/listen-and-choose-from-answer-group/index.js +2 -1
  346. package/dist/components/questions/types/listen-and-choose-from-answer-group/register.js +82 -1
  347. package/dist/components/questions/types/listen-and-choose-from-answer-group/transform.js +27 -1
  348. package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneClient.js +70 -1
  349. package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneCreator.js +386 -1
  350. package/dist/components/questions/types/listen-and-choose-objects-in-scene/index.js +2 -1
  351. package/dist/components/questions/types/listen-and-choose-objects-in-scene/register.js +100 -1
  352. package/dist/components/questions/types/listen-and-choose-objects-in-scene/transform.js +33 -1
  353. package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneClient.js +106 -1
  354. package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneCreator.js +457 -1
  355. package/dist/components/questions/types/listen-and-drag-objects-into-scene/index.js +2 -1
  356. package/dist/components/questions/types/listen-and-drag-objects-into-scene/register.js +110 -1
  357. package/dist/components/questions/types/listen-and-drag-objects-into-scene/transform.js +35 -1
  358. package/dist/components/questions/types/listen-and-speak-answer/ArrowIndicator.js +8 -1
  359. package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerClient.js +22 -1
  360. package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerCreator.js +291 -1
  361. package/dist/components/questions/types/listen-and-speak-answer/index.js +2 -1
  362. package/dist/components/questions/types/listen-and-speak-answer/register.js +84 -1
  363. package/dist/components/questions/types/listen-and-speak-answer/transform.js +27 -1
  364. package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesClient.js +32 -1
  365. package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesCreator.js +295 -1
  366. package/dist/components/questions/types/listen-and-speak-compare-images/register.js +79 -1
  367. package/dist/components/questions/types/listen-and-speak-compare-images/transform.js +27 -1
  368. package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupClient.js +34 -1
  369. package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupCreator.js +285 -1
  370. package/dist/components/questions/types/listen-and-speak-image-group/register.js +81 -1
  371. package/dist/components/questions/types/listen-and-speak-image-group/transform.js +26 -1
  372. package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeClient.js +38 -1
  373. package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeCreator.js +385 -1
  374. package/dist/components/questions/types/listen-and-speak-info-exchange/register.js +87 -1
  375. package/dist/components/questions/types/listen-and-speak-info-exchange/transform.js +32 -1
  376. package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutClient.js +26 -1
  377. package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutCreator.js +247 -1
  378. package/dist/components/questions/types/listen-and-speak-odd-one-out/register.js +59 -1
  379. package/dist/components/questions/types/listen-and-speak-odd-one-out/transform.js +18 -1
  380. package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListClient.js +26 -1
  381. package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListCreator.js +256 -1
  382. package/dist/components/questions/types/listen-and-speak-question-list/register.js +81 -1
  383. package/dist/components/questions/types/listen-and-speak-question-list/transform.js +26 -1
  384. package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesClient.js +26 -1
  385. package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesCreator.js +230 -1
  386. package/dist/components/questions/types/listen-and-speak-with-story-images/register.js +56 -1
  387. package/dist/components/questions/types/listen-and-speak-with-story-images/transform.js +16 -1
  388. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerClient.js +72 -1
  389. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerCreator.js +230 -1
  390. package/dist/components/questions/types/look-picture-choose-correct-answer/index.js +1 -1
  391. package/dist/components/questions/types/look-picture-choose-correct-answer/register.js +66 -1
  392. package/dist/components/questions/types/look-picture-choose-correct-answer/transform.js +42 -1
  393. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerClient.js +96 -1
  394. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerCreator.js +238 -1
  395. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/index.js +2 -1
  396. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/register.js +76 -1
  397. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/transform.js +19 -1
  398. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintClient.js +134 -1
  399. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintCreator.js +617 -1
  400. package/dist/components/questions/types/look-picture-fill-word-hint/index.js +2 -1
  401. package/dist/components/questions/types/look-picture-fill-word-hint/register.js +82 -1
  402. package/dist/components/questions/types/look-picture-fill-word-hint/transform.js +29 -1
  403. package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerClient.js +38 -1
  404. package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerCreator.js +359 -1
  405. package/dist/components/questions/types/match-by-writing-answer/index.js +3 -1
  406. package/dist/components/questions/types/match-by-writing-answer/register.js +58 -1
  407. package/dist/components/questions/types/match-by-writing-answer/transform.js +61 -1
  408. package/dist/components/questions/types/read-and-color-objects/ReadAndColorObjectsClient.js +16 -1
  409. package/dist/components/questions/types/read-and-color-objects/ReadAndColorObjectsCreator.js +23 -1
  410. package/dist/components/questions/types/read-and-color-objects/index.js +2 -1
  411. package/dist/components/questions/types/read-and-color-objects/register.js +3 -1
  412. package/dist/components/questions/types/read-and-color-objects/transform.js +36 -1
  413. package/dist/components/questions/types/read-displayed-content/ReadDisplayedContentCreator.js +125 -1
  414. package/dist/components/questions/types/read-displayed-content/register.js +64 -1
  415. package/dist/components/questions/types/read-displayed-content/transform.js +12 -1
  416. package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsClient.js +65 -1
  417. package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsCreator.js +511 -1
  418. package/dist/components/questions/types/read-passage-and-answer-questions/index.js +2 -1
  419. package/dist/components/questions/types/read-passage-and-answer-questions/register.js +58 -1
  420. package/dist/components/questions/types/read-passage-and-answer-questions/transform.js +28 -1
  421. package/dist/components/questions/types/speaking-conversation/SpeakingConversationCreator.js +373 -1
  422. package/dist/components/questions/types/speaking-conversation/SpeakingConversationPreviewClient.js +41 -1
  423. package/dist/components/questions/types/speaking-conversation/register.js +110 -1
  424. package/dist/components/questions/types/speaking-conversation/transform.js +34 -1
  425. package/dist/components/questions/types/speaking-cue-card/SpeakingCueCardCreator.js +74 -1
  426. package/dist/components/questions/types/speaking-cue-card/register.js +52 -1
  427. package/dist/components/questions/types/speaking-cue-card/transform.js +12 -1
  428. package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageClient.js +10 -1
  429. package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageCreator.js +161 -1
  430. package/dist/components/questions/types/speaking-describe-image/index.js +2 -1
  431. package/dist/components/questions/types/speaking-describe-image/register.js +69 -1
  432. package/dist/components/questions/types/speaking-describe-image/transform.js +16 -1
  433. package/dist/components/questions/types/spontaneous-qa/SpontaneousQACreator.js +234 -1
  434. package/dist/components/questions/types/spontaneous-qa/register.js +93 -1
  435. package/dist/components/questions/types/spontaneous-qa/transform.js +34 -1
  436. package/dist/components/questions/types/spontaneous-qa-group/SpontaneousQaGroupClient.d.ts +2 -0
  437. package/dist/components/questions/types/spontaneous-qa-group/SpontaneousQaGroupClient.js +9 -0
  438. package/dist/components/questions/types/spontaneous-qa-group/SpontaneousQaGroupCreator.d.ts +2 -0
  439. package/dist/components/questions/types/spontaneous-qa-group/SpontaneousQaGroupCreator.js +179 -0
  440. package/dist/components/questions/types/spontaneous-qa-group/creator-helpers.d.ts +5 -0
  441. package/dist/components/questions/types/spontaneous-qa-group/creator-helpers.js +43 -0
  442. package/dist/components/questions/types/spontaneous-qa-group/flatten.d.ts +14 -0
  443. package/dist/components/questions/types/spontaneous-qa-group/flatten.js +69 -0
  444. package/dist/components/questions/types/spontaneous-qa-group/index.d.ts +2 -0
  445. package/dist/components/questions/types/spontaneous-qa-group/index.js +2 -0
  446. package/dist/components/questions/types/spontaneous-qa-group/register.d.ts +2 -0
  447. package/dist/components/questions/types/spontaneous-qa-group/register.js +139 -0
  448. package/dist/components/questions/types/spontaneous-qa-group/transform.d.ts +2 -0
  449. package/dist/components/questions/types/spontaneous-qa-group/transform.js +52 -0
  450. package/dist/components/questions/types/true-false/TrueFalseClient.js +75 -1
  451. package/dist/components/questions/types/true-false/TrueFalseCreator.js +244 -1
  452. package/dist/components/questions/types/true-false/index.js +2 -1
  453. package/dist/components/questions/types/true-false/register.js +77 -1
  454. package/dist/components/questions/types/true-false/transform.js +32 -1
  455. package/dist/components/questions/types/true-false-group/TrueFalseGroupClient.js +25 -1
  456. package/dist/components/questions/types/true-false-group/TrueFalseGroupCreator.js +129 -1
  457. package/dist/components/questions/types/true-false-group/index.js +5 -1
  458. package/dist/components/questions/types/true-false-group/map-true-false-group-data.js +69 -1
  459. package/dist/components/questions/types/true-false-group/register.js +36 -1
  460. package/dist/components/questions/types/true-false-group/transform.js +43 -1
  461. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphClient.js +233 -1
  462. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphCreator.js +631 -1
  463. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphWrapper.js +28 -1
  464. package/dist/components/questions/types/word-fill-paragraph/index.js +2 -1
  465. package/dist/components/questions/types/word-fill-paragraph/register.js +136 -1
  466. package/dist/components/questions/types/word-fill-paragraph/transform.js +56 -1
  467. package/dist/components/questions/types/word-fill-structured-form/WfsfWordBankEditor.js +86 -1
  468. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormClient.js +246 -1
  469. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormCreator.d.ts +2 -0
  470. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormCreator.js +484 -1
  471. package/dist/components/questions/types/word-fill-structured-form/index.js +3 -1
  472. package/dist/components/questions/types/word-fill-structured-form/map-wfsf-question-data.js +113 -1
  473. package/dist/components/questions/types/word-fill-structured-form/register.js +36 -1
  474. package/dist/components/questions/types/word-fill-structured-form/transform.js +77 -1
  475. package/dist/components/questions/types/word-fill-structured-form/wfsf-word-bank.utils.js +110 -1
  476. package/dist/components/questions/types/word-order-and-match-group/WordOrderAndMatchGroupClient.d.ts +3 -0
  477. package/dist/components/questions/types/word-order-and-match-group/WordOrderAndMatchGroupClient.js +190 -0
  478. package/dist/components/questions/types/word-order-and-match-group/WordOrderAndMatchGroupCreator.d.ts +3 -0
  479. package/dist/components/questions/types/word-order-and-match-group/WordOrderAndMatchGroupCreator.js +182 -0
  480. package/dist/components/questions/types/word-order-and-match-group/index.d.ts +4 -0
  481. package/dist/components/questions/types/word-order-and-match-group/index.js +4 -0
  482. package/dist/components/questions/types/word-order-and-match-group/register.d.ts +2 -0
  483. package/dist/components/questions/types/word-order-and-match-group/register.js +121 -0
  484. package/dist/components/questions/types/word-order-and-match-group/transform.d.ts +2 -0
  485. package/dist/components/questions/types/word-order-and-match-group/transform.js +70 -0
  486. package/dist/components/questions/types/word-ordering/WordOrderingClient.js +84 -1
  487. package/dist/components/questions/types/word-ordering/WordOrderingCreator.js +192 -1
  488. package/dist/components/questions/types/word-ordering/index.js +2 -1
  489. package/dist/components/questions/types/word-ordering/register.js +46 -1
  490. package/dist/components/questions/types/word-ordering/transform.js +24 -1
  491. package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterClient.js +99 -1
  492. package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterCreator.js +320 -1
  493. package/dist/components/questions/types/write-a-short-letter/index.js +2 -1
  494. package/dist/components/questions/types/write-a-short-letter/register.js +68 -1
  495. package/dist/components/questions/types/write-a-short-letter/transform.js +25 -1
  496. package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormClient.js +61 -1
  497. package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormCreator.js +196 -1
  498. package/dist/components/questions/types/write-correct-verb-form/index.js +2 -1
  499. package/dist/components/questions/types/write-correct-verb-form/register.js +62 -1
  500. package/dist/components/questions/types/write-correct-verb-form/transform.js +17 -1
  501. package/dist/components/questions/types/write-sentences/WriteSentencesClient.js +22 -1
  502. package/dist/components/questions/types/write-sentences/WriteSentencesCreator.js +174 -1
  503. package/dist/components/questions/types/write-sentences/index.js +2 -1
  504. package/dist/components/questions/types/write-sentences/register.js +58 -1
  505. package/dist/components/questions/types/write-sentences/transform.js +28 -1
  506. package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphClient.js +96 -1
  507. package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphCreator.js +161 -1
  508. package/dist/components/questions/types/write-short-paragraph/index.js +2 -1
  509. package/dist/components/questions/types/write-short-paragraph/register.js +4 -1
  510. package/dist/components/questions/types/write-short-paragraph/transform.js +21 -1
  511. package/dist/components/questions/viewer/ChooseTheCorrectAnswerGroupViewer.js +11 -1
  512. package/dist/components/questions/viewer/CrossOutWordGroupViewer.js +8 -1
  513. package/dist/components/questions/viewer/QuestionGroupViewer.js +36 -1
  514. package/dist/components/questions/viewer/QuestionViewer.js +692 -1
  515. package/dist/components/questions/viewer/SpontaneousQaGroupViewer.d.ts +2 -1
  516. package/dist/components/questions/viewer/SpontaneousQaGroupViewer.js +82 -1
  517. package/dist/components/questions/viewer/TrueFalseGroupViewer.js +11 -1
  518. package/dist/components/questions/viewer/WordFillStructuredFormViewer.js +14 -1
  519. package/dist/components/questions/viewer/WordOrderAndMatchGroupViewer.d.ts +3 -1
  520. package/dist/components/questions/viewer/WordOrderAndMatchGroupViewer.js +95 -1
  521. package/dist/components/questions/viewer/index.js +8 -1
  522. package/dist/components/results/ResultReviewPageContainer.js +220 -1
  523. package/dist/components/results/ReviewQuestionRenderer.js +55 -1
  524. package/dist/components/results/hooks/useResultReviewPolling.js +76 -1
  525. package/dist/components/results/index.js +22 -1
  526. package/dist/components/results/renderers/QuestionExplanations.js +19 -1
  527. package/dist/components/results/renderers/ReviewChooseAdjectiveRenderer.js +94 -1
  528. package/dist/components/results/renderers/ReviewChooseBestAnswerRenderer.js +75 -1
  529. package/dist/components/results/renderers/ReviewColoringRenderer.js +110 -1
  530. package/dist/components/results/renderers/ReviewListenAndWriteRenderer.js +48 -1
  531. package/dist/components/results/renderers/ReviewListenChooseAnswerGroupRenderer.js +87 -1
  532. package/dist/components/results/renderers/ReviewListenChooseObjectsRenderer.js +104 -1
  533. package/dist/components/results/renderers/ReviewListenDragObjectsRenderer.js +123 -1
  534. package/dist/components/results/renderers/ReviewListeningHeader.js +104 -1
  535. package/dist/components/results/renderers/ReviewSpeakingAIPanel.js +116 -1
  536. package/dist/components/results/renderers/ReviewSpeakingMedia.js +48 -1
  537. package/dist/components/results/renderers/ReviewSpeakingQuestionItem.js +42 -1
  538. package/dist/components/results/renderers/ReviewSpeakingRenderer.js +12 -1
  539. package/dist/components/results/renderers/ReviewSpeakingRenderer.types.js +85 -1
  540. package/dist/components/results/renderers/review-question-body-dedicated.js +104 -1
  541. package/dist/components/results/renderers/review-question-body-movers.js +148 -1
  542. package/dist/components/results/renderers/review-speaking-map.js +226 -1
  543. package/dist/components/results/renderers/review-spontaneous-qa-group.d.ts +4 -0
  544. package/dist/components/results/renderers/review-spontaneous-qa-group.js +74 -0
  545. package/dist/components/results/report/BadgeTitle.js +5 -1
  546. package/dist/components/results/report/ExamSkillRow.js +20 -1
  547. package/dist/components/results/report/OceanEduExamReport.js +58 -1
  548. package/dist/components/results/report/OceanEduSpeakingReport.js +62 -1
  549. package/dist/components/results/report/OverallAssessmentSection.js +17 -1
  550. package/dist/components/results/report/ResultErrorState.js +18 -1
  551. package/dist/components/results/report/ResultLoadingState.js +10 -1
  552. package/dist/components/results/report/ResultNotPublicState.js +27 -1
  553. package/dist/components/results/report/SpeakingReportParts.js +14 -1
  554. package/dist/components/results/report/SpeakingReportShared.js +86 -1
  555. package/dist/components/results/report/SpeakingRubricSection.js +171 -1
  556. package/dist/components/results/report/speaking-report.utils.js +198 -1
  557. package/dist/components/results/result-review.utils.js +6 -1
  558. package/dist/components/results/review-data.js +222 -1
  559. package/dist/components/results/review-renderer.utils.js +97 -1
  560. package/dist/components/results/review-status.utils.js +36 -1
  561. package/dist/components/results/review-types.js +1 -1
  562. package/dist/components/results/speaking/SpeakingResultAudioPlayer.js +77 -1
  563. package/dist/components/results/speaking/SpeakingReviewResult.js +48 -1
  564. package/dist/components/results/utils/review-score.utils.js +72 -1
  565. package/dist/components/results/utils/speaking-summary.js +224 -1
  566. package/dist/components/results/utils/transform-speaking-review.js +183 -1
  567. package/dist/components/shared/RichTextEditor.d.ts +9 -0
  568. package/dist/components/shared/RichTextEditor.js +47 -0
  569. package/dist/components/shared/audio/SpeakingAudioPlayer.js +100 -1
  570. package/dist/components/themes/cambridge-yle/CambridgeYleAudioPlayer.js +140 -1
  571. package/dist/components/themes/cambridge-yle/CambridgeYleBottomNav.js +10 -1
  572. package/dist/components/themes/cambridge-yle/CambridgeYleExamLayout.d.ts +1 -1
  573. package/dist/components/themes/cambridge-yle/CambridgeYleExamLayout.js +18 -1
  574. package/dist/components/themes/cambridge-yle/CambridgeYleExampleText.js +11 -1
  575. package/dist/components/themes/cambridge-yle/CambridgeYleHeader.js +11 -1
  576. package/dist/components/themes/cambridge-yle/CambridgeYleInstructionBanner.d.ts +2 -1
  577. package/dist/components/themes/cambridge-yle/CambridgeYleInstructionBanner.js +19 -1
  578. package/dist/components/themes/cambridge-yle/CambridgeYleNavButton.js +13 -1
  579. package/dist/components/themes/cambridge-yle/CambridgeYlePartBanner.d.ts +1 -1
  580. package/dist/components/themes/cambridge-yle/CambridgeYlePartBanner.js +3 -1
  581. package/dist/components/themes/cambridge-yle/CambridgeYleProgressBar.js +6 -1
  582. package/dist/components/themes/cambridge-yle/CambridgeYleQuestionCard.js +5 -1
  583. package/dist/components/themes/cambridge-yle/CambridgeYleQuestionCardFullWidth.js +9 -1
  584. package/dist/components/themes/cambridge-yle/CambridgeYleSidebar.d.ts +2 -1
  585. package/dist/components/themes/cambridge-yle/CambridgeYleSidebar.js +61 -1
  586. package/dist/components/themes/cambridge-yle/CambridgeYleTimer.d.ts +1 -1
  587. package/dist/components/themes/cambridge-yle/CambridgeYleTimer.js +25 -1
  588. package/dist/components/themes/cambridge-yle/index.js +13 -1
  589. package/dist/components/themes/english-certification/EcAnswerTheQuestion.js +25 -1
  590. package/dist/components/themes/english-certification/EcMatchByWritingAnswer.js +89 -1
  591. package/dist/components/themes/english-certification/EcWordFillParagraph.js +56 -1
  592. package/dist/components/themes/english-certification/EcWordFillStructuredForm.js +192 -1
  593. package/dist/components/themes/english-certification/EcWritingTask.js +60 -1
  594. package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.js +108 -1
  595. package/dist/components/themes/english-certification/EnglishCertificationBrand.js +11 -1
  596. package/dist/components/themes/english-certification/EnglishCertificationExamLayout.js +34 -1
  597. package/dist/components/themes/english-certification/EnglishCertificationFlagButton.js +15 -1
  598. package/dist/components/themes/english-certification/EnglishCertificationFooterBar.js +19 -1
  599. package/dist/components/themes/english-certification/EnglishCertificationGroupedQuestion.js +166 -1
  600. package/dist/components/themes/english-certification/EnglishCertificationHeader.js +31 -1
  601. package/dist/components/themes/english-certification/EnglishCertificationInstructionBanner.js +79 -1
  602. package/dist/components/themes/english-certification/EnglishCertificationNavigationPanel.js +71 -1
  603. package/dist/components/themes/english-certification/EnglishCertificationOptionSelector.js +79 -1
  604. package/dist/components/themes/english-certification/EnglishCertificationPartHeader.js +47 -1
  605. package/dist/components/themes/english-certification/EnglishCertificationPassagePanel.js +77 -1
  606. package/dist/components/themes/english-certification/EnglishCertificationQuestionCard.js +25 -1
  607. package/dist/components/themes/english-certification/EnglishCertificationQuestionItem.js +36 -1
  608. package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.js +81 -1
  609. package/dist/components/themes/english-certification/EnglishCertificationReadingSection.js +95 -1
  610. package/dist/components/themes/english-certification/EnglishCertificationSingleQuestion.js +18 -1
  611. package/dist/components/themes/english-certification/EnglishCertificationSingleQuestionList.js +32 -1
  612. package/dist/components/themes/english-certification/english-cert-scroll.js +163 -1
  613. package/dist/components/themes/english-certification/english-certification-theme.js +58 -1
  614. package/dist/components/themes/english-certification/grouped-question-utils.js +243 -1
  615. package/dist/components/themes/english-certification/index.js +24 -1
  616. package/dist/components/themes/index.js +25 -1
  617. package/dist/components/themes/summer-sky/SummerSkyAudioPlayer.js +170 -1
  618. package/dist/components/themes/summer-sky/SummerSkyExitModal.js +21 -1
  619. package/dist/components/themes/summer-sky/SummerSkyLayout.js +221 -1
  620. package/dist/components/themes/summer-sky/SummerSkySubmitModal.js +18 -1
  621. package/dist/components/themes/summer-sky/SummerSkyWaitingRoom.js +193 -1
  622. package/dist/components/themes/types.js +1 -1
  623. package/dist/components/ui/alert-dialog.js +26 -1
  624. package/dist/components/ui/alert.js +22 -1
  625. package/dist/components/ui/avatar.js +12 -1
  626. package/dist/components/ui/badge.js +38 -1
  627. package/dist/components/ui/button.js +35 -1
  628. package/dist/components/ui/calendar.js +76 -1
  629. package/dist/components/ui/card.js +16 -1
  630. package/dist/components/ui/carousel.js +91 -1
  631. package/dist/components/ui/checkbox.js +9 -1
  632. package/dist/components/ui/collapsible.js +13 -1
  633. package/dist/components/ui/command.js +34 -1
  634. package/dist/components/ui/confirm-dialog.js +49 -1
  635. package/dist/components/ui/dialog.js +23 -1
  636. package/dist/components/ui/drawer.js +35 -1
  637. package/dist/components/ui/dropdown-menu.js +33 -1
  638. package/dist/components/ui/file-upload.js +155 -1
  639. package/dist/components/ui/form.js +62 -1
  640. package/dist/components/ui/hover-card.js +10 -1
  641. package/dist/components/ui/image-preview.js +29 -1
  642. package/dist/components/ui/input.js +8 -1
  643. package/dist/components/ui/label.js +9 -1
  644. package/dist/components/ui/language-switcher.js +15 -1
  645. package/dist/components/ui/multi-select.js +90 -1
  646. package/dist/components/ui/points-input.js +33 -1
  647. package/dist/components/ui/popover.js +26 -1
  648. package/dist/components/ui/progress.js +16 -1
  649. package/dist/components/ui/radio-group.js +12 -1
  650. package/dist/components/ui/scroll-area.js +11 -1
  651. package/dist/components/ui/select.js +38 -1
  652. package/dist/components/ui/separator.js +8 -1
  653. package/dist/components/ui/sheet.js +40 -1
  654. package/dist/components/ui/single-select.js +76 -1
  655. package/dist/components/ui/skeleton.js +6 -1
  656. package/dist/components/ui/switch.js +8 -1
  657. package/dist/components/ui/table.js +20 -1
  658. package/dist/components/ui/tabs.js +17 -1
  659. package/dist/components/ui/textarea.js +8 -1
  660. package/dist/components/ui/tooltip.js +11 -1
  661. package/dist/index.d.ts +3 -0
  662. package/dist/index.js +24 -1
  663. package/dist/shared/constants/ApiConstant.d.ts +1 -0
  664. package/dist/shared/constants/ApiConstant.js +278 -1
  665. package/dist/shared/constants/QueryKeyConstant.js +112 -1
  666. package/dist/shared/constants/exam-level.enum.js +41 -1
  667. package/dist/shared/constants/landings/placement-test.constants.js +431 -1
  668. package/dist/shared/constants/question-skills.js +277 -1
  669. package/dist/shared/constants/routes.js +81 -1
  670. package/dist/shared/index.js +10 -1
  671. package/dist/shared/lib/hooks/index.js +10 -1
  672. package/dist/shared/lib/hooks/useAlertDialog.js +57 -1
  673. package/dist/shared/lib/hooks/useAudioPlayCounter.js +30 -1
  674. package/dist/shared/lib/hooks/useAudioPreview.js +81 -1
  675. package/dist/shared/lib/hooks/useAudioUpload.js +24 -1
  676. package/dist/shared/lib/hooks/useConfirmDialog.js +89 -1
  677. package/dist/shared/lib/hooks/useDebouncedCallback.js +32 -1
  678. package/dist/shared/lib/hooks/useDelayedAutoPlay.js +12 -1
  679. package/dist/shared/lib/hooks/useFileUpload.js +24 -1
  680. package/dist/shared/lib/hooks/useImageUrl.js +5 -1
  681. package/dist/shared/lib/hooks/usePresignedFileUrl.js +108 -1
  682. package/dist/shared/lib/hooks/useReactHookForm.js +31 -1
  683. package/dist/shared/lib/hooks/useToast.js +62 -1
  684. package/dist/shared/lib/html-content.js +22 -1
  685. package/dist/shared/lib/i18n/index.js +54 -1
  686. package/dist/shared/lib/i18n/messages/en/admin.d.ts +11 -4
  687. package/dist/shared/lib/i18n/messages/en/admin.js +2111 -1
  688. package/dist/shared/lib/i18n/messages/en/auth.js +86 -1
  689. package/dist/shared/lib/i18n/messages/en/common.js +140 -1
  690. package/dist/shared/lib/i18n/messages/en/file-upload.js +18 -1
  691. package/dist/shared/lib/i18n/messages/en/student.js +133 -1
  692. package/dist/shared/lib/i18n/messages/en/terms.js +37 -1
  693. package/dist/shared/lib/i18n/messages/en.d.ts +11 -4
  694. package/dist/shared/lib/i18n/messages/en.js +15 -1
  695. package/dist/shared/lib/i18n/messages/vi/admin.d.ts +11 -4
  696. package/dist/shared/lib/i18n/messages/vi/admin.js +2111 -1
  697. package/dist/shared/lib/i18n/messages/vi/auth.js +86 -1
  698. package/dist/shared/lib/i18n/messages/vi/common.js +140 -1
  699. package/dist/shared/lib/i18n/messages/vi/file-upload.js +18 -1
  700. package/dist/shared/lib/i18n/messages/vi/student.js +133 -1
  701. package/dist/shared/lib/i18n/messages/vi/terms.js +37 -1
  702. package/dist/shared/lib/i18n/messages/vi.d.ts +11 -4
  703. package/dist/shared/lib/i18n/messages/vi.js +15 -1
  704. package/dist/shared/lib/i18n/types.js +1 -1
  705. package/dist/shared/lib/stores/examQuestionStore.js +212 -1
  706. package/dist/shared/lib/stores/examTakingStore.js +240 -1
  707. package/dist/shared/lib/stores/gradingTransientStore.js +39 -1
  708. package/dist/shared/lib/stores/localeStore.js +10 -1
  709. package/dist/shared/lib/themes/config/starters.config.js +71 -1
  710. package/dist/shared/lib/themes/index.js +49 -1
  711. package/dist/shared/lib/themes/types.js +2 -1
  712. package/dist/shared/lib/toast.js +43 -1
  713. package/dist/shared/lib/utils/public-page.js +44 -1
  714. package/dist/shared/lib/utils/question-reverse-transform.js +438 -1
  715. package/dist/shared/lib/utils/question-transform-types.js +1 -1
  716. package/dist/shared/lib/utils/question-transform-validation.js +194 -1
  717. package/dist/shared/lib/utils/question-transform.js +199 -1
  718. package/dist/shared/lib/utils.js +168 -1
  719. package/dist/shared/lib/validation/choose-correct-answer.validation.js +111 -1
  720. package/dist/shared/lib/validation/label-the-picture.validation.js +19 -1
  721. package/dist/shared/lib/validation/listen-and-choose-from-answer-group.validation.js +46 -1
  722. package/dist/shared/lib/validation/listen-and-choose-objects-in-scene.validation.js +21 -1
  723. package/dist/shared/lib/validation/listen-and-drag-objects-into-scene.validation.js +34 -1
  724. package/dist/shared/lib/validation/listen-and-speak-answer.validation.js +40 -1
  725. package/dist/shared/lib/validation/listen-and-speak-compare-images.validation.js +45 -1
  726. package/dist/shared/lib/validation/listen-and-speak-image-group.validation.js +19 -1
  727. package/dist/shared/lib/validation/listen-and-speak-info-exchange.validation.js +39 -1
  728. package/dist/shared/lib/validation/listen-and-speak-odd-one-out.validation.js +32 -1
  729. package/dist/shared/lib/validation/listen-and-speak-question-list.validation.js +19 -1
  730. package/dist/shared/lib/validation/listen-and-speak-with-story-images.validation.js +28 -1
  731. package/dist/shared/lib/validation/look-picture-choose-correct-answer.validation.js +12 -1
  732. package/dist/shared/lib/validation/look-picture-fill-blank-choose-answer.validation.js +47 -1
  733. package/dist/shared/lib/validation/read-and-color-objects.validation.js +29 -1
  734. package/dist/shared/lib/validation/read-displayed-content.validation.js +28 -1
  735. package/dist/shared/lib/validation/speaking-conversation.validation.js +75 -1
  736. package/dist/shared/lib/validation/speaking-describe-image.validation.js +31 -1
  737. package/dist/shared/lib/validation/spontaneous-qa.validation.js +48 -1
  738. package/dist/shared/lib/validation/word-fill-paragraph-default.validation.js +38 -1
  739. package/dist/shared/lib/validation/word-fill-paragraph-with-options.validation.js +39 -1
  740. package/dist/shared/lib/validation/word-fill-paragraph.validation.js +43 -1
  741. package/dist/shared/lib/validation/word-ordering.validation.js +33 -1
  742. package/dist/shared/types/branch.types.js +6 -1
  743. package/dist/shared/types/common.types.js +49 -1
  744. package/dist/shared/types/entities/exam-schedule.types.js +5 -1
  745. package/dist/shared/types/entities/exam.types.js +1 -1
  746. package/dist/shared/types/entities/question.types.js +4 -1
  747. package/dist/shared/types/entities/result.types.js +4 -1
  748. package/dist/shared/types/entities/user.types.js +4 -1
  749. package/dist/shared/types/exam-taking.types.js +2 -1
  750. package/dist/shared/types/history.types.js +34 -1
  751. package/dist/shared/types/index.js +1 -1
  752. package/dist/shared/types/questions/choose-correct-adjective.js +4 -1
  753. package/dist/shared/types/questions/choose-the-correct-answer-group.d.ts +1 -0
  754. package/dist/shared/types/questions/choose-the-correct-answer-group.js +1 -1
  755. package/dist/shared/types/questions/choose-the-correct-answer.js +9 -1
  756. package/dist/shared/types/questions/cross-out-word-group.d.ts +2 -0
  757. package/dist/shared/types/questions/cross-out-word-group.js +1 -1
  758. package/dist/shared/types/questions/fill-missing-words-in-grid.js +11 -1
  759. package/dist/shared/types/questions/index.d.ts +1 -0
  760. package/dist/shared/types/questions/index.js +46 -1
  761. package/dist/shared/types/questions/listen-and-speak-answer.js +1 -1
  762. package/dist/shared/types/questions/listen-and-speak-compare-images.js +1 -1
  763. package/dist/shared/types/questions/listen-and-speak-image-group.js +1 -1
  764. package/dist/shared/types/questions/listen-and-speak-info-exchange.js +3 -1
  765. package/dist/shared/types/questions/listen-and-speak-odd-one-out.js +3 -1
  766. package/dist/shared/types/questions/listen-and-speak-question-list.js +1 -1
  767. package/dist/shared/types/questions/listen-and-speak-with-story-images.js +3 -1
  768. package/dist/shared/types/questions/look-picture-choose-correct-answer.js +5 -1
  769. package/dist/shared/types/questions/look-picture-fill-blank-choose-answer.js +9 -1
  770. package/dist/shared/types/questions/look-picture-fill-word-hint.js +7 -1
  771. package/dist/shared/types/questions/read-displayed-content.js +1 -1
  772. package/dist/shared/types/questions/speaking-conversation.js +7 -1
  773. package/dist/shared/types/questions/speaking-describe-image.js +1 -1
  774. package/dist/shared/types/questions/spontaneous-qa.js +1 -1
  775. package/dist/shared/types/questions/word-order-and-match-group.d.ts +33 -0
  776. package/dist/shared/types/questions/word-order-and-match-group.js +1 -0
  777. package/dist/shared/types/questions/write-correct-verb-form.js +12 -1
  778. package/dist/shared/types/role.types.js +1 -1
  779. package/dist/shared/types/structure-management.js +28 -1
  780. package/dist/shared/types/student.types.js +57 -1
  781. package/dist/shared/types/teacher-dashboard-rooms.js +2 -1
  782. package/package.json +184 -166
  783. package/dist/mcp/config.d.ts +0 -12
  784. package/dist/mcp/config.js +0 -1
  785. package/dist/mcp/http-client.d.ts +0 -6
  786. package/dist/mcp/http-client.js +0 -1
  787. package/dist/mcp/index.d.ts +0 -6
  788. package/dist/mcp/index.js +0 -2
  789. package/dist/mcp/tools/_helpers.d.ts +0 -4
  790. package/dist/mcp/tools/_helpers.js +0 -1
  791. package/dist/mcp/tools/exams.d.ts +0 -2
  792. package/dist/mcp/tools/exams.js +0 -1
  793. package/dist/mcp/tools/index.d.ts +0 -2
  794. package/dist/mcp/tools/index.js +0 -1
  795. package/dist/mcp/tools/results.d.ts +0 -2
  796. package/dist/mcp/tools/results.js +0 -1
@@ -1 +1,18 @@
1
- "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{ChevronLeft as s,XCircle as a}from"lucide-react";export function ResultErrorState({error:l,fallbackMessage:r="Đã xảy ra lỗi khi tải kết quả bài thi.",backLabel:i="Quay lại danh sách",onBack:n}){const c=function(e,t){return e instanceof Error&&e.message?e.message:"string"==typeof e&&e.trim()?e:t}(l,r);return e("div",{className:"flex min-h-screen flex-col bg-[#e0e0e0]",children:e("div",{className:"flex flex-1 items-center justify-center px-4 py-10",children:t("div",{className:"w-full max-w-md rounded-[28px] bg-white p-8 text-center shadow-xl",children:[e("div",{className:"mx-auto mb-5 flex h-16 w-16 items-center justify-center rounded-full bg-red-50",children:e(a,{className:"h-8 w-8 text-red-400"})}),e("h2",{className:"text-base font-bold text-slate-800",children:"Không thể tải kết quả"}),e("p",{className:"mt-2 text-sm text-slate-500",children:c}),n?t("button",{type:"button",onClick:n,className:"mt-6 inline-flex items-center gap-2 rounded-xl bg-[#2874A6] px-5 py-2.5 text-sm font-semibold text-white shadow-sm transition-all hover:bg-[#1A5276] hover:shadow-md active:scale-[0.98]",children:[e(s,{className:"h-4 w-4"}),i]}):null]})})})}
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { ChevronLeft, XCircle } from 'lucide-react';
4
+ function resolveErrorMessage(error, fallback) {
5
+ if (error instanceof Error && error.message)
6
+ return error.message;
7
+ if (typeof error === 'string' && error.trim())
8
+ return error;
9
+ return fallback;
10
+ }
11
+ /**
12
+ * Generic full-page error state for the result review screen.
13
+ * Source: oe-exam-fe/.../review/page.tsx generic error branch
14
+ */
15
+ export function ResultErrorState({ error, fallbackMessage = 'Đã xảy ra lỗi khi tải kết quả bài thi.', backLabel = 'Quay lại danh sách', onBack, }) {
16
+ const message = resolveErrorMessage(error, fallbackMessage);
17
+ return (_jsx("div", { className: "flex min-h-screen flex-col bg-[#e0e0e0]", children: _jsx("div", { className: "flex flex-1 items-center justify-center px-4 py-10", children: _jsxs("div", { className: "w-full max-w-md rounded-[28px] bg-white p-8 text-center shadow-xl", children: [_jsx("div", { className: "mx-auto mb-5 flex h-16 w-16 items-center justify-center rounded-full bg-red-50", children: _jsx(XCircle, { className: "h-8 w-8 text-red-400" }) }), _jsx("h2", { className: "text-base font-bold text-slate-800", children: "Kh\u00F4ng th\u1EC3 t\u1EA3i k\u1EBFt qu\u1EA3" }), _jsx("p", { className: "mt-2 text-sm text-slate-500", children: message }), onBack ? (_jsxs("button", { type: "button", onClick: onBack, className: "mt-6 inline-flex items-center gap-2 rounded-xl bg-[#2874A6] px-5 py-2.5 text-sm font-semibold text-white shadow-sm transition-all hover:bg-[#1A5276] hover:shadow-md active:scale-[0.98]", children: [_jsx(ChevronLeft, { className: "h-4 w-4" }), backLabel] })) : null] }) }) }));
18
+ }
@@ -1 +1,10 @@
1
- "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{Loader2 as s}from"lucide-react";export function ResultLoadingState({message:i="Đang tải kết quả bài thi...",description:l="Vui lòng đợi trong giây lát"}){return e("div",{className:"flex min-h-screen flex-col bg-[#e0e0e0]",children:e("div",{className:"flex flex-1 items-center justify-center px-4 py-10",children:t("div",{className:"text-center",children:[t("div",{className:"relative mx-auto h-16 w-16",children:[e("div",{className:"absolute inset-0 animate-ping rounded-full bg-[#2874A6]/20"}),e("div",{className:"relative flex h-16 w-16 items-center justify-center rounded-full bg-white shadow-lg",children:e(s,{className:"h-8 w-8 animate-spin text-[#2874A6]"})})]}),e("p",{className:"mt-5 text-sm font-semibold text-slate-600",children:i}),l?e("p",{className:"mt-1 text-xs text-slate-500",children:l}):null]})})})}
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Loader2 } from 'lucide-react';
4
+ /**
5
+ * Full-page loading state for the result review screen.
6
+ * Source: oe-exam-fe/.../review/page.tsx isLoading branch
7
+ */
8
+ export function ResultLoadingState({ message = 'Đang tải kết quả bài thi...', description = 'Vui lòng đợi trong giây lát', }) {
9
+ return (_jsx("div", { className: "flex min-h-screen flex-col bg-[#e0e0e0]", children: _jsx("div", { className: "flex flex-1 items-center justify-center px-4 py-10", children: _jsxs("div", { className: "text-center", children: [_jsxs("div", { className: "relative mx-auto h-16 w-16", children: [_jsx("div", { className: "absolute inset-0 animate-ping rounded-full bg-[#2874A6]/20" }), _jsx("div", { className: "relative flex h-16 w-16 items-center justify-center rounded-full bg-white shadow-lg", children: _jsx(Loader2, { className: "h-8 w-8 animate-spin text-[#2874A6]" }) })] }), _jsx("p", { className: "mt-5 text-sm font-semibold text-slate-600", children: message }), description ? _jsx("p", { className: "mt-1 text-xs text-slate-500", children: description }) : null] }) }) }));
10
+ }
@@ -1 +1,27 @@
1
- "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{Lock as n}from"lucide-react";import a from"./assets/logo-ocean.png";import i from"./assets/penguin-small.png";import{resolveAssetUrl as r}from"./speaking-report.utils";export function ResultNotPublicState({loginHref:o,assetBaseUrl:s,onLogin:l}){const c=o??("undefined"==typeof window?"/auth/login":`/auth/login?redirect=${encodeURIComponent(window.location.href)}`),d=r(a,s,"logo-ocean.png"),m=r(i,s,"penguin-small.png");return e("div",{className:"flex min-h-screen flex-col items-center justify-center bg-gradient-to-br from-[#eaf4ff] via-[#f0f7ff] to-[#e8f0ff] px-4 py-10",children:e("div",{className:"w-full max-w-md",children:t("div",{className:"relative overflow-hidden rounded-[28px] bg-white px-8 py-10 text-center shadow-[0_20px_60px_rgba(0,84,166,0.12)]",children:[e("div",{className:"absolute inset-x-0 top-0 h-1.5 bg-gradient-to-r from-[#00AEEF] via-[#0054A6] to-[#00AEEF]"}),e("div",{className:"mb-6 flex justify-center",children:e("img",{src:d,alt:"Ocean Edu",className:"h-auto w-[120px] object-contain"})}),e("div",{className:"mx-auto mb-5 flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-[#eaf4ff] to-[#d0e8ff] ring-4 ring-[#00AEEF]/20",children:e(n,{className:"h-9 w-9 text-[#0054A6]",strokeWidth:1.8})}),e("h2",{className:"text-[20px] font-black text-[#0054A6]",children:"Bạn cần đăng nhập để xem kết quả"}),t("p",{className:"mt-3 text-sm leading-relaxed text-slate-500",children:["Kết quả bài thi này chỉ dành cho học viên đã đăng nhập.",e("br",{}),"Vui lòng đăng nhập vào tài khoản Ocean Edu của bạn để tiếp tục."]}),e("div",{className:"my-6 border-t border-dashed border-slate-200"}),e("a",{href:c,onClick:e=>{l&&(e.preventDefault(),l(c))},className:"inline-flex w-full items-center justify-center gap-2 rounded-2xl bg-gradient-to-r from-[#0054A6] to-[#00AEEF] px-6 py-3 text-sm font-bold text-white shadow-md shadow-[#00AEEF]/30 transition-all hover:opacity-90 hover:shadow-lg active:scale-[0.98]",children:"Đăng nhập ngay"}),e("div",{className:"my-5 border-t border-dashed border-slate-200"}),t("div",{className:"flex items-start gap-3 rounded-2xl bg-[#f4f9ff] px-4 py-3 text-left",children:[e("img",{src:m,alt:"",className:"h-auto w-10 shrink-0 object-contain"}),e("p",{className:"text-[12.5px] leading-relaxed text-[#555]",children:"Sau khi đăng nhập, bạn sẽ có thể xem đầy đủ kết quả và chi tiết bài thi của mình! 💙"})]})]})})})}
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Lock } from 'lucide-react';
4
+ import logoOcean from './assets/logo-ocean.png';
5
+ import penguinSmall from './assets/penguin-small.png';
6
+ import { resolveAssetUrl } from './speaking-report.utils';
7
+ function buildDefaultLoginHref() {
8
+ if (typeof window === 'undefined')
9
+ return '/auth/login';
10
+ return `/auth/login?redirect=${encodeURIComponent(window.location.href)}`;
11
+ }
12
+ /**
13
+ * Friendly full-page state when the result is private (403 not-public).
14
+ * Source: oe-exam-fe/.../review/page.tsx isResultNotPublic branch
15
+ */
16
+ export function ResultNotPublicState({ loginHref, assetBaseUrl, onLogin, }) {
17
+ const href = loginHref ?? buildDefaultLoginHref();
18
+ const logoSrc = resolveAssetUrl(logoOcean, assetBaseUrl, 'logo-ocean.png');
19
+ const penguinSrc = resolveAssetUrl(penguinSmall, assetBaseUrl, 'penguin-small.png');
20
+ const handleLoginClick = (event) => {
21
+ if (!onLogin)
22
+ return;
23
+ event.preventDefault();
24
+ onLogin(href);
25
+ };
26
+ return (_jsx("div", { className: "flex min-h-screen flex-col items-center justify-center bg-gradient-to-br from-[#eaf4ff] via-[#f0f7ff] to-[#e8f0ff] px-4 py-10", children: _jsx("div", { className: "w-full max-w-md", children: _jsxs("div", { className: "relative overflow-hidden rounded-[28px] bg-white px-8 py-10 text-center shadow-[0_20px_60px_rgba(0,84,166,0.12)]", children: [_jsx("div", { className: "absolute inset-x-0 top-0 h-1.5 bg-gradient-to-r from-[#00AEEF] via-[#0054A6] to-[#00AEEF]" }), _jsx("div", { className: "mb-6 flex justify-center", children: _jsx("img", { src: logoSrc, alt: "Ocean Edu", className: "h-auto w-[120px] object-contain" }) }), _jsx("div", { className: "mx-auto mb-5 flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-[#eaf4ff] to-[#d0e8ff] ring-4 ring-[#00AEEF]/20", children: _jsx(Lock, { className: "h-9 w-9 text-[#0054A6]", strokeWidth: 1.8 }) }), _jsx("h2", { className: "text-[20px] font-black text-[#0054A6]", children: "B\u1EA1n c\u1EA7n \u0111\u0103ng nh\u1EADp \u0111\u1EC3 xem k\u1EBFt qu\u1EA3" }), _jsxs("p", { className: "mt-3 text-sm leading-relaxed text-slate-500", children: ["K\u1EBFt qu\u1EA3 b\u00E0i thi n\u00E0y ch\u1EC9 d\u00E0nh cho h\u1ECDc vi\u00EAn \u0111\u00E3 \u0111\u0103ng nh\u1EADp.", _jsx("br", {}), "Vui l\u00F2ng \u0111\u0103ng nh\u1EADp v\u00E0o t\u00E0i kho\u1EA3n Ocean Edu c\u1EE7a b\u1EA1n \u0111\u1EC3 ti\u1EBFp t\u1EE5c."] }), _jsx("div", { className: "my-6 border-t border-dashed border-slate-200" }), _jsx("a", { href: href, onClick: handleLoginClick, className: "inline-flex w-full items-center justify-center gap-2 rounded-2xl bg-gradient-to-r from-[#0054A6] to-[#00AEEF] px-6 py-3 text-sm font-bold text-white shadow-md shadow-[#00AEEF]/30 transition-all hover:opacity-90 hover:shadow-lg active:scale-[0.98]", children: "\u0110\u0103ng nh\u1EADp ngay" }), _jsx("div", { className: "my-5 border-t border-dashed border-slate-200" }), _jsxs("div", { className: "flex items-start gap-3 rounded-2xl bg-[#f4f9ff] px-4 py-3 text-left", children: [_jsx("img", { src: penguinSrc, alt: "", className: "h-auto w-10 shrink-0 object-contain" }), _jsx("p", { className: "text-[12.5px] leading-relaxed text-[#555]", children: "Sau khi \u0111\u0103ng nh\u1EADp, b\u1EA1n s\u1EBD c\u00F3 th\u1EC3 xem \u0111\u1EA7y \u0111\u1EE7 k\u1EBFt qu\u1EA3 v\u00E0 chi ti\u1EBFt b\u00E0i thi c\u1EE7a m\u00ECnh! \uD83D\uDC99" })] })] }) }) }));
27
+ }
@@ -1 +1,14 @@
1
- "use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{BadgeTitle as r}from"./BadgeTitle";import{QuestionCard as i}from"./SpeakingReportShared";import{formatScore as n,getPartScore as a}from"./speaking-report.utils";function s({part:t}){const r=a(t);return r.hasPending||null==r.score?null:e("div",{className:"inline-flex items-center rounded-full bg-[#0054A6] px-4 py-2 text-sm font-bold text-white shadow-sm",children:["Điểm: ",Math.round(r.score)," / ",n(r.maxScore,0)]})}export function SpeakingPartSection({part:n}){return e("section",{className:"relative rounded-[20px] border-2 border-[#00AEEF] bg-white px-5 pb-6 pt-11 md:px-8",children:[t(r,{number:String(n.partNo),title:n.partName||`PHẦN ${n.partNo}`}),e("div",{className:"flex flex-col gap-4 md:flex-row md:items-start md:justify-between",children:[e("div",{className:"space-y-2",children:[t("h3",{className:"text-xl font-black text-[#0054A6]",children:n.partSectionName||"Speaking section"}),n.instructions?t("p",{className:"max-w-3xl text-sm leading-6 text-slate-600",children:n.instructions}):null]}),t(s,{part:n})]}),t("div",{className:"mt-6 grid gap-4",children:n.questions.map(e=>t(i,{question:e},e.questionId))})]})}
1
+ 'use client';
2
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
+ import { BadgeTitle } from './BadgeTitle';
4
+ import { QuestionCard } from './SpeakingReportShared';
5
+ import { formatScore, getPartScore } from './speaking-report.utils';
6
+ function PartScorePill({ part }) {
7
+ const partScore = getPartScore(part);
8
+ if (partScore.hasPending || partScore.score == null)
9
+ return null;
10
+ return (_jsxs("div", { className: "inline-flex items-center rounded-full bg-[#0054A6] px-4 py-2 text-sm font-bold text-white shadow-sm", children: ["\u0110i\u1EC3m: ", Math.round(partScore.score), " / ", formatScore(partScore.maxScore, 0)] }));
11
+ }
12
+ export function SpeakingPartSection({ part }) {
13
+ return (_jsxs("section", { className: "relative rounded-[20px] border-2 border-[#00AEEF] bg-white px-5 pb-6 pt-11 md:px-8", children: [_jsx(BadgeTitle, { number: String(part.partNo), title: part.partName || `PHẦN ${part.partNo}` }), _jsxs("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:justify-between", children: [_jsxs("div", { className: "space-y-2", children: [_jsx("h3", { className: "text-xl font-black text-[#0054A6]", children: part.partSectionName || 'Speaking section' }), part.instructions ? (_jsx("p", { className: "max-w-3xl text-sm leading-6 text-slate-600", children: part.instructions })) : null] }), _jsx(PartScorePill, { part: part })] }), _jsx("div", { className: "mt-6 grid gap-4", children: part.questions.map((question) => (_jsx(QuestionCard, { question: question }, question.questionId))) })] }));
14
+ }
@@ -1 +1,86 @@
1
- "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{CheckCheck as s,Clock as r,MessageSquare as l,MessageSquareQuote as a,Music2 as n,Volume2 as i,Zap as d}from"lucide-react";import{ReviewGradingStatus as c}from"../../../api/result-review";import{ResolvedImage as x}from"../../../components/common/ResolvedImage";import{cn as o}from"../../../shared/lib/utils";import{SpeakingResultAudioPlayer as m}from"../speaking/SpeakingResultAudioPlayer";import{deriveQuestionSkillMetrics as p,extractPrompt as u,extractQuestionFeedback as h,extractStudentAnswerText as f,formatScore as b,getPendingGradingLabel as g,getQuestionTypeLabel as N,isGradingComplete as w}from"./speaking-report.utils";export function InfoRow({icon:s,label:r,value:l}){return t("p",{className:"flex items-start text-[13px] font-medium text-[#333] xs:text-sm sm:text-base md:text-lg",children:[e(s,{className:"mr-2 mt-0.5 h-[14px] w-[14px] shrink-0 text-[#0054A6] xs:h-[16px] xs:w-[16px] sm:mr-3 sm:h-[18px] sm:w-[18px]"}),t("span",{className:"flex flex-wrap items-baseline gap-x-1.5",children:[t("span",{className:"whitespace-nowrap",children:[r," :"]}),e("strong",{suppressHydrationWarning:!0,className:"font-bold text-[#0054A6]",children:l})]})]})}function v({metric:t}){const r="h-[18px] w-[18px] text-white";switch(t.icon){case"speaker":return e(i,{className:r});case"bolt":return e(d,{className:r});case"message":return e(l,{className:r});case"check-double":return e(s,{className:r});case"music":return e(n,{className:r});default:return null}}export function SkillRow({metric:s,compact:r=!1}){const l=b(r?s.score/10:s.score,1),a=r?"/10":"/100";return t("div",{className:o("flex items-center rounded-full border border-[#eef4fb] bg-white shadow-[0_1px_0_rgba(255,255,255,0.9)] last:mb-0",r?"min-h-[70px] pl-[12px] pr-4":"mb-2 px-3 py-2 sm:mb-3 sm:px-4 sm:py-3"),children:[e("div",{className:"flex h-[48px] w-[48px] shrink-0 items-center justify-center rounded-full bg-white shadow-[0_4px_12px_rgba(15,23,42,0.08)] xs:h-[52px] xs:w-[52px] sm:h-[58px] sm:w-[58px]",children:e("div",{className:o("flex items-center justify-center rounded-full text-white",r?"h-[42px] w-[42px]":"h-[36px] w-[36px] xs:h-[38px] xs:w-[38px] sm:h-[42px] sm:w-[42px]",s.barClass),children:e(v,{metric:s})})}),t("div",{className:o("ml-2 mr-2 flex-1 border-r border-dashed border-[#d9e0ea] pr-2 xs:ml-3 xs:mr-3 xs:pr-3 sm:pr-4",r?"w-[148px]":"min-w-0"),children:[e("h4",{className:o("truncate font-extrabold leading-5 text-[#0054A6]",r?"text-[15px]":"text-[13px] xs:text-[14px] sm:text-[15px]"),children:s.label}),e("span",{className:o("mt-0.5 block truncate text-[#8b97a8] sm:mt-1",r?"text-[11px]":"text-[10px] xs:text-[10.5px] sm:text-[11px]"),children:s.sublabel})]}),t("div",{className:o("shrink-0 font-extrabold text-[#0054A6]",r?"w-[86px] text-[18px]":"w-[60px] text-[16px] xs:w-[70px] xs:text-[17px] sm:w-20 sm:text-xl"),children:[l," ",e("small",{className:o("font-semibold text-[#c5ced8]",r?"text-[12px]":"text-[11px] xs:text-[11.5px] sm:text-[13px]"),children:a})]}),e("div",{className:o("ml-2 flex-1 overflow-hidden rounded-full bg-[#edf0f4] xs:ml-2.5 sm:ml-3",r?"h-[12px]":"h-[10px] sm:h-[11px]"),children:e("div",{className:o("h-full rounded-full",s.barClass),style:{width:`${s.score}%`}})})]})}export function PendingGradingCard({gradingStatus:s}){const l=g(s),a=s===c.FAILED;return t("div",{className:o("flex flex-col items-center justify-center gap-3 rounded-2xl border px-6 py-8 text-center",a?"border-orange-200 bg-orange-50":"border-[#dbeafe] bg-[#F4F9FF]"),children:[e("div",{className:o("flex h-14 w-14 items-center justify-center rounded-full",a?"bg-orange-100":"bg-[#E8F6FF]"),children:e(r,{className:o("h-7 w-7 animate-pulse",a?"text-orange-500":"text-[#00AEEF]")})}),t("div",{children:[e("p",{className:o("text-base font-bold",a?"text-orange-600":"text-[#0054A6]"),children:l}),e("p",{className:"mt-1 text-sm text-slate-500",children:"Kết quả sẽ được cập nhật sớm nhất có thể."})]})]})}export function NotAnsweredCard(){return t("div",{className:"flex flex-col items-center justify-center gap-3 rounded-2xl border border-slate-200 bg-slate-50 px-6 py-8 text-center",children:[e("div",{className:"flex h-14 w-14 items-center justify-center rounded-full bg-slate-100",children:e(i,{className:"h-7 w-7 text-slate-300"})}),t("div",{children:[e("p",{className:"text-base font-bold text-slate-500",children:"Học sinh chưa trả lời câu hỏi"}),e("p",{className:"mt-1 text-sm text-slate-400",children:"Câu hỏi này không có bài ghi âm."})]})]})}export function QuestionScorePill({question:s}){return s.gradingStatus===c.NOT_ANSWERED?t("div",{className:"inline-flex items-center rounded-full bg-slate-100 px-3.5 py-2 text-sm font-bold text-slate-500 shadow-sm ring-1 ring-slate-200",children:["Bỏ qua — 0 / ",b(s.maxScore,0)]}):w(s.gradingStatus)?e("div",{className:"inline-flex items-center rounded-full bg-[#E8F6FF] px-3.5 py-2 text-sm font-extrabold text-[#0054A6] shadow-sm ring-1 ring-[#b9dcff]",children:null==s.score?`Chưa chấm / ${b(s.maxScore,0)}`:`${b(s.score,2)} / ${b(s.maxScore,0)}`}):t("div",{className:"inline-flex items-center gap-1.5 rounded-full bg-[#FFF8E8] px-3.5 py-2 text-sm font-bold text-[#D97706] shadow-sm ring-1 ring-[#fcd34d]",children:[e(r,{className:"h-3.5 w-3.5"}),"Chờ chấm"]})}export function PromptBlock({question:s}){const r=s.questionContent??{},l=r.imageUrl||r.image||r.promptImageUrl,a=s.audioUrl||r.audioUrl||r.audio||r.questionAudio,n=u(s);return t("div",{className:"rounded-xl border border-[#dbeafe] bg-[#F8FBFF] px-4 py-3",children:[e("div",{className:"mb-2 text-xs font-bold uppercase tracking-wide text-[#00AEEF]",children:"Câu hỏi"}),n.text&&"Nội dung câu hỏi đang được cập nhật."!==n.text&&(n.isHtml?e("div",{className:"mb-3 text-sm leading-relaxed text-slate-700 [&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5 [&_li]:my-0.5 [&_p]:my-1",dangerouslySetInnerHTML:{__html:n.text}}):e("p",{className:"mb-3 text-center text-sm leading-relaxed text-slate-700",children:n.text})),a?e("div",{className:"mb-3",children:e(m,{audioKey:a})}):null,l?e("div",{className:"overflow-hidden rounded-lg border border-slate-200",children:e(x,{src:l,alt:"Question image",className:"h-auto w-full"})}):null]})}export function AnswerBlock({question:s}){const r=f(s);return s.studentAnswerKey?t("div",{className:"rounded-xl border border-slate-200 bg-white px-4 py-3",children:[t("div",{className:"mb-2.5 flex items-center gap-2 text-xs font-bold text-[#0054A6]",children:[e(i,{className:"h-3.5 w-3.5 text-[#00AEEF]"}),"Bài nói của học viên"]}),e(m,{audioKey:s.studentAnswerKey})]}):t("div",{className:"rounded-xl border border-slate-200 bg-slate-50 px-4 py-3",children:[e("div",{className:"mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-slate-400",children:"Câu trả lời của học viên"}),e("p",{className:"text-sm leading-relaxed text-slate-600",children:r})]})}export function QuestionComponentScores({question:s}){const r=p(s);return t("div",{className:"rounded-[28px] border border-[#cfe4ff] bg-[#F3F8FF] px-4 py-5 md:px-5 md:py-6",children:[e("div",{className:"mb-5 text-center text-[20px] font-black uppercase tracking-tight text-[#0054A6]",children:"ĐIỂM THÀNH PHẦN"}),e("div",{className:"space-y-3",children:r.map(t=>e(SkillRow,{metric:t,compact:!0},`${s.questionId}-${t.key}`))})]})}export function FeedbackBlock({question:s}){return t("div",{className:"rounded-xl border border-[#ffe6b3] bg-[#FFF8E8] px-4 py-3",children:[t("div",{className:"mb-1.5 flex items-center gap-1.5 text-xs font-bold text-[#D97706]",children:[e(a,{className:"h-3.5 w-3.5"}),"Nhận xét AI"]}),e("p",{className:"text-sm leading-relaxed text-slate-700",children:h(s)})]})}export function QuestionCard({question:s}){const r=w(s.gradingStatus),l=s.gradingStatus===c.NOT_ANSWERED;return t("article",{className:"rounded-[28px] border border-[#cfe4ff] bg-white p-4 shadow-[0_10px_28px_rgba(15,23,42,0.06)] md:p-6",children:[e("div",{className:"mb-5 rounded-[22px] border border-[#dbeafe] bg-[linear-gradient(135deg,#f8fbff_0%,#eef6ff_100%)] px-4 py-4 md:px-5",children:t("div",{className:"flex flex-col gap-4 md:flex-row md:items-start md:justify-between",children:[t("div",{className:"min-w-0",children:[t("div",{className:"text-xl font-black text-[#0054A6]",children:["Câu ",s.questionNumber]}),e("div",{className:"mt-1 text-sm font-semibold text-slate-500",children:N(s.questionType)})]}),e("div",{className:"shrink-0 self-start",children:e(QuestionScorePill,{question:s})})]})}),t("div",r?{className:"grid gap-5 xl:grid-cols-[minmax(0,1fr)_minmax(0,1fr)] xl:items-start",children:[t("div",{className:"space-y-4",children:[e(PromptBlock,{question:s}),e(AnswerBlock,{question:s}),e(FeedbackBlock,{question:s})]}),e("aside",{className:"min-w-0",children:e(QuestionComponentScores,{question:s})})]}:l?{className:"space-y-4",children:[e(PromptBlock,{question:s}),e(NotAnsweredCard,{})]}:{className:"space-y-4",children:[e(PromptBlock,{question:s}),e(PendingGradingCard,{gradingStatus:s.gradingStatus})]})]})}
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { CheckCheck, Clock, MessageSquare, MessageSquareQuote, Music2, Volume2, Zap, } from 'lucide-react';
4
+ import { ReviewGradingStatus } from '../../../api/result-review';
5
+ import { ResolvedImage } from '../../../components/common/ResolvedImage';
6
+ import { cn } from '../../../shared/lib/utils';
7
+ import { SpeakingResultAudioPlayer } from '../speaking/SpeakingResultAudioPlayer';
8
+ import { deriveQuestionSkillMetrics, extractPrompt, extractQuestionFeedback, extractStudentAnswerText, formatScore, getPendingGradingLabel, getQuestionTypeLabel, isGradingComplete, } from './speaking-report.utils';
9
+ export function InfoRow({ icon: Icon, label, value, }) {
10
+ return (_jsxs("p", { className: "flex items-start text-[13px] font-medium text-[#333] xs:text-sm sm:text-base md:text-lg", children: [_jsx(Icon, { className: "mr-2 mt-0.5 h-[14px] w-[14px] shrink-0 text-[#0054A6] xs:h-[16px] xs:w-[16px] sm:mr-3 sm:h-[18px] sm:w-[18px]" }), _jsxs("span", { className: "flex flex-wrap items-baseline gap-x-1.5", children: [_jsxs("span", { className: "whitespace-nowrap", children: [label, " :"] }), _jsx("strong", { suppressHydrationWarning: true, className: "font-bold text-[#0054A6]", children: value })] })] }));
11
+ }
12
+ function SkillIcon({ metric }) {
13
+ const iconClassName = 'h-[18px] w-[18px] text-white';
14
+ switch (metric.icon) {
15
+ case 'speaker':
16
+ return _jsx(Volume2, { className: iconClassName });
17
+ case 'bolt':
18
+ return _jsx(Zap, { className: iconClassName });
19
+ case 'message':
20
+ return _jsx(MessageSquare, { className: iconClassName });
21
+ case 'check-double':
22
+ return _jsx(CheckCheck, { className: iconClassName });
23
+ case 'music':
24
+ return _jsx(Music2, { className: iconClassName });
25
+ default:
26
+ return null;
27
+ }
28
+ }
29
+ export function SkillRow({ metric, compact = false }) {
30
+ const scoreText = compact ? formatScore(metric.score / 10, 1) : formatScore(metric.score, 1);
31
+ const scoreUnit = compact ? '/10' : '/100';
32
+ return (_jsxs("div", { className: cn('flex items-center rounded-full border border-[#eef4fb] bg-white shadow-[0_1px_0_rgba(255,255,255,0.9)] last:mb-0', compact ? 'min-h-[70px] pl-[12px] pr-4' : 'mb-2 px-3 py-2 sm:mb-3 sm:px-4 sm:py-3'), children: [_jsx("div", { className: "flex h-[48px] w-[48px] shrink-0 items-center justify-center rounded-full bg-white shadow-[0_4px_12px_rgba(15,23,42,0.08)] xs:h-[52px] xs:w-[52px] sm:h-[58px] sm:w-[58px]", children: _jsx("div", { className: cn('flex items-center justify-center rounded-full text-white', compact
33
+ ? 'h-[42px] w-[42px]'
34
+ : 'h-[36px] w-[36px] xs:h-[38px] xs:w-[38px] sm:h-[42px] sm:w-[42px]', metric.barClass), children: _jsx(SkillIcon, { metric: metric }) }) }), _jsxs("div", { className: cn('ml-2 mr-2 flex-1 border-r border-dashed border-[#d9e0ea] pr-2 xs:ml-3 xs:mr-3 xs:pr-3 sm:pr-4', compact ? 'w-[148px]' : 'min-w-0'), children: [_jsx("h4", { className: cn('truncate font-extrabold leading-5 text-[#0054A6]', compact ? 'text-[15px]' : 'text-[13px] xs:text-[14px] sm:text-[15px]'), children: metric.label }), _jsx("span", { className: cn('mt-0.5 block truncate text-[#8b97a8] sm:mt-1', compact ? 'text-[11px]' : 'text-[10px] xs:text-[10.5px] sm:text-[11px]'), children: metric.sublabel })] }), _jsxs("div", { className: cn('shrink-0 font-extrabold text-[#0054A6]', compact
35
+ ? 'w-[86px] text-[18px]'
36
+ : 'w-[60px] text-[16px] xs:w-[70px] xs:text-[17px] sm:w-20 sm:text-xl'), children: [scoreText, ' ', _jsx("small", { className: cn('font-semibold text-[#c5ced8]', compact ? 'text-[12px]' : 'text-[11px] xs:text-[11.5px] sm:text-[13px]'), children: scoreUnit })] }), _jsx("div", { className: cn('ml-2 flex-1 overflow-hidden rounded-full bg-[#edf0f4] xs:ml-2.5 sm:ml-3', compact ? 'h-[12px]' : 'h-[10px] sm:h-[11px]'), children: _jsx("div", { className: cn('h-full rounded-full', metric.barClass), style: { width: `${metric.score}%` } }) })] }));
37
+ }
38
+ export function PendingGradingCard({ gradingStatus }) {
39
+ const label = getPendingGradingLabel(gradingStatus);
40
+ const isFailed = gradingStatus === ReviewGradingStatus.FAILED;
41
+ return (_jsxs("div", { className: cn('flex flex-col items-center justify-center gap-3 rounded-2xl border px-6 py-8 text-center', isFailed ? 'border-orange-200 bg-orange-50' : 'border-[#dbeafe] bg-[#F4F9FF]'), children: [_jsx("div", { className: cn('flex h-14 w-14 items-center justify-center rounded-full', isFailed ? 'bg-orange-100' : 'bg-[#E8F6FF]'), children: _jsx(Clock, { className: cn('h-7 w-7 animate-pulse', isFailed ? 'text-orange-500' : 'text-[#00AEEF]') }) }), _jsxs("div", { children: [_jsx("p", { className: cn('text-base font-bold', isFailed ? 'text-orange-600' : 'text-[#0054A6]'), children: label }), _jsx("p", { className: "mt-1 text-sm text-slate-500", children: "K\u1EBFt qu\u1EA3 s\u1EBD \u0111\u01B0\u1EE3c c\u1EADp nh\u1EADt s\u1EDBm nh\u1EA5t c\u00F3 th\u1EC3." })] })] }));
42
+ }
43
+ export function NotAnsweredCard() {
44
+ return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-3 rounded-2xl border border-slate-200 bg-slate-50 px-6 py-8 text-center", children: [_jsx("div", { className: "flex h-14 w-14 items-center justify-center rounded-full bg-slate-100", children: _jsx(Volume2, { className: "h-7 w-7 text-slate-300" }) }), _jsxs("div", { children: [_jsx("p", { className: "text-base font-bold text-slate-500", children: "H\u1ECDc sinh ch\u01B0a tr\u1EA3 l\u1EDDi c\u00E2u h\u1ECFi" }), _jsx("p", { className: "mt-1 text-sm text-slate-400", children: "C\u00E2u h\u1ECFi n\u00E0y kh\u00F4ng c\u00F3 b\u00E0i ghi \u00E2m." })] })] }));
45
+ }
46
+ export function QuestionScorePill({ question }) {
47
+ if (question.gradingStatus === ReviewGradingStatus.NOT_ANSWERED) {
48
+ return (_jsxs("div", { className: "inline-flex items-center rounded-full bg-slate-100 px-3.5 py-2 text-sm font-bold text-slate-500 shadow-sm ring-1 ring-slate-200", children: ["B\u1ECF qua \u2014 0 / ", formatScore(question.maxScore, 0)] }));
49
+ }
50
+ if (!isGradingComplete(question.gradingStatus)) {
51
+ return (_jsxs("div", { className: "inline-flex items-center gap-1.5 rounded-full bg-[#FFF8E8] px-3.5 py-2 text-sm font-bold text-[#D97706] shadow-sm ring-1 ring-[#fcd34d]", children: [_jsx(Clock, { className: "h-3.5 w-3.5" }), "Ch\u1EDD ch\u1EA5m"] }));
52
+ }
53
+ return (_jsx("div", { className: "inline-flex items-center rounded-full bg-[#E8F6FF] px-3.5 py-2 text-sm font-extrabold text-[#0054A6] shadow-sm ring-1 ring-[#b9dcff]", children: question.score == null
54
+ ? `Chưa chấm / ${formatScore(question.maxScore, 0)}`
55
+ : `${formatScore(question.score, 2)} / ${formatScore(question.maxScore, 0)}` }));
56
+ }
57
+ export function PromptBlock({ question }) {
58
+ const content = (question.questionContent ?? {});
59
+ const imageUrl = (content['imageUrl'] || content['image'] || content['promptImageUrl']);
60
+ const audioUrl = question.audioUrl ||
61
+ content['audioUrl'] ||
62
+ content['audio'] ||
63
+ content['questionAudio'];
64
+ const promptResult = extractPrompt(question);
65
+ const placeholder = 'Nội dung câu hỏi đang được cập nhật.';
66
+ return (_jsxs("div", { className: "rounded-xl border border-[#dbeafe] bg-[#F8FBFF] px-4 py-3", children: [_jsx("div", { className: "mb-2 text-xs font-bold uppercase tracking-wide text-[#00AEEF]", children: "C\u00E2u h\u1ECFi" }), promptResult.text && promptResult.text !== placeholder && (promptResult.isHtml ? (_jsx("div", { className: "mb-3 text-sm leading-relaxed text-slate-700 [&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5 [&_li]:my-0.5 [&_p]:my-1", dangerouslySetInnerHTML: { __html: promptResult.text } })) : (_jsx("p", { className: "mb-3 text-center text-sm leading-relaxed text-slate-700", children: promptResult.text }))), audioUrl ? (_jsx("div", { className: "mb-3", children: _jsx(SpeakingResultAudioPlayer, { audioKey: audioUrl }) })) : null, imageUrl ? (_jsx("div", { className: "overflow-hidden rounded-lg border border-slate-200", children: _jsx(ResolvedImage, { src: imageUrl, alt: "Question image", className: "h-auto w-full" }) })) : null] }));
67
+ }
68
+ export function AnswerBlock({ question }) {
69
+ const answerText = extractStudentAnswerText(question);
70
+ if (question.studentAnswerKey) {
71
+ return (_jsxs("div", { className: "rounded-xl border border-slate-200 bg-white px-4 py-3", children: [_jsxs("div", { className: "mb-2.5 flex items-center gap-2 text-xs font-bold text-[#0054A6]", children: [_jsx(Volume2, { className: "h-3.5 w-3.5 text-[#00AEEF]" }), "B\u00E0i n\u00F3i c\u1EE7a h\u1ECDc vi\u00EAn"] }), _jsx(SpeakingResultAudioPlayer, { audioKey: question.studentAnswerKey })] }));
72
+ }
73
+ return (_jsxs("div", { className: "rounded-xl border border-slate-200 bg-slate-50 px-4 py-3", children: [_jsx("div", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-slate-400", children: "C\u00E2u tr\u1EA3 l\u1EDDi c\u1EE7a h\u1ECDc vi\u00EAn" }), _jsx("p", { className: "text-sm leading-relaxed text-slate-600", children: answerText })] }));
74
+ }
75
+ export function QuestionComponentScores({ question }) {
76
+ const metrics = deriveQuestionSkillMetrics(question);
77
+ return (_jsxs("div", { className: "rounded-[28px] border border-[#cfe4ff] bg-[#F3F8FF] px-4 py-5 md:px-5 md:py-6", children: [_jsx("div", { className: "mb-5 text-center text-[20px] font-black uppercase tracking-tight text-[#0054A6]", children: "\u0110I\u1EC2M TH\u00C0NH PH\u1EA6N" }), _jsx("div", { className: "space-y-3", children: metrics.map((metric) => (_jsx(SkillRow, { metric: metric, compact: true }, `${question.questionId}-${metric.key}`))) })] }));
78
+ }
79
+ export function FeedbackBlock({ question }) {
80
+ return (_jsxs("div", { className: "rounded-xl border border-[#ffe6b3] bg-[#FFF8E8] px-4 py-3", children: [_jsxs("div", { className: "mb-1.5 flex items-center gap-1.5 text-xs font-bold text-[#D97706]", children: [_jsx(MessageSquareQuote, { className: "h-3.5 w-3.5" }), "Nh\u1EADn x\u00E9t AI"] }), _jsx("p", { className: "text-sm leading-relaxed text-slate-700", children: extractQuestionFeedback(question) })] }));
81
+ }
82
+ export function QuestionCard({ question }) {
83
+ const gradingDone = isGradingComplete(question.gradingStatus);
84
+ const isNotAnswered = question.gradingStatus === ReviewGradingStatus.NOT_ANSWERED;
85
+ return (_jsxs("article", { className: "rounded-[28px] border border-[#cfe4ff] bg-white p-4 shadow-[0_10px_28px_rgba(15,23,42,0.06)] md:p-6", children: [_jsx("div", { className: "mb-5 rounded-[22px] border border-[#dbeafe] bg-[linear-gradient(135deg,#f8fbff_0%,#eef6ff_100%)] px-4 py-4 md:px-5", children: _jsxs("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:justify-between", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "text-xl font-black text-[#0054A6]", children: ["C\u00E2u ", question.questionNumber] }), _jsx("div", { className: "mt-1 text-sm font-semibold text-slate-500", children: getQuestionTypeLabel(question.questionType) })] }), _jsx("div", { className: "shrink-0 self-start", children: _jsx(QuestionScorePill, { question: question }) })] }) }), gradingDone ? (_jsxs("div", { className: "grid gap-5 xl:grid-cols-[minmax(0,1fr)_minmax(0,1fr)] xl:items-start", children: [_jsxs("div", { className: "space-y-4", children: [_jsx(PromptBlock, { question: question }), _jsx(AnswerBlock, { question: question }), _jsx(FeedbackBlock, { question: question })] }), _jsx("aside", { className: "min-w-0", children: _jsx(QuestionComponentScores, { question: question }) })] })) : isNotAnswered ? (_jsxs("div", { className: "space-y-4", children: [_jsx(PromptBlock, { question: question }), _jsx(NotAnsweredCard, {})] })) : (_jsxs("div", { className: "space-y-4", children: [_jsx(PromptBlock, { question: question }), _jsx(PendingGradingCard, { gradingStatus: question.gradingStatus })] }))] }));
86
+ }
@@ -1 +1,171 @@
1
- "use client";import{jsx as e,jsxs as n}from"react/jsx-runtime";import{Star as t}from"lucide-react";import{BadgeTitle as i}from"./BadgeTitle";export var SpeakingRubricScoringVersion;!function(e){e.TEENS_FOCUS_PEARSON_V2="TEENS_FOCUS_PEARSON_V2",e.PRESCHOOL_PLACEMENT_V1="PRESCHOOL_PLACEMENT_V1",e.KINDY_PLACEMENT_V1="KINDY_PLACEMENT_V1"}(SpeakingRubricScoringVersion||(SpeakingRubricScoringVersion={}));export var KidsRubricSectionCode;!function(e){e.WARM_UP="WARM_UP",e.PART_1="PART_1",e.PART_2="PART_2",e.PART_3="PART_3"}(KidsRubricSectionCode||(KidsRubricSectionCode={}));const c={[SpeakingRubricScoringVersion.TEENS_FOCUS_PEARSON_V2]:{C1:{vi:"Ngữ pháp & Từ vựng",en:"Grammar & Vocabulary",hint:"Cấu trúc câu, thì động từ và độ đa dạng từ vựng"},C2:{vi:"Phát âm",en:"Pronunciation",hint:"Độ rõ ràng, trọng âm từ và ngữ điệu câu"},C3:{vi:"Giao tiếp tương tác",en:"Interactive Communication",hint:"Phản hồi đủ ý và tự mở rộng câu trả lời"},C4:{vi:"Quản lý diễn ngôn",en:"Discourse Management",hint:"Mạch lạc, tổ chức và phát triển ý rõ ràng"}},[SpeakingRubricScoringVersion.PRESCHOOL_PLACEMENT_V1]:{C1:{vi:"Nhận biết số đếm (1–10)",en:"Cardinal Numbers (1–10)",hint:"Đếm 1–10 và nhận ra từng số"},C2:{vi:"Nhận biết màu sắc",en:"Basic Colours",hint:"Gọi tên màu sắc và màu yêu thích"},C3:{vi:"Nhận biết hình học",en:"Basic Shapes",hint:"Gọi tên các hình cơ bản"},C4:{vi:"Nhận biết động vật",en:"Animals",hint:"Gọi tên động vật và con vật yêu thích"}},[SpeakingRubricScoringVersion.KINDY_PLACEMENT_V1]:{C1:{vi:"Chào hỏi & Giới thiệu bản thân",en:"Greeting & Self-Introduction",hint:"Giao tiếp xã hội cơ bản"},C2:{vi:"Nhận biết số đếm (1–20)",en:"Cardinal Numbers (1–20)",hint:"Từ vựng số học"},C3:{vi:"Đọc bảng chữ cái",en:"The Alphabet",hint:"Nhận biết chữ cái"},C4:{vi:"Nhận biết hình dạng",en:"Shapes",hint:"Từ vựng hình học"},C5:{vi:"Nhận biết màu sắc",en:"Colours",hint:"Từ vựng màu sắc"},C6:{vi:"Nhận biết động vật",en:"Animals",hint:"Từ vựng chủ đề quen thuộc"},C7:{vi:"Nhận biết thức ăn",en:"Food/Drinks",hint:"Từ vựng chủ đề quen thuộc"}}},r={5:{text:"#166534",bg:"#dcfce7",accent:"#16a34a"},4:{text:"#15803d",bg:"#dcfce7",accent:"#22c55e"},3:{text:"#b45309",bg:"#fef3c7",accent:"#f59e0b"},2:{text:"#c2410c",bg:"#ffedd5",accent:"#f97316"},1:{text:"#b91c1c",bg:"#fee2e2",accent:"#ef4444"}},a={5:"Excellent",4:"Good",3:"Adequate",2:"Weak",1:"Very weak"},s={5:"Vượt kỳ vọng",4:"Đáp ứng kỳ vọng (Cao)",3:"Đáp ứng kỳ vọng (Thấp)",2:"Dưới kỳ vọng",1:"Không thực hiện"},l={[SpeakingRubricScoringVersion.TEENS_FOCUS_PEARSON_V2]:a,[SpeakingRubricScoringVersion.PRESCHOOL_PLACEMENT_V1]:s,[SpeakingRubricScoringVersion.KINDY_PLACEMENT_V1]:s},o={[KidsRubricSectionCode.WARM_UP]:{vi:"Khởi động",en:"Warm-up Questions"},[KidsRubricSectionCode.PART_1]:{vi:"Part 1 — Nhận diện qua tranh",en:"Picture Identification"},[KidsRubricSectionCode.PART_2]:{vi:"Part 2 — Đọc và cung cấp thông tin",en:"Reading and Giving Information"},[KidsRubricSectionCode.PART_3]:{vi:"Part 3 — Mô tả tranh",en:"Picture Description"}};function d({score:n}){const i=Math.max(0,Math.min(5,Math.round(n)));return e("span",{className:"inline-flex items-center gap-0.5","aria-label":`${i}/5`,children:Array.from({length:5}).map((n,c)=>e(t,{"aria-hidden":!0,className:c<i?"h-4 w-4 fill-[#FFC107] text-[#FFC107]":"h-4 w-4 fill-[#e6edf5] text-[#e6edf5]"},c))})}function h({rubric:t}){const i=c[t.scoringVersion]??{},s=l[t.scoringVersion]??a;return e("div",{className:"overflow-hidden rounded-xl border border-[#00AEEF]/20 shadow-sm",children:e("div",{className:"overflow-x-auto",children:n("table",{className:"w-full min-w-[640px] text-left text-sm text-slate-700",children:[e("thead",{className:"border-b border-[#00AEEF]/20 bg-[#f0f8ff] text-[#0054A6]",children:n("tr",{className:"text-center",children:[e("th",{scope:"col",className:"w-[30%] border-r border-[#00AEEF]/10 px-4 py-3 font-bold",children:"Tiêu chí"}),e("th",{scope:"col",className:"border-r border-[#00AEEF]/10 px-4 py-3 font-bold",children:"Nhận xét chi tiết"}),e("th",{scope:"col",className:"w-[22%] px-4 py-3 font-bold",children:"Điểm"})]})}),e("tbody",{className:"divide-y divide-slate-100",children:t.criteria.map(t=>{const c=i[t.code]??{vi:t.code,en:"",hint:""},a=Math.round(t.score),l=Math.max(1,Math.min(5,a)),o=s[l],h=r[l];return n("tr",{className:"align-top transition-colors hover:bg-slate-50/70",children:[n("td",{className:"border-r border-[#00AEEF]/10 px-4 py-4",style:{boxShadow:`inset 4px 0 0 ${h.accent}`},children:[e("div",{className:"font-bold text-slate-800",children:c.vi}),c.en?e("div",{className:"text-xs italic text-slate-500",children:c.en}):null,c.hint?e("div",{className:"mt-1 text-[11px] leading-snug text-slate-400",children:c.hint}):null]}),e("td",{className:"border-r border-[#00AEEF]/10 px-4 py-4 leading-relaxed text-slate-700",children:t.evidence?.trim()?t.evidence:e("span",{className:"italic text-slate-400",children:"Không có nhận xét chi tiết."})}),n("td",{className:"px-4 py-4",children:[e(d,{score:t.score}),n("div",{className:"mt-1.5 flex items-baseline gap-1",children:[e("span",{className:"text-lg font-black leading-none text-[#0054A6]",children:a}),e("span",{className:"text-xs font-semibold text-slate-400",children:"/ 5"})]}),o?e("span",{className:"mt-1.5 inline-block whitespace-nowrap rounded-full px-2.5 py-0.5 text-xs font-bold",style:{backgroundColor:h.bg,color:h.text},children:o}):null]})]},t.code)})})]})})})}function m({section:t}){const i=o[t.code]??{vi:t.code,en:""},c=t.maxScore>0?Math.max(0,Math.min(100,t.score/t.maxScore*100)):0;return n("div",{className:"overflow-hidden rounded-xl border border-[#00AEEF]/20 shadow-sm",children:[n("div",{className:"flex flex-col gap-2 border-b border-[#00AEEF]/20 bg-[#f0f8ff] px-4 py-3 sm:flex-row sm:items-center sm:justify-between",children:[n("div",{children:[e("div",{className:"font-bold text-[#0054A6]",children:i.vi}),i.en?e("div",{className:"text-xs italic text-slate-500",children:i.en}):null]}),n("div",{className:"flex items-center gap-3",children:[e("div",{className:"h-[9px] w-24 overflow-hidden rounded-full bg-[#e6edf5]",children:e("div",{className:"h-full rounded-full bg-[#4CAF50]",style:{width:`${c}%`}})}),n("div",{className:"whitespace-nowrap text-sm font-black text-[#0054A6]",children:[t.score,n("span",{className:"text-xs font-semibold text-slate-400",children:[" / ",t.maxScore]})]})]})]}),e("table",{className:"w-full text-left text-sm text-slate-700",children:e("tbody",{className:"divide-y divide-[#00AEEF]/10",children:t.questions.map(t=>n("tr",{className:"align-top hover:bg-slate-50",children:[e("td",{className:"w-[72px] px-4 py-3",children:n("span",{className:"inline-flex h-7 min-w-7 items-center justify-center rounded-full bg-[#eaf4ff] px-2 text-xs font-black text-[#0054A6]",children:["Câu ",t.questionNo]})}),n("td",{className:"w-[88px] whitespace-nowrap px-2 py-3 font-black text-[#0054A6]",children:[t.score,n("span",{className:"text-xs font-semibold text-slate-400",children:[" / ",t.maxScore]})]}),e("td",{className:"px-4 py-3 leading-relaxed text-slate-700",children:t.evidence?.trim()?t.evidence:e("span",{className:"italic text-slate-400",children:"Không có nhận xét chi tiết."})})]},t.questionNo))})})]})}export function SpeakingRubricSection({rubric:t,badgeNumber:c="4"}){const r=t.criteria?.length>0,a=(t.sections?.length??0)>0;return r||a?n("section",{className:"relative mt-8 rounded-[20px] border-2 border-[#00AEEF] px-5 pb-6 pt-11 md:px-8",children:[e(i,{number:c,title:"ĐÁNH GIÁ KỸ NĂNG NÓI"}),a?e("div",{className:"space-y-4",children:(t.sections??[]).map(n=>e(m,{section:n},n.code))}):e(h,{rubric:t})]}):null}
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Star } from 'lucide-react';
4
+ import { BadgeTitle } from './BadgeTitle';
5
+ export var SpeakingRubricScoringVersion;
6
+ (function (SpeakingRubricScoringVersion) {
7
+ SpeakingRubricScoringVersion["TEENS_FOCUS_PEARSON_V2"] = "TEENS_FOCUS_PEARSON_V2";
8
+ SpeakingRubricScoringVersion["PRESCHOOL_PLACEMENT_V1"] = "PRESCHOOL_PLACEMENT_V1";
9
+ SpeakingRubricScoringVersion["KINDY_PLACEMENT_V1"] = "KINDY_PLACEMENT_V1";
10
+ })(SpeakingRubricScoringVersion || (SpeakingRubricScoringVersion = {}));
11
+ export var KidsRubricSectionCode;
12
+ (function (KidsRubricSectionCode) {
13
+ KidsRubricSectionCode["WARM_UP"] = "WARM_UP";
14
+ KidsRubricSectionCode["PART_1"] = "PART_1";
15
+ KidsRubricSectionCode["PART_2"] = "PART_2";
16
+ KidsRubricSectionCode["PART_3"] = "PART_3";
17
+ })(KidsRubricSectionCode || (KidsRubricSectionCode = {}));
18
+ const CRITERION_LABELS_BY_VERSION = {
19
+ [SpeakingRubricScoringVersion.TEENS_FOCUS_PEARSON_V2]: {
20
+ C1: {
21
+ vi: 'Ngữ pháp & Từ vựng',
22
+ en: 'Grammar & Vocabulary',
23
+ hint: 'Cấu trúc câu, thì động từ và độ đa dạng từ vựng',
24
+ },
25
+ C2: {
26
+ vi: 'Phát âm',
27
+ en: 'Pronunciation',
28
+ hint: 'Độ rõ ràng, trọng âm từ và ngữ điệu câu',
29
+ },
30
+ C3: {
31
+ vi: 'Giao tiếp tương tác',
32
+ en: 'Interactive Communication',
33
+ hint: 'Phản hồi đủ ý và tự mở rộng câu trả lời',
34
+ },
35
+ C4: {
36
+ vi: 'Quản lý diễn ngôn',
37
+ en: 'Discourse Management',
38
+ hint: 'Mạch lạc, tổ chức và phát triển ý rõ ràng',
39
+ },
40
+ },
41
+ [SpeakingRubricScoringVersion.PRESCHOOL_PLACEMENT_V1]: {
42
+ C1: {
43
+ vi: 'Nhận biết số đếm (1–10)',
44
+ en: 'Cardinal Numbers (1–10)',
45
+ hint: 'Đếm 1–10 và nhận ra từng số',
46
+ },
47
+ C2: {
48
+ vi: 'Nhận biết màu sắc',
49
+ en: 'Basic Colours',
50
+ hint: 'Gọi tên màu sắc và màu yêu thích',
51
+ },
52
+ C3: {
53
+ vi: 'Nhận biết hình học',
54
+ en: 'Basic Shapes',
55
+ hint: 'Gọi tên các hình cơ bản',
56
+ },
57
+ C4: {
58
+ vi: 'Nhận biết động vật',
59
+ en: 'Animals',
60
+ hint: 'Gọi tên động vật và con vật yêu thích',
61
+ },
62
+ },
63
+ [SpeakingRubricScoringVersion.KINDY_PLACEMENT_V1]: {
64
+ C1: {
65
+ vi: 'Chào hỏi & Giới thiệu bản thân',
66
+ en: 'Greeting & Self-Introduction',
67
+ hint: 'Giao tiếp xã hội cơ bản',
68
+ },
69
+ C2: {
70
+ vi: 'Nhận biết số đếm (1–20)',
71
+ en: 'Cardinal Numbers (1–20)',
72
+ hint: 'Từ vựng số học',
73
+ },
74
+ C3: {
75
+ vi: 'Đọc bảng chữ cái',
76
+ en: 'The Alphabet',
77
+ hint: 'Nhận biết chữ cái',
78
+ },
79
+ C4: {
80
+ vi: 'Nhận biết hình dạng',
81
+ en: 'Shapes',
82
+ hint: 'Từ vựng hình học',
83
+ },
84
+ C5: {
85
+ vi: 'Nhận biết màu sắc',
86
+ en: 'Colours',
87
+ hint: 'Từ vựng màu sắc',
88
+ },
89
+ C6: {
90
+ vi: 'Nhận biết động vật',
91
+ en: 'Animals',
92
+ hint: 'Từ vựng chủ đề quen thuộc',
93
+ },
94
+ C7: {
95
+ vi: 'Nhận biết thức ăn',
96
+ en: 'Food/Drinks',
97
+ hint: 'Từ vựng chủ đề quen thuộc',
98
+ },
99
+ },
100
+ };
101
+ const SCORE_BAND_STYLES = {
102
+ 5: { text: '#166534', bg: '#dcfce7', accent: '#16a34a' },
103
+ 4: { text: '#15803d', bg: '#dcfce7', accent: '#22c55e' },
104
+ 3: { text: '#b45309', bg: '#fef3c7', accent: '#f59e0b' },
105
+ 2: { text: '#c2410c', bg: '#ffedd5', accent: '#f97316' },
106
+ 1: { text: '#b91c1c', bg: '#fee2e2', accent: '#ef4444' },
107
+ };
108
+ const TEENS_BAND_LABELS = {
109
+ 5: 'Excellent',
110
+ 4: 'Good',
111
+ 3: 'Adequate',
112
+ 2: 'Weak',
113
+ 1: 'Very weak',
114
+ };
115
+ const EXPECTATIONS_BAND_LABELS = {
116
+ 5: 'Vượt kỳ vọng',
117
+ 4: 'Đáp ứng kỳ vọng (Cao)',
118
+ 3: 'Đáp ứng kỳ vọng (Thấp)',
119
+ 2: 'Dưới kỳ vọng',
120
+ 1: 'Không thực hiện',
121
+ };
122
+ const BAND_LABELS_BY_VERSION = {
123
+ [SpeakingRubricScoringVersion.TEENS_FOCUS_PEARSON_V2]: TEENS_BAND_LABELS,
124
+ [SpeakingRubricScoringVersion.PRESCHOOL_PLACEMENT_V1]: EXPECTATIONS_BAND_LABELS,
125
+ [SpeakingRubricScoringVersion.KINDY_PLACEMENT_V1]: EXPECTATIONS_BAND_LABELS,
126
+ };
127
+ const KIDS_SECTION_LABELS = {
128
+ [KidsRubricSectionCode.WARM_UP]: { vi: 'Khởi động', en: 'Warm-up Questions' },
129
+ [KidsRubricSectionCode.PART_1]: { vi: 'Part 1 — Nhận diện qua tranh', en: 'Picture Identification' },
130
+ [KidsRubricSectionCode.PART_2]: {
131
+ vi: 'Part 2 — Đọc và cung cấp thông tin',
132
+ en: 'Reading and Giving Information',
133
+ },
134
+ [KidsRubricSectionCode.PART_3]: { vi: 'Part 3 — Mô tả tranh', en: 'Picture Description' },
135
+ };
136
+ function StarRating({ score }) {
137
+ const clamped = Math.max(0, Math.min(5, Math.round(score)));
138
+ return (_jsx("span", { className: "inline-flex items-center gap-0.5", "aria-label": `${clamped}/5`, children: Array.from({ length: 5 }).map((_, i) => (_jsx(Star, { "aria-hidden": true, className: i < clamped
139
+ ? 'h-4 w-4 fill-[#FFC107] text-[#FFC107]'
140
+ : 'h-4 w-4 fill-[#e6edf5] text-[#e6edf5]' }, i))) }));
141
+ }
142
+ function CriteriaTable({ rubric }) {
143
+ const labels = CRITERION_LABELS_BY_VERSION[rubric.scoringVersion] ?? {};
144
+ const bandLabels = BAND_LABELS_BY_VERSION[rubric.scoringVersion] ?? TEENS_BAND_LABELS;
145
+ return (_jsx("div", { className: "overflow-hidden rounded-xl border border-[#00AEEF]/20 shadow-sm", children: _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full min-w-[640px] text-left text-sm text-slate-700", children: [_jsx("thead", { className: "border-b border-[#00AEEF]/20 bg-[#f0f8ff] text-[#0054A6]", children: _jsxs("tr", { className: "text-center", children: [_jsx("th", { scope: "col", className: "w-[30%] border-r border-[#00AEEF]/10 px-4 py-3 font-bold", children: "Ti\u00EAu ch\u00ED" }), _jsx("th", { scope: "col", className: "border-r border-[#00AEEF]/10 px-4 py-3 font-bold", children: "Nh\u1EADn x\u00E9t chi ti\u1EBFt" }), _jsx("th", { scope: "col", className: "w-[22%] px-4 py-3 font-bold", children: "\u0110i\u1EC3m" })] }) }), _jsx("tbody", { className: "divide-y divide-slate-100", children: rubric.criteria.map((c) => {
146
+ const label = labels[c.code] ?? { vi: c.code, en: '', hint: '' };
147
+ const rounded = Math.round(c.score);
148
+ const clamped = Math.max(1, Math.min(5, rounded));
149
+ const bandLabel = bandLabels[clamped];
150
+ const band = SCORE_BAND_STYLES[clamped];
151
+ return (_jsxs("tr", { className: "align-top transition-colors hover:bg-slate-50/70", children: [_jsxs("td", { className: "border-r border-[#00AEEF]/10 px-4 py-4", style: { boxShadow: `inset 4px 0 0 ${band.accent}` }, children: [_jsx("div", { className: "font-bold text-slate-800", children: label.vi }), label.en ? _jsx("div", { className: "text-xs italic text-slate-500", children: label.en }) : null, label.hint ? (_jsx("div", { className: "mt-1 text-[11px] leading-snug text-slate-400", children: label.hint })) : null] }), _jsx("td", { className: "border-r border-[#00AEEF]/10 px-4 py-4 leading-relaxed text-slate-700", children: c.evidence?.trim() ? (c.evidence) : (_jsx("span", { className: "italic text-slate-400", children: "Kh\u00F4ng c\u00F3 nh\u1EADn x\u00E9t chi ti\u1EBFt." })) }), _jsxs("td", { className: "px-4 py-4", children: [_jsx(StarRating, { score: c.score }), _jsxs("div", { className: "mt-1.5 flex items-baseline gap-1", children: [_jsx("span", { className: "text-lg font-black leading-none text-[#0054A6]", children: rounded }), _jsx("span", { className: "text-xs font-semibold text-slate-400", children: "/ 5" })] }), bandLabel ? (_jsx("span", { className: "mt-1.5 inline-block whitespace-nowrap rounded-full px-2.5 py-0.5 text-xs font-bold", style: { backgroundColor: band.bg, color: band.text }, children: bandLabel })) : null] })] }, c.code));
152
+ }) })] }) }) }));
153
+ }
154
+ function SectionCard({ section }) {
155
+ const label = KIDS_SECTION_LABELS[section.code] ?? { vi: section.code, en: '' };
156
+ const percentage = section.maxScore > 0
157
+ ? Math.max(0, Math.min(100, (section.score / section.maxScore) * 100))
158
+ : 0;
159
+ return (_jsxs("div", { className: "overflow-hidden rounded-xl border border-[#00AEEF]/20 shadow-sm", children: [_jsxs("div", { className: "flex flex-col gap-2 border-b border-[#00AEEF]/20 bg-[#f0f8ff] px-4 py-3 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { children: [_jsx("div", { className: "font-bold text-[#0054A6]", children: label.vi }), label.en ? _jsx("div", { className: "text-xs italic text-slate-500", children: label.en }) : null] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "h-[9px] w-24 overflow-hidden rounded-full bg-[#e6edf5]", children: _jsx("div", { className: "h-full rounded-full bg-[#4CAF50]", style: { width: `${percentage}%` } }) }), _jsxs("div", { className: "whitespace-nowrap text-sm font-black text-[#0054A6]", children: [section.score, _jsxs("span", { className: "text-xs font-semibold text-slate-400", children: [" / ", section.maxScore] })] })] })] }), _jsx("table", { className: "w-full text-left text-sm text-slate-700", children: _jsx("tbody", { className: "divide-y divide-[#00AEEF]/10", children: section.questions.map((q) => (_jsxs("tr", { className: "align-top hover:bg-slate-50", children: [_jsx("td", { className: "w-[72px] px-4 py-3", children: _jsxs("span", { className: "inline-flex h-7 min-w-7 items-center justify-center rounded-full bg-[#eaf4ff] px-2 text-xs font-black text-[#0054A6]", children: ["C\u00E2u ", q.questionNo] }) }), _jsxs("td", { className: "w-[88px] whitespace-nowrap px-2 py-3 font-black text-[#0054A6]", children: [q.score, _jsxs("span", { className: "text-xs font-semibold text-slate-400", children: [" / ", q.maxScore] })] }), _jsx("td", { className: "px-4 py-3 leading-relaxed text-slate-700", children: q.evidence?.trim() ? (q.evidence) : (_jsx("span", { className: "italic text-slate-400", children: "Kh\u00F4ng c\u00F3 nh\u1EADn x\u00E9t chi ti\u1EBFt." })) })] }, q.questionNo))) }) })] }));
160
+ }
161
+ /**
162
+ * Attempt-level speaking rubric breakdown for TEENS / PRESCHOOL / KINDY / KIDS.
163
+ * Source: oe-exam-fe/.../review/components/SpeakingRubricSection.tsx
164
+ */
165
+ export function SpeakingRubricSection({ rubric, badgeNumber = '4', }) {
166
+ const hasCriteria = rubric.criteria?.length > 0;
167
+ const hasSections = (rubric.sections?.length ?? 0) > 0;
168
+ if (!hasCriteria && !hasSections)
169
+ return null;
170
+ return (_jsxs("section", { className: "relative mt-8 rounded-[20px] border-2 border-[#00AEEF] px-5 pb-6 pt-11 md:px-8", children: [_jsx(BadgeTitle, { number: badgeNumber, title: "\u0110\u00C1NH GI\u00C1 K\u1EF8 N\u0102NG N\u00D3I" }), hasSections ? (_jsx("div", { className: "space-y-4", children: (rubric.sections ?? []).map((section) => (_jsx(SectionCard, { section: section }, section.code))) })) : (_jsx(CriteriaTable, { rubric: rubric }))] }));
171
+ }