@tinyweb_dev/oe-exam-sdk 1.0.6 → 1.0.8

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 (239) hide show
  1. package/dist/components/exams/ExamCreator.js +1 -16
  2. package/dist/components/exams/take/ExamTakingPageContainer.js +0 -12
  3. package/dist/components/exams/take/components/QuestionRenderer.js +2 -15
  4. package/dist/components/exams/take/components/question-renderers/index.d.ts +0 -3
  5. package/dist/components/exams/take/components/question-renderers/index.js +0 -3
  6. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.js +0 -4
  7. package/dist/components/exams/take/types/speaking.types.d.ts +0 -31
  8. package/dist/components/exams/take/types.d.ts +0 -65
  9. package/dist/components/exams/take/utils/answer-transformers.js +6 -60
  10. package/dist/components/exams/take/utils/question-transformers.d.ts +2 -15
  11. package/dist/components/exams/take/utils/question-transformers.js +0 -143
  12. package/dist/components/questions/_shared/components/compact/CompactCreatorHeader.d.ts +23 -0
  13. package/dist/components/questions/_shared/components/compact/CompactCreatorHeader.js +9 -0
  14. package/dist/components/questions/_shared/components/compact/CompactExampleToggle.d.ts +6 -0
  15. package/dist/components/questions/_shared/components/compact/CompactExampleToggle.js +8 -0
  16. package/dist/components/questions/_shared/components/compact/CompactExplanationToggle.d.ts +7 -0
  17. package/dist/components/questions/_shared/components/compact/CompactExplanationToggle.js +14 -0
  18. package/dist/components/questions/_shared/components/compact/CompactFieldCard.d.ts +9 -0
  19. package/dist/components/questions/_shared/components/compact/CompactFieldCard.js +7 -0
  20. package/dist/components/questions/_shared/components/compact/CompactPreviewBanner.d.ts +7 -0
  21. package/dist/components/questions/_shared/components/compact/CompactPreviewBanner.js +7 -0
  22. package/dist/components/questions/_shared/components/compact/CompactPreviewButton.d.ts +6 -0
  23. package/dist/components/questions/_shared/components/compact/CompactPreviewButton.js +7 -0
  24. package/dist/components/questions/_shared/components/compact/index.d.ts +6 -0
  25. package/dist/components/questions/_shared/components/compact/index.js +6 -0
  26. package/dist/components/questions/_shared/config/question-types.config.js +0 -24
  27. package/dist/components/questions/_shared/hooks/useQuestionInitialization.js +0 -9
  28. package/dist/components/questions/_shared/types/choose-the-correct-answer-group.type.d.ts +2 -2
  29. package/dist/components/questions/_shared/types/choose-the-correct-answer-group.type.js +5 -1
  30. package/dist/components/questions/_shared/types/index.d.ts +0 -1
  31. package/dist/components/questions/_shared/types/index.js +0 -1
  32. package/dist/components/questions/_shared/types/look-and-choose-answer.type.d.ts +0 -13
  33. package/dist/components/questions/_shared/utils/answer-builder.js +0 -11
  34. package/dist/components/questions/components/ColorRegionCreator.js +66 -63
  35. package/dist/components/questions/components/QuestionSearchDropdown.js +0 -8
  36. package/dist/components/questions/components/QuestionTypeSelector.js +0 -2
  37. package/dist/components/questions/components/index.d.ts +1 -0
  38. package/dist/components/questions/components/index.js +1 -0
  39. package/dist/components/questions/creator/question-type-registry.js +0 -8
  40. package/dist/components/questions/groups/ArticlesGroupCard.js +2 -2
  41. package/dist/components/questions/groups/BasicQuestionGroupCard.js +1 -1
  42. package/dist/components/questions/groups/DocumentGroupCard.js +1 -1
  43. package/dist/components/questions/groups/ImageLabelGroupCard.js +1 -1
  44. package/dist/components/questions/groups/MatchAnswerGroupCard.js +2 -2
  45. package/dist/components/questions/question-bank/QuestionEditorRenderer.d.ts +0 -3
  46. package/dist/components/questions/question-bank/QuestionEditorRenderer.js +1 -10
  47. package/dist/components/questions/question-bank/editor-adapters/choice-adapters.d.ts +0 -2
  48. package/dist/components/questions/question-bank/editor-adapters/choice-adapters.js +0 -41
  49. package/dist/components/questions/question-bank/editor-adapters/index.d.ts +2 -2
  50. package/dist/components/questions/question-bank/editor-adapters/index.js +2 -2
  51. package/dist/components/questions/question-bank/editor-adapters/media-adapters.d.ts +0 -1
  52. package/dist/components/questions/question-bank/editor-adapters/media-adapters.js +0 -28
  53. package/dist/components/questions/question-bank/question-bank-picker.utils.js +0 -7
  54. package/dist/components/questions/types/answer-the-question/AnswerTheQuestionClient.js +16 -16
  55. package/dist/components/questions/types/answer-the-question/AnswerTheQuestionCreator.js +36 -30
  56. package/dist/components/questions/types/answer-the-question-group/AnswerTheQuestionGroupClient.js +1 -1
  57. package/dist/components/questions/types/answer-the-question-group/AnswerTheQuestionGroupCreator.js +7 -6
  58. package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsClient.js +2 -2
  59. package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsCreator.js +11 -7
  60. package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveClient.js +1 -1
  61. package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveCreator.js +11 -5
  62. package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerClient.js +5 -5
  63. package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerCreator.js +34 -28
  64. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseAnswerGroupImageUpload.d.ts +7 -0
  65. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseAnswerGroupImageUpload.js +5 -2
  66. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupClient.js +9 -5
  67. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupCreator.js +65 -62
  68. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupItemEditor.d.ts +6 -0
  69. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupItemEditor.js +145 -0
  70. package/dist/components/questions/types/choose-the-correct-answer-group/map-choose-the-correct-answer-group-data.js +6 -15
  71. package/dist/components/questions/types/choose-the-correct-answer-group/transform.js +5 -4
  72. package/dist/components/questions/types/choose-then-answer-group/ChooseThenAnswerGroupClient.js +7 -7
  73. package/dist/components/questions/types/choose-then-answer-group/ChooseThenAnswerGroupCreator.js +8 -5
  74. package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupClient.js +2 -2
  75. package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupCreator.js +20 -16
  76. package/dist/components/questions/types/crossword-puzzle/CrosswordPuzzleClient.js +1 -1
  77. package/dist/components/questions/types/crossword-puzzle/CrosswordPuzzleCreator.js +66 -29
  78. package/dist/components/questions/types/fill-in-blank/FillInBlankClient.js +5 -5
  79. package/dist/components/questions/types/fill-in-blank/FillInBlankCreator.js +45 -37
  80. package/dist/components/questions/types/fill-in-blank-group/FillInBlankGroupCreator.js +24 -20
  81. package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridClient.js +2 -2
  82. package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridCreator.js +68 -65
  83. package/dist/components/questions/types/find-words-in-matrix/FindWordsInMatrixClient.js +1 -1
  84. package/dist/components/questions/types/find-words-in-matrix/FindWordsInMatrixCreator.js +45 -5
  85. package/dist/components/questions/types/label-the-picture/LabelThePictureClient.js +2 -2
  86. package/dist/components/questions/types/label-the-picture/LabelThePictureCreator.js +18 -14
  87. package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupClient.js +2 -2
  88. package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupCreator.js +30 -30
  89. package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneClient.js +2 -2
  90. package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneCreator.js +24 -31
  91. package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneClient.js +2 -2
  92. package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneCreator.js +29 -32
  93. package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerClient.js +1 -1
  94. package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerCreator.js +27 -29
  95. package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesClient.js +1 -1
  96. package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesCreator.js +11 -15
  97. package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupClient.js +1 -1
  98. package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupCreator.js +22 -24
  99. package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeClient.js +1 -1
  100. package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeCreator.js +17 -24
  101. package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutClient.js +1 -1
  102. package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutCreator.js +31 -31
  103. package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListClient.js +1 -1
  104. package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListCreator.js +11 -15
  105. package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesClient.js +1 -1
  106. package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesCreator.js +14 -15
  107. package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerClient.js +2 -2
  108. package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerCreator.js +27 -25
  109. package/dist/components/questions/types/match-columns-to-make-sentences/MatchColumnsToMakeSentencesClient.js +12 -12
  110. package/dist/components/questions/types/match-columns-to-make-sentences/MatchColumnsToMakeSentencesCreator.js +8 -5
  111. package/dist/components/questions/types/match-word-to-picture/MatchWordToPictureClient.js +8 -8
  112. package/dist/components/questions/types/match-word-to-picture/MatchWordToPictureCreator.js +25 -20
  113. package/dist/components/questions/types/match-word-to-picture-group/MatchWordToPictureGroupClient.js +1 -1
  114. package/dist/components/questions/types/match-word-to-picture-group/MatchWordToPictureGroupCreator.js +13 -10
  115. package/dist/components/questions/types/matching-with-lines-group/MatchingWithLinesGroupCreator.js +8 -5
  116. package/dist/components/questions/types/read-displayed-content/ReadDisplayedContentCreator.js +7 -11
  117. package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsClient.js +1 -1
  118. package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsCreator.js +15 -12
  119. package/dist/components/questions/types/sort-words-into-categories/SortWordsIntoCategoriesClient.js +1 -1
  120. package/dist/components/questions/types/sort-words-into-categories/SortWordsIntoCategoriesCreator.js +5 -5
  121. package/dist/components/questions/types/speaking-conversation/SpeakingConversationCreator.js +35 -39
  122. package/dist/components/questions/types/speaking-conversation/SpeakingConversationPreviewClient.js +2 -2
  123. package/dist/components/questions/types/speaking-cue-card/SpeakingCueCardClient.js +1 -1
  124. package/dist/components/questions/types/speaking-cue-card/SpeakingCueCardCreator.js +7 -8
  125. package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageClient.js +1 -1
  126. package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageCreator.js +30 -23
  127. package/dist/components/questions/types/spontaneous-qa/SpontaneousQAClient.js +1 -1
  128. package/dist/components/questions/types/spontaneous-qa/SpontaneousQACreator.js +26 -19
  129. package/dist/components/questions/types/spontaneous-qa-group/SpontaneousQaGroupClient.d.ts +1 -1
  130. package/dist/components/questions/types/spontaneous-qa-group/SpontaneousQaGroupClient.js +79 -3
  131. package/dist/components/questions/types/spontaneous-qa-group/SpontaneousQaGroupCreator.js +13 -11
  132. package/dist/components/questions/types/spontaneous-qa-group/index.d.ts +1 -0
  133. package/dist/components/questions/types/spontaneous-qa-group/index.js +1 -0
  134. package/dist/components/questions/types/spontaneous-qa-group/map-spontaneous-qa-group-data.d.ts +2 -0
  135. package/dist/components/questions/types/spontaneous-qa-group/map-spontaneous-qa-group-data.js +74 -0
  136. package/dist/components/questions/types/true-false/TrueFalseClient.js +2 -2
  137. package/dist/components/questions/types/true-false/TrueFalseCreator.js +35 -29
  138. package/dist/components/questions/types/true-false-correct-group/TrueFalseCorrectGroupClient.js +1 -1
  139. package/dist/components/questions/types/true-false-correct-group/TrueFalseCorrectGroupCreator.js +11 -7
  140. package/dist/components/questions/types/true-false-group/TrueFalseGroupClient.js +1 -1
  141. package/dist/components/questions/types/true-false-group/TrueFalseGroupCreator.js +11 -7
  142. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphClient.js +2 -2
  143. package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphCreator.js +21 -56
  144. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormClient.js +1 -1
  145. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormCreator.js +30 -24
  146. package/dist/components/questions/types/word-order-and-match-group/WordOrderAndMatchGroupClient.js +3 -3
  147. package/dist/components/questions/types/word-order-and-match-group/WordOrderAndMatchGroupCreator.js +12 -14
  148. package/dist/components/questions/types/word-ordering/WordOrderingClient.js +1 -1
  149. package/dist/components/questions/types/word-ordering/WordOrderingCreator.js +27 -18
  150. package/dist/components/questions/types/word-ordering-group/WordOrderingGroupClient.js +7 -7
  151. package/dist/components/questions/types/word-ordering-group/WordOrderingGroupCreator.js +16 -13
  152. package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterClient.js +2 -2
  153. package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterCreator.js +34 -28
  154. package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormClient.js +2 -2
  155. package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormCreator.js +22 -22
  156. package/dist/components/questions/types/write-sentences/WriteSentencesCreator.js +21 -18
  157. package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphClient.js +1 -1
  158. package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphCreator.js +7 -4
  159. package/dist/components/questions/viewer/QuestionViewer.js +0 -98
  160. package/dist/components/questions/viewer/SpontaneousQaGroupViewer.js +4 -79
  161. package/dist/components/results/renderers/review-question-body-movers.js +2 -26
  162. package/dist/components/results/review-data.js +0 -4
  163. package/dist/components/ui/points-input.d.ts +1 -0
  164. package/dist/components/ui/points-input.js +12 -2
  165. package/dist/shared/constants/question-skills.js +0 -11
  166. package/dist/shared/lib/i18n/messages/en/admin.d.ts +0 -3
  167. package/dist/shared/lib/i18n/messages/en/admin.js +0 -3
  168. package/dist/shared/lib/i18n/messages/en.d.ts +0 -3
  169. package/dist/shared/lib/i18n/messages/vi/admin.d.ts +0 -3
  170. package/dist/shared/lib/i18n/messages/vi/admin.js +0 -3
  171. package/dist/shared/lib/i18n/messages/vi.d.ts +0 -3
  172. package/dist/shared/lib/utils/question-reverse-transform.js +4 -23
  173. package/dist/shared/lib/utils/question-transform-types.d.ts +1 -23
  174. package/dist/shared/lib/utils/question-transform-validation.js +0 -40
  175. package/dist/shared/lib/utils/question-transform.js +0 -9
  176. package/dist/shared/types/common.types.d.ts +1 -1
  177. package/dist/shared/types/entities/question.types.d.ts +1 -11
  178. package/dist/shared/types/questions/choose-the-correct-answer-group.d.ts +1 -1
  179. package/dist/shared/types/questions/index.d.ts +0 -3
  180. package/dist/shared/types/questions/index.js +0 -6
  181. package/package.json +1 -1
  182. package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.d.ts +0 -2
  183. package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.js +0 -131
  184. package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.d.ts +0 -2
  185. package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.js +0 -76
  186. package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.d.ts +0 -2
  187. package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.js +0 -68
  188. package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.d.ts +0 -16
  189. package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.js +0 -212
  190. package/dist/components/questions/_shared/types/gn-speaking-interview.type.d.ts +0 -32
  191. package/dist/components/questions/_shared/types/gn-speaking-interview.type.js +0 -1
  192. package/dist/components/questions/_shared/types/look-picture-fill-word-hint.type.d.ts +0 -47
  193. package/dist/components/questions/_shared/types/look-picture-fill-word-hint.type.js +0 -1
  194. package/dist/components/questions/types/gn-speaking-interview/GNSpeakingInterviewCreator.d.ts +0 -2
  195. package/dist/components/questions/types/gn-speaking-interview/GNSpeakingInterviewCreator.js +0 -262
  196. package/dist/components/questions/types/gn-speaking-interview/register.d.ts +0 -2
  197. package/dist/components/questions/types/gn-speaking-interview/register.js +0 -121
  198. package/dist/components/questions/types/gn-speaking-interview/transform.d.ts +0 -2
  199. package/dist/components/questions/types/gn-speaking-interview/transform.js +0 -48
  200. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerClient.d.ts +0 -20
  201. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerClient.js +0 -72
  202. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerCreator.d.ts +0 -15
  203. package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerCreator.js +0 -230
  204. package/dist/components/questions/types/look-picture-choose-correct-answer/index.d.ts +0 -1
  205. package/dist/components/questions/types/look-picture-choose-correct-answer/index.js +0 -1
  206. package/dist/components/questions/types/look-picture-choose-correct-answer/register.d.ts +0 -2
  207. package/dist/components/questions/types/look-picture-choose-correct-answer/register.js +0 -66
  208. package/dist/components/questions/types/look-picture-choose-correct-answer/transform.d.ts +0 -2
  209. package/dist/components/questions/types/look-picture-choose-correct-answer/transform.js +0 -42
  210. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerClient.d.ts +0 -6
  211. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerClient.js +0 -96
  212. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerCreator.d.ts +0 -15
  213. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerCreator.js +0 -238
  214. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/index.d.ts +0 -2
  215. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/index.js +0 -2
  216. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/register.d.ts +0 -2
  217. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/register.js +0 -76
  218. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/transform.d.ts +0 -2
  219. package/dist/components/questions/types/look-picture-fill-blank-choose-answer/transform.js +0 -19
  220. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintClient.d.ts +0 -7
  221. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintClient.js +0 -134
  222. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintCreator.d.ts +0 -3
  223. package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintCreator.js +0 -617
  224. package/dist/components/questions/types/look-picture-fill-word-hint/index.d.ts +0 -2
  225. package/dist/components/questions/types/look-picture-fill-word-hint/index.js +0 -2
  226. package/dist/components/questions/types/look-picture-fill-word-hint/register.d.ts +0 -2
  227. package/dist/components/questions/types/look-picture-fill-word-hint/register.js +0 -82
  228. package/dist/components/questions/types/look-picture-fill-word-hint/transform.d.ts +0 -2
  229. package/dist/components/questions/types/look-picture-fill-word-hint/transform.js +0 -29
  230. package/dist/shared/lib/validation/look-picture-choose-correct-answer.validation.d.ts +0 -9
  231. package/dist/shared/lib/validation/look-picture-choose-correct-answer.validation.js +0 -12
  232. package/dist/shared/lib/validation/look-picture-fill-blank-choose-answer.validation.d.ts +0 -17
  233. package/dist/shared/lib/validation/look-picture-fill-blank-choose-answer.validation.js +0 -47
  234. package/dist/shared/types/questions/look-picture-choose-correct-answer.d.ts +0 -38
  235. package/dist/shared/types/questions/look-picture-choose-correct-answer.js +0 -5
  236. package/dist/shared/types/questions/look-picture-fill-blank-choose-answer.d.ts +0 -63
  237. package/dist/shared/types/questions/look-picture-fill-blank-choose-answer.js +0 -9
  238. package/dist/shared/types/questions/look-picture-fill-word-hint.d.ts +0 -57
  239. package/dist/shared/types/questions/look-picture-fill-word-hint.js +0 -7
