@tinyweb_dev/oe-exam-sdk 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (371) hide show
  1. package/README.md +112 -13
  2. package/dist/api/contest-rooms.d.ts +13 -0
  3. package/dist/api/contest-rooms.js +1 -0
  4. package/dist/api/contest-rooms.types.d.ts +47 -0
  5. package/dist/api/contest-rooms.types.js +1 -0
  6. package/dist/api/exam-entry.d.ts +14 -0
  7. package/dist/api/exam-entry.js +1 -0
  8. package/dist/api/exam-entry.types.d.ts +93 -0
  9. package/dist/api/exam-entry.types.js +1 -0
  10. package/dist/api/index.d.ts +2 -0
  11. package/dist/api/index.js +1 -1
  12. package/dist/api/result-review.d.ts +2 -1
  13. package/dist/api/result-review.js +1 -1
  14. package/dist/api/result-review.types.d.ts +69 -3
  15. package/dist/api/result-review.types.js +1 -1
  16. package/dist/components/exams/entry/EntryRestartDialog.d.ts +12 -0
  17. package/dist/components/exams/entry/EntryRestartDialog.js +1 -0
  18. package/dist/components/exams/entry/StudentExamEntryPageContainer.d.ts +31 -0
  19. package/dist/components/exams/entry/StudentExamEntryPageContainer.js +1 -0
  20. package/dist/components/exams/entry/exam-entry.states.d.ts +22 -0
  21. package/dist/components/exams/entry/exam-entry.states.js +1 -0
  22. package/dist/components/exams/entry/exam-entry.utils.d.ts +16 -0
  23. package/dist/components/exams/entry/exam-entry.utils.js +1 -0
  24. package/dist/components/exams/entry/fullscreen-loading.d.ts +5 -0
  25. package/dist/components/exams/entry/fullscreen-loading.js +1 -0
  26. package/dist/components/exams/entry/index.d.ts +7 -0
  27. package/dist/components/exams/entry/index.js +1 -0
  28. package/dist/components/exams/index.d.ts +8 -0
  29. package/dist/components/exams/index.js +1 -1
  30. package/dist/components/exams/rooms/StudentContestRoomsPageContainer.d.ts +18 -0
  31. package/dist/components/exams/rooms/StudentContestRoomsPageContainer.js +1 -0
  32. package/dist/components/exams/rooms/contest-rooms.utils.d.ts +32 -0
  33. package/dist/components/exams/rooms/contest-rooms.utils.js +1 -0
  34. package/dist/components/exams/rooms/index.d.ts +3 -0
  35. package/dist/components/exams/rooms/index.js +1 -0
  36. package/dist/components/exams/take/ExamTakingApiContext.d.ts +10 -0
  37. package/dist/components/exams/take/ExamTakingApiContext.js +1 -0
  38. package/dist/components/exams/take/ExamTakingPageContainer.d.ts +28 -4
  39. package/dist/components/exams/take/ExamTakingPageContainer.js +1 -1
  40. package/dist/components/exams/take/components/QuestionRenderer.d.ts +25 -0
  41. package/dist/components/exams/take/components/QuestionRenderer.js +1 -0
  42. package/dist/components/exams/take/components/index.d.ts +10 -0
  43. package/dist/components/exams/take/components/index.js +1 -0
  44. package/dist/components/exams/take/components/question-renderers/ArticlesViewer.d.ts +7 -0
  45. package/dist/components/exams/take/components/question-renderers/ArticlesViewer.js +1 -0
  46. package/dist/components/exams/take/components/question-renderers/MoversAnswerTheQuestionRenderer.d.ts +22 -0
  47. package/dist/components/exams/take/components/question-renderers/MoversAnswerTheQuestionRenderer.js +1 -0
  48. package/dist/components/exams/take/components/question-renderers/MoversChooseAdjectiveRenderer.d.ts +14 -0
  49. package/dist/components/exams/take/components/question-renderers/MoversChooseAdjectiveRenderer.js +1 -0
  50. package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.d.ts +2 -0
  51. package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.js +1 -0
  52. package/dist/components/exams/take/components/question-renderers/MoversColoringRenderer.d.ts +3 -0
  53. package/dist/components/exams/take/components/question-renderers/MoversColoringRenderer.js +1 -0
  54. package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.d.ts +2 -0
  55. package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.js +1 -0
  56. package/dist/components/exams/take/components/question-renderers/MoversGridFillRenderer.d.ts +2 -0
  57. package/dist/components/exams/take/components/question-renderers/MoversGridFillRenderer.js +1 -0
  58. package/dist/components/exams/take/components/question-renderers/MoversLabelThePictureRenderer.d.ts +2 -0
  59. package/dist/components/exams/take/components/question-renderers/MoversLabelThePictureRenderer.js +1 -0
  60. package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.d.ts +21 -0
  61. package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.js +1 -0
  62. package/dist/components/exams/take/components/question-renderers/MoversMatchByWritingAnswerRenderer.d.ts +19 -0
  63. package/dist/components/exams/take/components/question-renderers/MoversMatchByWritingAnswerRenderer.js +1 -0
  64. package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.d.ts +2 -0
  65. package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.js +1 -0
  66. package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.d.ts +2 -0
  67. package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.js +1 -0
  68. package/dist/components/exams/take/components/question-renderers/MoversReadingPassageRenderer.d.ts +2 -0
  69. package/dist/components/exams/take/components/question-renderers/MoversReadingPassageRenderer.js +1 -0
  70. package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.d.ts +20 -0
  71. package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.js +1 -0
  72. package/dist/components/exams/take/components/question-renderers/MoversWordFillParagraphRenderer.d.ts +32 -0
  73. package/dist/components/exams/take/components/question-renderers/MoversWordFillParagraphRenderer.js +1 -0
  74. package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.d.ts +18 -0
  75. package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.js +1 -0
  76. package/dist/components/exams/take/components/question-renderers/MoversWordOrderingRenderer.d.ts +19 -0
  77. package/dist/components/exams/take/components/question-renderers/MoversWordOrderingRenderer.js +1 -0
  78. package/dist/components/exams/take/components/question-renderers/MoversWriteSentencesRenderer.d.ts +22 -0
  79. package/dist/components/exams/take/components/question-renderers/MoversWriteSentencesRenderer.js +1 -0
  80. package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.d.ts +18 -0
  81. package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.js +1 -0
  82. package/dist/components/exams/take/components/question-renderers/index.d.ts +19 -0
  83. package/dist/components/exams/take/components/question-renderers/index.js +1 -0
  84. package/dist/components/exams/take/components/speaking/FindObjectInPicture.module.css +133 -0
  85. package/dist/components/exams/take/components/speaking/SpeakingAudioPlayer.d.ts +9 -0
  86. package/dist/components/exams/take/components/speaking/SpeakingAudioPlayer.js +1 -0
  87. package/dist/components/exams/take/components/speaking/SpeakingCompareImages.module.css +153 -0
  88. package/dist/components/exams/take/components/speaking/SpeakingContentFrame.d.ts +7 -0
  89. package/dist/components/exams/take/components/speaking/SpeakingContentFrame.js +1 -0
  90. package/dist/components/exams/take/components/speaking/SpeakingDragObjects.module.css +238 -0
  91. package/dist/components/exams/take/components/speaking/SpeakingExamLayout.d.ts +27 -0
  92. package/dist/components/exams/take/components/speaking/SpeakingExamLayout.js +1 -0
  93. package/dist/components/exams/take/components/speaking/SpeakingHeader.d.ts +6 -0
  94. package/dist/components/exams/take/components/speaking/SpeakingHeader.js +1 -0
  95. package/dist/components/exams/take/components/speaking/SpeakingInfoExchange.module.css +193 -0
  96. package/dist/components/exams/take/components/speaking/SpeakingInfoExchangeSummerSky.module.css +238 -0
  97. package/dist/components/exams/take/components/speaking/SpeakingInstructionBar.d.ts +5 -0
  98. package/dist/components/exams/take/components/speaking/SpeakingInstructionBar.js +1 -0
  99. package/dist/components/exams/take/components/speaking/SpeakingMicButton.d.ts +14 -0
  100. package/dist/components/exams/take/components/speaking/SpeakingMicButton.js +1 -0
  101. package/dist/components/exams/take/components/speaking/SpeakingNavButton.d.ts +7 -0
  102. package/dist/components/exams/take/components/speaking/SpeakingNavButton.js +1 -0
  103. package/dist/components/exams/take/components/speaking/SpeakingPartBadge.d.ts +6 -0
  104. package/dist/components/exams/take/components/speaking/SpeakingPartBadge.js +1 -0
  105. package/dist/components/exams/take/components/speaking/SpeakingReadDisplayedContent.module.css +115 -0
  106. package/dist/components/exams/take/components/speaking/SpeakingRecordingPreview.d.ts +11 -0
  107. package/dist/components/exams/take/components/speaking/SpeakingRecordingPreview.js +1 -0
  108. package/dist/components/exams/take/components/speaking/SpeakingReportErrorButton.d.ts +1 -0
  109. package/dist/components/exams/take/components/speaking/SpeakingReportErrorButton.js +1 -0
  110. package/dist/components/exams/take/components/speaking/SpeakingStoryImages.module.css +231 -0
  111. package/dist/components/exams/take/components/speaking/SpeakingVideoIntro.d.ts +13 -0
  112. package/dist/components/exams/take/components/speaking/SpeakingVideoIntro.js +1 -0
  113. package/dist/components/exams/take/components/speaking/index.d.ts +1 -0
  114. package/dist/components/exams/take/components/speaking/index.js +1 -0
  115. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseAnswerGroupRenderer.d.ts +16 -0
  116. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseAnswerGroupRenderer.js +1 -0
  117. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseObjectsRenderer.d.ts +16 -0
  118. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseObjectsRenderer.js +1 -0
  119. package/dist/components/exams/take/components/speaking/renderers/SpeakingCompareImagesRenderer.d.ts +17 -0
  120. package/dist/components/exams/take/components/speaking/renderers/SpeakingCompareImagesRenderer.js +1 -0
  121. package/dist/components/exams/take/components/speaking/renderers/SpeakingConversationRenderer.d.ts +16 -0
  122. package/dist/components/exams/take/components/speaking/renderers/SpeakingConversationRenderer.js +1 -0
  123. package/dist/components/exams/take/components/speaking/renderers/SpeakingCueCardRenderer.d.ts +17 -0
  124. package/dist/components/exams/take/components/speaking/renderers/SpeakingCueCardRenderer.js +1 -0
  125. package/dist/components/exams/take/components/speaking/renderers/SpeakingDescribeImageRenderer.d.ts +18 -0
  126. package/dist/components/exams/take/components/speaking/renderers/SpeakingDescribeImageRenderer.js +1 -0
  127. package/dist/components/exams/take/components/speaking/renderers/SpeakingDragObjectsRenderer.d.ts +16 -0
  128. package/dist/components/exams/take/components/speaking/renderers/SpeakingDragObjectsRenderer.js +1 -0
  129. package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.d.ts +16 -0
  130. package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.js +1 -0
  131. package/dist/components/exams/take/components/speaking/renderers/SpeakingInfoExchangeRenderer.d.ts +16 -0
  132. package/dist/components/exams/take/components/speaking/renderers/SpeakingInfoExchangeRenderer.js +1 -0
  133. package/dist/components/exams/take/components/speaking/renderers/SpeakingListenAndSpeakAnswerRenderer.d.ts +16 -0
  134. package/dist/components/exams/take/components/speaking/renderers/SpeakingListenAndSpeakAnswerRenderer.js +1 -0
  135. package/dist/components/exams/take/components/speaking/renderers/SpeakingOddOneOutRenderer.d.ts +16 -0
  136. package/dist/components/exams/take/components/speaking/renderers/SpeakingOddOneOutRenderer.js +1 -0
  137. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionListRenderer.d.ts +26 -0
  138. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionListRenderer.js +1 -0
  139. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.d.ts +32 -0
  140. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.js +1 -0
  141. package/dist/components/exams/take/components/speaking/renderers/SpeakingReadDisplayedContentRenderer.d.ts +17 -0
  142. package/dist/components/exams/take/components/speaking/renderers/SpeakingReadDisplayedContentRenderer.js +1 -0
  143. package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQARenderer.d.ts +17 -0
  144. package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQARenderer.js +1 -0
  145. package/dist/components/exams/take/components/speaking/renderers/SpeakingStoryImagesRenderer.d.ts +17 -0
  146. package/dist/components/exams/take/components/speaking/renderers/SpeakingStoryImagesRenderer.js +1 -0
  147. package/dist/components/exams/take/components/speaking/renderers/index.d.ts +13 -0
  148. package/dist/components/exams/take/components/speaking/renderers/index.js +1 -0
  149. package/dist/components/exams/take/hooks/index.d.ts +2 -0
  150. package/dist/components/exams/take/hooks/index.js +1 -0
  151. package/dist/components/exams/take/hooks/useAnswerAutosave.d.ts +27 -0
  152. package/dist/components/exams/take/hooks/useAnswerAutosave.js +1 -0
  153. package/dist/components/exams/take/hooks/useAttemptSubmit.d.ts +29 -0
  154. package/dist/components/exams/take/hooks/useAttemptSubmit.js +1 -0
  155. package/dist/components/exams/take/hooks/useAutoSave.d.ts +20 -0
  156. package/dist/components/exams/take/hooks/useAutoSave.js +1 -0
  157. package/dist/components/exams/take/hooks/useExamCountdown.d.ts +22 -0
  158. package/dist/components/exams/take/hooks/useExamCountdown.js +1 -0
  159. package/dist/components/exams/take/hooks/useExamTimer.d.ts +21 -0
  160. package/dist/components/exams/take/hooks/useExamTimer.js +1 -0
  161. package/dist/components/exams/take/hooks/useProctoringCamera.d.ts +19 -0
  162. package/dist/components/exams/take/hooks/useProctoringCamera.js +1 -0
  163. package/dist/components/exams/take/hooks/useProctoringSnapshot.d.ts +25 -0
  164. package/dist/components/exams/take/hooks/useProctoringSnapshot.js +1 -0
  165. package/dist/components/exams/take/hooks/useSpeakingConversationAudio.d.ts +19 -0
  166. package/dist/components/exams/take/hooks/useSpeakingConversationAudio.js +1 -0
  167. package/dist/components/exams/take/hooks/useSpeakingNavigation.d.ts +37 -0
  168. package/dist/components/exams/take/hooks/useSpeakingNavigation.js +1 -0
  169. package/dist/components/exams/take/hooks/useSpeakingRecorder.d.ts +45 -5
  170. package/dist/components/exams/take/hooks/useSpeakingRecorder.js +1 -1
  171. package/dist/components/exams/take/hooks/useSpeakingRendererSetup.d.ts +39 -0
  172. package/dist/components/exams/take/hooks/useSpeakingRendererSetup.js +1 -0
  173. package/dist/components/exams/take/hooks/useToeicAudio.d.ts +17 -0
  174. package/dist/components/exams/take/hooks/useToeicAudio.js +1 -0
  175. package/dist/components/exams/take/index.d.ts +9 -1
  176. package/dist/components/exams/take/index.js +1 -1
  177. package/dist/components/exams/take/types/speaking-cue-card.types.d.ts +10 -0
  178. package/dist/components/exams/take/types/speaking-cue-card.types.js +1 -0
  179. package/dist/components/exams/take/types/speaking.types.d.ts +153 -0
  180. package/dist/components/exams/take/types/speaking.types.js +1 -0
  181. package/dist/components/exams/take/types.d.ts +286 -1
  182. package/dist/components/exams/take/utils/answer-transformers.d.ts +26 -0
  183. package/dist/components/exams/take/utils/answer-transformers.js +1 -0
  184. package/dist/components/exams/take/utils/coloring-assignments.d.ts +5 -0
  185. package/dist/components/exams/take/utils/coloring-assignments.js +1 -0
  186. package/dist/components/exams/take/utils/question-transformers.d.ts +362 -0
  187. package/dist/components/exams/take/utils/question-transformers.js +1 -0
  188. package/dist/components/features/exam-entry/entry-state-cards.d.ts +19 -0
  189. package/dist/components/features/exam-entry/entry-state-cards.js +1 -0
  190. package/dist/components/features/exam-entry/index.d.ts +2 -0
  191. package/dist/components/features/exam-entry/index.js +1 -0
  192. package/dist/components/features/exam-entry/themed/CambridgeYleWaitingRoom.d.ts +12 -0
  193. package/dist/components/features/exam-entry/themed/CambridgeYleWaitingRoom.js +1 -0
  194. package/dist/components/features/exam-entry/themed/ThemedWaitingRoom.d.ts +14 -0
  195. package/dist/components/features/exam-entry/themed/ThemedWaitingRoom.js +1 -0
  196. package/dist/components/features/exam-entry/themed/ToeicWaitingRoom.d.ts +16 -0
  197. package/dist/components/features/exam-entry/themed/ToeicWaitingRoom.js +1 -0
  198. package/dist/components/features/exam-entry/themed/components/CloseButton.d.ts +9 -0
  199. package/dist/components/features/exam-entry/themed/components/CloseButton.js +1 -0
  200. package/dist/components/features/exam-entry/themed/components/ExamInfoPanel.d.ts +13 -0
  201. package/dist/components/features/exam-entry/themed/components/ExamInfoPanel.js +1 -0
  202. package/dist/components/features/exam-entry/themed/components/ModeSelector.d.ts +7 -0
  203. package/dist/components/features/exam-entry/themed/components/ModeSelector.js +1 -0
  204. package/dist/components/features/exam-entry/themed/components/StartButton.d.ts +11 -0
  205. package/dist/components/features/exam-entry/themed/components/StartButton.js +1 -0
  206. package/dist/components/features/exam-entry/themed/components/index.d.ts +4 -0
  207. package/dist/components/features/exam-entry/themed/components/index.js +1 -0
  208. package/dist/components/features/exam-entry/themed/index.d.ts +1 -0
  209. package/dist/components/features/exam-entry/themed/index.js +1 -0
  210. package/dist/components/results/ResultReviewPageContainer.d.ts +16 -2
  211. package/dist/components/results/ResultReviewPageContainer.js +1 -1
  212. package/dist/components/results/ReviewQuestionRenderer.d.ts +11 -1
  213. package/dist/components/results/ReviewQuestionRenderer.js +1 -1
  214. package/dist/components/results/hooks/useResultReviewPolling.d.ts +37 -0
  215. package/dist/components/results/hooks/useResultReviewPolling.js +1 -0
  216. package/dist/components/results/index.d.ts +36 -1
  217. package/dist/components/results/index.js +1 -1
  218. package/dist/components/results/renderers/QuestionExplanations.d.ts +22 -0
  219. package/dist/components/results/renderers/QuestionExplanations.js +1 -0
  220. package/dist/components/results/renderers/ReviewChooseAdjectiveRenderer.d.ts +13 -0
  221. package/dist/components/results/renderers/ReviewChooseAdjectiveRenderer.js +1 -0
  222. package/dist/components/results/renderers/ReviewChooseBestAnswerRenderer.d.ts +22 -0
  223. package/dist/components/results/renderers/ReviewChooseBestAnswerRenderer.js +1 -0
  224. package/dist/components/results/renderers/ReviewColoringRenderer.d.ts +16 -0
  225. package/dist/components/results/renderers/ReviewColoringRenderer.js +1 -0
  226. package/dist/components/results/renderers/ReviewListenAndWriteRenderer.d.ts +18 -0
  227. package/dist/components/results/renderers/ReviewListenAndWriteRenderer.js +1 -0
  228. package/dist/components/results/renderers/ReviewListenChooseAnswerGroupRenderer.d.ts +25 -0
  229. package/dist/components/results/renderers/ReviewListenChooseAnswerGroupRenderer.js +1 -0
  230. package/dist/components/results/renderers/ReviewListenChooseObjectsRenderer.d.ts +25 -0
  231. package/dist/components/results/renderers/ReviewListenChooseObjectsRenderer.js +1 -0
  232. package/dist/components/results/renderers/ReviewListenDragObjectsRenderer.d.ts +25 -0
  233. package/dist/components/results/renderers/ReviewListenDragObjectsRenderer.js +1 -0
  234. package/dist/components/results/renderers/ReviewListeningHeader.d.ts +44 -0
  235. package/dist/components/results/renderers/ReviewListeningHeader.js +1 -0
  236. package/dist/components/results/renderers/ReviewSpeakingAIPanel.d.ts +17 -0
  237. package/dist/components/results/renderers/ReviewSpeakingAIPanel.js +1 -0
  238. package/dist/components/results/renderers/ReviewSpeakingMedia.d.ts +39 -0
  239. package/dist/components/results/renderers/ReviewSpeakingMedia.js +1 -0
  240. package/dist/components/results/renderers/ReviewSpeakingQuestionItem.d.ts +5 -0
  241. package/dist/components/results/renderers/ReviewSpeakingQuestionItem.js +1 -0
  242. package/dist/components/results/renderers/ReviewSpeakingRenderer.d.ts +3 -0
  243. package/dist/components/results/renderers/ReviewSpeakingRenderer.js +1 -0
  244. package/dist/components/results/renderers/ReviewSpeakingRenderer.types.d.ts +80 -0
  245. package/dist/components/results/renderers/ReviewSpeakingRenderer.types.js +1 -0
  246. package/dist/components/results/renderers/review-question-body-dedicated.d.ts +15 -0
  247. package/dist/components/results/renderers/review-question-body-dedicated.js +1 -0
  248. package/dist/components/results/renderers/review-question-body-movers.d.ts +17 -0
  249. package/dist/components/results/renderers/review-question-body-movers.js +1 -0
  250. package/dist/components/results/renderers/review-speaking-map.d.ts +7 -0
  251. package/dist/components/results/renderers/review-speaking-map.js +1 -0
  252. package/dist/components/results/report/BadgeTitle.d.ts +5 -0
  253. package/dist/components/results/report/BadgeTitle.js +1 -0
  254. package/dist/components/results/report/ExamSkillRow.d.ts +14 -0
  255. package/dist/components/results/report/ExamSkillRow.js +1 -0
  256. package/dist/components/results/report/OceanEduExamReport.d.ts +31 -0
  257. package/dist/components/results/report/OceanEduExamReport.js +1 -0
  258. package/dist/components/results/report/OceanEduSpeakingReport.d.ts +26 -0
  259. package/dist/components/results/report/OceanEduSpeakingReport.js +1 -0
  260. package/dist/components/results/report/OverallAssessmentSection.d.ts +24 -0
  261. package/dist/components/results/report/OverallAssessmentSection.js +1 -0
  262. package/dist/components/results/report/ResultErrorState.d.ts +14 -0
  263. package/dist/components/results/report/ResultErrorState.js +1 -0
  264. package/dist/components/results/report/ResultLoadingState.d.ts +11 -0
  265. package/dist/components/results/report/ResultLoadingState.js +1 -0
  266. package/dist/components/results/report/ResultNotPublicState.d.ts +16 -0
  267. package/dist/components/results/report/ResultNotPublicState.js +1 -0
  268. package/dist/components/results/report/SpeakingReportParts.d.ts +4 -0
  269. package/dist/components/results/report/SpeakingReportParts.js +1 -0
  270. package/dist/components/results/report/SpeakingReportShared.d.ts +36 -0
  271. package/dist/components/results/report/SpeakingReportShared.js +1 -0
  272. package/dist/components/results/report/SpeakingRubricSection.d.ts +21 -0
  273. package/dist/components/results/report/SpeakingRubricSection.js +1 -0
  274. package/dist/components/results/report/assets/dofu2.png +0 -0
  275. package/dist/components/results/report/assets/dofu4.png +0 -0
  276. package/dist/components/results/report/assets/logo-ocean.png +0 -0
  277. package/dist/components/results/report/assets/penguin-main.png +0 -0
  278. package/dist/components/results/report/assets/penguin-small.png +0 -0
  279. package/dist/components/results/report/speaking-report.utils.d.ts +37 -0
  280. package/dist/components/results/report/speaking-report.utils.js +1 -0
  281. package/dist/components/results/review-data.d.ts +1 -0
  282. package/dist/components/results/review-data.js +1 -1
  283. package/dist/components/results/review-status.utils.d.ts +12 -0
  284. package/dist/components/results/review-status.utils.js +1 -0
  285. package/dist/components/results/review-types.d.ts +14 -0
  286. package/dist/components/results/speaking/SpeakingResultAudioPlayer.d.ts +17 -0
  287. package/dist/components/results/speaking/SpeakingResultAudioPlayer.js +1 -0
  288. package/dist/components/results/speaking/SpeakingReviewResult.d.ts +30 -0
  289. package/dist/components/results/speaking/SpeakingReviewResult.js +1 -0
  290. package/dist/components/results/utils/review-score.utils.d.ts +21 -0
  291. package/dist/components/results/utils/review-score.utils.js +1 -0
  292. package/dist/components/results/utils/speaking-summary.d.ts +41 -0
  293. package/dist/components/results/utils/speaking-summary.js +1 -0
  294. package/dist/components/results/utils/transform-speaking-review.d.ts +62 -0
  295. package/dist/components/results/utils/transform-speaking-review.js +1 -0
  296. package/dist/components/shared/audio/SpeakingAudioPlayer.d.ts +12 -0
  297. package/dist/components/shared/audio/SpeakingAudioPlayer.js +1 -0
  298. package/dist/components/shared/audio/SpeakingAudioPlayer.module.css +115 -0
  299. package/dist/components/shared/audio/assets/fr-image-part1-border.png +0 -0
  300. package/dist/components/shared/audio/assets/ic-speaker.webp +0 -0
  301. package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.d.ts +11 -3
  302. package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.js +1 -1
  303. package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.d.ts +5 -1
  304. package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.js +1 -1
  305. package/dist/components/themes/index.d.ts +11 -0
  306. package/dist/components/themes/index.js +1 -1
  307. package/dist/components/themes/spaceship/SpaceshipAudioPlayer.d.ts +8 -0
  308. package/dist/components/themes/spaceship/SpaceshipAudioPlayer.js +1 -0
  309. package/dist/components/themes/spaceship/SpaceshipLayout.d.ts +2 -0
  310. package/dist/components/themes/spaceship/SpaceshipLayout.js +1 -0
  311. package/dist/components/themes/spaceship/assets/images/X-sunset.png +0 -0
  312. package/dist/components/themes/spaceship/assets/images/X.webp +0 -0
  313. package/dist/components/themes/spaceship/assets/images/audio-bar.webp +0 -0
  314. package/dist/components/themes/spaceship/assets/images/background.webp +0 -0
  315. package/dist/components/themes/spaceship/assets/images/bg_sunset.png +0 -0
  316. package/dist/components/themes/spaceship/assets/images/big-blue-badge-sunset.png +0 -0
  317. package/dist/components/themes/spaceship/assets/images/big-blue-badge.png +0 -0
  318. package/dist/components/themes/spaceship/assets/images/big-blue-badge.webp +0 -0
  319. package/dist/components/themes/spaceship/assets/images/bingo.webp +0 -0
  320. package/dist/components/themes/spaceship/assets/images/blue-badge-sunset.png +0 -0
  321. package/dist/components/themes/spaceship/assets/images/blue-badge.png +0 -0
  322. package/dist/components/themes/spaceship/assets/images/blue-wrapper-sunset.png +0 -0
  323. package/dist/components/themes/spaceship/assets/images/blue-wrapper.webp +0 -0
  324. package/dist/components/themes/spaceship/assets/images/board_red.png +0 -0
  325. package/dist/components/themes/spaceship/assets/images/button_feedback_vi.png +0 -0
  326. package/dist/components/themes/spaceship/assets/images/circle-btn-right-sunset.png +0 -0
  327. package/dist/components/themes/spaceship/assets/images/circle-btn-right.png +0 -0
  328. package/dist/components/themes/spaceship/assets/images/circle-btn-sunset.png +0 -0
  329. package/dist/components/themes/spaceship/assets/images/circle-btn.webp +0 -0
  330. package/dist/components/themes/spaceship/assets/images/focus-vector.webp +0 -0
  331. package/dist/components/themes/spaceship/assets/images/head-phone_red.png +0 -0
  332. package/dist/components/themes/spaceship/assets/images/ic-mute-sunset.png +0 -0
  333. package/dist/components/themes/spaceship/assets/images/ic-mute.png +0 -0
  334. package/dist/components/themes/spaceship/assets/images/ic-play-sunset.png +0 -0
  335. package/dist/components/themes/spaceship/assets/images/ic-play-violet.webp +0 -0
  336. package/dist/components/themes/spaceship/assets/images/ic-play.webp +0 -0
  337. package/dist/components/themes/spaceship/assets/images/micro.png +0 -0
  338. package/dist/components/themes/spaceship/assets/images/next-small.webp +0 -0
  339. package/dist/components/themes/spaceship/assets/images/next-sunset.png +0 -0
  340. package/dist/components/themes/spaceship/assets/images/next.webp +0 -0
  341. package/dist/components/themes/spaceship/assets/images/purple-circle.webp +0 -0
  342. package/dist/components/themes/spaceship/assets/images/question-badge-sunset.png +0 -0
  343. package/dist/components/themes/spaceship/assets/images/question-badge.webp +0 -0
  344. package/dist/components/themes/spaceship/assets/images/red-badge-sunset.png +0 -0
  345. package/dist/components/themes/spaceship/assets/images/red-badge.webp +0 -0
  346. package/dist/components/themes/spaceship/assets/images/red-wrapper-sunset.png +0 -0
  347. package/dist/components/themes/spaceship/assets/images/red-wrapper.webp +0 -0
  348. package/dist/components/themes/spaceship/assets/images/robot-avatar.png +0 -0
  349. package/dist/components/themes/spaceship/assets/images/sound_red.png +0 -0
  350. package/dist/components/themes/spaceship/assets/images/student-avatar.png +0 -0
  351. package/dist/components/themes/spaceship/assets/images/teacher-play-sunset.png +0 -0
  352. package/dist/components/themes/spaceship/assets/images/teacher-play.webp +0 -0
  353. package/dist/components/themes/spaceship/assets/images/timer-badge.png +0 -0
  354. package/dist/components/themes/spaceship/assets/styles/SpaceshipLayout.module.css +347 -0
  355. package/dist/components/themes/spaceship/assets/styles/SpaceshipWaitingRoom.module.css +395 -0
  356. package/dist/components/ui/badge.d.ts +1 -1
  357. package/dist/index.d.ts +4 -4
  358. package/dist/index.js +1 -1
  359. package/dist/shared/lib/stores/examTakingStore.d.ts +54 -0
  360. package/dist/shared/lib/stores/examTakingStore.js +1 -0
  361. package/dist/shared/lib/stores/gradingTransientStore.d.ts +23 -0
  362. package/dist/shared/lib/stores/gradingTransientStore.js +1 -0
  363. package/dist/shared/lib/themes/config/starters.config.d.ts +3 -0
  364. package/dist/shared/lib/themes/config/starters.config.js +1 -0
  365. package/dist/shared/lib/themes/index.d.ts +18 -0
  366. package/dist/shared/lib/themes/index.js +1 -0
  367. package/dist/shared/lib/themes/types.d.ts +39 -0
  368. package/dist/shared/lib/themes/types.js +1 -0
  369. package/dist/shared/lib/toast.d.ts +19 -0
  370. package/dist/shared/lib/toast.js +1 -0
  371. package/package.json +12 -2
