@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,37 +1 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Card, CardContent } from '../../../../components/ui/card';
4
- import { Input } from '../../../../components/ui/input';
5
- import { Label } from '../../../../components/ui/label';
6
- import { CheckCircle2, XCircle, BookOpen } from 'lucide-react';
7
- import { usePresignedFileUrl } from '../../../../shared/lib/hooks';
8
- import { useState } from 'react';
9
- export function AnswerTheQuestionClient({ questionData, onSubmit, isReviewMode = false, userAnswer, autoFillCorrectAnswers = false, explanation, }) {
10
- const [answer, setAnswer] = useState(userAnswer || '');
11
- const { previewUrl: imagePreviewUrl } = usePresignedFileUrl(questionData.imageUrl || '');
12
- if (!questionData.question) {
13
- return (_jsx(Card, { children: _jsx(CardContent, { className: "p-6", children: _jsx("p", { className: "text-gray-500", children: "Kh\u00F4ng c\u00F3 d\u1EEF li\u1EC7u c\u00E2u h\u1ECFi" }) }) }));
14
- }
15
- const isExample = questionData.isExample || false;
16
- const displayedAnswer = autoFillCorrectAnswers || isExample
17
- ? questionData.correctAnswer
18
- : answer;
19
- const isCorrect = isReviewMode && userAnswer !== undefined
20
- ? userAnswer.trim().toLowerCase() === questionData.correctAnswer.trim().toLowerCase()
21
- : undefined;
22
- return (_jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-lg", children: [_jsx("div", { className: "h-1 bg-gradient-to-r from-teal-400 to-cyan-500" }), _jsxs(CardContent, { className: "p-6 space-y-6", children: [(questionData.title || questionData.groupContent) && (_jsxs("div", { className: "rounded-xl border border-indigo-200 bg-gradient-to-r from-indigo-50 to-blue-50 p-4 space-y-2", children: [questionData.title && (_jsx("h3", { className: "text-base font-bold text-indigo-900", children: questionData.title })), questionData.groupContent && (_jsx("p", { className: "text-sm text-indigo-700 leading-relaxed whitespace-pre-wrap", children: questionData.groupContent }))] })), (imagePreviewUrl || questionData.imageUrl) && (_jsx("div", { className: "flex justify-center", children: _jsx("div", { className: "relative max-w-lg overflow-hidden rounded-xl border border-gray-200 bg-gray-50 shadow-sm", children: _jsx("img", { src: imagePreviewUrl || questionData.imageUrl, alt: "Question", className: "h-auto max-h-80 w-full object-contain" }) }) })), _jsxs("div", { className: "rounded-xl border border-gray-200 bg-gradient-to-r from-gray-50 to-slate-50 p-5", children: [isExample && (_jsxs("div", { className: "mb-2 inline-flex items-center gap-1.5 rounded-full bg-amber-100 border border-amber-300 px-3 py-1", children: [_jsx(BookOpen, { className: "h-3.5 w-3.5 text-amber-600" }), _jsx("span", { className: "text-xs font-semibold text-amber-700 uppercase tracking-wide", children: "Example" })] })), _jsx(Label, { className: "text-base font-semibold text-gray-800 mb-3 block", children: questionData.question }), questionData.suggestedAnswers && questionData.suggestedAnswers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mt-2 mb-1", children: questionData.suggestedAnswers.map((suggestion, index) => (_jsx("button", { type: "button", disabled: isReviewMode || isExample, onClick: () => {
23
- if (!isReviewMode && !isExample) {
24
- setAnswer(suggestion);
25
- onSubmit?.(suggestion);
26
- }
27
- }, className: `inline-flex items-center rounded-full border px-3 py-1 text-sm font-medium transition-colors ${answer === suggestion
28
- ? 'border-teal-400 bg-teal-50 text-teal-700 ring-1 ring-teal-200'
29
- : 'border-gray-200 bg-white text-gray-600 hover:border-teal-300 hover:bg-teal-50/50 hover:text-teal-600'} ${isReviewMode || isExample ? 'cursor-not-allowed opacity-60' : 'cursor-pointer'}`, children: suggestion }, index))) })), _jsxs("div", { className: "flex items-center gap-3 mt-3", children: [questionData.prefixText && (_jsx("span", { className: "text-base font-medium text-gray-700", children: questionData.prefixText })), _jsx(Input, { value: displayedAnswer, onChange: (e) => {
30
- setAnswer(e.target.value);
31
- onSubmit?.(e.target.value);
32
- }, placeholder: "Vi\u1EBFt \u0111\u00E1p \u00E1n...", disabled: isReviewMode || isExample, className: `max-w-xs border-2 text-lg font-medium ${isReviewMode
33
- ? isCorrect
34
- ? 'border-green-400 bg-green-50 text-green-700'
35
- : 'border-red-400 bg-red-50 text-red-700'
36
- : 'border-teal-300 focus:border-teal-500 focus:ring-teal-200'}` }), questionData.suffixText && (_jsx("span", { className: "text-base font-medium text-gray-700", children: questionData.suffixText })), isReviewMode && isCorrect !== undefined && (_jsx("span", { className: "flex items-center gap-1", children: isCorrect ? (_jsx(CheckCircle2, { className: "h-5 w-5 text-green-500" })) : (_jsx(XCircle, { className: "h-5 w-5 text-red-500" })) }))] }), isReviewMode && isCorrect === false && (_jsxs("div", { className: "mt-3 flex items-center gap-2 rounded-lg bg-green-50 border border-green-200 px-4 py-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-green-600" }), _jsxs("span", { className: "text-sm text-green-700", children: ["\u0110\u00E1p \u00E1n \u0111\u00FAng: ", _jsx("strong", { children: questionData.correctAnswer })] })] })), autoFillCorrectAnswers && (_jsxs("div", { className: "mt-3 flex items-center gap-2 rounded-lg bg-teal-50 border border-teal-200 px-4 py-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-teal-600" }), _jsxs("span", { className: "text-sm text-teal-700", children: ["\u0110\u00E1p \u00E1n: ", _jsx("strong", { children: questionData.correctAnswer })] })] }))] }), explanation && isReviewMode && (_jsxs("div", { className: "rounded-xl border border-blue-200 bg-blue-50 p-4", children: [_jsx("p", { className: "text-sm font-semibold text-blue-800 mb-1", children: "Gi\u1EA3i th\u00EDch:" }), _jsx("p", { className: "text-sm text-blue-700", children: explanation })] }))] })] }));
37
- }
1
+ "use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import{Card as t,CardContent as a}from"../../../../components/ui/card";import{Input as s}from"../../../../components/ui/input";import{Label as l}from"../../../../components/ui/label";import{CheckCircle2 as n,XCircle as o,BookOpen as i}from"lucide-react";import{usePresignedFileUrl as d}from"../../../../shared/lib/hooks";import{useState as c}from"react";export function AnswerTheQuestionClient({questionData:m,onSubmit:g,isReviewMode:x=!1,userAnswer:b,autoFillCorrectAnswers:p=!1,explanation:u}){const[h,f]=c(b||""),{previewUrl:N}=d(m.imageUrl||"");if(!m.question)return e(t,{children:e(a,{className:"p-6",children:e("p",{className:"text-gray-500",children:"Không có dữ liệu câu hỏi"})})});const w=m.isExample||!1,v=p||w?m.correctAnswer:h,y=x&&void 0!==b?b.trim().toLowerCase()===m.correctAnswer.trim().toLowerCase():void 0;return r(t,{className:"overflow-hidden border-0 bg-white shadow-lg",children:[e("div",{className:"h-1 bg-gradient-to-r from-teal-400 to-cyan-500"}),r(a,{className:"p-6 space-y-6",children:[(m.title||m.groupContent)&&r("div",{className:"rounded-xl border border-indigo-200 bg-gradient-to-r from-indigo-50 to-blue-50 p-4 space-y-2",children:[m.title&&e("h3",{className:"text-base font-bold text-indigo-900",children:m.title}),m.groupContent&&e("p",{className:"text-sm text-indigo-700 leading-relaxed whitespace-pre-wrap",children:m.groupContent})]}),(N||m.imageUrl)&&e("div",{className:"flex justify-center",children:e("div",{className:"relative max-w-lg overflow-hidden rounded-xl border border-gray-200 bg-gray-50 shadow-sm",children:e("img",{src:N||m.imageUrl,alt:"Question",className:"h-auto max-h-80 w-full object-contain"})})}),r("div",{className:"rounded-xl border border-gray-200 bg-gradient-to-r from-gray-50 to-slate-50 p-5",children:[w&&r("div",{className:"mb-2 inline-flex items-center gap-1.5 rounded-full bg-amber-100 border border-amber-300 px-3 py-1",children:[e(i,{className:"h-3.5 w-3.5 text-amber-600"}),e("span",{className:"text-xs font-semibold text-amber-700 uppercase tracking-wide",children:"Example"})]}),e(l,{className:"text-base font-semibold text-gray-800 mb-3 block",children:m.question}),m.suggestedAnswers&&m.suggestedAnswers.length>0&&e("div",{className:"flex flex-wrap gap-2 mt-2 mb-1",children:m.suggestedAnswers.map((r,t)=>e("button",{type:"button",disabled:x||w,onClick:()=>{x||w||(f(r),g?.(r))},className:`inline-flex items-center rounded-full border px-3 py-1 text-sm font-medium transition-colors ${h===r?"border-teal-400 bg-teal-50 text-teal-700 ring-1 ring-teal-200":"border-gray-200 bg-white text-gray-600 hover:border-teal-300 hover:bg-teal-50/50 hover:text-teal-600"} ${x||w?"cursor-not-allowed opacity-60":"cursor-pointer"}`,children:r},t))}),r("div",{className:"flex items-center gap-3 mt-3",children:[m.prefixText&&e("span",{className:"text-base font-medium text-gray-700",children:m.prefixText}),e(s,{value:v,onChange:e=>{f(e.target.value),g?.(e.target.value)},placeholder:"Viết đáp án...",disabled:x||w,className:"max-w-xs border-2 text-lg font-medium "+(x?y?"border-green-400 bg-green-50 text-green-700":"border-red-400 bg-red-50 text-red-700":"border-teal-300 focus:border-teal-500 focus:ring-teal-200")}),m.suffixText&&e("span",{className:"text-base font-medium text-gray-700",children:m.suffixText}),x&&void 0!==y&&e("span",{className:"flex items-center gap-1",children:y?e(n,{className:"h-5 w-5 text-green-500"}):e(o,{className:"h-5 w-5 text-red-500"})})]}),x&&!1===y&&r("div",{className:"mt-3 flex items-center gap-2 rounded-lg bg-green-50 border border-green-200 px-4 py-2",children:[e(n,{className:"h-4 w-4 text-green-600"}),r("span",{className:"text-sm text-green-700",children:["Đáp án đúng: ",e("strong",{children:m.correctAnswer})]})]}),p&&r("div",{className:"mt-3 flex items-center gap-2 rounded-lg bg-teal-50 border border-teal-200 px-4 py-2",children:[e(n,{className:"h-4 w-4 text-teal-600"}),r("span",{className:"text-sm text-teal-700",children:["Đáp án: ",e("strong",{children:m.correctAnswer})]})]})]}),u&&x&&r("div",{className:"rounded-xl border border-blue-200 bg-blue-50 p-4",children:[e("p",{className:"text-sm font-semibold text-blue-800 mb-1",children:"Giải thích:"}),e("p",{className:"text-sm text-blue-700",children:u})]})]})]})}
@@ -1,351 +1 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState, useRef, useEffect } from 'react';
4
- import { Button } from '../../../../components/ui/button';
5
- import { Label } from '../../../../components/ui/label';
6
- import { Input } from '../../../../components/ui/input';
7
- import { Textarea } from '../../../../components/ui/textarea';
8
- import { PointsInput } from '../../../../components/ui/points-input';
9
- import { Card, CardContent, CardHeader, CardTitle } from '../../../../components/ui/card';
10
- import { Pencil, Eye, HelpCircle, BookOpen, Plus, X, ListChecks, MessageSquare } from 'lucide-react';
11
- import { Checkbox } from '../../../../components/ui/checkbox';
12
- import { AnswerTheQuestionClient } from './AnswerTheQuestionClient';
13
- import { useDebouncedCallback } from '../../../../shared/lib/hooks';
14
- import { BasicQuestionGroupCard } from '../../groups/BasicQuestionGroupCard';
15
- import { useBasicQuestionGroup, getGroupNumberForIndex } from '../../_shared/hooks/useBasicQuestionGroup';
16
- /**
17
- * AnswerTheQuestionCreator - Single Question Mode
18
- *
19
- * This component handles ONE question at a time. Navigation between questions
20
- * is handled by the parent ExamCreator component.
21
- *
22
- * Shared data within group:
23
- * - imageUrl: string (the question image, shared between questions in same group)
24
- * - title: string (the group title, shared between questions in same group)
25
- *
26
- * Per-question data:
27
- * - question: string (the question text)
28
- * - correctAnswer: string (the answer - a name or number)
29
- * - suffixText: string (optional text after the input, e.g. "School")
30
- * - prefixText: string (optional text before the input)
31
- */
32
- function AnswerTheQuestionContent({ initialData, onSave, onSaveToQuestionBank, onCancel, onChange, onUnsavedChangesChange, externalErrors, groups, questionIndexInPart = 0, partId = '', validationRef, suggestedAnswers: templateSuggestedAnswers, groupConfig, hasSuggestedAnswers, headerExtra, }) {
33
- // Create a default single question
34
- const createDefaultQuestion = () => {
35
- const groupNumber = getGroupNumberForIndex(questionIndexInPart, groups);
36
- return {
37
- id: `sq-${Date.now()}-${Math.random()}`,
38
- question: '',
39
- correctAnswer: '',
40
- suffixText: '',
41
- prefixText: '',
42
- points: 1,
43
- groupNumber,
44
- isExample: false,
45
- suggestedAnswers: templateSuggestedAnswers || [],
46
- };
47
- };
48
- // Initialize from initialData or create new
49
- const initializeQuestion = () => {
50
- // Flat format from register.tsx transformInitialData
51
- if (initialData?.question) {
52
- return {
53
- id: `sq-${Date.now()}-imported`,
54
- question: initialData.question,
55
- correctAnswer: initialData.correctAnswer || '',
56
- suffixText: initialData.suffixText || '',
57
- prefixText: initialData.prefixText || '',
58
- points: initialData.points || 1,
59
- groupNumber: getGroupNumberForIndex(questionIndexInPart, groups),
60
- isExample: initialData.isExample || false,
61
- suggestedAnswers: initialData.suggestedAnswers?.length ? initialData.suggestedAnswers : (templateSuggestedAnswers || []),
62
- };
63
- }
64
- return createDefaultQuestion();
65
- };
66
- // State for current question
67
- const [currentQuestion, setCurrentQuestion] = useState(initializeQuestion);
68
- // ============ GROUP (shared title / content / image) ============
69
- const { isGrouped, currentGroupNumber: hookGroupNumber, groupTitle, groupSubtitle, groupContent, imageUrl, setGroupTitle, setGroupSubtitle, setGroupContent, setImageUrl, } = useBasicQuestionGroup({
70
- partId,
71
- groups,
72
- questionIndexInPart,
73
- initialData: {
74
- title: (() => {
75
- const content = initialData?.content;
76
- const answer = initialData?.answer;
77
- const qgPayload = initialData?.questionGroup?.payload;
78
- return answer?.title || content?.passageTitle || qgPayload?.title || initialData?.title || '';
79
- })(),
80
- subtitle: (() => {
81
- const content = initialData?.content;
82
- const qgPayload = initialData?.questionGroup?.payload;
83
- return content?.passageSubtitle || qgPayload?.subtitle || '';
84
- })(),
85
- content: (() => {
86
- const content = initialData?.content;
87
- const qgPayload = initialData?.questionGroup?.payload;
88
- return initialData?.groupContent || qgPayload?.content || content?.passage || '';
89
- })(),
90
- imageUrl: (() => {
91
- const content = initialData?.content;
92
- const answer = initialData?.answer;
93
- const qgPayload = initialData?.questionGroup?.payload;
94
- return answer?.imageUrl || content?.imageUrl || qgPayload?.imageUrl || initialData?.imageUrl || '';
95
- })(),
96
- },
97
- });
98
- // UI State
99
- const [isClientMode, setIsClientMode] = useState(false);
100
- const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
101
- const [explanation, setExplanation] = useState(initialData?.explanation || '');
102
- // Inline validation errors
103
- const [validationErrors, setValidationErrors] = useState({});
104
- // Store the last saved state for comparison
105
- const savedStateRef = useRef('');
106
- // Refs for change tracking
107
- const previousInitialDataRef = useRef(initialData);
108
- const previousQuestionIndexRef = useRef(questionIndexInPart);
109
- const isInitializingRef = useRef(false);
110
- const hasInitializedRef = useRef(false);
111
- const onChangeRef = useRef(onChange);
112
- const previousPayloadRef = useRef('');
113
- // Current group number – prefer the hook's derived value (from groups config),
114
- // fall back to the question's own stored groupNumber
115
- const currentGroupNumber = hookGroupNumber || currentQuestion.groupNumber || 1;
116
- // Ref for onUnsavedChangesChange callback
117
- const onUnsavedChangesChangeRef = useRef(onUnsavedChangesChange);
118
- useEffect(() => {
119
- onUnsavedChangesChangeRef.current = onUnsavedChangesChange;
120
- }, [onUnsavedChangesChange]);
121
- // Update onChange ref
122
- useEffect(() => {
123
- onChangeRef.current = onChange;
124
- }, [onChange]);
125
- // Debounced onChange callback
126
- const debouncedOnChange = useDebouncedCallback((data) => {
127
- onChangeRef.current?.(data);
128
- }, 300);
129
- // Helper function to create current state string for comparison
130
- const getCurrentStateString = () => {
131
- return JSON.stringify({
132
- imageUrl,
133
- title: groupTitle,
134
- subtitle: groupSubtitle,
135
- question: currentQuestion.question,
136
- correctAnswer: currentQuestion.correctAnswer,
137
- suffixText: currentQuestion.suffixText,
138
- prefixText: currentQuestion.prefixText,
139
- points: currentQuestion.points,
140
- isExample: currentQuestion.isExample,
141
- suggestedAnswers: currentQuestion.suggestedAnswers,
142
- });
143
- };
144
- // Initialize saved state when questionIndexInPart changes (navigation)
145
- useEffect(() => {
146
- if (isInitializingRef.current)
147
- return;
148
- const timer = setTimeout(() => {
149
- savedStateRef.current = getCurrentStateString();
150
- setHasUnsavedChanges(false);
151
- }, 150);
152
- return () => clearTimeout(timer);
153
- }, [questionIndexInPart]);
154
- // Detect unsaved changes
155
- useEffect(() => {
156
- if (isInitializingRef.current)
157
- return;
158
- if (!savedStateRef.current)
159
- return;
160
- const currentState = getCurrentStateString();
161
- const hasChanges = currentState !== savedStateRef.current;
162
- if (hasChanges !== hasUnsavedChanges) {
163
- setHasUnsavedChanges(hasChanges);
164
- onUnsavedChangesChangeRef.current?.(hasChanges);
165
- }
166
- }, [imageUrl, currentQuestion, hasUnsavedChanges]);
167
- // Expose validation function via ref
168
- useEffect(() => {
169
- if (validationRef) {
170
- validationRef.current = {
171
- triggerValidation: async () => {
172
- const errors = {};
173
- let isValid = true;
174
- if (!currentQuestion.question || currentQuestion.question.trim() === '') {
175
- errors.question = 'Vui lòng nhập câu hỏi';
176
- isValid = false;
177
- }
178
- if (!currentQuestion.correctAnswer || currentQuestion.correctAnswer.trim() === '') {
179
- errors.correctAnswer = 'Vui lòng nhập đáp án';
180
- isValid = false;
181
- }
182
- setValidationErrors(errors);
183
- return isValid;
184
- },
185
- getFormData: () => ({
186
- imageUrl,
187
- title: groupTitle,
188
- subtitle: groupSubtitle,
189
- question: currentQuestion.question,
190
- correctAnswer: currentQuestion.correctAnswer,
191
- suffixText: currentQuestion.suffixText,
192
- prefixText: currentQuestion.prefixText,
193
- points: currentQuestion.points,
194
- groupNumber: currentQuestion.groupNumber,
195
- isExample: currentQuestion.isExample,
196
- suggestedAnswers: currentQuestion.suggestedAnswers,
197
- explanation,
198
- groups,
199
- }),
200
- };
201
- }
202
- }, [validationRef, currentQuestion, imageUrl, groupTitle, groupSubtitle, explanation, groups]);
203
- // Sync from initialData when navigation or first init
204
- // Note: shared group data (title/content/image) is managed by useBasicQuestionGroup hook.
205
- // This effect handles question-specific fields and explanation only.
206
- useEffect(() => {
207
- const questionIndexChanged = questionIndexInPart !== previousQuestionIndexRef.current;
208
- const hasValidInitialData = !!initialData?.question;
209
- const shouldSyncForFirstInit = !hasInitializedRef.current && hasValidInitialData;
210
- const shouldSyncForNavigation = questionIndexChanged;
211
- if (!shouldSyncForFirstInit && !shouldSyncForNavigation) {
212
- return;
213
- }
214
- isInitializingRef.current = true;
215
- previousInitialDataRef.current = initialData;
216
- previousQuestionIndexRef.current = questionIndexInPart;
217
- hasInitializedRef.current = true;
218
- const groupNum = getGroupNumberForIndex(questionIndexInPart, groups);
219
- // Initialize question
220
- setCurrentQuestion({
221
- ...initializeQuestion(),
222
- groupNumber: groupNum,
223
- });
224
- // Set explanation
225
- setExplanation(initialData?.explanation || '');
226
- setTimeout(() => {
227
- isInitializingRef.current = false;
228
- }, 100);
229
- }, [initialData, groups, questionIndexInPart]);
230
- // Call onChange when data changes
231
- useEffect(() => {
232
- if (isInitializingRef.current)
233
- return;
234
- const payload = {
235
- question: currentQuestion.question,
236
- correctAnswer: currentQuestion.correctAnswer,
237
- suffixText: currentQuestion.suffixText,
238
- prefixText: currentQuestion.prefixText,
239
- points: currentQuestion.points || 1,
240
- groupNumber: currentQuestion.groupNumber,
241
- isExample: currentQuestion.isExample,
242
- suggestedAnswers: currentQuestion.suggestedAnswers,
243
- imageUrl,
244
- title: groupTitle,
245
- subtitle: groupSubtitle,
246
- groupContent,
247
- explanation,
248
- groups,
249
- };
250
- const payloadString = JSON.stringify(payload);
251
- if (previousPayloadRef.current !== payloadString) {
252
- previousPayloadRef.current = payloadString;
253
- debouncedOnChange(payload);
254
- }
255
- }, [imageUrl, groupTitle, groupSubtitle, groupContent, explanation, currentQuestion, groups, debouncedOnChange]);
256
- // Update current question field
257
- const updateCurrentQuestion = (field, value) => {
258
- setCurrentQuestion((prev) => ({ ...prev, [field]: value }));
259
- // Clear validation errors
260
- if (field === 'question' && validationErrors.question) {
261
- setValidationErrors(prev => ({ ...prev, question: undefined }));
262
- }
263
- if (field === 'correctAnswer' && validationErrors.correctAnswer) {
264
- setValidationErrors(prev => ({ ...prev, correctAnswer: undefined }));
265
- }
266
- };
267
- // Validate all fields
268
- const validate = () => {
269
- const errors = {};
270
- let isValid = true;
271
- if (!currentQuestion.question || currentQuestion.question.trim() === '') {
272
- errors.question = 'Vui lòng nhập câu hỏi';
273
- isValid = false;
274
- }
275
- if (!currentQuestion.correctAnswer || currentQuestion.correctAnswer.trim() === '') {
276
- errors.correctAnswer = 'Vui lòng nhập đáp án';
277
- isValid = false;
278
- }
279
- setValidationErrors(errors);
280
- return isValid;
281
- };
282
- // Handle save
283
- const handleSave = () => {
284
- if (!validate())
285
- return;
286
- const payload = {
287
- question: currentQuestion.question,
288
- correctAnswer: currentQuestion.correctAnswer,
289
- suffixText: currentQuestion.suffixText,
290
- prefixText: currentQuestion.prefixText,
291
- points: currentQuestion.points || 1,
292
- groupNumber: currentQuestion.groupNumber,
293
- isExample: currentQuestion.isExample,
294
- suggestedAnswers: currentQuestion.suggestedAnswers,
295
- imageUrl,
296
- title: groupTitle,
297
- subtitle: groupSubtitle,
298
- explanation,
299
- groups,
300
- };
301
- // Update saved state
302
- savedStateRef.current = getCurrentStateString();
303
- setHasUnsavedChanges(false);
304
- onSave?.(payload);
305
- };
306
- // Client mode preview
307
- if (isClientMode) {
308
- const questionData = {
309
- question: currentQuestion.question,
310
- correctAnswer: currentQuestion.correctAnswer,
311
- suffixText: currentQuestion.suffixText,
312
- prefixText: currentQuestion.prefixText,
313
- points: currentQuestion.points,
314
- groupNumber: currentQuestion.groupNumber,
315
- isExample: currentQuestion.isExample,
316
- suggestedAnswers: currentQuestion.suggestedAnswers,
317
- imageUrl,
318
- title: groupTitle,
319
- subtitle: groupSubtitle,
320
- };
321
- return (_jsxs("div", { className: "space-y-4", children: [_jsx(Card, { children: _jsx(CardHeader, { children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx(CardTitle, { children: "Answer the question (Preview)" }), _jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Ch\u1EBF \u0111\u1ED9 xem tr\u01B0\u1EDBc - Hi\u1EC3n th\u1ECB \u0111\u00E1p \u00E1n \u0111\u00FAng" })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setIsClientMode(false), children: [_jsx(Pencil, { className: "mr-2 h-4 w-4" }), "Quay l\u1EA1i Edit Mode"] })] }) }) }), _jsx(AnswerTheQuestionClient, { questionData: questionData, isReviewMode: true, autoFillCorrectAnswers: true, explanation: explanation })] }));
322
- }
323
- // Creator UI
324
- return (_jsxs("div", { className: "space-y-4", children: [isGrouped && (_jsx(BasicQuestionGroupCard, { groupNumber: currentGroupNumber, title: groupTitle, subtitle: groupSubtitle, content: groupContent, imageUrl: imageUrl, onTitleChange: setGroupTitle, onSubtitleChange: setGroupSubtitle, onContentChange: setGroupContent, onImageChange: setImageUrl, groupConfig: groupConfig, uploadIdPrefix: `answer-the-question-${partId ?? 'group'}` })), _jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-lg shadow-blue-100/50", children: [_jsx(CardHeader, { className: "px-4 py-3", children: _jsxs("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-gradient-to-br from-teal-500 to-cyan-600 shadow-sm", children: _jsx(HelpCircle, { className: "h-4 w-4 text-white" }) }), _jsxs("div", { children: [_jsx(CardTitle, { className: "text-base font-bold text-gray-900", children: "\u0110\u1ECDc c\u00E2u h\u1ECFi v\u00E0 vi\u1EBFt \u0111\u00E1p \u00E1n" }), _jsx("p", { className: "text-xs text-gray-500", children: "Nghe - \u0110\u1ECDc c\u00E2u h\u1ECFi v\u00E0 vi\u1EBFt t\u00EAn ho\u1EB7c s\u1ED1" })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [headerExtra, _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setIsClientMode(true), disabled: !currentQuestion.question, className: "gap-2 border-teal-200 text-teal-600 hover:bg-teal-50 hover:text-teal-700", children: [_jsx(Eye, { className: "h-4 w-4" }), "Xem tr\u01B0\u1EDBc"] })] })] }) }), _jsxs(CardContent, { className: "space-y-4 px-4 pb-4", children: [_jsxs("div", { className: "flex items-center gap-6", children: [_jsx(PointsInput, { value: currentQuestion.points || 1, onChange: (e) => updateCurrentQuestion('points', parseFloat(e.target.value) || 1) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "isExample", checked: currentQuestion.isExample || false, onCheckedChange: (checked) => updateCurrentQuestion('isExample', !!checked) }), _jsx(Label, { htmlFor: "isExample", className: "flex items-center gap-1.5 cursor-pointer text-sm font-medium text-gray-700", children: "\u0110\u00E1nh d\u1EA5u l\u00E0 c\u00E2u h\u1ECFi Example" })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "question", className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-teal-500" }), "C\u00E2u h\u1ECFi ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: "question", value: currentQuestion.question, onChange: (e) => updateCurrentQuestion('question', e.target.value), placeholder: "Nh\u1EADp c\u00E2u h\u1ECFi... (vd: How many dolls has Lucy got?)", className: `border-gray-200 bg-white transition-all focus:border-teal-300 focus:ring-teal-200 ${validationErrors.question ? 'border-red-400 focus:border-red-500 focus:ring-red-200' : ''}` }), validationErrors.question && (_jsx("p", { className: "text-sm text-red-600", children: validationErrors.question }))] }), _jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "correctAnswer", className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(HelpCircle, { className: "h-4 w-4 text-green-500" }), "\u0110\u00E1p \u00E1n \u0111\u00FAng ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: "correctAnswer", value: currentQuestion.correctAnswer, onChange: (e) => updateCurrentQuestion('correctAnswer', e.target.value), placeholder: "Nh\u1EADp \u0111\u00E1p \u00E1n... (vd: 5 ho\u1EB7c Buster)", className: `border-gray-200 bg-white transition-all focus:border-green-300 focus:ring-green-200 ${validationErrors.correctAnswer ? 'border-red-400 focus:border-red-500 focus:ring-red-200' : ''}` }), validationErrors.correctAnswer && (_jsx("p", { className: "text-sm text-red-600", children: validationErrors.correctAnswer }))] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "prefixText", className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-gray-400" }), "Text tr\u01B0\u1EDBc \u00F4 tr\u1EA3 l\u1EDDi ", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(t\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: "prefixText", value: currentQuestion.prefixText || '', onChange: (e) => updateCurrentQuestion('prefixText', e.target.value), placeholder: "vd: There are", className: "border-gray-200 bg-white transition-all focus:border-gray-300 focus:ring-gray-200" })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "suffixText", className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-gray-400" }), "Text sau \u00F4 tr\u1EA3 l\u1EDDi ", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(t\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: "suffixText", value: currentQuestion.suffixText || '', onChange: (e) => updateCurrentQuestion('suffixText', e.target.value), placeholder: "vd: school", className: "border-gray-200 bg-white transition-all focus:border-gray-300 focus:ring-gray-200" })] })] }), hasSuggestedAnswers !== false && (_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(ListChecks, { className: "h-4 w-4 text-purple-500" }), "\u0110\u00E1p \u00E1n g\u1EE3i \u00FD ", _jsx("span", { className: "text-sm font-normal text-gray-500", children: "(t\u00F9y ch\u1ECDn)" })] }), _jsxs("div", { className: "rounded-xl border border-purple-200 bg-gradient-to-r from-purple-50 to-violet-50 p-4 space-y-3", children: [currentQuestion.suggestedAnswers && currentQuestion.suggestedAnswers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2", children: currentQuestion.suggestedAnswers.map((suggestion, index) => (_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-white border border-purple-200 px-3 py-1 text-sm font-medium text-purple-700 shadow-sm", children: [suggestion, _jsx("button", { type: "button", onClick: () => {
325
- const updated = [...(currentQuestion.suggestedAnswers || [])];
326
- updated.splice(index, 1);
327
- updateCurrentQuestion('suggestedAnswers', updated);
328
- }, className: "ml-0.5 rounded-full p-0.5 text-purple-400 hover:bg-purple-100 hover:text-purple-600 transition-colors", children: _jsx(X, { className: "h-3 w-3" }) })] }, index))) })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { id: "newSuggestedAnswer", placeholder: "Nh\u1EADp \u0111\u00E1p \u00E1n g\u1EE3i \u00FD...", className: "flex-1 border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200", onKeyDown: (e) => {
329
- if (e.key === 'Enter') {
330
- e.preventDefault();
331
- const input = e.currentTarget;
332
- const value = input.value.trim();
333
- if (value) {
334
- const current = currentQuestion.suggestedAnswers || [];
335
- updateCurrentQuestion('suggestedAnswers', [...current, value]);
336
- input.value = '';
337
- }
338
- }
339
- } }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "gap-1 border-purple-300 text-purple-600 hover:bg-purple-100 hover:text-purple-700", onClick: () => {
340
- const input = document.getElementById('newSuggestedAnswer');
341
- const value = input?.value.trim();
342
- if (value) {
343
- const current = currentQuestion.suggestedAnswers || [];
344
- updateCurrentQuestion('suggestedAnswers', [...current, value]);
345
- input.value = '';
346
- }
347
- }, children: [_jsx(Plus, { className: "h-3.5 w-3.5" }), "Th\u00EAm"] })] }), _jsx("p", { className: "text-xs text-purple-500", children: "Nh\u1EADp \u0111\u00E1p \u00E1n g\u1EE3i \u00FD r\u1ED3i nh\u1EA5n Enter ho\u1EB7c n\u00FAt Th\u00EAm" })] })] })), 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 shadow-lg shadow-amber-100/50", 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.5 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, { id: "explanation", value: explanation, onChange: (e) => setExplanation(e.target.value), placeholder: "VD: C\u00E2u tr\u1EA3 l\u1EDDi \u0111\u00FAng l\u00E0... v\u00EC...", rows: 3, className: "min-h-[80px] border-gray-200 bg-white transition-all focus:border-amber-300 focus:ring-amber-200 resize-none" }) })] })] }));
348
- }
349
- export function AnswerTheQuestionCreator(props) {
350
- return _jsx(AnswerTheQuestionContent, { ...props });
351
- }
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useState as r,useRef as s,useEffect as n}from"react";import{Button as i}from"../../../../components/ui/button";import{Label as a}from"../../../../components/ui/label";import{Input as o}from"../../../../components/ui/input";import{Textarea as l}from"../../../../components/ui/textarea";import{PointsInput as c}from"../../../../components/ui/points-input";import{Card as u,CardContent as d,CardHeader as m,CardTitle as p}from"../../../../components/ui/card";import{Pencil as g,Eye as x,HelpCircle as h,BookOpen as f,Plus as b,X as w,ListChecks as N,MessageSquare as v}from"lucide-react";import{Checkbox as y}from"../../../../components/ui/checkbox";import{AnswerTheQuestionClient as A}from"./AnswerTheQuestionClient";import{useDebouncedCallback as T}from"../../../../shared/lib/hooks";import{BasicQuestionGroupCard as q}from"../../groups/BasicQuestionGroupCard";import{useBasicQuestionGroup as C,getGroupNumberForIndex as E}from"../../_shared/hooks/useBasicQuestionGroup";function k({initialData:k,onSave:G,onSaveToQuestionBank:U,onCancel:S,onChange:I,onUnsavedChangesChange:D,externalErrors:j,groups:F,questionIndexInPart:Q=0,partId:B="",validationRef:z,suggestedAnswers:P,groupConfig:V,hasSuggestedAnswers:$,headerExtra:M}){const H=()=>k?.question?{id:`sq-${Date.now()}-imported`,question:k.question,correctAnswer:k.correctAnswer||"",suffixText:k.suffixText||"",prefixText:k.prefixText||"",points:k.points||1,groupNumber:E(Q,F),isExample:k.isExample||!1,suggestedAnswers:k.suggestedAnswers?.length?k.suggestedAnswers:P||[]}:(()=>{const e=E(Q,F);return{id:`sq-${Date.now()}-${Math.random()}`,question:"",correctAnswer:"",suffixText:"",prefixText:"",points:1,groupNumber:e,isExample:!1,suggestedAnswers:P||[]}})(),[J,K]=r(H),{isGrouped:L,currentGroupNumber:O,groupTitle:R,groupSubtitle:X,groupContent:_,imageUrl:W,setGroupTitle:Y,setGroupSubtitle:Z,setGroupContent:ee,setImageUrl:te}=C({partId:B,groups:F,questionIndexInPart:Q,initialData:{title:(()=>{const e=k?.content,t=k?.answer,r=k?.questionGroup?.payload;return t?.title||e?.passageTitle||r?.title||k?.title||""})(),subtitle:(()=>{const e=k?.content,t=k?.questionGroup?.payload;return e?.passageSubtitle||t?.subtitle||""})(),content:(()=>{const e=k?.content,t=k?.questionGroup?.payload;return k?.groupContent||t?.content||e?.passage||""})(),imageUrl:(()=>{const e=k?.content,t=k?.answer,r=k?.questionGroup?.payload;return t?.imageUrl||e?.imageUrl||r?.imageUrl||k?.imageUrl||""})()}}),[re,se]=r(!1),[ne,ie]=r(!1),[ae,oe]=r(k?.explanation||""),[le,ce]=r({}),ue=s(""),de=s(k),me=s(Q),pe=s(!1),ge=s(!1),xe=s(I),he=s(""),fe=O||J.groupNumber||1,be=s(D);n(()=>{be.current=D},[D]),n(()=>{xe.current=I},[I]);const we=T(e=>{xe.current?.(e)},300),Ne=()=>JSON.stringify({imageUrl:W,title:R,subtitle:X,question:J.question,correctAnswer:J.correctAnswer,suffixText:J.suffixText,prefixText:J.prefixText,points:J.points,isExample:J.isExample,suggestedAnswers:J.suggestedAnswers});n(()=>{if(pe.current)return;const e=setTimeout(()=>{ue.current=Ne(),ie(!1)},150);return()=>clearTimeout(e)},[Q]),n(()=>{if(pe.current)return;if(!ue.current)return;const e=Ne()!==ue.current;e!==ne&&(ie(e),be.current?.(e))},[W,J,ne]),n(()=>{z&&(z.current={triggerValidation:async()=>{const e={};let t=!0;return J.question&&""!==J.question.trim()||(e.question="Vui lòng nhập câu hỏi",t=!1),J.correctAnswer&&""!==J.correctAnswer.trim()||(e.correctAnswer="Vui lòng nhập đáp án",t=!1),ce(e),t},getFormData:()=>({imageUrl:W,title:R,subtitle:X,question:J.question,correctAnswer:J.correctAnswer,suffixText:J.suffixText,prefixText:J.prefixText,points:J.points,groupNumber:J.groupNumber,isExample:J.isExample,suggestedAnswers:J.suggestedAnswers,explanation:ae,groups:F})})},[z,J,W,R,X,ae,F]),n(()=>{const e=Q!==me.current,t=!!k?.question;if(!(!ge.current&&t)&&!e)return;pe.current=!0,de.current=k,me.current=Q,ge.current=!0;const r=E(Q,F);K({...H(),groupNumber:r}),oe(k?.explanation||""),setTimeout(()=>{pe.current=!1},100)},[k,F,Q]),n(()=>{if(pe.current)return;const e={question:J.question,correctAnswer:J.correctAnswer,suffixText:J.suffixText,prefixText:J.prefixText,points:J.points||1,groupNumber:J.groupNumber,isExample:J.isExample,suggestedAnswers:J.suggestedAnswers,imageUrl:W,title:R,subtitle:X,groupContent:_,explanation:ae,groups:F},t=JSON.stringify(e);he.current!==t&&(he.current=t,we(e))},[W,R,X,_,ae,J,F,we]);const ve=(e,t)=>{K(r=>({...r,[e]:t})),"question"===e&&le.question&&ce(e=>({...e,question:void 0})),"correctAnswer"===e&&le.correctAnswer&&ce(e=>({...e,correctAnswer:void 0}))};if(re){const r={question:J.question,correctAnswer:J.correctAnswer,suffixText:J.suffixText,prefixText:J.prefixText,points:J.points,groupNumber:J.groupNumber,isExample:J.isExample,suggestedAnswers:J.suggestedAnswers,imageUrl:W,title:R,subtitle:X};return t("div",{className:"space-y-4",children:[e(u,{children:e(m,{children:t("div",{className:"flex items-center justify-between",children:[t("div",{children:[e(p,{children:"Answer the question (Preview)"}),e("p",{className:"mt-1 text-sm text-gray-500",children:"Chế độ xem trước - Hiển thị đáp án đúng"})]}),t(i,{variant:"outline",size:"sm",onClick:()=>se(!1),children:[e(g,{className:"mr-2 h-4 w-4"}),"Quay lại Edit Mode"]})]})})}),e(A,{questionData:r,isReviewMode:!0,autoFillCorrectAnswers:!0,explanation:ae})]})}return t("div",{className:"space-y-4",children:[L&&e(q,{groupNumber:fe,title:R,subtitle:X,content:_,imageUrl:W,onTitleChange:Y,onSubtitleChange:Z,onContentChange:ee,onImageChange:te,groupConfig:V,uploadIdPrefix:`answer-the-question-${B??"group"}`}),t(u,{className:"overflow-hidden border-0 bg-white shadow-lg shadow-blue-100/50",children:[e(m,{className:"px-4 py-3",children:t("div",{className:"flex items-center justify-between",children:[t("div",{className:"flex items-center gap-2",children:[e("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-teal-500 to-cyan-600 shadow-sm",children:e(h,{className:"h-4 w-4 text-white"})}),t("div",{children:[e(p,{className:"text-base font-bold text-gray-900",children:"Đọc câu hỏi và viết đáp án"}),e("p",{className:"text-xs text-gray-500",children:"Nghe - Đọc câu hỏi và viết tên hoặc số"})]})]}),t("div",{className:"flex items-center gap-2",children:[M,t(i,{variant:"outline",size:"sm",onClick:()=>se(!0),disabled:!J.question,className:"gap-2 border-teal-200 text-teal-600 hover:bg-teal-50 hover:text-teal-700",children:[e(x,{className:"h-4 w-4"}),"Xem trước"]})]})]})}),t(d,{className:"space-y-4 px-4 pb-4",children:[t("div",{className:"flex items-center gap-6",children:[e(c,{value:J.points||1,onChange:e=>ve("points",parseFloat(e.target.value)||1)}),t("div",{className:"flex items-center gap-2",children:[e(y,{id:"isExample",checked:J.isExample||!1,onCheckedChange:e=>ve("isExample",!!e)}),e(a,{htmlFor:"isExample",className:"flex items-center gap-1.5 cursor-pointer text-sm font-medium text-gray-700",children:"Đánh dấu là câu hỏi Example"})]})]}),t("div",{className:"space-y-2",children:[t(a,{htmlFor:"question",className:"flex items-center gap-2 text-base font-semibold text-gray-800",children:[e(v,{className:"h-4 w-4 text-teal-500"}),"Câu hỏi ",e("span",{className:"text-red-500",children:"*"})]}),e(o,{id:"question",value:J.question,onChange:e=>ve("question",e.target.value),placeholder:"Nhập câu hỏi... (vd: How many dolls has Lucy got?)",className:"border-gray-200 bg-white transition-all focus:border-teal-300 focus:ring-teal-200 "+(le.question?"border-red-400 focus:border-red-500 focus:ring-red-200":"")}),le.question&&e("p",{className:"text-sm text-red-600",children:le.question})]}),t("div",{className:"space-y-2",children:[t(a,{htmlFor:"correctAnswer",className:"flex items-center gap-2 text-base font-semibold text-gray-800",children:[e(h,{className:"h-4 w-4 text-green-500"}),"Đáp án đúng ",e("span",{className:"text-red-500",children:"*"})]}),e(o,{id:"correctAnswer",value:J.correctAnswer,onChange:e=>ve("correctAnswer",e.target.value),placeholder:"Nhập đáp án... (vd: 5 hoặc Buster)",className:"border-gray-200 bg-white transition-all focus:border-green-300 focus:ring-green-200 "+(le.correctAnswer?"border-red-400 focus:border-red-500 focus:ring-red-200":"")}),le.correctAnswer&&e("p",{className:"text-sm text-red-600",children:le.correctAnswer})]}),t("div",{className:"grid grid-cols-2 gap-4",children:[t("div",{className:"space-y-2",children:[t(a,{htmlFor:"prefixText",className:"flex items-center gap-2 text-sm font-semibold text-gray-800",children:[e(v,{className:"h-4 w-4 text-gray-400"}),"Text trước ô trả lời ",e("span",{className:"text-xs font-normal text-gray-500",children:"(tùy chọn)"})]}),e(o,{id:"prefixText",value:J.prefixText||"",onChange:e=>ve("prefixText",e.target.value),placeholder:"vd: There are",className:"border-gray-200 bg-white transition-all focus:border-gray-300 focus:ring-gray-200"})]}),t("div",{className:"space-y-2",children:[t(a,{htmlFor:"suffixText",className:"flex items-center gap-2 text-sm font-semibold text-gray-800",children:[e(v,{className:"h-4 w-4 text-gray-400"}),"Text sau ô trả lời ",e("span",{className:"text-xs font-normal text-gray-500",children:"(tùy chọn)"})]}),e(o,{id:"suffixText",value:J.suffixText||"",onChange:e=>ve("suffixText",e.target.value),placeholder:"vd: school",className:"border-gray-200 bg-white transition-all focus:border-gray-300 focus:ring-gray-200"})]})]}),!1!==$&&t("div",{className:"space-y-2",children:[t(a,{className:"flex items-center gap-2 text-base font-semibold text-gray-800",children:[e(N,{className:"h-4 w-4 text-purple-500"}),"Đáp án gợi ý ",e("span",{className:"text-sm font-normal text-gray-500",children:"(tùy chọn)"})]}),t("div",{className:"rounded-xl border border-purple-200 bg-gradient-to-r from-purple-50 to-violet-50 p-4 space-y-3",children:[J.suggestedAnswers&&J.suggestedAnswers.length>0&&e("div",{className:"flex flex-wrap gap-2",children:J.suggestedAnswers.map((r,s)=>t("span",{className:"inline-flex items-center gap-1.5 rounded-full bg-white border border-purple-200 px-3 py-1 text-sm font-medium text-purple-700 shadow-sm",children:[r,e("button",{type:"button",onClick:()=>{const e=[...J.suggestedAnswers||[]];e.splice(s,1),ve("suggestedAnswers",e)},className:"ml-0.5 rounded-full p-0.5 text-purple-400 hover:bg-purple-100 hover:text-purple-600 transition-colors",children:e(w,{className:"h-3 w-3"})})]},s))}),t("div",{className:"flex items-center gap-2",children:[e(o,{id:"newSuggestedAnswer",placeholder:"Nhập đáp án gợi ý...",className:"flex-1 border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200",onKeyDown:e=>{if("Enter"===e.key){e.preventDefault();const t=e.currentTarget,r=t.value.trim();if(r){const e=J.suggestedAnswers||[];ve("suggestedAnswers",[...e,r]),t.value=""}}}}),t(i,{type:"button",variant:"outline",size:"sm",className:"gap-1 border-purple-300 text-purple-600 hover:bg-purple-100 hover:text-purple-700",onClick:()=>{const e=document.getElementById("newSuggestedAnswer"),t=e?.value.trim();if(t){const r=J.suggestedAnswers||[];ve("suggestedAnswers",[...r,t]),e.value=""}},children:[e(b,{className:"h-3.5 w-3.5"}),"Thêm"]})]}),e("p",{className:"text-xs text-purple-500",children:"Nhập đáp án gợi ý rồi nhấn Enter hoặc nút Thêm"})]})]}),j&&j.length>0&&t("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:"❌"})}),t("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:j.map((t,r)=>e("li",{children:t},r))})]})]})]})]}),t(u,{className:"overflow-hidden border-0 bg-white shadow-lg shadow-amber-100/50",children:[e(m,{className:"px-4 py-3",children:t("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(f,{className:"h-3.5 w-3.5 text-white"})}),t("div",{children:[t("div",{className:"flex items-center gap-2",children:[e(p,{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.5 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(d,{className:"px-4 pb-4",children:e(l,{id:"explanation",value:ae,onChange:e=>oe(e.target.value),placeholder:"VD: Câu trả lời đúng là... vì...",rows:3,className:"min-h-[80px] border-gray-200 bg-white transition-all focus:border-amber-300 focus:ring-amber-200 resize-none"})})]})]})}export function AnswerTheQuestionCreator(t){return e(k,{...t})}
@@ -1,67 +1 @@
1
- import { AnswerTheQuestionCreator } from './AnswerTheQuestionCreator';
2
- export const answerTheQuestionRegistration = {
3
- component: AnswerTheQuestionCreator,
4
- transformInitialData: (initialData) => {
5
- const content = initialData?.content || {};
6
- const answer = initialData?.answer || {};
7
- const explanation = initialData?.explanation || answer?.explanation || '';
8
- const apiPoints = initialData?.total_points
9
- ? parseFloat(initialData.total_points)
10
- : (initialData?.points || 1);
11
- // Extract imageUrl, title, and content from questionGroup.payload (API format) or fallback
12
- const questionGroup = initialData?.questionGroup || {};
13
- const groupPayload = questionGroup?.payload || {};
14
- const imageUrl = groupPayload?.imageUrl || answer?.imageUrl || content?.imageUrl || '';
15
- const groupTitle = groupPayload?.title || answer?.groupTitle || '';
16
- const groupContent = groupPayload?.content || answer?.groupContent || content?.passage || '';
17
- const groupNumber = questionGroup?.groupNumber || 1;
18
- // Flat format matching AnswerTheQuestionData
19
- // Supports both API format (content.question, answer.answer)
20
- // and internal onChange format (answer.question, answer.correctAnswer)
21
- return {
22
- question: content?.question || answer?.question || '',
23
- correctAnswer: answer?.answer || answer?.correctAnswer || '',
24
- suffixText: content?.suffixText || answer?.suffixText || '',
25
- prefixText: content?.prefixText || answer?.prefixText || '',
26
- points: answer?.points || apiPoints,
27
- groupNumber: answer?.groupNumber || groupNumber,
28
- isExample: initialData?.isExample || answer?.isExample || false,
29
- suggestedAnswers: initialData?.suggestedAnswers || answer?.suggestedAnswers || [],
30
- imageUrl,
31
- title: groupTitle,
32
- groupContent,
33
- explanation,
34
- groups: answer?.groups || initialData?.groups,
35
- };
36
- },
37
- getExtraProps: (ctx) => ({
38
- groups: ctx.groups,
39
- questionIndexInPart: ctx.questionIndexInPart,
40
- partId: ctx.partId,
41
- validationRef: ctx.validationRef,
42
- onUnsavedChangesChange: ctx.onUnsavedChangesChange,
43
- suggestedAnswers: ctx.suggestedAnswers,
44
- hasSuggestedAnswers: ctx.hasSuggestedAnswers,
45
- groupConfig: ctx.groupConfig,
46
- }),
47
- wrapOnSave: (data, ctx) => ({
48
- type: ctx.questionType,
49
- content: ctx.state.content,
50
- points: data?.points ?? ctx.state.points ?? 1,
51
- level: ctx.state.level,
52
- difficulty: ctx.state.difficulty,
53
- skill: ctx.state.skill,
54
- answer: data,
55
- explanation: data?.explanation || '',
56
- }),
57
- wrapOnChange: (data, ctx) => ({
58
- type: ctx.questionType,
59
- content: ctx.state.content,
60
- points: data?.points ?? ctx.state.points ?? 1,
61
- level: ctx.state.level,
62
- difficulty: ctx.state.difficulty,
63
- skill: ctx.state.skill,
64
- answer: data,
65
- explanation: data?.explanation || '',
66
- }),
67
- };
1
+ import{AnswerTheQuestionCreator as e}from"./AnswerTheQuestionCreator";export const answerTheQuestionRegistration={component:e,transformInitialData:e=>{const t=e?.content||{},s=e?.answer||{},n=e?.explanation||s?.explanation||"",o=e?.total_points?parseFloat(e.total_points):e?.points||1,a=e?.questionGroup||{},i=a?.payload||{},r=i?.imageUrl||s?.imageUrl||t?.imageUrl||"",p=i?.title||s?.groupTitle||"",l=i?.content||s?.groupContent||t?.passage||"",u=a?.groupNumber||1;return{question:t?.question||s?.question||"",correctAnswer:s?.answer||s?.correctAnswer||"",suffixText:t?.suffixText||s?.suffixText||"",prefixText:t?.prefixText||s?.prefixText||"",points:s?.points||o,groupNumber:s?.groupNumber||u,isExample:e?.isExample||s?.isExample||!1,suggestedAnswers:e?.suggestedAnswers||s?.suggestedAnswers||[],imageUrl:r,title:p,groupContent:l,explanation:n,groups:s?.groups||e?.groups}},getExtraProps:e=>({groups:e.groups,questionIndexInPart:e.questionIndexInPart,partId:e.partId,validationRef:e.validationRef,onUnsavedChangesChange:e.onUnsavedChangesChange,suggestedAnswers:e.suggestedAnswers,hasSuggestedAnswers:e.hasSuggestedAnswers,groupConfig:e.groupConfig}),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,36 +1 @@
1
- export const transformAnswerTheQuestion = (question) => {
2
- const answerData = question.answer;
3
- if (!answerData?.question) {
4
- return { apiContent: {}, apiCorrectAnswer: {} };
5
- }
6
- const apiContent = {
7
- question: answerData.question,
8
- };
9
- if (answerData.suffixText) {
10
- apiContent.suffixText = answerData.suffixText;
11
- }
12
- if (answerData.prefixText) {
13
- apiContent.prefixText = answerData.prefixText;
14
- }
15
- // Build basicGroupData when any group field is present (title, imageUrl, groupContent)
16
- const hasGroupData = !!(answerData.imageUrl || answerData.title || answerData.subtitle || answerData.groupContent);
17
- const basicGroupData = hasGroupData
18
- ? {
19
- title: answerData.title || '',
20
- subtitle: answerData.subtitle || '',
21
- content: answerData.groupContent || '',
22
- imageUrl: answerData.imageUrl || '',
23
- }
24
- : undefined;
25
- return {
26
- apiContent,
27
- apiCorrectAnswer: {
28
- answer: answerData.correctAnswer,
29
- },
30
- totalPoints: answerData.points || 1,
31
- basicGroupData,
32
- groupNumber: answerData.groupNumber || 1,
33
- isExample: answerData.isExample || false,
34
- suggestedAnswers: (answerData.suggestedAnswers && answerData.suggestedAnswers.length > 0) ? answerData.suggestedAnswers : undefined,
35
- };
36
- };
1
+ export const transformAnswerTheQuestion=e=>{const t=e.answer;if(!t?.question)return{apiContent:{},apiCorrectAnswer:{}};const s={question:t.question};t.suffixText&&(s.suffixText=t.suffixText),t.prefixText&&(s.prefixText=t.prefixText);const r=!!(t.imageUrl||t.title||t.subtitle||t.groupContent)?{title:t.title||"",subtitle:t.subtitle||"",content:t.groupContent||"",imageUrl:t.imageUrl||""}:void 0;return{apiContent:s,apiCorrectAnswer:{answer:t.correctAnswer},totalPoints:t.points||1,basicGroupData:r,groupNumber:t.groupNumber||1,isExample:t.isExample||!1,suggestedAnswers:t.suggestedAnswers&&t.suggestedAnswers.length>0?t.suggestedAnswers:void 0}};