@@ -107,7 +107,7 @@ export function DocumentGroupCard({ groupNumber, title, subtitle = '', content,
107
107
  const showImage = !hasConfig || groupConfig.includes('imageUrl');
108
108
  const { previewUrl } = usePresignedFileUrl(imageUrl);
109
109
  const displayPreviewUrl = previewUrl || '';
110
- return (_jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-lg shadow-indigo-100/50", children: [_jsx("div", { className: "h-1.5 bg-gradient-to-r from-indigo-500 via-violet-500 to-purple-500" }), _jsx(CardHeader, { className: "pb-4", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-indigo-500 to-violet-600 shadow-md", children: _jsx(Layers, { className: "h-5 w-5 text-white" }) }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CardTitle, { className: "text-lg font-bold text-gray-900", children: "\u0110o\u1EA1n v\u0103n nh\u00F3m" }), _jsxs("span", { className: "inline-flex items-center rounded-full border border-indigo-300 bg-indigo-100 px-2.5 py-0.5 text-xs font-semibold text-indigo-700", children: ["Nh\u00F3m ", groupNumber] })] }), _jsxs("p", { className: "text-sm text-gray-500", children: ["N\u1ED9i dung \u0111\u1ECBnh d\u1EA1ng phong ph\u00FA \u2014 d\u00F9ng chung cho t\u1EA5t c\u1EA3 c\u00E2u h\u1ECFi trong Nh\u00F3m ", groupNumber] })] })] }) }), _jsxs(CardContent, { className: "space-y-5", children: [showTitle && (_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: `${uploadIdPrefix}-title`, className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(Type, { className: "h-4 w-4 text-indigo-500" }), "Ti\u00EAu \u0111\u1EC1 nh\u00F3m", ' ', _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(T\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: `${uploadIdPrefix}-title`, value: title, onChange: (e) => { if (!isReadOnly)
110
+ return (_jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-sm", children: [_jsx(CardHeader, { className: "px-3 py-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-gray-100", children: _jsx(Layers, { className: "h-3.5 w-3.5 text-gray-600" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CardTitle, { className: "text-sm font-bold text-gray-900", children: "\u0110o\u1EA1n v\u0103n nh\u00F3m" }), _jsxs("span", { className: "inline-flex items-center rounded-md border border-gray-200 bg-gray-50 px-2 py-0.5 text-xs font-semibold text-gray-600", children: ["Nh\u00F3m ", groupNumber] })] })] }) }), _jsxs(CardContent, { className: "space-y-2.5 px-3 pb-3", children: [showTitle && (_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: `${uploadIdPrefix}-title`, className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(Type, { className: "h-4 w-4 text-indigo-500" }), "Ti\u00EAu \u0111\u1EC1 nh\u00F3m", ' ', _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(T\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: `${uploadIdPrefix}-title`, value: title, onChange: (e) => { if (!isReadOnly)
111
111
  onTitleChange(e.target.value); }, readOnly: isReadOnly, placeholder: "Nh\u1EADp ti\u00EAu \u0111\u1EC1 nh\u00F3m c\u00E2u h\u1ECFi\u2026", className: `border-gray-200 bg-white transition-all focus:border-indigo-300 focus:ring-indigo-200 ${isReadOnly ? 'cursor-not-allowed border-transparent bg-gray-50 text-gray-500 focus:border-transparent focus:ring-0' : ''}` })] })), showSubtitle && (_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: `${uploadIdPrefix}-subtitle`, className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(Pilcrow, { className: "h-4 w-4 text-indigo-500" }), "Ph\u1EE5 \u0111\u1EC1", ' ', _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(T\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: `${uploadIdPrefix}-subtitle`, value: subtitle, onChange: (e) => { if (!isReadOnly)
112
112
  onSubtitleChange?.(e.target.value); }, readOnly: isReadOnly, placeholder: "Nh\u1EADp ph\u1EE5 \u0111\u1EC1 ho\u1EB7c m\u00F4 t\u1EA3 ng\u1EAFn\u2026", className: `border-gray-200 bg-white transition-all focus:border-indigo-300 focus:ring-indigo-200 ${isReadOnly ? 'cursor-not-allowed border-transparent bg-gray-50 text-gray-500 focus:border-transparent focus:ring-0' : ''}` })] })), showContent && (_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(FileText, { className: "h-4 w-4 text-indigo-500" }), "N\u1ED9i dung \u0111o\u1EA1n v\u0103n", ' ', _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(T\u00F9y ch\u1ECDn)" })] }), _jsx(DocumentEditor, { value: content, onChange: onContentChange, isReadOnly: isReadOnly, placeholder: "Nh\u1EADp \u0111o\u1EA1n v\u0103n, email, th\u00F4ng b\u00E1o, qu\u1EA3ng c\u00E1o\u2026 d\u00F9ng chung cho nh\u00F3m c\u00E2u h\u1ECFi n\u00E0y", uploadIdPrefix: uploadIdPrefix }), !isReadOnly && (_jsxs("div", { className: "flex items-start gap-2.5 rounded-lg border border-amber-200 bg-amber-50 px-3.5 py-2.5", children: [_jsx(Info, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-500" }), _jsxs("div", { className: "text-xs text-amber-800 leading-relaxed", children: [_jsx("span", { className: "font-semibold", children: "G\u1EE3i \u00FD (ch\u1EC9 d\u00E0nh cho d\u1EA1ng \u0111i\u1EC1n t\u1EEB):" }), ' ', "N\u1EBFu \u0111o\u1EA1n v\u0103n c\u00F3 kho\u1EA3ng tr\u1ED1ng c\u1EA7n \u0111i\u1EC1n, h\u00E3y \u0111\u00E1nh d\u1EA5u b\u1EB1ng", ' ', _jsx("code", { className: "rounded bg-amber-100 px-1 py-0.5 font-mono font-semibold text-amber-700", children: '{0}' }), ",", ' ', _jsx("code", { className: "rounded bg-amber-100 px-1 py-0.5 font-mono font-semibold text-amber-700", children: '{1}' }), ",", ' ', _jsx("code", { className: "rounded bg-amber-100 px-1 py-0.5 font-mono font-semibold text-amber-700", children: '{2}' }), "\u2026 \u2014 m\u1ED7i s\u1ED1 t\u01B0\u01A1ng \u1EE9ng th\u1EE9 t\u1EF1 c\u00E2u h\u1ECFi trong nh\u00F3m. V\u1EDBi d\u1EA1ng b\u00E0i \u0111\u1ECDc th\u00F4ng th\u01B0\u1EDDng, b\u1EA1n kh\u00F4ng c\u1EA7n d\u00F9ng k\u00FD hi\u1EC7u n\u00E0y."] })] }))] })), showImage && (_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(ImageIcon, { className: "h-4 w-4 text-indigo-500" }), "H\u00ECnh \u1EA3nh nh\u00F3m", ' ', _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(T\u00F9y ch\u1ECDn)" })] }), !isReadOnly && (_jsx(FileUpload, { id: `${uploadIdPrefix}-image`, label: "", accept: "image/*", value: imageUrl, onChange: (url) => { if (!isReadOnly)
113
113
  onImageChange(url); }, onPresignedUrlChange: onImagePresignedUrlChange, maxSize: 5, placeholder: "Upload \u1EA3nh ho\u1EB7c paste URL", autoUpload: true, prefix: "questions" })), displayPreviewUrl && (_jsx(ImagePreview, { src: displayPreviewUrl, alt: "Group image preview", className: "mt-2 h-48 w-full max-w-md rounded-lg border border-gray-200" }))] }))] })] }));
@@ -38,5 +38,5 @@ export function ImageLabelGroupCard({ groupNumber, imageLabels, onImageLabelsCha
38
38
  return;
39
39
  onImageLabelsChange(displayItems.filter((_, i) => i !== index));
40
40
  };
41
- return (_jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-lg shadow-indigo-100/50", children: [_jsx("div", { className: "h-1.5 bg-gradient-to-r from-indigo-500 via-blue-500 to-sky-500" }), _jsx(CardHeader, { className: "pb-4", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-indigo-500 to-blue-600 shadow-md", children: _jsx(Layers, { className: "h-5 w-5 text-white" }) }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(CardTitle, { className: "text-lg font-bold text-gray-900", children: "Ng\u00E2n h\u00E0ng \u1EA3nh + t\u1EEB" }), _jsxs("span", { className: "inline-flex items-center rounded-full border border-indigo-300 bg-indigo-100 px-2.5 py-0.5 text-xs font-semibold text-indigo-700", children: ["Nh\u00F3m ", groupNumber] }), _jsxs("span", { className: "inline-flex items-center rounded-full border border-blue-200 bg-blue-50 px-2.5 py-0.5 text-xs font-medium text-blue-600", children: [displayItems.length, " m\u1EE5c"] })] }), _jsx("p", { className: "text-sm text-gray-500", children: "M\u1ED7i m\u1EE5c g\u1ED3m 1 h\u00ECnh v\u00E0 1 nh\u00E3n \u2014 h\u1ECDc sinh th\u1EA5y h\u00E0ng \u1EA3nh + t\u1EEB ph\u00EDa tr\u00EAn c\u00E2u h\u1ECFi." })] })] }) }), _jsxs(CardContent, { className: "space-y-5", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: `${uploadIdPrefix}-title`, className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(Type, { className: "h-4 w-4 text-indigo-500" }), "Ti\u00EAu \u0111\u1EC1 nh\u00F3m", ' ', _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(T\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: `${uploadIdPrefix}-title`, value: title, onChange: (e) => onTitleChange?.(e.target.value), placeholder: "VD: Words from the box", readOnly: isReadOnly, className: `border-gray-200 bg-white transition-all focus:border-indigo-300 focus:ring-indigo-200 ${isReadOnly ? 'cursor-not-allowed border-transparent bg-gray-50 text-gray-500 focus:border-transparent focus:ring-0' : ''}` })] }), _jsx("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3", children: displayItems.map((item, index) => (_jsxs("div", { className: "rounded-xl border-2 border-gray-200 bg-gradient-to-b from-slate-50 to-white p-3 transition-all hover:border-indigo-200 hover:shadow-sm", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsxs("span", { className: "text-xs font-semibold text-gray-600", children: ["M\u1EE5c ", index + 1] }), displayItems.length > 1 && !isReadOnly && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => handleDelete(index), className: "h-7 w-7 p-0 text-red-500 hover:bg-red-50 hover:text-red-600", title: "X\u00F3a m\u1EE5c", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }))] }), _jsxs("div", { className: "space-y-2.5", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsxs(Label, { htmlFor: `${uploadIdPrefix}-label-${index}`, className: "flex items-center gap-1.5 text-xs font-medium text-gray-700", children: [_jsx(Type, { className: "h-3.5 w-3.5 text-indigo-500" }), "Nh\u00E3n"] }), _jsx(Input, { id: `${uploadIdPrefix}-label-${index}`, value: item.label, onChange: (e) => handleFieldChange(index, 'label', e.target.value), placeholder: "VD: swimming", readOnly: isReadOnly, className: `border-gray-200 bg-white text-sm focus:border-indigo-300 focus:ring-indigo-200 ${isReadOnly ? 'cursor-not-allowed bg-gray-50 text-gray-500' : ''}` })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsxs(Label, { className: "flex items-center gap-1.5 text-xs font-medium text-gray-700", children: [_jsx(ImageIcon, { className: "h-3.5 w-3.5 text-indigo-500" }), "H\u00ECnh \u1EA3nh"] }), !isReadOnly && (_jsx(FileUpload, { id: `${uploadIdPrefix}-image-${index}`, label: "", accept: "image/*", value: item.imageUrl, onChange: (url) => handleFieldChange(index, 'imageUrl', url), maxSize: 5, placeholder: "Upload \u1EA3nh", autoUpload: true, prefix: "questions" })), item.imageUrl && (_jsx(ItemImagePreview, { src: item.imageUrl, alt: item.label || `Item ${index + 1}` }))] })] })] }, index))) }), !isReadOnly && (_jsxs(Button, { type: "button", variant: "outline", className: "w-full border-dashed border-indigo-300 bg-indigo-50/50 text-indigo-700 hover:border-indigo-400 hover:bg-indigo-50 hover:text-indigo-800", onClick: handleAdd, children: [_jsx(PlusCircle, { className: "mr-2 h-4 w-4" }), "Th\u00EAm m\u1EE5c \u1EA3nh + t\u1EEB"] })), _jsxs("div", { className: "rounded-xl border border-indigo-100 bg-indigo-50/40 p-4", children: [_jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-indigo-600", children: "Xem tr\u01B0\u1EDBc h\u00E0ng t\u1EEB" }), _jsx(ImageLabelWordBank, { items: displayItems })] })] })] }));
41
+ return (_jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-sm", children: [_jsx(CardHeader, { className: "px-3 py-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-gray-100", children: _jsx(Layers, { className: "h-3.5 w-3.5 text-gray-600" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CardTitle, { className: "text-sm font-bold text-gray-900", children: "Ng\u00E2n h\u00E0ng \u1EA3nh + t\u1EEB" }), _jsxs("span", { className: "inline-flex items-center rounded-md border border-gray-200 bg-gray-50 px-2 py-0.5 text-xs font-semibold text-gray-600", children: ["Nh\u00F3m ", groupNumber] }), _jsxs("span", { className: "inline-flex items-center rounded-md border border-blue-200 bg-blue-50 px-2 py-0.5 text-xs font-medium text-blue-600", children: [displayItems.length, " m\u1EE5c"] })] })] }) }), _jsxs(CardContent, { className: "space-y-2.5 px-3 pb-3", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: `${uploadIdPrefix}-title`, className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(Type, { className: "h-4 w-4 text-indigo-500" }), "Ti\u00EAu \u0111\u1EC1 nh\u00F3m", ' ', _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(T\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: `${uploadIdPrefix}-title`, value: title, onChange: (e) => onTitleChange?.(e.target.value), placeholder: "VD: Words from the box", readOnly: isReadOnly, className: `border-gray-200 bg-white transition-all focus:border-indigo-300 focus:ring-indigo-200 ${isReadOnly ? 'cursor-not-allowed border-transparent bg-gray-50 text-gray-500 focus:border-transparent focus:ring-0' : ''}` })] }), _jsx("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3", children: displayItems.map((item, index) => (_jsxs("div", { className: "rounded-md border border-gray-200 bg-white p-2.5 transition-all hover:border-gray-300 hover:shadow-sm", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsxs("span", { className: "text-xs font-semibold text-gray-600", children: ["M\u1EE5c ", index + 1] }), displayItems.length > 1 && !isReadOnly && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => handleDelete(index), className: "h-7 w-7 p-0 text-red-500 hover:bg-red-50 hover:text-red-600", title: "X\u00F3a m\u1EE5c", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }))] }), _jsxs("div", { className: "space-y-2.5", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsxs(Label, { htmlFor: `${uploadIdPrefix}-label-${index}`, className: "flex items-center gap-1.5 text-xs font-medium text-gray-700", children: [_jsx(Type, { className: "h-3.5 w-3.5 text-indigo-500" }), "Nh\u00E3n"] }), _jsx(Input, { id: `${uploadIdPrefix}-label-${index}`, value: item.label, onChange: (e) => handleFieldChange(index, 'label', e.target.value), placeholder: "VD: swimming", readOnly: isReadOnly, className: `border-gray-200 bg-white text-sm focus:border-indigo-300 focus:ring-indigo-200 ${isReadOnly ? 'cursor-not-allowed bg-gray-50 text-gray-500' : ''}` })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsxs(Label, { className: "flex items-center gap-1.5 text-xs font-medium text-gray-700", children: [_jsx(ImageIcon, { className: "h-3.5 w-3.5 text-indigo-500" }), "H\u00ECnh \u1EA3nh"] }), !isReadOnly && (_jsx(FileUpload, { id: `${uploadIdPrefix}-image-${index}`, label: "", accept: "image/*", value: item.imageUrl, onChange: (url) => handleFieldChange(index, 'imageUrl', url), maxSize: 5, placeholder: "Upload \u1EA3nh", autoUpload: true, prefix: "questions" })), item.imageUrl && (_jsx(ItemImagePreview, { src: item.imageUrl, alt: item.label || `Item ${index + 1}` }))] })] })] }, index))) }), !isReadOnly && (_jsxs(Button, { type: "button", variant: "outline", className: "w-full border-dashed border-indigo-300 bg-indigo-50/50 text-indigo-700 hover:border-indigo-400 hover:bg-indigo-50 hover:text-indigo-800", onClick: handleAdd, children: [_jsx(PlusCircle, { className: "mr-2 h-4 w-4" }), "Th\u00EAm m\u1EE5c \u1EA3nh + t\u1EEB"] })), _jsxs("div", { className: "rounded-xl border border-indigo-100 bg-indigo-50/40 p-4", children: [_jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-indigo-600", children: "Xem tr\u01B0\u1EDBc h\u00E0ng t\u1EEB" }), _jsx(ImageLabelWordBank, { items: displayItems })] })] })] }));
42
42
  }
@@ -16,10 +16,10 @@ function OptionRow({ option, index, canRemove, onUpdate, onRemove, groupConfig,
16
16
  const showAnswer = !groupConfig || groupConfig.includes('answer');
17
17
  const showContent = groupConfig?.includes('content') ?? false;
18
18
  const showImageUrl = !groupConfig || groupConfig.includes('imageUrl');
19
- return (_jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-purple-100 bg-gradient-to-r from-purple-50/50 to-violet-50/50 p-4", children: [_jsx("div", { className: "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-purple-500 to-violet-600 text-base font-bold text-white shadow-sm", children: index + 1 }), _jsxs("div", { className: "flex-1 space-y-3", children: [_jsxs("div", { className: "flex items-end gap-3", children: [showAnswer && (_jsx("div", { className: "flex-1", children: _jsx(Input, { value: option.answer, onChange: (e) => onUpdate(index, 'answer', e.target.value), placeholder: `Nhãn (ví dụ: ${String.fromCharCode(65 + index)} hoặc "a pineapple")`, className: "border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200" }) })), showContent && (_jsx("div", { className: "flex-1", children: _jsx(Input, { value: option.content || '', onChange: (e) => onUpdate(index, 'content', e.target.value), placeholder: "N\u1ED9i dung (m\u00F4 t\u1EA3 th\u00EAm cho \u0111\u00E1p \u00E1n)", className: "border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200" }) })), showImageUrl && (_jsx("div", { className: "flex-1", children: _jsx(FileUpload, { id: `option-image-${index}`, label: "", accept: "image/*", value: option.imageUrl || '', onChange: (url) => onUpdate(index, 'imageUrl', url), onPresignedUrlChange: setLocalPreviewUrl, maxSize: 5, placeholder: "Upload \u1EA3nh cho \u0111\u00E1p \u00E1n", autoUpload: true, prefix: "questions" }) }))] }), showImageUrl && displayUrl && (_jsx("div", { className: "relative h-32 w-32 overflow-hidden rounded-lg border border-purple-200 bg-white shadow-sm", children: _jsx("img", { src: displayUrl, alt: option.answer || `Option ${index + 1}`, className: "h-full w-full object-contain" }) }))] }), canRemove && (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => onRemove(index), className: "flex-shrink-0 text-red-500 hover:bg-red-50 hover:text-red-700", children: _jsx(X, { className: "h-4 w-4" }) }))] }));
19
+ return (_jsxs("div", { className: "flex items-start gap-2 rounded-md border border-gray-200 bg-white px-3 py-2.5", children: [_jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-gray-100 text-xs font-bold text-gray-800", children: index + 1 }), _jsxs("div", { className: "flex-1 space-y-3", children: [_jsxs("div", { className: "flex items-end gap-3", children: [showAnswer && (_jsx("div", { className: "flex-1", children: _jsx(Input, { value: option.answer, onChange: (e) => onUpdate(index, 'answer', e.target.value), placeholder: `Nhãn (ví dụ: ${String.fromCharCode(65 + index)} hoặc "a pineapple")`, className: "border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200" }) })), showContent && (_jsx("div", { className: "flex-1", children: _jsx(Input, { value: option.content || '', onChange: (e) => onUpdate(index, 'content', e.target.value), placeholder: "N\u1ED9i dung (m\u00F4 t\u1EA3 th\u00EAm cho \u0111\u00E1p \u00E1n)", className: "border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200" }) })), showImageUrl && (_jsx("div", { className: "flex-1", children: _jsx(FileUpload, { id: `option-image-${index}`, label: "", accept: "image/*", value: option.imageUrl || '', onChange: (url) => onUpdate(index, 'imageUrl', url), onPresignedUrlChange: setLocalPreviewUrl, maxSize: 5, placeholder: "Upload \u1EA3nh cho \u0111\u00E1p \u00E1n", autoUpload: true, prefix: "questions" }) }))] }), showImageUrl && displayUrl && (_jsx("div", { className: "relative h-32 w-32 overflow-hidden rounded-lg border border-purple-200 bg-white shadow-sm", children: _jsx("img", { src: displayUrl, alt: option.answer || `Option ${index + 1}`, className: "h-full w-full object-contain" }) }))] }), canRemove && (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => onRemove(index), className: "flex-shrink-0 text-red-500 hover:bg-red-50 hover:text-red-700", children: _jsx(X, { className: "h-4 w-4" }) }))] }));
20
20
  }
21
21
  export function MatchAnswerGroupCard({ currentGroupNumber, groupTitle, groupImageUrl, groupImagePreviewUrl, options, groupConfig, showGroupTitle, showGroupImageUrl, onGroupTitleChange, onGroupImageChange, onGroupImagePreviewUrlChange, onUpdateOption, onRemoveOption, onAddOption, }) {
22
22
  const { previewUrl: groupImagePresignedUrl } = usePresignedFileUrl(groupImageUrl || '');
23
23
  const displayGroupImageUrl = groupImagePreviewUrl || groupImagePresignedUrl || '';
24
- return (_jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-lg shadow-purple-100/50", children: [_jsx(CardHeader, { className: "pb-3", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-purple-500 to-violet-600 shadow-md", children: _jsx(Layers, { className: "h-5 w-5 text-white" }) }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CardTitle, { className: "text-lg font-bold text-gray-900", children: "\u0110\u00E1p \u00E1n gh\u00E9p n\u1ED1i" }), _jsxs("span", { className: "inline-flex items-center rounded-full border border-purple-300 bg-purple-100 px-2.5 py-0.5 text-xs font-semibold text-purple-700", children: ["Nh\u00F3m ", currentGroupNumber] })] }), _jsx("p", { className: "text-sm text-gray-500", children: "C\u00E1c \u0111\u00E1p \u00E1n (h\u00ECnh \u1EA3nh + nh\u00E3n) d\u00F9ng \u0111\u1EC3 gh\u00E9p n\u1ED1i v\u1EDBi t\u1EEBng c\u00E2u h\u1ECFi trong nh\u00F3m" })] })] }) }), _jsxs(CardContent, { className: "space-y-4", children: [showGroupTitle && (_jsxs("div", { className: "space-y-2 rounded-xl border border-purple-100 bg-gradient-to-r from-purple-50/30 to-violet-50/30 p-4", children: [_jsxs(Label, { htmlFor: "group-title", className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(Type, { className: "h-4 w-4 text-purple-500" }), "Ti\u00EAu \u0111\u1EC1 nh\u00F3m", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(d\u00F9ng chung cho c\u1EA3 nh\u00F3m)" })] }), _jsx(Input, { id: "group-title", value: groupTitle, onChange: (e) => onGroupTitleChange(e.target.value), placeholder: "Nh\u1EADp ti\u00EAu \u0111\u1EC1 nh\u00F3m...", className: "border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200" })] })), showGroupImageUrl && (_jsxs("div", { className: "space-y-2 rounded-xl border border-purple-100 bg-gradient-to-r from-purple-50/30 to-violet-50/30 p-4", children: [_jsxs(Label, { className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(ImageIcon, { className: "h-4 w-4 text-purple-500" }), "H\u00ECnh \u1EA3nh nh\u00F3m ", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(T\u00F9y ch\u1ECDn - d\u00F9ng chung cho c\u1EA3 nh\u00F3m)" })] }), _jsx(FileUpload, { id: "group-image", label: "", accept: "image/*", value: groupImageUrl || '', onChange: onGroupImageChange, onPresignedUrlChange: onGroupImagePreviewUrlChange, maxSize: 5, placeholder: "Upload \u1EA3nh nh\u00F3m ho\u1EB7c paste URL", autoUpload: true, prefix: "questions" }), displayGroupImageUrl && (_jsx(ImagePreview, { src: displayGroupImageUrl, alt: "Group image preview", className: "mt-2 h-48 w-full max-w-md rounded-lg border border-gray-200" }))] })), _jsx("div", { className: "space-y-4", children: options.map((option, index) => (_jsx(OptionRow, { option: option, index: index, canRemove: options.length > 2, onUpdate: onUpdateOption, onRemove: onRemoveOption, groupConfig: groupConfig }, index))) }), _jsxs(Button, { variant: "outline", size: "sm", onClick: onAddOption, className: "gap-2 border-purple-300 text-purple-600 hover:bg-purple-50 hover:text-purple-700", children: [_jsx(Plus, { className: "h-4 w-4" }), "Th\u00EAm \u0111\u00E1p \u00E1n (", options.length + 1, ")"] })] })] }));
24
+ return (_jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-sm", children: [_jsx(CardHeader, { className: "px-3 py-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-md bg-gray-100", children: _jsx(Layers, { className: "h-3.5 w-3.5 text-gray-600" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CardTitle, { className: "text-sm font-bold text-gray-900", children: "\u0110\u00E1p \u00E1n gh\u00E9p n\u1ED1i" }), _jsxs("span", { className: "inline-flex items-center rounded-md border border-gray-200 bg-gray-50 px-2 py-0.5 text-xs font-semibold text-gray-600", children: ["Nh\u00F3m ", currentGroupNumber] })] })] }) }), _jsxs(CardContent, { className: "space-y-2.5 px-3 pb-3", children: [showGroupTitle && (_jsxs("div", { className: "space-y-2 rounded-xl border border-purple-100 bg-gradient-to-r from-purple-50/30 to-violet-50/30 p-4", children: [_jsxs(Label, { htmlFor: "group-title", className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(Type, { className: "h-4 w-4 text-purple-500" }), "Ti\u00EAu \u0111\u1EC1 nh\u00F3m", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(d\u00F9ng chung cho c\u1EA3 nh\u00F3m)" })] }), _jsx(Input, { id: "group-title", value: groupTitle, onChange: (e) => onGroupTitleChange(e.target.value), placeholder: "Nh\u1EADp ti\u00EAu \u0111\u1EC1 nh\u00F3m...", className: "border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200" })] })), showGroupImageUrl && (_jsxs("div", { className: "space-y-2 rounded-xl border border-purple-100 bg-gradient-to-r from-purple-50/30 to-violet-50/30 p-4", children: [_jsxs(Label, { className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(ImageIcon, { className: "h-4 w-4 text-purple-500" }), "H\u00ECnh \u1EA3nh nh\u00F3m ", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(T\u00F9y ch\u1ECDn - d\u00F9ng chung cho c\u1EA3 nh\u00F3m)" })] }), _jsx(FileUpload, { id: "group-image", label: "", accept: "image/*", value: groupImageUrl || '', onChange: onGroupImageChange, onPresignedUrlChange: onGroupImagePreviewUrlChange, maxSize: 5, placeholder: "Upload \u1EA3nh nh\u00F3m ho\u1EB7c paste URL", autoUpload: true, prefix: "questions" }), displayGroupImageUrl && (_jsx(ImagePreview, { src: displayGroupImageUrl, alt: "Group image preview", className: "mt-2 h-48 w-full max-w-md rounded-lg border border-gray-200" }))] })), _jsx("div", { className: "space-y-4", children: options.map((option, index) => (_jsx(OptionRow, { option: option, index: index, canRemove: options.length > 2, onUpdate: onUpdateOption, onRemove: onRemoveOption, groupConfig: groupConfig }, index))) }), _jsxs(Button, { variant: "outline", size: "sm", onClick: onAddOption, className: "gap-2 border-purple-300 text-purple-600 hover:bg-purple-50 hover:text-purple-700", children: [_jsx(Plus, { className: "h-4 w-4" }), "Th\u00EAm \u0111\u00E1p \u00E1n (", options.length + 1, ")"] })] })] }));
25
25
  }
@@ -3,11 +3,8 @@ import type { QuestionEditorRendererProps } from './types';
3
3
  /** Marketing question types supported by the question-bank editor. */
4
4
  export declare enum QuestionBankEditorType {
5
5
  CHOOSE_THE_CORRECT_ANSWER = "CHOOSE_THE_CORRECT_ANSWER",
6
- LOOK_PICTURE_CHOOSE_CORRECT_ANSWER = "LOOK_PICTURE_CHOOSE_CORRECT_ANSWER",
7
- LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER = "LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER",
8
6
  FILL_MISSING_WORDS_IN_GRID = "FILL_MISSING_WORDS_IN_GRID",
9
7
  LABEL_THE_PICTURE = "LABEL_THE_PICTURE",
10
- LOOK_PICTURE_FILL_WORD_HINT = "LOOK_PICTURE_FILL_WORD_HINT",
11
8
  READ_AND_COLOR_OBJECTS = "READ_AND_COLOR_OBJECTS",
12
9
  IMAGE_OBJECT_MATCHING = "IMAGE_OBJECT_MATCHING",
13
10
  READ_PASSAGE_AND_ANSWER_QUESTIONS = "READ_PASSAGE_AND_ANSWER_QUESTIONS",
@@ -2,18 +2,15 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useEffect, useRef, useState } from 'react';
4
4
  import { t } from '../../../shared/lib/i18n';
5
- import { renderChooseCorrectAdjectiveEditor, renderChooseTheCorrectAnswerEditor, renderFillInBlankEditor, renderFillMissingWordsInGridEditor, renderImageObjectMatchingEditor, renderLabelThePictureEditor, renderLookPictureChooseCorrectAnswerEditor, renderLookPictureFillBlankChooseAnswerEditor, renderLookPictureFillWordHintEditor, renderReadAndColorObjectsEditor, renderReadPassageAndAnswerQuestionsEditor, renderWriteAShortLetterEditor, renderWriteCorrectVerbFormEditor, UnsupportedEditorFallback, } from './editor-adapters';
5
+ import { renderChooseCorrectAdjectiveEditor, renderChooseTheCorrectAnswerEditor, renderFillInBlankEditor, renderFillMissingWordsInGridEditor, renderImageObjectMatchingEditor, renderLabelThePictureEditor, renderReadAndColorObjectsEditor, renderReadPassageAndAnswerQuestionsEditor, renderWriteAShortLetterEditor, renderWriteCorrectVerbFormEditor, UnsupportedEditorFallback, } from './editor-adapters';
6
6
  import { CrosswordPuzzleCreator } from '../types/crossword-puzzle/CrosswordPuzzleCreator';
7
7
  import { FindWordsInMatrixCreator } from '../types/find-words-in-matrix/FindWordsInMatrixCreator';
8
8
  /** Marketing question types supported by the question-bank editor. */
9
9
  export var QuestionBankEditorType;
10
10
  (function (QuestionBankEditorType) {
11
11
  QuestionBankEditorType["CHOOSE_THE_CORRECT_ANSWER"] = "CHOOSE_THE_CORRECT_ANSWER";
12
- QuestionBankEditorType["LOOK_PICTURE_CHOOSE_CORRECT_ANSWER"] = "LOOK_PICTURE_CHOOSE_CORRECT_ANSWER";
13
- QuestionBankEditorType["LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER"] = "LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER";
14
12
  QuestionBankEditorType["FILL_MISSING_WORDS_IN_GRID"] = "FILL_MISSING_WORDS_IN_GRID";
15
13
  QuestionBankEditorType["LABEL_THE_PICTURE"] = "LABEL_THE_PICTURE";
16
- QuestionBankEditorType["LOOK_PICTURE_FILL_WORD_HINT"] = "LOOK_PICTURE_FILL_WORD_HINT";
17
14
  QuestionBankEditorType["READ_AND_COLOR_OBJECTS"] = "READ_AND_COLOR_OBJECTS";
18
15
  QuestionBankEditorType["IMAGE_OBJECT_MATCHING"] = "IMAGE_OBJECT_MATCHING";
19
16
  QuestionBankEditorType["READ_PASSAGE_AND_ANSWER_QUESTIONS"] = "READ_PASSAGE_AND_ANSWER_QUESTIONS";
@@ -49,16 +46,10 @@ export function QuestionEditorRenderer({ questionType, content, correctAnswer, e
49
46
  switch (questionType) {
50
47
  case QuestionBankEditorType.CHOOSE_THE_CORRECT_ANSWER:
51
48
  return renderChooseTheCorrectAnswerEditor(adapterProps);
52
- case QuestionBankEditorType.LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:
53
- return renderLookPictureChooseCorrectAnswerEditor(adapterProps);
54
- case QuestionBankEditorType.LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:
55
- return renderLookPictureFillBlankChooseAnswerEditor(adapterProps);
56
49
  case QuestionBankEditorType.FILL_MISSING_WORDS_IN_GRID:
57
50
  return renderFillMissingWordsInGridEditor(adapterProps);
58
51
  case QuestionBankEditorType.LABEL_THE_PICTURE:
59
52
  return renderLabelThePictureEditor(adapterProps);
60
- case QuestionBankEditorType.LOOK_PICTURE_FILL_WORD_HINT:
61
- return renderLookPictureFillWordHintEditor(adapterProps);
62
53
  case QuestionBankEditorType.READ_AND_COLOR_OBJECTS:
63
54
  return renderReadAndColorObjectsEditor(adapterProps);
64
55
  case QuestionBankEditorType.IMAGE_OBJECT_MATCHING:
@@ -1,5 +1,3 @@
1
1
  import type { QuestionEditorAdapterProps } from './types';
2
2
  export declare function renderChooseTheCorrectAnswerEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }: QuestionEditorAdapterProps): import("react").JSX.Element;
3
- export declare function renderLookPictureChooseCorrectAnswerEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }: QuestionEditorAdapterProps): import("react").JSX.Element;
4
- export declare function renderLookPictureFillBlankChooseAnswerEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }: QuestionEditorAdapterProps): import("react").JSX.Element;
5
3
  export declare function renderChooseCorrectAdjectiveEditor({ content, correctAnswer, explanation, points, onChange, }: QuestionEditorAdapterProps): import("react").JSX.Element;