@@ -0,0 +1 @@
1
+ export { SpeakingRecordingPreview } from './SpeakingRecordingPreview';
@@ -0,0 +1 @@
1
+ export{SpeakingRecordingPreview}from"./SpeakingRecordingPreview";
@@ -0,0 +1,16 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingChooseAnswerGroupRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ }
15
+ export declare function SpeakingChooseAnswerGroupRenderer(props: SpeakingChooseAnswerGroupRendererProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as n}from"react/jsx-runtime";import{ResolvedImage as o}from"../../../../../../components/common/ResolvedImage";import{cn as r}from"../../../../../../shared/lib/utils";import{useSpeakingRendererSetup as t}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as a}from"../../../../../../components/themes";import s from"../SpeakingReadDisplayedContent.module.css";function i({total:o,currentIndex:r,answeredIds:t,questionIds:a}){return e("div",{className:s.taskIndicator,style:{color:"#1e3a8a",textShadow:"none",fontWeight:800},children:[e("span",{children:["Question ",r+1,"/ ",o]}),n("div",{className:"flex gap-2",children:Array.from({length:o},(e,o)=>{const i=o===r,l=t.has(a[o]);return n("div",{className:`${s.taskDot} ${i?s.taskDotActive:""} ${l&&!i?s.taskDotCompleted:""}`,style:i||l?void 0:{background:"#bfdbfe"}},o)})})]})}function l({option:e,isSelected:t,isDisabled:a,onClick:s}){return n("button",{type:"button",onClick:s,disabled:a&&!t,className:r("group relative aspect-square w-[calc(33.333%-16px)] overflow-hidden rounded-xl bg-white shadow-sm cursor-pointer outline-none focus:outline-none transition-all duration-200",t?"border-[5px] border-red-400 shadow-[0_0_8px_rgba(239,68,68,0.5),0_0_16px_rgba(239,68,68,0.3)]":"border-2 border-gray-300 hover:border-gray-400 hover:shadow-md hover:scale-105",a&&!t&&"cursor-not-allowed"),children:n(o,{src:e.imageUrl,alt:e.label||"Answer option",className:"h-full w-full object-contain p-2 pointer-events-none",draggable:!1})})}export function SpeakingChooseAnswerGroupRenderer(e){const o=t({...e,hasMic:!1}),r=a(e.speakingTheme),s=o.currentQuestion?.content,d=o.currentQuestion?.questionGroup?.payload,c=s?.audioUrl??"",u=d?.options??s?.options??[],p=o.currentQuestion?e.answers[o.currentQuestion.id]:void 0,h=p?.answer??"";if(!o.currentQuestion)return null;const m=new Set(e.part.questions.map(e=>e.id).filter(n=>!!e.answers[n])),v=e.part.questions.map(e=>e.id),f=n(i,{total:e.part.questions.length,currentIndex:o.nav.currentIndex,answeredIds:m,questionIds:v});return n(r,{onExit:e.onExit,partName:e.part.name||`Part ${e.part.partNo}`,instruction:e.part.instructions||"LISTEN AND CHOOSE THE CORRECT ANSWER.",audioUrl:c,questionNumber:o.nav.questionNumberInPart,onPrev:o.handlePrev,onNext:o.handleNext,showPrev:o.nav.showPrev,showNext:o.nav.showNext,canGoPrev:o.nav.canGoPrev,canGoNext:o.nav.canGoNext,onAudioPlayingChange:o.onAudioPlayingChange,recorder:null,headerRight:f,teacherVideoUrl:e.teacherVideoUrl,onTeacherVideoEnded:e.onTeacherIntroPlayed,skipTeacherVideo:e.skipTeacherVideo,contentClassName:"h-full !p-0",children:n("div",{className:"w-full h-full overflow-y-auto pr-2",style:{scrollbarWidth:"thin",scrollbarColor:"#fff rgba(0,0,0,0.2)"},children:u.length>0?n("div",{className:"mx-auto flex max-w-[830px] flex-wrap justify-center gap-6 pb-6 pt-17",children:u.map(r=>n(l,{option:r,isSelected:h===r.id,isDisabled:e.isReviewMode||!1,onClick:()=>{return n=r.id,void(o.currentQuestion&&!e.isReviewMode&&e.onAnswerChange(o.currentQuestion.id,{answer:n}));var n}},r.id))}):n("div",{className:"flex h-48 items-center justify-center text-sm text-stone-400",children:"No options available"})})})}
@@ -0,0 +1,16 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingChooseObjectsRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ }
15
+ export declare function SpeakingChooseObjectsRenderer(props: SpeakingChooseObjectsRendererProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{usePresignedFileUrl as n}from"../../../../../../shared/lib/hooks";import{useSpeakingRendererSetup as r}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as o}from"../../../../../../components/themes";import i from"../FindObjectInPicture.module.css";import a from"../SpeakingReadDisplayedContent.module.css";function s({total:n,currentIndex:r,answeredIds:o,questionIds:i}){return e("div",{className:a.taskIndicator,style:{color:"#1e3a8a",textShadow:"none",fontWeight:800},children:[e("span",{children:["Question ",r+1,"/ ",n]}),t("div",{className:"flex gap-2",children:Array.from({length:n},(e,n)=>{const s=n===r,c=o.has(i[n]);return t("div",{className:`${a.taskDot} ${s?a.taskDotActive:""} ${c&&!s?a.taskDotCompleted:""}`,style:s||c?void 0:{background:"#bfdbfe"}},n)})})]})}function c({node:e,isSelected:r,isDisabled:o,onClick:a}){const{previewUrl:s}=n(e.imageUrl||"");return t("button",{type:"button",onClick:a,disabled:o,className:`${i.objectItem} ${r?i.objectItemSelected:""}`,style:{left:`${e.x}%`,top:`${e.y}%`,width:`${e.width}%`,height:`${e.height}%`},children:s?t("img",{src:s,alt:e.label,className:i.objectItemImageBorder,style:{height:"100%",width:"100%"},draggable:!1}):t("div",{style:{display:"flex",height:"100%",width:"100%",alignItems:"center",justifyContent:"center",background:"rgba(255,255,255,0.5)",fontSize:"12px",color:"#999"},children:e.label})})}export function SpeakingChooseObjectsRenderer(a){const d=r({...a,hasMic:!1}),l=o(a.speakingTheme),u=d.currentQuestion?.content,h=d.currentQuestion;let m=h?.questionGroup?.payload||h?.question_group?.payload;if("string"==typeof m)try{m=JSON.parse(m)}catch{m={}}const p=u?.audioUrl??"",g=m?.backgroundImageUrl??"",b=m?.objectNodes??[],v=d.currentQuestion?a.answers[d.currentQuestion.id]:void 0,f=v?.objectId??"",{previewUrl:x}=n(g);if(!d.currentQuestion)return null;const y=new Set(a.part.questions.map(e=>e.id).filter(e=>!!a.answers[e])),N=a.part.questions.map(e=>e.id),k=t(s,{total:a.part.questions.length,currentIndex:d.nav.currentIndex,answeredIds:y,questionIds:N});return t(l,{onExit:a.onExit,partName:a.part.name||`Part ${a.part.partNo}`,instruction:a.part.instructions||"Choose the correct objects in the Scene picture:",audioUrl:p,questionNumber:d.nav.questionNumberInPart,onPrev:d.handlePrev,onNext:d.handleNext,showPrev:d.nav.showPrev,showNext:d.nav.showNext,canGoPrev:d.nav.canGoPrev,canGoNext:d.nav.canGoNext,onAudioPlayingChange:d.onAudioPlayingChange,recorder:null,headerRight:k,teacherVideoUrl:a.teacherVideoUrl,onTeacherVideoEnded:a.onTeacherIntroPlayed,skipTeacherVideo:a.skipTeacherVideo,contentClassName:"!p-0",children:t("div",{className:i.findObjectContainer,children:e("div",{className:i.objectBackground,children:[t("div",{className:i.imageBackground,children:x?t("img",{alt:"Scene",src:x,draggable:!1}):t("div",{style:{display:"flex",height:"100%",width:"100%",alignItems:"center",justifyContent:"center",color:"#999"},children:"Loading..."})}),b.map(e=>t(c,{node:e,isSelected:f===e.id,isDisabled:a.isReviewMode||!1,onClick:()=>{return t=e.id,void(d.currentQuestion&&!a.isReviewMode&&a.onAnswerChange(d.currentQuestion.id,{objectId:t}));var t}},e.id))]})})})}
@@ -0,0 +1,17 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingCompareImagesRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ waitForTeacherVideo?: boolean;
15
+ }
16
+ export declare function SpeakingCompareImagesRenderer(props: SpeakingCompareImagesRendererProps): import("react").JSX.Element;
17
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as r,Fragment as a}from"react/jsx-runtime";import{ResolvedImage as n}from"../../../../../../components/common/ResolvedImage";import{useSpeakingRendererSetup as t}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as o}from"../../../../../../components/themes";export function SpeakingCompareImagesRenderer(r){const a=t({...r,maxDurationMs:3e4}),n=o(r.speakingTheme),d=a.currentQuestion?.content,l=a.currentQuestion?.questionGroup?.payload;if(!a.currentQuestion)return null;const s=d?.audioUrl??"",c=l?.candidateImageUrl??"",m=l?.examinerImageUrl??"";return e(n,{onExit:r.onExit,partName:r.part.name||`Part ${r.part.partNo}`,instruction:r.part.instructions||"LOOK AT THE TWO PICTURES. THEY LOOK THE SAME BUT SOME THINGS ARE DIFFERENT.",audioUrl:s,questionNumber:a.nav.questionNumberInPart,onPrev:a.handlePrev,onNext:a.handleNext,showPrev:a.nav.showPrev,showNext:a.nav.showNext,canGoPrev:a.nav.canGoPrev,canGoNext:a.nav.canGoNext,onAudioPlayingChange:a.onAudioPlayingChange,recorder:r.isReviewMode?null:a.recorder,showExistingBadge:a.showExistingBadge,teacherVideoUrl:r.teacherVideoUrl,onTeacherVideoEnded:r.onTeacherIntroPlayed,skipTeacherVideo:r.skipTeacherVideo,waitForTeacherVideo:r.waitForTeacherVideo,children:e("div",{className:"flex h-full w-full flex-col items-center gap-8 overflow-y-auto overflow-x-hidden px-4 py-18 scrollbar-thin",children:e(i,{candidateImageUrl:c,examinerImageUrl:m,showExistingBadge:a.showExistingBadge})})})}function i({candidateImageUrl:t,examinerImageUrl:o,showExistingBadge:i}){return r(a,{children:[i&&r("div",{className:"absolute right-4 top-4 z-10 flex items-center gap-2 rounded-full border-2 border-white bg-green-500 px-4 py-1 text-sm font-bold text-white shadow-md",children:[e("span",{className:"h-2.5 w-2.5 animate-pulse rounded-full bg-white"}),"Đã ghi âm"]}),r("div",{className:"relative flex w-full max-w-[1000px] flex-col items-center",children:[e("div",{className:"z-10 -mb-3 flex h-8 min-w-[200px] items-center justify-center rounded-xl bg-[#1e3458] px-6 text-[13px] font-bold uppercase tracking-[1.5px] text-white shadow-md md:-mb-4 md:h-10 md:text-sm",children:"Candidate's copy"}),e("div",{className:"relative aspect-[3.3] w-full overflow-hidden rounded-xl border-4 p-[10px] border-[#b45309] bg-white shadow-md",children:e(n,{src:t,alt:"Candidate's copy",className:"pointer-events-none h-full w-full object-cover rounded-xl",draggable:!1})})]}),r("div",{className:"relative flex w-full max-w-[1000px] flex-col items-center pb-8",children:[e("div",{className:"z-10 -mb-3 flex h-8 min-w-[200px] items-center justify-center rounded-xl bg-[#1e3458] px-6 text-[13px] font-bold uppercase tracking-[1.5px] text-white shadow-md md:-mb-4 md:h-10 md:text-sm",children:"Examiner's copy"}),e("div",{className:"relative aspect-[3.3] w-full overflow-hidden rounded-xl border-4 p-[10px] border-[#1e3a8a] bg-white shadow-md",children:e(n,{src:o,alt:"Examiner's copy",className:"pointer-events-none h-full w-full object-cover rounded-xl",draggable:!1})})]})]})}
@@ -0,0 +1,16 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingConversationRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ }
15
+ export declare function SpeakingConversationRenderer(props: SpeakingConversationRendererProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useState as a}from"react";import s from"next/image";import{Pause as n,Play as r}from"lucide-react";import{ResolvedImage as i}from"../../../../../../components/common/ResolvedImage";import{useSpeakingRendererSetup as l}from"../../../hooks/useSpeakingRendererSetup";import{useSpeakingConversationAudio as o}from"../../../hooks/useSpeakingConversationAudio";import{getSpeakingLayout as c}from"../../../../../../components/themes";import d from"../../../../../../components/themes/spaceship/assets/styles/SpaceshipLayout.module.css";import p from"../../../../../../components/themes/spaceship/assets/images/big-blue-badge-sunset.png";import m from"../../../../../../components/themes/spaceship/assets/images/teacher-play-sunset.png";import h from"../../../../../../components/themes/spaceship/assets/images/question-badge-sunset.png";import u from"../../../../../../components/themes/spaceship/assets/images/red-badge-sunset.png";import x from"../../../../../../components/themes/spaceship/assets/images/blue-badge-sunset.png";import g from"../../../../../../components/themes/spaceship/assets/images/red-wrapper-sunset.png";import f from"../../../../../../components/themes/spaceship/assets/images/blue-wrapper-sunset.png";import N from"../../../../../../components/themes/spaceship/assets/images/robot-avatar.png";import v from"../../../../../../components/themes/spaceship/assets/images/student-avatar.png";import y from"../../../../../../components/themes/spaceship/assets/images/next-small.webp";function b(e){if(!isFinite(e)||e<0)return"0:00";return`${Math.floor(e/60)}:${Math.floor(e%60).toString().padStart(2,"0")}`}function w({phase:a,isPlaying:i,togglePlayPause:l,partNumber:o,partnerName:c,currentTime:h,duration:u}){const x="playing-partner"===a?c||"Bạn thi":`PART ${o}`,g=u>0?h/u*100:0;return e("div",{className:d.examAudioContainer,children:t("div",{className:d.bigBlueBadge,children:[e(s,{src:p,alt:"Audio Badge",className:d.bigBlueBadgeBg,priority:!0}),e("div",{className:d.audioBarContent,children:t("div",{className:d.audioBarInner,children:[e("span",{className:d.partLabel,children:x}),t("div",{className:d.teacherAvatarContainer,onClick:l,title:i?"Tạm dừng":"Phát",children:[e("img",{src:m.src,alt:"Speaker",className:d.teacherPlayIcon}),e("div",{className:"absolute inset-0 flex items-center justify-center",children:i?e(n,{className:"h-5 w-5 text-white drop-shadow-md",fill:"currentColor"}):e(r,{className:"h-5 w-5 text-white drop-shadow-md ml-0.5",fill:"currentColor"})})]}),t("div",{className:d.audioControlsWrapper,children:[t("span",{className:d.audioTime,children:["idle"===a&&"0:00 / 0:00",i&&`${b(h)} / ${b(u)}`,"ready"===a&&`${b(u)} / ${b(u)}`]}),e("div",{className:d.sliderTrack,children:e("div",{className:d.sliderFill,style:{width:`${g}%`,transition:"width 0.25s linear"}})})]})]})})]})})}function P({text:n}){const[r,i]=a(!0);return n?e("div",{className:"flex flex-col items-center w-full",style:{maxWidth:"882px"},children:t("div",r?{className:"relative flex flex-col justify-center items-center",style:{width:"882px",maxWidth:"90%",paddingLeft:"77px",paddingRight:"77px",paddingTop:"26px",paddingBottom:"26px",backgroundColor:"rgba(232, 136, 154, 0.15)",borderRadius:"20px"},children:[t("div",{className:"absolute cursor-pointer",style:{top:"-19px"},onClick:()=>i(!1),children:[e(s,{src:h,alt:"",style:{width:"169px",height:"38px"}}),e("div",{className:"absolute inset-0 flex justify-center items-center select-none",children:e("span",{className:"font-normal text-center leading-5 text-white",style:{fontSize:"18px"},children:"Ấn câu hỏi"})})]}),e("p",{className:"text-black font-bold leading-[26px] text-center m-0",style:{fontSize:"18px",fontFamily:'"Open Sans", sans-serif'},children:n})]}:{className:"relative cursor-pointer",onClick:()=>i(!0),children:[e(s,{src:h,alt:"",style:{width:"169px",height:"38px"}}),e("div",{className:"absolute inset-0 flex justify-center items-center select-none",children:e("span",{className:"font-normal text-center leading-5 text-white",style:{fontSize:"18px"},children:"Hiện câu hỏi"})})]})}):null}function S({images:a}){if(!a||0===a.length)return null;const s=1===a.length,n=s?"grid-cols-1":2===a.length||4===a.length?"grid-cols-2":"grid-cols-3";return e("div",{className:`grid ${n} gap-4 w-full`,style:{maxWidth:s?"650px":"800px",margin:"0 auto"},children:a.map(a=>t("div",{className:"flex flex-col items-center gap-2",children:[e("div",{className:`relative w-full ${s?"":"aspect-square"} flex justify-center items-center rounded-xl overflow-hidden border-2 border-white/40 shadow-md bg-white/20`,children:e(i,{src:a.url,alt:a.label||"Image",className:"object-contain pointer-events-none "+(s?"max-h-[350px] w-auto":"w-full h-full p-1"),draggable:!1})}),a.label&&e("span",{className:"text-center font-bold",style:{fontSize:"14px",color:"#333"},children:a.label})]},a.id))})}function C({partnerName:a,partnerAvatarUrl:n,studentName:r,activeCharacter:l,isPartnerQuestion:o}){const c="partner"===l,d="student"===l;return t("div",{className:"flex justify-between select-none",style:{width:"990px",maxWidth:"95%",paddingBottom:"10px",paddingLeft:"20px",paddingRight:"20px"},children:[t("div",{className:"relative select-none",style:{opacity:c?1:.55},children:[t("div",{className:"relative flex",children:[e(s,{src:u,alt:"",style:{height:"57px",width:"258px"}}),e("div",{className:"absolute inset-0 flex justify-center items-center",style:{paddingTop:"12px"},children:e("p",{className:"m-0 truncate select-none text-white font-normal text-center leading-5",style:{fontSize:"18px",paddingLeft:"60px",paddingRight:"60px"},children:a||"Bạn thi"})})]}),t("div",{className:"absolute",style:{top:"7px",right:"-58px"},children:[e(s,{src:g,alt:"",className:"relative",style:{width:"115px",height:"84px",zIndex:0}}),e("div",{className:"absolute inset-0 flex justify-center items-center w-full h-full",children:t("div",{className:"relative",style:{width:"68px",height:"68px"},children:[n?e(i,{src:n,alt:a||"Partner",className:"object-cover rounded-full select-none",style:{width:"68px",height:"68px"},draggable:!1}):e(s,{src:N,alt:a||"Partner",width:68,height:68,className:"object-cover rounded-full select-none",draggable:!1}),c&&e("div",{className:"absolute inset-0 rounded-full border-4 border-yellow-400 shadow-[0_0_12px_4px_rgba(250,204,21,0.6)]"})]})})]})]}),t("div",{className:"relative select-none",style:{opacity:d||!o?1:.55},children:[t("div",{className:"relative flex",children:[e(s,{src:x,alt:"",style:{height:"57px",width:"258px"}}),e("div",{className:"absolute inset-0 flex justify-center items-center",style:{paddingTop:"12px"},children:e("p",{className:"m-0 truncate select-none text-white font-normal text-center leading-5",style:{fontSize:"18px",paddingLeft:"60px",paddingRight:"60px"},children:r||"Bạn"})})]}),t("div",{className:"absolute",style:{top:"7px",left:"-58px"},children:[e(s,{src:f,alt:"",className:"relative",style:{width:"115px",height:"84px",zIndex:0}}),e("div",{className:"absolute inset-0 flex justify-center items-center w-full h-full",children:t("div",{className:"relative",style:{width:"68px",height:"68px"},children:[e(s,{src:v,alt:r||"Bạn",width:68,height:68,className:"object-cover rounded-full select-none",draggable:!1}),d&&e("div",{className:"absolute inset-0 rounded-full border-4 border-sky-400 shadow-[0_0_12px_4px_rgba(56,189,248,0.6)]"})]})})]})]})]})}function A({audioReady:a,onNext:n}){return a?e("div",{className:"flex flex-col items-center text-center",style:{maxWidth:"291px",marginTop:"-10px",marginBottom:"10px"},children:t("div",{className:"flex items-center gap-1",children:[e("p",{className:"m-0",style:{color:"#333",fontSize:"13px"},children:"Ấn nút"}),e("div",{className:"cursor-pointer",onClick:n,children:e(s,{src:y,alt:"next",width:30,height:30})}),e("p",{className:"m-0",style:{color:"#333",fontSize:"13px"},children:"để tiếp tục."})]})}):null}export function SpeakingConversationRenderer(s){const[n,r]=a(!1),i=l({...s,maxDurationMs:3e4,hasMic:!0}),d=c("SPACESHIP"),p=i.currentQuestion?.content,m=i.currentQuestion?.questionGroup?.payload,h="PARTNER"===p?.responder,u=o({interlocutorAudioUrl:p?.interlocutorAudioUrl,partnerAudioUrl:p?.partnerAudioUrl,onSequenceComplete:()=>r(!0)});if(!i.currentQuestion||!p)return null;const x="playing-interlocutor"===u.phase?"interlocutor":"playing-partner"===u.phase||h?"partner":n?"student":"none",g=()=>{r(!1),i.handleNext()};return e(d,{onExit:s.onExit,partName:s.part.name||`Part ${s.part.partNo}`,instruction:s.part.instructions||"SPEAKING CONVERSATION",audioUrl:"",questionNumber:i.nav.questionNumberInPart,onPrev:()=>{r(!1),i.handlePrev()},onNext:g,showPrev:i.nav.showPrev,showNext:i.nav.showNext,canGoPrev:i.nav.canGoPrev,canGoNext:i.nav.canGoNext,onAudioPlayingChange:i.onAudioPlayingChange,recorder:s.isReviewMode||h?null:i.recorder,showExistingBadge:!h&&i.showExistingBadge,teacherVideoUrl:s.teacherVideoUrl,onTeacherVideoEnded:s.onTeacherIntroPlayed,skipTeacherVideo:s.skipTeacherVideo,hideAudioBar:!0,hideFooterTitle:h,children:t("div",{className:"w-full h-full flex flex-col items-center relative",style:{paddingBottom:h?"0":"50px"},children:[e(w,{phase:u.phase,isPlaying:u.isPlaying,togglePlayPause:u.togglePlayPause,partNumber:i.nav.currentPartNo,partnerName:m?.partnerName,currentTime:u.currentTime,duration:u.duration}),e(P,{text:p.questionText}),m?.images&&m.images.length>0&&e("div",{className:"mt-4 w-full flex justify-center",children:e(S,{images:m.images})}),e("div",{className:"flex-1"}),h&&e(A,{audioReady:n,onNext:g}),e(C,{partnerName:m?.partnerName,partnerAvatarUrl:m?.partnerAvatarUrl,activeCharacter:x,isPartnerQuestion:h})]},i.currentQuestion.id)})}
@@ -0,0 +1,17 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingCueCardRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ waitForTeacherVideo?: boolean;
15
+ }
16
+ export declare function SpeakingCueCardRenderer(props: SpeakingCueCardRendererProps): import("react").JSX.Element;
17
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as n}from"react/jsx-runtime";import{useEffect as t,useRef as r,useState as o}from"react";import{useSpeakingRendererSetup as a}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as i}from"../../../../../../components/themes";import s from"../../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import l from"next/image";import d from"../../../../../../components/themes/summer-sky/assets/images/mic_ver2_icon.png";import c from"../../../../../../components/themes/summer-sky/assets/images/stop_audio_ver2_icon.png";import p from"../../../../../../components/themes/summer-sky/assets/images/audio_ver2_icon.png";import u from"../../../../../../components/themes/summer-sky/assets/images/pause_audio_ver2_icon.png";import m from"../../../../../../components/themes/summer-sky/assets/images/lock_mic_ver2_icon.png";import h from"../SpeakingReadDisplayedContent.module.css";function g({total:t,currentIndex:r,answeredIds:o,questionIds:a}){return e("div",{className:h.taskIndicator,style:{color:"#78350f",textShadow:"none",fontWeight:800},children:[e("span",{children:["Question ",r+1,"/ ",t]}),n("div",{className:"flex gap-2",children:Array.from({length:t},(e,t)=>{const i=t===r,s=o.has(a[t]);return n("div",{className:`${h.taskDot} ${i?h.taskDotActive:""} ${s&&!i?h.taskDotCompleted:""}`},t)})})]})}function x({total:t,currentIndex:r,answeredIds:o,questionIds:a}){return e("div",{className:"flex items-center gap-2 font-bold text-[#78350f] font-['Quicksand'] z-10",children:[e("span",{className:"text-sm",children:["Question ",r+1,"/ ",t]}),n("div",{className:"flex gap-1.5",children:Array.from({length:t},(e,t)=>{const i=t===r,s=o.has(a[t]);return n("div",{className:"w-2.5 h-2.5 rounded-full "+(i?"bg-[#FF9900] scale-125 shadow-sm":s?"bg-[#16CA3B]":"bg-white/60")},t)})})]})}export function SpeakingCueCardRenderer(m){const h=a({...m,maxDurationMs:12e4}),f=i(m.speakingTheme),v=h.currentQuestion?.content,w=v?.speakingTimeSeconds??120;t(()=>{h.recorder&&(h.recorder.maxDurationMs=1e3*w)},[w,h.recorder]);const b=r(null),[y,N]=o(!1);if(t(()=>{const e=b.current;if(!e)return;const n=()=>{N(!0),h.onAudioPlayingChange?.(!0)},t=()=>{N(!1),h.onAudioPlayingChange?.(!1)},r=()=>{N(!1),h.onAudioPlayingChange?.(!1)};return e.addEventListener("play",n),e.addEventListener("pause",t),e.addEventListener("ended",r),()=>{e.removeEventListener("play",n),e.removeEventListener("pause",t),e.removeEventListener("ended",r),h.onAudioPlayingChange?.(!1)}},[h.recorder?.previewUrl,h.onAudioPlayingChange]),!h.currentQuestion||!v)return null;const k=new Set(m.part.questions.map(e=>e.id).filter(e=>!!m.answers[e])),_=m.part.questions.map(e=>e.id);if(m.speakingTheme&&"CAMBRIDGE_YLE"!==m.speakingTheme){const t=n(g,{total:m.part.questions.length,currentIndex:h.nav.currentIndex,answeredIds:k,questionIds:_});return e(f,{onExit:m.onExit,partName:m.part.name||`Part ${m.part.partNo}`,instruction:m.part.instructions||"READ CUE CARD AND SPEAK",audioUrl:"",questionNumber:h.nav.questionNumberInPart,onPrev:h.handlePrev,onNext:h.handleNext,showPrev:h.nav.showPrev,showNext:h.nav.showNext,canGoPrev:h.nav.canGoPrev,canGoNext:h.nav.canGoNext,onAudioPlayingChange:h.onAudioPlayingChange,recorder:m.isReviewMode?null:h.recorder,showExistingBadge:h.showExistingBadge,headerRight:t,teacherVideoUrl:m.teacherVideoUrl,onTeacherVideoEnded:m.onTeacherIntroPlayed,skipTeacherVideo:m.skipTeacherVideo,waitForTeacherVideo:m.waitForTeacherVideo,children:[n("div",{className:"w-full h-full flex flex-col items-center relative",children:n("div",{className:"w-full flex-1",style:{minHeight:0},children:n("div",{className:"mx-auto",style:{width:"850px",maxWidth:"95%",height:"calc(100% - 80px)"},children:n("div",{className:"w-full h-full flex flex-col items-center justify-center",children:e("div",{className:"relative flex flex-col justify-start",style:{width:"100%",paddingLeft:"50px",paddingRight:"50px",paddingTop:"16px",paddingBottom:"16px"},children:[h.showExistingBadge&&e("div",{className:"absolute right-12 top-4 z-10 rounded-full bg-green-500 px-4 py-1.5 flex items-center gap-2 text-sm font-bold text-white shadow-md border-2 border-white",children:[n("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),n("div",{className:"cue-card-content",dangerouslySetInnerHTML:{__html:v.cueCardHtml},style:{fontSize:"22px",fontFamily:'"SVN-Volte Rounded", "Quicksand", sans-serif',fontWeight:600,lineHeight:"35px",letterSpacing:"-0.01em",color:"#2C38B6"}})]})})})})}),n("style",{jsx:!0,global:!0,children:"\n .cue-card-content p {\n margin: 0 0 12px 0;\n }\n .cue-card-content p:last-child {\n margin-bottom: 0;\n }\n .cue-card-content strong {\n font-weight: 700;\n font-size: 24px;\n color: #1a237e;\n line-height: 37px;\n }\n .cue-card-content ul {\n margin: 16px 0;\n padding: 0;\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .cue-card-content ul li {\n position: relative;\n padding: 9px 15px 9px 34px;\n font-size: 19px;\n line-height: 28px;\n font-weight: 500;\n color: #283593;\n background: rgba(44, 56, 182, 0.06);\n border-radius: 12px;\n border-left: 3px solid #5c6bc0;\n }\n .cue-card-content ul li::before {\n content: '';\n position: absolute;\n left: 14px;\n top: 50%;\n transform: translateY(-50%);\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #5c6bc0;\n }\n .cue-card-content ul li p {\n margin: 0;\n }\n "})]})}return e("div",{className:"flex flex-col w-full h-full relative",style:{background:"linear-gradient(180deg, #E6F3FF 0%, #FFFFFF 100%)"},children:[e("div",{className:"relative w-full flex justify-between items-start pt-6 px-6 z-20 shrink-0",children:[n("div",{className:"flex-1"}),n("div",{className:"flex-none drop-shadow-md",children:n(s,{partNumber:m.part.partNo,questionCount:m.part.questions.length,partName:m.part.name||`Part ${m.part.partNo}`})}),n("div",{className:"flex-1 flex justify-end mt-2 z-20",children:n(x,{total:m.part.questions.length,currentIndex:h.nav.currentIndex,answeredIds:k,questionIds:_})})]}),e("div",{className:"flex-1 w-full flex flex-col items-center min-h-0 px-4 pb-6 pt-8",children:[n("div",{className:"flex-1 w-full flex flex-col items-center min-h-0 relative mb-6",children:e("div",{className:"w-full max-w-[850px] relative bg-white/60 backdrop-blur-md rounded-2xl shadow-[0_2px_15px_rgba(0,0,0,0.04)] border border-blue-50 p-8",children:[h.showExistingBadge&&e("div",{className:"absolute right-4 top-0 z-10 rounded-full bg-green-500 px-4 py-1.5 flex items-center gap-2 text-sm font-bold text-white shadow-lg border-2 border-white transform -translate-y-1/2",children:[n("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),n("div",{className:"cue-card-content",dangerouslySetInnerHTML:{__html:v.cueCardHtml},style:{fontSize:"22px",fontFamily:'"SVN-Volte Rounded", "Quicksand", sans-serif',fontWeight:600,lineHeight:"35px",letterSpacing:"-0.01em",color:"#2C38B6"}})]})}),h.recorder&&!m.isReviewMode&&e("div",{className:"shrink-0 flex flex-col items-center z-50 gap-3",children:[n("div",{className:"bg-white rounded-[100px] shadow-[0_4px_10px_rgba(0,0,0,0.1)] whitespace-nowrap flex items-center justify-center",style:{padding:"10px 30px",color:"recording"===h.recorder.status?"#FF4D4D":["recorded","uploading","uploaded"].includes(h.recorder.status)?"#16CA3B":"#343C55",fontSize:"18px",fontFamily:'"Quicksand", sans-serif',fontWeight:700,lineHeight:"100%",letterSpacing:"-0.01em"},children:"recording"===h.recorder.status?"Ấn lần nữa để lưu kết quả":["recorded","uploading","uploaded"].includes(h.recorder.status)?"Câu trả lời đã được ghi nhận !":"Ấn biểu tượng Micro để trả lời"}),n("div",{className:"relative flex flex-col items-center",children:"recording"===h.recorder.status?e("div",{className:"relative flex flex-col justify-center items-center cursor-pointer drop-shadow-[0_0_15px_rgba(255,100,100,0.8)] transition-transform hover:scale-[1.05] active:scale-[0.95]",onClick:h.recorder.stopRecording,children:[n(l,{src:c,alt:"stop audio",className:"animate-pulse",style:{width:"120px",height:"120px"}}),e("span",{className:"absolute text-white text-[16px] font-bold font-['Quicksand']",style:{bottom:"30px"},children:[Math.floor(h.recorder.remainingSeconds/60),":",(h.recorder.remainingSeconds%60).toString().padStart(2,"0")]})]}):n(l,{src:["recorded","uploading","uploaded"].includes(h.recorder.status)?y?u:p:d,alt:"micro",className:"transition-transform cursor-pointer hover:scale-[1.05] active:scale-[0.95]",style:{width:"120px",height:"120px"},onClick:()=>{if("recording"===h.recorder?.status)h.recorder.stopRecording();else if("idle"===h.recorder?.status||"error"===h.recorder?.status)h.recorder.startRecording();else if("uploaded"===h.recorder?.status||"recorded"===h.recorder?.status){const e=b.current;e&&(y?e.pause():e.play().catch(console.error))}}})}),h.recorder.previewUrl&&n("audio",{ref:b,src:h.recorder.previewUrl})]})]}),n("style",{jsx:!0,global:!0,children:"\n .cue-card-content p {\n margin: 0 0 12px 0;\n }\n .cue-card-content p:last-child {\n margin-bottom: 0;\n }\n .cue-card-content strong {\n font-weight: 700;\n font-size: 24px;\n color: #1a237e;\n line-height: 37px;\n }\n .cue-card-content ul {\n margin: 16px 0;\n padding: 0;\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .cue-card-content ul li {\n position: relative;\n padding: 9px 15px 9px 34px;\n font-size: 19px;\n line-height: 28px;\n font-weight: 500;\n color: #283593;\n background: rgba(44, 56, 182, 0.06);\n border-radius: 12px;\n border-left: 3px solid #5c6bc0;\n }\n .cue-card-content ul li::before {\n content: '';\n position: absolute;\n left: 14px;\n top: 50%;\n transform: translateY(-50%);\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #5c6bc0;\n }\n .cue-card-content ul li p {\n margin: 0;\n }\n "})]})}
@@ -0,0 +1,18 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingDescribeImageRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ waitForTeacherVideo?: boolean;
15
+ currentQuestionIndex?: number;
16
+ }
17
+ export declare function SpeakingDescribeImageRenderer(props: SpeakingDescribeImageRendererProps): import("react").JSX.Element;
18
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as r}from"react/jsx-runtime";import{usePresignedFileUrl as t}from"../../../../../../shared/lib/hooks";import{useSpeakingRendererSetup as a}from"../../../hooks/useSpeakingRendererSetup";import n from"../../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import{getSpeakingLayout as i}from"../../../../../../components/themes";import{SpeakingAudioPlayer as o}from"../../../../../../components/shared/audio/SpeakingAudioPlayer";import{useEffect as s,useRef as d,useState as l}from"react";import c from"next/image";import{useExamTakingStore as m}from"../../../../../../shared/lib/stores/examTakingStore";import u from"../../../../../../components/themes/summer-sky/assets/images/mic_ver2_icon.png";import h from"../../../../../../components/themes/summer-sky/assets/images/stop_audio_ver2_icon.png";import p from"../../../../../../components/themes/summer-sky/assets/images/audio_ver2_icon.png";import g from"../../../../../../components/themes/summer-sky/assets/images/pause_audio_ver2_icon.png";import x from"../../../../../../components/themes/summer-sky/assets/images/lock_mic_ver2_icon.png";function f({total:t,currentIndex:a,answeredIds:n,questionIds:i}){return e("div",{className:"flex items-center gap-2 font-bold text-[#78350f] font-['Quicksand'] z-10",children:[e("span",{className:"text-sm",children:["Question ",a+1,"/ ",t]}),r("div",{className:"flex gap-1.5",children:Array.from({length:t},(e,t)=>{const o=t===a,s=n.has(i[t]);return r("div",{className:"w-2.5 h-2.5 rounded-full "+(o?"bg-[#FF9900] scale-125 shadow-sm":s?"bg-[#16CA3B]":"bg-white/60")},t)})})]})}const b=new Set(["/speaking/video/read_displayed_content.webm","/speaking/video/speaking_describe_image.webm","/speaking/video/spontaneous_qa.webm"]);function w(e){const r=Math.floor(e/60),t=Math.floor(e%60);return`${r.toString().padStart(2,"0")}:${t.toString().padStart(2,"0")}`}export function SpeakingDescribeImageRenderer(x){const{currentQuestionIndex:v}=x,y=a({...x,maxDurationMs:6e4,currentQuestionIndex:v}),N=m(e=>e.examTitle),k=N?.toLowerCase().includes("placement test")||!1,_=y.currentQuestion?.content,{previewUrl:C,isLoading:E}=t(_?.imageUrl||""),P=d(null),[S,F]=l(!!x.skipTeacherVideo),I=d(null),[T,U]=l(!1),[j,q]=l(0),[A,z]=l(0);if(s(()=>{const e=P.current;e&&x.teacherVideoUrl&&(e.playbackRate=b.has(x.teacherVideoUrl)?1.25:1)},[x.teacherVideoUrl]),s(()=>{const e=I.current;if(!e)return;const r=()=>{U(!0),y.onAudioPlayingChange?.(!0)},t=()=>{U(!1),y.onAudioPlayingChange?.(!1)},a=()=>{U(!1),q(0),y.onAudioPlayingChange?.(!1)},n=()=>{q(e.currentTime),e.duration&&isFinite(e.duration)&&z(e.duration)},i=()=>{e.duration&&isFinite(e.duration)&&z(e.duration)};return e.addEventListener("play",r),e.addEventListener("pause",t),e.addEventListener("ended",a),e.addEventListener("timeupdate",n),e.addEventListener("loadedmetadata",i),e.addEventListener("durationchange",i),()=>{e.removeEventListener("play",r),e.removeEventListener("pause",t),e.removeEventListener("ended",a),e.removeEventListener("timeupdate",n),e.removeEventListener("loadedmetadata",i),e.removeEventListener("durationchange",i),y.onAudioPlayingChange?.(!1)}},[y.recorder?.previewUrl,y.onAudioPlayingChange]),!y.currentQuestion||!_)return null;const L=new Set(x.part.questions.map(e=>e.id).filter(e=>!!x.answers[e])),V=x.part.questions.map(e=>e.id);if(x.speakingTheme&&"CAMBRIDGE_YLE"!==x.speakingTheme){const t=i(x.speakingTheme),a=r(f,{total:x.part.questions.length,currentIndex:y.nav.currentIndex,answeredIds:L,questionIds:V});return r(t,{onExit:x.onExit,partName:x.part.name||`Part ${x.part.partNo}`,instruction:x.part.instructions||"DESCRIBE THE IMAGE",audioUrl:"",questionNumber:y.nav.questionNumberInPart,onPrev:y.handlePrev,onNext:y.handleNext,showPrev:y.nav.showPrev,showNext:y.nav.showNext,canGoPrev:y.nav.canGoPrev,canGoNext:y.nav.canGoNext,onAudioPlayingChange:y.onAudioPlayingChange,recorder:x.isReviewMode?null:y.recorder,showExistingBadge:y.showExistingBadge,headerRight:a,teacherVideoUrl:x.teacherVideoUrl,waitForTeacherVideo:x.waitForTeacherVideo,onTeacherVideoEnded:x.onTeacherIntroPlayed,skipTeacherVideo:x.skipTeacherVideo,children:r("div",{className:"w-full h-full flex flex-col items-center relative",children:r("div",{className:"w-full flex-1",style:{minHeight:0},children:r("div",{className:"mx-auto",style:{width:"900px",maxWidth:"95%",height:"calc(100% - 40px)"},children:e("div",{className:"w-full h-full flex flex-col items-center justify-center",style:{paddingTop:"10px"},children:[_.isBackup&&r("div",{className:"bg-amber-500 text-white px-3 py-1 rounded-md text-xs font-bold border border-white shadow-md z-10 shrink-0 mb-4",children:"Câu hỏi dự phòng"}),_.question&&r("div",{className:"z-10 mx-auto px-8 py-2.5 bg-white/80 backdrop-blur-md rounded-full shadow-sm border border-slate-100 w-fit shrink-0 mb-4",children:r("h3",{className:"text-[17px] md:text-lg font-bold text-[#343C55] font-['Quicksand'] text-center whitespace-pre-wrap leading-tight",children:_.question})}),_.audioUrl&&r("div",{className:"z-10 mx-auto w-full max-w-[280px] shrink-0 mb-4",children:r(o,{audioUrl:_.audioUrl,onPlayingChange:y.onAudioPlayingChange,autoPlay:!x.waitForTeacherVideo})}),y.showExistingBadge&&e("div",{className:"absolute right-12 top-12 z-10 rounded-full bg-green-500 px-4 py-1.5 flex items-center gap-2 text-sm font-bold text-white shadow-md border-2 border-white",children:[r("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),r("div",{className:"flex-1 flex justify-center items-center min-h-0 w-full",children:r("div",E?{className:"flex justify-center items-center w-full max-w-[60%] h-full max-h-[300px] border-4 border-dashed border-gray-300 rounded-xl bg-gray-50/50",children:r("div",{className:"animate-spin rounded-full h-12 w-12 border-4 border-blue-500 border-t-transparent"})}:C?{className:"bg-white rounded-2xl shadow-[0_4px_15px_rgba(0,0,0,0.08)] p-2 h-full max-w-[90%] flex justify-center items-center",children:r("img",{src:C,alt:"Scene to describe",className:"max-h-full max-w-full object-contain rounded-xl",draggable:!1})}:{className:"flex justify-center items-center text-orange-800 font-semibold opacity-70 w-full h-full max-h-[300px] border-4 border-dashed border-orange-900/30 rounded-xl bg-orange-900/10",children:"Chưa có hình ảnh mô tả"})})]})})})})})}const B=x.teacherVideoUrl?r("div",{className:"fixed bottom-6 left-6 z-40 flex flex-col items-start w-[12vw] min-w-[150px] pointer-events-none",children:e("div",{className:"relative w-full",children:[r("video",{ref:P,src:x.teacherVideoUrl,autoPlay:!x.skipTeacherVideo,playsInline:!0,onEnded:()=>{F(!0),x.onTeacherIntroPlayed?.()},className:"w-full h-auto drop-shadow-[0_4px_16px_rgba(0,0,0,0.2)] transition-opacity duration-700",style:{opacity:S?0:1}}),!k&&"CAMBRIDGE_YLE"!==x.speakingTheme&&r("img",{src:"/speaking/image/teacher_ai_smile.png",alt:"AI Teacher",className:"absolute top-0 left-0 w-full h-auto drop-shadow-[0_4px_16px_rgba(0,0,0,0.2)] transition-opacity duration-700",style:{opacity:S?1:0}})]})}):null;return e("div",{className:"flex flex-col w-full h-full relative",style:{background:"linear-gradient(180deg, #E6F3FF 0%, #FFFFFF 100%)"},children:[e("div",{className:"relative w-full flex justify-between items-start pt-6 px-6 z-20 shrink-0",children:[r("div",{className:"flex-1"}),r("div",{className:"flex-none drop-shadow-md",children:r(n,{partNumber:x.part.partNo,questionCount:x.part.questions.length,partName:x.part.name||`Part ${x.part.partNo}`})}),r("div",{className:"flex-1 flex justify-end mt-2 z-20",children:r(f,{total:x.part.questions.length,currentIndex:y.nav.currentIndex,answeredIds:L,questionIds:V})})]}),e("div",{className:"flex-1 w-full flex flex-col items-center min-h-0 px-4 pb-6 pt-2",children:[_.isBackup&&r("div",{className:"bg-amber-500 text-white px-3 py-1 rounded-md text-xs font-bold border border-white shadow-md z-10 shrink-0 mb-4",children:"Câu hỏi dự phòng"}),_.question&&r("div",{className:"z-10 mx-auto px-8 py-2.5 bg-white backdrop-blur-md rounded-full shadow-[0_2px_10px_rgba(0,0,0,0.05)] border border-slate-100 w-fit shrink-0 mb-4",children:r("h3",{className:"text-[17px] md:text-lg font-bold text-[#343C55] font-['Quicksand'] text-center whitespace-pre-wrap leading-tight",children:_.question})}),_.audioUrl&&r("div",{className:"z-10 mx-auto w-full max-w-[280px] shrink-0 mb-4",children:r(o,{audioUrl:_.audioUrl,onPlayingChange:y.onAudioPlayingChange,autoPlay:!x.waitForTeacherVideo})}),e("div",{className:"flex-1 w-full flex justify-center items-center min-h-[320px] relative mb-4",children:[y.showExistingBadge&&e("div",{className:"absolute right-4 top-0 z-10 rounded-full bg-green-500 px-4 py-1.5 flex items-center gap-2 text-sm font-bold text-white shadow-lg border-2 border-white transform -translate-y-1/2",children:[r("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),r("div",E?{className:"flex justify-center items-center w-full max-w-[60%] h-full max-h-[300px] border-4 border-dashed border-gray-300 rounded-xl bg-gray-50/50",children:r("div",{className:"animate-spin rounded-full h-12 w-12 border-4 border-blue-500 border-t-transparent"})}:C?{className:"bg-white rounded-2xl shadow-[0_4px_15px_rgba(0,0,0,0.08)] p-2 h-full max-w-[92%] flex justify-center items-center",children:r("img",{src:C,alt:"Scene to describe",className:"h-full w-auto max-w-full object-contain rounded-xl",draggable:!1})}:{className:"flex justify-center items-center text-orange-800 font-semibold opacity-70 w-full h-full max-h-[300px] border-4 border-dashed border-orange-900/30 rounded-xl bg-orange-900/10",children:"Chưa có hình ảnh mô tả"})]}),y.recorder&&!x.isReviewMode&&e("div",{className:"shrink-0 flex flex-col items-center z-50 gap-3",children:[r("div",{className:"bg-white rounded-[100px] shadow-[0_4px_10px_rgba(0,0,0,0.1)] whitespace-nowrap flex items-center justify-center",style:{padding:"10px 30px",color:"recording"===y.recorder.status?"#FF4D4D":["recorded","uploading","uploaded"].includes(y.recorder.status)?"#16CA3B":"#343C55",fontSize:"18px",fontFamily:'"Quicksand", sans-serif',fontWeight:700,lineHeight:"100%",letterSpacing:"-0.01em"},children:"recording"===y.recorder.status?"Ấn lần nữa để lưu kết quả":["recorded","uploading","uploaded"].includes(y.recorder.status)?"Câu trả lời đã được ghi nhận !":"Ấn biểu tượng Micro để trả lời"}),e("div",{className:"relative flex flex-col items-center",children:["recording"===y.recorder.status?e("div",{className:"relative flex flex-col justify-center items-center cursor-pointer drop-shadow-[0_0_15px_rgba(255,100,100,0.8)] transition-transform hover:scale-[1.05] active:scale-[0.95]",onClick:y.recorder.stopRecording,children:[r(c,{src:h,alt:"stop recording",className:"animate-pulse",style:{width:"120px",height:"120px"}}),e("span",{className:"absolute text-white text-[16px] font-bold font-['Quicksand']",style:{bottom:"30px"},children:[Math.floor(y.recorder.remainingSeconds/60),":",(y.recorder.remainingSeconds%60).toString().padStart(2,"0")]})]}):r(c,{src:["recorded","uploading","uploaded"].includes(y.recorder.status)?T?g:p:u,alt:"mic",className:"transition-transform cursor-pointer hover:scale-[1.05] active:scale-[0.95]",style:{width:"120px",height:"120px"},onClick:()=>{if("recording"===y.recorder?.status)y.recorder.stopRecording();else if("idle"===y.recorder?.status||"error"===y.recorder?.status)y.recorder.startRecording();else if("uploaded"===y.recorder?.status||"recorded"===y.recorder?.status){const e=I.current;e&&(T?e.pause():e.play().catch(console.error))}}}),y.recorder?.previewUrl&&r("audio",{ref:I,src:y.recorder.previewUrl}),"recording"===y.recorder.status&&r("div",{className:"absolute whitespace-nowrap text-center",style:{top:"100%",marginTop:"16px",color:"#FF4D4D",fontSize:"18px",fontFamily:'"Quicksand", sans-serif',fontWeight:700,lineHeight:"100%",letterSpacing:"-0.01em",textShadow:"0 1px 3px rgba(0,0,0,0.15)"},children:"Đang ghi âm câu hỏi . . ."}),["recorded","uploading","uploaded"].includes(y.recorder.status)&&r("div",{className:"absolute whitespace-nowrap text-center flex flex-col items-center",style:{top:"100%",marginTop:"16px",color:"#343C55",fontSize:"18px",fontFamily:'"Quicksand", sans-serif',fontWeight:700,lineHeight:"100%",letterSpacing:"-0.01em"},children:T?`${w(j)}/${A?w(A):"--:--"}`:"Nghe đáp án"})]})]})]}),B]})}
@@ -0,0 +1,16 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingDragObjectsRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ }
15
+ export declare function SpeakingDragObjectsRenderer(props: SpeakingDragObjectsRendererProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as t,Fragment as r}from"react/jsx-runtime";import{useMemo as a,useState as n}from"react";import{X as o}from"lucide-react";import{usePresignedFileUrl as i}from"../../../../../../shared/lib/hooks";import{useSpeakingRendererSetup as s}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as d}from"../../../../../../components/themes";import l from"../SpeakingDragObjects.module.css";import c from"../SpeakingReadDisplayedContent.module.css";function u({total:r,currentIndex:a,answeredIds:n,questionIds:o}){return e("div",{className:c.taskIndicator,style:{color:"#1e3a8a",textShadow:"none",fontWeight:800},children:[e("span",{children:["Question ",a+1,"/ ",r]}),t("div",{className:"flex gap-2",children:Array.from({length:r},(e,r)=>{const i=r===a,s=n.has(o[r]);return t("div",{className:`${c.taskDot} ${i?c.taskDotActive:""} ${s&&!i?c.taskDotCompleted:""}`,style:i||s?void 0:{background:"#bfdbfe"}},r)})})]})}function m({node:e,isPlaced:r,onDragStart:a}){const{previewUrl:n}=i(e.imageUrl||"");return t("div",{className:l.dragItemContainer,children:t("div",{id:e.id,draggable:!r,className:l.dragItem,style:{cursor:r?"not-allowed":"move",position:"relative",zIndex:2,opacity:r?.3:1},onDragStart:t=>{r?t.preventDefault():(t.dataTransfer.setData("text/plain",e.id),t.dataTransfer.effectAllowed="move",a(e.id))},children:n?t("img",{alt:e.label||"icon",src:n,style:{maxHeight:"100%",maxWidth:"100%",height:"auto",width:"auto",objectFit:"contain"},draggable:!1}):t("div",{className:"flex h-full w-full items-center justify-center text-[10px] text-center px-1 text-gray-500 font-medium",children:e.label})})})}function p({zone:a,droppedObject:n,isDragOver:s,isReviewMode:d,onDragOver:c,onDrop:u,onDragLeave:m,onRemove:p}){const{previewUrl:h}=i(n?.imageUrl??"");return t("div",{onDragOver:e=>c(e,a.id),onDrop:e=>u(e,a.id),onDragLeave:m,"data-testid":`(${a.x}%,${a.y}%)`,style:{position:"absolute",zIndex:1,top:`${a.y}%`,left:`${a.x}%`,height:`${a.height}%`,width:`${a.width}%`,backgroundColor:n?"transparent":s?"rgba(245, 158, 11, 0.4)":"rgba(255, 255, 255, 0.2)",border:n?"none":s?"2px dashed #f59e0b":"1px dashed rgba(255,255,255,0.5)",borderRadius:"8px",transition:"all 0.2s"},children:n&&h&&e(r,{children:[t("img",{src:h,alt:n.label,className:l.objectImageMoved,style:{position:"absolute",height:"100%",width:"100%",inset:0,objectFit:"contain"},draggable:!1}),!d&&t("button",{type:"button",onClick:e=>{e.stopPropagation(),p(a.id)},className:"absolute -right-2 -top-2 flex h-5 w-5 items-center justify-center rounded-full bg-red-500 text-white shadow-md hover:bg-red-600 z-10 border border-white",title:"Remove",children:t(o,{className:"h-3 w-3"})})]})})}export function SpeakingDragObjectsRenderer(r){const o=s({...r,hasMic:!1}),c=d(r.speakingTheme),h=o.currentQuestion?.content,g=o.currentQuestion,v=a(()=>{let e=g?.questionGroup?.payload||g?.question_group?.payload;if("string"==typeof e)try{e=JSON.parse(e)}catch{e={}}return e||{}},[g?.questionGroup?.payload,g?.question_group?.payload]),f=h?.audioUrl??"",b=v?.backgroundImageUrl??"",x=v?.objectNodes??[],w=v?.dropZones??[],{previewUrl:N}=i(b),[D,y]=a(()=>{const e=Math.ceil(x.length/2);return[x.slice(0,e),x.slice(e)]},[x]),[I,j]=n(null),k=o.currentQuestion?r.answers[o.currentQuestion.id]:void 0,C=k?.dropZoneId??null,R=k?.objectId??null,P=e=>{if(C===e&&R)return t=R,x.find(e=>e.id===t);var t},T=e=>{},O=(e,t)=>{e.preventDefault(),e.dataTransfer.dropEffect="move",j(t)},S=(e,t)=>{if(e.preventDefault(),j(null),!o.currentQuestion||r.isReviewMode)return;const a=e.dataTransfer.getData("text/plain");a&&r.onAnswerChange(o.currentQuestion.id,{objectId:a,dropZoneId:t})},$=()=>j(null),q=e=>{o.currentQuestion&&!r.isReviewMode&&C===e&&r.onAnswerChange(o.currentQuestion.id,void 0)};if(!o.currentQuestion)return null;const E=new Set(r.part.questions.map(e=>e.id).filter(e=>!!r.answers[e])),A=r.part.questions.map(e=>e.id),Q=t(u,{total:r.part.questions.length,currentIndex:o.nav.currentIndex,answeredIds:E,questionIds:A});return t(c,{onExit:r.onExit,partName:r.part.name||`Part ${r.part.partNo}`,instruction:r.part.instructions||"LISTEN AND DRAG THE CORRECT OBJECT INTO THE SCENE.",audioUrl:f,questionNumber:o.nav.questionNumberInPart,onPrev:o.handlePrev,onNext:o.handleNext,showPrev:o.nav.showPrev,showNext:o.nav.showNext,canGoPrev:o.nav.canGoPrev,canGoNext:o.nav.canGoNext,onAudioPlayingChange:o.onAudioPlayingChange,recorder:null,headerRight:Q,teacherVideoUrl:r.teacherVideoUrl,onTeacherVideoEnded:r.onTeacherIntroPlayed,skipTeacherVideo:r.skipTeacherVideo,contentClassName:"!p-0 !gap-0",children:e("div",{className:l.moveObjectContainer,children:[t("div",{className:l.objectChoices,children:D.map(e=>t(m,{node:e,isPlaced:R===e.id,onDragStart:T},e.id))}),t("div",{className:l.objectBackground,children:t("div",{className:`relative flex items-center justify-center w-full h-full ${l.imageBackground}`,children:t("div",{className:"relative w-full max-w-[950px] mx-auto rounded-xl drop-shadow-md bg-white border-2 border-stone-200 overflow-hidden mb-6",children:N?e("div",{className:l.imageAspectWrapper,children:[t("img",{alt:"scene",src:N,className:l.mainImg,draggable:!1}),w.map(e=>t(p,{zone:e,droppedObject:P(e.id),isDragOver:I===e.id,isReviewMode:r.isReviewMode||!1,onDragOver:O,onDrop:S,onDragLeave:$,onRemove:q},e.id))]}):t("div",{className:"flex h-full w-full items-center justify-center text-sm text-stone-400",children:"Đang tải ảnh..."})})})}),t("div",{className:`${l.objectChoices} ${l.objectChoicesRight}`,children:y.map(e=>t(m,{node:e,isPlaced:R===e.id,onDragStart:T},e.id))})]})})}
@@ -0,0 +1,16 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingGNInterviewRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ }
15
+ export declare function SpeakingGNInterviewRenderer(props: SpeakingGNInterviewRendererProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useState as i,useEffect as s,useRef as n,useCallback as a,useMemo as r}from"react";import l from"next/image";import{usePresignedFileUrl as o}from"../../../../../../shared/lib/hooks";import{useSpeakingRendererSetup as c}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as d}from"../../../../../../components/themes";import p from"../../../../../../components/themes/spaceship/assets/images/question-badge-sunset.png";import h from"../../../../../../components/themes/spaceship/assets/images/red-badge-sunset.png";import m from"../../../../../../components/themes/spaceship/assets/images/blue-badge-sunset.png";import u from"../../../../../../components/themes/spaceship/assets/images/red-wrapper-sunset.png";import x from"../../../../../../components/themes/spaceship/assets/images/blue-wrapper-sunset.png";import f from"../../../../../../components/themes/spaceship/assets/images/robot-avatar.png";import g from"../../../../../../components/themes/spaceship/assets/images/student-avatar.png";import y from"../../../../../../components/themes/spaceship/assets/images/ic-play-sunset.png";import v from"../../../../../../components/themes/spaceship/assets/images/ic-play-violet.webp";import w from"../../../../../../components/themes/spaceship/assets/images/next-small.webp";function N({total:t,currentIndex:i,answeredIds:s,questionIds:n,virtualIndices:a}){return e("div",{className:"flex items-center gap-1.5 flex-wrap justify-center",children:Array.from({length:t},(t,r)=>{const l=r===i,o=s.has(n[r]),c=a.has(r);return e("div",{className:"h-2.5 w-2.5 rounded-full border-2 transition-all "+(l?"scale-125 border-yellow-300 bg-yellow-400 shadow-lg":o?"border-green-400 bg-green-400":c?"border-white/30 bg-white/10":"border-white/50 bg-white/20"),title:c?"Câu HS ảo":`Câu ${r+1}`},r)})})}export function SpeakingGNInterviewRenderer(b){const[S,R]=i(!0),[j,I]=i(!1),P=n(null),T=b.part.groupPayload,k=T?.virtualStudentName||"Học sinh AI",W=r(()=>{const e=new Set;return b.part.questions.forEach((t,i)=>{const s=t.content;"VIRTUAL"===s?.targetCandidate&&e.add(i)}),e},[b.part.questions]),q=c({...b,maxDurationMs:6e4,hasMic:!0}),A=d("SPACESHIP"),z=q.currentQuestion?.content,C="VIRTUAL"===z?.targetCandidate,U=!C,{previewUrl:E}=o(z?.virtualAnswer?.audioUrl??""),{previewUrl:B}=o(z?.imageUrl??""),L=!!z?.imageUrl&&!!B;s(()=>{P.current&&(P.current.pause(),P.current.currentTime=0),I(!1)},[q.currentQuestion?.id]);const V=a(()=>{if(E){if(j&&P.current)return P.current.pause(),void I(!1);P.current?P.current.src=E:(P.current=new Audio(E),P.current.onended=()=>I(!1),P.current.onerror=()=>I(!1)),P.current.play(),I(!0)}},[E,j]);s(()=>()=>{P.current&&(P.current.pause(),P.current=null)},[]);const H=a(()=>{if(!C||!E)return;const e=setTimeout(()=>{V()},1e3);return()=>clearTimeout(e)},[C,E,V]);if(!q.currentQuestion||!z)return null;const F=new Set(b.part.questions.map(e=>e.id).filter(e=>!!b.answers[e])),Y=b.part.questions.map(e=>e.id),D=e(N,{total:b.part.questions.length,currentIndex:q.nav.currentIndex,answeredIds:F,questionIds:Y,virtualIndices:W});return t(A,{onExit:b.onExit,partName:b.part.name||`Part ${b.part.partNo}`,instruction:b.part.instructions||"LISTEN AND ANSWER",audioUrl:z.audioUrl??"",questionNumber:q.nav.questionNumberInPart,onPrev:q.handlePrev,onNext:q.handleNext,showPrev:q.nav.showPrev,showNext:q.nav.showNext,canGoPrev:q.nav.canGoPrev,canGoNext:q.nav.canGoNext,onAudioPlayingChange:q.onAudioPlayingChange,recorder:b.isReviewMode||C?null:q.recorder,showExistingBadge:U&&q.showExistingBadge,teacherVideoUrl:b.teacherVideoUrl,onTeacherVideoEnded:b.onTeacherIntroPlayed,skipTeacherVideo:b.skipTeacherVideo,headerRight:D,onAudioEnded:H,children:[t("div",{className:"w-full h-full flex flex-col items-center relative",children:[e("div",{className:"w-full flex-1",style:{minHeight:0},children:e("div",{className:"mx-auto",style:{width:"850px",maxWidth:"90%",height:L?"auto":"calc(100% - 100px)"},children:t("div",{className:`w-full ${L?"":"h-full"} flex flex-col items-center`,style:L?{}:{paddingTop:"30px"},children:[S&&z.questionText&&t("div",{className:"relative flex flex-col justify-center items-center",style:{width:"882px",maxWidth:"90%",maxHeight:"80%",paddingLeft:"77px",paddingRight:"77px",paddingTop:"26px",paddingBottom:"26px",backgroundColor:"rgba(232, 136, 154, 0.15)",borderRadius:"20px"},children:[t("div",{className:"absolute cursor-pointer",style:{top:"-19px"},onClick:()=>R(!1),children:[e(l,{src:p,alt:"",style:{width:"169px",height:"38px"}}),e("div",{className:"absolute inset-0 flex justify-center items-center select-none",children:e("span",{className:"font-normal text-center leading-5 text-white",style:{fontSize:"18px"},children:"Ẩn câu hỏi"})})]}),e("div",{className:"max-w-full",children:e("div",{className:"text-black font-bold leading-[26px] text-center max-w-full",style:{fontSize:"18px",fontFamily:'"Open Sans", sans-serif'},children:e("p",{children:z.questionText})})})]}),!S&&t("div",{className:"cursor-pointer",onClick:()=>R(!0),children:[e(l,{src:p,alt:"",style:{width:"169px",height:"38px"}}),e("div",{className:"absolute inset-0 flex justify-center items-center select-none",style:{position:"relative",top:"-30px"},children:e("span",{className:"font-normal text-center leading-5 text-white",style:{fontSize:"18px"},children:"Hiện câu hỏi"})})]}),L&&e("div",{className:"flex justify-center",style:{marginTop:"12px"},children:e("div",{className:"relative overflow-hidden",style:{maxWidth:"100%",borderRadius:"16px",border:"3px solid rgba(230, 99, 93, 0.3)",boxShadow:"0 4px 15px rgba(0,0,0,0.08)"},children:e("img",{src:B,alt:"Booklet",style:{width:"100%",height:"100%",objectFit:"cover"}})})})]})})}),t("div",{className:"flex justify-between select-none items-end",style:{width:"990px",maxWidth:"95%",paddingBottom:"40px",paddingLeft:"20px",paddingRight:"20px"},children:[t("div",{className:"relative select-none transition-opacity duration-300 "+(C?"opacity-100":"opacity-50 grayscale"),children:[e("div",{children:t("div",{className:"relative flex",children:[e(l,{src:h,alt:"",style:{height:"57px",width:"258px"}}),e("div",{className:"absolute inset-0 flex justify-center items-center",style:{paddingTop:"12px"},children:e("div",{className:"text-white leading-5 font-normal text-center m-0 w-full select-none",children:e("p",{className:"m-0 truncate select-none",style:{fontSize:"18px",paddingLeft:"60px",paddingRight:"60px"},children:k})})})]})}),t("div",{className:"absolute",style:{top:"7px",right:"-58px"},children:[e(l,{src:u,alt:"",className:"relative",style:{width:"115px",height:"84px",zIndex:0}}),e("div",{className:"absolute inset-0 flex justify-center items-center w-full h-full",children:t("div",{className:"relative",style:{width:"68px",height:"68px"},children:[e(l,{src:f,alt:k,width:68,height:68,className:"object-cover rounded-full select-none",style:{width:"68px",height:"68px"},draggable:!1}),e("div",{className:"flex items-center justify-center absolute w-full h-full top-0 rounded-full text-white cursor-pointer",onClick:C?V:void 0,children:e(l,{src:y,alt:"play",width:16,height:16,className:"opacity-80"})})]})})]}),j&&e("div",{className:"absolute pointer-events-none",style:{top:"0px",right:"-130px",width:"70px",height:"84px",display:"flex",alignItems:"center"},children:t("div",{className:"relative",style:{width:"70px",height:"70px"},children:[e("div",{style:{position:"absolute",left:"0px",top:"50%",transform:"translateY(-50%)",width:"20px",height:"34px",borderRight:"3px solid rgba(30, 64, 175, 0.95)",borderRadius:"0 50% 50% 0",animation:"soundWavePulse 1s ease-in-out infinite",animationDelay:"0s"}}),e("div",{style:{position:"absolute",left:"12px",top:"50%",transform:"translateY(-50%)",width:"28px",height:"50px",borderRight:"3px solid rgba(30, 64, 175, 0.7)",borderRadius:"0 50% 50% 0",animation:"soundWavePulse 1s ease-in-out infinite",animationDelay:"0.2s"}}),e("div",{style:{position:"absolute",left:"24px",top:"50%",transform:"translateY(-50%)",width:"36px",height:"66px",borderRight:"3px solid rgba(30, 64, 175, 0.45)",borderRadius:"0 50% 50% 0",animation:"soundWavePulse 1s ease-in-out infinite",animationDelay:"0.4s"}})]})})]}),j&&e("div",{className:"flex-1 flex justify-center items-center text-center",style:{paddingLeft:"40px",paddingRight:"40px",paddingBottom:"40px"},children:t("p",{className:"m-0 select-none",style:{fontSize:"16px",fontWeight:700,fontStyle:"italic",color:"#1a1a2e",lineHeight:"1.5",fontFamily:'"Open Sans", sans-serif'},children:["Người chơi khác đang trả lời.",e("br",{}),"Vui lòng nghe xong để tiếp tục."]})}),C&&!j&&t("div",{className:"flex-1 flex flex-col justify-center items-center text-center",style:{paddingLeft:"40px",paddingRight:"40px",paddingBottom:"40px"},children:[t("p",{className:"m-0 whitespace-nowrap",style:{color:"#1a1a2e",fontSize:"16px",fontWeight:700,fontStyle:"italic",fontFamily:'"Open Sans", sans-serif'},children:["Ấn biểu tượng"," ",e(l,{src:v,alt:"",width:20,height:20,className:"inline-block"})," ","trên avatar để nghe lại."]}),t("div",{className:"flex items-center",style:{gap:"4px"},children:[e("p",{className:"m-0",style:{color:"#1a1a2e",fontSize:"16px",fontWeight:700,fontStyle:"italic",fontFamily:'"Open Sans", sans-serif'},children:"Ấn nút"}),e(l,{src:w,alt:"next",width:34,height:34}),e("p",{className:"m-0",style:{color:"#1a1a2e",fontSize:"16px",fontWeight:700,fontStyle:"italic",fontFamily:'"Open Sans", sans-serif'},children:"để tiếp tục."})]})]}),t("div",{className:"relative select-none transition-opacity duration-300 "+(U?"opacity-100":"opacity-50 grayscale"),children:[e("div",{children:t("div",{className:"relative flex",children:[e(l,{src:m,alt:"",style:{height:"57px",width:"258px"}}),e("div",{className:"absolute inset-0 flex justify-center items-center",style:{paddingTop:"12px"},children:e("div",{className:"text-white leading-5 font-normal text-center m-0 w-full select-none",children:e("p",{className:"m-0 truncate select-none",style:{fontSize:"18px",paddingLeft:"60px",paddingRight:"60px"},children:"Bạn"})})})]})}),t("div",{className:"absolute",style:{top:"7px",left:"-58px"},children:[e(l,{src:x,alt:"",className:"relative",style:{width:"115px",height:"84px",zIndex:0}}),e("div",{className:"absolute inset-0 flex justify-center items-center w-full h-full",children:e("div",{className:"relative",style:{width:"68px",height:"68px"},children:e(l,{src:g,alt:"Bạn",width:68,height:68,className:"object-cover rounded-full select-none",style:{width:"68px",height:"68px"},draggable:!1})})})]})]})]})]}),e("style",{jsx:!0,children:"\n @keyframes soundWavePulse {\n 0% {\n opacity: 0.2;\n transform: translateY(-50%) scaleX(0.7);\n }\n 50% {\n opacity: 1;\n transform: translateY(-50%) scaleX(1);\n }\n 100% {\n opacity: 0.2;\n transform: translateY(-50%) scaleX(0.7);\n }\n }\n "})]})}
@@ -0,0 +1,16 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingInfoExchangeRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ }
15
+ export declare function SpeakingInfoExchangeRenderer(props: SpeakingInfoExchangeRendererProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as a}from"react/jsx-runtime";import{ResolvedImage as i}from"../../../../../../components/common/ResolvedImage";import{useSpeakingRendererSetup as n}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as r}from"../../../../../../components/themes";import t from"../SpeakingInfoExchange.module.css";import s from"../SpeakingInfoExchangeSummerSky.module.css";export function SpeakingInfoExchangeRenderer(l){const d=n({...l,maxDurationMs:3e4}),c=r(l.speakingTheme),m="SUMMER_SKY"===l.speakingTheme,h=m?s:t,f=d.currentQuestion?.content,u=d.currentQuestion?.questionGroup?.payload;if(!d.currentQuestion||!f)return null;const g=f.audioUrl??"",p=u?.title??"",N=u?.imageUrl??"",v=u?.candidateFields??[],x=u?.examinerFields??[];return e(c,{onExit:l.onExit,partName:l.part.name||`Part ${l.part.partNo}`,instruction:l.part.instructions||"INFORMATION EXCHANGE",audioUrl:g,questionNumber:d.nav.questionNumberInPart,onPrev:d.handlePrev,onNext:d.handleNext,showPrev:d.nav.showPrev,showNext:d.nav.showNext,canGoPrev:d.nav.canGoPrev,canGoNext:d.nav.canGoNext,onAudioPlayingChange:d.onAudioPlayingChange,recorder:l.isReviewMode?null:d.recorder,showExistingBadge:d.showExistingBadge,teacherVideoUrl:l.teacherVideoUrl,onTeacherVideoEnded:l.onTeacherIntroPlayed,skipTeacherVideo:l.skipTeacherVideo,contentClassName:"!gap-2",children:e("div",{className:"w-full h-full",children:e("div",{className:h.part2Container,children:a("div",{className:h.questionContainer,children:[N&&a("div",m?{className:h.imageWrapper,children:[d.showExistingBadge&&a("div",{className:h.recordedBadge,children:[e("span",{className:h.recordedBadgeDot}),"Đã ghi âm"]}),e("div",{className:h.imageFrame,children:e(i,{src:N,alt:p||"Info Exchange",className:"object-contain h-full w-full pointer-events-none",draggable:!1})})]}:{className:"relative h-full flex items-center justify-center",children:[d.showExistingBadge&&a("div",{className:"absolute right-4 top-4 z-10 rounded-full bg-green-500 px-4 py-1 flex items-center gap-2 text-sm font-bold text-white shadow-md border-2 border-white",children:[e("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),e("div",{className:t.imageBorder,children:e(i,{src:N,alt:p||"Info Exchange",className:"object-cover h-full w-full pointer-events-none",draggable:!1})})]}),a("div",{className:h.infoContainer,children:[e(o,{heading:"Candidate's Copy",title:p,fields:v,styles:h,isSummerSky:m}),e(o,{heading:"Examiner's Copy",title:p,fields:x,styles:h,isSummerSky:m})]})]})})})})}function o({heading:i,title:n,fields:r,styles:t,isSummerSky:s}){const o=r.map((i,n)=>{const r=!i.answer||"___"===i.answer||"?"===i.answer;return a("div",s?{className:t.infoDetailItem,children:[e("div",{className:t.infoDetailLabel,children:i.key}),e("div",{className:t.infoDetailDivide}),e("div",{className:[t.infoDetailValue,r?t.infoDetailValueBlank:""].join(" "),children:r?"?":i.answer})]}:{className:t.infoDetailItem,children:[e("div",{className:t.infoDetailItemValue,style:{textAlign:"right",flex:1,minWidth:0,wordBreak:"break-word",paddingRight:"10px",color:"#fff",fontSize:"18px",fontWeight:700},children:i.key}),e("div",{className:t.infoDetailItemDivide}),e("div",{className:t.infoDetailItemValue,style:{textAlign:"left",flex:1,minWidth:0,wordBreak:"break-word",paddingLeft:"10px",color:r?"#a8a29e":"#fff",fontStyle:r?"italic":"normal",fontSize:"18px",fontWeight:r?"normal":700},children:r?"?":i.answer})]},n)});return a("div",s?{className:t.infoItem,children:[e("div",{className:t.infoHeader,children:i}),a("div",{className:t.infoItemInner,children:[n&&e("div",{className:t.infoName,children:n}),o]})]}:{className:t.infoItem,children:[e("div",{className:t.infoHeader,children:i}),n&&e("div",{className:t.infoName,children:n}),o]})}
@@ -0,0 +1,16 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingListenAndSpeakAnswerRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ }
15
+ export declare function SpeakingListenAndSpeakAnswerRenderer(props: SpeakingListenAndSpeakAnswerRendererProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{usePresignedFileUrl as r}from"../../../../../../shared/lib/hooks";import{useSpeakingRendererSetup as n}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as a}from"../../../../../../components/themes";import o from"../SpeakingReadDisplayedContent.module.css";function s({total:r,currentIndex:n,answeredIds:a,questionIds:s}){return e("div",{className:o.taskIndicator,style:{color:"#1e3a8a",textShadow:"none",fontWeight:800},children:[e("span",{children:["Question ",n+1,"/ ",r]}),t("div",{className:"flex gap-2",children:Array.from({length:r},(e,r)=>{const i=r===n,l=a.has(s[r]);return t("div",{className:`${o.taskDot} ${i?o.taskDotActive:""} ${l&&!i?o.taskDotCompleted:""}`,style:i||l?void 0:{background:"#bfdbfe"}},r)})})]})}function i({backgroundImageUrl:n,arrowNode:a}){const{previewUrl:o}=r(n);return o?e("div",{className:"relative w-full flex justify-center items-center",children:[t("img",{src:o,alt:"Scene",className:"block w-full h-auto max-h-[calc(100vh-280px)] object-contain rounded-xl",draggable:!1}),a&&t("div",{className:"absolute",style:{left:`${a.x}%`,top:`${a.y}%`,width:`${a.width}%`,height:`${a.height}%`},"aria-hidden":"true",children:t("div",{className:"flex h-full w-full items-end justify-center pb-1",children:t("svg",{viewBox:"0 0 24 24",className:"w-full h-full text-red-500 drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]",fill:"currentColor",children:t("path",{d:"M12 21L4 12h5V3h6v9h5L12 21z"})})})})]}):null}export function SpeakingListenAndSpeakAnswerRenderer(r){const o=n({...r,maxDurationMs:3e4}),l=a(r.speakingTheme),d=o.currentQuestion?.content;if(!o.currentQuestion||!d)return null;const c=d.audioUrl??"",h=d.backgroundImageUrl??"",u=d.arrowNode,m=new Set(r.part.questions.map(e=>e.id).filter(e=>!!r.answers[e])),p=r.part.questions.map(e=>e.id),x=t(s,{total:r.part.questions.length,currentIndex:o.nav.currentIndex,answeredIds:m,questionIds:p});return t(l,{onExit:r.onExit,partName:r.part.name||`Part ${r.part.partNo}`,instruction:r.part.instructions||"LISTEN AND SPEAK YOUR ANSWER.",audioUrl:c,questionNumber:o.nav.questionNumberInPart,onPrev:o.handlePrev,onNext:o.handleNext,showPrev:o.nav.showPrev,showNext:o.nav.showNext,canGoPrev:o.nav.canGoPrev,canGoNext:o.nav.canGoNext,onAudioPlayingChange:o.onAudioPlayingChange,recorder:r.isReviewMode?null:o.recorder,showExistingBadge:o.showExistingBadge,headerRight:x,teacherVideoUrl:r.teacherVideoUrl,onTeacherVideoEnded:r.onTeacherIntroPlayed,skipTeacherVideo:r.skipTeacherVideo,contentClassName:"!p-0 !gap-0",children:t("div",{className:"w-full h-full flex items-center justify-center px-8 pb-[80px] pt-[70px]",children:e("div",{className:"relative w-full max-w-[850px] bg-white rounded-xl drop-shadow-md border-2 border-stone-200 overflow-hidden",children:[o.showExistingBadge&&e("div",{className:"absolute right-4 top-4 z-10 rounded-full bg-green-500 px-4 py-1 flex items-center gap-2 text-sm font-bold text-white shadow-md border-2 border-white",children:[t("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),h?t(i,{backgroundImageUrl:h,arrowNode:u}):t("div",{className:"flex h-[400px] w-full justify-center items-center text-stone-400 font-medium",children:"Đang tải ảnh..."})]})})})}
@@ -0,0 +1,16 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingOddOneOutRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ onTeacherIntroPlayed?: () => void;
13
+ skipTeacherVideo?: boolean;
14
+ }
15
+ export declare function SpeakingOddOneOutRenderer(props: SpeakingOddOneOutRendererProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{cn as n}from"../../../../../../shared/lib/utils";import{ResolvedImage as r}from"../../../../../../components/common/ResolvedImage";import{useSpeakingRendererSetup as a}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as i}from"../../../../../../components/themes";import s from"../SpeakingReadDisplayedContent.module.css";function o({total:n,currentIndex:r,answeredIds:a,questionIds:i}){return e("div",{className:s.taskIndicator,style:{color:"#1e3a8a",textShadow:"none",fontWeight:800},children:[e("span",{children:["Question ",r+1,"/ ",n]}),t("div",{className:"flex gap-2",children:Array.from({length:n},(e,n)=>{const o=n===r,d=a.has(i[n]);return t("div",{className:`${s.taskDot} ${o?s.taskDotActive:""} ${d&&!o?s.taskDotCompleted:""}`,style:o||d?void 0:{background:"#bfdbfe"}},n)})})]})}export function SpeakingOddOneOutRenderer(e){const n=a({...e,maxDurationMs:3e4}),r=i(e.speakingTheme),s=n.currentQuestion?.content,l=n.currentQuestion?.questionGroup?.payload;if(!n.currentQuestion||!s)return null;const c=s.audioUrl??"",m=l?.images??[],u=s.images,h=m.length>0?m:(u??[]).map((e,t)=>({id:`img-${t}`,url:e,label:String(t+1)})),g=s.activeImageId,p=new Set(e.part.questions.map(e=>e.id).filter(t=>!!e.answers[t])),x=e.part.questions.map(e=>e.id),v=t(o,{total:e.part.questions.length,currentIndex:n.nav.currentIndex,answeredIds:p,questionIds:x});return t(r,{onExit:e.onExit,partName:e.part.name||`Part ${e.part.partNo}`,instruction:e.part.instructions||"WHICH ONE IS DIFFERENT? LISTEN AND EXPLAIN.",audioUrl:c,questionNumber:n.nav.questionNumberInPart,onPrev:n.handlePrev,onNext:n.handleNext,showPrev:n.nav.showPrev,showNext:n.nav.showNext,canGoPrev:n.nav.canGoPrev,canGoNext:n.nav.canGoNext,onAudioPlayingChange:n.onAudioPlayingChange,recorder:e.isReviewMode?null:n.recorder,showExistingBadge:n.showExistingBadge,headerRight:v,teacherVideoUrl:e.teacherVideoUrl,onTeacherVideoEnded:e.onTeacherIntroPlayed,skipTeacherVideo:e.skipTeacherVideo,children:t("div",{className:"w-full flex justify-center items-center",style:{flex:"1 1 0",minHeight:0},children:t(d,{images:h,activeImageId:g,showExistingBadge:n.showExistingBadge})})})}function d({images:a,activeImageId:i,showExistingBadge:s}){return 0===a.length?t("div",{className:"flex h-40 items-center justify-center text-stone-400",children:t("span",{className:"text-sm",children:"No images available"})}):e("div",{className:"relative flex h-full items-center justify-center px-4 py-3",children:[s&&t("div",{className:"absolute right-3 top-3 z-10 rounded-full bg-green-600 px-3 py-1 text-xs font-bold text-white shadow",children:"Đã ghi âm"}),t("div",{className:"flex items-end gap-6",children:a.map(e=>{const a=e.id===i;return t("div",{className:"flex flex-col items-center",children:t("div",{className:n("overflow-hidden",a?"rounded-[10px] border-4 border-white shadow-lg":"rounded-[10px] border-4 border-white shadow-sm"),style:{width:a?"300px":"220px",height:a?"300px":"220px"},children:t(r,{src:e.url,alt:`Image ${e.label}`,className:"h-full w-full object-cover pointer-events-none",draggable:!1})})},e.id)})})]})}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * SpeakingQuestionListRenderer
3
+ *
4
+ * Renderer for LISTEN_AND_SPEAK_QUESTION_LIST (Movers/Flyers Part 4).
5
+ *
6
+ * The group payload holds a list of question texts. Each individual question has an
7
+ * `activeQuestionId` pointing to the question that is currently being asked.
8
+ * The matching item is highlighted. The student listens and records their answer.
9
+ */
10
+ import type { QuestionPart } from '../../../utils/question-transformers';
11
+ interface SpeakingQuestionListRendererProps {
12
+ part: QuestionPart;
13
+ answers: Record<string, unknown>;
14
+ onAnswerChange: (questionId: string, value: unknown) => void;
15
+ isReviewMode?: boolean;
16
+ onExit: () => void;
17
+ onPartComplete?: () => void;
18
+ onPartBack?: () => void;
19
+ speakingTheme?: string;
20
+ teacherVideoUrl?: string;
21
+ onTeacherIntroPlayed?: () => void;
22
+ skipTeacherVideo?: boolean;
23
+ waitForTeacherVideo?: boolean;
24
+ }
25
+ export declare function SpeakingQuestionListRenderer(props: SpeakingQuestionListRendererProps): import("react").JSX.Element;
26
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{useSpeakingRendererSetup as n}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as i}from"../../../../../../components/themes";import a from"../SpeakingReadDisplayedContent.module.css";function s({total:n,currentIndex:i,answeredIds:s,questionIds:r}){return e("div",{className:a.taskIndicator,style:{color:"#1e3a8a",textShadow:"none",fontWeight:800},children:[e("span",{children:["Question ",i+1,"/ ",n]}),t("div",{className:"flex gap-2",children:Array.from({length:n},(e,n)=>{const o=n===i,l=s.has(r[n]);return t("div",{className:`${a.taskDot} ${o?a.taskDotActive:""} ${l&&!o?a.taskDotCompleted:""}`,style:o||l?void 0:{background:"#bfdbfe"}},n)})})]})}export function SpeakingQuestionListRenderer(e){const a=n({...e,maxDurationMs:15e3}),o=i(e.speakingTheme),l=a.currentQuestion?.content,d=a.currentQuestion?.questionGroup?.payload;if(!a.currentQuestion||!l)return null;const c=l.audioUrl??"",u=d?.content??d?.questions??[],h=l.activeQuestionId,x=new Set(e.part.questions.map(e=>e.id).filter(t=>!!e.answers[t])),m=e.part.questions.map(e=>e.id),p=t(s,{total:e.part.questions.length,currentIndex:a.nav.currentIndex,answeredIds:x,questionIds:m});return t(o,{onExit:e.onExit,partName:e.part.name||`Part ${e.part.partNo}`,instruction:e.part.instructions||"ANSWER THE QUESTIONS.",audioUrl:c,questionNumber:a.nav.questionNumberInPart,onPrev:a.handlePrev,onNext:a.handleNext,showPrev:a.nav.showPrev,showNext:a.nav.showNext,canGoPrev:a.nav.canGoPrev,canGoNext:a.nav.canGoNext,onAudioPlayingChange:a.onAudioPlayingChange,recorder:e.isReviewMode?null:a.recorder,showExistingBadge:a.showExistingBadge,headerRight:p,teacherVideoUrl:e.teacherVideoUrl,onTeacherVideoEnded:e.onTeacherIntroPlayed,skipTeacherVideo:e.skipTeacherVideo,waitForTeacherVideo:e.waitForTeacherVideo,contentClassName:"!p-0 !gap-0",children:t("div",{className:"w-full h-full flex items-center justify-center px-8 pb-[80px] pt-[70px]",children:t(r,{questionList:u,activeQuestionId:h,showExistingBadge:a.showExistingBadge})})})}function r({questionList:n,activeQuestionId:i,showExistingBadge:a}){return 0===n.length?t("div",{className:"flex h-40 items-center justify-center text-stone-400",children:t("span",{className:"text-sm",children:"No questions available"})}):e("div",{className:"relative w-full max-w-[820px] flex flex-col gap-3",children:[a&&e("div",{className:"absolute right-0 -top-8 z-10 rounded-full bg-green-500 px-4 py-1 flex items-center gap-2 text-sm font-bold text-white shadow-md border-2 border-white",children:[t("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),n.map((e,n)=>{const a=e.id===i;return t(o,{index:n,text:e.text,isActive:a},e.id)})]})}function o({index:n,text:i,isActive:a}){return e("div",{className:`\n flex items-center gap-4 w-full px-6 py-4 rounded-2xl\n border-2 transition-all duration-300 select-none\n ${a?"bg-gradient-to-r from-[#3B82F6] to-[#1D4ED8] border-[#60A5FA] shadow-lg shadow-blue-200/60":"bg-white border-[#BFDBFE] shadow-sm"}\n `,children:[t("div",{className:`\n flex-shrink-0 w-9 h-9 rounded-full flex items-center justify-center\n text-base font-bold transition-colors duration-300\n ${a?"bg-white/20 text-white":"bg-blue-100 text-blue-600"}\n `,children:n+1}),t("span",{className:`\n text-xl font-semibold leading-snug tracking-wide transition-colors duration-300\n ${a?"text-white":"text-slate-500"}\n `,children:i}),a&&t("div",{className:"ml-auto flex-shrink-0",children:e("span",{className:"flex h-3 w-3",children:[t("span",{className:"animate-ping absolute inline-flex h-3 w-3 rounded-full bg-white opacity-75"}),t("span",{className:"relative inline-flex rounded-full h-3 w-3 bg-white"})]})})]})}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * SpeakingQuestionRenderer — Factory component for speaking question types.
3
+ *
4
+ * Reads `part.questionType` and dispatches to the appropriate speaking renderer.
5
+ * This is the single entry point from QuestionRenderer.tsx for all LISTEN_AND_SPEAK_* types.
6
+ *
7
+ * `onExit` is optional: when omitted the renderers default to router.back().
8
+ * During Phase 4 integration, page.tsx should pass its handleClose as onExit.
9
+ */
10
+ import type { QuestionPart } from '../../../utils/question-transformers';
11
+ interface SpeakingQuestionRendererProps {
12
+ part: QuestionPart;
13
+ answers: Record<string, unknown>;
14
+ onAnswerChange: (questionId: string, value: unknown) => void;
15
+ isReviewMode?: boolean;
16
+ /** Override the exit action. Defaults to router.back(). */
17
+ onExit?: () => void;
18
+ /** Called when navigating past the last question of this part. */
19
+ onPartComplete?: () => void;
20
+ /** Called when navigating back from the first question of this part. */
21
+ onPartBack?: () => void;
22
+ speakingTheme?: string;
23
+ initialQuestionIndex?: number;
24
+ /** Skip teacher intro video (already played for this part). */
25
+ skipTeacherVideo?: boolean;
26
+ /** Callback when teacher intro video finishes playing. */
27
+ onTeacherIntroPlayed?: () => void;
28
+ /** Index of the question to render within the part (for Cambridge YLE 1-by-1 navigation) */
29
+ currentQuestionIndex?: number;
30
+ }
31
+ export declare function SpeakingQuestionRenderer({ part, answers, onAnswerChange, isReviewMode, onExit, onPartComplete, onPartBack, speakingTheme, initialQuestionIndex, skipTeacherVideo, onTeacherIntroPlayed, currentQuestionIndex, }: SpeakingQuestionRendererProps): import("react").JSX.Element;
32
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import{getTeacherVideoUrl as n,shouldWaitForTeacherVideo as t}from"../SpeakingVideoIntro";import{SpeakingCompareImagesRenderer as o}from"./SpeakingCompareImagesRenderer";import{SpeakingStoryImagesRenderer as i}from"./SpeakingStoryImagesRenderer";import{SpeakingOddOneOutRenderer as a}from"./SpeakingOddOneOutRenderer";import{SpeakingQuestionListRenderer as s}from"./SpeakingQuestionListRenderer";import{SpeakingChooseObjectsRenderer as p}from"./SpeakingChooseObjectsRenderer";import{SpeakingChooseAnswerGroupRenderer as S}from"./SpeakingChooseAnswerGroupRenderer";import{SpeakingDragObjectsRenderer as _}from"./SpeakingDragObjectsRenderer";import{SpeakingListenAndSpeakAnswerRenderer as E}from"./SpeakingListenAndSpeakAnswerRenderer";import{SpeakingDescribeImageRenderer as m}from"./SpeakingDescribeImageRenderer";import{SpeakingInfoExchangeRenderer as d}from"./SpeakingInfoExchangeRenderer";import{SpeakingReadDisplayedContentRenderer as N}from"./SpeakingReadDisplayedContentRenderer";import{SpeakingSpontaneousQARenderer as c}from"./SpeakingSpontaneousQARenderer";import{SpeakingConversationRenderer as A}from"./SpeakingConversationRenderer";import{SpeakingGNInterviewRenderer as u}from"./SpeakingGNInterviewRenderer";import{SpeakingCueCardRenderer as I}from"./SpeakingCueCardRenderer";export function SpeakingQuestionRenderer({part:T,answers:R,onAnswerChange:g,isReviewMode:O=!1,onExit:k,onPartComplete:f,onPartBack:C,speakingTheme:P,initialQuestionIndex:D,skipTeacherVideo:h,onTeacherIntroPlayed:l,currentQuestionIndex:w}){const x=k??(()=>{"undefined"!=typeof window&&window.history.back()}),G=!h&&t(T.questionType),L={part:T,answers:R,onAnswerChange:g,isReviewMode:O,onExit:x,onPartComplete:f,onPartBack:C,speakingTheme:P,initialQuestionIndex:D,teacherVideoUrl:n(T.questionType),waitForTeacherVideo:G,onTeacherIntroPlayed:l,skipTeacherVideo:!!h,currentQuestionIndex:w};switch(T.questionType){case"LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE":return e(p,{...L});case"LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP":return e(S,{...L});case"LISTEN_AND_DRAG_OBJECTS_INTO_SCENE":return e(_,{...L});case"LISTEN_AND_SPEAK_ANSWER":return e(E,{...L});case"SPEAKING_DESCRIBE_IMAGE":return e(m,{...L});case"LISTEN_AND_SPEAK_COMPARE_IMAGES":return e(o,{...L});case"LISTEN_AND_SPEAK_WITH_STORY_IMAGES":return e(i,{...L});case"LISTEN_AND_SPEAK_IMAGE_GROUP":case"LISTEN_AND_SPEAK_ODD_ONE_OUT":return e(a,{...L});case"LISTEN_AND_SPEAK_QUESTION_LIST":return e(s,{...L});case"LISTEN_AND_SPEAK_INFO_EXCHANGE":return e(d,{...L});case"READ_DISPLAYED_CONTENT":return e(N,{...L});case"SPONTANEOUS_QA":return e(c,{...L});case"SPEAKING_CONVERSATION":return e(A,{...L});case"GN_SPEAKING_INTERVIEW":return e(u,{...L});case"SPEAKING_CUE_CARD":return e(I,{...L});default:return e("div",{className:"flex h-full items-center justify-center p-8",children:r("p",{className:"text-center text-sm text-red-500",children:["Unsupported speaking question type: ",T.questionType]})})}}
@@ -0,0 +1,17 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingReadDisplayedContentRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ waitForTeacherVideo?: boolean;
13
+ onTeacherIntroPlayed?: () => void;
14
+ skipTeacherVideo?: boolean;
15
+ }
16
+ export declare function SpeakingReadDisplayedContentRenderer(props: SpeakingReadDisplayedContentRendererProps): import("react").JSX.Element;
17
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as r}from"react/jsx-runtime";import{useEffect as t,useRef as i,useState as n}from"react";import{useSpeakingRendererSetup as s}from"../../../hooks/useSpeakingRendererSetup";import{getSpeakingLayout as a}from"../../../../../../components/themes";import l from"../../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import o from"next/image";import d from"../../../../../../components/themes/summer-sky/assets/images/mic_ver2_icon.png";import c from"../../../../../../components/themes/summer-sky/assets/images/stop_audio_ver2_icon.png";import m from"../../../../../../components/themes/summer-sky/assets/images/audio_ver2_icon.png";import u from"../../../../../../components/themes/summer-sky/assets/images/pause_audio_ver2_icon.png";import p from"../SpeakingReadDisplayedContent.module.css";import{SpeakingAudioPlayer as h}from"../../../../../../components/shared/audio/SpeakingAudioPlayer";function f(e){switch(e){case"BASIC_PHONICS":return p.difficultyBasicPhonics;case"DAILY_ROUTINE":return p.difficultyDailyRoutine;case"DESCRIPTIVE_EMOTIONAL":return p.difficultyDescriptiveEmotional;default:return""}}function x(e){switch(e){case"BASIC_PHONICS":return"📖 Basic Phonics";case"DAILY_ROUTINE":return"🕐 Daily Routine & Time";case"DESCRIPTIVE_EMOTIONAL":return"🌄 Descriptive & Emotional";default:return""}}function g({total:t,currentIndex:i,answeredIds:n,questionIds:s,isSpaceship:a}){return e("div",{className:p.taskIndicator,style:a?{color:"#78350f",textShadow:"none",fontWeight:800}:void 0,children:[e("span",{children:["Question ",i+1,"/ ",t]}),r("div",{className:"flex gap-2",children:Array.from({length:t},(e,t)=>{const a=t===i,l=n.has(s[t]);return r("div",{className:`${p.taskDot} ${a?p.taskDotActive:""} ${l&&!a?p.taskDotCompleted:""}`},t)})})]})}function v({total:t,currentIndex:i,answeredIds:n,questionIds:s}){return e("div",{className:"flex items-center gap-2 font-bold text-[#78350f] font-['Quicksand'] z-10",children:[e("span",{className:"text-sm",children:["Question ",i+1,"/ ",t]}),r("div",{className:"flex gap-1.5",children:Array.from({length:t},(e,t)=>{const a=t===i,l=n.has(s[t]);return r("div",{className:"w-2.5 h-2.5 rounded-full "+(a?"bg-[#FF9900] scale-125 shadow-sm":l?"bg-[#16CA3B]":"bg-white/60")},t)})})]})}export function SpeakingReadDisplayedContentRenderer(w){const N=s({...w,maxDurationMs:3e4}),y=i(null),[b,k]=n(!1);t(()=>{const e=y.current;if(!e)return;const r=()=>{k(!0),N.onAudioPlayingChange?.(!0)},t=()=>{k(!1),N.onAudioPlayingChange?.(!1)},i=()=>{k(!1),N.onAudioPlayingChange?.(!1)};return e.addEventListener("play",r),e.addEventListener("pause",t),e.addEventListener("ended",i),()=>{e.removeEventListener("play",r),e.removeEventListener("pause",t),e.removeEventListener("ended",i),N.onAudioPlayingChange?.(!1)}},[N.recorder?.previewUrl,N.onAudioPlayingChange]);const S=a(w.speakingTheme),E="SPACESHIP"===w.speakingTheme||"SUMMER_SKY"===w.speakingTheme,I=N.currentQuestion?.content;if(!N.currentQuestion||!I)return null;const C=I.referenceText??"",A=I.modelAudioUrl??"",P=I.difficultyTag,_=C.length>700?"clamp(15px, 1.6vw, 19px)":C.length>400?"clamp(18px, 2vw, 24px)":"clamp(22px, 2.2vw, 30px)",T=new Set(w.part.questions.map(e=>e.id).filter(e=>!!w.answers[e])),F=w.part.questions.map(e=>e.id);if(w.speakingTheme&&"CAMBRIDGE_YLE"!==w.speakingTheme){const t=r(g,{total:w.part.questions.length,currentIndex:N.nav.currentIndex,answeredIds:T,questionIds:F,isSpaceship:E}),i=A?e("div",{className:p.modelAudioSection,children:[r("span",{className:p.modelAudioLabel,children:"🔊 Model pronunciation:"}),r(h,{audioUrl:A})]}):null;return r(S,{onExit:w.onExit,partName:w.part.name||`Part ${w.part.partNo}`,instruction:w.part.instructions||"READ THE PASSAGE ALOUD",audioUrl:E&&A||"",questionNumber:N.nav.questionNumberInPart,onPrev:N.handlePrev,onNext:N.handleNext,showPrev:N.nav.showPrev,showNext:N.nav.showNext,canGoPrev:N.nav.canGoPrev,canGoNext:N.nav.canGoNext,onAudioPlayingChange:N.onAudioPlayingChange,recorder:w.isReviewMode?null:N.recorder,showExistingBadge:N.showExistingBadge,headerRight:t,audioBarRight:E?null:i,teacherVideoUrl:w.teacherVideoUrl,waitForTeacherVideo:w.waitForTeacherVideo,onTeacherVideoEnded:w.onTeacherIntroPlayed,skipTeacherVideo:w.skipTeacherVideo,children:E?r("div",{className:"w-full h-full flex flex-col items-center relative",children:r("div",{className:"w-full flex-1",style:{minHeight:0},children:r("div",{className:"mx-auto",style:{width:"900px",maxWidth:"95%",height:"calc(100% - 100px)"},children:r("div",{className:"w-full h-full flex flex-col items-center justify-center",style:{paddingTop:"10px"},children:e("div",{className:"relative flex flex-col justify-center items-center",style:{width:"100%",paddingLeft:"60px",paddingRight:"60px",paddingTop:"20px",paddingBottom:"20px"},children:[N.showExistingBadge&&e("div",{className:"absolute right-12 top-12 z-10 rounded-full bg-green-500 px-4 py-1.5 flex items-center gap-2 text-sm font-bold text-white shadow-md border-2 border-white",children:[r("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),r("div",{className:"max-w-full",children:r("div",{className:"text-center max-w-full",style:{fontSize:"40px",fontFamily:'"SVN-Volte Rounded", sans-serif',fontWeight:600,lineHeight:"52px",letterSpacing:"-0.01em",color:"#2C38B6"},children:r("p",{className:"m-0 break-words whitespace-pre-wrap",children:`"${C}"`})})})]})})})})}):e("div",{className:"flex flex-col items-center justify-center h-full w-full gap-4 px-4",children:[P&&r("div",{className:`${p.difficultyBadge} ${f(P)}`,children:x(P)}),e("div",{className:p.referenceTextCard,children:[N.showExistingBadge&&e("div",{className:"absolute right-4 top-4 z-10 rounded-full bg-green-500 px-4 py-1 flex items-center gap-2 text-sm font-bold text-white shadow-md border-2 border-white",children:[r("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),r("p",{className:p.referenceText,children:`"${C}"`})]})]})})}return e("div",{className:"flex flex-col w-full h-full relative",style:{background:"linear-gradient(180deg, #E6F3FF 0%, #FFFFFF 100%)"},children:[e("div",{className:"relative w-full flex justify-between items-start pt-6 px-6 z-20 shrink-0",children:[r("div",{className:"flex-1"}),r("div",{className:"flex-none drop-shadow-md",children:r(l,{partNumber:w.part.partNo,questionCount:w.part.questions.length,partName:w.part.name||`Part ${w.part.partNo}`})}),r("div",{className:"flex-1 flex justify-end mt-2 z-20",children:r(v,{total:w.part.questions.length,currentIndex:N.nav.currentIndex,answeredIds:T,questionIds:F})})]}),e("div",{className:"flex-1 w-full flex flex-col items-center min-h-0 px-4 pb-6 pt-5",children:[w.part.instructions&&e("div",{className:"shrink-0 w-full max-w-[760px] flex items-center gap-3 rounded-2xl px-5 py-3 mb-4",style:{background:"rgba(255, 255, 255, 0.9)",border:"2px solid #FCD34D",boxShadow:"0 3px 12px rgba(180, 130, 20, 0.12)"},children:[r("div",{className:"shrink-0 flex items-center justify-center rounded-full",style:{width:42,height:42,background:"#FEF3C7"},children:r("span",{style:{fontSize:22,lineHeight:1},children:"💡"})}),r("div",{className:"flex flex-col text-left min-w-0",children:r("p",{className:"m-0",style:{color:"#78350F",fontSize:16,fontWeight:600,lineHeight:1.35,fontFamily:'"Quicksand", sans-serif'},children:w.part.instructions})})]}),P&&r("div",{className:"shrink-0 mb-3",children:r("div",{className:`${p.difficultyBadge} ${f(P)}`,children:x(P)})}),r("div",{className:"flex-1 w-full flex flex-col items-center justify-center min-h-0 relative mb-8",children:e("div",{className:"w-full max-w-[850px] max-h-full relative bg-white/60 backdrop-blur-md rounded-2xl shadow-[0_2px_15px_rgba(0,0,0,0.04)] border border-blue-50 p-8 flex flex-col min-h-0",children:[N.showExistingBadge&&e("div",{className:"absolute right-4 top-0 z-10 rounded-full bg-green-500 px-4 py-1.5 flex items-center gap-2 text-sm font-bold text-white shadow-lg border-2 border-white transform -translate-y-1/2",children:[r("span",{className:"h-2.5 w-2.5 rounded-full bg-white animate-pulse"}),"Đã ghi âm"]}),r("div",{className:"w-full min-h-0 overflow-y-auto",children:r("p",{className:"text-center break-words whitespace-pre-wrap m-0",style:{fontSize:_,fontFamily:'"SVN-Volte Rounded", "Quicksand", sans-serif',fontWeight:600,lineHeight:1.4,letterSpacing:"-0.01em",color:"#2C38B6"},children:`"${C}"`})}),A&&e("div",{className:"mt-6 flex items-center justify-center gap-2 shrink-0",children:[r("span",{className:"text-sm font-semibold text-[#283593] font-['Quicksand']",children:"🔊 Model pronunciation:"}),r(h,{audioUrl:A})]})]})}),N.recorder&&!w.isReviewMode&&e("div",{className:"shrink-0 flex flex-col items-center z-50 gap-3",children:[r("div",{className:"bg-white rounded-[100px] shadow-[0_4px_10px_rgba(0,0,0,0.1)] whitespace-nowrap flex items-center justify-center",style:{padding:"10px 30px",color:"recording"===N.recorder.status?"#FF4D4D":["recorded","uploading","uploaded"].includes(N.recorder.status)?"#16CA3B":"#343C55",fontSize:"18px",fontFamily:'"Quicksand", sans-serif',fontWeight:700,lineHeight:"100%",letterSpacing:"-0.01em"},children:"recording"===N.recorder.status?"Ấn lần nữa để lưu kết quả":["recorded","uploading","uploaded"].includes(N.recorder.status)?"Câu trả lời đã được ghi nhận !":"Ấn biểu tượng Micro để trả lời"}),r("div",{className:"relative flex flex-col items-center",children:"recording"===N.recorder.status?e("div",{className:"relative flex flex-col justify-center items-center cursor-pointer drop-shadow-[0_0_15px_rgba(255,100,100,0.8)] transition-transform hover:scale-[1.05] active:scale-[0.95]",onClick:N.recorder.stopRecording,children:[r(o,{src:c,alt:"stop audio",className:"animate-pulse",style:{width:"120px",height:"120px"}}),e("span",{className:"absolute text-white text-[16px] font-bold font-['Quicksand']",style:{bottom:"30px"},children:[Math.floor(N.recorder.remainingSeconds/60),":",(N.recorder.remainingSeconds%60).toString().padStart(2,"0")]})]}):r(o,{src:["recorded","uploading","uploaded"].includes(N.recorder.status)?b?u:m:d,alt:"micro",className:"transition-transform cursor-pointer hover:scale-[1.05] active:scale-[0.95]",style:{width:"120px",height:"120px"},onClick:()=>{if("recording"===N.recorder?.status)N.recorder.stopRecording();else if("idle"===N.recorder?.status||"error"===N.recorder?.status)N.recorder.startRecording();else if("uploaded"===N.recorder?.status||"recorded"===N.recorder?.status){const e=y.current;e&&(b?e.pause():e.play().catch(console.error))}}})}),N.recorder.previewUrl&&r("audio",{ref:y,src:N.recorder.previewUrl})]})]})]})}
@@ -0,0 +1,17 @@
1
+ import type { QuestionPart } from '../../../utils/question-transformers';
2
+ interface SpeakingSpontaneousQARendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, unknown>;
5
+ onAnswerChange: (questionId: string, value: unknown) => void;
6
+ isReviewMode?: boolean;
7
+ onExit: () => void;
8
+ onPartComplete?: () => void;
9
+ onPartBack?: () => void;
10
+ speakingTheme?: string;
11
+ teacherVideoUrl?: string;
12
+ waitForTeacherVideo?: boolean;
13
+ onTeacherIntroPlayed?: () => void;
14
+ skipTeacherVideo?: boolean;
15
+ }
16
+ export declare function SpeakingSpontaneousQARenderer(props: SpeakingSpontaneousQARendererProps): import("react").JSX.Element;
17
+ export {};