@tinyweb_dev/oe-exam-sdk 0.1.1 → 0.1.3

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 (514) 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.d.ts +1 -1
  4. package/dist/api/exam-questions.js +1 -98
  5. package/dist/api/exam-questions.types.d.ts +45 -1
  6. package/dist/api/exam-questions.types.js +1 -1
  7. package/dist/api/exam-taking.js +1 -73
  8. package/dist/api/exam-taking.types.js +1 -1
  9. package/dist/api/index.js +1 -6
  10. package/dist/api/result-review.js +1 -50
  11. package/dist/api/result-review.types.js +1 -1
  12. package/dist/components/CueCardEditor.js +1 -58
  13. package/dist/components/common/ResolvedImage.js +1 -15
  14. package/dist/components/exams/CompletionDialog.d.ts +8 -0
  15. package/dist/components/exams/CompletionDialog.js +1 -0
  16. package/dist/components/exams/CreateExamInfoForm.d.ts +4 -1
  17. package/dist/components/exams/CreateExamInfoForm.js +1 -35
  18. package/dist/components/exams/CreateExamPageContainer.d.ts +3 -0
  19. package/dist/components/exams/CreateExamPageContainer.js +1 -103
  20. package/dist/components/exams/ExamCreator.d.ts +9 -3
  21. package/dist/components/exams/ExamCreator.js +1 -89
  22. package/dist/components/exams/ExamPartTabs.d.ts +1 -1
  23. package/dist/components/exams/ExamPartTabs.js +1 -40
  24. package/dist/components/exams/ExamPreviewDialog.d.ts +20 -0
  25. package/dist/components/exams/ExamPreviewDialog.js +1 -0
  26. package/dist/components/exams/ExamQuestionGrid.d.ts +1 -1
  27. package/dist/components/exams/ExamQuestionGrid.js +1 -18
  28. package/dist/components/exams/ExamQuestionsPageContainer.d.ts +3 -0
  29. package/dist/components/exams/ExamQuestionsPageContainer.js +1 -90
  30. package/dist/components/exams/ExamViewDialog.d.ts +24 -0
  31. package/dist/components/exams/ExamViewDialog.js +1 -0
  32. package/dist/components/exams/PartAudioUploader.js +1 -9
  33. package/dist/components/exams/TemplateSelector.js +1 -66
  34. package/dist/components/exams/UnsavedChangesDialog.d.ts +8 -0
  35. package/dist/components/exams/UnsavedChangesDialog.js +1 -0
  36. package/dist/components/exams/api.d.ts +1 -1
  37. package/dist/components/exams/api.js +1 -3
  38. package/dist/components/exams/create-exam.texts.d.ts +58 -0
  39. package/dist/components/exams/create-exam.texts.js +1 -0
  40. package/dist/components/exams/create-exam.validation.js +1 -18
  41. package/dist/components/exams/exam-question-status.d.ts +9 -0
  42. package/dist/components/exams/exam-question-status.js +1 -0
  43. package/dist/components/exams/exam-template.utils.js +1 -18
  44. package/dist/components/exams/index.d.ts +11 -1
  45. package/dist/components/exams/index.js +1 -10
  46. package/dist/components/exams/take/ExamTakingPageContainer.js +1 -153
  47. package/dist/components/exams/take/GenericQuestionRenderer.js +1 -14
  48. package/dist/components/exams/take/exam-taking.utils.js +1 -88
  49. package/dist/components/exams/take/hooks/useSpeakingRecorder.js +1 -24
  50. package/dist/components/exams/take/index.js +1 -2
  51. package/dist/components/exams/take/types.js +1 -1
  52. package/dist/components/index.js +1 -42
  53. package/dist/components/questions/_shared/config/question-types.config.js +1 -333
  54. package/dist/components/questions/_shared/constants/color-palette.js +1 -21
  55. package/dist/components/questions/_shared/hooks/useAnswerGroupQuestionGroup.js +1 -105
  56. package/dist/components/questions/_shared/hooks/useBasicQuestionGroup.js +1 -222
  57. package/dist/components/questions/_shared/hooks/useCompareImagesGroup.js +1 -140
  58. package/dist/components/questions/_shared/hooks/useImageQuestionGroup.js +1 -123
  59. package/dist/components/questions/_shared/hooks/useInfoExchangeGroup.js +1 -50
  60. package/dist/components/questions/_shared/hooks/useQuestionFormState.js +1 -54
  61. package/dist/components/questions/_shared/hooks/useQuestionInitialization.js +1 -123
  62. package/dist/components/questions/_shared/hooks/useQuestionListGroup.js +1 -121
  63. package/dist/components/questions/_shared/hooks/useQuestionOnChange.js +1 -70
  64. package/dist/components/questions/_shared/hooks/useSceneQuestionGroup.js +1 -194
  65. package/dist/components/questions/_shared/index.js +1 -7
  66. package/dist/components/questions/_shared/types/answer-the-question.type.js +1 -1
  67. package/dist/components/questions/_shared/types/arrange-letters-into-words.type.js +1 -1
  68. package/dist/components/questions/_shared/types/choose-correct-adjective.type.js +1 -3
  69. package/dist/components/questions/_shared/types/color-region.config.js +1 -1
  70. package/dist/components/questions/_shared/types/fill-in-blank.type.js +1 -1
  71. package/dist/components/questions/_shared/types/fill-missing-words-in-grid.type.js +1 -1
  72. package/dist/components/questions/_shared/types/gn-speaking-interview.type.js +1 -1
  73. package/dist/components/questions/_shared/types/index.js +1 -12
  74. package/dist/components/questions/_shared/types/label-the-picture.type.js +1 -1
  75. package/dist/components/questions/_shared/types/listen-and-choose-from-answer-group.type.js +1 -1
  76. package/dist/components/questions/_shared/types/listen-and-choose-objects-in-scene.type.js +1 -1
  77. package/dist/components/questions/_shared/types/listen-and-drag-objects-into-scene.type.js +1 -1
  78. package/dist/components/questions/_shared/types/listen-and-speak-answer.type.js +1 -1
  79. package/dist/components/questions/_shared/types/listen-and-speak-compare-images.type.js +1 -1
  80. package/dist/components/questions/_shared/types/listen-and-speak-image-group.type.js +1 -1
  81. package/dist/components/questions/_shared/types/listen-and-speak-info-exchange.type.js +1 -1
  82. package/dist/components/questions/_shared/types/listen-and-speak-odd-one-out.type.js +1 -3
  83. package/dist/components/questions/_shared/types/listen-and-speak-question-list.type.js +1 -1
  84. package/dist/components/questions/_shared/types/listen-and-speak-with-story-images.type.js +1 -3
  85. package/dist/components/questions/_shared/types/listen-and-tick-answer.type.js +1 -1
  86. package/dist/components/questions/_shared/types/listening-drawline.type.js +1 -1
  87. package/dist/components/questions/_shared/types/look-and-choose-answer.type.js +1 -1
  88. package/dist/components/questions/_shared/types/look-picture-fill-word-hint.type.js +1 -1
  89. package/dist/components/questions/_shared/types/match-by-writing-answer.type.js +1 -1
  90. package/dist/components/questions/_shared/types/multiple-choice.type.js +1 -1
  91. package/dist/components/questions/_shared/types/question-group.type.js +1 -11
  92. package/dist/components/questions/_shared/types/read-and-color-objects.type.js +1 -1
  93. package/dist/components/questions/_shared/types/read-displayed-content.type.js +1 -1
  94. package/dist/components/questions/_shared/types/read-passage-and-answer-questions.type.js +1 -1
  95. package/dist/components/questions/_shared/types/speaking-describe-image.type.js +1 -1
  96. package/dist/components/questions/_shared/types/spontaneous-qa.type.js +1 -1
  97. package/dist/components/questions/_shared/types/word-fill-paragraph-with-options.type.js +1 -1
  98. package/dist/components/questions/_shared/types/word-fill-paragraph.type.js +1 -1
  99. package/dist/components/questions/_shared/types/word-fill-structured-form.type.js +1 -1
  100. package/dist/components/questions/_shared/types/word-ordering.type.js +1 -1
  101. package/dist/components/questions/_shared/types/write-a-short-letter.type.js +1 -1
  102. package/dist/components/questions/_shared/types/write-correct-verb-form.type.js +1 -3
  103. package/dist/components/questions/_shared/types/write-sentences.type.js +1 -1
  104. package/dist/components/questions/_shared/types/write-short-paragraph.type.js +1 -1
  105. package/dist/components/questions/_shared/utils/answer-builder.js +1 -79
  106. package/dist/components/questions/_shared/utils/createColorRegionRegistration.js +1 -39
  107. package/dist/components/questions/_shared/utils/id-generator.js +1 -3
  108. package/dist/components/questions/_shared/utils/question-validation.js +1 -21
  109. package/dist/components/questions/components/ColorNode.js +1 -85
  110. package/dist/components/questions/components/ColorRegionClient.js +1 -545
  111. package/dist/components/questions/components/ColorRegionCreator.js +1 -420
  112. package/dist/components/questions/components/ColorRegionNode.js +1 -59
  113. package/dist/components/questions/components/CreatorGuide.js +1 -103
  114. package/dist/components/questions/components/NameNode.js +1 -26
  115. package/dist/components/questions/components/QuestionBankOption.js +1 -46
  116. package/dist/components/questions/components/QuestionBasicInfoForm.js +1 -9
  117. package/dist/components/questions/components/QuestionCommonFields.js +1 -33
  118. package/dist/components/questions/components/QuestionSearchDropdown.js +1 -258
  119. package/dist/components/questions/components/QuestionTypeSelector.js +1 -32
  120. package/dist/components/questions/components/QuestionTypeSpecificForms.js +1 -6
  121. package/dist/components/questions/components/RegionNode.js +1 -94
  122. package/dist/components/questions/components/index.js +1 -14
  123. package/dist/components/questions/creator/QuestionCreator.js +1 -90
  124. package/dist/components/questions/creator/QuestionGroupCreator.js +1 -119
  125. package/dist/components/questions/creator/dedicated-component-router.js +1 -79
  126. package/dist/components/questions/creator/index.js +1 -3
  127. package/dist/components/questions/creator/question-type-registry.js +1 -80
  128. package/dist/components/questions/groups/ArticlesGroupCard.js +1 -121
  129. package/dist/components/questions/groups/BasicQuestionGroupCard.js +1 -50
  130. package/dist/components/questions/groups/DocumentGroupCard.js +1 -114
  131. package/dist/components/questions/groups/MatchAnswerGroupCard.js +1 -25
  132. package/dist/components/questions/index.js +1 -10
  133. package/dist/components/questions/types/answer-the-question/AnswerTheQuestionClient.js +1 -37
  134. package/dist/components/questions/types/answer-the-question/AnswerTheQuestionCreator.js +1 -351
  135. package/dist/components/questions/types/answer-the-question/register.js +1 -67
  136. package/dist/components/questions/types/answer-the-question/transform.js +1 -36
  137. package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsClient.js +1 -141
  138. package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsCreator.js +1 -118
  139. package/dist/components/questions/types/arrange-letters-into-words/index.js +1 -2
  140. package/dist/components/questions/types/arrange-letters-into-words/register.js +1 -4
  141. package/dist/components/questions/types/arrange-letters-into-words/transform.js +1 -24
  142. package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveClient.js +1 -64
  143. package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveCreator.js +1 -169
  144. package/dist/components/questions/types/choose-correct-adjective/index.js +1 -2
  145. package/dist/components/questions/types/choose-correct-adjective/register.js +1 -55
  146. package/dist/components/questions/types/choose-correct-adjective/transform.js +1 -16
  147. package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerClient.js +1 -131
  148. package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerCreator.js +1 -581
  149. package/dist/components/questions/types/choose-the-correct-answer/index.js +1 -2
  150. package/dist/components/questions/types/choose-the-correct-answer/register.js +1 -101
  151. package/dist/components/questions/types/choose-the-correct-answer/transform.js +1 -43
  152. package/dist/components/questions/types/fill-in-blank/FillInBlankClient.js +1 -275
  153. package/dist/components/questions/types/fill-in-blank/FillInBlankCreator.js +1 -448
  154. package/dist/components/questions/types/fill-in-blank/index.js +1 -2
  155. package/dist/components/questions/types/fill-in-blank/register.js +1 -138
  156. package/dist/components/questions/types/fill-in-blank/transform.js +1 -59
  157. package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridClient.js +1 -117
  158. package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridCreator.js +1 -671
  159. package/dist/components/questions/types/fill-missing-words-in-grid/index.js +1 -2
  160. package/dist/components/questions/types/fill-missing-words-in-grid/register.js +1 -37
  161. package/dist/components/questions/types/fill-missing-words-in-grid/transform.js +1 -15
  162. package/dist/components/questions/types/gn-speaking-interview/GNSpeakingInterviewCreator.js +1 -262
  163. package/dist/components/questions/types/gn-speaking-interview/register.js +1 -121
  164. package/dist/components/questions/types/gn-speaking-interview/transform.js +1 -48
  165. package/dist/components/questions/types/image-object-matching/ImageObjectMatchingClient.js +1 -16
  166. package/dist/components/questions/types/image-object-matching/ImageObjectMatchingCreator.js +1 -27
  167. package/dist/components/questions/types/image-object-matching/index.js +1 -2
  168. package/dist/components/questions/types/image-object-matching/register.js +1 -3
  169. package/dist/components/questions/types/image-object-matching/transform.js +1 -2
  170. package/dist/components/questions/types/label-the-picture/LabelThePictureClient.js +1 -102
  171. package/dist/components/questions/types/label-the-picture/LabelThePictureCreator.js +1 -344
  172. package/dist/components/questions/types/label-the-picture/index.js +1 -2
  173. package/dist/components/questions/types/label-the-picture/register.js +1 -54
  174. package/dist/components/questions/types/label-the-picture/transform.js +1 -28
  175. package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupClient.js +1 -78
  176. package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupCreator.js +1 -232
  177. package/dist/components/questions/types/listen-and-choose-from-answer-group/index.js +1 -2
  178. package/dist/components/questions/types/listen-and-choose-from-answer-group/register.js +1 -82
  179. package/dist/components/questions/types/listen-and-choose-from-answer-group/transform.js +1 -27
  180. package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneClient.js +1 -70
  181. package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneCreator.js +1 -386
  182. package/dist/components/questions/types/listen-and-choose-objects-in-scene/index.js +1 -2
  183. package/dist/components/questions/types/listen-and-choose-objects-in-scene/register.js +1 -100
  184. package/dist/components/questions/types/listen-and-choose-objects-in-scene/transform.js +1 -33
  185. package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneClient.js +1 -106
  186. package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneCreator.js +1 -457
  187. package/dist/components/questions/types/listen-and-drag-objects-into-scene/index.js +1 -2
  188. package/dist/components/questions/types/listen-and-drag-objects-into-scene/register.js +1 -110
  189. package/dist/components/questions/types/listen-and-drag-objects-into-scene/transform.js +1 -35
  190. package/dist/components/questions/types/listen-and-speak-answer/ArrowIndicator.js +1 -8
  191. package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerClient.js +1 -22
  192. package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerCreator.js +1 -291
  193. package/dist/components/questions/types/listen-and-speak-answer/index.js +1 -2
  194. package/dist/components/questions/types/listen-and-speak-answer/register.js +1 -84
  195. package/dist/components/questions/types/listen-and-speak-answer/transform.js +1 -27
  196. package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesClient.js +1 -32
  197. package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesCreator.js +1 -295
  198. package/dist/components/questions/types/listen-and-speak-compare-images/register.js +1 -79
  199. package/dist/components/questions/types/listen-and-speak-compare-images/transform.js +1 -27
  200. package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupClient.js +1 -34
  201. package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupCreator.js +1 -285
  202. package/dist/components/questions/types/listen-and-speak-image-group/register.js +1 -81
  203. package/dist/components/questions/types/listen-and-speak-image-group/transform.js +1 -26
  204. package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeClient.js +1 -38
  205. package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeCreator.js +1 -385
  206. package/dist/components/questions/types/listen-and-speak-info-exchange/register.js +1 -87
  207. package/dist/components/questions/types/listen-and-speak-info-exchange/transform.js +1 -32
  208. package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutClient.js +1 -26
  209. package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutCreator.js +1 -247
  210. package/dist/components/questions/types/listen-and-speak-odd-one-out/register.js +1 -59
  211. package/dist/components/questions/types/listen-and-speak-odd-one-out/transform.js +1 -18
  212. package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListClient.js +1 -26
  213. package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListCreator.js +1 -256
  214. package/dist/components/questions/types/listen-and-speak-question-list/register.js +1 -81
  215. package/dist/components/questions/types/listen-and-speak-question-list/transform.js +1 -26
  216. package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesClient.js +1 -26
  217. package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesCreator.js +1 -230
  218. package/dist/components/questions/types/listen-and-speak-with-story-images/register.js +1 -56
  219. package/dist/components/questions/types/listen-and-speak-with-story-images/transform.js +1 -16
  220. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerClient.js +1 -72
  221. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerCreator.js +1 -230
  222. package/dist/components/questions/types/look-picture-choose-correct-answer/index.js +1 -1
  223. package/dist/components/questions/types/look-picture-choose-correct-answer/register.js +1 -66
  224. package/dist/components/questions/types/look-picture-choose-correct-answer/transform.js +1 -42
  225. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerClient.js +1 -96
  226. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerCreator.js +1 -238
  227. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/index.js +1 -2
  228. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/register.js +1 -76
  229. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/transform.js +1 -19
  230. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintClient.js +1 -134
  231. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintCreator.js +1 -617
  232. package/dist/components/questions/types/look-picture-fill-word-hint/index.js +1 -2
  233. package/dist/components/questions/types/look-picture-fill-word-hint/register.js +1 -82
  234. package/dist/components/questions/types/look-picture-fill-word-hint/transform.js +1 -29
  235. package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerClient.js +1 -38
  236. package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerCreator.js +1 -359
  237. package/dist/components/questions/types/match-by-writing-answer/index.js +1 -3
  238. package/dist/components/questions/types/match-by-writing-answer/register.js +1 -58
  239. package/dist/components/questions/types/match-by-writing-answer/transform.js +1 -61
  240. package/dist/components/questions/types/read-and-color-objects/ReadAndColorObjectsClient.js +1 -16
  241. package/dist/components/questions/types/read-and-color-objects/ReadAndColorObjectsCreator.js +1 -23
  242. package/dist/components/questions/types/read-and-color-objects/index.js +1 -2
  243. package/dist/components/questions/types/read-and-color-objects/register.js +1 -3
  244. package/dist/components/questions/types/read-and-color-objects/transform.js +1 -36
  245. package/dist/components/questions/types/read-displayed-content/ReadDisplayedContentCreator.js +1 -125
  246. package/dist/components/questions/types/read-displayed-content/register.js +1 -64
  247. package/dist/components/questions/types/read-displayed-content/transform.js +1 -12
  248. package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsClient.js +1 -64
  249. package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsCreator.js +1 -511
  250. package/dist/components/questions/types/read-passage-and-answer-questions/index.js +1 -2
  251. package/dist/components/questions/types/read-passage-and-answer-questions/register.js +1 -58
  252. package/dist/components/questions/types/read-passage-and-answer-questions/transform.js +1 -28
  253. package/dist/components/questions/types/speaking-conversation/SpeakingConversationCreator.js +1 -373
  254. package/dist/components/questions/types/speaking-conversation/SpeakingConversationPreviewClient.js +1 -41
  255. package/dist/components/questions/types/speaking-conversation/register.js +1 -110
  256. package/dist/components/questions/types/speaking-conversation/transform.js +1 -34
  257. package/dist/components/questions/types/speaking-cue-card/SpeakingCueCardCreator.js +1 -74
  258. package/dist/components/questions/types/speaking-cue-card/register.js +1 -52
  259. package/dist/components/questions/types/speaking-cue-card/transform.js +1 -12
  260. package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageClient.js +1 -10
  261. package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageCreator.js +1 -161
  262. package/dist/components/questions/types/speaking-describe-image/index.js +1 -2
  263. package/dist/components/questions/types/speaking-describe-image/register.js +1 -69
  264. package/dist/components/questions/types/speaking-describe-image/transform.js +1 -16
  265. package/dist/components/questions/types/spontaneous-qa/SpontaneousQACreator.js +1 -234
  266. package/dist/components/questions/types/spontaneous-qa/register.js +1 -93
  267. package/dist/components/questions/types/spontaneous-qa/transform.js +1 -34
  268. package/dist/components/questions/types/true-false/TrueFalseClient.js +1 -75
  269. package/dist/components/questions/types/true-false/TrueFalseCreator.js +1 -244
  270. package/dist/components/questions/types/true-false/index.js +1 -2
  271. package/dist/components/questions/types/true-false/register.js +1 -77
  272. package/dist/components/questions/types/true-false/transform.js +1 -32
  273. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphClient.js +1 -233
  274. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphCreator.js +1 -631
  275. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphWrapper.js +1 -28
  276. package/dist/components/questions/types/word-fill-paragraph/index.js +1 -2
  277. package/dist/components/questions/types/word-fill-paragraph/register.js +1 -136
  278. package/dist/components/questions/types/word-fill-paragraph/transform.js +1 -56
  279. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormClient.js +1 -138
  280. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormCreator.js +1 -261
  281. package/dist/components/questions/types/word-fill-structured-form/index.js +1 -2
  282. package/dist/components/questions/types/word-fill-structured-form/register.js +1 -67
  283. package/dist/components/questions/types/word-fill-structured-form/transform.js +1 -40
  284. package/dist/components/questions/types/word-ordering/WordOrderingClient.js +1 -84
  285. package/dist/components/questions/types/word-ordering/WordOrderingCreator.js +1 -192
  286. package/dist/components/questions/types/word-ordering/index.js +1 -2
  287. package/dist/components/questions/types/word-ordering/register.js +1 -46
  288. package/dist/components/questions/types/word-ordering/transform.js +1 -24
  289. package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterClient.js +1 -98
  290. package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterCreator.js +1 -320
  291. package/dist/components/questions/types/write-a-short-letter/index.js +1 -2
  292. package/dist/components/questions/types/write-a-short-letter/register.js +1 -68
  293. package/dist/components/questions/types/write-a-short-letter/transform.js +1 -25
  294. package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormClient.js +1 -61
  295. package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormCreator.js +1 -196
  296. package/dist/components/questions/types/write-correct-verb-form/index.js +1 -2
  297. package/dist/components/questions/types/write-correct-verb-form/register.js +1 -62
  298. package/dist/components/questions/types/write-correct-verb-form/transform.js +1 -17
  299. package/dist/components/questions/types/write-sentences/WriteSentencesClient.js +1 -22
  300. package/dist/components/questions/types/write-sentences/WriteSentencesCreator.js +1 -174
  301. package/dist/components/questions/types/write-sentences/index.js +1 -2
  302. package/dist/components/questions/types/write-sentences/register.js +1 -58
  303. package/dist/components/questions/types/write-sentences/transform.js +1 -28
  304. package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphClient.js +1 -96
  305. package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphCreator.js +1 -161
  306. package/dist/components/questions/types/write-short-paragraph/index.js +1 -2
  307. package/dist/components/questions/types/write-short-paragraph/register.js +1 -4
  308. package/dist/components/questions/types/write-short-paragraph/transform.js +1 -21
  309. package/dist/components/questions/viewer/QuestionGroupViewer.js +1 -36
  310. package/dist/components/questions/viewer/QuestionViewer.js +1 -446
  311. package/dist/components/questions/viewer/index.js +1 -2
  312. package/dist/components/results/ResultReviewPageContainer.js +1 -98
  313. package/dist/components/results/ReviewQuestionRenderer.js +1 -72
  314. package/dist/components/results/index.js +1 -2
  315. package/dist/components/results/result-review.utils.js +1 -6
  316. package/dist/components/results/review-data.js +1 -150
  317. package/dist/components/results/review-renderer.utils.js +1 -97
  318. package/dist/components/results/review-types.js +1 -1
  319. package/dist/components/themes/cambridge-yle/CambridgeYleAudioPlayer.js +1 -138
  320. package/dist/components/themes/cambridge-yle/CambridgeYleBottomNav.js +1 -12
  321. package/dist/components/themes/cambridge-yle/CambridgeYleExamLayout.js +1 -18
  322. package/dist/components/themes/cambridge-yle/CambridgeYleExampleText.js +1 -11
  323. package/dist/components/themes/cambridge-yle/CambridgeYleHeader.js +1 -11
  324. package/dist/components/themes/cambridge-yle/CambridgeYleInstructionBanner.js +1 -9
  325. package/dist/components/themes/cambridge-yle/CambridgeYleNavButton.js +1 -13
  326. package/dist/components/themes/cambridge-yle/CambridgeYlePartBanner.js +1 -8
  327. package/dist/components/themes/cambridge-yle/CambridgeYleProgressBar.js +1 -6
  328. package/dist/components/themes/cambridge-yle/CambridgeYleQuestionCard.js +1 -5
  329. package/dist/components/themes/cambridge-yle/CambridgeYleQuestionCardFullWidth.js +1 -9
  330. package/dist/components/themes/cambridge-yle/CambridgeYleSidebar.js +1 -41
  331. package/dist/components/themes/cambridge-yle/CambridgeYleTimer.js +1 -25
  332. package/dist/components/themes/cambridge-yle/index.js +1 -13
  333. package/dist/components/themes/english-certification/EcAnswerTheQuestion.js +1 -24
  334. package/dist/components/themes/english-certification/EcMatchByWritingAnswer.js +1 -88
  335. package/dist/components/themes/english-certification/EcWordFillParagraph.js +1 -55
  336. package/dist/components/themes/english-certification/EcWordFillStructuredForm.js +1 -156
  337. package/dist/components/themes/english-certification/EcWritingTask.js +1 -34
  338. package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.js +1 -114
  339. package/dist/components/themes/english-certification/EnglishCertificationBrand.js +1 -11
  340. package/dist/components/themes/english-certification/EnglishCertificationExamLayout.js +1 -21
  341. package/dist/components/themes/english-certification/EnglishCertificationFlagButton.js +1 -15
  342. package/dist/components/themes/english-certification/EnglishCertificationFooterBar.js +1 -19
  343. package/dist/components/themes/english-certification/EnglishCertificationGroupedQuestion.js +1 -148
  344. package/dist/components/themes/english-certification/EnglishCertificationHeader.js +1 -31
  345. package/dist/components/themes/english-certification/EnglishCertificationNavigationPanel.js +1 -71
  346. package/dist/components/themes/english-certification/EnglishCertificationOptionSelector.js +1 -33
  347. package/dist/components/themes/english-certification/EnglishCertificationPassagePanel.js +1 -16
  348. package/dist/components/themes/english-certification/EnglishCertificationQuestionCard.js +1 -22
  349. package/dist/components/themes/english-certification/EnglishCertificationQuestionItem.js +1 -37
  350. package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.js +1 -72
  351. package/dist/components/themes/english-certification/EnglishCertificationReadingSection.js +1 -90
  352. package/dist/components/themes/english-certification/EnglishCertificationSingleQuestion.js +1 -18
  353. package/dist/components/themes/english-certification/EnglishCertificationSingleQuestionList.js +1 -29
  354. package/dist/components/themes/english-certification/english-certification-theme.js +1 -58
  355. package/dist/components/themes/english-certification/grouped-question-utils.js +1 -218
  356. package/dist/components/themes/english-certification/index.js +1 -21
  357. package/dist/components/themes/index.js +1 -6
  358. package/dist/components/themes/summer-sky/SummerSkyAudioPlayer.js +1 -170
  359. package/dist/components/themes/summer-sky/SummerSkyLayout.js +1 -221
  360. package/dist/components/themes/summer-sky/SummerSkySubmitModal.js +1 -18
  361. package/dist/components/themes/summer-sky/SummerSkyWaitingRoom.js +1 -194
  362. package/dist/components/themes/types.js +1 -1
  363. package/dist/components/ui/alert-dialog.js +1 -26
  364. package/dist/components/ui/alert.js +1 -22
  365. package/dist/components/ui/avatar.js +1 -12
  366. package/dist/components/ui/badge.js +1 -38
  367. package/dist/components/ui/button.js +1 -35
  368. package/dist/components/ui/calendar.js +1 -76
  369. package/dist/components/ui/card.js +1 -16
  370. package/dist/components/ui/carousel.js +1 -91
  371. package/dist/components/ui/checkbox.js +1 -9
  372. package/dist/components/ui/collapsible.js +1 -13
  373. package/dist/components/ui/command.js +1 -34
  374. package/dist/components/ui/confirm-dialog.js +1 -49
  375. package/dist/components/ui/dialog.js +1 -23
  376. package/dist/components/ui/drawer.js +1 -35
  377. package/dist/components/ui/dropdown-menu.js +1 -33
  378. package/dist/components/ui/file-upload.js +1 -155
  379. package/dist/components/ui/form.js +1 -62
  380. package/dist/components/ui/hover-card.js +1 -10
  381. package/dist/components/ui/image-preview.js +1 -29
  382. package/dist/components/ui/input.js +1 -8
  383. package/dist/components/ui/label.js +1 -9
  384. package/dist/components/ui/language-switcher.js +1 -15
  385. package/dist/components/ui/multi-select.js +1 -90
  386. package/dist/components/ui/points-input.js +1 -33
  387. package/dist/components/ui/popover.js +1 -26
  388. package/dist/components/ui/progress.js +1 -16
  389. package/dist/components/ui/radio-group.js +1 -12
  390. package/dist/components/ui/scroll-area.js +1 -11
  391. package/dist/components/ui/select.js +1 -38
  392. package/dist/components/ui/separator.js +1 -8
  393. package/dist/components/ui/sheet.js +1 -40
  394. package/dist/components/ui/single-select.js +1 -76
  395. package/dist/components/ui/skeleton.js +1 -6
  396. package/dist/components/ui/switch.js +1 -8
  397. package/dist/components/ui/table.js +1 -20
  398. package/dist/components/ui/tabs.js +1 -17
  399. package/dist/components/ui/textarea.js +1 -8
  400. package/dist/components/ui/tooltip.js +1 -11
  401. package/dist/index.d.ts +3 -3
  402. package/dist/index.js +1 -19
  403. package/dist/mcp/config.js +1 -32
  404. package/dist/mcp/http-client.js +1 -48
  405. package/dist/mcp/index.js +1 -29
  406. package/dist/mcp/tools/_helpers.js +1 -25
  407. package/dist/mcp/tools/exams.js +1 -439
  408. package/dist/mcp/tools/index.js +1 -6
  409. package/dist/mcp/tools/results.js +1 -19
  410. package/dist/shared/constants/ApiConstant.js +1 -276
  411. package/dist/shared/constants/QueryKeyConstant.js +1 -112
  412. package/dist/shared/constants/exam-level.enum.js +1 -41
  413. package/dist/shared/constants/landings/placement-test.constants.js +1 -431
  414. package/dist/shared/constants/question-skills.js +1 -267
  415. package/dist/shared/constants/routes.js +1 -81
  416. package/dist/shared/index.d.ts +3 -0
  417. package/dist/shared/index.js +1 -7
  418. package/dist/shared/lib/hooks/index.js +1 -10
  419. package/dist/shared/lib/hooks/useAlertDialog.js +1 -57
  420. package/dist/shared/lib/hooks/useAudioPlayCounter.js +1 -30
  421. package/dist/shared/lib/hooks/useAudioPreview.js +1 -81
  422. package/dist/shared/lib/hooks/useAudioUpload.js +1 -24
  423. package/dist/shared/lib/hooks/useConfirmDialog.js +1 -89
  424. package/dist/shared/lib/hooks/useDebouncedCallback.js +1 -32
  425. package/dist/shared/lib/hooks/useDelayedAutoPlay.js +1 -12
  426. package/dist/shared/lib/hooks/useFileUpload.js +1 -24
  427. package/dist/shared/lib/hooks/useImageUrl.js +1 -5
  428. package/dist/shared/lib/hooks/usePresignedFileUrl.js +1 -10
  429. package/dist/shared/lib/hooks/useReactHookForm.js +1 -31
  430. package/dist/shared/lib/hooks/useToast.js +1 -62
  431. package/dist/shared/lib/i18n/index.js +1 -54
  432. package/dist/shared/lib/i18n/messages/en/admin.js +1 -2104
  433. package/dist/shared/lib/i18n/messages/en/auth.js +1 -86
  434. package/dist/shared/lib/i18n/messages/en/common.js +1 -140
  435. package/dist/shared/lib/i18n/messages/en/file-upload.js +1 -18
  436. package/dist/shared/lib/i18n/messages/en/student.js +1 -133
  437. package/dist/shared/lib/i18n/messages/en/terms.js +1 -37
  438. package/dist/shared/lib/i18n/messages/en.js +1 -15
  439. package/dist/shared/lib/i18n/messages/vi/admin.js +1 -2104
  440. package/dist/shared/lib/i18n/messages/vi/auth.js +1 -86
  441. package/dist/shared/lib/i18n/messages/vi/common.js +1 -140
  442. package/dist/shared/lib/i18n/messages/vi/file-upload.js +1 -18
  443. package/dist/shared/lib/i18n/messages/vi/student.js +1 -133
  444. package/dist/shared/lib/i18n/messages/vi/terms.js +1 -37
  445. package/dist/shared/lib/i18n/messages/vi.js +1 -15
  446. package/dist/shared/lib/i18n/types.js +1 -1
  447. package/dist/shared/lib/stores/examQuestionStore.js +1 -212
  448. package/dist/shared/lib/stores/localeStore.js +1 -10
  449. package/dist/shared/lib/utils/public-page.js +1 -44
  450. package/dist/shared/lib/utils/question-reverse-transform.d.ts +6 -0
  451. package/dist/shared/lib/utils/question-reverse-transform.js +1 -0
  452. package/dist/shared/lib/utils/question-transform-types.js +1 -1
  453. package/dist/shared/lib/utils/question-transform-validation.d.ts +6 -0
  454. package/dist/shared/lib/utils/question-transform-validation.js +1 -0
  455. package/dist/shared/lib/utils/question-transform.d.ts +6 -2
  456. package/dist/shared/lib/utils/question-transform.js +1 -174
  457. package/dist/shared/lib/utils.js +1 -168
  458. package/dist/shared/lib/validation/choose-correct-answer.validation.js +1 -111
  459. package/dist/shared/lib/validation/label-the-picture.validation.js +1 -19
  460. package/dist/shared/lib/validation/listen-and-choose-from-answer-group.validation.js +1 -46
  461. package/dist/shared/lib/validation/listen-and-choose-objects-in-scene.validation.js +1 -21
  462. package/dist/shared/lib/validation/listen-and-drag-objects-into-scene.validation.js +1 -34
  463. package/dist/shared/lib/validation/listen-and-speak-answer.validation.js +1 -40
  464. package/dist/shared/lib/validation/listen-and-speak-compare-images.validation.js +1 -45
  465. package/dist/shared/lib/validation/listen-and-speak-image-group.validation.js +1 -19
  466. package/dist/shared/lib/validation/listen-and-speak-info-exchange.validation.js +1 -39
  467. package/dist/shared/lib/validation/listen-and-speak-odd-one-out.validation.js +1 -32
  468. package/dist/shared/lib/validation/listen-and-speak-question-list.validation.js +1 -19
  469. package/dist/shared/lib/validation/listen-and-speak-with-story-images.validation.js +1 -28
  470. package/dist/shared/lib/validation/look-picture-choose-correct-answer.validation.js +1 -12
  471. package/dist/shared/lib/validation/look-picture-fill-blank-choose-answer.validation.js +1 -47
  472. package/dist/shared/lib/validation/read-and-color-objects.validation.js +1 -29
  473. package/dist/shared/lib/validation/read-displayed-content.validation.js +1 -28
  474. package/dist/shared/lib/validation/speaking-conversation.validation.js +1 -75
  475. package/dist/shared/lib/validation/speaking-describe-image.validation.js +1 -31
  476. package/dist/shared/lib/validation/spontaneous-qa.validation.js +1 -48
  477. package/dist/shared/lib/validation/word-fill-paragraph-default.validation.js +1 -38
  478. package/dist/shared/lib/validation/word-fill-paragraph-with-options.validation.js +1 -39
  479. package/dist/shared/lib/validation/word-fill-paragraph.validation.js +1 -43
  480. package/dist/shared/lib/validation/word-ordering.validation.js +1 -33
  481. package/dist/shared/types/branch.types.js +1 -6
  482. package/dist/shared/types/common.types.js +1 -50
  483. package/dist/shared/types/entities/exam-schedule.types.js +1 -5
  484. package/dist/shared/types/entities/exam.types.js +1 -1
  485. package/dist/shared/types/entities/question.types.js +1 -4
  486. package/dist/shared/types/entities/result.types.js +1 -4
  487. package/dist/shared/types/entities/user.types.js +1 -4
  488. package/dist/shared/types/exam-taking.types.js +1 -2
  489. package/dist/shared/types/history.types.js +1 -34
  490. package/dist/shared/types/index.js +1 -1
  491. package/dist/shared/types/questions/choose-correct-adjective.js +1 -4
  492. package/dist/shared/types/questions/choose-the-correct-answer.js +1 -9
  493. package/dist/shared/types/questions/fill-missing-words-in-grid.js +1 -11
  494. package/dist/shared/types/questions/index.js +1 -40
  495. package/dist/shared/types/questions/listen-and-speak-answer.js +1 -1
  496. package/dist/shared/types/questions/listen-and-speak-compare-images.js +1 -1
  497. package/dist/shared/types/questions/listen-and-speak-image-group.js +1 -1
  498. package/dist/shared/types/questions/listen-and-speak-info-exchange.js +1 -3
  499. package/dist/shared/types/questions/listen-and-speak-odd-one-out.js +1 -3
  500. package/dist/shared/types/questions/listen-and-speak-question-list.js +1 -1
  501. package/dist/shared/types/questions/listen-and-speak-with-story-images.js +1 -3
  502. package/dist/shared/types/questions/look-picture-choose-correct-answer.js +1 -5
  503. package/dist/shared/types/questions/look-picture-fill-blank-choose-answer.js +1 -9
  504. package/dist/shared/types/questions/look-picture-fill-word-hint.js +1 -7
  505. package/dist/shared/types/questions/read-displayed-content.js +1 -1
  506. package/dist/shared/types/questions/speaking-conversation.js +1 -7
  507. package/dist/shared/types/questions/speaking-describe-image.js +1 -1
  508. package/dist/shared/types/questions/spontaneous-qa.js +1 -1
  509. package/dist/shared/types/questions/write-correct-verb-form.js +1 -12
  510. package/dist/shared/types/role.types.js +1 -1
  511. package/dist/shared/types/structure-management.js +1 -28
  512. package/dist/shared/types/student.types.js +1 -54
  513. package/dist/shared/types/teacher-dashboard-rooms.js +1 -2
  514. package/package.json +12 -3