@@ -2,8 +2,6 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { ChooseTheCorrectAnswerCreator } from '../../types/choose-the-correct-answer/ChooseTheCorrectAnswerCreator';
4
4
  import { normalizeChooseAnswerCorrectAnswer, normalizeChooseAnswerOptions, pickRawChooseAnswer, } from '../../types/choose-the-correct-answer/normalize';
5
- import { LookPictureChooseCorrectAnswer } from '../../types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerCreator';
6
- import { LookPictureFillBlankChooseAnswer } from '../../types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerCreator';
7
5
  import { ChooseCorrectAdjectiveCreator } from '../../types/choose-correct-adjective/ChooseCorrectAdjectiveCreator';
8
6
  export function renderChooseTheCorrectAnswerEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }) {
9
7
  const rawOptions = content.options;
@@ -40,45 +38,6 @@ export function renderChooseTheCorrectAnswerEditor({ content, correctAnswer, exp
40
38
  });
41
39
  } }));
42
40
  }
43
- export function renderLookPictureChooseCorrectAnswerEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }) {
44
- const initialData = {
45
- imageUrl: content.imageUrl || '',
46
- options: content.options || ['', ''],
47
- correctAnswer: correctAnswer?.answer ?? -1,
48
- explanation: explanation || '',
49
- points: points || 1,
50
- };
51
- return (_jsx(LookPictureChooseCorrectAnswer, { initialData: initialData, validationRef: validationRef, onChange: (data) => {
52
- onChange?.({
53
- content: { imageUrl: data?.imageUrl, options: data?.options },
54
- answer: { answer: data?.correctAnswer },
55
- explanation: data?.explanation,
56
- points: data?.points,
57
- });
58
- } }));
59
- }
60
- export function renderLookPictureFillBlankChooseAnswerEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }) {
61
- const initialData = {
62
- imageUrl: content.imageUrl || '',
63
- question: content.question || '',
64
- options: content.options || ['', '', '', ''],
65
- correctAnswer: correctAnswer?.answer ?? -1,
66
- explanation: explanation || '',
67
- points: points || 1,
68
- };
69
- return (_jsx(LookPictureFillBlankChooseAnswer, { initialData: initialData, validationRef: validationRef, onChange: (data) => {
70
- onChange?.({
71
- content: {
72
- imageUrl: data?.imageUrl,
73
- question: data?.question,
74
- options: data?.options,
75
- },
76
- answer: { answer: data?.correctAnswer },
77
- explanation: data?.explanation,
78
- points: data?.points,
79
- });
80
- } }));
81
- }
82
41
  export function renderChooseCorrectAdjectiveEditor({ content, correctAnswer, explanation, points, onChange, }) {
83
42
  const initialData = {
84
43
  sentence: content.sentence || '',
@@ -1,5 +1,5 @@
1
- export { renderChooseTheCorrectAnswerEditor, renderLookPictureChooseCorrectAnswerEditor, renderLookPictureFillBlankChooseAnswerEditor, renderChooseCorrectAdjectiveEditor, } from './choice-adapters';
2
- export { renderFillMissingWordsInGridEditor, renderLabelThePictureEditor, renderLookPictureFillWordHintEditor, renderReadAndColorObjectsEditor, renderImageObjectMatchingEditor, } from './media-adapters';
1
+ export { renderChooseTheCorrectAnswerEditor, renderChooseCorrectAdjectiveEditor, } from './choice-adapters';
2
+ export { renderFillMissingWordsInGridEditor, renderLabelThePictureEditor, renderReadAndColorObjectsEditor, renderImageObjectMatchingEditor, } from './media-adapters';
3
3
  export { renderReadPassageAndAnswerQuestionsEditor, renderWriteAShortLetterEditor, renderWriteCorrectVerbFormEditor, renderFillInBlankEditor, } from './writing-adapters';
4
4
  export { UnsupportedEditorFallback } from './unsupported-fallback';
5
5
  export type { QuestionEditorAdapterProps, QuestionEditorChangeData } from './types';
@@ -1,4 +1,4 @@
1
- export { renderChooseTheCorrectAnswerEditor, renderLookPictureChooseCorrectAnswerEditor, renderLookPictureFillBlankChooseAnswerEditor, renderChooseCorrectAdjectiveEditor, } from './choice-adapters';
2
- export { renderFillMissingWordsInGridEditor, renderLabelThePictureEditor, renderLookPictureFillWordHintEditor, renderReadAndColorObjectsEditor, renderImageObjectMatchingEditor, } from './media-adapters';
1
+ export { renderChooseTheCorrectAnswerEditor, renderChooseCorrectAdjectiveEditor, } from './choice-adapters';
2
+ export { renderFillMissingWordsInGridEditor, renderLabelThePictureEditor, renderReadAndColorObjectsEditor, renderImageObjectMatchingEditor, } from './media-adapters';
3
3
  export { renderReadPassageAndAnswerQuestionsEditor, renderWriteAShortLetterEditor, renderWriteCorrectVerbFormEditor, renderFillInBlankEditor, } from './writing-adapters';
4
4
  export { UnsupportedEditorFallback } from './unsupported-fallback';
@@ -1,6 +1,5 @@
1
1
  import type { QuestionEditorAdapterProps } from './types';
2
2
  export declare function renderFillMissingWordsInGridEditor({ content, correctAnswer, onChange, }: QuestionEditorAdapterProps): import("react").JSX.Element;
3
3
  export declare function renderLabelThePictureEditor({ content, explanation, points, onChange, validationRef, }: QuestionEditorAdapterProps): import("react").JSX.Element;
4
- export declare function renderLookPictureFillWordHintEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }: QuestionEditorAdapterProps): import("react").JSX.Element;
5
4
  export declare function renderReadAndColorObjectsEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }: QuestionEditorAdapterProps): import("react").JSX.Element;
