@tinyweb_dev/oe-exam-sdk 0.1.1 → 0.1.2

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 (485) hide show
  1. package/dist/api/exam-create.js +1 -179
  2. package/dist/api/exam-create.types.js +1 -1
  3. package/dist/api/exam-questions.js +1 -98
  4. package/dist/api/exam-questions.types.js +1 -1
  5. package/dist/api/exam-taking.js +1 -73
  6. package/dist/api/exam-taking.types.js +1 -1
  7. package/dist/api/index.js +1 -6
  8. package/dist/api/result-review.js +1 -50
  9. package/dist/api/result-review.types.js +1 -1
  10. package/dist/components/CueCardEditor.js +1 -58
  11. package/dist/components/common/ResolvedImage.js +1 -15
  12. package/dist/components/exams/CreateExamInfoForm.js +1 -35
  13. package/dist/components/exams/CreateExamPageContainer.js +1 -103
  14. package/dist/components/exams/ExamCreator.js +1 -89
  15. package/dist/components/exams/ExamPartTabs.js +1 -40
  16. package/dist/components/exams/ExamQuestionGrid.js +1 -18
  17. package/dist/components/exams/ExamQuestionsPageContainer.js +1 -90
  18. package/dist/components/exams/PartAudioUploader.js +1 -9
  19. package/dist/components/exams/TemplateSelector.js +1 -66
  20. package/dist/components/exams/api.js +1 -3
  21. package/dist/components/exams/create-exam.validation.js +1 -18
  22. package/dist/components/exams/exam-template.utils.js +1 -18
  23. package/dist/components/exams/index.js +1 -10
  24. package/dist/components/exams/take/ExamTakingPageContainer.js +1 -153
  25. package/dist/components/exams/take/GenericQuestionRenderer.js +1 -14
  26. package/dist/components/exams/take/exam-taking.utils.js +1 -88
  27. package/dist/components/exams/take/hooks/useSpeakingRecorder.js +1 -24
  28. package/dist/components/exams/take/index.js +1 -2
  29. package/dist/components/exams/take/types.js +1 -1
  30. package/dist/components/index.js +1 -42
  31. package/dist/components/questions/_shared/config/question-types.config.js +1 -333
  32. package/dist/components/questions/_shared/constants/color-palette.js +1 -21
  33. package/dist/components/questions/_shared/hooks/useAnswerGroupQuestionGroup.js +1 -105
  34. package/dist/components/questions/_shared/hooks/useBasicQuestionGroup.js +1 -222
  35. package/dist/components/questions/_shared/hooks/useCompareImagesGroup.js +1 -140
  36. package/dist/components/questions/_shared/hooks/useImageQuestionGroup.js +1 -123
  37. package/dist/components/questions/_shared/hooks/useInfoExchangeGroup.js +1 -50
  38. package/dist/components/questions/_shared/hooks/useQuestionFormState.js +1 -54
  39. package/dist/components/questions/_shared/hooks/useQuestionInitialization.js +1 -123
  40. package/dist/components/questions/_shared/hooks/useQuestionListGroup.js +1 -121
  41. package/dist/components/questions/_shared/hooks/useQuestionOnChange.js +1 -70
  42. package/dist/components/questions/_shared/hooks/useSceneQuestionGroup.js +1 -194
  43. package/dist/components/questions/_shared/index.js +1 -7
  44. package/dist/components/questions/_shared/types/answer-the-question.type.js +1 -1
  45. package/dist/components/questions/_shared/types/arrange-letters-into-words.type.js +1 -1
  46. package/dist/components/questions/_shared/types/choose-correct-adjective.type.js +1 -3
  47. package/dist/components/questions/_shared/types/color-region.config.js +1 -1
  48. package/dist/components/questions/_shared/types/fill-in-blank.type.js +1 -1
  49. package/dist/components/questions/_shared/types/fill-missing-words-in-grid.type.js +1 -1
  50. package/dist/components/questions/_shared/types/gn-speaking-interview.type.js +1 -1
  51. package/dist/components/questions/_shared/types/index.js +1 -12
  52. package/dist/components/questions/_shared/types/label-the-picture.type.js +1 -1
  53. package/dist/components/questions/_shared/types/listen-and-choose-from-answer-group.type.js +1 -1
  54. package/dist/components/questions/_shared/types/listen-and-choose-objects-in-scene.type.js +1 -1
  55. package/dist/components/questions/_shared/types/listen-and-drag-objects-into-scene.type.js +1 -1
  56. package/dist/components/questions/_shared/types/listen-and-speak-answer.type.js +1 -1
  57. package/dist/components/questions/_shared/types/listen-and-speak-compare-images.type.js +1 -1
  58. package/dist/components/questions/_shared/types/listen-and-speak-image-group.type.js +1 -1
  59. package/dist/components/questions/_shared/types/listen-and-speak-info-exchange.type.js +1 -1
  60. package/dist/components/questions/_shared/types/listen-and-speak-odd-one-out.type.js +1 -3
  61. package/dist/components/questions/_shared/types/listen-and-speak-question-list.type.js +1 -1
  62. package/dist/components/questions/_shared/types/listen-and-speak-with-story-images.type.js +1 -3
  63. package/dist/components/questions/_shared/types/listen-and-tick-answer.type.js +1 -1
  64. package/dist/components/questions/_shared/types/listening-drawline.type.js +1 -1
  65. package/dist/components/questions/_shared/types/look-and-choose-answer.type.js +1 -1
  66. package/dist/components/questions/_shared/types/look-picture-fill-word-hint.type.js +1 -1
  67. package/dist/components/questions/_shared/types/match-by-writing-answer.type.js +1 -1
  68. package/dist/components/questions/_shared/types/multiple-choice.type.js +1 -1
  69. package/dist/components/questions/_shared/types/question-group.type.js +1 -11
  70. package/dist/components/questions/_shared/types/read-and-color-objects.type.js +1 -1
  71. package/dist/components/questions/_shared/types/read-displayed-content.type.js +1 -1
  72. package/dist/components/questions/_shared/types/read-passage-and-answer-questions.type.js +1 -1
  73. package/dist/components/questions/_shared/types/speaking-describe-image.type.js +1 -1
  74. package/dist/components/questions/_shared/types/spontaneous-qa.type.js +1 -1
  75. package/dist/components/questions/_shared/types/word-fill-paragraph-with-options.type.js +1 -1
  76. package/dist/components/questions/_shared/types/word-fill-paragraph.type.js +1 -1
  77. package/dist/components/questions/_shared/types/word-fill-structured-form.type.js +1 -1
  78. package/dist/components/questions/_shared/types/word-ordering.type.js +1 -1
  79. package/dist/components/questions/_shared/types/write-a-short-letter.type.js +1 -1
  80. package/dist/components/questions/_shared/types/write-correct-verb-form.type.js +1 -3
  81. package/dist/components/questions/_shared/types/write-sentences.type.js +1 -1
  82. package/dist/components/questions/_shared/types/write-short-paragraph.type.js +1 -1
  83. package/dist/components/questions/_shared/utils/answer-builder.js +1 -79
  84. package/dist/components/questions/_shared/utils/createColorRegionRegistration.js +1 -39
  85. package/dist/components/questions/_shared/utils/id-generator.js +1 -3
  86. package/dist/components/questions/_shared/utils/question-validation.js +1 -21
  87. package/dist/components/questions/components/ColorNode.js +1 -85
  88. package/dist/components/questions/components/ColorRegionClient.js +1 -545
  89. package/dist/components/questions/components/ColorRegionCreator.js +1 -420
  90. package/dist/components/questions/components/ColorRegionNode.js +1 -59
  91. package/dist/components/questions/components/CreatorGuide.js +1 -103
  92. package/dist/components/questions/components/NameNode.js +1 -26
  93. package/dist/components/questions/components/QuestionBankOption.js +1 -46
  94. package/dist/components/questions/components/QuestionBasicInfoForm.js +1 -9
  95. package/dist/components/questions/components/QuestionCommonFields.js +1 -33
  96. package/dist/components/questions/components/QuestionSearchDropdown.js +1 -258
  97. package/dist/components/questions/components/QuestionTypeSelector.js +1 -32
  98. package/dist/components/questions/components/QuestionTypeSpecificForms.js +1 -6
  99. package/dist/components/questions/components/RegionNode.js +1 -94
  100. package/dist/components/questions/components/index.js +1 -14
  101. package/dist/components/questions/creator/QuestionCreator.js +1 -90
  102. package/dist/components/questions/creator/QuestionGroupCreator.js +1 -119
  103. package/dist/components/questions/creator/dedicated-component-router.js +1 -79
  104. package/dist/components/questions/creator/index.js +1 -3
  105. package/dist/components/questions/creator/question-type-registry.js +1 -80
  106. package/dist/components/questions/groups/ArticlesGroupCard.js +1 -121
  107. package/dist/components/questions/groups/BasicQuestionGroupCard.js +1 -50
  108. package/dist/components/questions/groups/DocumentGroupCard.js +1 -114
  109. package/dist/components/questions/groups/MatchAnswerGroupCard.js +1 -25
  110. package/dist/components/questions/index.js +1 -10
  111. package/dist/components/questions/types/answer-the-question/AnswerTheQuestionClient.js +1 -37
  112. package/dist/components/questions/types/answer-the-question/AnswerTheQuestionCreator.js +1 -351
  113. package/dist/components/questions/types/answer-the-question/register.js +1 -67
  114. package/dist/components/questions/types/answer-the-question/transform.js +1 -36
  115. package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsClient.js +1 -141
  116. package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsCreator.js +1 -118
  117. package/dist/components/questions/types/arrange-letters-into-words/index.js +1 -2
  118. package/dist/components/questions/types/arrange-letters-into-words/register.js +1 -4
  119. package/dist/components/questions/types/arrange-letters-into-words/transform.js +1 -24
  120. package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveClient.js +1 -64
  121. package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveCreator.js +1 -169
  122. package/dist/components/questions/types/choose-correct-adjective/index.js +1 -2
  123. package/dist/components/questions/types/choose-correct-adjective/register.js +1 -55
  124. package/dist/components/questions/types/choose-correct-adjective/transform.js +1 -16
  125. package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerClient.js +1 -131
  126. package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerCreator.js +1 -581
  127. package/dist/components/questions/types/choose-the-correct-answer/index.js +1 -2
  128. package/dist/components/questions/types/choose-the-correct-answer/register.js +1 -101
  129. package/dist/components/questions/types/choose-the-correct-answer/transform.js +1 -43
  130. package/dist/components/questions/types/fill-in-blank/FillInBlankClient.js +1 -275
  131. package/dist/components/questions/types/fill-in-blank/FillInBlankCreator.js +1 -448
  132. package/dist/components/questions/types/fill-in-blank/index.js +1 -2
  133. package/dist/components/questions/types/fill-in-blank/register.js +1 -138
  134. package/dist/components/questions/types/fill-in-blank/transform.js +1 -59
  135. package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridClient.js +1 -117
  136. package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridCreator.js +1 -671
  137. package/dist/components/questions/types/fill-missing-words-in-grid/index.js +1 -2
  138. package/dist/components/questions/types/fill-missing-words-in-grid/register.js +1 -37
  139. package/dist/components/questions/types/fill-missing-words-in-grid/transform.js +1 -15
  140. package/dist/components/questions/types/gn-speaking-interview/GNSpeakingInterviewCreator.js +1 -262
  141. package/dist/components/questions/types/gn-speaking-interview/register.js +1 -121
  142. package/dist/components/questions/types/gn-speaking-interview/transform.js +1 -48
  143. package/dist/components/questions/types/image-object-matching/ImageObjectMatchingClient.js +1 -16
  144. package/dist/components/questions/types/image-object-matching/ImageObjectMatchingCreator.js +1 -27
  145. package/dist/components/questions/types/image-object-matching/index.js +1 -2
  146. package/dist/components/questions/types/image-object-matching/register.js +1 -3
  147. package/dist/components/questions/types/image-object-matching/transform.js +1 -2
  148. package/dist/components/questions/types/label-the-picture/LabelThePictureClient.js +1 -102
  149. package/dist/components/questions/types/label-the-picture/LabelThePictureCreator.js +1 -344
  150. package/dist/components/questions/types/label-the-picture/index.js +1 -2
  151. package/dist/components/questions/types/label-the-picture/register.js +1 -54
  152. package/dist/components/questions/types/label-the-picture/transform.js +1 -28
  153. package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupClient.js +1 -78
  154. package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupCreator.js +1 -232
  155. package/dist/components/questions/types/listen-and-choose-from-answer-group/index.js +1 -2
  156. package/dist/components/questions/types/listen-and-choose-from-answer-group/register.js +1 -82
  157. package/dist/components/questions/types/listen-and-choose-from-answer-group/transform.js +1 -27
  158. package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneClient.js +1 -70
  159. package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneCreator.js +1 -386
  160. package/dist/components/questions/types/listen-and-choose-objects-in-scene/index.js +1 -2
  161. package/dist/components/questions/types/listen-and-choose-objects-in-scene/register.js +1 -100
  162. package/dist/components/questions/types/listen-and-choose-objects-in-scene/transform.js +1 -33
  163. package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneClient.js +1 -106
  164. package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneCreator.js +1 -457
  165. package/dist/components/questions/types/listen-and-drag-objects-into-scene/index.js +1 -2
  166. package/dist/components/questions/types/listen-and-drag-objects-into-scene/register.js +1 -110
  167. package/dist/components/questions/types/listen-and-drag-objects-into-scene/transform.js +1 -35
  168. package/dist/components/questions/types/listen-and-speak-answer/ArrowIndicator.js +1 -8
  169. package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerClient.js +1 -22
  170. package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerCreator.js +1 -291
  171. package/dist/components/questions/types/listen-and-speak-answer/index.js +1 -2
  172. package/dist/components/questions/types/listen-and-speak-answer/register.js +1 -84
  173. package/dist/components/questions/types/listen-and-speak-answer/transform.js +1 -27
  174. package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesClient.js +1 -32
  175. package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesCreator.js +1 -295
  176. package/dist/components/questions/types/listen-and-speak-compare-images/register.js +1 -79
  177. package/dist/components/questions/types/listen-and-speak-compare-images/transform.js +1 -27
  178. package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupClient.js +1 -34
  179. package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupCreator.js +1 -285
  180. package/dist/components/questions/types/listen-and-speak-image-group/register.js +1 -81
  181. package/dist/components/questions/types/listen-and-speak-image-group/transform.js +1 -26
  182. package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeClient.js +1 -38
  183. package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeCreator.js +1 -385
  184. package/dist/components/questions/types/listen-and-speak-info-exchange/register.js +1 -87
  185. package/dist/components/questions/types/listen-and-speak-info-exchange/transform.js +1 -32
  186. package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutClient.js +1 -26
  187. package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutCreator.js +1 -247
  188. package/dist/components/questions/types/listen-and-speak-odd-one-out/register.js +1 -59
  189. package/dist/components/questions/types/listen-and-speak-odd-one-out/transform.js +1 -18
  190. package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListClient.js +1 -26
  191. package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListCreator.js +1 -256
  192. package/dist/components/questions/types/listen-and-speak-question-list/register.js +1 -81
  193. package/dist/components/questions/types/listen-and-speak-question-list/transform.js +1 -26
  194. package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesClient.js +1 -26
  195. package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesCreator.js +1 -230
  196. package/dist/components/questions/types/listen-and-speak-with-story-images/register.js +1 -56
  197. package/dist/components/questions/types/listen-and-speak-with-story-images/transform.js +1 -16
  198. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerClient.js +1 -72
  199. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerCreator.js +1 -230
  200. package/dist/components/questions/types/look-picture-choose-correct-answer/index.js +1 -1
  201. package/dist/components/questions/types/look-picture-choose-correct-answer/register.js +1 -66
  202. package/dist/components/questions/types/look-picture-choose-correct-answer/transform.js +1 -42
  203. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerClient.js +1 -96
  204. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerCreator.js +1 -238
  205. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/index.js +1 -2
  206. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/register.js +1 -76
  207. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/transform.js +1 -19
  208. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintClient.js +1 -134
  209. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintCreator.js +1 -617
  210. package/dist/components/questions/types/look-picture-fill-word-hint/index.js +1 -2
  211. package/dist/components/questions/types/look-picture-fill-word-hint/register.js +1 -82
  212. package/dist/components/questions/types/look-picture-fill-word-hint/transform.js +1 -29
  213. package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerClient.js +1 -38
  214. package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerCreator.js +1 -359
  215. package/dist/components/questions/types/match-by-writing-answer/index.js +1 -3
  216. package/dist/components/questions/types/match-by-writing-answer/register.js +1 -58
  217. package/dist/components/questions/types/match-by-writing-answer/transform.js +1 -61
  218. package/dist/components/questions/types/read-and-color-objects/ReadAndColorObjectsClient.js +1 -16
  219. package/dist/components/questions/types/read-and-color-objects/ReadAndColorObjectsCreator.js +1 -23
  220. package/dist/components/questions/types/read-and-color-objects/index.js +1 -2
  221. package/dist/components/questions/types/read-and-color-objects/register.js +1 -3
  222. package/dist/components/questions/types/read-and-color-objects/transform.js +1 -36
  223. package/dist/components/questions/types/read-displayed-content/ReadDisplayedContentCreator.js +1 -125
  224. package/dist/components/questions/types/read-displayed-content/register.js +1 -64
  225. package/dist/components/questions/types/read-displayed-content/transform.js +1 -12
  226. package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsClient.js +1 -64
  227. package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsCreator.js +1 -511
  228. package/dist/components/questions/types/read-passage-and-answer-questions/index.js +1 -2
  229. package/dist/components/questions/types/read-passage-and-answer-questions/register.js +1 -58
  230. package/dist/components/questions/types/read-passage-and-answer-questions/transform.js +1 -28
  231. package/dist/components/questions/types/speaking-conversation/SpeakingConversationCreator.js +1 -373
  232. package/dist/components/questions/types/speaking-conversation/SpeakingConversationPreviewClient.js +1 -41
  233. package/dist/components/questions/types/speaking-conversation/register.js +1 -110
  234. package/dist/components/questions/types/speaking-conversation/transform.js +1 -34
  235. package/dist/components/questions/types/speaking-cue-card/SpeakingCueCardCreator.js +1 -74
  236. package/dist/components/questions/types/speaking-cue-card/register.js +1 -52
  237. package/dist/components/questions/types/speaking-cue-card/transform.js +1 -12
  238. package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageClient.js +1 -10
  239. package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageCreator.js +1 -161
  240. package/dist/components/questions/types/speaking-describe-image/index.js +1 -2
  241. package/dist/components/questions/types/speaking-describe-image/register.js +1 -69
  242. package/dist/components/questions/types/speaking-describe-image/transform.js +1 -16
  243. package/dist/components/questions/types/spontaneous-qa/SpontaneousQACreator.js +1 -234
  244. package/dist/components/questions/types/spontaneous-qa/register.js +1 -93
  245. package/dist/components/questions/types/spontaneous-qa/transform.js +1 -34
  246. package/dist/components/questions/types/true-false/TrueFalseClient.js +1 -75
  247. package/dist/components/questions/types/true-false/TrueFalseCreator.js +1 -244
  248. package/dist/components/questions/types/true-false/index.js +1 -2
  249. package/dist/components/questions/types/true-false/register.js +1 -77
  250. package/dist/components/questions/types/true-false/transform.js +1 -32
  251. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphClient.js +1 -233
  252. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphCreator.js +1 -631
  253. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphWrapper.js +1 -28
  254. package/dist/components/questions/types/word-fill-paragraph/index.js +1 -2
  255. package/dist/components/questions/types/word-fill-paragraph/register.js +1 -136
  256. package/dist/components/questions/types/word-fill-paragraph/transform.js +1 -56
  257. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormClient.js +1 -138
  258. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormCreator.js +1 -261
  259. package/dist/components/questions/types/word-fill-structured-form/index.js +1 -2
  260. package/dist/components/questions/types/word-fill-structured-form/register.js +1 -67
  261. package/dist/components/questions/types/word-fill-structured-form/transform.js +1 -40
  262. package/dist/components/questions/types/word-ordering/WordOrderingClient.js +1 -84
  263. package/dist/components/questions/types/word-ordering/WordOrderingCreator.js +1 -192
  264. package/dist/components/questions/types/word-ordering/index.js +1 -2
  265. package/dist/components/questions/types/word-ordering/register.js +1 -46
  266. package/dist/components/questions/types/word-ordering/transform.js +1 -24
  267. package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterClient.js +1 -98
  268. package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterCreator.js +1 -320
  269. package/dist/components/questions/types/write-a-short-letter/index.js +1 -2
  270. package/dist/components/questions/types/write-a-short-letter/register.js +1 -68
  271. package/dist/components/questions/types/write-a-short-letter/transform.js +1 -25
  272. package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormClient.js +1 -61
  273. package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormCreator.js +1 -196
  274. package/dist/components/questions/types/write-correct-verb-form/index.js +1 -2
  275. package/dist/components/questions/types/write-correct-verb-form/register.js +1 -62
  276. package/dist/components/questions/types/write-correct-verb-form/transform.js +1 -17
  277. package/dist/components/questions/types/write-sentences/WriteSentencesClient.js +1 -22
  278. package/dist/components/questions/types/write-sentences/WriteSentencesCreator.js +1 -174
  279. package/dist/components/questions/types/write-sentences/index.js +1 -2
  280. package/dist/components/questions/types/write-sentences/register.js +1 -58
  281. package/dist/components/questions/types/write-sentences/transform.js +1 -28
  282. package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphClient.js +1 -96
  283. package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphCreator.js +1 -161
  284. package/dist/components/questions/types/write-short-paragraph/index.js +1 -2
  285. package/dist/components/questions/types/write-short-paragraph/register.js +1 -4
  286. package/dist/components/questions/types/write-short-paragraph/transform.js +1 -21
  287. package/dist/components/questions/viewer/QuestionGroupViewer.js +1 -36
  288. package/dist/components/questions/viewer/QuestionViewer.js +1 -446
  289. package/dist/components/questions/viewer/index.js +1 -2
  290. package/dist/components/results/ResultReviewPageContainer.js +1 -98
  291. package/dist/components/results/ReviewQuestionRenderer.js +1 -72
  292. package/dist/components/results/index.js +1 -2
  293. package/dist/components/results/result-review.utils.js +1 -6
  294. package/dist/components/results/review-data.js +1 -150
  295. package/dist/components/results/review-renderer.utils.js +1 -97
  296. package/dist/components/results/review-types.js +1 -1
  297. package/dist/components/themes/cambridge-yle/CambridgeYleAudioPlayer.js +1 -138
  298. package/dist/components/themes/cambridge-yle/CambridgeYleBottomNav.js +1 -12
  299. package/dist/components/themes/cambridge-yle/CambridgeYleExamLayout.js +1 -18
  300. package/dist/components/themes/cambridge-yle/CambridgeYleExampleText.js +1 -11
  301. package/dist/components/themes/cambridge-yle/CambridgeYleHeader.js +1 -11
  302. package/dist/components/themes/cambridge-yle/CambridgeYleInstructionBanner.js +1 -9
  303. package/dist/components/themes/cambridge-yle/CambridgeYleNavButton.js +1 -13
  304. package/dist/components/themes/cambridge-yle/CambridgeYlePartBanner.js +1 -8
  305. package/dist/components/themes/cambridge-yle/CambridgeYleProgressBar.js +1 -6
  306. package/dist/components/themes/cambridge-yle/CambridgeYleQuestionCard.js +1 -5
  307. package/dist/components/themes/cambridge-yle/CambridgeYleQuestionCardFullWidth.js +1 -9
  308. package/dist/components/themes/cambridge-yle/CambridgeYleSidebar.js +1 -41
  309. package/dist/components/themes/cambridge-yle/CambridgeYleTimer.js +1 -25
  310. package/dist/components/themes/cambridge-yle/index.js +1 -13
  311. package/dist/components/themes/english-certification/EcAnswerTheQuestion.js +1 -24
  312. package/dist/components/themes/english-certification/EcMatchByWritingAnswer.js +1 -88
  313. package/dist/components/themes/english-certification/EcWordFillParagraph.js +1 -55
  314. package/dist/components/themes/english-certification/EcWordFillStructuredForm.js +1 -156
  315. package/dist/components/themes/english-certification/EcWritingTask.js +1 -34
  316. package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.js +1 -114
  317. package/dist/components/themes/english-certification/EnglishCertificationBrand.js +1 -11
  318. package/dist/components/themes/english-certification/EnglishCertificationExamLayout.js +1 -21
  319. package/dist/components/themes/english-certification/EnglishCertificationFlagButton.js +1 -15
  320. package/dist/components/themes/english-certification/EnglishCertificationFooterBar.js +1 -19
  321. package/dist/components/themes/english-certification/EnglishCertificationGroupedQuestion.js +1 -148
  322. package/dist/components/themes/english-certification/EnglishCertificationHeader.js +1 -31
  323. package/dist/components/themes/english-certification/EnglishCertificationNavigationPanel.js +1 -71
  324. package/dist/components/themes/english-certification/EnglishCertificationOptionSelector.js +1 -33
  325. package/dist/components/themes/english-certification/EnglishCertificationPassagePanel.js +1 -16
  326. package/dist/components/themes/english-certification/EnglishCertificationQuestionCard.js +1 -22
  327. package/dist/components/themes/english-certification/EnglishCertificationQuestionItem.js +1 -37
  328. package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.js +1 -72
  329. package/dist/components/themes/english-certification/EnglishCertificationReadingSection.js +1 -90
  330. package/dist/components/themes/english-certification/EnglishCertificationSingleQuestion.js +1 -18
  331. package/dist/components/themes/english-certification/EnglishCertificationSingleQuestionList.js +1 -29
  332. package/dist/components/themes/english-certification/english-certification-theme.js +1 -58
  333. package/dist/components/themes/english-certification/grouped-question-utils.js +1 -218
  334. package/dist/components/themes/english-certification/index.js +1 -21
  335. package/dist/components/themes/index.js +1 -6
  336. package/dist/components/themes/summer-sky/SummerSkyAudioPlayer.js +1 -170
  337. package/dist/components/themes/summer-sky/SummerSkyLayout.js +1 -221
  338. package/dist/components/themes/summer-sky/SummerSkySubmitModal.js +1 -18
  339. package/dist/components/themes/summer-sky/SummerSkyWaitingRoom.js +1 -194
  340. package/dist/components/themes/types.js +1 -1
  341. package/dist/components/ui/alert-dialog.js +1 -26
  342. package/dist/components/ui/alert.js +1 -22
  343. package/dist/components/ui/avatar.js +1 -12
  344. package/dist/components/ui/badge.js +1 -38
  345. package/dist/components/ui/button.js +1 -35
  346. package/dist/components/ui/calendar.js +1 -76
  347. package/dist/components/ui/card.js +1 -16
  348. package/dist/components/ui/carousel.js +1 -91
  349. package/dist/components/ui/checkbox.js +1 -9
  350. package/dist/components/ui/collapsible.js +1 -13
  351. package/dist/components/ui/command.js +1 -34
  352. package/dist/components/ui/confirm-dialog.js +1 -49
  353. package/dist/components/ui/dialog.js +1 -23
  354. package/dist/components/ui/drawer.js +1 -35
  355. package/dist/components/ui/dropdown-menu.js +1 -33
  356. package/dist/components/ui/file-upload.js +1 -155
  357. package/dist/components/ui/form.js +1 -62
  358. package/dist/components/ui/hover-card.js +1 -10
  359. package/dist/components/ui/image-preview.js +1 -29
  360. package/dist/components/ui/input.js +1 -8
  361. package/dist/components/ui/label.js +1 -9
  362. package/dist/components/ui/language-switcher.js +1 -15
  363. package/dist/components/ui/multi-select.js +1 -90
  364. package/dist/components/ui/points-input.js +1 -33
  365. package/dist/components/ui/popover.js +1 -26
  366. package/dist/components/ui/progress.js +1 -16
  367. package/dist/components/ui/radio-group.js +1 -12
  368. package/dist/components/ui/scroll-area.js +1 -11
  369. package/dist/components/ui/select.js +1 -38
  370. package/dist/components/ui/separator.js +1 -8
  371. package/dist/components/ui/sheet.js +1 -40
  372. package/dist/components/ui/single-select.js +1 -76
  373. package/dist/components/ui/skeleton.js +1 -6
  374. package/dist/components/ui/switch.js +1 -8
  375. package/dist/components/ui/table.js +1 -20
  376. package/dist/components/ui/tabs.js +1 -17
  377. package/dist/components/ui/textarea.js +1 -8
  378. package/dist/components/ui/tooltip.js +1 -11
  379. package/dist/index.js +1 -19
  380. package/dist/mcp/config.js +1 -32
  381. package/dist/mcp/http-client.js +1 -48
  382. package/dist/mcp/index.js +1 -29
  383. package/dist/mcp/tools/_helpers.js +1 -25
  384. package/dist/mcp/tools/exams.js +1 -439
  385. package/dist/mcp/tools/index.js +1 -6
  386. package/dist/mcp/tools/results.js +1 -19
  387. package/dist/shared/constants/ApiConstant.js +1 -276
  388. package/dist/shared/constants/QueryKeyConstant.js +1 -112
  389. package/dist/shared/constants/exam-level.enum.js +1 -41
  390. package/dist/shared/constants/landings/placement-test.constants.js +1 -431
  391. package/dist/shared/constants/question-skills.js +1 -267
  392. package/dist/shared/constants/routes.js +1 -81
  393. package/dist/shared/index.js +1 -7
  394. package/dist/shared/lib/hooks/index.js +1 -10
  395. package/dist/shared/lib/hooks/useAlertDialog.js +1 -57
  396. package/dist/shared/lib/hooks/useAudioPlayCounter.js +1 -30
  397. package/dist/shared/lib/hooks/useAudioPreview.js +1 -81
  398. package/dist/shared/lib/hooks/useAudioUpload.js +1 -24
  399. package/dist/shared/lib/hooks/useConfirmDialog.js +1 -89
  400. package/dist/shared/lib/hooks/useDebouncedCallback.js +1 -32
  401. package/dist/shared/lib/hooks/useDelayedAutoPlay.js +1 -12
  402. package/dist/shared/lib/hooks/useFileUpload.js +1 -24
  403. package/dist/shared/lib/hooks/useImageUrl.js +1 -5
  404. package/dist/shared/lib/hooks/usePresignedFileUrl.js +1 -10
  405. package/dist/shared/lib/hooks/useReactHookForm.js +1 -31
  406. package/dist/shared/lib/hooks/useToast.js +1 -62
  407. package/dist/shared/lib/i18n/index.js +1 -54
  408. package/dist/shared/lib/i18n/messages/en/admin.js +1 -2104
  409. package/dist/shared/lib/i18n/messages/en/auth.js +1 -86
  410. package/dist/shared/lib/i18n/messages/en/common.js +1 -140
  411. package/dist/shared/lib/i18n/messages/en/file-upload.js +1 -18
  412. package/dist/shared/lib/i18n/messages/en/student.js +1 -133
  413. package/dist/shared/lib/i18n/messages/en/terms.js +1 -37
  414. package/dist/shared/lib/i18n/messages/en.js +1 -15
  415. package/dist/shared/lib/i18n/messages/vi/admin.js +1 -2104
  416. package/dist/shared/lib/i18n/messages/vi/auth.js +1 -86
  417. package/dist/shared/lib/i18n/messages/vi/common.js +1 -140
  418. package/dist/shared/lib/i18n/messages/vi/file-upload.js +1 -18
  419. package/dist/shared/lib/i18n/messages/vi/student.js +1 -133
  420. package/dist/shared/lib/i18n/messages/vi/terms.js +1 -37
  421. package/dist/shared/lib/i18n/messages/vi.js +1 -15
  422. package/dist/shared/lib/i18n/types.js +1 -1
  423. package/dist/shared/lib/stores/examQuestionStore.js +1 -212
  424. package/dist/shared/lib/stores/localeStore.js +1 -10
  425. package/dist/shared/lib/utils/public-page.js +1 -44
  426. package/dist/shared/lib/utils/question-transform-types.js +1 -1
  427. package/dist/shared/lib/utils/question-transform.js +1 -174
  428. package/dist/shared/lib/utils.js +1 -168
  429. package/dist/shared/lib/validation/choose-correct-answer.validation.js +1 -111
  430. package/dist/shared/lib/validation/label-the-picture.validation.js +1 -19
  431. package/dist/shared/lib/validation/listen-and-choose-from-answer-group.validation.js +1 -46
  432. package/dist/shared/lib/validation/listen-and-choose-objects-in-scene.validation.js +1 -21
  433. package/dist/shared/lib/validation/listen-and-drag-objects-into-scene.validation.js +1 -34
  434. package/dist/shared/lib/validation/listen-and-speak-answer.validation.js +1 -40
  435. package/dist/shared/lib/validation/listen-and-speak-compare-images.validation.js +1 -45
  436. package/dist/shared/lib/validation/listen-and-speak-image-group.validation.js +1 -19
  437. package/dist/shared/lib/validation/listen-and-speak-info-exchange.validation.js +1 -39
  438. package/dist/shared/lib/validation/listen-and-speak-odd-one-out.validation.js +1 -32
  439. package/dist/shared/lib/validation/listen-and-speak-question-list.validation.js +1 -19
  440. package/dist/shared/lib/validation/listen-and-speak-with-story-images.validation.js +1 -28
  441. package/dist/shared/lib/validation/look-picture-choose-correct-answer.validation.js +1 -12
  442. package/dist/shared/lib/validation/look-picture-fill-blank-choose-answer.validation.js +1 -47
  443. package/dist/shared/lib/validation/read-and-color-objects.validation.js +1 -29
  444. package/dist/shared/lib/validation/read-displayed-content.validation.js +1 -28
  445. package/dist/shared/lib/validation/speaking-conversation.validation.js +1 -75
  446. package/dist/shared/lib/validation/speaking-describe-image.validation.js +1 -31
  447. package/dist/shared/lib/validation/spontaneous-qa.validation.js +1 -48
  448. package/dist/shared/lib/validation/word-fill-paragraph-default.validation.js +1 -38
  449. package/dist/shared/lib/validation/word-fill-paragraph-with-options.validation.js +1 -39
  450. package/dist/shared/lib/validation/word-fill-paragraph.validation.js +1 -43
  451. package/dist/shared/lib/validation/word-ordering.validation.js +1 -33
  452. package/dist/shared/types/branch.types.js +1 -6
  453. package/dist/shared/types/common.types.js +1 -50
  454. package/dist/shared/types/entities/exam-schedule.types.js +1 -5
  455. package/dist/shared/types/entities/exam.types.js +1 -1
  456. package/dist/shared/types/entities/question.types.js +1 -4
  457. package/dist/shared/types/entities/result.types.js +1 -4
  458. package/dist/shared/types/entities/user.types.js +1 -4
  459. package/dist/shared/types/exam-taking.types.js +1 -2
  460. package/dist/shared/types/history.types.js +1 -34
  461. package/dist/shared/types/index.js +1 -1
  462. package/dist/shared/types/questions/choose-correct-adjective.js +1 -4
  463. package/dist/shared/types/questions/choose-the-correct-answer.js +1 -9
  464. package/dist/shared/types/questions/fill-missing-words-in-grid.js +1 -11
  465. package/dist/shared/types/questions/index.js +1 -40
  466. package/dist/shared/types/questions/listen-and-speak-answer.js +1 -1
  467. package/dist/shared/types/questions/listen-and-speak-compare-images.js +1 -1
  468. package/dist/shared/types/questions/listen-and-speak-image-group.js +1 -1
  469. package/dist/shared/types/questions/listen-and-speak-info-exchange.js +1 -3
  470. package/dist/shared/types/questions/listen-and-speak-odd-one-out.js +1 -3
  471. package/dist/shared/types/questions/listen-and-speak-question-list.js +1 -1
  472. package/dist/shared/types/questions/listen-and-speak-with-story-images.js +1 -3
  473. package/dist/shared/types/questions/look-picture-choose-correct-answer.js +1 -5
  474. package/dist/shared/types/questions/look-picture-fill-blank-choose-answer.js +1 -9
  475. package/dist/shared/types/questions/look-picture-fill-word-hint.js +1 -7
  476. package/dist/shared/types/questions/read-displayed-content.js +1 -1
  477. package/dist/shared/types/questions/speaking-conversation.js +1 -7
  478. package/dist/shared/types/questions/speaking-describe-image.js +1 -1
  479. package/dist/shared/types/questions/spontaneous-qa.js +1 -1
  480. package/dist/shared/types/questions/write-correct-verb-form.js +1 -12
  481. package/dist/shared/types/role.types.js +1 -1
  482. package/dist/shared/types/structure-management.js +1 -28
  483. package/dist/shared/types/student.types.js +1 -54
  484. package/dist/shared/types/teacher-dashboard-rooms.js +1 -2
  485. package/package.json +4 -2