@@ -1,2 +1 @@
1
- export * from './ChooseTheCorrectAnswerCreator';
2
- export * from './ChooseTheCorrectAnswerClient';
1
+ export*from"./ChooseTheCorrectAnswerCreator";export*from"./ChooseTheCorrectAnswerClient";
@@ -1,101 +1 @@
1
- import { ChooseTheCorrectAnswerCreator } from './ChooseTheCorrectAnswerCreator';
2
- export const chooseTheCorrectAnswerRegistration = {
3
- component: ChooseTheCorrectAnswerCreator,
4
- transformInitialData: (initialData) => {
5
- let creatorData = initialData?.answer;
6
- const content = initialData?.content;
7
- const answer = initialData?.answer;
8
- const points = initialData?.total_points
9
- ? parseFloat(initialData.total_points)
10
- : (initialData?.points || content?.points || answer?.points || 1);
11
- const explanation = initialData?.explanation || content?.explanation || answer?.explanation || '';
12
- // Extract group info from API format
13
- const questionGroup = initialData?.questionGroup || {};
14
- const groupPayload = questionGroup?.payload || {};
15
- if (content && typeof content === 'object' && (content.question !== undefined || content.options)) {
16
- const optionsStrings = content.options || [];
17
- const rawCorrectAnswer = answer?.answer;
18
- const normalizedCorrectAnswer = Array.isArray(rawCorrectAnswer)
19
- ? rawCorrectAnswer
20
- : typeof rawCorrectAnswer === 'number'
21
- ? rawCorrectAnswer
22
- : -1;
23
- const isMultipleAnswers = Boolean(content?.multipleAnswers
24
- ?? answer?.multipleAnswers
25
- ?? initialData?.multipleAnswers
26
- ?? groupPayload?.multipleAnswers
27
- ?? Array.isArray(normalizedCorrectAnswer));
28
- creatorData = {
29
- question: content.question || '',
30
- optionType: content.optionType || 'text',
31
- options: optionsStrings,
32
- correctAnswer: normalizedCorrectAnswer,
33
- multipleAnswers: isMultipleAnswers,
34
- imageUrl: content.imageUrl || '',
35
- askerName: content.askerName || '',
36
- answererName: content.answererName || '',
37
- isExample: initialData?.isExample || answer?.isExample || false,
38
- explanation,
39
- points,
40
- // Add group stuff
41
- groupTitle: groupPayload?.title || answer?.groupTitle || '',
42
- groupContent: groupPayload?.content || answer?.groupContent || '',
43
- groupImageUrl: groupPayload?.imageUrl || answer?.groupImageUrl || content?.groupImageUrl || '',
44
- groupNumber: questionGroup.groupNumber || answer?.groupNumber || 1,
45
- articles: groupPayload?.articles || answer?.articles || undefined,
46
- };
47
- }
48
- else if (answer && typeof answer === 'object' && (answer.question !== undefined || answer.options)) {
49
- creatorData = {
50
- ...answer,
51
- multipleAnswers: Boolean(answer?.multipleAnswers ?? initialData?.multipleAnswers ?? Array.isArray(answer?.correctAnswer)),
52
- optionType: answer.optionType || content?.optionType || 'text',
53
- imageUrl: answer.imageUrl || content?.imageUrl || '',
54
- isExample: initialData?.isExample || answer?.isExample || false,
55
- explanation,
56
- points,
57
- // Add group stuff
58
- groupTitle: groupPayload?.title || answer?.groupTitle || '',
59
- groupContent: groupPayload?.content || answer?.groupContent || '',
60
- groupImageUrl: groupPayload?.imageUrl || answer?.groupImageUrl || content?.groupImageUrl || '',
61
- groupNumber: questionGroup.groupNumber || answer?.groupNumber || 1,
62
- articles: groupPayload?.articles || answer?.articles || undefined,
63
- };
64
- }
65
- return creatorData;
66
- },
67
- getExtraProps: (ctx) => ({
68
- optionCount: ctx.optionCount || 4,
69
- optionMode: ctx.optionMode,
70
- defaultValue: ctx.defaultValue,
71
- defaultQuestion: ctx.defaultQuestion,
72
- viewMode: ctx.viewMode,
73
- onUnsavedChangesChange: ctx.onUnsavedChangesChange,
74
- validationRef: ctx.validationRef,
75
- groups: ctx.groups,
76
- groupType: ctx.groupType,
77
- articleCount: ctx.articleCount,
78
- questionIndexInPart: ctx.questionIndexInPart,
79
- partId: ctx.partId,
80
- questionConfig: ctx.questionConfig,
81
- multipleAnswers: ctx.multipleAnswers,
82
- }),
83
- wrapOnSave: (data, ctx) => ({
84
- type: ctx.questionType,
85
- content: ctx.state.content,
86
- points: data?.points ?? ctx.state.points ?? 1,
87
- level: ctx.state.level,
88
- difficulty: ctx.state.difficulty,
89
- skill: ctx.state.skill,
90
- answer: data,
91
- }),
92
- wrapOnChange: (data, ctx) => ({
93
- type: ctx.questionType,
94
- content: ctx.state.content,
95
- points: data?.points ?? ctx.state.points ?? 1,
96
- level: ctx.state.level,
97
- difficulty: ctx.state.difficulty,
98
- skill: ctx.state.skill,
99
- answer: data,
100
- }),
101
- };
1
+ import{ChooseTheCorrectAnswerCreator as e}from"./ChooseTheCorrectAnswerCreator";export const chooseTheCorrectAnswerRegistration={component:e,transformInitialData:e=>{let t=e?.answer;const o=e?.content,n=e?.answer,r=e?.total_points?parseFloat(e.total_points):e?.points||o?.points||n?.points||1,i=e?.explanation||o?.explanation||n?.explanation||"",s=e?.questionGroup||{},a=s?.payload||{};if(o&&"object"==typeof o&&(void 0!==o.question||o.options)){const p=o.options||[],l=n?.answer,u=Array.isArray(l)||"number"==typeof l?l:-1,g=Boolean(o?.multipleAnswers??n?.multipleAnswers??e?.multipleAnswers??a?.multipleAnswers??Array.isArray(u));t={question:o.question||"",optionType:o.optionType||"text",options:p,correctAnswer:u,multipleAnswers:g,imageUrl:o.imageUrl||"",askerName:o.askerName||"",answererName:o.answererName||"",isExample:e?.isExample||n?.isExample||!1,explanation:i,points:r,groupTitle:a?.title||n?.groupTitle||"",groupContent:a?.content||n?.groupContent||"",groupImageUrl:a?.imageUrl||n?.groupImageUrl||o?.groupImageUrl||"",groupNumber:s.groupNumber||n?.groupNumber||1,articles:a?.articles||n?.articles||void 0}}else n&&"object"==typeof n&&(void 0!==n.question||n.options)&&(t={...n,multipleAnswers:Boolean(n?.multipleAnswers??e?.multipleAnswers??Array.isArray(n?.correctAnswer)),optionType:n.optionType||o?.optionType||"text",imageUrl:n.imageUrl||o?.imageUrl||"",isExample:e?.isExample||n?.isExample||!1,explanation:i,points:r,groupTitle:a?.title||n?.groupTitle||"",groupContent:a?.content||n?.groupContent||"",groupImageUrl:a?.imageUrl||n?.groupImageUrl||o?.groupImageUrl||"",groupNumber:s.groupNumber||n?.groupNumber||1,articles:a?.articles||n?.articles||void 0});return t},getExtraProps:e=>({optionCount:e.optionCount||4,optionMode:e.optionMode,defaultValue:e.defaultValue,defaultQuestion:e.defaultQuestion,viewMode:e.viewMode,onUnsavedChangesChange:e.onUnsavedChangesChange,validationRef:e.validationRef,groups:e.groups,groupType:e.groupType,articleCount:e.articleCount,questionIndexInPart:e.questionIndexInPart,partId:e.partId,questionConfig:e.questionConfig,multipleAnswers:e.multipleAnswers}),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}),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})};
@@ -1,43 +1 @@
1
- export const transformChooseTheCorrectAnswer = (question) => {
2
- const answerData = question.answer;
3
- if (!answerData?.options || answerData.correctAnswer === undefined) {
4
- return { apiContent: {}, apiCorrectAnswer: {} };
5
- }
6
- const apiContent = {
7
- question: answerData.question || '',
8
- optionType: answerData.optionType || 'text',
9
- options: answerData.options,
10
- ...(answerData.multipleAnswers ? { multipleAnswers: true } : {}),
11
- };
12
- // Per-question image goes into content (not group card)
13
- if (answerData.imageUrl) {
14
- apiContent.imageUrl = answerData.imageUrl;
15
- }
16
- if (answerData.askerName) {
17
- apiContent.askerName = answerData.askerName;
18
- }
19
- if (answerData.answererName) {
20
- apiContent.answererName = answerData.answererName;
21
- }
22
- // Build basicGroupData when any group field is present
23
- const hasGroupData = !!(answerData.groupTitle || answerData.groupSubtitle || answerData.groupContent || answerData.groupImageUrl || (answerData.articles && answerData.articles.length > 0));
24
- const basicGroupData = hasGroupData
25
- ? {
26
- title: answerData.groupTitle || '',
27
- subtitle: answerData.groupSubtitle || '',
28
- content: answerData.groupContent || '',
29
- imageUrl: answerData.groupImageUrl || '',
30
- ...(answerData.articles ? { articles: answerData.articles } : {}),
31
- }
32
- : undefined;
33
- return {
34
- apiContent,
35
- apiCorrectAnswer: {
36
- answer: answerData.correctAnswer,
37
- ...(answerData.multipleAnswers ? { multipleAnswers: true } : {}),
38
- },
39
- isExample: answerData.isExample || false,
40
- basicGroupData,
41
- groupNumber: answerData.groupNumber || 1,
42
- };
43
- };
1
+ export const transformChooseTheCorrectAnswer=e=>{const r=e.answer;if(!r?.options||void 0===r.correctAnswer)return{apiContent:{},apiCorrectAnswer:{}};const t={question:r.question||"",optionType:r.optionType||"text",options:r.options,...r.multipleAnswers?{multipleAnswers:!0}:{}};r.imageUrl&&(t.imageUrl=r.imageUrl),r.askerName&&(t.askerName=r.askerName),r.answererName&&(t.answererName=r.answererName);const o=!!(r.groupTitle||r.groupSubtitle||r.groupContent||r.groupImageUrl||r.articles&&r.articles.length>0)?{title:r.groupTitle||"",subtitle:r.groupSubtitle||"",content:r.groupContent||"",imageUrl:r.groupImageUrl||"",...r.articles?{articles:r.articles}:{}}:void 0;return{apiContent:t,apiCorrectAnswer:{answer:r.correctAnswer,...r.multipleAnswers?{multipleAnswers:!0}:{}},isExample:r.isExample||!1,basicGroupData:o,groupNumber:r.groupNumber||1}};
@@ -1,275 +1 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useState, useEffect, useMemo } from 'react';
4
- import { Input } from '../../../../components/ui/input';
5
- import { Check, X, PenLine, AlertTriangle, ClipboardList, Lightbulb, BookOpen, Type, Hash, } from 'lucide-react';
6
- import { cn } from '../../../../shared/lib/utils';
7
- import { usePresignedFileUrl } from '../../../../shared/lib/hooks';
8
- // Helper: Extract placeholder indices from question text
9
- function extractPlaceholderIndices(question) {
10
- const regex = /\{(\d+)\}/g;
11
- const indices = [];
12
- let match;
13
- while ((match = regex.exec(question)) !== null) {
14
- const index = parseInt(match[1], 10);
15
- if (!indices.includes(index)) {
16
- indices.push(index);
17
- }
18
- }
19
- return indices.sort((a, b) => a - b);
20
- }
21
- // Sub-component: Resolve presigned URL for group image
22
- function GroupImage({ src, alt, className }) {
23
- const { previewUrl, isLoading } = usePresignedFileUrl(src);
24
- if (isLoading) {
25
- return (_jsx("div", { className: "flex h-40 items-center justify-center", children: _jsx("div", { className: "h-6 w-6 animate-spin rounded-full border-3 border-gray-200 border-t-indigo-500" }) }));
26
- }
27
- return (
28
- /* eslint-disable-next-line @next/next/no-img-element */
29
- _jsx("img", { src: previewUrl || src, alt: alt, className: cn('max-h-72 w-auto object-contain rounded-lg drop-shadow-sm', className), onError: (e) => {
30
- const target = e.target;
31
- target.onerror = null;
32
- target.src = '/images/placeholder-image.svg';
33
- } }));
34
- }
35
- export function FillInBlankClient({ questionData, onSubmit, isReviewMode = false, userAnswer = [], autoFillCorrectAnswers = false, explanation: explanationProp, }) {
36
- // Detect if this is new format (question + answers) or legacy format (blanks array)
37
- const isLegacyFormat = !questionData.question && questionData.blanks && questionData.blanks.length > 0;
38
- const explanation = explanationProp || questionData.explanation;
39
- // Group data - resolve from multiple possible field names
40
- const isGroup = questionData.isGroup;
41
- const groupTitle = questionData.groupTitle || questionData.title || '';
42
- const groupContent = questionData.groupContent || '';
43
- const groupImageUrl = questionData.groupImageUrl || '';
44
- const groupNumber = questionData.groupNumber;
45
- const hasGroupData = isGroup && (groupTitle || groupContent || groupImageUrl);
46
- // Custom hooks for presigned URL (question-level image, not group image)
47
- const { previewUrl: imagePreviewUrl, isLoading: isImageLoading } = usePresignedFileUrl(
48
- // Only use question-level imageUrl when NOT grouped (group image is handled separately)
49
- (!isGroup && questionData.imageUrl) ? questionData.imageUrl : '');
50
- // For new format: extract placeholders from question
51
- const placeholderIndices = useMemo(() => {
52
- if (isLegacyFormat)
53
- return [];
54
- return extractPlaceholderIndices(questionData.question || '');
55
- }, [questionData.question, isLegacyFormat]);
56
- // Initialize answers based on format
57
- const getInitialAnswers = () => {
58
- if (autoFillCorrectAnswers) {
59
- if (isLegacyFormat && questionData.blanks) {
60
- return questionData.blanks.map(b => b.correctAnswer);
61
- }
62
- return questionData.answers || [];
63
- }
64
- return userAnswer || [];
65
- };
66
- const [answers, setAnswers] = useState(getInitialAnswers());
67
- // Sync userAnswer when it changes
68
- useEffect(() => {
69
- if (autoFillCorrectAnswers) {
70
- if (isLegacyFormat && questionData.blanks) {
71
- setAnswers(questionData.blanks.map(b => b.correctAnswer));
72
- }
73
- else {
74
- setAnswers(questionData.answers || []);
75
- }
76
- }
77
- else if (userAnswer) {
78
- setAnswers(userAnswer);
79
- }
80
- }, [userAnswer, autoFillCorrectAnswers, questionData, isLegacyFormat]);
81
- // Handle answer change for specific placeholder index
82
- const handleAnswerChange = (index, value) => {
83
- if (isReviewMode)
84
- return;
85
- const newAnswers = [...answers];
86
- while (newAnswers.length <= index) {
87
- newAnswers.push('');
88
- }
89
- newAnswers[index] = value;
90
- setAnswers(newAnswers);
91
- onSubmit?.(newAnswers);
92
- };
93
- // Check if answer at index is correct
94
- const isAnswerCorrect = (index, userInput) => {
95
- let correctAnswer;
96
- if (isLegacyFormat && questionData.blanks?.[index]) {
97
- correctAnswer = questionData.blanks[index].correctAnswer;
98
- }
99
- else if (questionData.answers?.[index]) {
100
- correctAnswer = questionData.answers[index];
101
- }
102
- else {
103
- return false;
104
- }
105
- const answer = userInput.trim();
106
- const correct = correctAnswer.trim();
107
- if (questionData.caseSensitive) {
108
- return answer === correct;
109
- }
110
- else {
111
- return answer.toLowerCase() === correct.toLowerCase();
112
- }
113
- };
114
- // Calculate score
115
- const calculateScore = () => {
116
- let correct = 0;
117
- let total = 0;
118
- if (isLegacyFormat && questionData.blanks) {
119
- total = questionData.blanks.length;
120
- questionData.blanks.forEach((_, idx) => {
121
- if (isAnswerCorrect(idx, answers[idx] || '')) {
122
- correct++;
123
- }
124
- });
125
- }
126
- else {
127
- total = placeholderIndices.length;
128
- placeholderIndices.forEach((idx) => {
129
- if (isAnswerCorrect(idx, answers[idx] || '')) {
130
- correct++;
131
- }
132
- });
133
- }
134
- return { correct, total };
135
- };
136
- const score = isReviewMode ? calculateScore() : null;
137
- // =====================================================
138
- // SHARED SUB-RENDERS
139
- // =====================================================
140
- /** Group Block – displayed above the question when isGroup */
141
- const renderGroupBlock = () => {
142
- if (!hasGroupData)
143
- return null;
144
- return (_jsxs("div", { className: "relative overflow-hidden rounded-2xl border border-indigo-100 bg-white shadow-sm ring-1 ring-black/5 transition-all", children: [_jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-indigo-50/80 via-white to-blue-50/30 opacity-70 pointer-events-none" }), _jsx("div", { className: "absolute left-0 top-0 bottom-0 w-1.5 bg-gradient-to-b from-indigo-500 to-blue-600 rounded-l-2xl" }), _jsxs("div", { className: "relative p-6 sm:p-7", children: [_jsxs("div", { className: "flex items-start gap-4 mb-5 border-b border-indigo-50/60 pb-4", children: [_jsx("div", { className: "flex h-11 w-11 flex-shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-indigo-100 to-blue-100 shadow-inner ring-1 ring-indigo-200/50", children: _jsx(BookOpen, { className: "h-5 w-5 text-indigo-600" }) }), _jsxs("div", { className: "flex-1 pt-1", children: [_jsxs("div", { className: "flex items-center gap-2 mb-1", children: [groupNumber && (_jsxs("span", { className: "inline-flex items-center rounded-md bg-indigo-50 px-2 py-1 text-xs font-semibold text-indigo-700 ring-1 ring-inset ring-indigo-700/10", children: ["Nh\u00F3m ", groupNumber] })), _jsx("span", { className: "inline-flex items-center rounded-md bg-orange-50 px-2 py-1 text-xs font-semibold text-orange-700 ring-1 ring-inset ring-orange-700/10", children: "\u0110i\u1EC1n v\u00E0o ch\u1ED7 tr\u1ED1ng" })] }), groupTitle && (_jsx("h4", { className: "text-xl font-bold text-slate-800 leading-tight tracking-tight", children: groupTitle }))] })] }), _jsxs("div", { className: "space-y-6 text-slate-700", children: [groupContent && (_jsx("div", { className: "prose prose-slate prose-p:leading-relaxed prose-p:mb-3 max-w-none text-[15px]", children: groupContent.split('\n').map((line, i) => (_jsx("p", { className: "last:mb-0", children: line }, i))) })), groupImageUrl && (_jsxs("div", { className: "mt-5 relative overflow-hidden rounded-xl border border-slate-200/60 bg-slate-50 shadow-sm transition-all hover:shadow-md", children: [_jsx("div", { className: "flex items-center justify-between border-b border-slate-200/60 bg-slate-100/50 px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("div", { className: "h-2.5 w-2.5 rounded-full bg-slate-300" }), _jsx("div", { className: "h-2.5 w-2.5 rounded-full bg-slate-300" }), _jsx("div", { className: "h-2.5 w-2.5 rounded-full bg-slate-300" }), _jsx("span", { className: "ml-2 text-[11px] font-semibold uppercase tracking-wider text-slate-500", children: "T\u00E0i li\u1EC7u \u0111\u00EDnh k\u00E8m" })] }) }), _jsx("div", { className: "flex items-center justify-center p-4 min-h-[160px]", children: _jsx(GroupImage, { src: groupImageUrl, alt: groupTitle || 'Hình ảnh nhóm' }) })] }))] })] })] }));
145
- };
146
- /** Render inline blanks within question text (new format) */
147
- const renderQuestionWithBlanks = () => {
148
- const question = questionData.question || '';
149
- const parts = question.split(/(\{\d+\})/g);
150
- return (_jsx("div", { className: "flex flex-wrap items-baseline gap-x-1.5 gap-y-2 leading-loose text-[15px]", children: parts.map((part, partIndex) => {
151
- const match = part.match(/\{(\d+)\}/);
152
- if (match) {
153
- const placeholderIndex = parseInt(match[1], 10);
154
- const userInput = answers[placeholderIndex] || '';
155
- const isCorrect = isReviewMode && isAnswerCorrect(placeholderIndex, userInput);
156
- const isWrong = isReviewMode && userInput && !isCorrect;
157
- return (_jsxs("span", { className: "relative inline-flex items-center mx-0.5", children: [_jsx("span", { className: "flex h-5 w-5 items-center justify-center rounded-md bg-orange-100 text-[10px] font-bold text-orange-600 mr-1 ring-1 ring-orange-200/60", children: placeholderIndex + 1 }), _jsx(Input, { value: userInput, onChange: (e) => handleAnswerChange(placeholderIndex, e.target.value), disabled: isReviewMode, className: cn('h-9 w-28 text-center text-sm font-medium rounded-lg border-2 transition-all duration-200', 'focus:ring-2 focus:ring-offset-1 focus:outline-none', isReviewMode
158
- ? isCorrect
159
- ? 'border-emerald-400 bg-emerald-50 text-emerald-700'
160
- : isWrong
161
- ? 'border-red-400 bg-red-50 text-red-700'
162
- : 'border-gray-200 bg-gray-50 text-gray-500'
163
- : 'border-orange-200 bg-white hover:border-orange-300 focus:border-orange-400 focus:ring-orange-200/50'), placeholder: "..." }), isReviewMode && (isCorrect || isWrong) && (_jsx("span", { className: cn('absolute -right-1.5 -top-1.5 flex h-4 w-4 items-center justify-center rounded-full shadow-sm ring-2 ring-white', isCorrect ? 'bg-emerald-500' : 'bg-red-500'), children: isCorrect ? (_jsx(Check, { className: "h-2.5 w-2.5 text-white" })) : (_jsx(X, { className: "h-2.5 w-2.5 text-white" })) }))] }, partIndex));
164
- }
165
- else {
166
- return (_jsx("span", { className: "text-slate-800 font-medium", children: part }, partIndex));
167
- }
168
- }) }));
169
- };
170
- /** Legacy format: render blanks array */
171
- const renderLegacyBlank = (text, _blankId, blankIndex) => {
172
- const parts = text.split(/(\{0\})/g);
173
- return (_jsx("div", { className: "flex flex-wrap items-baseline gap-x-1.5 gap-y-2 leading-loose text-[15px]", children: parts.map((part, partIdx) => {
174
- if (part === '{0}') {
175
- const userInput = answers[blankIndex] || '';
176
- const isCorrect = isReviewMode && isAnswerCorrect(blankIndex, userInput);
177
- const isWrong = isReviewMode && userInput && !isCorrect;
178
- return (_jsxs("span", { className: "relative inline-flex items-center mx-0.5", children: [_jsx(Input, { value: userInput, onChange: (e) => handleAnswerChange(blankIndex, e.target.value), disabled: isReviewMode, className: cn('h-9 w-32 text-center text-sm font-medium rounded-lg border-2 transition-all duration-200', 'focus:ring-2 focus:ring-offset-1 focus:outline-none', isReviewMode
179
- ? isCorrect
180
- ? 'border-emerald-400 bg-emerald-50 text-emerald-700'
181
- : isWrong
182
- ? 'border-red-400 bg-red-50 text-red-700'
183
- : 'border-gray-200 bg-gray-50 text-gray-500'
184
- : 'border-orange-200 bg-white hover:border-orange-300 focus:border-orange-400 focus:ring-orange-200/50'), placeholder: "..." }), isReviewMode && (isCorrect || isWrong) && (_jsx("span", { className: cn('absolute -right-1.5 -top-1.5 flex h-4 w-4 items-center justify-center rounded-full shadow-sm ring-2 ring-white', isCorrect ? 'bg-emerald-500' : 'bg-red-500'), children: isCorrect ? (_jsx(Check, { className: "h-2.5 w-2.5 text-white" })) : (_jsx(X, { className: "h-2.5 w-2.5 text-white" })) }))] }, partIdx));
185
- }
186
- else {
187
- return (_jsx("span", { className: "text-slate-800 font-medium", children: part }, partIdx));
188
- }
189
- }) }));
190
- };
191
- /** Hints pills block */
192
- const renderHints = () => {
193
- if (isReviewMode || !questionData.showHints || !questionData.hints || questionData.hints.length === 0) {
194
- return null;
195
- }
196
- return (_jsxs("div", { className: "rounded-xl border border-violet-200 bg-gradient-to-r from-violet-50/80 to-purple-50/50 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-3", children: [_jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-lg bg-violet-100 ring-1 ring-violet-200/60", children: _jsx(Lightbulb, { className: "h-3.5 w-3.5 text-violet-600" }) }), _jsx("span", { className: "text-sm font-semibold text-violet-800", children: "G\u1EE3i \u00FD \u0111\u00E1p \u00E1n" })] }), _jsx("div", { className: "flex flex-wrap gap-2", children: questionData.hints.map((hint, index) => (_jsx("span", { className: "inline-flex items-center rounded-full border border-violet-200 bg-white px-3 py-1 text-sm font-medium text-violet-700 shadow-sm transition-all hover:border-violet-300 hover:bg-violet-50 hover:shadow", children: hint }, index))) })] }));
197
- };
198
- /** Case-sensitivity warning */
199
- const renderCaseSensitiveNote = () => {
200
- if (isReviewMode || !questionData.caseSensitive)
201
- return null;
202
- return (_jsxs("div", { className: "flex items-center gap-3 rounded-xl border border-amber-200 bg-gradient-to-r from-amber-50 to-yellow-50/50 px-4 py-3", children: [_jsx("div", { className: "flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-lg bg-gradient-to-br from-amber-400 to-orange-500 text-white shadow-sm", children: _jsx(Type, { className: "h-3.5 w-3.5" }) }), _jsxs("div", { children: [_jsx("span", { className: "text-sm font-semibold text-amber-800", children: "Ph\u00E2n bi\u1EC7t hoa/th\u01B0\u1EDDng" }), _jsx("span", { className: "text-sm text-amber-700 ml-1", children: "\u2013 Vui l\u00F2ng nh\u1EADp \u0111\u00FAng ch\u1EEF hoa/th\u01B0\u1EDDng" })] })] }));
203
- };
204
- /** Explanation card (review mode only) */
205
- const renderExplanation = () => {
206
- const explText = explanation || questionData.explanation;
207
- if (!isReviewMode || !explText)
208
- return null;
209
- return (_jsxs("div", { className: "overflow-hidden rounded-xl border border-blue-200 bg-gradient-to-br from-blue-50 to-indigo-50 shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-2.5 border-b border-blue-100 bg-white/60 px-5 py-3", children: [_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-amber-400 to-orange-500 text-white shadow-sm", children: _jsx(Lightbulb, { className: "h-4 w-4" }) }), _jsx("h4", { className: "text-sm font-semibold text-slate-800", children: "Gi\u1EA3i th\u00EDch" })] }), _jsx("div", { className: "p-5", children: _jsx("p", { className: "text-sm text-slate-700 leading-relaxed", children: explText }) })] }));
210
- };
211
- /** Question-level image (non-group) */
212
- const renderQuestionImage = () => {
213
- if (isGroup)
214
- return null; // group image is rendered in group block
215
- if (!imagePreviewUrl && !questionData.imageUrl)
216
- return null;
217
- return (_jsxs("div", { className: "overflow-hidden rounded-xl border border-gray-200 bg-gradient-to-br from-slate-50 to-gray-100 shadow-sm", children: [_jsx("div", { className: "border-b border-gray-100 px-3 py-1.5", children: _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("div", { className: "h-2 w-2 rounded-full bg-red-400" }), _jsx("div", { className: "h-2 w-2 rounded-full bg-yellow-400" }), _jsx("div", { className: "h-2 w-2 rounded-full bg-green-400" }), _jsx("span", { className: "ml-2 text-xs font-medium text-gray-500", children: "H\u00ECnh \u1EA3nh" })] }) }), _jsx("div", { className: "flex items-center justify-center p-4", children: isImageLoading ? (_jsx("div", { className: "flex h-48 items-center justify-center", children: _jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-gray-200 border-t-orange-500" }) })) : (
218
- /* eslint-disable-next-line @next/next/no-img-element */
219
- _jsx("img", { src: imagePreviewUrl || questionData.imageUrl, alt: "Question illustration", className: "max-h-56 w-auto object-contain rounded-md", onError: (e) => {
220
- const target = e.target;
221
- target.onerror = null;
222
- target.src = '/images/placeholder-image.svg';
223
- } })) })] }));
224
- };
225
- // =====================================================
226
- // NEW FORMAT RENDER
227
- // =====================================================
228
- if (!isLegacyFormat) {
229
- const hasAnyAnswer = placeholderIndices.some(idx => (answers[idx] || '').trim());
230
- return (_jsxs("div", { className: "space-y-4", children: [renderGroupBlock(), _jsxs("div", { className: "overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm transition-all hover:shadow-md", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white px-5 py-3", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-orange-500 to-amber-600 text-white shadow-sm", children: _jsx(PenLine, { className: "h-4 w-4" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-semibold text-gray-700", children: "\u0110i\u1EC1n v\u00E0o ch\u1ED7 tr\u1ED1ng" }), _jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-medium text-orange-700 ring-1 ring-inset ring-orange-200/60", children: [_jsx(Hash, { className: "h-3 w-3" }), placeholderIndices.length] })] })] }), isReviewMode && score && (_jsxs("div", { className: cn('flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-bold', score.correct === score.total
231
- ? 'bg-emerald-100 text-emerald-700 ring-1 ring-emerald-200/60'
232
- : score.correct >= score.total / 2
233
- ? 'bg-yellow-100 text-yellow-700 ring-1 ring-yellow-200/60'
234
- : 'bg-red-100 text-red-700 ring-1 ring-red-200/60'), children: [score.correct === score.total && _jsx(Check, { className: "h-3 w-3" }), score.correct, "/", score.total, " \u0111\u00FAng"] }))] }), _jsxs("div", { className: "p-5 space-y-4", children: [_jsx("div", { className: "rounded-xl bg-gradient-to-r from-orange-50/80 to-amber-50/50 p-5 border border-orange-100/80", children: renderQuestionWithBlanks() }), renderQuestionImage(), renderHints(), isReviewMode && (_jsxs("div", { className: "rounded-xl border border-gray-200 bg-white overflow-hidden shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-2 border-b border-gray-100 bg-gradient-to-r from-slate-50 to-gray-50 px-4 py-2.5", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-slate-500 text-white", children: _jsx(ClipboardList, { className: "h-3 w-3" }) }), _jsx("h4", { className: "text-xs font-semibold text-gray-600 uppercase tracking-wider", children: "Chi ti\u1EBFt \u0111\u00E1p \u00E1n" })] }), _jsx("div", { className: "p-4 space-y-2.5", children: placeholderIndices.map((idx) => {
235
- const userInput = answers[idx] || '';
236
- const correctAnswer = questionData.answers?.[idx] || '';
237
- const isCorrect = isAnswerCorrect(idx, userInput);
238
- const hasInput = userInput.trim().length > 0;
239
- return (_jsxs("div", { className: cn('rounded-lg border p-3 transition-colors', isCorrect
240
- ? 'border-emerald-200 bg-emerald-50/50'
241
- : hasInput
242
- ? 'border-red-200 bg-red-50/50'
243
- : 'border-gray-100 bg-gray-50/50'), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-md bg-orange-100 text-xs font-bold text-orange-600 ring-1 ring-orange-200/60", children: idx + 1 }), _jsxs("span", { className: "text-sm text-gray-500", children: ["Ch\u1ED7 tr\u1ED1ng ", idx + 1] })] }), _jsx("div", { className: cn('flex items-center gap-1 text-xs font-semibold', isCorrect ? 'text-emerald-600' : hasInput ? 'text-red-600' : 'text-gray-400'), children: isCorrect ? (_jsxs(_Fragment, { children: [_jsx(Check, { className: "h-3.5 w-3.5" }), " \u0110\u00FAng"] })) : hasInput ? (_jsxs(_Fragment, { children: [_jsx(X, { className: "h-3.5 w-3.5" }), " Sai"] })) : ('Bỏ trống') })] }), _jsxs("div", { className: "mt-2 grid grid-cols-2 gap-2 text-sm", children: [_jsxs("div", { className: "flex items-center justify-between rounded-md bg-white px-3 py-2 border border-gray-100", children: [_jsx("span", { className: "text-gray-500 text-xs", children: "\u0110\u00E3 nh\u1EADp" }), _jsx("span", { className: cn('font-semibold', isCorrect ? 'text-emerald-600' : hasInput ? 'text-red-600' : 'text-gray-400 italic'), children: userInput || '—' })] }), _jsxs("div", { className: "flex items-center justify-between rounded-md bg-emerald-50 px-3 py-2 border border-emerald-100", children: [_jsx("span", { className: "text-gray-500 text-xs", children: "\u0110\u00E1p \u00E1n" }), _jsx("span", { className: "font-semibold text-emerald-600", children: correctAnswer })] })] })] }, idx));
244
- }) })] })), !isReviewMode && !hasAnyAnswer && (_jsxs("div", { className: "rounded-lg border border-amber-200 bg-gradient-to-r from-amber-50 to-yellow-50 p-3 flex items-center gap-2.5", children: [_jsx("div", { className: "flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-amber-400 text-white", children: _jsx(AlertTriangle, { className: "h-3 w-3" }) }), _jsx("span", { className: "text-sm text-amber-800", children: "Vui l\u00F2ng \u0111i\u1EC1n c\u00E2u tr\u1EA3 l\u1EDDi v\u00E0o c\u00E1c ch\u1ED7 tr\u1ED1ng" })] }))] })] }), renderCaseSensitiveNote(), renderExplanation()] }));
245
- }
246
- // =====================================================
247
- // LEGACY FORMAT RENDER
248
- // =====================================================
249
- return (_jsxs("div", { className: "space-y-4", children: [renderGroupBlock(), questionData.blanks?.map((blank, index) => {
250
- const userInput = answers[index] || '';
251
- const isCorrect = isReviewMode && isAnswerCorrect(index, userInput);
252
- const hasAnswered = userInput.trim() !== '';
253
- return (_jsxs("div", { className: "overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm transition-all hover:shadow-md", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white px-5 py-3", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-orange-500 to-amber-600 text-white shadow-sm", children: _jsx(PenLine, { className: "h-4 w-4" }) }), _jsxs("span", { className: "text-sm font-semibold text-gray-700", children: ["C\u00E2u ", index + 1, ": \u0110i\u1EC1n v\u00E0o ch\u1ED7 tr\u1ED1ng"] })] }), isReviewMode && hasAnswered && (_jsxs("div", { className: cn('flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-bold', isCorrect
254
- ? 'bg-emerald-100 text-emerald-700 ring-1 ring-emerald-200/60'
255
- : 'bg-red-100 text-red-700 ring-1 ring-red-200/60'), children: [isCorrect ? _jsx(Check, { className: "h-3.5 w-3.5" }) : _jsx(X, { className: "h-3.5 w-3.5" }), isCorrect ? 'Đúng' : 'Sai'] }))] }), _jsxs("div", { className: "p-5 space-y-4", children: [_jsx("div", { className: "rounded-xl bg-gradient-to-r from-orange-50/80 to-amber-50/50 p-5 border border-orange-100/80", children: renderLegacyBlank(blank.text, blank.id, index) }), index === 0 && renderQuestionImage(), index === 0 && renderHints(), isReviewMode && (_jsx("div", { className: cn('rounded-xl border p-3 transition-colors', isCorrect
256
- ? 'border-emerald-200 bg-emerald-50/50'
257
- : hasAnswered
258
- ? 'border-red-200 bg-red-50/50'
259
- : 'border-gray-100 bg-gray-50/50'), children: _jsxs("div", { className: "space-y-2.5", children: [_jsxs("div", { className: "flex items-center justify-between rounded-md bg-white p-3 border border-gray-100", children: [_jsx("span", { className: "text-sm text-gray-500", children: "\u0110\u00E3 nh\u1EADp:" }), _jsx("span", { className: cn('text-sm font-semibold', isCorrect ? 'text-emerald-600' : hasAnswered ? 'text-red-600' : 'text-gray-400 italic'), children: userInput || '—' })] }), _jsxs("div", { className: "flex items-center justify-between rounded-md bg-emerald-50 p-3 border border-emerald-100", children: [_jsx("span", { className: "text-sm text-gray-500", children: "\u0110\u00E1p \u00E1n \u0111\u00FAng:" }), _jsx("span", { className: "text-sm font-semibold text-emerald-600", children: blank.correctAnswer })] }), _jsxs("div", { className: cn('flex items-center justify-between rounded-md p-3 border', isCorrect
260
- ? 'bg-emerald-50 border-emerald-200'
261
- : 'bg-red-50 border-red-200'), children: [_jsx("span", { className: "text-sm text-gray-500", children: "K\u1EBFt qu\u1EA3:" }), _jsx("div", { className: cn('flex items-center gap-1.5 text-sm font-bold', isCorrect ? 'text-emerald-600' : 'text-red-600'), children: isCorrect ? (_jsxs(_Fragment, { children: [_jsx(Check, { className: "h-4 w-4" }), " Ch\u00EDnh x\u00E1c"] })) : (_jsxs(_Fragment, { children: [_jsx(X, { className: "h-4 w-4" }), " Sai"] })) })] })] }) })), !isReviewMode && !hasAnswered && (_jsxs("div", { className: "rounded-lg border border-amber-200 bg-gradient-to-r from-amber-50 to-yellow-50 p-3 flex items-center gap-2.5", children: [_jsx("div", { className: "flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-amber-400 text-white", children: _jsx(AlertTriangle, { className: "h-3 w-3" }) }), _jsx("span", { className: "text-sm text-amber-800", children: "Vui l\u00F2ng \u0111i\u1EC1n c\u00E2u tr\u1EA3 l\u1EDDi" })] }))] })] }, blank.id));
262
- }), renderCaseSensitiveNote(), isReviewMode && score && (questionData.blanks?.length || 0) > 1 && (_jsx("div", { className: cn('overflow-hidden rounded-xl border shadow-sm', score.correct === score.total
263
- ? 'border-emerald-200 bg-gradient-to-r from-emerald-50 to-green-50'
264
- : score.correct >= score.total / 2
265
- ? 'border-yellow-200 bg-gradient-to-r from-yellow-50 to-amber-50'
266
- : 'border-red-200 bg-gradient-to-r from-red-50 to-rose-50'), children: _jsxs("div", { className: "flex items-center justify-between px-5 py-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: cn('flex h-10 w-10 items-center justify-center rounded-xl text-white shadow-sm', score.correct === score.total
267
- ? 'bg-gradient-to-br from-emerald-500 to-green-600'
268
- : score.correct >= score.total / 2
269
- ? 'bg-gradient-to-br from-yellow-500 to-amber-600'
270
- : 'bg-gradient-to-br from-red-500 to-rose-600'), children: score.correct === score.total ? (_jsx(Check, { className: "h-5 w-5" })) : (_jsx(ClipboardList, { className: "h-5 w-5" })) }), _jsxs("div", { children: [_jsx("h4", { className: "text-sm font-semibold text-gray-800", children: "T\u1ED5ng k\u1EBFt" }), _jsx("p", { className: "text-xs text-gray-500", children: "K\u1EBFt qu\u1EA3 b\u00E0i l\u00E0m c\u1EE7a b\u1EA1n" })] })] }), _jsxs("div", { className: "text-right", children: [_jsxs("div", { className: cn('text-2xl font-bold', score.correct === score.total
271
- ? 'text-emerald-600'
272
- : score.correct >= score.total / 2
273
- ? 'text-yellow-600'
274
- : 'text-red-600'), children: [score.correct, "/", score.total] }), _jsxs("div", { className: "text-xs text-gray-500", children: [Math.round((score.correct / score.total) * 100), "% ch\u00EDnh x\u00E1c"] })] })] }) })), renderExplanation()] }));
275
- }
1
+ "use client";import{jsx as e,jsxs as r,Fragment as t}from"react/jsx-runtime";import{useState as a,useEffect as s,useMemo as l}from"react";import{Input as n}from"../../../../components/ui/input";import{Check as i,X as d,PenLine as o,AlertTriangle as c,ClipboardList as m,Lightbulb as g,BookOpen as h,Type as b,Hash as x}from"lucide-react";import{cn as f}from"../../../../shared/lib/utils";import{usePresignedFileUrl as u}from"../../../../shared/lib/hooks";function p({src:r,alt:t,className:a}){const{previewUrl:s,isLoading:l}=u(r);return l?e("div",{className:"flex h-40 items-center justify-center",children:e("div",{className:"h-6 w-6 animate-spin rounded-full border-3 border-gray-200 border-t-indigo-500"})}):e("img",{src:s||r,alt:t,className:f("max-h-72 w-auto object-contain rounded-lg drop-shadow-sm",a),onError:e=>{const r=e.target;r.onerror=null,r.src="/images/placeholder-image.svg"}})}export function FillInBlankClient({questionData:N,onSubmit:w,isReviewMode:v=!1,userAnswer:y=[],autoFillCorrectAnswers:j=!1,explanation:k}){const C=!N.question&&N.blanks&&N.blanks.length>0,q=k||N.explanation,U=N.isGroup,A=N.groupTitle||N.title||"",S=N.groupContent||"",E=N.groupImageUrl||"",I=N.groupNumber,L=U&&(A||S||E),{previewUrl:F,isLoading:G}=u(!U&&N.imageUrl?N.imageUrl:""),H=l(()=>C?[]:function(e){const r=/\{(\d+)\}/g,t=[];let a;for(;null!==(a=r.exec(e));){const e=parseInt(a[1],10);t.includes(e)||t.push(e)}return t.sort((e,r)=>e-r)}(N.question||""),[N.question,C]),[T,V]=a(j?C&&N.blanks?N.blanks.map(e=>e.correctAnswer):N.answers||[]:y||[]);s(()=>{j?C&&N.blanks?V(N.blanks.map(e=>e.correctAnswer)):V(N.answers||[]):y&&V(y)},[y,j,N,C]);const B=(e,r)=>{if(v)return;const t=[...T];for(;t.length<=e;)t.push("");t[e]=r,V(t),w?.(t)},K=(e,r)=>{let t;if(C&&N.blanks?.[e])t=N.blanks[e].correctAnswer;else{if(!N.answers?.[e])return!1;t=N.answers[e]}const a=r.trim(),s=t.trim();return N.caseSensitive?a===s:a.toLowerCase()===s.toLowerCase()},M=v?(()=>{let e=0,r=0;return C&&N.blanks?(r=N.blanks.length,N.blanks.forEach((r,t)=>{K(t,T[t]||"")&&e++})):(r=H.length,H.forEach(r=>{K(r,T[r]||"")&&e++})),{correct:e,total:r}})():null,D=()=>L?r("div",{className:"relative overflow-hidden rounded-2xl border border-indigo-100 bg-white shadow-sm ring-1 ring-black/5 transition-all",children:[e("div",{className:"absolute inset-0 bg-gradient-to-br from-indigo-50/80 via-white to-blue-50/30 opacity-70 pointer-events-none"}),e("div",{className:"absolute left-0 top-0 bottom-0 w-1.5 bg-gradient-to-b from-indigo-500 to-blue-600 rounded-l-2xl"}),r("div",{className:"relative p-6 sm:p-7",children:[r("div",{className:"flex items-start gap-4 mb-5 border-b border-indigo-50/60 pb-4",children:[e("div",{className:"flex h-11 w-11 flex-shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-indigo-100 to-blue-100 shadow-inner ring-1 ring-indigo-200/50",children:e(h,{className:"h-5 w-5 text-indigo-600"})}),r("div",{className:"flex-1 pt-1",children:[r("div",{className:"flex items-center gap-2 mb-1",children:[I&&r("span",{className:"inline-flex items-center rounded-md bg-indigo-50 px-2 py-1 text-xs font-semibold text-indigo-700 ring-1 ring-inset ring-indigo-700/10",children:["Nhóm ",I]}),e("span",{className:"inline-flex items-center rounded-md bg-orange-50 px-2 py-1 text-xs font-semibold text-orange-700 ring-1 ring-inset ring-orange-700/10",children:"Điền vào chỗ trống"})]}),A&&e("h4",{className:"text-xl font-bold text-slate-800 leading-tight tracking-tight",children:A})]})]}),r("div",{className:"space-y-6 text-slate-700",children:[S&&e("div",{className:"prose prose-slate prose-p:leading-relaxed prose-p:mb-3 max-w-none text-[15px]",children:S.split("\n").map((r,t)=>e("p",{className:"last:mb-0",children:r},t))}),E&&r("div",{className:"mt-5 relative overflow-hidden rounded-xl border border-slate-200/60 bg-slate-50 shadow-sm transition-all hover:shadow-md",children:[e("div",{className:"flex items-center justify-between border-b border-slate-200/60 bg-slate-100/50 px-4 py-2",children:r("div",{className:"flex items-center gap-1.5",children:[e("div",{className:"h-2.5 w-2.5 rounded-full bg-slate-300"}),e("div",{className:"h-2.5 w-2.5 rounded-full bg-slate-300"}),e("div",{className:"h-2.5 w-2.5 rounded-full bg-slate-300"}),e("span",{className:"ml-2 text-[11px] font-semibold uppercase tracking-wider text-slate-500",children:"Tài liệu đính kèm"})]})}),e("div",{className:"flex items-center justify-center p-4 min-h-[160px]",children:e(p,{src:E,alt:A||"Hình ảnh nhóm"})})]})]})]})]}):null,P=()=>{const t=(N.question||"").split(/(\{\d+\})/g);return e("div",{className:"flex flex-wrap items-baseline gap-x-1.5 gap-y-2 leading-loose text-[15px]",children:t.map((t,a)=>{const s=t.match(/\{(\d+)\}/);if(s){const t=parseInt(s[1],10),l=T[t]||"",o=v&&K(t,l),c=v&&l&&!o;return r("span",{className:"relative inline-flex items-center mx-0.5",children:[e("span",{className:"flex h-5 w-5 items-center justify-center rounded-md bg-orange-100 text-[10px] font-bold text-orange-600 mr-1 ring-1 ring-orange-200/60",children:t+1}),e(n,{value:l,onChange:e=>B(t,e.target.value),disabled:v,className:f("h-9 w-28 text-center text-sm font-medium rounded-lg border-2 transition-all duration-200","focus:ring-2 focus:ring-offset-1 focus:outline-none",v?o?"border-emerald-400 bg-emerald-50 text-emerald-700":c?"border-red-400 bg-red-50 text-red-700":"border-gray-200 bg-gray-50 text-gray-500":"border-orange-200 bg-white hover:border-orange-300 focus:border-orange-400 focus:ring-orange-200/50"),placeholder:"..."}),v&&(o||c)&&e("span",{className:f("absolute -right-1.5 -top-1.5 flex h-4 w-4 items-center justify-center rounded-full shadow-sm ring-2 ring-white",o?"bg-emerald-500":"bg-red-500"),children:e(o?i:d,{className:"h-2.5 w-2.5 text-white"})})]},a)}return e("span",{className:"text-slate-800 font-medium",children:t},a)})})},Q=(t,a,s)=>{const l=t.split(/(\{0\})/g);return e("div",{className:"flex flex-wrap items-baseline gap-x-1.5 gap-y-2 leading-loose text-[15px]",children:l.map((t,a)=>{if("{0}"===t){const t=T[s]||"",l=v&&K(s,t),o=v&&t&&!l;return r("span",{className:"relative inline-flex items-center mx-0.5",children:[e(n,{value:t,onChange:e=>B(s,e.target.value),disabled:v,className:f("h-9 w-32 text-center text-sm font-medium rounded-lg border-2 transition-all duration-200","focus:ring-2 focus:ring-offset-1 focus:outline-none",v?l?"border-emerald-400 bg-emerald-50 text-emerald-700":o?"border-red-400 bg-red-50 text-red-700":"border-gray-200 bg-gray-50 text-gray-500":"border-orange-200 bg-white hover:border-orange-300 focus:border-orange-400 focus:ring-orange-200/50"),placeholder:"..."}),v&&(l||o)&&e("span",{className:f("absolute -right-1.5 -top-1.5 flex h-4 w-4 items-center justify-center rounded-full shadow-sm ring-2 ring-white",l?"bg-emerald-500":"bg-red-500"),children:e(l?i:d,{className:"h-2.5 w-2.5 text-white"})})]},a)}return e("span",{className:"text-slate-800 font-medium",children:t},a)})})},R=()=>!v&&N.showHints&&N.hints&&0!==N.hints.length?r("div",{className:"rounded-xl border border-violet-200 bg-gradient-to-r from-violet-50/80 to-purple-50/50 p-4",children:[r("div",{className:"flex items-center gap-2 mb-3",children:[e("div",{className:"flex h-6 w-6 items-center justify-center rounded-lg bg-violet-100 ring-1 ring-violet-200/60",children:e(g,{className:"h-3.5 w-3.5 text-violet-600"})}),e("span",{className:"text-sm font-semibold text-violet-800",children:"Gợi ý đáp án"})]}),e("div",{className:"flex flex-wrap gap-2",children:N.hints.map((r,t)=>e("span",{className:"inline-flex items-center rounded-full border border-violet-200 bg-white px-3 py-1 text-sm font-medium text-violet-700 shadow-sm transition-all hover:border-violet-300 hover:bg-violet-50 hover:shadow",children:r},t))})]}):null,z=()=>v||!N.caseSensitive?null:r("div",{className:"flex items-center gap-3 rounded-xl border border-amber-200 bg-gradient-to-r from-amber-50 to-yellow-50/50 px-4 py-3",children:[e("div",{className:"flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-lg bg-gradient-to-br from-amber-400 to-orange-500 text-white shadow-sm",children:e(b,{className:"h-3.5 w-3.5"})}),r("div",{children:[e("span",{className:"text-sm font-semibold text-amber-800",children:"Phân biệt hoa/thường"}),e("span",{className:"text-sm text-amber-700 ml-1",children:"– Vui lòng nhập đúng chữ hoa/thường"})]})]}),J=()=>{const t=q||N.explanation;return v&&t?r("div",{className:"overflow-hidden rounded-xl border border-blue-200 bg-gradient-to-br from-blue-50 to-indigo-50 shadow-sm",children:[r("div",{className:"flex items-center gap-2.5 border-b border-blue-100 bg-white/60 px-5 py-3",children:[e("div",{className:"flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-amber-400 to-orange-500 text-white shadow-sm",children:e(g,{className:"h-4 w-4"})}),e("h4",{className:"text-sm font-semibold text-slate-800",children:"Giải thích"})]}),e("div",{className:"p-5",children:e("p",{className:"text-sm text-slate-700 leading-relaxed",children:t})})]}):null},O=()=>U?null:F||N.imageUrl?r("div",{className:"overflow-hidden rounded-xl border border-gray-200 bg-gradient-to-br from-slate-50 to-gray-100 shadow-sm",children:[e("div",{className:"border-b border-gray-100 px-3 py-1.5",children:r("div",{className:"flex items-center gap-1.5",children:[e("div",{className:"h-2 w-2 rounded-full bg-red-400"}),e("div",{className:"h-2 w-2 rounded-full bg-yellow-400"}),e("div",{className:"h-2 w-2 rounded-full bg-green-400"}),e("span",{className:"ml-2 text-xs font-medium text-gray-500",children:"Hình ảnh"})]})}),e("div",{className:"flex items-center justify-center p-4",children:G?e("div",{className:"flex h-48 items-center justify-center",children:e("div",{className:"h-8 w-8 animate-spin rounded-full border-4 border-gray-200 border-t-orange-500"})}):e("img",{src:F||N.imageUrl,alt:"Question illustration",className:"max-h-56 w-auto object-contain rounded-md",onError:e=>{const r=e.target;r.onerror=null,r.src="/images/placeholder-image.svg"}})})]}):null;if(!C){const a=H.some(e=>(T[e]||"").trim());return r("div",{className:"space-y-4",children:[D(),r("div",{className:"overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm transition-all hover:shadow-md",children:[r("div",{className:"flex items-center justify-between border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white px-5 py-3",children:[r("div",{className:"flex items-center gap-3",children:[e("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-orange-500 to-amber-600 text-white shadow-sm",children:e(o,{className:"h-4 w-4"})}),r("div",{className:"flex items-center gap-2",children:[e("span",{className:"text-sm font-semibold text-gray-700",children:"Điền vào chỗ trống"}),r("span",{className:"inline-flex items-center gap-1 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-medium text-orange-700 ring-1 ring-inset ring-orange-200/60",children:[e(x,{className:"h-3 w-3"}),H.length]})]})]}),v&&M&&r("div",{className:f("flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-bold",M.correct===M.total?"bg-emerald-100 text-emerald-700 ring-1 ring-emerald-200/60":M.correct>=M.total/2?"bg-yellow-100 text-yellow-700 ring-1 ring-yellow-200/60":"bg-red-100 text-red-700 ring-1 ring-red-200/60"),children:[M.correct===M.total&&e(i,{className:"h-3 w-3"}),M.correct,"/",M.total," đúng"]})]}),r("div",{className:"p-5 space-y-4",children:[e("div",{className:"rounded-xl bg-gradient-to-r from-orange-50/80 to-amber-50/50 p-5 border border-orange-100/80",children:P()}),O(),R(),v&&r("div",{className:"rounded-xl border border-gray-200 bg-white overflow-hidden shadow-sm",children:[r("div",{className:"flex items-center gap-2 border-b border-gray-100 bg-gradient-to-r from-slate-50 to-gray-50 px-4 py-2.5",children:[e("div",{className:"flex h-5 w-5 items-center justify-center rounded-full bg-slate-500 text-white",children:e(m,{className:"h-3 w-3"})}),e("h4",{className:"text-xs font-semibold text-gray-600 uppercase tracking-wider",children:"Chi tiết đáp án"})]}),e("div",{className:"p-4 space-y-2.5",children:H.map(a=>{const s=T[a]||"",l=N.answers?.[a]||"",n=K(a,s),o=s.trim().length>0;return r("div",{className:f("rounded-lg border p-3 transition-colors",n?"border-emerald-200 bg-emerald-50/50":o?"border-red-200 bg-red-50/50":"border-gray-100 bg-gray-50/50"),children:[r("div",{className:"flex items-center justify-between",children:[r("div",{className:"flex items-center gap-2",children:[e("span",{className:"flex h-6 w-6 items-center justify-center rounded-md bg-orange-100 text-xs font-bold text-orange-600 ring-1 ring-orange-200/60",children:a+1}),r("span",{className:"text-sm text-gray-500",children:["Chỗ trống ",a+1]})]}),e("div",{className:f("flex items-center gap-1 text-xs font-semibold",n?"text-emerald-600":o?"text-red-600":"text-gray-400"),children:n?r(t,{children:[e(i,{className:"h-3.5 w-3.5"})," Đúng"]}):o?r(t,{children:[e(d,{className:"h-3.5 w-3.5"})," Sai"]}):"Bỏ trống"})]}),r("div",{className:"mt-2 grid grid-cols-2 gap-2 text-sm",children:[r("div",{className:"flex items-center justify-between rounded-md bg-white px-3 py-2 border border-gray-100",children:[e("span",{className:"text-gray-500 text-xs",children:"Đã nhập"}),e("span",{className:f("font-semibold",n?"text-emerald-600":o?"text-red-600":"text-gray-400 italic"),children:s||"—"})]}),r("div",{className:"flex items-center justify-between rounded-md bg-emerald-50 px-3 py-2 border border-emerald-100",children:[e("span",{className:"text-gray-500 text-xs",children:"Đáp án"}),e("span",{className:"font-semibold text-emerald-600",children:l})]})]})]},a)})})]}),!v&&!a&&r("div",{className:"rounded-lg border border-amber-200 bg-gradient-to-r from-amber-50 to-yellow-50 p-3 flex items-center gap-2.5",children:[e("div",{className:"flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-amber-400 text-white",children:e(c,{className:"h-3 w-3"})}),e("span",{className:"text-sm text-amber-800",children:"Vui lòng điền câu trả lời vào các chỗ trống"})]})]})]}),z(),J()]})}return r("div",{className:"space-y-4",children:[D(),N.blanks?.map((a,s)=>{const l=T[s]||"",n=v&&K(s,l),m=""!==l.trim();return r("div",{className:"overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm transition-all hover:shadow-md",children:[r("div",{className:"flex items-center justify-between border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white px-5 py-3",children:[r("div",{className:"flex items-center gap-3",children:[e("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-orange-500 to-amber-600 text-white shadow-sm",children:e(o,{className:"h-4 w-4"})}),r("span",{className:"text-sm font-semibold text-gray-700",children:["Câu ",s+1,": Điền vào chỗ trống"]})]}),v&&m&&r("div",{className:f("flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-bold",n?"bg-emerald-100 text-emerald-700 ring-1 ring-emerald-200/60":"bg-red-100 text-red-700 ring-1 ring-red-200/60"),children:[e(n?i:d,{className:"h-3.5 w-3.5"}),n?"Đúng":"Sai"]})]}),r("div",{className:"p-5 space-y-4",children:[e("div",{className:"rounded-xl bg-gradient-to-r from-orange-50/80 to-amber-50/50 p-5 border border-orange-100/80",children:Q(a.text,a.id,s)}),0===s&&O(),0===s&&R(),v&&e("div",{className:f("rounded-xl border p-3 transition-colors",n?"border-emerald-200 bg-emerald-50/50":m?"border-red-200 bg-red-50/50":"border-gray-100 bg-gray-50/50"),children:r("div",{className:"space-y-2.5",children:[r("div",{className:"flex items-center justify-between rounded-md bg-white p-3 border border-gray-100",children:[e("span",{className:"text-sm text-gray-500",children:"Đã nhập:"}),e("span",{className:f("text-sm font-semibold",n?"text-emerald-600":m?"text-red-600":"text-gray-400 italic"),children:l||"—"})]}),r("div",{className:"flex items-center justify-between rounded-md bg-emerald-50 p-3 border border-emerald-100",children:[e("span",{className:"text-sm text-gray-500",children:"Đáp án đúng:"}),e("span",{className:"text-sm font-semibold text-emerald-600",children:a.correctAnswer})]}),r("div",{className:f("flex items-center justify-between rounded-md p-3 border",n?"bg-emerald-50 border-emerald-200":"bg-red-50 border-red-200"),children:[e("span",{className:"text-sm text-gray-500",children:"Kết quả:"}),e("div",{className:f("flex items-center gap-1.5 text-sm font-bold",n?"text-emerald-600":"text-red-600"),children:r(t,n?{children:[e(i,{className:"h-4 w-4"})," Chính xác"]}:{children:[e(d,{className:"h-4 w-4"})," Sai"]})})]})]})}),!v&&!m&&r("div",{className:"rounded-lg border border-amber-200 bg-gradient-to-r from-amber-50 to-yellow-50 p-3 flex items-center gap-2.5",children:[e("div",{className:"flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-amber-400 text-white",children:e(c,{className:"h-3 w-3"})}),e("span",{className:"text-sm text-amber-800",children:"Vui lòng điền câu trả lời"})]})]})]},a.id)}),z(),v&&M&&(N.blanks?.length||0)>1&&e("div",{className:f("overflow-hidden rounded-xl border shadow-sm",M.correct===M.total?"border-emerald-200 bg-gradient-to-r from-emerald-50 to-green-50":M.correct>=M.total/2?"border-yellow-200 bg-gradient-to-r from-yellow-50 to-amber-50":"border-red-200 bg-gradient-to-r from-red-50 to-rose-50"),children:r("div",{className:"flex items-center justify-between px-5 py-4",children:[r("div",{className:"flex items-center gap-3",children:[e("div",{className:f("flex h-10 w-10 items-center justify-center rounded-xl text-white shadow-sm",M.correct===M.total?"bg-gradient-to-br from-emerald-500 to-green-600":M.correct>=M.total/2?"bg-gradient-to-br from-yellow-500 to-amber-600":"bg-gradient-to-br from-red-500 to-rose-600"),children:M.correct===M.total?e(i,{className:"h-5 w-5"}):e(m,{className:"h-5 w-5"})}),r("div",{children:[e("h4",{className:"text-sm font-semibold text-gray-800",children:"Tổng kết"}),e("p",{className:"text-xs text-gray-500",children:"Kết quả bài làm của bạn"})]})]}),r("div",{className:"text-right",children:[r("div",{className:f("text-2xl font-bold",M.correct===M.total?"text-emerald-600":M.correct>=M.total/2?"text-yellow-600":"text-red-600"),children:[M.correct,"/",M.total]}),r("div",{className:"text-xs text-gray-500",children:[Math.round(M.correct/M.total*100),"% chính xác"]})]})]})}),J()]})}