6
5
  export declare function renderImageObjectMatchingEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }: QuestionEditorAdapterProps): import("react").JSX.Element;
@@ -2,7 +2,6 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { FillMissingWordsInGridCreator } from '../../types/fill-missing-words-in-grid/FillMissingWordsInGridCreator';
4
4
  import { LabelThePictureCreator } from '../../types/label-the-picture/LabelThePictureCreator';
5
- import { LookPictureFillWordHintCreator } from '../../types/look-picture-fill-word-hint/LookPictureFillWordHintCreator';
6
5
  import { ReadAndColorObjectsCreator } from '../../types/read-and-color-objects/ReadAndColorObjectsCreator';
7
6
  import { ImageObjectMatchingCreator } from '../../types/image-object-matching/ImageObjectMatchingCreator';
8
7
  export function renderFillMissingWordsInGridEditor({ content, correctAnswer, onChange, }) {
@@ -63,33 +62,6 @@ export function renderLabelThePictureEditor({ content, explanation, points, onCh
63
62
  });
64
63
  } }));
65
64
  }
66
- export function renderLookPictureFillWordHintEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }) {
67
- const initialData = {
68
- subQuestions: [
69
- {
70
- id: 'edit-1',
71
- imageUrl: content.imageUrl || '',
72
- word: content.word || '',
73
- correctAnswer: correctAnswer?.correctAnswer || '',
74
- },
75
- ],
76
- hintLetters: [],
77
- explanation: explanation || '',
78
- points: points || 1,
79
- };
80
- return (_jsx(LookPictureFillWordHintCreator, { initialData: initialData, validationRef: validationRef, onChange: (data) => {
81
- const subQ = data?.subQuestions?.[0] || {};
82
- onChange?.({
83
- content: {
84
- imageUrl: subQ.imageUrl,
85
- word: subQ.word,
86
- },
87
- answer: { correctAnswer: subQ.correctAnswer },
88
- explanation: data?.explanation,
89
- points: data?.points,
90
- });
91
- } }));
92
- }
93
65
  export function renderReadAndColorObjectsEditor({ content, correctAnswer, explanation, points, onChange, validationRef, }) {
94
66
  const initialData = {
95
67
  backgroundImageUrl: content.backgroundImageUrl || '',
@@ -35,10 +35,6 @@ const QUESTION_TYPE_LABELS = {
35
35
  MATCH_BY_WRITING_ANSWER: 'Nối bằng cách viết đáp án',
36
36
  SPEAKING_DESCRIBE_IMAGE: 'Nói: mô tả tranh',
37
37
  SPEAKING_CONVERSATION: 'Nói: hội thoại',
38
- GN_SPEAKING_INTERVIEW: 'Nói: phỏng vấn',
39
- LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER: 'Nhìn tranh điền chỗ trống',
40
- LOOK_PICTURE_CHOOSE_CORRECT_ANSWER: 'Nhìn tranh chọn đáp án',
41
- LOOK_PICTURE_FILL_WORD_HINT: 'Nhìn tranh điền từ gợi ý',
42
38
  LABEL_THE_PICTURE: 'Gắn nhãn hình ảnh',
43
39
  MATCH_WORD_TO_PICTURE: 'Nối từ với tranh',
44
40
  MATCH_WORD_TO_PICTURE_GROUP: 'Nối từ với tranh (nhóm)',
@@ -72,9 +68,6 @@ var QuestionTypeVisualKind;
72
68
  QuestionTypeVisualKind["TEXT"] = "text";
73
69
  })(QuestionTypeVisualKind || (QuestionTypeVisualKind = {}));
74
70
  const TYPE_VISUAL_KIND = {
75
- LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER: QuestionTypeVisualKind.IMAGE,
76
- LOOK_PICTURE_CHOOSE_CORRECT_ANSWER: QuestionTypeVisualKind.IMAGE,
77
- LOOK_PICTURE_FILL_WORD_HINT: QuestionTypeVisualKind.IMAGE,
78
71
  LABEL_THE_PICTURE: QuestionTypeVisualKind.IMAGE,
79
72
  MATCH_WORD_TO_PICTURE: QuestionTypeVisualKind.IMAGE,
80
73
  MATCH_WORD_TO_PICTURE_GROUP: QuestionTypeVisualKind.IMAGE,
@@ -33,7 +33,7 @@ export function AnswerTheQuestionClient({ questionData, onSubmit, isReviewMode =
33
33
  const [answer, setAnswer] = useState(userAnswer || '');
34
34
  const imageUrls = toAnswerTheQuestionImageUrls(questionData.imageUrl);
35
35
  if (!questionData.question && imageUrls.length === 0) {
36
- return (_jsx(Card, { children: _jsx(CardContent, { className: "p-6", children: _jsx("p", { className: "text-gray-500", children: "Kh\u00F4ng c\u00F3 d\u1EEF li\u1EC7u c\u00E2u h\u1ECFi" }) }) }));
36
+ return (_jsx(Card, { children: _jsx(CardContent, { className: "p-3", children: _jsx("p", { className: "text-gray-500", children: "Kh\u00F4ng c\u00F3 d\u1EEF li\u1EC7u c\u00E2u h\u1ECFi" }) }) }));
37
37
  }
38
38
  const isExample = questionData.isExample || false;
39
39
  const correctAnswer = questionData.correctAnswer || '';
@@ -43,19 +43,19 @@ export function AnswerTheQuestionClient({ questionData, onSubmit, isReviewMode =
43
43
  const isCorrect = isReviewMode && userAnswer !== undefined
44
44
  ? userAnswer.trim().toLowerCase() === correctAnswer.trim().toLowerCase()
45
45
  : undefined;
46
- return (_jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-lg", children: [_jsx("div", { className: "h-1 bg-gradient-to-r from-teal-400 to-cyan-500" }), _jsxs(CardContent, { className: "p-6 space-y-6", children: [(questionData.title || questionData.groupContent) && (_jsxs("div", { className: "rounded-xl border border-indigo-200 bg-gradient-to-r from-indigo-50 to-blue-50 p-4 space-y-2", children: [questionData.title && (_jsx("h3", { className: "text-base font-bold text-indigo-900", children: questionData.title })), questionData.groupContent && (_jsx("p", { className: "text-sm text-indigo-700 leading-relaxed whitespace-pre-wrap", children: questionData.groupContent }))] })), imageUrls.length > 0 && (_jsx("div", { className: "flex flex-wrap justify-center gap-3", children: imageUrls.map((url, imageIndex) => (_jsx("div", { className: "relative max-w-lg overflow-hidden rounded-xl border border-gray-200 bg-gray-50 shadow-sm", children: _jsx(MediaPreview, { src: url, alt: `Question image ${imageIndex + 1}` }) }, `atq-image-${imageIndex}`))) })), _jsxs("div", { className: "rounded-xl border border-gray-200 bg-gradient-to-r from-gray-50 to-slate-50 p-5", children: [isExample && (_jsxs("div", { className: "mb-2 inline-flex items-center gap-1.5 rounded-full bg-amber-100 border border-amber-300 px-3 py-1", children: [_jsx(BookOpen, { className: "h-3.5 w-3.5 text-amber-600" }), _jsx("span", { className: "text-xs font-semibold text-amber-700 uppercase tracking-wide", children: "Example" })] })), questionData.question ? (_jsx(Label, { className: "text-base font-semibold text-gray-800 mb-3 block", children: questionData.question })) : null, questionData.suggestedAnswers && questionData.suggestedAnswers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mt-2 mb-1", children: questionData.suggestedAnswers.map((suggestion, index) => (_jsx("button", { type: "button", disabled: isReviewMode || isExample, onClick: () => {
47
- if (!isReviewMode && !isExample) {
48
- setAnswer(suggestion);
49
- onSubmit?.(suggestion);
50
- }
51
- }, className: `inline-flex items-center rounded-full border px-3 py-1 text-sm font-medium transition-colors ${answer === suggestion
52
- ? 'border-teal-400 bg-teal-50 text-teal-700 ring-1 ring-teal-200'
53
- : 'border-gray-200 bg-white text-gray-600 hover:border-teal-300 hover:bg-teal-50/50 hover:text-teal-600'} ${isReviewMode || isExample ? 'cursor-not-allowed opacity-60' : 'cursor-pointer'}`, children: suggestion }, index))) })), _jsxs("div", { className: "flex items-center gap-3 mt-3", children: [questionData.prefixText && (_jsx("span", { className: "text-base font-medium text-gray-700", children: questionData.prefixText })), _jsx(Input, { value: displayedAnswer, onChange: (e) => {
54
- setAnswer(e.target.value);
55
- onSubmit?.(e.target.value);
56
- }, placeholder: "Vi\u1EBFt \u0111\u00E1p \u00E1n...", disabled: isReviewMode || isExample, className: `max-w-xs border-2 text-lg font-medium ${isReviewMode
57
- ? isCorrect
58
- ? 'border-green-400 bg-green-50 text-green-700'
59
- : 'border-red-400 bg-red-50 text-red-700'
60
- : 'border-teal-300 focus:border-teal-500 focus:ring-teal-200'}` }), questionData.suffixText && (_jsx("span", { className: "text-base font-medium text-gray-700", children: questionData.suffixText })), isReviewMode && isCorrect !== undefined && (_jsx("span", { className: "flex items-center gap-1", children: isCorrect ? (_jsx(CheckCircle2, { className: "h-5 w-5 text-green-500" })) : (_jsx(XCircle, { className: "h-5 w-5 text-red-500" })) }))] }), isReviewMode && isCorrect === false && (_jsxs("div", { className: "mt-3 flex items-center gap-2 rounded-lg bg-green-50 border border-green-200 px-4 py-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-green-600" }), _jsxs("span", { className: "text-sm text-green-700", children: ["\u0110\u00E1p \u00E1n \u0111\u00FAng: ", _jsx("strong", { children: correctAnswer })] })] })), autoFillCorrectAnswers && (_jsxs("div", { className: "mt-3 flex items-center gap-2 rounded-lg bg-teal-50 border border-teal-200 px-4 py-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-teal-600" }), _jsxs("span", { className: "text-sm text-teal-700", children: ["\u0110\u00E1p \u00E1n: ", _jsx("strong", { children: correctAnswer })] })] }))] }), explanation && isReviewMode && (_jsxs("div", { className: "rounded-xl border border-blue-200 bg-blue-50 p-4", children: [_jsx("p", { className: "text-sm font-semibold text-blue-800 mb-1", children: "Gi\u1EA3i th\u00EDch:" }), _jsx("p", { className: "text-sm text-blue-700", children: explanation })] }))] })] }));
46
+ return (_jsx(Card, { className: "overflow-hidden border-0 bg-white shadow-sm", children: _jsxs(CardContent, { className: "p-3 space-y-3", children: [(questionData.title || questionData.groupContent) && (_jsxs("div", { className: "rounded-xl border border-indigo-200 bg-gradient-to-r from-indigo-50 to-blue-50 p-4 space-y-2", children: [questionData.title && (_jsx("h3", { className: "text-base font-bold text-indigo-900", children: questionData.title })), questionData.groupContent && (_jsx("p", { className: "text-sm text-indigo-700 leading-relaxed whitespace-pre-wrap", children: questionData.groupContent }))] })), imageUrls.length > 0 && (_jsx("div", { className: "flex flex-wrap justify-center gap-3", children: imageUrls.map((url, imageIndex) => (_jsx("div", { className: "relative max-w-lg overflow-hidden rounded-xl border border-gray-200 bg-gray-50 shadow-sm", children: _jsx(MediaPreview, { src: url, alt: `Question image ${imageIndex + 1}` }) }, `atq-image-${imageIndex}`))) })), _jsxs("div", { className: "rounded-xl border border-gray-200 bg-gradient-to-r from-gray-50 to-slate-50 p-5", children: [isExample && (_jsxs("div", { className: "mb-2 inline-flex items-center gap-1.5 rounded-full bg-amber-100 border border-amber-300 px-3 py-1", children: [_jsx(BookOpen, { className: "h-3.5 w-3.5 text-amber-600" }), _jsx("span", { className: "text-xs font-semibold text-amber-700 uppercase tracking-wide", children: "Example" })] })), questionData.question ? (_jsx(Label, { className: "text-base font-semibold text-gray-800 mb-3 block", children: questionData.question })) : null, questionData.suggestedAnswers && questionData.suggestedAnswers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mt-2 mb-1", children: questionData.suggestedAnswers.map((suggestion, index) => (_jsx("button", { type: "button", disabled: isReviewMode || isExample, onClick: () => {
47
+ if (!isReviewMode && !isExample) {
48
+ setAnswer(suggestion);
49
+ onSubmit?.(suggestion);
50
+ }
51
+ }, className: `inline-flex items-center rounded-full border px-3 py-1 text-sm font-medium transition-colors ${answer === suggestion
52
+ ? 'border-teal-400 bg-teal-50 text-teal-700 ring-1 ring-teal-200'
53
+ : 'border-gray-200 bg-white text-gray-600 hover:border-teal-300 hover:bg-teal-50/50 hover:text-teal-600'} ${isReviewMode || isExample ? 'cursor-not-allowed opacity-60' : 'cursor-pointer'}`, children: suggestion }, index))) })), _jsxs("div", { className: "flex items-center gap-3 mt-3", children: [questionData.prefixText && (_jsx("span", { className: "text-base font-medium text-gray-700", children: questionData.prefixText })), _jsx(Input, { value: displayedAnswer, onChange: (e) => {
54
+ setAnswer(e.target.value);
55
+ onSubmit?.(e.target.value);
56
+ }, placeholder: "Vi\u1EBFt \u0111\u00E1p \u00E1n...", disabled: isReviewMode || isExample, className: `max-w-xs border-2 text-lg font-medium ${isReviewMode
57
+ ? isCorrect
58
+ ? 'border-green-400 bg-green-50 text-green-700'
59
+ : 'border-red-400 bg-red-50 text-red-700'
60
+ : 'border-teal-300 focus:border-teal-500 focus:ring-teal-200'}` }), questionData.suffixText && (_jsx("span", { className: "text-base font-medium text-gray-700", children: questionData.suffixText })), isReviewMode && isCorrect !== undefined && (_jsx("span", { className: "flex items-center gap-1", children: isCorrect ? (_jsx(CheckCircle2, { className: "h-5 w-5 text-green-500" })) : (_jsx(XCircle, { className: "h-5 w-5 text-red-500" })) }))] }), isReviewMode && isCorrect === false && (_jsxs("div", { className: "mt-3 flex items-center gap-2 rounded-lg bg-green-50 border border-green-200 px-4 py-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-green-600" }), _jsxs("span", { className: "text-sm text-green-700", children: ["\u0110\u00E1p \u00E1n \u0111\u00FAng: ", _jsx("strong", { children: correctAnswer })] })] })), autoFillCorrectAnswers && (_jsxs("div", { className: "mt-3 flex items-center gap-2 rounded-lg bg-teal-50 border border-teal-200 px-4 py-2", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-teal-600" }), _jsxs("span", { className: "text-sm text-teal-700", children: ["\u0110\u00E1p \u00E1n: ", _jsx("strong", { children: correctAnswer })] })] }))] }), explanation && isReviewMode && (_jsxs("div", { className: "rounded-xl border border-blue-200 bg-blue-50 p-4", children: [_jsx("p", { className: "text-sm font-semibold text-blue-800 mb-1", children: "Gi\u1EA3i th\u00EDch:" }), _jsx("p", { className: "text-sm text-blue-700", children: explanation })] }))] }) }));
61
61
  }
@@ -4,11 +4,8 @@ import { useState, useRef, useEffect } from 'react';
4
4
  import { Button } from '../../../../components/ui/button';
5
5
  import { Label } from '../../../../components/ui/label';
6
6
  import { Input } from '../../../../components/ui/input';
7
- import { Textarea } from '../../../../components/ui/textarea';
8
- import { PointsInput } from '../../../../components/ui/points-input';
9
- import { Card, CardContent, CardHeader, CardTitle } from '../../../../components/ui/card';
10
- import { Pencil, Eye, HelpCircle, BookOpen, Plus, X, ListChecks, MessageSquare } from 'lucide-react';
11
- import { Checkbox } from '../../../../components/ui/checkbox';
7
+ import { HelpCircle, Plus, X, ListChecks, MessageSquare } from 'lucide-react';
8
+ import { CompactCreatorHeader, CompactExplanationToggle, CompactFieldCard, CompactPreviewBanner, } from '../../_shared/components/compact';
12
9
  import { AnswerTheQuestionClient } from './AnswerTheQuestionClient';
13
10
  import { useDebouncedCallback } from '../../../../shared/lib/hooks';
14
11
  import { BasicQuestionGroupCard } from '../../groups/BasicQuestionGroupCard';
@@ -318,33 +315,42 @@ function AnswerTheQuestionContent({ initialData, onSave, onSaveToQuestionBank, o
318
315
  title: groupTitle,
319
316
  subtitle: groupSubtitle,
320
317
  };
321
- return (_jsxs("div", { className: "space-y-4", children: [_jsx(Card, { children: _jsx(CardHeader, { children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx(CardTitle, { children: "Answer the question (Preview)" }), _jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Ch\u1EBF \u0111\u1ED9 xem tr\u01B0\u1EDBc - Hi\u1EC3n th\u1ECB \u0111\u00E1p \u00E1n \u0111\u00FAng" })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setIsClientMode(false), children: [_jsx(Pencil, { className: "mr-2 h-4 w-4" }), "Quay l\u1EA1i Edit Mode"] })] }) }) }), _jsx(AnswerTheQuestionClient, { questionData: questionData, isReviewMode: true, autoFillCorrectAnswers: true, explanation: explanation })] }));
318
+ return (_jsxs("div", { className: "space-y-4", children: [_jsx(CompactPreviewBanner, { onBack: () => setIsClientMode(false) }), _jsx(AnswerTheQuestionClient, { questionData: questionData, isReviewMode: true, autoFillCorrectAnswers: true, explanation: explanation })] }));
322
319
  }
323
320
  // Creator UI
324
- return (_jsxs("div", { className: "space-y-4", children: [isGrouped && (_jsx(BasicQuestionGroupCard, { groupNumber: currentGroupNumber, title: groupTitle, subtitle: groupSubtitle, content: groupContent, imageUrl: imageUrl, onTitleChange: setGroupTitle, onSubtitleChange: setGroupSubtitle, onContentChange: setGroupContent, onImageChange: setImageUrl, groupConfig: groupConfig, uploadIdPrefix: `answer-the-question-${partId ?? 'group'}` })), _jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-lg shadow-blue-100/50", children: [_jsx(CardHeader, { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-teal-500 to-cyan-600 shadow-sm", children: _jsx(HelpCircle, { className: "h-4 w-4 text-white" }) }), _jsxs("div", { children: [_jsx(CardTitle, { className: "text-base font-bold text-gray-900", children: "\u0110\u1ECDc c\u00E2u h\u1ECFi v\u00E0 vi\u1EBFt \u0111\u00E1p \u00E1n" }), _jsx("p", { className: "text-xs text-gray-500", children: "Nghe - \u0110\u1ECDc c\u00E2u h\u1ECFi v\u00E0 vi\u1EBFt t\u00EAn ho\u1EB7c s\u1ED1" })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [headerExtra, _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setIsClientMode(true), disabled: !currentQuestion.question, className: "gap-2 border-teal-200 text-teal-600 hover:bg-teal-50 hover:text-teal-700", children: [_jsx(Eye, { className: "h-4 w-4" }), "Xem tr\u01B0\u1EDBc"] })] })] }) }), _jsxs(CardContent, { className: "space-y-4 px-4 pb-4", children: [_jsxs("div", { className: "flex items-center gap-6", children: [_jsx(PointsInput, { value: currentQuestion.points || 1, onChange: (e) => updateCurrentQuestion('points', parseFloat(e.target.value) || 1) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "isExample", checked: currentQuestion.isExample || false, onCheckedChange: (checked) => updateCurrentQuestion('isExample', !!checked) }), _jsx(Label, { htmlFor: "isExample", className: "flex items-center gap-1.5 cursor-pointer text-sm font-medium text-gray-700", children: "\u0110\u00E1nh d\u1EA5u l\u00E0 c\u00E2u h\u1ECFi Example" })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "question", className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-teal-500" }), "C\u00E2u h\u1ECFi ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: "question", value: currentQuestion.question, onChange: (e) => updateCurrentQuestion('question', e.target.value), placeholder: "Nh\u1EADp c\u00E2u h\u1ECFi... (vd: How many dolls has Lucy got?)", className: `border-gray-200 bg-white transition-all focus:border-teal-300 focus:ring-teal-200 ${validationErrors.question ? 'border-red-400 focus:border-red-500 focus:ring-red-200' : ''}` }), validationErrors.question && (_jsx("p", { className: "text-sm text-red-600", children: validationErrors.question }))] }), _jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "correctAnswer", className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(HelpCircle, { className: "h-4 w-4 text-green-500" }), "\u0110\u00E1p \u00E1n \u0111\u00FAng ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: "correctAnswer", value: currentQuestion.correctAnswer, onChange: (e) => updateCurrentQuestion('correctAnswer', e.target.value), placeholder: "Nh\u1EADp \u0111\u00E1p \u00E1n... (vd: 5 ho\u1EB7c Buster)", className: `border-gray-200 bg-white transition-all focus:border-green-300 focus:ring-green-200 ${validationErrors.correctAnswer ? 'border-red-400 focus:border-red-500 focus:ring-red-200' : ''}` }), validationErrors.correctAnswer && (_jsx("p", { className: "text-sm text-red-600", children: validationErrors.correctAnswer }))] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "prefixText", className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-gray-400" }), "Text tr\u01B0\u1EDBc \u00F4 tr\u1EA3 l\u1EDDi ", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(t\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: "prefixText", value: currentQuestion.prefixText || '', onChange: (e) => updateCurrentQuestion('prefixText', e.target.value), placeholder: "vd: There are", className: "border-gray-200 bg-white transition-all focus:border-gray-300 focus:ring-gray-200" })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "suffixText", className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-gray-400" }), "Text sau \u00F4 tr\u1EA3 l\u1EDDi ", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(t\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: "suffixText", value: currentQuestion.suffixText || '', onChange: (e) => updateCurrentQuestion('suffixText', e.target.value), placeholder: "vd: school", className: "border-gray-200 bg-white transition-all focus:border-gray-300 focus:ring-gray-200" })] })] }), hasSuggestedAnswers !== false && (_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(ListChecks, { className: "h-4 w-4 text-purple-500" }), "\u0110\u00E1p \u00E1n g\u1EE3i \u00FD ", _jsx("span", { className: "text-sm font-normal text-gray-500", children: "(t\u00F9y ch\u1ECDn)" })] }), _jsxs("div", { className: "rounded-xl border border-purple-200 bg-gradient-to-r from-purple-50 to-violet-50 p-4 space-y-3", children: [currentQuestion.suggestedAnswers && currentQuestion.suggestedAnswers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2", children: currentQuestion.suggestedAnswers.map((suggestion, index) => (_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-white border border-purple-200 px-3 py-1 text-sm font-medium text-purple-700 shadow-sm", children: [suggestion, _jsx("button", { type: "button", onClick: () => {
325
- const updated = [...(currentQuestion.suggestedAnswers || [])];
326
- updated.splice(index, 1);
327
- updateCurrentQuestion('suggestedAnswers', updated);
328
- }, className: "ml-0.5 rounded-full p-0.5 text-purple-400 hover:bg-purple-100 hover:text-purple-600 transition-colors", children: _jsx(X, { className: "h-3 w-3" }) })] }, index))) })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { id: "newSuggestedAnswer", placeholder: "Nh\u1EADp \u0111\u00E1p \u00E1n g\u1EE3i \u00FD...", className: "flex-1 border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200", onKeyDown: (e) => {
329
- if (e.key === 'Enter') {
330
- e.preventDefault();
331
- const input = e.currentTarget;
332
- const value = input.value.trim();
333
- if (value) {
334
- const current = currentQuestion.suggestedAnswers || [];
335
- updateCurrentQuestion('suggestedAnswers', [...current, value]);
336
- input.value = '';
337
- }
338
- }
339
- } }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "gap-1 border-purple-300 text-purple-600 hover:bg-purple-100 hover:text-purple-700", onClick: () => {
340
- const input = document.getElementById('newSuggestedAnswer');
341
- const value = input?.value.trim();
342
- if (value) {
343
- const current = currentQuestion.suggestedAnswers || [];
344
- updateCurrentQuestion('suggestedAnswers', [...current, value]);
345
- input.value = '';
346
- }
347
- }, children: [_jsx(Plus, { className: "h-3.5 w-3.5" }), "Th\u00EAm"] })] }), _jsx("p", { className: "text-xs text-purple-500", children: "Nh\u1EADp \u0111\u00E1p \u00E1n g\u1EE3i \u00FD r\u1ED3i nh\u1EA5n Enter ho\u1EB7c n\u00FAt Th\u00EAm" })] })] })), externalErrors && externalErrors.length > 0 && (_jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-red-200 bg-gradient-to-r from-red-50 to-rose-50 p-4", children: [_jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-red-100", children: _jsx("span", { className: "text-lg", children: "\u274C" }) }), _jsxs("div", { className: "text-sm", children: [_jsx("p", { className: "font-semibold text-red-800", children: "L\u1ED7i:" }), _jsx("ul", { className: "mt-1 list-inside list-disc text-red-700", children: externalErrors.map((error, index) => (_jsx("li", { children: error }, index))) })] })] }))] })] }), _jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-lg shadow-amber-100/50", children: [_jsx(CardHeader, { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-amber-500 to-orange-500 shadow-sm", children: _jsx(BookOpen, { className: "h-3.5 w-3.5 text-white" }) }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CardTitle, { className: "text-base font-semibold text-gray-800", children: "Gi\u1EA3i th\u00EDch" }), _jsx("span", { className: "inline-flex items-center rounded-full border border-amber-200 bg-amber-50 px-2.5 py-0.5 text-xs font-medium text-amber-600", children: "Kh\u00F4ng b\u1EAFt bu\u1ED9c" })] }), _jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: "Gi\u1EA3i th\u00EDch cho \u0111\u00E1p \u00E1n \u0111\u00FAng \u2014 hi\u1EC3n th\u1ECB sau khi h\u1ECDc sinh ho\u00E0n th\u00E0nh c\u00E2u h\u1ECFi" })] })] }) }), _jsx(CardContent, { className: "px-4 pb-4", children: _jsx(Textarea, { id: "explanation", value: explanation, onChange: (e) => setExplanation(e.target.value), placeholder: "VD: C\u00E2u tr\u1EA3 l\u1EDDi \u0111\u00FAng l\u00E0... v\u00EC...", rows: 3, className: "min-h-[80px] border-gray-200 bg-white transition-all focus:border-amber-300 focus:ring-amber-200 resize-none" }) })] })] }));
321
+ return (_jsxs("div", { className: "space-y-3", children: [isGrouped && (_jsx(BasicQuestionGroupCard, { groupNumber: currentGroupNumber, title: groupTitle, subtitle: groupSubtitle, content: groupContent, imageUrl: imageUrl, onTitleChange: setGroupTitle, onSubtitleChange: setGroupSubtitle, onContentChange: setGroupContent, onImageChange: setImageUrl, groupConfig: groupConfig, uploadIdPrefix: `answer-the-question-${partId ?? 'group'}` })), _jsxs(CompactFieldCard, { header: _jsx(CompactCreatorHeader, { icon: _jsx(HelpCircle, { className: "h-3.5 w-3.5" }), title: "\u0110\u1ECDc c\u00E2u h\u1ECFi v\u00E0 vi\u1EBFt \u0111\u00E1p \u00E1n", points: {
322
+ value: currentQuestion.points || 1,
323
+ onValueChange: (value) => updateCurrentQuestion('points', value),
324
+ }, example: {
325
+ checked: currentQuestion.isExample || false,
326
+ onChange: (checked) => updateCurrentQuestion('isExample', checked),
327
+ }, headerExtra: headerExtra, preview: {
328
+ onClick: () => setIsClientMode(true),
329
+ disabled: !currentQuestion.question,
330
+ } }), children: [_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "question", className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-teal-500" }), "C\u00E2u h\u1ECFi ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: "question", value: currentQuestion.question, onChange: (e) => updateCurrentQuestion('question', e.target.value), placeholder: "Nh\u1EADp c\u00E2u h\u1ECFi... (vd: How many dolls has Lucy got?)", className: `border-gray-200 bg-white transition-all focus:border-teal-300 focus:ring-teal-200 ${validationErrors.question ? 'border-red-400 focus:border-red-500 focus:ring-red-200' : ''}` }), validationErrors.question && (_jsx("p", { className: "text-sm text-red-600", children: validationErrors.question }))] }), _jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "correctAnswer", className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(HelpCircle, { className: "h-4 w-4 text-green-500" }), "\u0110\u00E1p \u00E1n \u0111\u00FAng ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: "correctAnswer", value: currentQuestion.correctAnswer, onChange: (e) => updateCurrentQuestion('correctAnswer', e.target.value), placeholder: "Nh\u1EADp \u0111\u00E1p \u00E1n... (vd: 5 ho\u1EB7c Buster)", className: `border-gray-200 bg-white transition-all focus:border-green-300 focus:ring-green-200 ${validationErrors.correctAnswer ? 'border-red-400 focus:border-red-500 focus:ring-red-200' : ''}` }), validationErrors.correctAnswer && (_jsx("p", { className: "text-sm text-red-600", children: validationErrors.correctAnswer }))] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "prefixText", className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-gray-400" }), "Text tr\u01B0\u1EDBc \u00F4 tr\u1EA3 l\u1EDDi ", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(t\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: "prefixText", value: currentQuestion.prefixText || '', onChange: (e) => updateCurrentQuestion('prefixText', e.target.value), placeholder: "vd: There are", className: "border-gray-200 bg-white transition-all focus:border-gray-300 focus:ring-gray-200" })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { htmlFor: "suffixText", className: "flex items-center gap-2 text-sm font-semibold text-gray-800", children: [_jsx(MessageSquare, { className: "h-4 w-4 text-gray-400" }), "Text sau \u00F4 tr\u1EA3 l\u1EDDi ", _jsx("span", { className: "text-xs font-normal text-gray-500", children: "(t\u00F9y ch\u1ECDn)" })] }), _jsx(Input, { id: "suffixText", value: currentQuestion.suffixText || '', onChange: (e) => updateCurrentQuestion('suffixText', e.target.value), placeholder: "vd: school", className: "border-gray-200 bg-white transition-all focus:border-gray-300 focus:ring-gray-200" })] })] }), hasSuggestedAnswers !== false && (_jsxs("div", { className: "space-y-2", children: [_jsxs(Label, { className: "flex items-center gap-2 text-base font-semibold text-gray-800", children: [_jsx(ListChecks, { className: "h-4 w-4 text-purple-500" }), "\u0110\u00E1p \u00E1n g\u1EE3i \u00FD ", _jsx("span", { className: "text-sm font-normal text-gray-500", children: "(t\u00F9y ch\u1ECDn)" })] }), _jsxs("div", { className: "rounded-xl border border-purple-200 bg-gradient-to-r from-purple-50 to-violet-50 p-4 space-y-3", children: [currentQuestion.suggestedAnswers && currentQuestion.suggestedAnswers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2", children: currentQuestion.suggestedAnswers.map((suggestion, index) => (_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-white border border-purple-200 px-3 py-1 text-sm font-medium text-purple-700 shadow-sm", children: [suggestion, _jsx("button", { type: "button", onClick: () => {
331
+ const updated = [...(currentQuestion.suggestedAnswers || [])];
332
+ updated.splice(index, 1);
333
+ updateCurrentQuestion('suggestedAnswers', updated);
334
+ }, className: "ml-0.5 rounded-full p-0.5 text-purple-400 hover:bg-purple-100 hover:text-purple-600 transition-colors", children: _jsx(X, { className: "h-3 w-3" }) })] }, index))) })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { id: "newSuggestedAnswer", placeholder: "Nh\u1EADp \u0111\u00E1p \u00E1n g\u1EE3i \u00FD...", className: "flex-1 border-purple-200 bg-white focus:border-purple-400 focus:ring-purple-200", onKeyDown: (e) => {
335
+ if (e.key === 'Enter') {
336
+ e.preventDefault();
337
+ const input = e.currentTarget;
338
+ const value = input.value.trim();
339
+ if (value) {
340
+ const current = currentQuestion.suggestedAnswers || [];
341
+ updateCurrentQuestion('suggestedAnswers', [...current, value]);
342
+ input.value = '';
343
+ }
344
+ }
345
+ } }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "gap-1 border-purple-300 text-purple-600 hover:bg-purple-100 hover:text-purple-700", onClick: () => {
346
+ const input = document.getElementById('newSuggestedAnswer');
347
+ const value = input?.value.trim();
348
+ if (value) {
349
+ const current = currentQuestion.suggestedAnswers || [];
350
+ updateCurrentQuestion('suggestedAnswers', [...current, value]);
351
+ input.value = '';
352
+ }
353
+ }, children: [_jsx(Plus, { className: "h-3.5 w-3.5" }), "Th\u00EAm"] })] }), _jsx("p", { className: "text-xs text-purple-500", children: "Nh\u1EADp \u0111\u00E1p \u00E1n g\u1EE3i \u00FD r\u1ED3i nh\u1EA5n Enter ho\u1EB7c n\u00FAt Th\u00EAm" })] })] })), externalErrors && externalErrors.length > 0 && (_jsxs("div", { className: "flex items-center gap-2 rounded-md border border-red-200 bg-red-50 p-2 text-xs text-red-700", children: [_jsx("span", { className: "font-semibold text-red-800", children: "L\u1ED7i:" }), _jsx("span", { children: externalErrors.join(' · ') })] }))] }), _jsx(CompactExplanationToggle, { value: explanation, onValueChange: setExplanation })] }));
348
354
  }