@@ -1,58 +1 @@
1
- import { MatchByWritingAnswerCreator } from './MatchByWritingAnswerCreator';
2
- export const matchByWritingAnswerRegistration = {
3
- component: MatchByWritingAnswerCreator,
4
- transformInitialData: (initialData) => {
5
- const content = initialData?.content;
6
- const answer = initialData?.answer;
7
- const questionGroup = initialData?.questionGroup;
8
- const groupPayload = questionGroup?.payload || {};
9
- const groupNumber = questionGroup?.groupNumber || 1;
10
- // Extract shared options from group payload
11
- const options = groupPayload?.options || answer?.options || [];
12
- const groupImageUrl = groupPayload?.groupImageUrl || answer?.groupImageUrl || '';
13
- const groupTitle = groupPayload?.groupTitle || answer?.groupTitle || '';
14
- return {
15
- question: content?.question || answer?.question || '',
16
- imageUrl: content?.imageUrl || answer?.imageUrl || '',
17
- correctAnswer: answer?.answer || answer?.correctAnswer || '',
18
- points: initialData?.points || 1,
19
- groupNumber: answer?.groupNumber || groupNumber,
20
- isExample: initialData?.isExample || answer?.isExample || false,
21
- askerName: content?.askerName || answer?.askerName || '',
22
- answererName: content?.answererName || answer?.answererName || '',
23
- options,
24
- groupImageUrl,
25
- groupTitle,
26
- explanation: initialData?.explanation || answer?.explanation || '',
27
- };
28
- },
29
- getExtraProps: (ctx) => ({
30
- groups: ctx.groups,
31
- groupConfig: ctx.groupConfig,
32
- questionConfig: ctx.questionConfig,
33
- viewMode: ctx.viewMode,
34
- questionIndexInPart: ctx.questionIndexInPart,
35
- partId: ctx.partId,
36
- validationRef: ctx.validationRef,
37
- }),
38
- wrapOnSave: (data, ctx) => ({
39
- type: ctx.questionType,
40
- content: ctx.state.content,
41
- points: data?.points ?? ctx.state.points ?? 1,
42
- level: ctx.state.level,
43
- difficulty: ctx.state.difficulty,
44
- skill: ctx.state.skill,
45
- answer: data,
46
- explanation: data?.explanation || '',
47
- }),
48
- wrapOnChange: (data, ctx) => ({
49
- type: ctx.questionType,
50
- content: ctx.state.content,
51
- points: data?.points ?? ctx.state.points ?? 1,
52
- level: ctx.state.level,
53
- difficulty: ctx.state.difficulty,
54
- skill: ctx.state.skill,
55
- answer: data,
56
- explanation: data?.explanation || '',
57
- }),
58
- };
1
+ import{MatchByWritingAnswerCreator as e}from"./MatchByWritingAnswerCreator";export const matchByWritingAnswerRegistration={component:e,transformInitialData:e=>{const t=e?.content,n=e?.answer,a=e?.questionGroup,o=a?.payload||{},i=a?.groupNumber||1,r=o?.options||n?.options||[],s=o?.groupImageUrl||n?.groupImageUrl||"",p=o?.groupTitle||n?.groupTitle||"";return{question:t?.question||n?.question||"",imageUrl:t?.imageUrl||n?.imageUrl||"",correctAnswer:n?.answer||n?.correctAnswer||"",points:e?.points||1,groupNumber:n?.groupNumber||i,isExample:e?.isExample||n?.isExample||!1,askerName:t?.askerName||n?.askerName||"",answererName:t?.answererName||n?.answererName||"",options:r,groupImageUrl:s,groupTitle:p,explanation:e?.explanation||n?.explanation||""}},getExtraProps:e=>({groups:e.groups,groupConfig:e.groupConfig,questionConfig:e.questionConfig,viewMode:e.viewMode,questionIndexInPart:e.questionIndexInPart,partId:e.partId,validationRef:e.validationRef}),wrapOnSave:(e,t)=>({type:t.questionType,content:t.state.content,points:e?.points??t.state.points??1,level:t.state.level,difficulty:t.state.difficulty,skill:t.state.skill,answer:e,explanation:e?.explanation||""}),wrapOnChange:(e,t)=>({type:t.questionType,content:t.state.content,points:e?.points??t.state.points??1,level:t.state.level,difficulty:t.state.difficulty,skill:t.state.skill,answer:e,explanation:e?.explanation||""})};
@@ -1,61 +1 @@
1
- function normalizeMatchByWritingAnswerOptions(options) {
2
- if (!Array.isArray(options)) {
3
- return [];
4
- }
5
- return options.map((option) => ({
6
- answer: typeof option?.answer === 'string' ? option.answer : '',
7
- content: typeof option?.content === 'string' ? option.content : '',
8
- imageUrl: typeof option?.imageUrl === 'string' ? option.imageUrl : '',
9
- }));
10
- }
11
- /**
12
- * Transform MATCH_BY_WRITING_ANSWER creator data → API format
13
- *
14
- * API format:
15
- * content: { question, imageUrl }
16
- * correctAnswer: { answer }
17
- * questionGroup.payload: { options: [{ answer, imageUrl }] }
18
- */
19
- export function transformMatchByWritingAnswer(question) {
20
- const answerData = question.answer;
21
- if (!answerData) {
22
- return { apiContent: {}, apiCorrectAnswer: {} };
23
- }
24
- const apiContent = {
25
- question: answerData.question || '',
26
- };
27
- // Add question image if present
28
- if (answerData.imageUrl) {
29
- apiContent.imageUrl = answerData.imageUrl;
30
- }
31
- // Add conversation names if present (viewMode = conversation)
32
- if (answerData.askerName) {
33
- apiContent.askerName = answerData.askerName;
34
- }
35
- if (answerData.answererName) {
36
- apiContent.answererName = answerData.answererName;
37
- }
38
- const apiCorrectAnswer = {
39
- answer: answerData.correctAnswer || '',
40
- };
41
- const normalizedOptions = normalizeMatchByWritingAnswerOptions(answerData.options);
42
- // Build imageData to store shared options and group metadata in questionGroup.payload
43
- const imageData = {};
44
- if (normalizedOptions.length > 0) {
45
- imageData.options = normalizedOptions;
46
- }
47
- if (answerData.groupImageUrl) {
48
- imageData.groupImageUrl = answerData.groupImageUrl;
49
- }
50
- if (answerData.groupTitle) {
51
- imageData.groupTitle = answerData.groupTitle;
52
- }
53
- return {
54
- apiContent,
55
- apiCorrectAnswer,
56
- totalPoints: answerData.points || 1,
57
- imageData: imageData,
58
- groupNumber: answerData.groupNumber || 1,
59
- isExample: answerData.isExample || false,
60
- };
61
- }
1
+ export function transformMatchByWritingAnswer(r){const e=r.answer;if(!e)return{apiContent:{},apiCorrectAnswer:{}};const t={question:e.question||""};e.imageUrl&&(t.imageUrl=e.imageUrl),e.askerName&&(t.askerName=e.askerName),e.answererName&&(t.answererName=e.answererName);const a={answer:e.correctAnswer||""},n=(o=e.options,Array.isArray(o)?o.map(r=>({answer:"string"==typeof r?.answer?r.answer:"",content:"string"==typeof r?.content?r.content:"",imageUrl:"string"==typeof r?.imageUrl?r.imageUrl:""})):[]);var o;const s={};return n.length>0&&(s.options=n),e.groupImageUrl&&(s.groupImageUrl=e.groupImageUrl),e.groupTitle&&(s.groupTitle=e.groupTitle),{apiContent:t,apiCorrectAnswer:a,totalPoints:e.points||1,imageData:s,groupNumber:e.groupNumber||1,isExample:e.isExample||!1}}
@@ -1,16 +1 @@
1
- 'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import { ColorRegionClient } from '../../components/ColorRegionClient';
4
- const readAndColorObjectsConfig = {
5
- creatorTitle: 'Đọc và tô màu',
6
- creatorSubtitle: 'Tạo câu hỏi tô màu với hình ảnh và vùng màu',
7
- instructionsLabel: 'Hướng dẫn tô màu',
8
- instructionsTips: [],
9
- instructionPlaceholder: '',
10
- previewTitle: 'Read and Color Objects (Preview)',
11
- clientTitle: 'Read and Color',
12
- clientSubtitle: 'Đọc hướng dẫn và tô màu các vật thể trong hình',
13
- };
14
- export function ReadAndColorObjectsClient(props) {
15
- return _jsx(ColorRegionClient, { ...props, config: readAndColorObjectsConfig });
16
- }
1
+ "use client";import{jsx as t}from"react/jsx-runtime";import{ColorRegionClient as n}from"../../components/ColorRegionClient";const e={creatorTitle:"Đọc và tô màu",creatorSubtitle:"Tạo câu hỏi tô màu với hình ảnh và vùng màu",instructionsLabel:"Hướng dẫn tô màu",instructionsTips:[],instructionPlaceholder:"",previewTitle:"Read and Color Objects (Preview)",clientTitle:"Read and Color",clientSubtitle:"Đọc hướng dẫn và tô màu các vật thể trong hình"};export function ReadAndColorObjectsClient(i){return t(n,{...i,config:e})}
@@ -1,23 +1 @@
1
- 'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import { ColorRegionCreator } from '../../components/ColorRegionCreator';
4
- import { ReadAndColorObjectsClient } from './ReadAndColorObjectsClient';
5
- const readAndColorObjectsConfig = {
6
- creatorTitle: 'Đọc và tô màu',
7
- creatorSubtitle: 'Tạo câu hỏi tô màu với hình ảnh và vùng màu',
8
- instructionsLabel: 'Hướng dẫn tô màu',
9
- instructionsRequired: false,
10
- instructionsTips: [
11
- 'Upload hình ảnh nền cần tô màu',
12
- 'Thêm các màu sắc và tạo vùng tương ứng trên hình ảnh',
13
- 'Kéo thả các vùng để điều chỉnh vị trí',
14
- 'Thêm hướng dẫn tô màu cho mỗi câu lệnh (ví dụ: "Colour the sun yellow")',
15
- ],
16
- instructionPlaceholder: 'Colour the sun yellow',
17
- previewTitle: 'Read and Color Objects (Preview)',
18
- clientTitle: 'Read and Color',
19
- clientSubtitle: 'Đọc hướng dẫn và tô màu các vật thể trong hình',
20
- };
21
- export function ReadAndColorObjectsCreator(props) {
22
- return (_jsx(ColorRegionCreator, { ...props, config: readAndColorObjectsConfig, ClientComponent: ReadAndColorObjectsClient }));
23
- }
1
+ "use client";import{jsx as n}from"react/jsx-runtime";import{ColorRegionCreator as t}from"../../components/ColorRegionCreator";import{ReadAndColorObjectsClient as o}from"./ReadAndColorObjectsClient";const e={creatorTitle:"Đọc và tô màu",creatorSubtitle:"Tạo câu hỏi tô màu với hình ảnh và vùng màu",instructionsLabel:"Hướng dẫn tô màu",instructionsRequired:!1,instructionsTips:["Upload hình ảnh nền cần tô màu","Thêm các màu sắc và tạo vùng tương ứng trên hình ảnh","Kéo thả các vùng để điều chỉnh vị trí",'Thêm hướng dẫn tô màu cho mỗi câu lệnh (ví dụ: "Colour the sun yellow")'],instructionPlaceholder:"Colour the sun yellow",previewTitle:"Read and Color Objects (Preview)",clientTitle:"Read and Color",clientSubtitle:"Đọc hướng dẫn và tô màu các vật thể trong hình"};export function ReadAndColorObjectsCreator(r){return n(t,{...r,config:e,ClientComponent:o})}
@@ -1,2 +1 @@
1
- export * from './ReadAndColorObjectsCreator';
2
- export * from './ReadAndColorObjectsClient';
1
+ export*from"./ReadAndColorObjectsCreator";export*from"./ReadAndColorObjectsClient";
@@ -1,3 +1 @@
1
- import { ReadAndColorObjectsCreator } from './ReadAndColorObjectsCreator';
2
- import { createColorRegionRegistration } from '../../_shared/utils/createColorRegionRegistration';
3
- export const readAndColorObjectsRegistration = createColorRegionRegistration(ReadAndColorObjectsCreator);
1
+ import{ReadAndColorObjectsCreator as o}from"./ReadAndColorObjectsCreator";import{createColorRegionRegistration as r}from"../../_shared/utils/createColorRegionRegistration";export const readAndColorObjectsRegistration=r(o);
@@ -1,36 +1 @@
1
- export const transformReadAndColorObjects = (question) => {
2
- const answerData = question.answer;
3
- if (!answerData?.backgroundImageUrl) {
4
- return { apiContent: {}, apiCorrectAnswer: {} };
5
- }
6
- const apiContent = {
7
- backgroundImageUrl: answerData.backgroundImageUrl,
8
- colorNodes: (answerData.colorNodes || []).map((node) => ({
9
- id: node.id,
10
- color: node.color,
11
- ...(node.label ? { label: node.label } : {}),
12
- })),
13
- regionNodes: (answerData.regionNodes || []).map((region) => ({
14
- id: region.id,
15
- x: region.x,
16
- y: region.y,
17
- width: region.width,
18
- height: region.height,
19
- color: region.color,
20
- linkedColorNodeId: region.linkedColorNodeId,
21
- })),
22
- instructions: answerData.instructions || [],
23
- };
24
- const answers = (answerData.regionNodes || []).reduce((acc, region) => {
25
- if (region.id && region.color) {
26
- acc[region.id] = region.color;
27
- }
28
- return acc;
29
- }, {});
30
- return {
31
- apiContent,
32
- apiCorrectAnswer: {
33
- answers,
34
- },
35
- };
36
- };
1
+ export const transformReadAndColorObjects=o=>{const r=o.answer;if(!r?.backgroundImageUrl)return{apiContent:{},apiCorrectAnswer:{}};return{apiContent:{backgroundImageUrl:r.backgroundImageUrl,colorNodes:(r.colorNodes||[]).map(o=>({id:o.id,color:o.color,...o.label?{label:o.label}:{}})),regionNodes:(r.regionNodes||[]).map(o=>({id:o.id,x:o.x,y:o.y,width:o.width,height:o.height,color:o.color,linkedColorNodeId:o.linkedColorNodeId})),instructions:r.instructions||[]},apiCorrectAnswer:{answers:(r.regionNodes||[]).reduce((o,r)=>(r.id&&r.color&&(o[r.id]=r.color),o),{})}}};
@@ -1,125 +1 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useRef, useEffect } from 'react';
4
- import { Label } from '../../../../components/ui/label';
5
- import { Textarea } from '../../../../components/ui/textarea';
6
- import { PointsInput } from '../../../../components/ui/points-input';
7
- import { Card, CardContent, CardHeader, CardTitle } from '../../../../components/ui/card';
8
- import { useDebouncedCallback } from '../../../../shared/lib/hooks';
9
- import { useReactHookForm } from '../../../../shared/lib/hooks/useReactHookForm';
10
- import { BookOpen, FileText, Info, MessageSquare } from 'lucide-react';
11
- import { CreatorGuide } from '../../components/CreatorGuide';
12
- import { readDisplayedContentFormSchema, } from '../../../../shared/lib/validation/read-displayed-content.validation';
13
- export function ReadDisplayedContentCreator({ initialData, onSave, onChange, externalErrors, validationRef, }) {
14
- const apiData = initialData;
15
- const form = useReactHookForm({
16
- defaultValues: {
17
- referenceText: apiData?.referenceText || apiData?.content?.referenceText || apiData?.correctAnswer?.expectedAnswers || '',
18
- explanation: apiData?.explanation || '',
19
- points: apiData?.points ?? 5,
20
- },
21
- zodSchema: readDisplayedContentFormSchema,
22
- mode: 'onBlur',
23
- });
24
- const previousInitialDataRef = useRef(initialData);
25
- const isInitializingRef = useRef(false);
26
- const onChangeRef = useRef(onChange);
27
- const previousPayloadRef = useRef('');
28
- useEffect(() => {
29
- onChangeRef.current = onChange;
30
- }, [onChange]);
31
- const debouncedOnChange = useDebouncedCallback((data) => {
32
- onChangeRef.current?.(data);
33
- }, 300);
34
- const watchedReferenceText = form.watch('referenceText');
35
- const watchedExplanation = form.watch('explanation');
36
- const watchedPoints = form.watch('points');
37
- // Expose validation ref for external trigger
38
- useEffect(() => {
39
- if (validationRef) {
40
- validationRef.current = {
41
- triggerValidation: async () => {
42
- return await form.trigger();
43
- },
44
- getFormData: () => ({
45
- referenceText: watchedReferenceText,
46
- explanation: watchedExplanation,
47
- points: watchedPoints,
48
- }),
49
- };
50
- }
51
- }, [validationRef, form, watchedReferenceText, watchedExplanation, watchedPoints]);
52
- // Reset form when initialData changes externally
53
- useEffect(() => {
54
- const apiD = initialData;
55
- const normalizedInitialData = {
56
- referenceText: apiD?.referenceText || apiD?.content?.referenceText || apiD?.correctAnswer?.expectedAnswers || '',
57
- explanation: apiD?.explanation || '',
58
- points: apiD?.points ?? 5,
59
- };
60
- const initialDataChanged = JSON.stringify(previousInitialDataRef.current) !== JSON.stringify(initialData);
61
- if (!initialDataChanged) {
62
- return;
63
- }
64
- previousInitialDataRef.current = initialData;
65
- const currentFormData = {
66
- referenceText: watchedReferenceText,
67
- explanation: watchedExplanation,
68
- points: watchedPoints,
69
- };
70
- const isEchoFromOnChange = currentFormData.points === normalizedInitialData.points &&
71
- currentFormData.explanation === normalizedInitialData.explanation &&
72
- currentFormData.referenceText === normalizedInitialData.referenceText;
73
- const wasJustSaved = initialData?.isCompleted === true;
74
- if (isEchoFromOnChange && wasJustSaved) {
75
- return;
76
- }
77
- const shouldReset = !isEchoFromOnChange;
78
- if (shouldReset) {
79
- isInitializingRef.current = true;
80
- form.reset(normalizedInitialData);
81
- setTimeout(() => {
82
- isInitializingRef.current = false;
83
- }, 150);
84
- }
85
- }, [initialData, form, watchedReferenceText, watchedExplanation, watchedPoints]);
86
- // Debounced onChange
87
- useEffect(() => {
88
- if (isInitializingRef.current) {
89
- const currentPayload = JSON.stringify({
90
- referenceText: watchedReferenceText,
91
- explanation: watchedExplanation,
92
- points: watchedPoints,
93
- });
94
- previousPayloadRef.current = currentPayload;
95
- return;
96
- }
97
- const payload = {
98
- referenceText: watchedReferenceText,
99
- explanation: watchedExplanation,
100
- points: watchedPoints,
101
- };
102
- const payloadString = JSON.stringify(payload);
103
- if (previousPayloadRef.current !== payloadString) {
104
- previousPayloadRef.current = payloadString;
105
- debouncedOnChange(payload);
106
- }
107
- }, [
108
- watchedReferenceText,
109
- watchedExplanation,
110
- watchedPoints,
111
- debouncedOnChange,
112
- ]);
113
- const handleSave = form.handleSubmit((data) => {
114
- onSave?.({
115
- ...data,
116
- });
117
- });
118
- return (_jsxs("div", { className: "space-y-4", children: [_jsx(CreatorGuide, { colorScheme: "blue", steps: [
119
- { text: 'Nhập đoạn văn bản mà học sinh sẽ đọc to (reference text)', highlight: true },
120
- { text: 'Thêm giải thích (tùy chọn)' },
121
- ], tips: [
122
- 'Học sinh sẽ nhìn thấy đoạn văn trên màn hình và đọc to.',
123
- 'AI sẽ so sánh giọng đọc của học sinh với văn bản gốc (Phonetic Distance).',
124
- ] }), _jsxs(Card, { className: "overflow-hidden border-0 bg-white", children: [_jsx(CardHeader, { className: "px-4 py-3", children: _jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-gray-100", children: _jsx(FileText, { className: "h-4 w-4 text-gray-600" }) }), _jsxs("div", { children: [_jsx(CardTitle, { className: "text-base font-bold text-gray-900", children: "\u0110o\u1EA1n v\u0103n b\u1EA3n c\u1EA7n \u0111\u1ECDc" }), _jsx("p", { className: "text-xs text-gray-500", children: "T\u1EA1o c\u00E2u h\u1ECFi \u0111\u1ECDc \u0111o\u1EA1n v\u0103n" })] })] }) }) }), _jsxs(CardContent, { className: "space-y-3 px-4 pb-4", children: [_jsx("div", { className: "flex items-center gap-6", children: _jsx(PointsInput, { ...form.register('points', { valueAsNumber: true }), error: form.hasError('points') ? form.getFieldError('points') : undefined }) }), _jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "referenceText", className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-indigo-500" }), _jsx("span", { className: "flex items-center gap-1", children: "\u0110o\u1EA1n v\u0103n b\u1EA3n" }), _jsx("span", { className: "text-sm font-normal text-red-500", children: "*" })] }), _jsx(Textarea, { id: "referenceText", ...form.register('referenceText'), placeholder: "VD: The fat cat sat on a red mat. It has a small bell on its neck. The bell rings when the cat jumps.", rows: 4, className: `min-h-[120px] border-gray-200 bg-white transition-all focus:border-indigo-300 focus:ring-indigo-200 resize-none ${form.hasError('referenceText') ? 'border-red-400 focus:border-red-500 focus:ring-red-200' : ''}` }), form.hasError('referenceText') && (_jsx("p", { className: "text-sm text-red-600", children: form.getFieldError('referenceText') })), _jsxs("div", { className: "mt-2 flex items-start gap-3 rounded-xl border border-blue-100 bg-gradient-to-r from-blue-50 to-indigo-50 p-4 text-sm text-blue-800", children: [_jsx(Info, { className: "mt-0.5 h-4 w-4 flex-shrink-0 text-indigo-500" }), _jsx("p", { children: "\u0110\u00E2y l\u00E0 \u0111o\u1EA1n v\u0103n s\u1EBD hi\u1EC3n th\u1ECB tr\u00EAn m\u00E0n h\u00ECnh cho h\u1ECDc sinh \u0111\u1ECDc to. AI s\u1EBD so s\u00E1nh ph\u00E1t \u00E2m c\u1EE7a h\u1ECDc sinh v\u1EDBi \u0111o\u1EA1n v\u0103n n\u00E0y." })] })] }), externalErrors && externalErrors.length > 0 && (_jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-red-200 bg-gradient-to-r from-red-50 to-rose-50 p-4", children: [_jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-red-100", children: _jsx("span", { className: "text-lg", children: "\u274C" }) }), _jsxs("div", { className: "text-sm", children: [_jsx("p", { className: "font-semibold text-red-800", children: "L\u1ED7i:" }), _jsx("ul", { className: "mt-1 list-inside list-disc text-red-700", children: externalErrors.map((error, index) => (_jsx("li", { children: error }, index))) })] })] }))] })] }), _jsxs(Card, { className: "overflow-hidden border-0 bg-white", children: [_jsx(CardHeader, { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-amber-500 to-orange-500 shadow-sm", children: _jsx(BookOpen, { className: "h-3.5 w-3.5 text-white" }) }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CardTitle, { className: "text-base font-semibold text-gray-800", children: "Gi\u1EA3i th\u00EDch" }), _jsx("span", { className: "inline-flex items-center rounded-full border border-amber-200 bg-amber-50 px-2 py-0.5 text-xs font-medium text-amber-600", children: "Kh\u00F4ng b\u1EAFt bu\u1ED9c" })] }), _jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: "Gi\u1EA3i th\u00EDch cho \u0111\u00E1p \u00E1n \u0111\u00FAng \u2014 hi\u1EC3n th\u1ECB sau khi h\u1ECDc sinh ho\u00E0n th\u00E0nh c\u00E2u h\u1ECFi" })] })] }) }), _jsx(CardContent, { className: "px-4 pb-4", children: _jsx(Textarea, { value: watchedExplanation || '', onChange: (e) => form.setValue('explanation', e.target.value, { shouldValidate: true }), placeholder: "VD: \u0110o\u1EA1n v\u0103n t\u1EADp trung v\u00E0o c\u00E1c \u00E2m ng\u1EAFn /\u00E6/, /e/, /\u026A/...", rows: 3, className: "min-h-[80px] border-gray-200 bg-white transition-all focus:border-amber-300 focus:ring-amber-200 resize-none" }) })] })] }));
125
- }
1
+ "use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import{useRef as t,useEffect as n}from"react";import{Label as i}from"../../../../components/ui/label";import{Textarea as s}from"../../../../components/ui/textarea";import{PointsInput as a}from"../../../../components/ui/points-input";import{Card as c,CardContent as o,CardHeader as l,CardTitle as d}from"../../../../components/ui/card";import{useDebouncedCallback as h}from"../../../../shared/lib/hooks";import{useReactHookForm as m}from"../../../../shared/lib/hooks/useReactHookForm";import{BookOpen as x,FileText as p,Info as f,MessageSquare as g}from"lucide-react";import{CreatorGuide as u}from"../../components/CreatorGuide";import{readDisplayedContentFormSchema as b}from"../../../../shared/lib/validation/read-displayed-content.validation";export function ReadDisplayedContentCreator({initialData:N,onSave:v,onChange:y,externalErrors:w,validationRef:T}){const j=N,S=m({defaultValues:{referenceText:j?.referenceText||j?.content?.referenceText||j?.correctAnswer?.expectedAnswers||"",explanation:j?.explanation||"",points:j?.points??5},zodSchema:b,mode:"onBlur"}),k=t(N),A=t(!1),C=t(y),D=t("");n(()=>{C.current=y},[y]);const E=h(e=>{C.current?.(e)},300),V=S.watch("referenceText"),F=S.watch("explanation"),J=S.watch("points");n(()=>{T&&(T.current={triggerValidation:async()=>await S.trigger(),getFormData:()=>({referenceText:V,explanation:F,points:J})})},[T,S,V,F,J]),n(()=>{const e=N,r={referenceText:e?.referenceText||e?.content?.referenceText||e?.correctAnswer?.expectedAnswers||"",explanation:e?.explanation||"",points:e?.points??5};if(!(JSON.stringify(k.current)!==JSON.stringify(N)))return;k.current=N;const t=J===r.points&&F===r.explanation&&V===r.referenceText;if(t&&!0===N?.isCompleted)return;!t&&(A.current=!0,S.reset(r),setTimeout(()=>{A.current=!1},150))},[N,S,V,F,J]),n(()=>{if(A.current){const e=JSON.stringify({referenceText:V,explanation:F,points:J});return void(D.current=e)}const e={referenceText:V,explanation:F,points:J},r=JSON.stringify(e);D.current!==r&&(D.current=r,E(e))},[V,F,J,E]);S.handleSubmit(e=>{v?.({...e})});return r("div",{className:"space-y-4",children:[e(u,{colorScheme:"blue",steps:[{text:"Nhập đoạn văn bản mà học sinh sẽ đọc to (reference text)",highlight:!0},{text:"Thêm giải thích (tùy chọn)"}],tips:["Học sinh sẽ nhìn thấy đoạn văn trên màn hình và đọc to.","AI sẽ so sánh giọng đọc của học sinh với văn bản gốc (Phonetic Distance)."]}),r(c,{className:"overflow-hidden border-0 bg-white",children:[e(l,{className:"px-4 py-3",children:e("div",{className:"flex items-center justify-between",children:r("div",{className:"flex items-center gap-2",children:[e("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-gray-100",children:e(p,{className:"h-4 w-4 text-gray-600"})}),r("div",{children:[e(d,{className:"text-base font-bold text-gray-900",children:"Đoạn văn bản cần đọc"}),e("p",{className:"text-xs text-gray-500",children:"Tạo câu hỏi đọc đoạn văn"})]})]})})}),r(o,{className:"space-y-3 px-4 pb-4",children:[e("div",{className:"flex items-center gap-6",children:e(a,{...S.register("points",{valueAsNumber:!0}),error:S.hasError("points")?S.getFieldError("points"):void 0})}),r("div",{className:"space-y-2",children:[r(i,{htmlFor:"referenceText",className:"flex items-center gap-2 text-base font-semibold text-gray-800",children:[e(g,{className:"h-4 w-4 text-indigo-500"}),e("span",{className:"flex items-center gap-1",children:"Đoạn văn bản"}),e("span",{className:"text-sm font-normal text-red-500",children:"*"})]}),e(s,{id:"referenceText",...S.register("referenceText"),placeholder:"VD: The fat cat sat on a red mat. It has a small bell on its neck. The bell rings when the cat jumps.",rows:4,className:"min-h-[120px] border-gray-200 bg-white transition-all focus:border-indigo-300 focus:ring-indigo-200 resize-none "+(S.hasError("referenceText")?"border-red-400 focus:border-red-500 focus:ring-red-200":"")}),S.hasError("referenceText")&&e("p",{className:"text-sm text-red-600",children:S.getFieldError("referenceText")}),r("div",{className:"mt-2 flex items-start gap-3 rounded-xl border border-blue-100 bg-gradient-to-r from-blue-50 to-indigo-50 p-4 text-sm text-blue-800",children:[e(f,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-indigo-500"}),e("p",{children:"Đây là đoạn văn sẽ hiển thị trên màn hình cho học sinh đọc to. AI sẽ so sánh phát âm của học sinh với đoạn văn này."})]})]}),w&&w.length>0&&r("div",{className:"flex items-start gap-3 rounded-xl border border-red-200 bg-gradient-to-r from-red-50 to-rose-50 p-4",children:[e("div",{className:"flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-red-100",children:e("span",{className:"text-lg",children:"❌"})}),r("div",{className:"text-sm",children:[e("p",{className:"font-semibold text-red-800",children:"Lỗi:"}),e("ul",{className:"mt-1 list-inside list-disc text-red-700",children:w.map((r,t)=>e("li",{children:r},t))})]})]})]})]}),r(c,{className:"overflow-hidden border-0 bg-white",children:[e(l,{className:"px-4 py-3",children:r("div",{className:"flex items-center gap-2",children:[e("div",{className:"flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-amber-500 to-orange-500 shadow-sm",children:e(x,{className:"h-3.5 w-3.5 text-white"})}),r("div",{children:[r("div",{className:"flex items-center gap-2",children:[e(d,{className:"text-base font-semibold text-gray-800",children:"Giải thích"}),e("span",{className:"inline-flex items-center rounded-full border border-amber-200 bg-amber-50 px-2 py-0.5 text-xs font-medium text-amber-600",children:"Không bắt buộc"})]}),e("p",{className:"text-xs text-gray-500 mt-0.5",children:"Giải thích cho đáp án đúng — hiển thị sau khi học sinh hoàn thành câu hỏi"})]})]})}),e(o,{className:"px-4 pb-4",children:e(s,{value:F||"",onChange:e=>S.setValue("explanation",e.target.value,{shouldValidate:!0}),placeholder:"VD: Đoạn văn tập trung vào các âm ngắn /æ/, /e/, /ɪ/...",rows:3,className:"min-h-[80px] border-gray-200 bg-white transition-all focus:border-amber-300 focus:ring-amber-200 resize-none"})})]})]})}
@@ -1,64 +1 @@
1
- import { ReadDisplayedContentCreator } from './ReadDisplayedContentCreator';
2
- export const readDisplayedContentRegistration = {
3
- component: ReadDisplayedContentCreator,
4
- transformInitialData: (initialData) => {
5
- let creatorData = initialData?.answer;
6
- const content = initialData?.content;
7
- const answer = initialData?.answer || initialData?.correctAnswer || initialData?.correct_answer;
8
- const referenceTextValue = answer?.referenceText || answer?.expectedAnswers || content?.referenceText || '';
9
- const points = initialData?.total_points
10
- ? parseFloat(initialData.total_points)
11
- : (initialData?.points || content?.points || answer?.points || 5);
12
- const explanation = initialData?.explanation || content?.explanation || answer?.explanation || '';
13
- if (content && typeof content === 'object' && (content.referenceText !== undefined || answer?.expectedAnswers !== undefined)) {
14
- creatorData = {
15
- referenceText: referenceTextValue,
16
- explanation,
17
- points,
18
- };
19
- }
20
- else if (answer && typeof answer === 'object') {
21
- creatorData = {
22
- ...answer,
23
- referenceText: referenceTextValue,
24
- explanation,
25
- points,
26
- };
27
- }
28
- return creatorData;
29
- },
30
- getExtraProps: (ctx) => ({
31
- onUnsavedChangesChange: ctx.onUnsavedChangesChange,
32
- validationRef: ctx.validationRef,
33
- }),
34
- wrapOnSave: (data, ctx) => ({
35
- type: ctx.questionType,
36
- content: {
37
- ...(typeof ctx.state.content === 'object' && ctx.state.content !== null ? ctx.state.content : {}),
38
- referenceText: data.referenceText,
39
- },
40
- points: data?.points ?? ctx.state.points ?? 5,
41
- level: ctx.state.level,
42
- difficulty: ctx.state.difficulty,
43
- skill: ctx.state.skill,
44
- answer: {
45
- expectedAnswers: data.referenceText,
46
- },
47
- explanation: data?.explanation || '',
48
- }),
49
- wrapOnChange: (data, ctx) => ({
50
- type: ctx.questionType,
51
- content: {
52
- ...(typeof ctx.state.content === 'object' && ctx.state.content !== null ? ctx.state.content : {}),
53
- referenceText: data.referenceText,
54
- },
55
- points: data?.points ?? ctx.state.points ?? 5,
56
- level: ctx.state.level,
57
- difficulty: ctx.state.difficulty,
58
- skill: ctx.state.skill,
59
- answer: {
60
- expectedAnswers: data.referenceText,
61
- },
62
- explanation: data?.explanation || '',
63
- }),
64
- };
1
+ import{ReadDisplayedContentCreator as e}from"./ReadDisplayedContentCreator";export const readDisplayedContentRegistration={component:e,transformInitialData:e=>{let t=e?.answer;const n=e?.content,a=e?.answer||e?.correctAnswer||e?.correct_answer,o=a?.referenceText||a?.expectedAnswers||n?.referenceText||"",s=e?.total_points?parseFloat(e.total_points):e?.points||n?.points||a?.points||5,r=e?.explanation||n?.explanation||a?.explanation||"";return!n||"object"!=typeof n||void 0===n.referenceText&&void 0===a?.expectedAnswers?a&&"object"==typeof a&&(t={...a,referenceText:o,explanation:r,points:s}):t={referenceText:o,explanation:r,points:s},t},getExtraProps:e=>({onUnsavedChangesChange:e.onUnsavedChangesChange,validationRef:e.validationRef}),wrapOnSave:(e,t)=>({type:t.questionType,content:{..."object"==typeof t.state.content&&null!==t.state.content?t.state.content:{},referenceText:e.referenceText},points:e?.points??t.state.points??5,level:t.state.level,difficulty:t.state.difficulty,skill:t.state.skill,answer:{expectedAnswers:e.referenceText},explanation:e?.explanation||""}),wrapOnChange:(e,t)=>({type:t.questionType,content:{..."object"==typeof t.state.content&&null!==t.state.content?t.state.content:{},referenceText:e.referenceText},points:e?.points??t.state.points??5,level:t.state.level,difficulty:t.state.difficulty,skill:t.state.skill,answer:{expectedAnswers:e.referenceText},explanation:e?.explanation||""})};
@@ -1,12 +1 @@
1
- export const transformReadDisplayedContent = (question) => {
2
- const contentData = question.content;
3
- const answerData = question.answer;
4
- const referenceText = contentData?.referenceText || answerData?.referenceText || answerData?.expectedAnswers || '';
5
- const apiContent = {
6
- referenceText,
7
- };
8
- return {
9
- apiContent,
10
- apiCorrectAnswer: {},
11
- };
12
- };
1
+ export const transformReadDisplayedContent=e=>{const n=e.content,r=e.answer;return{apiContent:{referenceText:n?.referenceText||r?.referenceText||r?.expectedAnswers||""},apiCorrectAnswer:{}}};
@@ -1,64 +1 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState, useEffect, useRef } from 'react';
4
- import { cn } from '../../../../shared/lib/utils';
5
- import { Check, X, BookOpen, FileText, ClipboardList, Lightbulb } from 'lucide-react';
6
- export function ReadPassageAndAnswerQuestionsClient({ questionData, userAnswer, isReviewMode = false, onSubmit, autoFillCorrectAnswers = false, explanation: explanationProp, }) {
7
- const { passage, passageTitle, instructions, singleQuestion, explanation: dataExplanation } = questionData;
8
- const explanation = explanationProp || dataExplanation;
9
- // Single answer state
10
- const [selectedAnswer, setSelectedAnswer] = useState(() => {
11
- if (autoFillCorrectAnswers && singleQuestion) {
12
- return singleQuestion.correctAnswer;
13
- }
14
- return typeof userAnswer === 'number' ? userAnswer : -1;
15
- });
16
- const previousUserAnswerRef = useRef(JSON.stringify(userAnswer));
17
- // Sync userAnswer when it changes
18
- useEffect(() => {
19
- if (autoFillCorrectAnswers)
20
- return;
21
- const currentUserAnswerStr = JSON.stringify(userAnswer);
22
- if (previousUserAnswerRef.current !== currentUserAnswerStr) {
23
- previousUserAnswerRef.current = currentUserAnswerStr;
24
- setSelectedAnswer(typeof userAnswer === 'number' ? userAnswer : -1);
25
- }
26
- }, [userAnswer, autoFillCorrectAnswers]);
27
- // Handle answer change
28
- const handleAnswerChange = (value) => {
29
- if (isReviewMode)
30
- return;
31
- setSelectedAnswer(value);
32
- onSubmit?.(value);
33
- };
34
- // If no singleQuestion data, show empty state
35
- if (!singleQuestion) {
36
- return (_jsx("div", { className: "text-center text-gray-500 py-8", children: "Kh\u00F4ng c\u00F3 c\u00E2u h\u1ECFi n\u00E0o" }));
37
- }
38
- const isCorrect = isReviewMode && selectedAnswer === singleQuestion.correctAnswer;
39
- const isWrong = isReviewMode && selectedAnswer >= 0 && selectedAnswer !== singleQuestion.correctAnswer;
40
- const hasAnswered = selectedAnswer >= 0;
41
- return (_jsxs("div", { className: "space-y-5", children: [instructions && (_jsx("div", { className: "overflow-hidden rounded-xl border border-blue-200 bg-gradient-to-r from-blue-50 to-indigo-50 shadow-sm", children: _jsxs("div", { className: "flex items-center gap-3 px-5 py-4", children: [_jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-indigo-600 text-white shadow-sm", children: _jsx(FileText, { className: "h-4 w-4" }) }), _jsx("p", { className: "text-sm font-medium text-blue-900", children: instructions })] }) })), _jsxs("div", { className: "overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-3 border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white px-5 py-3", children: [_jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-emerald-500 to-teal-600 text-white shadow-sm", children: _jsx(BookOpen, { className: "h-4 w-4" }) }), _jsx("span", { className: "text-sm font-medium text-gray-700", children: "\u0110o\u1EA1n v\u0103n \u0111\u1ECDc hi\u1EC3u" })] }), _jsxs("div", { className: "p-5 space-y-4", children: [passageTitle && (_jsx("h3", { className: "text-center text-lg font-bold text-gray-900 border-b border-gray-100 pb-3", children: passageTitle })), _jsx("div", { className: "rounded-lg bg-gradient-to-br from-slate-50 to-gray-50 p-5 border border-gray-100", children: _jsx("p", { className: "whitespace-pre-wrap text-base leading-relaxed text-gray-700", children: passage }) })] })] }), _jsxs("div", { className: "overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm transition-all hover:shadow-md", children: [_jsxs("div", { className: cn('flex items-center justify-between border-b px-5 py-3', isReviewMode && isCorrect && 'border-green-200 bg-gradient-to-r from-green-50 to-emerald-50', isReviewMode && isWrong && 'border-red-200 bg-gradient-to-r from-red-50 to-rose-50', !isReviewMode && 'border-gray-100 bg-gradient-to-r from-gray-50 to-white'), children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: cn('flex h-8 w-8 items-center justify-center rounded-lg text-sm font-bold text-white shadow-sm', isReviewMode && isCorrect && 'bg-gradient-to-br from-green-500 to-emerald-600', isReviewMode && isWrong && 'bg-gradient-to-br from-red-500 to-rose-600', !isReviewMode && 'bg-gradient-to-br from-indigo-500 to-purple-600'), children: _jsx(ClipboardList, { className: "h-4 w-4" }) }), _jsx("span", { className: "text-sm font-medium text-gray-800", children: singleQuestion.question })] }), isReviewMode && hasAnswered && (_jsxs("div", { className: cn('flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-semibold', isCorrect ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'), children: [isCorrect ? _jsx(Check, { className: "h-3.5 w-3.5" }) : _jsx(X, { className: "h-3.5 w-3.5" }), isCorrect ? 'Đúng' : 'Sai'] }))] }), _jsxs("div", { className: "p-5 space-y-2.5", children: [singleQuestion.options.map((option, optIndex) => {
42
- const isSelected = selectedAnswer === optIndex;
43
- const isCorrectOption = optIndex === singleQuestion.correctAnswer;
44
- const letter = String.fromCharCode(65 + optIndex);
45
- return (_jsxs("button", { type: "button", onClick: () => handleAnswerChange(optIndex), disabled: isReviewMode, className: cn('group flex w-full items-center gap-3 rounded-lg border-2 p-3.5 text-left transition-all', isReviewMode
46
- ? isCorrectOption
47
- ? 'border-green-400 bg-green-50'
48
- : isSelected
49
- ? 'border-red-400 bg-red-50'
50
- : 'border-gray-200 bg-gray-50'
51
- : isSelected
52
- ? 'border-indigo-500 bg-indigo-50 shadow-sm ring-2 ring-indigo-100'
53
- : 'border-gray-200 bg-white hover:border-gray-300 hover:bg-gray-50 hover:shadow-sm'), children: [_jsx("div", { className: cn('flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-lg text-sm font-bold transition-all', isReviewMode
54
- ? isCorrectOption
55
- ? 'bg-green-500 text-white'
56
- : isSelected
57
- ? 'bg-red-500 text-white'
58
- : 'bg-gray-200 text-gray-600'
59
- : isSelected
60
- ? 'bg-gradient-to-br from-indigo-500 to-purple-600 text-white shadow-sm'
61
- : 'bg-gray-100 text-gray-600 group-hover:bg-gray-200'), children: letter }), _jsx("span", { className: cn('flex-1 text-sm font-medium', isReviewMode && isCorrectOption ? 'text-green-800' :
62
- isReviewMode && isSelected && !isCorrectOption ? 'text-red-800' : 'text-gray-700'), children: option }), isReviewMode && (isCorrectOption || isSelected) && (_jsx("div", { className: cn('flex h-6 w-6 items-center justify-center rounded-full', isCorrectOption ? 'bg-green-500' : 'bg-red-500'), children: isCorrectOption ? _jsx(Check, { className: "h-4 w-4 text-white" }) : _jsx(X, { className: "h-4 w-4 text-white" }) }))] }, optIndex));
63
- }), !isReviewMode && !hasAnswered && (_jsxs("div", { className: "rounded-lg border border-amber-200 bg-gradient-to-r from-amber-50 to-yellow-50 p-3 flex items-center gap-2 mt-3", children: [_jsx("div", { className: "flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-amber-400 text-white", children: _jsx("span", { className: "text-xs font-bold", children: "!" }) }), _jsx("span", { className: "text-sm text-amber-800", children: "Vui l\u00F2ng ch\u1ECDn m\u1ED9t \u0111\u00E1p \u00E1n" })] })), isReviewMode && isWrong && (_jsx("div", { className: "rounded-lg bg-gradient-to-r from-green-50 to-emerald-50 p-4 border border-green-200 mt-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Check, { className: "h-4 w-4 text-green-600" }), _jsxs("span", { className: "text-sm text-green-700", children: ["\u0110\u00E1p \u00E1n \u0111\u00FAng: ", _jsxs("strong", { children: [String.fromCharCode(65 + singleQuestion.correctAnswer), ". ", singleQuestion.options[singleQuestion.correctAnswer]] })] })] }) }))] })] }), isReviewMode && explanation && (_jsxs("div", { className: "overflow-hidden rounded-xl border border-blue-200 bg-gradient-to-br from-blue-50 to-indigo-50 shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-2 border-b border-blue-100 bg-white/50 px-4 py-3", children: [_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-amber-400 to-orange-500 text-white shadow-sm", children: _jsx(Lightbulb, { className: "h-4 w-4" }) }), _jsx("h4", { className: "text-sm font-semibold text-gray-800", children: "Gi\u1EA3i th\u00EDch" })] }), _jsx("div", { className: "p-4", children: _jsx("p", { className: "text-sm text-gray-700 leading-relaxed", children: explanation }) })] }))] }));
64
- }
1
+ "use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import{useState as t,useEffect as s,useRef as a}from"react";import{cn as n}from"../../../../shared/lib/utils";import{Check as d,X as i,BookOpen as o,FileText as l,ClipboardList as c,Lightbulb as g}from"lucide-react";export function ReadPassageAndAnswerQuestionsClient({questionData:m,userAnswer:b,isReviewMode:h=!1,onSubmit:x,autoFillCorrectAnswers:f=!1,explanation:u}){const{passage:p,passageTitle:w,instructions:y,singleQuestion:N,explanation:v}=m,j=u||v,[A,C]=t(()=>f&&N?N.correctAnswer:"number"==typeof b?b:-1),S=a(JSON.stringify(b));s(()=>{if(f)return;const e=JSON.stringify(b);S.current!==e&&(S.current=e,C("number"==typeof b?b:-1))},[b,f]);if(!N)return e("div",{className:"text-center text-gray-500 py-8",children:"Không có câu hỏi nào"});const k=h&&A===N.correctAnswer,q=h&&A>=0&&A!==N.correctAnswer,J=A>=0;return r("div",{className:"space-y-5",children:[y&&e("div",{className:"overflow-hidden rounded-xl border border-blue-200 bg-gradient-to-r from-blue-50 to-indigo-50 shadow-sm",children:r("div",{className:"flex items-center gap-3 px-5 py-4",children:[e("div",{className:"flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-indigo-600 text-white shadow-sm",children:e(l,{className:"h-4 w-4"})}),e("p",{className:"text-sm font-medium text-blue-900",children:y})]})}),r("div",{className:"overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm",children:[r("div",{className:"flex items-center gap-3 border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white px-5 py-3",children:[e("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-emerald-500 to-teal-600 text-white shadow-sm",children:e(o,{className:"h-4 w-4"})}),e("span",{className:"text-sm font-medium text-gray-700",children:"Đoạn văn đọc hiểu"})]}),r("div",{className:"p-5 space-y-4",children:[w&&e("h3",{className:"text-center text-lg font-bold text-gray-900 border-b border-gray-100 pb-3",children:w}),e("div",{className:"rounded-lg bg-gradient-to-br from-slate-50 to-gray-50 p-5 border border-gray-100",children:e("p",{className:"whitespace-pre-wrap text-base leading-relaxed text-gray-700",children:p})})]})]}),r("div",{className:"overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm transition-all hover:shadow-md",children:[r("div",{className:n("flex items-center justify-between border-b px-5 py-3",h&&k&&"border-green-200 bg-gradient-to-r from-green-50 to-emerald-50",h&&q&&"border-red-200 bg-gradient-to-r from-red-50 to-rose-50",!h&&"border-gray-100 bg-gradient-to-r from-gray-50 to-white"),children:[r("div",{className:"flex items-center gap-3",children:[e("div",{className:n("flex h-8 w-8 items-center justify-center rounded-lg text-sm font-bold text-white shadow-sm",h&&k&&"bg-gradient-to-br from-green-500 to-emerald-600",h&&q&&"bg-gradient-to-br from-red-500 to-rose-600",!h&&"bg-gradient-to-br from-indigo-500 to-purple-600"),children:e(c,{className:"h-4 w-4"})}),e("span",{className:"text-sm font-medium text-gray-800",children:N.question})]}),h&&J&&r("div",{className:n("flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-semibold",k?"bg-green-100 text-green-700":"bg-red-100 text-red-700"),children:[e(k?d:i,{className:"h-3.5 w-3.5"}),k?"Đúng":"Sai"]})]}),r("div",{className:"p-5 space-y-2.5",children:[N.options.map((t,s)=>{const a=A===s,o=s===N.correctAnswer,l=String.fromCharCode(65+s);return r("button",{type:"button",onClick:()=>{return e=s,void(h||(C(e),x?.(e)));var e},disabled:h,className:n("group flex w-full items-center gap-3 rounded-lg border-2 p-3.5 text-left transition-all",h?o?"border-green-400 bg-green-50":a?"border-red-400 bg-red-50":"border-gray-200 bg-gray-50":a?"border-indigo-500 bg-indigo-50 shadow-sm ring-2 ring-indigo-100":"border-gray-200 bg-white hover:border-gray-300 hover:bg-gray-50 hover:shadow-sm"),children:[e("div",{className:n("flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-lg text-sm font-bold transition-all",h?o?"bg-green-500 text-white":a?"bg-red-500 text-white":"bg-gray-200 text-gray-600":a?"bg-gradient-to-br from-indigo-500 to-purple-600 text-white shadow-sm":"bg-gray-100 text-gray-600 group-hover:bg-gray-200"),children:l}),e("span",{className:n("flex-1 text-sm font-medium",h&&o?"text-green-800":h&&a&&!o?"text-red-800":"text-gray-700"),children:t}),h&&(o||a)&&e("div",{className:n("flex h-6 w-6 items-center justify-center rounded-full",o?"bg-green-500":"bg-red-500"),children:e(o?d:i,{className:"h-4 w-4 text-white"})})]},s)}),!h&&!J&&r("div",{className:"rounded-lg border border-amber-200 bg-gradient-to-r from-amber-50 to-yellow-50 p-3 flex items-center gap-2 mt-3",children:[e("div",{className:"flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-amber-400 text-white",children:e("span",{className:"text-xs font-bold",children:"!"})}),e("span",{className:"text-sm text-amber-800",children:"Vui lòng chọn một đáp án"})]}),h&&q&&e("div",{className:"rounded-lg bg-gradient-to-r from-green-50 to-emerald-50 p-4 border border-green-200 mt-3",children:r("div",{className:"flex items-center gap-2",children:[e(d,{className:"h-4 w-4 text-green-600"}),r("span",{className:"text-sm text-green-700",children:["Đáp án đúng: ",r("strong",{children:[String.fromCharCode(65+N.correctAnswer),". ",N.options[N.correctAnswer]]})]})]})})]})]}),h&&j&&r("div",{className:"overflow-hidden rounded-xl border border-blue-200 bg-gradient-to-br from-blue-50 to-indigo-50 shadow-sm",children:[r("div",{className:"flex items-center gap-2 border-b border-blue-100 bg-white/50 px-4 py-3",children:[e("div",{className:"flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-amber-400 to-orange-500 text-white shadow-sm",children:e(g,{className:"h-4 w-4"})}),e("h4",{className:"text-sm font-semibold text-gray-800",children:"Giải thích"})]}),e("div",{className:"p-4",children:e("p",{className:"text-sm text-gray-700 leading-relaxed",children:j})})]})]})}