@tinyweb_dev/oe-exam-sdk 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/exam-create.js +1 -179
- package/dist/api/exam-create.types.js +1 -1
- package/dist/api/exam-questions.d.ts +1 -1
- package/dist/api/exam-questions.js +1 -98
- package/dist/api/exam-questions.types.d.ts +45 -1
- package/dist/api/exam-questions.types.js +1 -1
- package/dist/api/exam-taking.js +1 -73
- package/dist/api/exam-taking.types.js +1 -1
- package/dist/api/index.js +1 -6
- package/dist/api/result-review.js +1 -50
- package/dist/api/result-review.types.js +1 -1
- package/dist/components/CueCardEditor.js +1 -58
- package/dist/components/common/ResolvedImage.js +1 -15
- package/dist/components/exams/CompletionDialog.d.ts +8 -0
- package/dist/components/exams/CompletionDialog.js +1 -0
- package/dist/components/exams/CreateExamInfoForm.d.ts +4 -1
- package/dist/components/exams/CreateExamInfoForm.js +1 -35
- package/dist/components/exams/CreateExamPageContainer.d.ts +3 -0
- package/dist/components/exams/CreateExamPageContainer.js +1 -103
- package/dist/components/exams/ExamCreator.d.ts +9 -3
- package/dist/components/exams/ExamCreator.js +1 -89
- package/dist/components/exams/ExamPartTabs.d.ts +1 -1
- package/dist/components/exams/ExamPartTabs.js +1 -40
- package/dist/components/exams/ExamPreviewDialog.d.ts +20 -0
- package/dist/components/exams/ExamPreviewDialog.js +1 -0
- package/dist/components/exams/ExamQuestionGrid.d.ts +1 -1
- package/dist/components/exams/ExamQuestionGrid.js +1 -18
- package/dist/components/exams/ExamQuestionsPageContainer.d.ts +3 -0
- package/dist/components/exams/ExamQuestionsPageContainer.js +1 -90
- package/dist/components/exams/ExamViewDialog.d.ts +24 -0
- package/dist/components/exams/ExamViewDialog.js +1 -0
- package/dist/components/exams/PartAudioUploader.js +1 -9
- package/dist/components/exams/TemplateSelector.js +1 -66
- package/dist/components/exams/UnsavedChangesDialog.d.ts +8 -0
- package/dist/components/exams/UnsavedChangesDialog.js +1 -0
- package/dist/components/exams/api.d.ts +1 -1
- package/dist/components/exams/api.js +1 -3
- package/dist/components/exams/create-exam.texts.d.ts +58 -0
- package/dist/components/exams/create-exam.texts.js +1 -0
- package/dist/components/exams/create-exam.validation.js +1 -18
- package/dist/components/exams/exam-question-status.d.ts +9 -0
- package/dist/components/exams/exam-question-status.js +1 -0
- package/dist/components/exams/exam-template.utils.js +1 -18
- package/dist/components/exams/index.d.ts +11 -1
- package/dist/components/exams/index.js +1 -10
- package/dist/components/exams/take/ExamTakingPageContainer.js +1 -153
- package/dist/components/exams/take/GenericQuestionRenderer.js +1 -14
- package/dist/components/exams/take/exam-taking.utils.js +1 -88
- package/dist/components/exams/take/hooks/useSpeakingRecorder.js +1 -24
- package/dist/components/exams/take/index.js +1 -2
- package/dist/components/exams/take/types.js +1 -1
- package/dist/components/index.js +1 -42
- package/dist/components/questions/_shared/config/question-types.config.js +1 -333
- package/dist/components/questions/_shared/constants/color-palette.js +1 -21
- package/dist/components/questions/_shared/hooks/useAnswerGroupQuestionGroup.js +1 -105
- package/dist/components/questions/_shared/hooks/useBasicQuestionGroup.js +1 -222
- package/dist/components/questions/_shared/hooks/useCompareImagesGroup.js +1 -140
- package/dist/components/questions/_shared/hooks/useImageQuestionGroup.js +1 -123
- package/dist/components/questions/_shared/hooks/useInfoExchangeGroup.js +1 -50
- package/dist/components/questions/_shared/hooks/useQuestionFormState.js +1 -54
- package/dist/components/questions/_shared/hooks/useQuestionInitialization.js +1 -123
- package/dist/components/questions/_shared/hooks/useQuestionListGroup.js +1 -121
- package/dist/components/questions/_shared/hooks/useQuestionOnChange.js +1 -70
- package/dist/components/questions/_shared/hooks/useSceneQuestionGroup.js +1 -194
- package/dist/components/questions/_shared/index.js +1 -7
- package/dist/components/questions/_shared/types/answer-the-question.type.js +1 -1
- package/dist/components/questions/_shared/types/arrange-letters-into-words.type.js +1 -1
- package/dist/components/questions/_shared/types/choose-correct-adjective.type.js +1 -3
- package/dist/components/questions/_shared/types/color-region.config.js +1 -1
- package/dist/components/questions/_shared/types/fill-in-blank.type.js +1 -1
- package/dist/components/questions/_shared/types/fill-missing-words-in-grid.type.js +1 -1
- package/dist/components/questions/_shared/types/gn-speaking-interview.type.js +1 -1
- package/dist/components/questions/_shared/types/index.js +1 -12
- package/dist/components/questions/_shared/types/label-the-picture.type.js +1 -1
- package/dist/components/questions/_shared/types/listen-and-choose-from-answer-group.type.js +1 -1
- package/dist/components/questions/_shared/types/listen-and-choose-objects-in-scene.type.js +1 -1
- package/dist/components/questions/_shared/types/listen-and-drag-objects-into-scene.type.js +1 -1
- package/dist/components/questions/_shared/types/listen-and-speak-answer.type.js +1 -1
- package/dist/components/questions/_shared/types/listen-and-speak-compare-images.type.js +1 -1
- package/dist/components/questions/_shared/types/listen-and-speak-image-group.type.js +1 -1
- package/dist/components/questions/_shared/types/listen-and-speak-info-exchange.type.js +1 -1
- package/dist/components/questions/_shared/types/listen-and-speak-odd-one-out.type.js +1 -3
- package/dist/components/questions/_shared/types/listen-and-speak-question-list.type.js +1 -1
- package/dist/components/questions/_shared/types/listen-and-speak-with-story-images.type.js +1 -3
- package/dist/components/questions/_shared/types/listen-and-tick-answer.type.js +1 -1
- package/dist/components/questions/_shared/types/listening-drawline.type.js +1 -1
- package/dist/components/questions/_shared/types/look-and-choose-answer.type.js +1 -1
- package/dist/components/questions/_shared/types/look-picture-fill-word-hint.type.js +1 -1
- package/dist/components/questions/_shared/types/match-by-writing-answer.type.js +1 -1
- package/dist/components/questions/_shared/types/multiple-choice.type.js +1 -1
- package/dist/components/questions/_shared/types/question-group.type.js +1 -11
- package/dist/components/questions/_shared/types/read-and-color-objects.type.js +1 -1
- package/dist/components/questions/_shared/types/read-displayed-content.type.js +1 -1
- package/dist/components/questions/_shared/types/read-passage-and-answer-questions.type.js +1 -1
- package/dist/components/questions/_shared/types/speaking-describe-image.type.js +1 -1
- package/dist/components/questions/_shared/types/spontaneous-qa.type.js +1 -1
- package/dist/components/questions/_shared/types/word-fill-paragraph-with-options.type.js +1 -1
- package/dist/components/questions/_shared/types/word-fill-paragraph.type.js +1 -1
- package/dist/components/questions/_shared/types/word-fill-structured-form.type.js +1 -1
- package/dist/components/questions/_shared/types/word-ordering.type.js +1 -1
- package/dist/components/questions/_shared/types/write-a-short-letter.type.js +1 -1
- package/dist/components/questions/_shared/types/write-correct-verb-form.type.js +1 -3
- package/dist/components/questions/_shared/types/write-sentences.type.js +1 -1
- package/dist/components/questions/_shared/types/write-short-paragraph.type.js +1 -1
- package/dist/components/questions/_shared/utils/answer-builder.js +1 -79
- package/dist/components/questions/_shared/utils/createColorRegionRegistration.js +1 -39
- package/dist/components/questions/_shared/utils/id-generator.js +1 -3
- package/dist/components/questions/_shared/utils/question-validation.js +1 -21
- package/dist/components/questions/components/ColorNode.js +1 -85
- package/dist/components/questions/components/ColorRegionClient.js +1 -545
- package/dist/components/questions/components/ColorRegionCreator.js +1 -420
- package/dist/components/questions/components/ColorRegionNode.js +1 -59
- package/dist/components/questions/components/CreatorGuide.js +1 -103
- package/dist/components/questions/components/NameNode.js +1 -26
- package/dist/components/questions/components/QuestionBankOption.js +1 -46
- package/dist/components/questions/components/QuestionBasicInfoForm.js +1 -9
- package/dist/components/questions/components/QuestionCommonFields.js +1 -33
- package/dist/components/questions/components/QuestionSearchDropdown.js +1 -258
- package/dist/components/questions/components/QuestionTypeSelector.js +1 -32
- package/dist/components/questions/components/QuestionTypeSpecificForms.js +1 -6
- package/dist/components/questions/components/RegionNode.js +1 -94
- package/dist/components/questions/components/index.js +1 -14
- package/dist/components/questions/creator/QuestionCreator.js +1 -90
- package/dist/components/questions/creator/QuestionGroupCreator.js +1 -119
- package/dist/components/questions/creator/dedicated-component-router.js +1 -79
- package/dist/components/questions/creator/index.js +1 -3
- package/dist/components/questions/creator/question-type-registry.js +1 -80
- package/dist/components/questions/groups/ArticlesGroupCard.js +1 -121
- package/dist/components/questions/groups/BasicQuestionGroupCard.js +1 -50
- package/dist/components/questions/groups/DocumentGroupCard.js +1 -114
- package/dist/components/questions/groups/MatchAnswerGroupCard.js +1 -25
- package/dist/components/questions/index.js +1 -10
- package/dist/components/questions/types/answer-the-question/AnswerTheQuestionClient.js +1 -37
- package/dist/components/questions/types/answer-the-question/AnswerTheQuestionCreator.js +1 -351
- package/dist/components/questions/types/answer-the-question/register.js +1 -67
- package/dist/components/questions/types/answer-the-question/transform.js +1 -36
- package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsClient.js +1 -141
- package/dist/components/questions/types/arrange-letters-into-words/ArrangeLettersIntoWordsCreator.js +1 -118
- package/dist/components/questions/types/arrange-letters-into-words/index.js +1 -2
- package/dist/components/questions/types/arrange-letters-into-words/register.js +1 -4
- package/dist/components/questions/types/arrange-letters-into-words/transform.js +1 -24
- package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveClient.js +1 -64
- package/dist/components/questions/types/choose-correct-adjective/ChooseCorrectAdjectiveCreator.js +1 -169
- package/dist/components/questions/types/choose-correct-adjective/index.js +1 -2
- package/dist/components/questions/types/choose-correct-adjective/register.js +1 -55
- package/dist/components/questions/types/choose-correct-adjective/transform.js +1 -16
- package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerClient.js +1 -131
- package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerCreator.js +1 -581
- package/dist/components/questions/types/choose-the-correct-answer/index.js +1 -2
- package/dist/components/questions/types/choose-the-correct-answer/register.js +1 -101
- package/dist/components/questions/types/choose-the-correct-answer/transform.js +1 -43
- package/dist/components/questions/types/fill-in-blank/FillInBlankClient.js +1 -275
- package/dist/components/questions/types/fill-in-blank/FillInBlankCreator.js +1 -448
- package/dist/components/questions/types/fill-in-blank/index.js +1 -2
- package/dist/components/questions/types/fill-in-blank/register.js +1 -138
- package/dist/components/questions/types/fill-in-blank/transform.js +1 -59
- package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridClient.js +1 -117
- package/dist/components/questions/types/fill-missing-words-in-grid/FillMissingWordsInGridCreator.js +1 -671
- package/dist/components/questions/types/fill-missing-words-in-grid/index.js +1 -2
- package/dist/components/questions/types/fill-missing-words-in-grid/register.js +1 -37
- package/dist/components/questions/types/fill-missing-words-in-grid/transform.js +1 -15
- package/dist/components/questions/types/gn-speaking-interview/GNSpeakingInterviewCreator.js +1 -262
- package/dist/components/questions/types/gn-speaking-interview/register.js +1 -121
- package/dist/components/questions/types/gn-speaking-interview/transform.js +1 -48
- package/dist/components/questions/types/image-object-matching/ImageObjectMatchingClient.js +1 -16
- package/dist/components/questions/types/image-object-matching/ImageObjectMatchingCreator.js +1 -27
- package/dist/components/questions/types/image-object-matching/index.js +1 -2
- package/dist/components/questions/types/image-object-matching/register.js +1 -3
- package/dist/components/questions/types/image-object-matching/transform.js +1 -2
- package/dist/components/questions/types/label-the-picture/LabelThePictureClient.js +1 -102
- package/dist/components/questions/types/label-the-picture/LabelThePictureCreator.js +1 -344
- package/dist/components/questions/types/label-the-picture/index.js +1 -2
- package/dist/components/questions/types/label-the-picture/register.js +1 -54
- package/dist/components/questions/types/label-the-picture/transform.js +1 -28
- package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupClient.js +1 -78
- package/dist/components/questions/types/listen-and-choose-from-answer-group/ListenAndChooseFromAnswerGroupCreator.js +1 -232
- package/dist/components/questions/types/listen-and-choose-from-answer-group/index.js +1 -2
- package/dist/components/questions/types/listen-and-choose-from-answer-group/register.js +1 -82
- package/dist/components/questions/types/listen-and-choose-from-answer-group/transform.js +1 -27
- package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneClient.js +1 -70
- package/dist/components/questions/types/listen-and-choose-objects-in-scene/ListenAndChooseObjectsInSceneCreator.js +1 -386
- package/dist/components/questions/types/listen-and-choose-objects-in-scene/index.js +1 -2
- package/dist/components/questions/types/listen-and-choose-objects-in-scene/register.js +1 -100
- package/dist/components/questions/types/listen-and-choose-objects-in-scene/transform.js +1 -33
- package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneClient.js +1 -106
- package/dist/components/questions/types/listen-and-drag-objects-into-scene/ListenAndDragObjectsIntoSceneCreator.js +1 -457
- package/dist/components/questions/types/listen-and-drag-objects-into-scene/index.js +1 -2
- package/dist/components/questions/types/listen-and-drag-objects-into-scene/register.js +1 -110
- package/dist/components/questions/types/listen-and-drag-objects-into-scene/transform.js +1 -35
- package/dist/components/questions/types/listen-and-speak-answer/ArrowIndicator.js +1 -8
- package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerClient.js +1 -22
- package/dist/components/questions/types/listen-and-speak-answer/ListenAndSpeakAnswerCreator.js +1 -291
- package/dist/components/questions/types/listen-and-speak-answer/index.js +1 -2
- package/dist/components/questions/types/listen-and-speak-answer/register.js +1 -84
- package/dist/components/questions/types/listen-and-speak-answer/transform.js +1 -27
- package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesClient.js +1 -32
- package/dist/components/questions/types/listen-and-speak-compare-images/ListenAndSpeakCompareImagesCreator.js +1 -295
- package/dist/components/questions/types/listen-and-speak-compare-images/register.js +1 -79
- package/dist/components/questions/types/listen-and-speak-compare-images/transform.js +1 -27
- package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupClient.js +1 -34
- package/dist/components/questions/types/listen-and-speak-image-group/ListenAndSpeakImageGroupCreator.js +1 -285
- package/dist/components/questions/types/listen-and-speak-image-group/register.js +1 -81
- package/dist/components/questions/types/listen-and-speak-image-group/transform.js +1 -26
- package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeClient.js +1 -38
- package/dist/components/questions/types/listen-and-speak-info-exchange/ListenAndSpeakInfoExchangeCreator.js +1 -385
- package/dist/components/questions/types/listen-and-speak-info-exchange/register.js +1 -87
- package/dist/components/questions/types/listen-and-speak-info-exchange/transform.js +1 -32
- package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutClient.js +1 -26
- package/dist/components/questions/types/listen-and-speak-odd-one-out/ListenAndSpeakOddOneOutCreator.js +1 -247
- package/dist/components/questions/types/listen-and-speak-odd-one-out/register.js +1 -59
- package/dist/components/questions/types/listen-and-speak-odd-one-out/transform.js +1 -18
- package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListClient.js +1 -26
- package/dist/components/questions/types/listen-and-speak-question-list/ListenAndSpeakQuestionListCreator.js +1 -256
- package/dist/components/questions/types/listen-and-speak-question-list/register.js +1 -81
- package/dist/components/questions/types/listen-and-speak-question-list/transform.js +1 -26
- package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesClient.js +1 -26
- package/dist/components/questions/types/listen-and-speak-with-story-images/ListenAndSpeakWithStoryImagesCreator.js +1 -230
- package/dist/components/questions/types/listen-and-speak-with-story-images/register.js +1 -56
- package/dist/components/questions/types/listen-and-speak-with-story-images/transform.js +1 -16
- package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerClient.js +1 -72
- package/dist/components/questions/types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerCreator.js +1 -230
- package/dist/components/questions/types/look-picture-choose-correct-answer/index.js +1 -1
- package/dist/components/questions/types/look-picture-choose-correct-answer/register.js +1 -66
- package/dist/components/questions/types/look-picture-choose-correct-answer/transform.js +1 -42
- package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerClient.js +1 -96
- package/dist/components/questions/types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerCreator.js +1 -238
- package/dist/components/questions/types/look-picture-fill-blank-choose-answer/index.js +1 -2
- package/dist/components/questions/types/look-picture-fill-blank-choose-answer/register.js +1 -76
- package/dist/components/questions/types/look-picture-fill-blank-choose-answer/transform.js +1 -19
- package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintClient.js +1 -134
- package/dist/components/questions/types/look-picture-fill-word-hint/LookPictureFillWordHintCreator.js +1 -617
- package/dist/components/questions/types/look-picture-fill-word-hint/index.js +1 -2
- package/dist/components/questions/types/look-picture-fill-word-hint/register.js +1 -82
- package/dist/components/questions/types/look-picture-fill-word-hint/transform.js +1 -29
- package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerClient.js +1 -38
- package/dist/components/questions/types/match-by-writing-answer/MatchByWritingAnswerCreator.js +1 -359
- package/dist/components/questions/types/match-by-writing-answer/index.js +1 -3
- package/dist/components/questions/types/match-by-writing-answer/register.js +1 -58
- package/dist/components/questions/types/match-by-writing-answer/transform.js +1 -61
- package/dist/components/questions/types/read-and-color-objects/ReadAndColorObjectsClient.js +1 -16
- package/dist/components/questions/types/read-and-color-objects/ReadAndColorObjectsCreator.js +1 -23
- package/dist/components/questions/types/read-and-color-objects/index.js +1 -2
- package/dist/components/questions/types/read-and-color-objects/register.js +1 -3
- package/dist/components/questions/types/read-and-color-objects/transform.js +1 -36
- package/dist/components/questions/types/read-displayed-content/ReadDisplayedContentCreator.js +1 -125
- package/dist/components/questions/types/read-displayed-content/register.js +1 -64
- package/dist/components/questions/types/read-displayed-content/transform.js +1 -12
- package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsClient.js +1 -64
- package/dist/components/questions/types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsCreator.js +1 -511
- package/dist/components/questions/types/read-passage-and-answer-questions/index.js +1 -2
- package/dist/components/questions/types/read-passage-and-answer-questions/register.js +1 -58
- package/dist/components/questions/types/read-passage-and-answer-questions/transform.js +1 -28
- package/dist/components/questions/types/speaking-conversation/SpeakingConversationCreator.js +1 -373
- package/dist/components/questions/types/speaking-conversation/SpeakingConversationPreviewClient.js +1 -41
- package/dist/components/questions/types/speaking-conversation/register.js +1 -110
- package/dist/components/questions/types/speaking-conversation/transform.js +1 -34
- package/dist/components/questions/types/speaking-cue-card/SpeakingCueCardCreator.js +1 -74
- package/dist/components/questions/types/speaking-cue-card/register.js +1 -52
- package/dist/components/questions/types/speaking-cue-card/transform.js +1 -12
- package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageClient.js +1 -10
- package/dist/components/questions/types/speaking-describe-image/SpeakingDescribeImageCreator.js +1 -161
- package/dist/components/questions/types/speaking-describe-image/index.js +1 -2
- package/dist/components/questions/types/speaking-describe-image/register.js +1 -69
- package/dist/components/questions/types/speaking-describe-image/transform.js +1 -16
- package/dist/components/questions/types/spontaneous-qa/SpontaneousQACreator.js +1 -234
- package/dist/components/questions/types/spontaneous-qa/register.js +1 -93
- package/dist/components/questions/types/spontaneous-qa/transform.js +1 -34
- package/dist/components/questions/types/true-false/TrueFalseClient.js +1 -75
- package/dist/components/questions/types/true-false/TrueFalseCreator.js +1 -244
- package/dist/components/questions/types/true-false/index.js +1 -2
- package/dist/components/questions/types/true-false/register.js +1 -77
- package/dist/components/questions/types/true-false/transform.js +1 -32
- package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphClient.js +1 -233
- package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphCreator.js +1 -631
- package/dist/components/questions/types/word-fill-paragraph/WordFillParagraphWrapper.js +1 -28
- package/dist/components/questions/types/word-fill-paragraph/index.js +1 -2
- package/dist/components/questions/types/word-fill-paragraph/register.js +1 -136
- package/dist/components/questions/types/word-fill-paragraph/transform.js +1 -56
- package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormClient.js +1 -138
- package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormCreator.js +1 -261
- package/dist/components/questions/types/word-fill-structured-form/index.js +1 -2
- package/dist/components/questions/types/word-fill-structured-form/register.js +1 -67
- package/dist/components/questions/types/word-fill-structured-form/transform.js +1 -40
- package/dist/components/questions/types/word-ordering/WordOrderingClient.js +1 -84
- package/dist/components/questions/types/word-ordering/WordOrderingCreator.js +1 -192
- package/dist/components/questions/types/word-ordering/index.js +1 -2
- package/dist/components/questions/types/word-ordering/register.js +1 -46
- package/dist/components/questions/types/word-ordering/transform.js +1 -24
- package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterClient.js +1 -98
- package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterCreator.js +1 -320
- package/dist/components/questions/types/write-a-short-letter/index.js +1 -2
- package/dist/components/questions/types/write-a-short-letter/register.js +1 -68
- package/dist/components/questions/types/write-a-short-letter/transform.js +1 -25
- package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormClient.js +1 -61
- package/dist/components/questions/types/write-correct-verb-form/WriteCorrectVerbFormCreator.js +1 -196
- package/dist/components/questions/types/write-correct-verb-form/index.js +1 -2
- package/dist/components/questions/types/write-correct-verb-form/register.js +1 -62
- package/dist/components/questions/types/write-correct-verb-form/transform.js +1 -17
- package/dist/components/questions/types/write-sentences/WriteSentencesClient.js +1 -22
- package/dist/components/questions/types/write-sentences/WriteSentencesCreator.js +1 -174
- package/dist/components/questions/types/write-sentences/index.js +1 -2
- package/dist/components/questions/types/write-sentences/register.js +1 -58
- package/dist/components/questions/types/write-sentences/transform.js +1 -28
- package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphClient.js +1 -96
- package/dist/components/questions/types/write-short-paragraph/WriteShortParagraphCreator.js +1 -161
- package/dist/components/questions/types/write-short-paragraph/index.js +1 -2
- package/dist/components/questions/types/write-short-paragraph/register.js +1 -4
- package/dist/components/questions/types/write-short-paragraph/transform.js +1 -21
- package/dist/components/questions/viewer/QuestionGroupViewer.js +1 -36
- package/dist/components/questions/viewer/QuestionViewer.js +1 -446
- package/dist/components/questions/viewer/index.js +1 -2
- package/dist/components/results/ResultReviewPageContainer.js +1 -98
- package/dist/components/results/ReviewQuestionRenderer.js +1 -72
- package/dist/components/results/index.js +1 -2
- package/dist/components/results/result-review.utils.js +1 -6
- package/dist/components/results/review-data.js +1 -150
- package/dist/components/results/review-renderer.utils.js +1 -97
- package/dist/components/results/review-types.js +1 -1
- package/dist/components/themes/cambridge-yle/CambridgeYleAudioPlayer.js +1 -138
- package/dist/components/themes/cambridge-yle/CambridgeYleBottomNav.js +1 -12
- package/dist/components/themes/cambridge-yle/CambridgeYleExamLayout.js +1 -18
- package/dist/components/themes/cambridge-yle/CambridgeYleExampleText.js +1 -11
- package/dist/components/themes/cambridge-yle/CambridgeYleHeader.js +1 -11
- package/dist/components/themes/cambridge-yle/CambridgeYleInstructionBanner.js +1 -9
- package/dist/components/themes/cambridge-yle/CambridgeYleNavButton.js +1 -13
- package/dist/components/themes/cambridge-yle/CambridgeYlePartBanner.js +1 -8
- package/dist/components/themes/cambridge-yle/CambridgeYleProgressBar.js +1 -6
- package/dist/components/themes/cambridge-yle/CambridgeYleQuestionCard.js +1 -5
- package/dist/components/themes/cambridge-yle/CambridgeYleQuestionCardFullWidth.js +1 -9
- package/dist/components/themes/cambridge-yle/CambridgeYleSidebar.js +1 -41
- package/dist/components/themes/cambridge-yle/CambridgeYleTimer.js +1 -25
- package/dist/components/themes/cambridge-yle/index.js +1 -13
- package/dist/components/themes/english-certification/EcAnswerTheQuestion.js +1 -24
- package/dist/components/themes/english-certification/EcMatchByWritingAnswer.js +1 -88
- package/dist/components/themes/english-certification/EcWordFillParagraph.js +1 -55
- package/dist/components/themes/english-certification/EcWordFillStructuredForm.js +1 -156
- package/dist/components/themes/english-certification/EcWritingTask.js +1 -34
- package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.js +1 -114
- package/dist/components/themes/english-certification/EnglishCertificationBrand.js +1 -11
- package/dist/components/themes/english-certification/EnglishCertificationExamLayout.js +1 -21
- package/dist/components/themes/english-certification/EnglishCertificationFlagButton.js +1 -15
- package/dist/components/themes/english-certification/EnglishCertificationFooterBar.js +1 -19
- package/dist/components/themes/english-certification/EnglishCertificationGroupedQuestion.js +1 -148
- package/dist/components/themes/english-certification/EnglishCertificationHeader.js +1 -31
- package/dist/components/themes/english-certification/EnglishCertificationNavigationPanel.js +1 -71
- package/dist/components/themes/english-certification/EnglishCertificationOptionSelector.js +1 -33
- package/dist/components/themes/english-certification/EnglishCertificationPassagePanel.js +1 -16
- package/dist/components/themes/english-certification/EnglishCertificationQuestionCard.js +1 -22
- package/dist/components/themes/english-certification/EnglishCertificationQuestionItem.js +1 -37
- package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.js +1 -72
- package/dist/components/themes/english-certification/EnglishCertificationReadingSection.js +1 -90
- package/dist/components/themes/english-certification/EnglishCertificationSingleQuestion.js +1 -18
- package/dist/components/themes/english-certification/EnglishCertificationSingleQuestionList.js +1 -29
- package/dist/components/themes/english-certification/english-certification-theme.js +1 -58
- package/dist/components/themes/english-certification/grouped-question-utils.js +1 -218
- package/dist/components/themes/english-certification/index.js +1 -21
- package/dist/components/themes/index.js +1 -6
- package/dist/components/themes/summer-sky/SummerSkyAudioPlayer.js +1 -170
- package/dist/components/themes/summer-sky/SummerSkyLayout.js +1 -221
- package/dist/components/themes/summer-sky/SummerSkySubmitModal.js +1 -18
- package/dist/components/themes/summer-sky/SummerSkyWaitingRoom.js +1 -194
- package/dist/components/themes/types.js +1 -1
- package/dist/components/ui/alert-dialog.js +1 -26
- package/dist/components/ui/alert.js +1 -22
- package/dist/components/ui/avatar.js +1 -12
- package/dist/components/ui/badge.js +1 -38
- package/dist/components/ui/button.js +1 -35
- package/dist/components/ui/calendar.js +1 -76
- package/dist/components/ui/card.js +1 -16
- package/dist/components/ui/carousel.js +1 -91
- package/dist/components/ui/checkbox.js +1 -9
- package/dist/components/ui/collapsible.js +1 -13
- package/dist/components/ui/command.js +1 -34
- package/dist/components/ui/confirm-dialog.js +1 -49
- package/dist/components/ui/dialog.js +1 -23
- package/dist/components/ui/drawer.js +1 -35
- package/dist/components/ui/dropdown-menu.js +1 -33
- package/dist/components/ui/file-upload.js +1 -155
- package/dist/components/ui/form.js +1 -62
- package/dist/components/ui/hover-card.js +1 -10
- package/dist/components/ui/image-preview.js +1 -29
- package/dist/components/ui/input.js +1 -8
- package/dist/components/ui/label.js +1 -9
- package/dist/components/ui/language-switcher.js +1 -15
- package/dist/components/ui/multi-select.js +1 -90
- package/dist/components/ui/points-input.js +1 -33
- package/dist/components/ui/popover.js +1 -26
- package/dist/components/ui/progress.js +1 -16
- package/dist/components/ui/radio-group.js +1 -12
- package/dist/components/ui/scroll-area.js +1 -11
- package/dist/components/ui/select.js +1 -38
- package/dist/components/ui/separator.js +1 -8
- package/dist/components/ui/sheet.js +1 -40
- package/dist/components/ui/single-select.js +1 -76
- package/dist/components/ui/skeleton.js +1 -6
- package/dist/components/ui/switch.js +1 -8
- package/dist/components/ui/table.js +1 -20
- package/dist/components/ui/tabs.js +1 -17
- package/dist/components/ui/textarea.js +1 -8
- package/dist/components/ui/tooltip.js +1 -11
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -19
- package/dist/mcp/config.js +1 -32
- package/dist/mcp/http-client.js +1 -48
- package/dist/mcp/index.js +1 -29
- package/dist/mcp/tools/_helpers.js +1 -25
- package/dist/mcp/tools/exams.js +1 -439
- package/dist/mcp/tools/index.js +1 -6
- package/dist/mcp/tools/results.js +1 -19
- package/dist/shared/constants/ApiConstant.js +1 -276
- package/dist/shared/constants/QueryKeyConstant.js +1 -112
- package/dist/shared/constants/exam-level.enum.js +1 -41
- package/dist/shared/constants/landings/placement-test.constants.js +1 -431
- package/dist/shared/constants/question-skills.js +1 -267
- package/dist/shared/constants/routes.js +1 -81
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +1 -7
- package/dist/shared/lib/hooks/index.js +1 -10
- package/dist/shared/lib/hooks/useAlertDialog.js +1 -57
- package/dist/shared/lib/hooks/useAudioPlayCounter.js +1 -30
- package/dist/shared/lib/hooks/useAudioPreview.js +1 -81
- package/dist/shared/lib/hooks/useAudioUpload.js +1 -24
- package/dist/shared/lib/hooks/useConfirmDialog.js +1 -89
- package/dist/shared/lib/hooks/useDebouncedCallback.js +1 -32
- package/dist/shared/lib/hooks/useDelayedAutoPlay.js +1 -12
- package/dist/shared/lib/hooks/useFileUpload.js +1 -24
- package/dist/shared/lib/hooks/useImageUrl.js +1 -5
- package/dist/shared/lib/hooks/usePresignedFileUrl.js +1 -10
- package/dist/shared/lib/hooks/useReactHookForm.js +1 -31
- package/dist/shared/lib/hooks/useToast.js +1 -62
- package/dist/shared/lib/i18n/index.js +1 -54
- package/dist/shared/lib/i18n/messages/en/admin.js +1 -2104
- package/dist/shared/lib/i18n/messages/en/auth.js +1 -86
- package/dist/shared/lib/i18n/messages/en/common.js +1 -140
- package/dist/shared/lib/i18n/messages/en/file-upload.js +1 -18
- package/dist/shared/lib/i18n/messages/en/student.js +1 -133
- package/dist/shared/lib/i18n/messages/en/terms.js +1 -37
- package/dist/shared/lib/i18n/messages/en.js +1 -15
- package/dist/shared/lib/i18n/messages/vi/admin.js +1 -2104
- package/dist/shared/lib/i18n/messages/vi/auth.js +1 -86
- package/dist/shared/lib/i18n/messages/vi/common.js +1 -140
- package/dist/shared/lib/i18n/messages/vi/file-upload.js +1 -18
- package/dist/shared/lib/i18n/messages/vi/student.js +1 -133
- package/dist/shared/lib/i18n/messages/vi/terms.js +1 -37
- package/dist/shared/lib/i18n/messages/vi.js +1 -15
- package/dist/shared/lib/i18n/types.js +1 -1
- package/dist/shared/lib/stores/examQuestionStore.js +1 -212
- package/dist/shared/lib/stores/localeStore.js +1 -10
- package/dist/shared/lib/utils/public-page.js +1 -44
- package/dist/shared/lib/utils/question-reverse-transform.d.ts +6 -0
- package/dist/shared/lib/utils/question-reverse-transform.js +1 -0
- package/dist/shared/lib/utils/question-transform-types.js +1 -1
- package/dist/shared/lib/utils/question-transform-validation.d.ts +6 -0
- package/dist/shared/lib/utils/question-transform-validation.js +1 -0
- package/dist/shared/lib/utils/question-transform.d.ts +6 -2
- package/dist/shared/lib/utils/question-transform.js +1 -174
- package/dist/shared/lib/utils.js +1 -168
- package/dist/shared/lib/validation/choose-correct-answer.validation.js +1 -111
- package/dist/shared/lib/validation/label-the-picture.validation.js +1 -19
- package/dist/shared/lib/validation/listen-and-choose-from-answer-group.validation.js +1 -46
- package/dist/shared/lib/validation/listen-and-choose-objects-in-scene.validation.js +1 -21
- package/dist/shared/lib/validation/listen-and-drag-objects-into-scene.validation.js +1 -34
- package/dist/shared/lib/validation/listen-and-speak-answer.validation.js +1 -40
- package/dist/shared/lib/validation/listen-and-speak-compare-images.validation.js +1 -45
- package/dist/shared/lib/validation/listen-and-speak-image-group.validation.js +1 -19
- package/dist/shared/lib/validation/listen-and-speak-info-exchange.validation.js +1 -39
- package/dist/shared/lib/validation/listen-and-speak-odd-one-out.validation.js +1 -32
- package/dist/shared/lib/validation/listen-and-speak-question-list.validation.js +1 -19
- package/dist/shared/lib/validation/listen-and-speak-with-story-images.validation.js +1 -28
- package/dist/shared/lib/validation/look-picture-choose-correct-answer.validation.js +1 -12
- package/dist/shared/lib/validation/look-picture-fill-blank-choose-answer.validation.js +1 -47
- package/dist/shared/lib/validation/read-and-color-objects.validation.js +1 -29
- package/dist/shared/lib/validation/read-displayed-content.validation.js +1 -28
- package/dist/shared/lib/validation/speaking-conversation.validation.js +1 -75
- package/dist/shared/lib/validation/speaking-describe-image.validation.js +1 -31
- package/dist/shared/lib/validation/spontaneous-qa.validation.js +1 -48
- package/dist/shared/lib/validation/word-fill-paragraph-default.validation.js +1 -38
- package/dist/shared/lib/validation/word-fill-paragraph-with-options.validation.js +1 -39
- package/dist/shared/lib/validation/word-fill-paragraph.validation.js +1 -43
- package/dist/shared/lib/validation/word-ordering.validation.js +1 -33
- package/dist/shared/types/branch.types.js +1 -6
- package/dist/shared/types/common.types.js +1 -50
- package/dist/shared/types/entities/exam-schedule.types.js +1 -5
- package/dist/shared/types/entities/exam.types.js +1 -1
- package/dist/shared/types/entities/question.types.js +1 -4
- package/dist/shared/types/entities/result.types.js +1 -4
- package/dist/shared/types/entities/user.types.js +1 -4
- package/dist/shared/types/exam-taking.types.js +1 -2
- package/dist/shared/types/history.types.js +1 -34
- package/dist/shared/types/index.js +1 -1
- package/dist/shared/types/questions/choose-correct-adjective.js +1 -4
- package/dist/shared/types/questions/choose-the-correct-answer.js +1 -9
- package/dist/shared/types/questions/fill-missing-words-in-grid.js +1 -11
- package/dist/shared/types/questions/index.js +1 -40
- package/dist/shared/types/questions/listen-and-speak-answer.js +1 -1
- package/dist/shared/types/questions/listen-and-speak-compare-images.js +1 -1
- package/dist/shared/types/questions/listen-and-speak-image-group.js +1 -1
- package/dist/shared/types/questions/listen-and-speak-info-exchange.js +1 -3
- package/dist/shared/types/questions/listen-and-speak-odd-one-out.js +1 -3
- package/dist/shared/types/questions/listen-and-speak-question-list.js +1 -1
- package/dist/shared/types/questions/listen-and-speak-with-story-images.js +1 -3
- package/dist/shared/types/questions/look-picture-choose-correct-answer.js +1 -5
- package/dist/shared/types/questions/look-picture-fill-blank-choose-answer.js +1 -9
- package/dist/shared/types/questions/look-picture-fill-word-hint.js +1 -7
- package/dist/shared/types/questions/read-displayed-content.js +1 -1
- package/dist/shared/types/questions/speaking-conversation.js +1 -7
- package/dist/shared/types/questions/speaking-describe-image.js +1 -1
- package/dist/shared/types/questions/spontaneous-qa.js +1 -1
- package/dist/shared/types/questions/write-correct-verb-form.js +1 -12
- package/dist/shared/types/role.types.js +1 -1
- package/dist/shared/types/structure-management.js +1 -28
- package/dist/shared/types/student.types.js +1 -54
- package/dist/shared/types/teacher-dashboard-rooms.js +1 -2
- package/package.json +12 -3
|
@@ -1,28 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export const listenAndSpeakWithStoryImagesSchema = z.object({
|
|
3
|
-
audioUrl: z.string().min(1, 'Vui lòng tải lên file audio câu hỏi'),
|
|
4
|
-
images: z
|
|
5
|
-
.array(z.string().min(1))
|
|
6
|
-
.min(1, 'Vui lòng tải lên ít nhất 1 hình ảnh')
|
|
7
|
-
.refine((imgs) => imgs.filter((img) => img.trim() !== '').length >= 1, { message: 'Phải có ít nhất 1 hình ảnh hợp lệ' }),
|
|
8
|
-
expectedAnswers: z
|
|
9
|
-
.array(z.string().min(1, 'Đáp án không được để trống'))
|
|
10
|
-
.min(1, 'Vui lòng nhập ít nhất 1 đáp án mong muốn'),
|
|
11
|
-
explanation: z.string().optional(),
|
|
12
|
-
points: z
|
|
13
|
-
.union([z.string(), z.number()])
|
|
14
|
-
.transform((val, ctx) => {
|
|
15
|
-
if (val === '' || val === undefined || val === null) {
|
|
16
|
-
ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Vui lòng nhập điểm' });
|
|
17
|
-
return z.NEVER;
|
|
18
|
-
}
|
|
19
|
-
const num = typeof val === 'string' ? parseFloat(val) : val;
|
|
20
|
-
if (isNaN(num)) {
|
|
21
|
-
ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Điểm phải là số hợp lệ' });
|
|
22
|
-
return z.NEVER;
|
|
23
|
-
}
|
|
24
|
-
return num;
|
|
25
|
-
})
|
|
26
|
-
.pipe(z.number().min(0.5, 'Điểm phải >= 0.5')),
|
|
27
|
-
isBackup: z.boolean().optional(),
|
|
28
|
-
});
|
|
1
|
+
import{z as n}from"zod";export const listenAndSpeakWithStoryImagesSchema=n.object({audioUrl:n.string().min(1,"Vui lòng tải lên file audio câu hỏi"),images:n.array(n.string().min(1)).min(1,"Vui lòng tải lên ít nhất 1 hình ảnh").refine(n=>n.filter(n=>""!==n.trim()).length>=1,{message:"Phải có ít nhất 1 hình ảnh hợp lệ"}),expectedAnswers:n.array(n.string().min(1,"Đáp án không được để trống")).min(1,"Vui lòng nhập ít nhất 1 đáp án mong muốn"),explanation:n.string().optional(),points:n.union([n.string(),n.number()]).transform((i,e)=>{if(""===i||null==i)return e.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm"}),n.NEVER;const t="string"==typeof i?parseFloat(i):i;return isNaN(t)?(e.addIssue({code:n.ZodIssueCode.custom,message:"Điểm phải là số hợp lệ"}),n.NEVER):t}).pipe(n.number().min(.5,"Điểm phải >= 0.5")),isBackup:n.boolean().optional()});
|
|
@@ -1,12 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
// Main form validation schema - NEW flat structure
|
|
3
|
-
// Same as LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER but without question field
|
|
4
|
-
export const lookPictureChooseCorrectAnswerFormSchema = z.object({
|
|
5
|
-
imageUrl: z.string().min(1, 'Vui lòng upload hình ảnh!'),
|
|
6
|
-
options: z
|
|
7
|
-
.array(z.string().min(1, 'Vui lòng nhập nội dung đáp án!'))
|
|
8
|
-
.min(2, 'Phải có ít nhất 2 lựa chọn!'),
|
|
9
|
-
correctAnswer: z.number(),
|
|
10
|
-
explanation: z.string().optional(),
|
|
11
|
-
points: z.number().min(0.5).optional(),
|
|
12
|
-
});
|
|
1
|
+
import{z as n}from"zod";export const lookPictureChooseCorrectAnswerFormSchema=n.object({imageUrl:n.string().min(1,"Vui lòng upload hình ảnh!"),options:n.array(n.string().min(1,"Vui lòng nhập nội dung đáp án!")).min(2,"Phải có ít nhất 2 lựa chọn!"),correctAnswer:n.number(),explanation:n.string().optional(),points:n.number().min(.5).optional()});
|
|
@@ -1,47 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/**
|
|
3
|
-
* Validation schema for LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER form
|
|
4
|
-
*
|
|
5
|
-
* Based on API payload structure:
|
|
6
|
-
* - content: { imageUrl, question, options: string[] }
|
|
7
|
-
* - correct_answer: { answer: number }
|
|
8
|
-
*/
|
|
9
|
-
export const lookPictureFillBlankChooseAnswerFormSchema = z.object({
|
|
10
|
-
imageUrl: z.string().min(1, 'Vui lòng upload hình ảnh!'),
|
|
11
|
-
question: z
|
|
12
|
-
.string()
|
|
13
|
-
.min(1, 'Vui lòng nhập nội dung câu hỏi!')
|
|
14
|
-
.refine((val) => val.includes('{0}'), {
|
|
15
|
-
message: 'Câu hỏi phải chứa {0} để đánh dấu chỗ trống',
|
|
16
|
-
})
|
|
17
|
-
.refine((val) => (val.match(/\{0\}/g) || []).length <= 1, {
|
|
18
|
-
message: 'Chỉ được có một {0} trong câu hỏi',
|
|
19
|
-
}),
|
|
20
|
-
options: z
|
|
21
|
-
.array(z.string().min(1, 'Vui lòng nhập đáp án!'))
|
|
22
|
-
.min(2, 'Phải có ít nhất 2 đáp án!')
|
|
23
|
-
.refine((options) => options.filter((opt) => opt.trim() !== '').length >= 2, { message: 'Phải có ít nhất 2 đáp án được điền!' }),
|
|
24
|
-
correctAnswer: z.number().min(0, 'Vui lòng chọn đáp án đúng!'),
|
|
25
|
-
explanation: z.string().optional(),
|
|
26
|
-
points: z
|
|
27
|
-
.union([z.string(), z.number()])
|
|
28
|
-
.transform((val, ctx) => {
|
|
29
|
-
if (val === '' || val === undefined || val === null) {
|
|
30
|
-
ctx.addIssue({
|
|
31
|
-
code: z.ZodIssueCode.custom,
|
|
32
|
-
message: 'Vui lòng nhập điểm số!',
|
|
33
|
-
});
|
|
34
|
-
return z.NEVER;
|
|
35
|
-
}
|
|
36
|
-
const num = typeof val === 'string' ? parseInt(val, 10) : val;
|
|
37
|
-
if (isNaN(num)) {
|
|
38
|
-
ctx.addIssue({
|
|
39
|
-
code: z.ZodIssueCode.custom,
|
|
40
|
-
message: 'Vui lòng nhập điểm số hợp lệ!',
|
|
41
|
-
});
|
|
42
|
-
return z.NEVER;
|
|
43
|
-
}
|
|
44
|
-
return num;
|
|
45
|
-
})
|
|
46
|
-
.pipe(z.number().min(1, 'Điểm số phải >= 1')),
|
|
47
|
-
});
|
|
1
|
+
import{z as n}from"zod";export const lookPictureFillBlankChooseAnswerFormSchema=n.object({imageUrl:n.string().min(1,"Vui lòng upload hình ảnh!"),question:n.string().min(1,"Vui lòng nhập nội dung câu hỏi!").refine(n=>n.includes("{0}"),{message:"Câu hỏi phải chứa {0} để đánh dấu chỗ trống"}).refine(n=>(n.match(/\{0\}/g)||[]).length<=1,{message:"Chỉ được có một {0} trong câu hỏi"}),options:n.array(n.string().min(1,"Vui lòng nhập đáp án!")).min(2,"Phải có ít nhất 2 đáp án!").refine(n=>n.filter(n=>""!==n.trim()).length>=2,{message:"Phải có ít nhất 2 đáp án được điền!"}),correctAnswer:n.number().min(0,"Vui lòng chọn đáp án đúng!"),explanation:n.string().optional(),points:n.union([n.string(),n.number()]).transform((i,e)=>{if(""===i||null==i)return e.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm số!"}),n.NEVER;const s="string"==typeof i?parseInt(i,10):i;return isNaN(s)?(e.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm số hợp lệ!"}),n.NEVER):s}).pipe(n.number().min(1,"Điểm số phải >= 1"))});
|
|
@@ -1,29 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
// Color node schema
|
|
3
|
-
const colorNodeSchema = z.object({
|
|
4
|
-
id: z.string(),
|
|
5
|
-
color: z.string().min(1, 'Vui lòng chọn màu!'),
|
|
6
|
-
label: z.string().optional(), // Optional label (e.g. "Tom", "Apple") for IMAGE_OBJECT_MATCHING
|
|
7
|
-
});
|
|
8
|
-
// Color region node schema
|
|
9
|
-
const colorRegionNodeSchema = z.object({
|
|
10
|
-
id: z.string(),
|
|
11
|
-
x: z.number(),
|
|
12
|
-
y: z.number(),
|
|
13
|
-
width: z.number().optional(),
|
|
14
|
-
height: z.number().optional(),
|
|
15
|
-
color: z.string().optional(),
|
|
16
|
-
linkedColorNodeId: z.string().optional(),
|
|
17
|
-
});
|
|
18
|
-
// Main form validation schema for Read and Color Objects
|
|
19
|
-
export const readAndColorObjectsFormSchema = z.object({
|
|
20
|
-
backgroundImageUrl: z.string().min(1, 'Vui lòng upload ảnh nền!'),
|
|
21
|
-
colorNodes: z.array(colorNodeSchema).min(1, 'Vui lòng thêm ít nhất một màu!'),
|
|
22
|
-
regionNodes: z
|
|
23
|
-
.array(colorRegionNodeSchema)
|
|
24
|
-
.min(1, 'Vui lòng thêm ít nhất một vùng tô màu!')
|
|
25
|
-
.refine((regions) => regions.every((r) => r.linkedColorNodeId && r.linkedColorNodeId.trim() !== ''), { message: 'Tất cả các vùng phải được liên kết với màu!' }),
|
|
26
|
-
instructions: z
|
|
27
|
-
.array(z.string().min(1, 'Vui lòng nhập hướng dẫn!'))
|
|
28
|
-
.min(1, 'Vui lòng thêm ít nhất một hướng dẫn!'),
|
|
29
|
-
});
|
|
1
|
+
import{z as n}from"zod";const o=n.object({id:n.string(),color:n.string().min(1,"Vui lòng chọn màu!"),label:n.string().optional()}),i=n.object({id:n.string(),x:n.number(),y:n.number(),width:n.number().optional(),height:n.number().optional(),color:n.string().optional(),linkedColorNodeId:n.string().optional()});export const readAndColorObjectsFormSchema=n.object({backgroundImageUrl:n.string().min(1,"Vui lòng upload ảnh nền!"),colorNodes:n.array(o).min(1,"Vui lòng thêm ít nhất một màu!"),regionNodes:n.array(i).min(1,"Vui lòng thêm ít nhất một vùng tô màu!").refine(n=>n.every(n=>n.linkedColorNodeId&&""!==n.linkedColorNodeId.trim()),{message:"Tất cả các vùng phải được liên kết với màu!"}),instructions:n.array(n.string().min(1,"Vui lòng nhập hướng dẫn!")).min(1,"Vui lòng thêm ít nhất một hướng dẫn!")});
|
|
@@ -1,28 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export const readDisplayedContentFormSchema = z.object({
|
|
3
|
-
referenceText: z
|
|
4
|
-
.string()
|
|
5
|
-
.min(1, 'Vui lòng nhập đoạn văn bản cần đọc!'),
|
|
6
|
-
explanation: z.string().optional(),
|
|
7
|
-
points: z
|
|
8
|
-
.union([z.string(), z.number()])
|
|
9
|
-
.transform((val, ctx) => {
|
|
10
|
-
if (val === '' || val === undefined || val === null) {
|
|
11
|
-
ctx.addIssue({
|
|
12
|
-
code: z.ZodIssueCode.custom,
|
|
13
|
-
message: 'Vui lòng nhập điểm!',
|
|
14
|
-
});
|
|
15
|
-
return z.NEVER;
|
|
16
|
-
}
|
|
17
|
-
const num = typeof val === 'string' ? parseInt(val, 10) : val;
|
|
18
|
-
if (isNaN(num)) {
|
|
19
|
-
ctx.addIssue({
|
|
20
|
-
code: z.ZodIssueCode.custom,
|
|
21
|
-
message: 'Vui lòng nhập điểm hợp lệ!',
|
|
22
|
-
});
|
|
23
|
-
return z.NEVER;
|
|
24
|
-
}
|
|
25
|
-
return num;
|
|
26
|
-
})
|
|
27
|
-
.pipe(z.number().min(1, 'Điểm số phải >= 1')),
|
|
28
|
-
});
|
|
1
|
+
import{z as n}from"zod";export const readDisplayedContentFormSchema=n.object({referenceText:n.string().min(1,"Vui lòng nhập đoạn văn bản cần đọc!"),explanation:n.string().optional(),points:n.union([n.string(),n.number()]).transform((e,s)=>{if(""===e||null==e)return s.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm!"}),n.NEVER;const o="string"==typeof e?parseInt(e,10):e;return isNaN(o)?(s.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm hợp lệ!"}),n.NEVER):o}).pipe(n.number().min(1,"Điểm số phải >= 1"))});
|
|
@@ -1,75 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/**
|
|
3
|
-
* Zod validation schema for SPEAKING_CONVERSATION creator form.
|
|
4
|
-
*
|
|
5
|
-
* Key rules:
|
|
6
|
-
* - responder: 'PARTNER' → partnerAudioUrl required, points auto-set to 0
|
|
7
|
-
* - responder: 'STUDENT' → points must be >= 1
|
|
8
|
-
*/
|
|
9
|
-
export const speakingConversationFormSchema = z
|
|
10
|
-
.object({
|
|
11
|
-
// ─── Group Data ─────────────────────────────────────────────────────────
|
|
12
|
-
partnerName: z.string().optional(),
|
|
13
|
-
partnerAvatarUrl: z.string().optional(),
|
|
14
|
-
images: z
|
|
15
|
-
.array(z.object({
|
|
16
|
-
id: z.string(),
|
|
17
|
-
url: z.string(),
|
|
18
|
-
label: z.string(),
|
|
19
|
-
}))
|
|
20
|
-
.optional()
|
|
21
|
-
.default([]),
|
|
22
|
-
// ─── Question Content ────────────────────────────────────────────────────
|
|
23
|
-
responder: z.enum(['PARTNER', 'STUDENT'], {
|
|
24
|
-
message: 'Vui lòng chọn người trả lời!',
|
|
25
|
-
}),
|
|
26
|
-
interlocutorAudioUrl: z.string().optional(),
|
|
27
|
-
partnerAudioUrl: z.string().optional(),
|
|
28
|
-
questionText: z.string().optional(),
|
|
29
|
-
isBackup: z.boolean().optional().default(false),
|
|
30
|
-
// ─── Expected Answers ────────────────────────────────────────────────────
|
|
31
|
-
expectedAnswers: z.array(z.string()).optional().default(['']),
|
|
32
|
-
// ─── Explanation ─────────────────────────────────────────────────────────
|
|
33
|
-
explanation: z.string().optional(),
|
|
34
|
-
// ─── Points ──────────────────────────────────────────────────────────────
|
|
35
|
-
points: z
|
|
36
|
-
.union([z.string(), z.number()])
|
|
37
|
-
.transform((val, ctx) => {
|
|
38
|
-
if (val === '' || val === undefined || val === null) {
|
|
39
|
-
ctx.addIssue({
|
|
40
|
-
code: z.ZodIssueCode.custom,
|
|
41
|
-
message: 'Vui lòng nhập điểm!',
|
|
42
|
-
});
|
|
43
|
-
return z.NEVER;
|
|
44
|
-
}
|
|
45
|
-
const num = typeof val === 'string' ? parseInt(val, 10) : val;
|
|
46
|
-
if (isNaN(num)) {
|
|
47
|
-
ctx.addIssue({
|
|
48
|
-
code: z.ZodIssueCode.custom,
|
|
49
|
-
message: 'Vui lòng nhập điểm hợp lệ!',
|
|
50
|
-
});
|
|
51
|
-
return z.NEVER;
|
|
52
|
-
}
|
|
53
|
-
return num;
|
|
54
|
-
})
|
|
55
|
-
.pipe(z.number().min(0, 'Điểm số phải >= 0')),
|
|
56
|
-
})
|
|
57
|
-
.superRefine((data, ctx) => {
|
|
58
|
-
// PARTNER questions require partnerAudioUrl
|
|
59
|
-
if (data.responder === 'PARTNER' &&
|
|
60
|
-
(!data.partnerAudioUrl || data.partnerAudioUrl.trim() === '')) {
|
|
61
|
-
ctx.addIssue({
|
|
62
|
-
code: z.ZodIssueCode.custom,
|
|
63
|
-
message: 'Câu hỏi mẫu (Partner) cần có audio của Partner!',
|
|
64
|
-
path: ['partnerAudioUrl'],
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
// STUDENT questions require points >= 1
|
|
68
|
-
if (data.responder === 'STUDENT' && data.points < 1) {
|
|
69
|
-
ctx.addIssue({
|
|
70
|
-
code: z.ZodIssueCode.custom,
|
|
71
|
-
message: 'Câu hỏi học sinh phải có điểm >= 1!',
|
|
72
|
-
path: ['points'],
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
});
|
|
1
|
+
import{z as e}from"zod";export const speakingConversationFormSchema=e.object({partnerName:e.string().optional(),partnerAvatarUrl:e.string().optional(),images:e.array(e.object({id:e.string(),url:e.string(),label:e.string()})).optional().default([]),responder:e.enum(["PARTNER","STUDENT"],{message:"Vui lòng chọn người trả lời!"}),interlocutorAudioUrl:e.string().optional(),partnerAudioUrl:e.string().optional(),questionText:e.string().optional(),isBackup:e.boolean().optional().default(!1),expectedAnswers:e.array(e.string()).optional().default([""]),explanation:e.string().optional(),points:e.union([e.string(),e.number()]).transform((n,o)=>{if(""===n||null==n)return o.addIssue({code:e.ZodIssueCode.custom,message:"Vui lòng nhập điểm!"}),e.NEVER;const r="string"==typeof n?parseInt(n,10):n;return isNaN(r)?(o.addIssue({code:e.ZodIssueCode.custom,message:"Vui lòng nhập điểm hợp lệ!"}),e.NEVER):r}).pipe(e.number().min(0,"Điểm số phải >= 0"))}).superRefine((n,o)=>{"PARTNER"!==n.responder||n.partnerAudioUrl&&""!==n.partnerAudioUrl.trim()||o.addIssue({code:e.ZodIssueCode.custom,message:"Câu hỏi mẫu (Partner) cần có audio của Partner!",path:["partnerAudioUrl"]}),"STUDENT"===n.responder&&n.points<1&&o.addIssue({code:e.ZodIssueCode.custom,message:"Câu hỏi học sinh phải có điểm >= 1!",path:["points"]})});
|
|
@@ -1,31 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export const speakingDescribeImageFormSchema = z.object({
|
|
3
|
-
question: z.string().optional(),
|
|
4
|
-
imageUrl: z.string().min(1, 'Vui lòng upload hình ảnh!'),
|
|
5
|
-
expectedAnswers: z
|
|
6
|
-
.array(z.string().min(1, 'Vui lòng nhập đáp án!'))
|
|
7
|
-
.min(1, 'Cần tối thiểu 1 đáp án!')
|
|
8
|
-
.refine((options) => options.filter((opt) => opt.trim() !== '').length >= 1, { message: 'Cần tối thiểu 1 đáp án hợp lệ!' }),
|
|
9
|
-
explanation: z.string().optional(),
|
|
10
|
-
points: z
|
|
11
|
-
.union([z.string(), z.number()])
|
|
12
|
-
.transform((val, ctx) => {
|
|
13
|
-
if (val === '' || val === undefined || val === null) {
|
|
14
|
-
ctx.addIssue({
|
|
15
|
-
code: z.ZodIssueCode.custom,
|
|
16
|
-
message: 'Vui lòng nhập điểm!',
|
|
17
|
-
});
|
|
18
|
-
return z.NEVER;
|
|
19
|
-
}
|
|
20
|
-
const num = typeof val === 'string' ? parseInt(val, 10) : val;
|
|
21
|
-
if (isNaN(num)) {
|
|
22
|
-
ctx.addIssue({
|
|
23
|
-
code: z.ZodIssueCode.custom,
|
|
24
|
-
message: 'Vui lòng nhập điểm hợp lệ!',
|
|
25
|
-
});
|
|
26
|
-
return z.NEVER;
|
|
27
|
-
}
|
|
28
|
-
return num;
|
|
29
|
-
})
|
|
30
|
-
.pipe(z.number().min(1, 'Điểm số phải >= 1')),
|
|
31
|
-
});
|
|
1
|
+
import{z as n}from"zod";export const speakingDescribeImageFormSchema=n.object({question:n.string().optional(),imageUrl:n.string().min(1,"Vui lòng upload hình ảnh!"),expectedAnswers:n.array(n.string().min(1,"Vui lòng nhập đáp án!")).min(1,"Cần tối thiểu 1 đáp án!").refine(n=>n.filter(n=>""!==n.trim()).length>=1,{message:"Cần tối thiểu 1 đáp án hợp lệ!"}),explanation:n.string().optional(),points:n.union([n.string(),n.number()]).transform((e,i)=>{if(""===e||null==e)return i.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm!"}),n.NEVER;const s="string"==typeof e?parseInt(e,10):e;return isNaN(s)?(i.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm hợp lệ!"}),n.NEVER):s}).pipe(n.number().min(1,"Điểm số phải >= 1"))});
|
|
@@ -1,48 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export const spontaneousQAFormSchema = z
|
|
3
|
-
.object({
|
|
4
|
-
inputType: z.enum(['AUDIO', 'TEXT'], {
|
|
5
|
-
message: 'Vui lòng chọn hình thức nhập câu hỏi!',
|
|
6
|
-
}),
|
|
7
|
-
audioUrl: z.string().optional(),
|
|
8
|
-
questionText: z.string().optional(),
|
|
9
|
-
sampleAnswers: z.array(z.string()).optional().default(['']),
|
|
10
|
-
explanation: z.string().optional(),
|
|
11
|
-
points: z
|
|
12
|
-
.union([z.string(), z.number()])
|
|
13
|
-
.transform((val, ctx) => {
|
|
14
|
-
if (val === '' || val === undefined || val === null) {
|
|
15
|
-
ctx.addIssue({
|
|
16
|
-
code: z.ZodIssueCode.custom,
|
|
17
|
-
message: 'Vui lòng nhập điểm!',
|
|
18
|
-
});
|
|
19
|
-
return z.NEVER;
|
|
20
|
-
}
|
|
21
|
-
const num = typeof val === 'string' ? parseInt(val, 10) : val;
|
|
22
|
-
if (isNaN(num)) {
|
|
23
|
-
ctx.addIssue({
|
|
24
|
-
code: z.ZodIssueCode.custom,
|
|
25
|
-
message: 'Vui lòng nhập điểm hợp lệ!',
|
|
26
|
-
});
|
|
27
|
-
return z.NEVER;
|
|
28
|
-
}
|
|
29
|
-
return num;
|
|
30
|
-
})
|
|
31
|
-
.pipe(z.number().min(1, 'Điểm số phải >= 1')),
|
|
32
|
-
})
|
|
33
|
-
.superRefine((data, ctx) => {
|
|
34
|
-
if (data.inputType === 'AUDIO' && (!data.audioUrl || data.audioUrl.trim() === '')) {
|
|
35
|
-
ctx.addIssue({
|
|
36
|
-
code: z.ZodIssueCode.custom,
|
|
37
|
-
message: 'Vui lòng upload file audio câu hỏi!',
|
|
38
|
-
path: ['audioUrl'],
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
if (data.inputType === 'TEXT' && (!data.questionText || data.questionText.trim() === '')) {
|
|
42
|
-
ctx.addIssue({
|
|
43
|
-
code: z.ZodIssueCode.custom,
|
|
44
|
-
message: 'Vui lòng nhập nội dung câu hỏi!',
|
|
45
|
-
path: ['questionText'],
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
});
|
|
1
|
+
import{z as e}from"zod";export const spontaneousQAFormSchema=e.object({inputType:e.enum(["AUDIO","TEXT"],{message:"Vui lòng chọn hình thức nhập câu hỏi!"}),audioUrl:e.string().optional(),questionText:e.string().optional(),sampleAnswers:e.array(e.string()).optional().default([""]),explanation:e.string().optional(),points:e.union([e.string(),e.number()]).transform((s,n)=>{if(""===s||null==s)return n.addIssue({code:e.ZodIssueCode.custom,message:"Vui lòng nhập điểm!"}),e.NEVER;const o="string"==typeof s?parseInt(s,10):s;return isNaN(o)?(n.addIssue({code:e.ZodIssueCode.custom,message:"Vui lòng nhập điểm hợp lệ!"}),e.NEVER):o}).pipe(e.number().min(1,"Điểm số phải >= 1"))}).superRefine((s,n)=>{"AUDIO"!==s.inputType||s.audioUrl&&""!==s.audioUrl.trim()||n.addIssue({code:e.ZodIssueCode.custom,message:"Vui lòng upload file audio câu hỏi!",path:["audioUrl"]}),"TEXT"!==s.inputType||s.questionText&&""!==s.questionText.trim()||n.addIssue({code:e.ZodIssueCode.custom,message:"Vui lòng nhập nội dung câu hỏi!",path:["questionText"]})});
|
|
@@ -1,38 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/**
|
|
3
|
-
* Validation schema for WORD_FILL_PARAGRAPH with DEFAULT viewMode.
|
|
4
|
-
* In DEFAULT mode, each placeholder {0}, {1}, ... gets a text input
|
|
5
|
-
* for the correct answer — no word bank, no options.
|
|
6
|
-
*/
|
|
7
|
-
export const wordFillParagraphDefaultFormSchema = z.object({
|
|
8
|
-
title: z.string().optional().default(''),
|
|
9
|
-
imageUrl: z.string().optional(),
|
|
10
|
-
paragraph: z.string().min(1, 'Vui lòng nhập đoạn văn!'),
|
|
11
|
-
answers: z
|
|
12
|
-
.array(z.string().min(1, 'Vui lòng nhập đáp án cho chỗ trống này!'))
|
|
13
|
-
.min(1, 'Cần ít nhất 1 đáp án!'),
|
|
14
|
-
exampleAnswer: z.array(z.string()).optional().default([]),
|
|
15
|
-
caseSensitive: z.boolean().optional().default(false),
|
|
16
|
-
explanation: z.string().optional(),
|
|
17
|
-
points: z
|
|
18
|
-
.union([z.string(), z.number()])
|
|
19
|
-
.transform((val, ctx) => {
|
|
20
|
-
if (val === '' || val === undefined || val === null) {
|
|
21
|
-
ctx.addIssue({
|
|
22
|
-
code: z.ZodIssueCode.custom,
|
|
23
|
-
message: 'Vui lòng nhập điểm!',
|
|
24
|
-
});
|
|
25
|
-
return z.NEVER;
|
|
26
|
-
}
|
|
27
|
-
const num = typeof val === 'string' ? parseInt(val, 10) : val;
|
|
28
|
-
if (isNaN(num)) {
|
|
29
|
-
ctx.addIssue({
|
|
30
|
-
code: z.ZodIssueCode.custom,
|
|
31
|
-
message: 'Điểm không hợp lệ!',
|
|
32
|
-
});
|
|
33
|
-
return z.NEVER;
|
|
34
|
-
}
|
|
35
|
-
return num;
|
|
36
|
-
})
|
|
37
|
-
.pipe(z.number().min(1, 'Điểm phải >= 1')),
|
|
38
|
-
});
|
|
1
|
+
import{z as n}from"zod";export const wordFillParagraphDefaultFormSchema=n.object({title:n.string().optional().default(""),imageUrl:n.string().optional(),paragraph:n.string().min(1,"Vui lòng nhập đoạn văn!"),answers:n.array(n.string().min(1,"Vui lòng nhập đáp án cho chỗ trống này!")).min(1,"Cần ít nhất 1 đáp án!"),exampleAnswer:n.array(n.string()).optional().default([]),caseSensitive:n.boolean().optional().default(!1),explanation:n.string().optional(),points:n.union([n.string(),n.number()]).transform((e,t)=>{if(""===e||null==e)return t.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm!"}),n.NEVER;const i="string"==typeof e?parseInt(e,10):e;return isNaN(i)?(t.addIssue({code:n.ZodIssueCode.custom,message:"Điểm không hợp lệ!"}),n.NEVER):i}).pipe(n.number().min(1,"Điểm phải >= 1"))});
|
|
@@ -1,39 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const wordBankWithOptionsItemSchema = z.object({
|
|
3
|
-
options: z.array(z.string().min(1, 'Vui lòng nhập đáp án!')).min(2, 'Mỗi chỗ trống cần ít nhất 2 lựa chọn!'),
|
|
4
|
-
isExample: z.boolean().optional(),
|
|
5
|
-
});
|
|
6
|
-
export const wordFillParagraphWithOptionsFormSchema = z.object({
|
|
7
|
-
title: z.string().optional().default(''),
|
|
8
|
-
imageUrl: z.string().optional(),
|
|
9
|
-
paragraph: z.string().min(1, 'Vui lòng nhập đoạn văn!'),
|
|
10
|
-
wordBank: z
|
|
11
|
-
.array(wordBankWithOptionsItemSchema)
|
|
12
|
-
.min(1, 'Cần ít nhất 1 chỗ trống với lựa chọn!'),
|
|
13
|
-
answers: z
|
|
14
|
-
.array(z.string().min(1, 'Vui lòng chọn đáp án cho chỗ trống này!'))
|
|
15
|
-
.min(1, 'Cần ít nhất 1 đáp án!'),
|
|
16
|
-
caseSensitive: z.boolean().optional().default(false),
|
|
17
|
-
explanation: z.string().optional(),
|
|
18
|
-
points: z
|
|
19
|
-
.union([z.string(), z.number()])
|
|
20
|
-
.transform((val, ctx) => {
|
|
21
|
-
if (val === '' || val === undefined || val === null) {
|
|
22
|
-
ctx.addIssue({
|
|
23
|
-
code: z.ZodIssueCode.custom,
|
|
24
|
-
message: 'Vui lòng nhập điểm!',
|
|
25
|
-
});
|
|
26
|
-
return z.NEVER;
|
|
27
|
-
}
|
|
28
|
-
const num = typeof val === 'string' ? parseInt(val, 10) : val;
|
|
29
|
-
if (isNaN(num)) {
|
|
30
|
-
ctx.addIssue({
|
|
31
|
-
code: z.ZodIssueCode.custom,
|
|
32
|
-
message: 'Điểm không hợp lệ!',
|
|
33
|
-
});
|
|
34
|
-
return z.NEVER;
|
|
35
|
-
}
|
|
36
|
-
return num;
|
|
37
|
-
})
|
|
38
|
-
.pipe(z.number().min(1, 'Điểm phải >= 1')),
|
|
39
|
-
});
|
|
1
|
+
import{z as n}from"zod";const i=n.object({options:n.array(n.string().min(1,"Vui lòng nhập đáp án!")).min(2,"Mỗi chỗ trống cần ít nhất 2 lựa chọn!"),isExample:n.boolean().optional()});export const wordFillParagraphWithOptionsFormSchema=n.object({title:n.string().optional().default(""),imageUrl:n.string().optional(),paragraph:n.string().min(1,"Vui lòng nhập đoạn văn!"),wordBank:n.array(i).min(1,"Cần ít nhất 1 chỗ trống với lựa chọn!"),answers:n.array(n.string().min(1,"Vui lòng chọn đáp án cho chỗ trống này!")).min(1,"Cần ít nhất 1 đáp án!"),caseSensitive:n.boolean().optional().default(!1),explanation:n.string().optional(),points:n.union([n.string(),n.number()]).transform((i,t)=>{if(""===i||null==i)return t.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm!"}),n.NEVER;const o="string"==typeof i?parseInt(i,10):i;return isNaN(o)?(t.addIssue({code:n.ZodIssueCode.custom,message:"Điểm không hợp lệ!"}),n.NEVER):o}).pipe(n.number().min(1,"Điểm phải >= 1"))});
|
|
@@ -1,43 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const wordBankItemSchema = z.object({
|
|
3
|
-
word: z.string().min(1, 'Vui lòng nhập từ!'),
|
|
4
|
-
content: z.string().optional(),
|
|
5
|
-
imageUrl: z.string().optional(),
|
|
6
|
-
isExample: z.boolean().optional(),
|
|
7
|
-
});
|
|
8
|
-
export const wordFillParagraphFormSchema = z.object({
|
|
9
|
-
title: z.string().optional().default(''),
|
|
10
|
-
imageUrl: z.string().optional(),
|
|
11
|
-
paragraph: z.string().min(1, 'Vui lòng nhập đoạn văn!'),
|
|
12
|
-
wordBank: z
|
|
13
|
-
.array(wordBankItemSchema)
|
|
14
|
-
.min(2, 'Cần ít nhất 2 từ trong word bank!'),
|
|
15
|
-
answers: z
|
|
16
|
-
.array(z.string().min(1, 'Vui lòng chọn đáp án cho chỗ trống này!'))
|
|
17
|
-
.min(1, 'Cần ít nhất 1 đáp án!'),
|
|
18
|
-
exampleAnswer: z.array(z.string()).optional().default([]),
|
|
19
|
-
isExample: z.boolean().optional(),
|
|
20
|
-
caseSensitive: z.boolean().optional().default(false),
|
|
21
|
-
explanation: z.string().optional(),
|
|
22
|
-
points: z
|
|
23
|
-
.union([z.string(), z.number()])
|
|
24
|
-
.transform((val, ctx) => {
|
|
25
|
-
if (val === '' || val === undefined || val === null) {
|
|
26
|
-
ctx.addIssue({
|
|
27
|
-
code: z.ZodIssueCode.custom,
|
|
28
|
-
message: 'Vui lòng nhập điểm!',
|
|
29
|
-
});
|
|
30
|
-
return z.NEVER;
|
|
31
|
-
}
|
|
32
|
-
const num = typeof val === 'string' ? parseInt(val, 10) : val;
|
|
33
|
-
if (isNaN(num)) {
|
|
34
|
-
ctx.addIssue({
|
|
35
|
-
code: z.ZodIssueCode.custom,
|
|
36
|
-
message: 'Điểm không hợp lệ!',
|
|
37
|
-
});
|
|
38
|
-
return z.NEVER;
|
|
39
|
-
}
|
|
40
|
-
return num;
|
|
41
|
-
})
|
|
42
|
-
.pipe(z.number().min(1, 'Điểm phải >= 1')),
|
|
43
|
-
});
|
|
1
|
+
import{z as n}from"zod";const o=n.object({word:n.string().min(1,"Vui lòng nhập từ!"),content:n.string().optional(),imageUrl:n.string().optional(),isExample:n.boolean().optional()});export const wordFillParagraphFormSchema=n.object({title:n.string().optional().default(""),imageUrl:n.string().optional(),paragraph:n.string().min(1,"Vui lòng nhập đoạn văn!"),wordBank:n.array(o).min(2,"Cần ít nhất 2 từ trong word bank!"),answers:n.array(n.string().min(1,"Vui lòng chọn đáp án cho chỗ trống này!")).min(1,"Cần ít nhất 1 đáp án!"),exampleAnswer:n.array(n.string()).optional().default([]),isExample:n.boolean().optional(),caseSensitive:n.boolean().optional().default(!1),explanation:n.string().optional(),points:n.union([n.string(),n.number()]).transform((o,t)=>{if(""===o||null==o)return t.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm!"}),n.NEVER;const i="string"==typeof o?parseInt(o,10):o;return isNaN(i)?(t.addIssue({code:n.ZodIssueCode.custom,message:"Điểm không hợp lệ!"}),n.NEVER):i}).pipe(n.number().min(1,"Điểm phải >= 1"))});
|
|
@@ -1,33 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export const wordOrderingFormSchema = z.object({
|
|
3
|
-
words: z
|
|
4
|
-
.array(z.string().min(1, 'Vui lòng nhập từ/chữ cái!'))
|
|
5
|
-
.min(2, 'Cần ít nhất 2 từ/chữ cái!'),
|
|
6
|
-
answer: z
|
|
7
|
-
.array(z.string().min(1, 'Vui lòng nhập đáp án!'))
|
|
8
|
-
.min(2, 'Cần ít nhất 2 từ/chữ cái trong đáp án!'),
|
|
9
|
-
imageUrl: z.string().optional(),
|
|
10
|
-
isExample: z.boolean().optional(),
|
|
11
|
-
explanation: z.string().optional(),
|
|
12
|
-
points: z
|
|
13
|
-
.union([z.string(), z.number()])
|
|
14
|
-
.transform((val, ctx) => {
|
|
15
|
-
if (val === '' || val === undefined || val === null) {
|
|
16
|
-
ctx.addIssue({
|
|
17
|
-
code: z.ZodIssueCode.custom,
|
|
18
|
-
message: 'Vui lòng nhập điểm!',
|
|
19
|
-
});
|
|
20
|
-
return z.NEVER;
|
|
21
|
-
}
|
|
22
|
-
const num = typeof val === 'string' ? parseInt(val, 10) : val;
|
|
23
|
-
if (isNaN(num)) {
|
|
24
|
-
ctx.addIssue({
|
|
25
|
-
code: z.ZodIssueCode.custom,
|
|
26
|
-
message: 'Điểm không hợp lệ!',
|
|
27
|
-
});
|
|
28
|
-
return z.NEVER;
|
|
29
|
-
}
|
|
30
|
-
return num;
|
|
31
|
-
})
|
|
32
|
-
.pipe(z.number().min(1, 'Điểm phải >= 1')),
|
|
33
|
-
});
|
|
1
|
+
import{z as n}from"zod";export const wordOrderingFormSchema=n.object({words:n.array(n.string().min(1,"Vui lòng nhập từ/chữ cái!")).min(2,"Cần ít nhất 2 từ/chữ cái!"),answer:n.array(n.string().min(1,"Vui lòng nhập đáp án!")).min(2,"Cần ít nhất 2 từ/chữ cái trong đáp án!"),imageUrl:n.string().optional(),isExample:n.boolean().optional(),explanation:n.string().optional(),points:n.union([n.string(),n.number()]).transform((i,o)=>{if(""===i||null==i)return o.addIssue({code:n.ZodIssueCode.custom,message:"Vui lòng nhập điểm!"}),n.NEVER;const t="string"==typeof i?parseInt(i,10):i;return isNaN(t)?(o.addIssue({code:n.ZodIssueCode.custom,message:"Điểm không hợp lệ!"}),n.NEVER):t}).pipe(n.number().min(1,"Điểm phải >= 1"))});
|
|
@@ -1,50 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Common shared types across the application
|
|
3
|
-
*/
|
|
4
|
-
// User role enum for role-based permissions
|
|
5
|
-
export var UserRole;
|
|
6
|
-
(function (UserRole) {
|
|
7
|
-
UserRole["SYSTEM_ADMIN"] = "SYSTEM_ADMIN";
|
|
8
|
-
UserRole["ADMIN"] = "ADMIN";
|
|
9
|
-
UserRole["TEACHER"] = "TEACHER";
|
|
10
|
-
UserRole["STUDENT"] = "STUDENT";
|
|
11
|
-
})(UserRole || (UserRole = {}));
|
|
12
|
-
export var Gender;
|
|
13
|
-
(function (Gender) {
|
|
14
|
-
Gender["MALE"] = "male";
|
|
15
|
-
Gender["FEMALE"] = "female";
|
|
16
|
-
Gender["OTHER"] = "other";
|
|
17
|
-
})(Gender || (Gender = {}));
|
|
18
|
-
export var RoomType;
|
|
19
|
-
(function (RoomType) {
|
|
20
|
-
RoomType["CONTEST"] = "CONTEST";
|
|
21
|
-
RoomType["PRACTICE_TEST"] = "PRACTICE_TEST";
|
|
22
|
-
})(RoomType || (RoomType = {}));
|
|
23
|
-
export var ExamRoomStatus;
|
|
24
|
-
(function (ExamRoomStatus) {
|
|
25
|
-
ExamRoomStatus["SCHEDULED"] = "SCHEDULED";
|
|
26
|
-
ExamRoomStatus["IN_PROGRESS"] = "IN_PROGRESS";
|
|
27
|
-
ExamRoomStatus["COMPLETED"] = "COMPLETED";
|
|
28
|
-
})(ExamRoomStatus || (ExamRoomStatus = {}));
|
|
29
|
-
export var StudentSelectionType;
|
|
30
|
-
(function (StudentSelectionType) {
|
|
31
|
-
StudentSelectionType["ALL"] = "ALL";
|
|
32
|
-
StudentSelectionType["SPECIFIC"] = "SPECIFIC";
|
|
33
|
-
})(StudentSelectionType || (StudentSelectionType = {}));
|
|
34
|
-
// Skill enum for programmatic use
|
|
35
|
-
export var SkillEnum;
|
|
36
|
-
(function (SkillEnum) {
|
|
37
|
-
SkillEnum["LISTENING"] = "LISTENING";
|
|
38
|
-
SkillEnum["SPEAKING"] = "SPEAKING";
|
|
39
|
-
SkillEnum["READING"] = "READING";
|
|
40
|
-
SkillEnum["WRITING"] = "WRITING";
|
|
41
|
-
})(SkillEnum || (SkillEnum = {}));
|
|
42
|
-
// Exam template theme enum
|
|
43
|
-
export var ExamTemplateTheme;
|
|
44
|
-
(function (ExamTemplateTheme) {
|
|
45
|
-
ExamTemplateTheme["CAMBRIDGE_YLE"] = "CAMBRIDGE_YLE";
|
|
46
|
-
ExamTemplateTheme["FLYER_WOODEN"] = "FLYER_WOODEN";
|
|
47
|
-
ExamTemplateTheme["SPACESHIP"] = "SPACESHIP";
|
|
48
|
-
ExamTemplateTheme["SUMMER_SKY"] = "SUMMER_SKY";
|
|
49
|
-
ExamTemplateTheme["IELTS_LRW"] = "IELTS_LRW";
|
|
50
|
-
})(ExamTemplateTheme || (ExamTemplateTheme = {}));
|
|
1
|
+
export var UserRole;!function(E){E.SYSTEM_ADMIN="SYSTEM_ADMIN",E.ADMIN="ADMIN",E.TEACHER="TEACHER",E.STUDENT="STUDENT"}(UserRole||(UserRole={}));export var Gender;!function(E){E.MALE="male",E.FEMALE="female",E.OTHER="other"}(Gender||(Gender={}));export var RoomType;!function(E){E.CONTEST="CONTEST",E.PRACTICE_TEST="PRACTICE_TEST"}(RoomType||(RoomType={}));export var ExamRoomStatus;!function(E){E.SCHEDULED="SCHEDULED",E.IN_PROGRESS="IN_PROGRESS",E.COMPLETED="COMPLETED"}(ExamRoomStatus||(ExamRoomStatus={}));export var StudentSelectionType;!function(E){E.ALL="ALL",E.SPECIFIC="SPECIFIC"}(StudentSelectionType||(StudentSelectionType={}));export var SkillEnum;!function(E){E.LISTENING="LISTENING",E.SPEAKING="SPEAKING",E.READING="READING",E.WRITING="WRITING"}(SkillEnum||(SkillEnum={}));export var ExamTemplateTheme;!function(E){E.CAMBRIDGE_YLE="CAMBRIDGE_YLE",E.FLYER_WOODEN="FLYER_WOODEN",E.SPACESHIP="SPACESHIP",E.SUMMER_SKY="SUMMER_SKY",E.IELTS_LRW="IELTS_LRW"}(ExamTemplateTheme||(ExamTemplateTheme={}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export {};
|
|
1
|
+
export{};
|
|
@@ -1,34 +1 @@
|
|
|
1
|
-
|
|
2
|
-
// Default filter values
|
|
3
|
-
export const DEFAULT_HISTORY_FILTERS = {
|
|
4
|
-
level: 'ALL',
|
|
5
|
-
skill: 'ALL',
|
|
6
|
-
testName: '',
|
|
7
|
-
status: 'ALL',
|
|
8
|
-
};
|
|
9
|
-
// Display labels for exam levels
|
|
10
|
-
export const EXAM_LEVEL_LABELS = {
|
|
11
|
-
STARTERS: 'STARTERS',
|
|
12
|
-
MOVERS: 'MOVERS',
|
|
13
|
-
FLYERS: 'FLYERS',
|
|
14
|
-
PET: 'PET',
|
|
15
|
-
KET: 'KET',
|
|
16
|
-
TOEFL_JUNIOR: 'TOEFL JUNIOR',
|
|
17
|
-
};
|
|
18
|
-
// Display labels for skills
|
|
19
|
-
export const SKILL_LABELS = {
|
|
20
|
-
listening: 'Listening',
|
|
21
|
-
'reading & writing': 'Reading & Writing',
|
|
22
|
-
writing: 'Writing',
|
|
23
|
-
};
|
|
24
|
-
// All exam levels for filter dropdown
|
|
25
|
-
export const ALL_EXAM_LEVELS = [
|
|
26
|
-
'STARTERS',
|
|
27
|
-
'MOVERS',
|
|
28
|
-
'FLYERS',
|
|
29
|
-
'PET',
|
|
30
|
-
'KET',
|
|
31
|
-
'TOEFL_JUNIOR',
|
|
32
|
-
];
|
|
33
|
-
// All skills for filter dropdown
|
|
34
|
-
export const ALL_SKILLS = ['listening', 'reading & writing', 'writing'];
|
|
1
|
+
export const DEFAULT_HISTORY_FILTERS={level:"ALL",skill:"ALL",testName:"",status:"ALL"};export const EXAM_LEVEL_LABELS={STARTERS:"STARTERS",MOVERS:"MOVERS",FLYERS:"FLYERS",PET:"PET",KET:"KET",TOEFL_JUNIOR:"TOEFL JUNIOR"};export const SKILL_LABELS={listening:"Listening","reading & writing":"Reading & Writing",writing:"Writing"};export const ALL_EXAM_LEVELS=["STARTERS","MOVERS","FLYERS","PET","KET","TOEFL_JUNIOR"];export const ALL_SKILLS=["listening","reading & writing","writing"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{};
|