349
355
  export function AnswerTheQuestionCreator(props) {
350
356
  return _jsx(AnswerTheQuestionContent, { ...props });
@@ -52,6 +52,6 @@ export function AnswerTheQuestionGroupClient({ questionData, isReviewMode = fals
52
52
  const expectedAnswers = Array.isArray(item.expectedAnswers)
53
53
  ? item.expectedAnswers.filter((answer) => answer.trim() !== '')
54
54
  : [];
55
- return (_jsxs("div", { className: "overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white px-4 py-2.5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-indigo-600 text-white", children: _jsx(CircleHelp, { className: "h-3.5 w-3.5" }) }), _jsxs("span", { className: "text-sm font-medium text-gray-700", children: ["C\u00E2u ", item.questionNumber || itemIndex + 1] }), item.isExample && (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-amber-100 px-2 py-0.5 text-xs font-semibold text-amber-700", children: [_jsx(Star, { className: "h-3 w-3" }), "Example"] })), _jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-violet-100 px-2 py-0.5 text-xs font-semibold text-violet-700", children: [_jsx(Sparkles, { className: "h-3 w-3" }), "AI"] })] }), _jsxs("span", { className: "text-xs text-gray-500", children: [item.points || 0, " \u0111i\u1EC3m"] })] }), _jsxs("div", { className: "space-y-3 p-4", children: [toAnswerTheQuestionGroupImageUrls(item.imageUrl).length > 0 && (_jsx("div", { className: "flex flex-wrap justify-center gap-3", children: toAnswerTheQuestionGroupImageUrls(item.imageUrl).map((url, imageIndex) => (_jsx(MediaPreview, { src: url, alt: `Hình ảnh câu ${item.questionNumber || itemIndex + 1} (${imageIndex + 1})` }, `${item.questionNumber}-${imageIndex}`))) })), _jsx("p", { className: "text-sm font-semibold leading-relaxed text-gray-800", children: item.question || 'Câu hỏi chưa được nhập' }), _jsx("div", { className: "rounded-lg border border-gray-200 bg-gray-50 px-3 py-2 text-sm text-gray-700", children: userValue || (isReviewMode ? '(Chưa trả lời)' : 'Học sinh sẽ nhập câu trả lời tại đây') }), isReviewMode && expectedAnswers.length > 0 && (_jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-xs font-medium text-gray-500", children: "\u0110\u00E1p \u00E1n m\u1EABu (AI)" }), _jsx("ul", { className: "list-disc space-y-1 pl-5 text-sm text-gray-700", children: expectedAnswers.map((answer) => (_jsx("li", { children: answer }, answer))) })] }))] })] }, `${item.questionNumber}-${itemIndex}`));
55
+ return (_jsxs("div", { className: "overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-indigo-600 text-white", children: _jsx(CircleHelp, { className: "h-3.5 w-3.5" }) }), _jsxs("span", { className: "text-sm font-medium text-gray-700", children: ["C\u00E2u ", item.questionNumber || itemIndex + 1] }), item.isExample && (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-amber-100 px-2 py-0.5 text-xs font-semibold text-amber-700", children: [_jsx(Star, { className: "h-3 w-3" }), "Example"] })), _jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-violet-100 px-2 py-0.5 text-xs font-semibold text-violet-700", children: [_jsx(Sparkles, { className: "h-3 w-3" }), "AI"] })] }), _jsxs("span", { className: "text-xs text-gray-500", children: [item.points || 0, " \u0111i\u1EC3m"] })] }), _jsxs("div", { className: "space-y-3 p-3", children: [toAnswerTheQuestionGroupImageUrls(item.imageUrl).length > 0 && (_jsx("div", { className: "flex flex-wrap justify-center gap-3", children: toAnswerTheQuestionGroupImageUrls(item.imageUrl).map((url, imageIndex) => (_jsx(MediaPreview, { src: url, alt: `Hình ảnh câu ${item.questionNumber || itemIndex + 1} (${imageIndex + 1})` }, `${item.questionNumber}-${imageIndex}`))) })), _jsx("p", { className: "text-sm font-semibold leading-relaxed text-gray-800", children: item.question || 'Câu hỏi chưa được nhập' }), _jsx("div", { className: "rounded-lg border border-gray-200 bg-gray-50 px-3 py-2 text-sm text-gray-700", children: userValue || (isReviewMode ? '(Chưa trả lời)' : 'Học sinh sẽ nhập câu trả lời tại đây') }), isReviewMode && expectedAnswers.length > 0 && (_jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-xs font-medium text-gray-500", children: "\u0110\u00E1p \u00E1n m\u1EABu (AI)" }), _jsx("ul", { className: "list-disc space-y-1 pl-5 text-sm text-gray-700", children: expectedAnswers.map((answer) => (_jsx("li", { children: answer }, answer))) })] }))] })] }, `${item.questionNumber}-${itemIndex}`));
56
56
  }), isReviewMode && questionData.explanation && (_jsxs("div", { className: "flex items-start gap-2 rounded-xl border border-amber-100 bg-amber-50 px-4 py-3 text-sm text-amber-800", children: [_jsx(Lightbulb, { className: "mt-0.5 h-4 w-4 flex-shrink-0" }), questionData.explanation] }))] }));
57
57
  }
@@ -10,7 +10,8 @@ import { Card, CardContent, CardHeader, CardTitle } from '../../../../components
10
10
  import { Switch } from '../../../../components/ui/switch';
11
11
  import { RichTextEditor } from '../../../../components/shared/RichTextEditor';
12
12
  import { useDebouncedCallback } from '../../../../shared/lib/hooks';
13
- import { Eye, Pencil, Plus, Sparkles, Star, Trash2 } from 'lucide-react';
13
+ import { MessageSquare, Plus, Star, Trash2 } from 'lucide-react';
14
+ import { CompactCreatorHeader, CompactExplanationToggle, CompactFieldCard, CompactPreviewBanner, } from '../../_shared/components/compact';
14
15
  import { AnswerTheQuestionGroupClient } from './AnswerTheQuestionGroupClient';
15
16
  import { toAnswerTheQuestionGroupImageUrls } from '../../_shared/types/answer-the-question-group.type';
16
17
  const DEFAULT_INSTRUCTION = 'Read the text again and answer the questions.';
@@ -180,10 +181,10 @@ export function AnswerTheQuestionGroupCreator({ initialData, onChange, externalE
180
181
  };
181
182
  const displayErrors = externalErrors && externalErrors.length > 0 ? externalErrors : errors;
182
183
  if (isClientMode) {
183
- return (_jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "flex justify-end", children: _jsxs(Button, { type: "button", variant: "outline", onClick: () => setIsClientMode(false), children: [_jsx(Pencil, { className: "mr-2 h-4 w-4" }), "Ch\u1EBF \u0111\u1ED9 ch\u1EC9nh s\u1EEDa"] }) }), _jsx(AnswerTheQuestionGroupClient, { questionData: buildPayload(), isReviewMode: true })] }));
184
+ return (_jsxs("div", { className: "space-y-4", children: [_jsx(CompactPreviewBanner, { onBack: () => setIsClientMode(false) }), _jsx(AnswerTheQuestionGroupClient, { questionData: buildPayload(), isReviewMode: true })] }));
184
185
  }
185
- return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-lg font-medium text-gray-900", children: "\u0110\u1ECDc v\u00E0 tr\u1EA3 l\u1EDDi c\u00E2u h\u1ECFi (AI)" }), _jsx("p", { className: "text-sm text-gray-500", children: "Nh\u00F3m c\u00E2u \u0111\u1ECDc hi\u1EC3u l\u01B0u 1 row. AI ch\u1EA5m theo question + expectedAnswers." })] }), _jsxs(Button, { type: "button", variant: "outline", onClick: () => setIsClientMode(true), children: [_jsx(Eye, { className: "mr-2 h-4 w-4" }), "Xem tr\u01B0\u1EDBc"] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { children: "Nh\u00F3m \u0111\u1ECDc hi\u1EC3u" }) }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "group-instruction", children: "H\u01B0\u1EDBng d\u1EABn" }), _jsx(Input, { id: "group-instruction", value: instruction, onChange: (event) => setInstruction(event.target.value), placeholder: DEFAULT_INSTRUCTION })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "N\u1ED9i dung b\u00E0i \u0111\u1ECDc (Passage)" }), _jsx(RichTextEditor, { value: passage, onChange: setPassage, minHeightClassName: "min-h-[160px]" })] }), _jsxs("div", { className: "rounded-xl border border-violet-100 bg-violet-50 p-4 text-sm text-violet-800", children: [_jsxs("div", { className: "flex items-center gap-2 font-medium", children: [_jsx(Sparkles, { className: "h-4 w-4" }), "Ch\u1EA5m \u0111i\u1EC3m b\u1EB1ng AI"] }), _jsx("p", { className: "mt-1 text-xs text-violet-700", children: "H\u1ECDc sinh vi\u1EBFt c\u00E2u tr\u1EA3 l\u1EDDi. AI so v\u1EDBi b\u1EA5t k\u1EF3 \u0111\u00E1p \u00E1n m\u1EABu n\u00E0o c\u1EE7a t\u1EEBng c\u00E2u (binary 0/1)." })] }), _jsxs("div", { className: "rounded-xl border border-gray-200 bg-gray-50 p-4", children: [_jsx(PointsInput, { value: sumPoints(items), allowZero: true, readOnly: true }), _jsx("p", { className: "mt-2 text-xs text-gray-500", children: "T\u1ED5ng \u0111i\u1EC3m \u0111\u01B0\u1EE3c c\u1ED9ng t\u1EEB c\u00E1c c\u00E2u kh\u00F4ng ph\u1EA3i example." })] })] })] }), items.map((item, itemIndex) => (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0", children: [_jsxs(CardTitle, { className: "text-base", children: ["C\u00E2u ", itemIndex + 1] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => removeItem(itemIndex), disabled: items.length <= 1, children: _jsx(Trash2, { className: "h-4 w-4" }) })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between rounded-lg border border-amber-100 bg-amber-50 px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm font-medium text-amber-800", children: [_jsx(Star, { className: "h-4 w-4" }), "C\u00E2u v\u00ED d\u1EE5"] }), _jsx(Switch, { checked: item.isExample === true, onCheckedChange: (checked) => updateItem(itemIndex, {
186
- isExample: checked,
187
- points: checked ? 0 : (item.points || 1),
188
- }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "C\u00E2u h\u1ECFi" }), _jsx(Textarea, { value: item.question, onChange: (event) => updateItem(itemIndex, { question: event.target.value }), rows: 2, placeholder: "What is autism?" })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "\u0110\u00E1p \u00E1n m\u1EABu cho AI" }), item.expectedAnswers.map((answer, answerIndex) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { value: answer, onChange: (event) => updateExpectedAnswer(itemIndex, answerIndex, event.target.value), placeholder: `Đáp án mẫu ${answerIndex + 1}` }), item.expectedAnswers.length > 1 && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => removeExpectedAnswer(itemIndex, answerIndex), children: _jsx(Trash2, { className: "h-4 w-4" }) }))] }, `expected-${itemIndex}-${answerIndex}`))), _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => addExpectedAnswer(itemIndex), children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "Th\u00EAm \u0111\u00E1p \u00E1n m\u1EABu"] })] }), !item.isExample && (_jsx(PointsInput, { value: item.points, allowZero: true, onChange: (e) => updateItem(itemIndex, { points: Number(e.target.value) || 0 }) }))] })] }, `item-${itemIndex}`))), _jsxs(Button, { type: "button", variant: "outline", onClick: addItem, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "Th\u00EAm c\u00E2u h\u1ECFi"] }), displayErrors.length > 0 && (_jsx("div", { className: "rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700", children: displayErrors.map((error) => (_jsx("p", { children: error }, error))) }))] }));
186
+ return (_jsxs("div", { className: "space-y-3", children: [displayErrors.length > 0 && (_jsx("div", { className: "rounded-md border border-red-200 bg-red-50 p-2 text-xs text-red-700", children: displayErrors.map((error) => (_jsx("p", { children: error }, error))) })), _jsxs(CompactFieldCard, { header: _jsx(CompactCreatorHeader, { icon: _jsx(MessageSquare, { className: "h-3.5 w-3.5" }), title: "\u0110\u1ECDc v\u00E0 tr\u1EA3 l\u1EDDi c\u00E2u h\u1ECFi (AI)", preview: { onClick: () => setIsClientMode(true) } }), children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "group-instruction", className: "text-sm font-semibold text-gray-800", children: "H\u01B0\u1EDBng d\u1EABn" }), _jsx(Input, { id: "group-instruction", value: instruction, onChange: (event) => setInstruction(event.target.value), placeholder: DEFAULT_INSTRUCTION, className: "h-10 border-gray-200 bg-white" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { className: "text-sm font-semibold text-gray-800", children: "N\u1ED9i dung b\u00E0i \u0111\u1ECDc (Passage)" }), _jsx(RichTextEditor, { value: passage, onChange: setPassage, minHeightClassName: "min-h-[160px]" })] }), _jsxs("div", { className: "rounded-md border border-gray-200 bg-gray-50 px-3 py-2.5", children: [_jsx(PointsInput, { value: sumPoints(items), allowZero: true, readOnly: true }), _jsx("p", { className: "mt-1.5 text-xs text-gray-500", children: "T\u1ED5ng \u0111i\u1EC3m \u0111\u01B0\u1EE3c c\u1ED9ng t\u1EEB c\u00E1c c\u00E2u kh\u00F4ng ph\u1EA3i example." })] })] }), _jsxs(Card, { className: "overflow-hidden border-0 bg-white shadow-sm", children: [_jsx(CardHeader, { className: "px-3 py-2", children: _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsxs(CardTitle, { className: "text-sm font-semibold text-gray-800", children: ["Danh s\u00E1ch c\u00E2u h\u1ECFi (", items.length, ")"] }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: addItem, className: "h-8 gap-1.5 px-2.5 text-xs", children: [_jsx(Plus, { className: "h-3.5 w-3.5" }), "Th\u00EAm c\u00E2u h\u1ECFi"] })] }) }), _jsxs(CardContent, { className: "space-y-2.5 px-3 pb-3", children: [items.map((item, itemIndex) => (_jsxs("div", { className: "space-y-2.5 rounded-md border border-gray-200 bg-white px-3 py-2.5", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("span", { className: "text-sm font-medium text-gray-700", children: ["C\u00E2u ", itemIndex + 1] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { checked: item.isExample === true, onCheckedChange: (checked) => updateItem(itemIndex, {
187
+ isExample: checked,
188
+ points: checked ? 0 : (item.points || 1),
189
+ }) }), _jsxs(Label, { className: "flex cursor-pointer items-center gap-1 text-xs", children: [_jsx(Star, { className: "h-3 w-3 text-amber-500" }), "C\u00E2u v\u00ED d\u1EE5"] })] }), !item.isExample && (_jsx(PointsInput, { value: item.points, allowZero: true, onChange: (e) => updateItem(itemIndex, { points: Number(e.target.value) || 0 }) })), _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => removeItem(itemIndex), disabled: items.length <= 1, className: "h-7 w-7 text-red-500 hover:bg-red-50 hover:text-red-600", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) })] })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: "C\u00E2u h\u1ECFi" }), _jsx(Textarea, { value: item.question, onChange: (event) => updateItem(itemIndex, { question: event.target.value }), rows: 2, placeholder: "What is autism?", className: "min-h-[56px] border-gray-200 bg-white" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: "\u0110\u00E1p \u00E1n m\u1EABu cho AI" }), item.expectedAnswers.map((answer, answerIndex) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { value: answer, onChange: (event) => updateExpectedAnswer(itemIndex, answerIndex, event.target.value), placeholder: `Đáp án mẫu ${answerIndex + 1}`, className: "h-10 border-gray-200 bg-white" }), item.expectedAnswers.length > 1 && (_jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => removeExpectedAnswer(itemIndex, answerIndex), className: "h-7 w-7 text-red-500 hover:bg-red-50 hover:text-red-600", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }))] }, `expected-${itemIndex}-${answerIndex}`))), _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => addExpectedAnswer(itemIndex), className: "h-8 gap-1.5 px-2.5 text-xs", children: [_jsx(Plus, { className: "h-3.5 w-3.5" }), "Th\u00EAm \u0111\u00E1p \u00E1n m\u1EABu"] })] })] }, `item-${itemIndex}`))), _jsx(CompactExplanationToggle, { value: explanation, onValueChange: setExplanation, defaultVisible: Boolean(initialData?.explanation) })] })] })] }));
189
190
  }