@tinyweb_dev/oe-exam-sdk 0.1.26 → 0.1.27
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/README.md +5 -4
- package/dist/components/exams/ExamPreviewDialog.d.ts +7 -6
- package/dist/components/exams/ExamPreviewDialog.js +1 -1
- package/dist/components/exams/index.d.ts +0 -1
- package/dist/components/exams/take/components/QuestionRenderer.js +1 -1
- package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.js +1 -1
- package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.js +1 -1
- package/dist/components/exams/take/exam-taking.utils.d.ts +0 -13
- package/dist/components/exams/take/exam-taking.utils.js +1 -1
- package/dist/components/exams/take/utils/answer-transformers.js +1 -1
- package/dist/components/exams/take/utils/question-transformers.d.ts +7 -17
- package/dist/components/exams/take/utils/question-transformers.js +1 -1
- package/dist/components/questions/_shared/config/question-types.config.js +1 -1
- package/dist/components/questions/_shared/types/choose-the-correct-answer-group.type.d.ts +36 -0
- package/dist/components/questions/_shared/types/cross-out-word-group.type.d.ts +40 -0
- package/dist/components/questions/_shared/types/index.d.ts +1 -0
- package/dist/components/questions/_shared/types/index.js +1 -1
- package/dist/components/questions/_shared/types/true-false-group.type.d.ts +31 -0
- package/dist/components/questions/_shared/types/true-false-group.type.js +1 -0
- package/dist/components/questions/_shared/types/word-fill-structured-form.type.d.ts +11 -17
- package/dist/components/questions/creator/question-type-registry.js +1 -1
- package/dist/components/questions/index.d.ts +0 -1
- package/dist/components/questions/index.js +1 -1
- package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupClient.d.ts +2 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupClient.js +1 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupCreator.d.ts +2 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupCreator.js +1 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/index.d.ts +2 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/index.js +1 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/register.d.ts +2 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/register.js +1 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/transform.d.ts +2 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/transform.js +1 -0
- package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupClient.d.ts +2 -0
- package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupClient.js +1 -0
- package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupCreator.d.ts +2 -0
- package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupCreator.js +1 -0
- package/dist/components/questions/types/cross-out-word-group/index.d.ts +4 -0
- package/dist/components/questions/types/cross-out-word-group/index.js +1 -0
- package/dist/components/questions/types/cross-out-word-group/register.d.ts +2 -0
- package/dist/components/questions/types/cross-out-word-group/register.js +1 -0
- package/dist/components/questions/types/cross-out-word-group/transform.d.ts +2 -0
- package/dist/components/questions/types/cross-out-word-group/transform.js +1 -0
- package/dist/components/questions/types/true-false-group/TrueFalseGroupClient.d.ts +2 -0
- package/dist/components/questions/types/true-false-group/TrueFalseGroupClient.js +1 -0
- package/dist/components/questions/types/true-false-group/TrueFalseGroupCreator.d.ts +2 -0
- package/dist/components/questions/types/true-false-group/TrueFalseGroupCreator.js +1 -0
- package/dist/components/questions/types/true-false-group/index.d.ts +4 -0
- package/dist/components/questions/types/true-false-group/index.js +1 -0
- package/dist/components/questions/types/true-false-group/register.d.ts +2 -0
- package/dist/components/questions/types/true-false-group/register.js +1 -0
- package/dist/components/questions/types/true-false-group/transform.d.ts +2 -0
- package/dist/components/questions/types/true-false-group/transform.js +1 -0
- package/dist/components/questions/types/word-fill-structured-form/transform.js +1 -1
- package/dist/components/questions/viewer/QuestionViewer.js +1 -1
- package/dist/components/results/renderers/review-question-body-dedicated.js +1 -1
- package/dist/components/results/review-data.js +1 -1
- package/dist/components/themes/english-certification/EcWordFillStructuredForm.js +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -1
- package/dist/mcp/config.d.ts +12 -0
- package/dist/mcp/config.js +1 -0
- package/dist/mcp/http-client.d.ts +6 -0
- package/dist/mcp/http-client.js +1 -0
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/tools/_helpers.d.ts +4 -0
- package/dist/mcp/tools/_helpers.js +1 -0
- package/dist/mcp/tools/exams.d.ts +2 -0
- package/dist/mcp/tools/exams.js +1 -0
- package/dist/mcp/tools/index.d.ts +2 -0
- package/dist/mcp/tools/index.js +1 -0
- package/dist/mcp/tools/results.d.ts +2 -0
- package/dist/mcp/tools/results.js +1 -0
- package/dist/shared/constants/question-skills.js +1 -1
- package/dist/shared/lib/i18n/messages/en/admin.d.ts +4 -11
- package/dist/shared/lib/i18n/messages/en/admin.js +1 -1
- package/dist/shared/lib/i18n/messages/en.d.ts +4 -11
- package/dist/shared/lib/i18n/messages/vi/admin.d.ts +4 -11
- package/dist/shared/lib/i18n/messages/vi/admin.js +1 -1
- package/dist/shared/lib/i18n/messages/vi.d.ts +4 -11
- package/dist/shared/lib/utils/question-reverse-transform.js +1 -1
- package/dist/shared/lib/utils/question-transform.js +1 -1
- package/dist/shared/types/common.types.d.ts +1 -1
- package/dist/shared/types/questions/choose-the-correct-answer-group.d.ts +41 -0
- package/dist/shared/types/questions/choose-the-correct-answer-group.js +1 -0
- package/dist/shared/types/questions/cross-out-word-group.d.ts +41 -0
- package/dist/shared/types/questions/cross-out-word-group.js +1 -0
- package/dist/shared/types/questions/index.d.ts +2 -0
- package/dist/shared/types/questions/index.js +1 -1
- package/package.json +165 -169
- package/dist/components/exams/ExamPreviewPartContent.d.ts +0 -18
- package/dist/components/exams/ExamPreviewPartContent.js +0 -1
- package/dist/components/exams/ExamPreviewSidebar.d.ts +0 -17
- package/dist/components/exams/ExamPreviewSidebar.js +0 -1
- package/dist/components/exams/exam-preview.types.d.ts +0 -34
- package/dist/components/exams/exam-preview.types.js +0 -1
- package/dist/components/questions/_shared/utils/parseFillBlankStem.d.ts +0 -30
- package/dist/components/questions/_shared/utils/parseFillBlankStem.js +0 -1
- package/dist/components/questions/question-bank/EditQuestionBankDialog.d.ts +0 -2
- package/dist/components/questions/question-bank/EditQuestionBankDialog.js +0 -1
- package/dist/components/questions/question-bank/QuestionEditorRenderer.d.ts +0 -23
- package/dist/components/questions/question-bank/QuestionEditorRenderer.js +0 -1
- package/dist/components/questions/question-bank/difficulty.d.ts +0 -15
- package/dist/components/questions/question-bank/difficulty.js +0 -1
- package/dist/components/questions/question-bank/editor-adapters/choice-adapters.d.ts +0 -5
- package/dist/components/questions/question-bank/editor-adapters/choice-adapters.js +0 -1
- package/dist/components/questions/question-bank/editor-adapters/index.d.ts +0 -5
- package/dist/components/questions/question-bank/editor-adapters/index.js +0 -1
- package/dist/components/questions/question-bank/editor-adapters/media-adapters.d.ts +0 -6
- package/dist/components/questions/question-bank/editor-adapters/media-adapters.js +0 -1
- package/dist/components/questions/question-bank/editor-adapters/types.d.ts +0 -1
- package/dist/components/questions/question-bank/editor-adapters/unsupported-fallback.d.ts +0 -8
- package/dist/components/questions/question-bank/editor-adapters/unsupported-fallback.js +0 -1
- package/dist/components/questions/question-bank/editor-adapters/writing-adapters.d.ts +0 -5
- package/dist/components/questions/question-bank/editor-adapters/writing-adapters.js +0 -1
- package/dist/components/questions/question-bank/index.d.ts +0 -4
- package/dist/components/questions/question-bank/index.js +0 -1
- package/dist/components/questions/question-bank/types.d.ts +0 -59
- /package/dist/components/questions/{question-bank/editor-adapters/types.js → _shared/types/choose-the-correct-answer-group.type.js} +0 -0
- /package/dist/components/questions/{question-bank/types.js → _shared/types/cross-out-word-group.type.js} +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { MutableRefObject } from 'react';
|
|
2
|
+
export type CrossOutWordItemMode = 'CROSS_OUT' | 'CROSS_OUT_AND_REPLACE';
|
|
3
|
+
export interface CrossOutWordGroupItemAnswer {
|
|
4
|
+
type: CrossOutWordItemMode;
|
|
5
|
+
/** Word to cross out. Empty string = line is correct. */
|
|
6
|
+
crossOut: string;
|
|
7
|
+
/** Replacement word. Only for CROSS_OUT_AND_REPLACE. */
|
|
8
|
+
replaceWith?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface CrossOutWordGroupItemData {
|
|
11
|
+
type: CrossOutWordItemMode;
|
|
12
|
+
question: string;
|
|
13
|
+
correctAnswer: CrossOutWordGroupItemAnswer;
|
|
14
|
+
isExample?: boolean;
|
|
15
|
+
points: number;
|
|
16
|
+
questionNumber: number;
|
|
17
|
+
}
|
|
18
|
+
export interface CrossOutWordGroupData {
|
|
19
|
+
instruction: string;
|
|
20
|
+
items: CrossOutWordGroupItemData[];
|
|
21
|
+
explanation?: string;
|
|
22
|
+
points?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface CrossOutWordGroupCreatorProps {
|
|
25
|
+
initialData?: CrossOutWordGroupData;
|
|
26
|
+
onSave?: (data: CrossOutWordGroupData) => void;
|
|
27
|
+
onCancel?: () => void;
|
|
28
|
+
onChange?: (data: CrossOutWordGroupData) => void;
|
|
29
|
+
externalErrors?: string[];
|
|
30
|
+
onUnsavedChangesChange?: (hasUnsavedChanges: boolean) => void;
|
|
31
|
+
validationRef?: MutableRefObject<{
|
|
32
|
+
triggerValidation: () => Promise<boolean>;
|
|
33
|
+
getFormData?: () => CrossOutWordGroupData;
|
|
34
|
+
} | null>;
|
|
35
|
+
}
|
|
36
|
+
export interface CrossOutWordGroupClientProps {
|
|
37
|
+
questionData: CrossOutWordGroupData;
|
|
38
|
+
isReviewMode?: boolean;
|
|
39
|
+
userAnswers?: Array<CrossOutWordGroupItemAnswer | null | undefined>;
|
|
40
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./listening-drawline.type";export*from"./listen-and-tick-answer.type";export*from"./arrange-letters-into-words.type";export*from"./write-short-paragraph.type";export*from"./fill-missing-words-in-grid.type";export*from"./look-and-choose-answer.type";export*from"./look-picture-fill-word-hint.type";export*from"./label-the-picture.type";export*from"./read-and-color-objects.type";export*from"./fill-in-blank.type";export*from"./read-passage-and-answer-questions.type";export*from"./word-fill-structured-form.type";
|
|
1
|
+
export*from"./choose-the-correct-answer-group.type";export*from"./listening-drawline.type";export*from"./listen-and-tick-answer.type";export*from"./arrange-letters-into-words.type";export*from"./write-short-paragraph.type";export*from"./fill-missing-words-in-grid.type";export*from"./look-and-choose-answer.type";export*from"./look-picture-fill-word-hint.type";export*from"./label-the-picture.type";export*from"./read-and-color-objects.type";export*from"./fill-in-blank.type";export*from"./read-passage-and-answer-questions.type";export*from"./word-fill-structured-form.type";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { MutableRefObject } from 'react';
|
|
2
|
+
export interface TrueFalseGroupItemData {
|
|
3
|
+
question: string;
|
|
4
|
+
correctAnswer: boolean;
|
|
5
|
+
isExample?: boolean;
|
|
6
|
+
points: number;
|
|
7
|
+
questionNumber: number;
|
|
8
|
+
}
|
|
9
|
+
export interface TrueFalseGroupData {
|
|
10
|
+
instruction: string;
|
|
11
|
+
items: TrueFalseGroupItemData[];
|
|
12
|
+
explanation?: string;
|
|
13
|
+
points?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface TrueFalseGroupCreatorProps {
|
|
16
|
+
initialData?: TrueFalseGroupData;
|
|
17
|
+
onSave?: (data: TrueFalseGroupData) => void;
|
|
18
|
+
onCancel?: () => void;
|
|
19
|
+
onChange?: (data: TrueFalseGroupData) => void;
|
|
20
|
+
externalErrors?: string[];
|
|
21
|
+
onUnsavedChangesChange?: (hasUnsavedChanges: boolean) => void;
|
|
22
|
+
validationRef?: MutableRefObject<{
|
|
23
|
+
triggerValidation: () => Promise<boolean>;
|
|
24
|
+
getFormData?: () => TrueFalseGroupData;
|
|
25
|
+
} | null>;
|
|
26
|
+
}
|
|
27
|
+
export interface TrueFalseGroupClientProps {
|
|
28
|
+
questionData: TrueFalseGroupData;
|
|
29
|
+
isReviewMode?: boolean;
|
|
30
|
+
userAnswers?: boolean[];
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/** WFSF blank input width/shape (content.blankStyle). */
|
|
2
|
-
export type WfsfBlankStyle = 'letter' | 'word' | 'phrase';
|
|
3
1
|
/**
|
|
4
2
|
* WORD_FILL_STRUCTURED_FORM — creator / client contracts.
|
|
5
3
|
* wordBank + viewMode: plan 0024 (WITH_OPTIONS) + 0025 (WITH_WORD_BANK).
|
|
@@ -20,24 +18,20 @@ export interface WordFillStructuredFormData {
|
|
|
20
18
|
imageUrl?: string;
|
|
21
19
|
content: string;
|
|
22
20
|
answers: Record<string, string>;
|
|
23
|
-
/**
|
|
24
|
-
* letter = square 1-char box; word = single-word underline; phrase = multi-word.
|
|
25
|
-
* Default when omitted: word.
|
|
26
|
-
*/
|
|
27
|
-
blankStyle?: WfsfBlankStyle;
|
|
28
|
-
/**
|
|
29
|
-
* WITH_OPTIONS (0024): per-blank options.
|
|
30
|
-
* WITH_WORD_BANK (0025): shared chip box { word }[] (not 1:1 blanks).
|
|
31
|
-
* Pure free-type pages omit these fields.
|
|
32
|
-
*/
|
|
33
|
-
viewMode?: 'WITH_OPTIONS' | 'WITH_WORD_BANK' | 'DEFAULT' | string;
|
|
34
|
-
/** OPTIONS: index i ↔ {i}; WORD_BANK: shared list of { word }. */
|
|
35
|
-
wordBank?: WfsfWordBankEntry[];
|
|
36
21
|
points?: number;
|
|
37
22
|
/** Student rubric / page instruction (shown in client header). */
|
|
38
23
|
instruction?: string;
|
|
39
24
|
explanation?: string;
|
|
40
25
|
caseSensitive?: boolean;
|
|
26
|
+
/** Free-type width hint when not WITH_OPTIONS. */
|
|
27
|
+
blankStyle?: 'letter' | 'word' | 'phrase';
|
|
28
|
+
/** Discriminates wordBank shape (0024 / 0025). */
|
|
29
|
+
viewMode?: WfsfViewMode | null;
|
|
30
|
+
/**
|
|
31
|
+
* WITH_OPTIONS: index i ↔ blank {i}; entry null = free-type.
|
|
32
|
+
* WITH_WORD_BANK: shared list (not 1:1 with blanks).
|
|
33
|
+
*/
|
|
34
|
+
wordBank?: WfsfWordBankEntry[];
|
|
41
35
|
groupTitle?: string;
|
|
42
36
|
groupSubtitle?: string;
|
|
43
37
|
groupContent?: string;
|
|
@@ -74,7 +68,7 @@ export interface WordFillStructuredFormClientProps {
|
|
|
74
68
|
autoFillCorrectAnswers?: boolean;
|
|
75
69
|
/** Page rubric — prefer over hard-coded type label in header. */
|
|
76
70
|
instruction?: string;
|
|
77
|
-
|
|
78
|
-
/** Exercise / question number shown above instruction (e.g. Bài 1). */
|
|
71
|
+
/** Optional part/question index for "Bài N" prefix in header. */
|
|
79
72
|
questionNumber?: number;
|
|
73
|
+
explanation?: string;
|
|
80
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fillInBlankRegistration as r}from"../types/fill-in-blank/register";import{arrangeLettersIntoWordsRegistration as e}from"../types/arrange-letters-into-words/register";import{writeShortParagraphRegistration as t}from"../types/write-short-paragraph/register";import{fillMissingWordsInGridRegistration as s}from"../types/fill-missing-words-in-grid/register";import{lookPictureChooseCorrectAnswerRegistration as o}from"../types/look-picture-choose-correct-answer/register";import{lookPictureFillBlankChooseAnswerRegistration as i}from"../types/look-picture-fill-blank-choose-answer/register";import{lookPictureFillWordHintRegistration as _}from"../types/look-picture-fill-word-hint/register";import{labelThePictureRegistration as p}from"../types/label-the-picture/register";import{readAndColorObjectsRegistration as E}from"../types/read-and-color-objects/register";import{imageObjectMatchingRegistration as m}from"../types/image-object-matching/register";import{readPassageAndAnswerQuestionsRegistration as
|
|
1
|
+
import{fillInBlankRegistration as r}from"../types/fill-in-blank/register";import{arrangeLettersIntoWordsRegistration as e}from"../types/arrange-letters-into-words/register";import{writeShortParagraphRegistration as t}from"../types/write-short-paragraph/register";import{fillMissingWordsInGridRegistration as s}from"../types/fill-missing-words-in-grid/register";import{lookPictureChooseCorrectAnswerRegistration as o}from"../types/look-picture-choose-correct-answer/register";import{lookPictureFillBlankChooseAnswerRegistration as i}from"../types/look-picture-fill-blank-choose-answer/register";import{lookPictureFillWordHintRegistration as _}from"../types/look-picture-fill-word-hint/register";import{labelThePictureRegistration as p}from"../types/label-the-picture/register";import{readAndColorObjectsRegistration as E}from"../types/read-and-color-objects/register";import{imageObjectMatchingRegistration as m}from"../types/image-object-matching/register";import{readPassageAndAnswerQuestionsRegistration as R}from"../types/read-passage-and-answer-questions/register";import{chooseTheCorrectAnswerRegistration as S}from"../types/choose-the-correct-answer/register";import{chooseTheCorrectAnswerGroupRegistration as g}from"../types/choose-the-correct-answer-group/register";import{trueFalseGroupRegistration as n}from"../types/true-false-group/register";import{crossOutWordGroupRegistration as a}from"../types/cross-out-word-group/register";import{writeAShortLetterRegistration as A}from"../types/write-a-short-letter/register";import{writeCorrectVerbFormRegistration as O}from"../types/write-correct-verb-form/register";import{chooseCorrectAdjectiveRegistration as N}from"../types/choose-correct-adjective/register";import{answerTheQuestionRegistration as T}from"../types/answer-the-question/register";import{trueFalseRegistration as I}from"../types/true-false/register";import{wordOrderingRegistration as f}from"../types/word-ordering/register";import{wordFillParagraphRegistration as y}from"../types/word-fill-paragraph/register";import{matchByWritingAnswerRegistration as c}from"../types/match-by-writing-answer/register";import{writeSentencesRegistration as C}from"../types/write-sentences/register";import{listenAndChooseFromAnswerGroupRegistration as l}from"../types/listen-and-choose-from-answer-group/register";import{listenAndChooseObjectsInSceneRegistration as L}from"../types/listen-and-choose-objects-in-scene/register";import{listenAndDragObjectsIntoSceneRegistration as d}from"../types/listen-and-drag-objects-into-scene/register";import{listenAndSpeakAnswerRegistration as D}from"../types/listen-and-speak-answer/register";import{listenAndSpeakImageGroupRegistration as P}from"../types/listen-and-speak-image-group/register";import{listenAndSpeakQuestionListRegistration as G}from"../types/listen-and-speak-question-list/register";import{ListenAndSpeakCompareImagesRegistration as w}from"../types/listen-and-speak-compare-images/register";import{listenAndSpeakWithStoryImagesRegistration as W}from"../types/listen-and-speak-with-story-images/register";import{listenAndSpeakOddOneOutRegistration as u}from"../types/listen-and-speak-odd-one-out/register";import{listenAndSpeakInfoExchangeRegistration as h}from"../types/listen-and-speak-info-exchange/register";import{speakingDescribeImageRegistration as H}from"../types/speaking-describe-image/register";import{spontaneousQARegistration as U}from"../types/spontaneous-qa/register";import{readDisplayedContentRegistration as k}from"../types/read-displayed-content/register";import{speakingConversationRegistration as K}from"../types/speaking-conversation/register";import{gnSpeakingInterviewRegistration as F}from"../types/gn-speaking-interview/register";import{speakingCueCardRegistration as M}from"../types/speaking-cue-card/register";import{wordFillStructuredFormRegistration as b}from"../types/word-fill-structured-form/register";export const questionTypeRegistry={CHOOSE_THE_CORRECT_ANSWER:S,CHOOSE_THE_CORRECT_ANSWER_GROUP:g,TRUE_FALSE_GROUP:n,CROSS_OUT_WORD_GROUP:a,FILL_IN_BLANK:r,ARRANGE_LETTERS_INTO_WORDS:e,WRITE_SHORT_PARAGRAPH:t,FILL_MISSING_WORDS_IN_GRID:s,LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:o,LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:i,LOOK_PICTURE_FILL_WORD_HINT:_,LABEL_THE_PICTURE:p,READ_AND_COLOR_OBJECTS:E,IMAGE_OBJECT_MATCHING:m,READ_PASSAGE_AND_ANSWER_QUESTIONS:R,WRITE_A_SHORT_LETTER:A,WRITE_CORRECT_VERB_FORM:O,CHOOSE_CORRECT_ADJECTIVE:N,ANSWER_THE_QUESTION:T,TRUE_FALSE:I,WORD_ORDERING:f,WORD_FILL_PARAGRAPH:y,MATCH_BY_WRITING_ANSWER:c,WRITE_SENTENCES:C,LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:l,LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:L,LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:d,LISTEN_AND_SPEAK_ANSWER:D,LISTEN_AND_SPEAK_IMAGE_GROUP:P,LISTEN_AND_SPEAK_QUESTION_LIST:G,LISTEN_AND_SPEAK_COMPARE_IMAGES:w,LISTEN_AND_SPEAK_WITH_STORY_IMAGES:W,LISTEN_AND_SPEAK_ODD_ONE_OUT:u,LISTEN_AND_SPEAK_INFO_EXCHANGE:h,SPEAKING_DESCRIBE_IMAGE:H,SPONTANEOUS_QA:U,READ_DISPLAYED_CONTENT:k,SPEAKING_CONVERSATION:K,GN_SPEAKING_INTERVIEW:F,SPEAKING_CUE_CARD:M,WORD_FILL_STRUCTURED_FORM:b};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./creator";export*from"./creator/dedicated-component-router";export*from"./creator/question-type-registry";export*from"./components";export*from"./groups/ArticlesGroupCard";export*from"./groups/BasicQuestionGroupCard";export*from"./groups/DocumentGroupCard";export*from"./groups/MatchAnswerGroupCard";export*from"./viewer";export*from"./_shared";
|
|
1
|
+
export*from"./creator";export*from"./creator/dedicated-component-router";export*from"./creator/question-type-registry";export*from"./components";export*from"./groups/ArticlesGroupCard";export*from"./groups/BasicQuestionGroupCard";export*from"./groups/DocumentGroupCard";export*from"./groups/MatchAnswerGroupCard";export*from"./viewer";export*from"./_shared";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { ChooseTheCorrectAnswerGroupClientProps } from '../../_shared/types/choose-the-correct-answer-group.type';
|
|
2
|
+
export declare function ChooseTheCorrectAnswerGroupClient({ questionData, isReviewMode, userAnswers, }: ChooseTheCorrectAnswerGroupClientProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import{Check as t,CircleHelp as s,Lightbulb as i,Star as a}from"lucide-react";import{cn as n}from"../../../../shared/lib/utils";const d=["A","B","C","D","E","F"];export function ChooseTheCorrectAnswerGroupClient({questionData:l,isReviewMode:o=!1,userAnswers:c=[]}){const m=l.items||[];return r("div",{className:"space-y-4",children:[l.instruction&&e("div",{className:"rounded-xl border border-indigo-100 bg-indigo-50 px-4 py-3 text-sm font-medium text-indigo-800",children:l.instruction}),m.map((i,l)=>{const m=c[l];return r("div",{className:"overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm",children:[r("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:[r("div",{className:"flex items-center gap-2",children:[e("div",{className:"flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-indigo-600 text-white",children:e(s,{className:"h-3.5 w-3.5"})}),r("span",{className:"text-sm font-medium text-gray-700",children:["Câu ",i.questionNumber||l+1]}),i.isExample&&r("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:[e(a,{className:"h-3 w-3"}),"Example"]})]}),r("span",{className:"text-xs text-gray-500",children:[i.points||0," điểm"]})]}),r("div",{className:"space-y-3 p-4",children:[e("p",{className:"text-sm font-semibold leading-relaxed text-gray-800",children:i.question||"Câu hỏi chưa được nhập"}),e("div",{className:"space-y-2",children:i.options.map((s,a)=>{const l=s.id===i.correctAnswer,c=s.id===m;return r("div",{className:n("flex items-center gap-3 rounded-lg border-2 px-3 py-2.5 text-sm",o&&l?"border-green-400 bg-green-50":c?"border-blue-400 bg-blue-50":"border-gray-200 bg-white"),children:[e("span",{className:n("flex h-7 w-7 items-center justify-center rounded-md text-xs font-bold",o&&l?"bg-green-500 text-white":"bg-gray-100 text-gray-600"),children:d[a]||a+1}),e("span",{className:"flex-1 text-gray-800",children:s.text||`Đáp án ${d[a]}`}),o&&l&&e(t,{className:"h-4 w-4 text-green-600"})]},s.id||a)})})]})]},`${i.questionNumber}-${l}`)}),o&&l.explanation&&r("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:[e(i,{className:"mt-0.5 h-4 w-4 flex-shrink-0"}),l.explanation]})]})}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { ChooseTheCorrectAnswerGroupCreatorProps } from '../../_shared/types/choose-the-correct-answer-group.type';
|
|
2
|
+
export declare function ChooseTheCorrectAnswerGroupCreator({ initialData, onChange, externalErrors, onUnsavedChangesChange, validationRef, }: ChooseTheCorrectAnswerGroupCreatorProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useEffect as n,useRef as r,useState as i}from"react";import{Button as o}from"../../../../components/ui/button";import{Label as s}from"../../../../components/ui/label";import{Input as a}from"../../../../components/ui/input";import{Textarea as c}from"../../../../components/ui/textarea";import{PointsInput as l}from"../../../../components/ui/points-input";import{Card as p,CardContent as m,CardHeader as u,CardTitle as h}from"../../../../components/ui/card";import{Switch as d}from"../../../../components/ui/switch";import{useDebouncedCallback as g}from"../../../../shared/lib/hooks";import{Eye as x,Pencil as f,Plus as v,Star as y,Trash2 as b}from"lucide-react";import{ChooseTheCorrectAnswerGroupClient as N}from"./ChooseTheCorrectAnswerGroupClient";const C=["A","B","C","D","E","F"];function w(e){return{question:"",optionType:"text",options:[{id:"opt-1",text:""},{id:"opt-2",text:""},{id:"opt-3",text:""}],correctAnswer:"opt-1",isExample:!1,points:1,questionNumber:e}}function A(e){return e.reduce((e,t)=>t.isExample?e:e+("number"==typeof t.points?t.points:1),0)}function q(e,t){const n=Number.parseInt(e.replace(/[^0-9]/g,""),10);return Number.isNaN(n)?t?0:1:t?Math.max(0,n):Math.max(1,n)}export function ChooseTheCorrectAnswerGroupCreator({initialData:E,onChange:k,externalErrors:j,onUnsavedChangesChange:T,validationRef:$}){const[D,F]=i(E?.instruction||"Choose the correct answer."),[G,M]=i(()=>{return e=E?.items,Array.isArray(e)&&0!==e.length?e.map((e,t)=>({question:e.question||"",optionType:"image"===e.optionType?"image":"text",options:Array.isArray(e.options)&&e.options.length>=2?e.options.map((e,t)=>({id:e.id||`opt-${t+1}`,text:e.text||""})):w(t+1).options,correctAnswer:e.correctAnswer||"opt-1",isExample:!0===e.isExample,points:e.isExample?0:"number"==typeof e.points?e.points:1,questionNumber:e.questionNumber||t+1})):[w(1)];var e}),[V,O]=i(E?.explanation||""),[R,Z]=i(!1),[z,B]=i([]),H=r(k),I=r("");n(()=>{H.current=k},[k]);const J=(e=D,t=G,n=V)=>({instruction:e,items:t,explanation:n,points:A(t)}),S=g(e=>{H.current?.(e)},300);n(()=>{const e=J(),t=JSON.stringify(e);t!==I.current&&(I.current=t,T?.(!0),S(e))},[D,G,V,S,T]);n(()=>{$&&($.current={triggerValidation:async()=>{const e=(()=>{const e=[];return D.trim()||e.push("Vui lòng nhập hướng dẫn."),G.length<1&&e.push("Cần ít nhất một câu hỏi."),G.forEach((t,n)=>{t.question.trim()||e.push(`Câu ${n+1}: nội dung câu hỏi là bắt buộc.`),t.options.filter(e=>""!==e.text.trim()).length<2&&e.push(`Câu ${n+1}: cần ít nhất 2 đáp án.`),t.options.some(e=>e.id===t.correctAnswer&&""!==e.text.trim())||e.push(`Câu ${n+1}: hãy chọn đáp án đúng.`)}),e})();return B(e),0===e.length},getFormData:()=>J()})});const U=(e,t)=>{M(n=>n.map((n,r)=>r===e?{...n,...t}:n))};if(R)return t("div",{className:"space-y-4",children:[e("div",{className:"flex justify-end",children:t(o,{type:"button",variant:"outline",onClick:()=>Z(!1),children:[e(f,{className:"mr-2 h-4 w-4"}),"Chỉnh sửa"]})}),e(N,{questionData:J(),isReviewMode:!0})]});const X=[...z,...j||[]];return t("div",{className:"space-y-4",children:[e("div",{className:"flex justify-end",children:t(o,{type:"button",variant:"outline",onClick:()=>Z(!0),children:[e(x,{className:"mr-2 h-4 w-4"}),"Xem trước"]})}),t(p,{children:[e(u,{children:e(h,{children:"Nhóm chọn đáp án đúng"})}),t(m,{className:"space-y-4",children:[t("div",{className:"space-y-2",children:[e(s,{htmlFor:"group-instruction",children:"Hướng dẫn"}),e(a,{id:"group-instruction",value:D,onChange:e=>F(e.target.value),placeholder:"Choose the correct answer."})]}),t("div",{className:"rounded-xl border border-gray-200 bg-gray-50 p-4",children:[e(l,{value:A(G),allowZero:!0,readOnly:!0}),e("p",{className:"mt-2 text-xs text-gray-500",children:"Tổng điểm được cộng từ các câu không phải example."})]})]})]}),G.map((n,r)=>t(p,{children:[t(u,{className:"flex flex-row items-center justify-between space-y-0",children:[t(h,{className:"text-base",children:["Câu ",r+1]}),e(o,{type:"button",variant:"ghost",size:"sm",onClick:()=>{return e=r,void M(t=>t.length<=1?t:t.filter((t,n)=>n!==e).map((e,t)=>({...e,questionNumber:t+1})));var e},disabled:G.length<=1,children:e(b,{className:"h-4 w-4"})})]}),t(m,{className:"space-y-4",children:[t("div",{className:"flex items-center justify-between rounded-lg border border-amber-100 bg-amber-50 px-3 py-2",children:[t("div",{className:"flex items-center gap-2 text-sm font-medium text-amber-800",children:[e(y,{className:"h-4 w-4"}),"Câu ví dụ"]}),e(d,{checked:!0===n.isExample,onCheckedChange:e=>U(r,{isExample:e,points:e?0:n.points||1})})]}),t("div",{className:"space-y-2",children:[e(s,{children:"Câu hỏi"}),e(c,{value:n.question,onChange:e=>U(r,{question:e.target.value}),rows:2,placeholder:"A place for someone to stay or live is called"})]}),e("div",{className:"space-y-2",children:n.options.map((i,o)=>t("div",{className:"flex items-center gap-2",children:[e("input",{type:"radio",name:`correct-${r}`,checked:n.correctAnswer===i.id,onChange:()=>U(r,{correctAnswer:i.id})}),e("span",{className:"w-6 text-sm font-semibold text-gray-600",children:C[o]||o+1}),e(a,{value:i.text,onChange:e=>((e,t,n)=>{M(r=>r.map((r,i)=>{if(i!==e)return r;const o=r.options.map((e,r)=>r===t?{...e,text:n}:e);return{...r,options:o}}))})(r,o,e.target.value),placeholder:`Đáp án ${C[o]}`})]},i.id))}),!n.isExample&&e(l,{value:n.points,allowZero:!0,onChange:e=>U(r,{points:q(e.target.value,!0)})})]})]},`item-${r}`)),t(o,{type:"button",variant:"outline",onClick:()=>{M(e=>[...e,w(e.length+1)])},children:[e(v,{className:"mr-2 h-4 w-4"}),"Thêm câu hỏi"]}),t(p,{children:[e(u,{children:e(h,{className:"text-base",children:"Giải thích"})}),e(m,{children:e(c,{id:"explanation",value:V,onChange:e=>O(e.target.value),placeholder:"VD: Câu trả lời đúng là... vì...",rows:3})})]}),X.length>0&&e("div",{className:"rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700",children:X.map(t=>e("p",{children:t},t))})]})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./ChooseTheCorrectAnswerGroupCreator";export*from"./ChooseTheCorrectAnswerGroupClient";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ChooseTheCorrectAnswerGroupCreator as t}from"./ChooseTheCorrectAnswerGroupCreator";function e(t){return function(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}(t)?t:{}}function n(t,e=""){return"string"==typeof t?t:e}export const chooseTheCorrectAnswerGroupRegistration={component:t,transformInitialData:t=>{const o=t?.content,i=t?.answer,r=t?.correctAnswer||i?.correctAnswer||{},s=t?.explanation||i?.explanation||"",a=Array.isArray(r?.answer)?r.answer:[];if(Array.isArray(o?.items)){const t=o.items.map((t,o)=>function(t,o,i){const r=e(t),s=e(r.content),a=e(r.correctAnswer),p=Array.isArray(s.options)?s.options:[],c=p.length>=2?p.map((t,o)=>{const i=e(t);return{id:n(i.id,`opt-${o+1}`),text:n(i.text)}}):[{id:"opt-1",text:""},{id:"opt-2",text:""},{id:"opt-3",text:""}],u=!0===r.isExample;return{question:n(s.question)||n(r.question),optionType:"image"===n(s.optionType)?"image":"text",options:c,correctAnswer:n(a.answer)||i||c[0]?.id||"opt-1",isExample:u,points:u?0:"number"==typeof r.points?r.points:1,questionNumber:"number"==typeof r.questionNumber?r.questionNumber:o+1}}(t,o,a[o]));return{instruction:o?.meta?.instruction||"Choose the correct answer.",items:t,explanation:s,points:t.reduce((t,e)=>e.isExample?t:t+(e.points||0),0)}}return Array.isArray(i?.items)?{instruction:i.instruction||"Choose the correct answer.",items:i.items,explanation:s,points:i.points}:{instruction:"Choose the correct answer.",items:[(p=1,{question:"",optionType:"text",options:[{id:"opt-1",text:""},{id:"opt-2",text:""},{id:"opt-3",text:""}],correctAnswer:"opt-1",isExample:!1,points:1,questionNumber:p})],explanation:s,points:1};var p},getExtraProps:t=>({onUnsavedChangesChange:t.onUnsavedChangesChange,validationRef:t.validationRef}),wrapOnSave:(t,e)=>{const n=t;return{type:e.questionType,content:e.state.content,points:n.points??e.state.points??1,level:e.state.level,difficulty:e.state.difficulty,skill:e.state.skill,answer:n,explanation:n.explanation||""}},wrapOnChange:(t,e)=>{const n=t;return{type:e.questionType,content:e.state.content,points:n.points??e.state.points??1,level:e.state.level,difficulty:e.state.difficulty,skill:e.state.skill,answer:n,explanation:n.explanation||""}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function t(t,e){return t?.id&&""!==t.id.trim()?t.id:`opt-${e+1}`}function e(t){return t.reduce((t,e)=>{if(e.isExample)return t;return t+("number"==typeof e.points?e.points:1)},0)}export const transformChooseTheCorrectAnswerGroup=n=>{const r=n.answer,o=Array.isArray(r?.items)?r.items:[];if(0===o.length)return{apiContent:{items:[]},apiCorrectAnswer:{answer:[]}};const s=o.map((e,n)=>{const r=(e.options||[]).map((e,n)=>({id:t(e,n),text:e.text||""})),o=e.correctAnswer||r[0]?.id||"opt-1";return{questionType:"CHOOSE_THE_CORRECT_ANSWER",...e.isExample?{isExample:!0}:{},content:{question:e.question||"",options:r,optionType:e.optionType||"text"},correctAnswer:{answer:o},points:e.isExample?0:"number"==typeof e.points?e.points:1,questionNumber:e.questionNumber||n+1}});return{apiContent:{meta:{instruction:r?.instruction||"Choose the correct answer."},items:s},apiCorrectAnswer:{answer:s.map(t=>t.correctAnswer.answer)},totalPoints:e(o)}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{CircleHelp as r,Lightbulb as s,Star as i}from"lucide-react";import{cn as a}from"../../../../shared/lib/utils";function n(e){return e?"CROSS_OUT_AND_REPLACE"===e.type?`gạch "${e.crossOut}" → "${e.replaceWith||""}"`:e.crossOut?`gạch "${e.crossOut}"`:"câu đúng (không gạch)":"—"}export function CrossOutWordGroupClient({questionData:d,isReviewMode:l=!1,userAnswers:o=[]}){const c=d.items||[];return t("div",{className:"space-y-4",children:[d.instruction&&e("div",{className:"rounded-xl border border-indigo-100 bg-indigo-50 px-4 py-3 text-sm font-medium text-indigo-800",children:d.instruction}),c.map((s,d)=>{const c=o[d],m="CROSS_OUT_AND_REPLACE"===s.type;return t("div",{className:"overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm",children:[t("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:[t("div",{className:"flex items-center gap-2",children:[e("div",{className:"flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-indigo-600 text-white",children:e(r,{className:"h-3.5 w-3.5"})}),t("span",{className:"text-sm font-medium text-gray-700",children:["Câu ",s.questionNumber||d+1]}),s.isExample&&t("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:[e(i,{className:"h-3 w-3"}),"Example"]}),e("span",{className:a("rounded-full px-2 py-0.5 text-xs font-semibold",m?"bg-violet-100 text-violet-700":"bg-sky-100 text-sky-700"),children:m?"Gạch + thay":"Chỉ gạch"})]}),t("span",{className:"text-xs text-gray-500",children:[s.points||0," điểm"]})]}),t("div",{className:"space-y-3 p-4",children:[e("p",{className:"text-sm font-semibold leading-relaxed text-gray-800",children:s.question||"Câu hỏi chưa được nhập"}),t("div",{className:"rounded-lg border border-gray-100 bg-gray-50 px-3 py-2 text-sm text-gray-700",children:[e("span",{className:"font-medium text-gray-500",children:"Đáp án: "}),n(s.correctAnswer)]}),l&&t("div",{className:"rounded-lg border border-blue-100 bg-blue-50 px-3 py-2 text-sm text-blue-800",children:[e("span",{className:"font-medium",children:"Học sinh: "}),n(c)]})]})]},`${s.questionNumber}-${d}`)}),l&&d.explanation&&t("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:[e(s,{className:"mt-0.5 h-4 w-4 flex-shrink-0"}),d.explanation]})]})}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { CrossOutWordGroupCreatorProps } from '../../_shared/types/cross-out-word-group.type';
|
|
2
|
+
export declare function CrossOutWordGroupCreator({ initialData, onChange, externalErrors, onUnsavedChangesChange, validationRef, }: CrossOutWordGroupCreatorProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useEffect as r,useRef as n,useState as c}from"react";import{Button as s}from"../../../../components/ui/button";import{Label as i}from"../../../../components/ui/label";import{Input as a}from"../../../../components/ui/input";import{Textarea as o}from"../../../../components/ui/textarea";import{PointsInput as l}from"../../../../components/ui/points-input";import{Card as h,CardContent as m,CardHeader as u,CardTitle as d}from"../../../../components/ui/card";import{Switch as p}from"../../../../components/ui/switch";import{Select as g,SelectContent as x,SelectItem as N,SelectTrigger as C,SelectValue as f}from"../../../../components/ui/select";import{useDebouncedCallback as O}from"../../../../shared/lib/hooks";import{Eye as v,Pencil as b,Plus as y,Star as w,Trash2 as S}from"lucide-react";import{CrossOutWordGroupClient as A}from"./CrossOutWordGroupClient";function _(e,t=!1){if(""===e)return t?0:1;const r=parseInt(e.replace(/[^0-9]/g,""),10);if(Number.isNaN(r))return t?0:1;const n=t?0:1;return Math.max(n,r)}const E="Cross out the extra or incorrect word. If the word is incorrect, write the correct word. If the line is correct, leave it blank.";function R(e,t="",r=""){return"CROSS_OUT_AND_REPLACE"===e?{type:e,crossOut:t,replaceWith:r}:{type:"CROSS_OUT",crossOut:t}}function T(e){return{type:"CROSS_OUT",question:"",correctAnswer:R("CROSS_OUT"),isExample:!1,points:1,questionNumber:e}}function U(e){return e.reduce((e,t)=>t.isExample?e:e+("number"==typeof t.points?t.points:1),0)}export function CrossOutWordGroupCreator({initialData:D,onChange:q,externalErrors:W,onUnsavedChangesChange:$,validationRef:k}){const[L,P]=c(D?.instruction||E),[j,F]=c(()=>{return e=D?.items,Array.isArray(e)&&0!==e.length?e.map((e,t)=>{const r="CROSS_OUT_AND_REPLACE"===e.type||"CROSS_OUT_AND_REPLACE"===e.correctAnswer?.type?"CROSS_OUT_AND_REPLACE":"CROSS_OUT",n=R(r,e.correctAnswer?.crossOut||"",e.correctAnswer?.replaceWith||"");return{type:r,question:e.question||"",correctAnswer:n,isExample:!0===e.isExample,points:e.isExample?0:"number"==typeof e.points?e.points:1,questionNumber:e.questionNumber||t+1}}):[T(1)];var e}),[V,G]=c(D?.explanation||""),[I,z]=c(!1),[H,M]=c([]),X=n(q),J=n("");r(()=>{X.current=q},[q]);const Z=(e=L,t=j,r=V)=>({instruction:e,items:t,explanation:r,points:U(t)}),B=O(e=>{X.current?.(e)},300);r(()=>{const e=Z(),t=JSON.stringify(e);t!==J.current&&(J.current=t,B(e),$?.(!0))},[L,j,V,B,$]);r(()=>{k&&(k.current={triggerValidation:async()=>(()=>{const e=[];return L.trim()||e.push("Hướng dẫn (Instruction) không được để trống."),0===j.length&&e.push("Cần ít nhất một câu hỏi trong nhóm."),j.forEach((t,r)=>{t.question.trim()||e.push(`Câu ${r+1}: Nội dung câu không được để trống.`),"CROSS_OUT_AND_REPLACE"===t.type&&(t.correctAnswer.crossOut.trim()||e.push(`Câu ${r+1}: Cần nhập từ cần gạch (crossOut).`),t.correctAnswer.replaceWith?.trim()||e.push(`Câu ${r+1}: Cần nhập từ thay thế (replaceWith).`))}),M(e),0===e.length})(),getFormData:()=>Z()})},[k,L,j,V]);const K=(e,t)=>{F(r=>{const n=[...r],c=n[e];return c?(n[e]={...c,...t},n):r})},Q=(e,t)=>{F(r=>{const n=[...r],c=n[e];if(!c)return r;const s=c.type;return n[e]={...c,correctAnswer:R(s,void 0!==t.crossOut?t.crossOut:c.correctAnswer.crossOut,void 0!==t.replaceWith?t.replaceWith:c.correctAnswer.replaceWith||"")},n})},Y=Z(),ee=W&&W.length>0?W:H;return t("div",{className:"space-y-6",children:[t("div",{className:"flex items-center justify-between",children:[t("div",{children:[e("h3",{className:"text-lg font-medium text-gray-900",children:"Tạo câu hỏi Gạch từ / Sửa từ (Nhóm)"}),e("p",{className:"text-sm text-gray-500",children:"Mix 2 dạng: chỉ gạch từ thừa, hoặc gạch từ sai rồi thay bằng từ đúng"})]}),t(s,{type:"button",variant:"outline",size:"sm",onClick:()=>z(e=>!e),className:"gap-2",children:[e(I?b:v,{className:"h-4 w-4"}),I?"Chế độ chỉnh sửa":"Xem trước học sinh"]})]}),ee.length>0&&t("div",{className:"rounded-lg border border-red-200 bg-red-50 p-4",children:[e("h3",{className:"text-sm font-medium text-red-800",children:"Cần sửa các lỗi sau:"}),e("ul",{className:"mt-2 list-disc space-y-1 pl-5 text-sm text-red-700",children:ee.map((t,r)=>e("li",{children:t},r))})]}),I?t(h,{children:[e(u,{children:e(d,{className:"text-base font-semibold",children:"Xem trước hiển thị học sinh"})}),e(m,{children:e(A,{questionData:Y})})]}):t("div",{className:"space-y-6",children:[t(h,{children:[e(u,{children:e(d,{className:"text-base font-semibold",children:"Hướng dẫn chung (Instruction)"})}),t(m,{children:[e(i,{htmlFor:"instruction",children:"Hướng dẫn bài làm"}),e(a,{id:"instruction",value:L,onChange:e=>P(e.target.value),placeholder:E,className:"mt-1"})]})]}),t(h,{children:[t(u,{className:"flex flex-row items-center justify-between",children:[t(d,{className:"text-base font-semibold",children:["Danh sách câu (",j.length,")"]}),t(s,{type:"button",variant:"outline",size:"sm",onClick:()=>{F(e=>[...e,T(e.length+1)])},className:"gap-2",children:[e(y,{className:"h-4 w-4"}),"Thêm câu"]})]}),e(m,{className:"space-y-4",children:j.map((r,n)=>t("div",{className:"space-y-4 rounded-lg border border-gray-200 bg-gray-50/50 p-4",children:[t("div",{className:"flex flex-wrap items-center justify-between gap-4",children:[t("div",{className:"flex items-center gap-2",children:[e("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-blue-100 text-xs font-semibold text-blue-700",children:r.questionNumber||n+1}),t("span",{className:"text-sm font-medium text-gray-700",children:["Câu ",n+1]})]}),t("div",{className:"flex flex-wrap items-center gap-4",children:[e("div",{className:"w-52",children:t(g,{value:r.type,onValueChange:e=>((e,t)=>{F(r=>{const n=[...r],c=n[e];return c?(n[e]={...c,type:t,correctAnswer:R(t,c.correctAnswer.crossOut,c.correctAnswer.replaceWith||"")},n):r})})(n,e),children:[e(C,{children:e(f,{placeholder:"Loại câu"})}),t(x,{children:[e(N,{value:"CROSS_OUT",children:"Chỉ gạch (CROSS_OUT)"}),e(N,{value:"CROSS_OUT_AND_REPLACE",children:"Gạch + thay (CROSS_OUT_AND_REPLACE)"})]})]})}),t("div",{className:"flex items-center gap-2",children:[e(p,{id:`example-${n}`,checked:r.isExample||!1,onCheckedChange:e=>K(n,{isExample:e,points:e?0:1})}),t(i,{htmlFor:`example-${n}`,className:"flex cursor-pointer items-center gap-1 text-xs",children:[e(w,{className:"h-3 w-3 text-amber-500"}),"Example"]})]}),!r.isExample&&e("div",{className:"w-24",children:e(l,{value:r.points,allowZero:!0,onChange:e=>K(n,{points:_(e.target.value,!0)})})}),j.length>1&&e(s,{type:"button",variant:"ghost",size:"sm",onClick:()=>(e=>{F(t=>t.length<=1?t:t.filter((t,r)=>r!==e).map((e,t)=>({...e,questionNumber:t+1})))})(n),className:"text-red-500 hover:bg-red-50 hover:text-red-600",children:e(S,{className:"h-4 w-4"})})]})]}),t("div",{children:[e(i,{htmlFor:`question-${n}`,children:"Nội dung câu"}),e(o,{id:`question-${n}`,value:r.question,onChange:e=>K(n,{question:e.target.value}),placeholder:"Nhập câu gốc...",className:"mt-1 bg-white",rows:2})]}),t("div",{className:"grid gap-4 md:grid-cols-2",children:[t("div",{children:[t(i,{htmlFor:`crossout-${n}`,children:["Từ cần gạch (crossOut)","CROSS_OUT"===r.type&&e("span",{className:"ml-1 text-xs font-normal text-gray-500",children:"— để trống nếu câu đúng"})]}),e(a,{id:`crossout-${n}`,value:r.correctAnswer.crossOut,onChange:e=>Q(n,{crossOut:e.target.value}),placeholder:"CROSS_OUT"===r.type?"VD: to (hoặc trống)":"VD: have",className:"mt-1 bg-white"})]}),"CROSS_OUT_AND_REPLACE"===r.type&&t("div",{children:[e(i,{htmlFor:`replace-${n}`,children:"Từ thay thế (replaceWith)"}),e(a,{id:`replace-${n}`,value:r.correctAnswer.replaceWith||"",onChange:e=>Q(n,{replaceWith:e.target.value}),placeholder:"VD: has",className:"mt-1 bg-white"})]})]})]},n))})]}),t(h,{children:[e(u,{children:e(d,{className:"text-base",children:"Giải thích"})}),e(m,{children:e(o,{id:"explanation",value:V,onChange:e=>G(e.target.value),placeholder:"VD: Câu trả lời đúng là... vì...",rows:3})})]})]})]})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./CrossOutWordGroupCreator";export*from"./CrossOutWordGroupClient";export*from"./transform";export*from"./register";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{CrossOutWordGroupCreator as t}from"./CrossOutWordGroupCreator";const e="Cross out the extra or incorrect word. If the word is incorrect, write the correct word. If the line is correct, leave it blank.";function n(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function r(t){return n(t)?t:{}}function o(t,e=""){return"string"==typeof t?t:e}function s(t,e="",n=""){return"CROSS_OUT_AND_REPLACE"===t?{type:t,crossOut:e,replaceWith:n}:{type:"CROSS_OUT",crossOut:e}}export const crossOutWordGroupRegistration={component:t,transformInitialData:t=>{const i=t?.content,a=t?.answer,c=t?.correctAnswer||a?.correctAnswer||{},p=t?.explanation||a?.explanation||"",u=Array.isArray(c?.answer)?c.answer:[];if(Array.isArray(i?.items)){const t=i.items.map((t,e)=>function(t,e,i){const a=r(t),c=r(a.content),p=r(a.correctAnswer),u=n(p.answer)?p.answer:n(i)?i:{},l=function(t){return"CROSS_OUT_AND_REPLACE"===t?"CROSS_OUT_AND_REPLACE":"CROSS_OUT"}(c.type||u.type),y=!0===a.isExample;return{type:l,question:o(c.question)||o(a.question),correctAnswer:s(l,o(u.crossOut),o(u.replaceWith)),isExample:y,points:y?0:"number"==typeof a.points?a.points:1,questionNumber:"number"==typeof a.questionNumber?a.questionNumber:e+1}}(t,e,u[e]));return{instruction:i?.meta?.instruction||e,items:t,explanation:p,points:t.reduce((t,e)=>e.isExample?t:t+(e.points||0),0)}}return Array.isArray(a?.items)?{instruction:a.instruction||e,items:a.items,explanation:p,points:a.points}:{instruction:e,items:[(l=1,{type:"CROSS_OUT",question:"",correctAnswer:s("CROSS_OUT"),isExample:!1,points:1,questionNumber:l})],explanation:p,points:1};var l},getExtraProps:t=>({onUnsavedChangesChange:t.onUnsavedChangesChange,validationRef:t.validationRef}),wrapOnSave:(t,e)=>{const n=t;return{type:e.questionType,content:e.state.content,points:n.points??e.state.points??1,level:e.state.level,difficulty:e.state.difficulty,skill:e.state.skill,answer:n,explanation:n.explanation||""}},wrapOnChange:(t,e)=>{const n=t;return{type:e.questionType,content:e.state.content,points:n.points??e.state.points??1,level:e.state.level,difficulty:e.state.difficulty,skill:e.state.skill,answer:n,explanation:n.explanation||""}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function t(t){return t.reduce((t,r)=>{if(r.isExample)return t;return t+("number"==typeof r.points?r.points:1)},0)}function r(t){return"CROSS_OUT_AND_REPLACE"===t?"CROSS_OUT_AND_REPLACE":"CROSS_OUT"}export const transformCrossOutWordGroup=e=>{const n=e.answer,o=Array.isArray(n?.items)?n.items:[];if(0===o.length)return{apiContent:{items:[]},apiCorrectAnswer:{answer:[]}};const s=o.map((t,e)=>{const n=r(t.type||t.correctAnswer?.type),o=function(t,e){const n=r(t?.type||e),o={type:n,crossOut:"string"==typeof t?.crossOut?t.crossOut.trim():""};return"CROSS_OUT_AND_REPLACE"===n&&(o.replaceWith="string"==typeof t?.replaceWith?t.replaceWith.trim():""),o}(t.correctAnswer,n);return{questionType:"CROSS_OUT_WORD",...t.isExample?{isExample:!0}:{},content:{type:n,question:t.question||""},correctAnswer:{answer:o},points:t.isExample?0:"number"==typeof t.points?t.points:1,questionNumber:t.questionNumber||e+1}});return{apiContent:{meta:{instruction:n?.instruction||"Cross out the extra or incorrect word. If the word is incorrect, write the correct word."},items:s},apiCorrectAnswer:{answer:s.map(t=>t.correctAnswer.answer)},totalPoints:t(o)}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import{Check as t,CircleHelp as s,Lightbulb as a,Star as i,X as l}from"lucide-react";import{cn as n}from"../../../../shared/lib/utils";export function TrueFalseGroupClient({questionData:d,isReviewMode:o=!1,userAnswers:m=[]}){const c=d.items||[];return r("div",{className:"space-y-4",children:[d.instruction&&e("div",{className:"rounded-xl border border-indigo-100 bg-indigo-50 px-4 py-3 text-sm font-medium text-indigo-800",children:d.instruction}),c.map((a,d)=>{const c=m[d],x=a.correctAnswer;return r("div",{className:"overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm",children:[r("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:[r("div",{className:"flex items-center gap-2",children:[e("div",{className:"flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-indigo-600 text-white",children:e(s,{className:"h-3.5 w-3.5"})}),r("span",{className:"text-sm font-medium text-gray-700",children:["Câu ",a.questionNumber||d+1]}),a.isExample&&r("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:[e(i,{className:"h-3 w-3"}),"Example"]})]}),r("span",{className:"text-xs text-gray-500",children:[a.points||0," điểm"]})]}),r("div",{className:"space-y-3 p-4",children:[e("p",{className:"text-sm font-semibold leading-relaxed text-gray-800",children:a.question||"Câu hỏi chưa được nhập"}),e("div",{className:"flex items-center gap-3",children:[{value:!0,label:"True"},{value:!1,label:"False"}].map(s=>{const a=s.value===x,i=s.value===c;return r("div",{className:n("flex flex-1 items-center justify-center gap-2 rounded-lg border-2 px-4 py-2 text-sm font-semibold transition-colors",o&&a?"border-green-500 bg-green-50 text-green-700":o&&i&&!a?"border-red-500 bg-red-50 text-red-700":i?"border-blue-500 bg-blue-50 text-blue-700":"border-gray-200 bg-white text-gray-700"),children:[s.value?e(t,{className:"h-4 w-4"}):e(l,{className:"h-4 w-4"}),e("span",{children:s.label})]},String(s.value))})})]})]},`${a.questionNumber}-${d}`)}),o&&d.explanation&&r("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:[e(a,{className:"mt-0.5 h-4 w-4 flex-shrink-0"}),d.explanation]})]})}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { TrueFalseGroupCreatorProps } from '../../_shared/types/true-false-group.type';
|
|
2
|
+
export declare function TrueFalseGroupCreator({ initialData, onChange, externalErrors, onUnsavedChangesChange, validationRef, }: TrueFalseGroupCreatorProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useEffect as n,useRef as r,useState as i}from"react";import{Button as s}from"../../../../components/ui/button";import{Label as a}from"../../../../components/ui/label";import{Input as c}from"../../../../components/ui/input";import{Textarea as l}from"../../../../components/ui/textarea";import{PointsInput as o}from"../../../../components/ui/points-input";import{Card as m,CardContent as h,CardHeader as u,CardTitle as d}from"../../../../components/ui/card";import{Switch as p}from"../../../../components/ui/switch";import{useDebouncedCallback as g}from"../../../../shared/lib/hooks";import{Eye as x,Pencil as N,Plus as f,Star as b,Trash2 as v}from"lucide-react";import{TrueFalseGroupClient as y}from"./TrueFalseGroupClient";function w(e,t=!1){if(""===e)return t?0:1;const n=parseInt(e.replace(/[^0-9]/g,""),10);if(Number.isNaN(n))return t?0:1;const r=t?0:1;return Math.max(r,n)}function C(e){return{question:"",correctAnswer:!0,isExample:!1,points:1,questionNumber:e}}function q(e){return e.reduce((e,t)=>t.isExample?e:e+("number"==typeof t.points?t.points:1),0)}export function TrueFalseGroupCreator({initialData:k,onChange:E,externalErrors:T,onUnsavedChangesChange:A,validationRef:F}){const[j,D]=i(k?.instruction||"Tick True or False."),[z,$]=i(()=>{return e=k?.items,Array.isArray(e)&&0!==e.length?e.map((e,t)=>({question:e.question||"",correctAnswer:"boolean"!=typeof e.correctAnswer||e.correctAnswer,isExample:!0===e.isExample,points:e.isExample?0:"number"==typeof e.points?e.points:1,questionNumber:e.questionNumber||t+1})):[C(1)];var e}),[G,H]=i(k?.explanation||""),[I,V]=i(!1),[S,X]=i([]),J=r(E),M=r("");n(()=>{J.current=E},[E]);const O=(e=j,t=z,n=G)=>({instruction:e,items:t,explanation:n,points:q(t)}),R=g(e=>{J.current?.(e)},300);n(()=>{const e=O(),t=JSON.stringify(e);t!==M.current&&(M.current=t,R(e),A?.(!0))},[j,z,G,R,A]);n(()=>{F&&(F.current={triggerValidation:async()=>(()=>{const e=[];return j.trim()||e.push("Hướng dẫn (Instruction) không được để trống."),0===z.length&&e.push("Cần ít nhất một câu hỏi trong nhóm."),z.forEach((t,n)=>{t.question.trim()||e.push(`Câu ${n+1}: Nội dung câu hỏi không được để trống.`)}),X(e),0===e.length})(),getFormData:()=>O()})},[F,j,z,G]);const U=(e,t)=>{$(n=>{const r=[...n],i=r[e];return i?(r[e]={...i,...t},r):n})},Z=O(),B=T&&T.length>0?T:S;return t("div",{className:"space-y-6",children:[t("div",{className:"flex items-center justify-between",children:[t("div",{children:[e("h3",{className:"text-lg font-medium text-gray-900",children:"Tạo câu hỏi Đúng / Sai (Nhóm)"}),e("p",{className:"text-sm text-gray-500",children:"Thêm danh sách các câu hỏi True/False trong 1 nhóm"})]}),t(s,{type:"button",variant:"outline",size:"sm",onClick:()=>V(e=>!e),className:"gap-2",children:[e(I?N:x,{className:"h-4 w-4"}),I?"Chế độ chỉnh sửa":"Xem trước học sinh"]})]}),B.length>0&&e("div",{className:"rounded-lg bg-red-50 p-4 border border-red-200",children:e("div",{className:"flex",children:t("div",{className:"ml-3",children:[e("h3",{className:"text-sm font-medium text-red-800",children:"Cần sửa các lỗi sau:"}),e("div",{className:"mt-2 text-sm text-red-700",children:e("ul",{className:"list-disc space-y-1 pl-5",children:B.map((t,n)=>e("li",{children:t},n))})})]})})}),I?t(m,{children:[e(u,{children:e(d,{className:"text-base font-semibold",children:"Xem trước hiển thị học sinh"})}),e(h,{children:e(y,{questionData:Z})})]}):t("div",{className:"space-y-6",children:[t(m,{children:[e(u,{children:e(d,{className:"text-base font-semibold",children:"Hướng dẫn chung (Instruction)"})}),e(h,{className:"space-y-4",children:t("div",{children:[e(a,{htmlFor:"instruction",children:"Hướng dẫn bài làm"}),e(c,{id:"instruction",value:j,onChange:e=>D(e.target.value),placeholder:"VD: Tick True or False.",className:"mt-1"})]})})]}),t(m,{children:[t(u,{className:"flex flex-row items-center justify-between",children:[t(d,{className:"text-base font-semibold",children:["Danh sách câu hỏi (",z.length,")"]}),t(s,{type:"button",variant:"outline",size:"sm",onClick:()=>{$(e=>[...e,C(e.length+1)])},className:"gap-2",children:[e(f,{className:"h-4 w-4"}),"Thêm câu hỏi"]})]}),e(h,{className:"space-y-4",children:z.map((n,r)=>t("div",{className:"space-y-4 rounded-lg border border-gray-200 bg-gray-50/50 p-4 transition-colors hover:border-gray-300",children:[t("div",{className:"flex items-center justify-between gap-4",children:[t("div",{className:"flex items-center gap-2",children:[e("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-blue-100 text-xs font-semibold text-blue-700",children:n.questionNumber||r+1}),t("span",{className:"text-sm font-medium text-gray-700",children:["Câu hỏi ",r+1]})]}),t("div",{className:"flex items-center gap-4",children:[t("div",{className:"flex items-center gap-2",children:[e(p,{id:`example-${r}`,checked:n.isExample||!1,onCheckedChange:e=>U(r,{isExample:e,points:e?0:1})}),t(a,{htmlFor:`example-${r}`,className:"flex items-center gap-1 text-xs cursor-pointer",children:[e(b,{className:"h-3 w-3 text-amber-500"}),"Câu mẫu (Example)"]})]}),!n.isExample&&e("div",{className:"w-24",children:e(o,{value:n.points,allowZero:!0,onChange:e=>U(r,{points:w(e.target.value,!0)})})}),z.length>1&&e(s,{type:"button",variant:"ghost",size:"sm",onClick:()=>(e=>{$(t=>t.length<=1?t:t.filter((t,n)=>n!==e).map((e,t)=>({...e,questionNumber:t+1})))})(r),className:"text-red-500 hover:bg-red-50 hover:text-red-600",children:e(v,{className:"h-4 w-4"})})]})]}),t("div",{children:[e(a,{htmlFor:`question-${r}`,children:"Nội dung câu hỏi"}),e(l,{id:`question-${r}`,value:n.question,onChange:e=>U(r,{question:e.target.value}),placeholder:"Nhập nội dung câu hỏi...",className:"mt-1 bg-white",rows:2})]}),t("div",{children:[e(a,{className:"mb-2 block text-xs font-medium text-gray-700",children:"Đáp án đúng"}),t("div",{className:"flex items-center gap-4",children:[e(s,{type:"button",variant:!0===n.correctAnswer?"default":"outline",size:"sm",onClick:()=>U(r,{correctAnswer:!0}),className:"w-24",children:"True"}),e(s,{type:"button",variant:!1===n.correctAnswer?"default":"outline",size:"sm",onClick:()=>U(r,{correctAnswer:!1}),className:"w-24",children:"False"})]})]})]},r))})]}),t(m,{children:[e(u,{children:e(d,{className:"text-base",children:"Giải thích"})}),e(h,{children:e(l,{id:"explanation",value:G,onChange:e=>H(e.target.value),placeholder:"VD: Câu trả lời đúng là... vì...",rows:3})})]})]})]})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./TrueFalseGroupCreator";export*from"./TrueFalseGroupClient";export*from"./transform";export*from"./register";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{TrueFalseGroupCreator as t}from"./TrueFalseGroupCreator";function e(t){return function(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}(t)?t:{}}function n(t,e=""){return"string"==typeof t?t:e}export const trueFalseGroupRegistration={component:t,transformInitialData:t=>{const r=t?.content,s=t?.answer,i=t?.correctAnswer||s?.correctAnswer||{},o=t?.explanation||s?.explanation||"",a=Array.isArray(i?.answer)?i.answer:[];if(Array.isArray(r?.items)){const t=r.items.map((t,r)=>function(t,r,s){const i=e(t),o=e(i.content),a=e(i.correctAnswer),p=!0===i.isExample,u="boolean"==typeof a.answer?a.answer:"boolean"!=typeof s||s;return{question:n(o.question)||n(i.question),correctAnswer:u,isExample:p,points:p?0:"number"==typeof i.points?i.points:1,questionNumber:"number"==typeof i.questionNumber?i.questionNumber:r+1}}(t,r,a[r]));return{instruction:r?.meta?.instruction||"Tick True or False.",items:t,explanation:o,points:t.reduce((t,e)=>e.isExample?t:t+(e.points||0),0)}}return Array.isArray(s?.items)?{instruction:s.instruction||"Tick True or False.",items:s.items,explanation:o,points:s.points}:{instruction:"Tick True or False.",items:[(p=1,{question:"",correctAnswer:!0,isExample:!1,points:1,questionNumber:p})],explanation:o,points:1};var p},getExtraProps:t=>({onUnsavedChangesChange:t.onUnsavedChangesChange,validationRef:t.validationRef}),wrapOnSave:(t,e)=>{const n=t;return{type:e.questionType,content:e.state.content,points:n.points??e.state.points??1,level:e.state.level,difficulty:e.state.difficulty,skill:e.state.skill,answer:n,explanation:n.explanation||""}},wrapOnChange:(t,e)=>{const n=t;return{type:e.questionType,content:e.state.content,points:n.points??e.state.points??1,level:e.state.level,difficulty:e.state.difficulty,skill:e.state.skill,answer:n,explanation:n.explanation||""}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){return e.reduce((e,r)=>{if(r.isExample)return e;return e+("number"==typeof r.points?r.points:1)},0)}export const transformTrueFalseGroup=r=>{const t=r.answer,n=Array.isArray(t?.items)?t.items:[];if(0===n.length)return{apiContent:{items:[]},apiCorrectAnswer:{answer:[]}};const s=n.map((e,r)=>{const t=!("boolean"==typeof e.correctAnswer)||e.correctAnswer;return{questionType:"TRUE_FALSE",...e.isExample?{isExample:!0}:{},content:{question:e.question||""},correctAnswer:{answer:t},points:e.isExample?0:"number"==typeof e.points?e.points:1,questionNumber:e.questionNumber||r+1}});return{apiContent:{meta:{instruction:t?.instruction||"Tick True or False."},items:s},apiCorrectAnswer:{answer:s.map(e=>e.correctAnswer.answer)},totalPoints:e(n)}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const transformWordFillStructuredForm=e=>{const
|
|
1
|
+
export const transformWordFillStructuredForm=e=>{const t=e.answer;if(!t?.content||!t?.answers)return{apiContent:{},apiCorrectAnswer:{}};const r=!!(t.groupTitle||t.groupSubtitle||t.groupContent||t.groupImageUrl),n={title:t.title||"",imageUrl:t.imageUrl||"",content:t.content};"letter"!==t.blankStyle&&"word"!==t.blankStyle&&"phrase"!==t.blankStyle||(n.blankStyle=t.blankStyle),"WITH_OPTIONS"!==t.viewMode&&"WITH_WORD_BANK"!==t.viewMode||(n.viewMode=t.viewMode),Array.isArray(t.wordBank)&&(n.wordBank=t.wordBank);return{apiContent:n,apiCorrectAnswer:{answers:t.answers,caseSensitive:t.caseSensitive??!1},basicGroupData:r?{title:t.groupTitle||"",subtitle:t.groupSubtitle||"",content:t.groupContent||"",imageUrl:t.groupImageUrl||""}:void 0,groupNumber:t.groupNumber||1}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import{Button as t}from"../../../components/ui/button";import{Card as n,CardContent as s,CardHeader as a,CardTitle as o}from"../../../components/ui/card";import{Input as i}from"../../../components/ui/input";import{Check as l,Volume2 as c,X as d}from"lucide-react";import{useRef as u,useState as m}from"react";import{toast as p}from"sonner";import{t as g}from"../../../shared/lib/i18n";import{ReadAndColorObjectsClient as b}from"../types/read-and-color-objects/ReadAndColorObjectsClient";import{ArrangeLettersIntoWordsClient as h}from"../types/arrange-letters-into-words/ArrangeLettersIntoWordsClient";import{WriteShortParagraphClient as w}from"../types/write-short-paragraph/WriteShortParagraphClient";import{LabelThePictureClient as x}from"../types/label-the-picture/LabelThePictureClient";import{LookPictureFillWordHintClient as N}from"../types/look-picture-fill-word-hint/LookPictureFillWordHintClient";import{ReadPassageAndAnswerQuestionsClient as y}from"../types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsClient";import{ChooseTheCorrectAnswerClient as f}from"../types/choose-the-correct-answer/ChooseTheCorrectAnswerClient";import{WriteAShortLetterClient as A}from"../types/write-a-short-letter/WriteAShortLetterClient";import{LookPictureChooseCorrectAnswerClient as v}from"../types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerClient";import{LookPictureFillBlankChooseAnswerClient as S}from"../types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerClient";import{FillMissingWordsInGridClient as C}from"../types/fill-missing-words-in-grid/FillMissingWordsInGridClient";import{WordFillStructuredFormClient as _}from"../types/word-fill-structured-form/WordFillStructuredFormClient";import{parseFillBlankStemLine as R}from"../_shared/utils/parseFillBlankStem";export function QuestionViewer({question:T,onSubmitAnswer:E,isReviewMode:I=!1,userAnswer:O}){const[k,W]=m(O||null),[$,D]=m(0),U=u(null),[q,M]=m(O||{}),P=T.answer,[B,F]=m(O||Array(P?.blanks?.length||0).fill("")),[j,H]=m(O||{}),[Q,G]=m(O||{}),[K,Y]=m(O||{}),V=()=>{const e=T.answer.maxPlayCount||3;$>=e?p.warning(g("common.audio.maxPlayReached",{maxPlay:String(e)})):(U.current?.play(),D($+1))},z=()=>{switch(T.type){case"CHOOSE_THE_CORRECT_ANSWER":return(()=>{const r=T.answer,{isGroup:t,questionGroup:n}=T;let s={};return s=T.content&&"object"==typeof T.content?{...T.content,correctAnswer:T.correctAnswer?.answer??-1,id:T.id,isGroup:t,groupTitle:n?.payload?.title,groupContent:n?.payload?.content,groupImageUrl:n?.payload?.imageUrl,groupNumber:n?.groupNumber}:{...r,question:T.content||r?.question,id:T.id,isGroup:t,groupTitle:n?.payload?.title,groupContent:n?.payload?.content,groupImageUrl:n?.payload?.imageUrl,groupNumber:n?.groupNumber},e(f,{questionData:s,questionConfig:T.questionConfig,onSubmit:e=>{W(e),E?.(e)},isReviewMode:I,userAnswer:O})})();case"FILL_IN_BLANK":return(()=>{const n=T.content&&"object"==typeof T.content?T.content:{},s=T.answer??{},a=Boolean(s.caseSensitive),o="string"==typeof n.question?n.question:"string"==typeof T.content?T.content:"",c="box"===String(n.blankStyle||"").toLowerCase()?"box":"underline",u=(()=>{if(Array.isArray(s.answers)&&s.answers.length>0)return s.answers.map(e=>Array.isArray(e)?String(e[0]??""):String(e??""));if(Array.isArray(s.blanks)&&s.blanks.length>0)return"string"==typeof s.blanks[0]?s.blanks.map(e=>String(e??"")):s.blanks.map(e=>String(e?.correctAnswer??""));const e=[...o.matchAll(/\{(\d+)\}/g)].map(e=>Number(e[1]));if(e.length>0){const r=Math.max(...e);return Array.from({length:r+1},()=>"")}return[""]})(),m=Array.isArray(B)&&B.length>0?B:Array.from({length:u.length},()=>""),p=(e,r)=>{const t=Array.from({length:Math.max(u.length,m.length,e+1)},(e,r)=>m[r]??"");t[e]=r,F(t),W(t)},g=(e,r)=>{const t=u[e]??"";return!!r&&(a?r===t:r.toLowerCase()===t.toLowerCase())},b=(r,t)=>R(r).map((r,n)=>{if("text"===r.kind)return r.text?e("span",{className:r.bold?"font-semibold":void 0,children:r.text},`${t}-t${n}`):null;const s=m[r.index]||"",a=I&&g(r.index,s),o="box"===c;return e("input",{type:"text",value:s,disabled:I,maxLength:o?Math.max(1,(u[r.index]||" ").length):void 0,"aria-label":`Blank ${r.index+1}`,onChange:e=>p(r.index,e.target.value),className:`mx-0.5 inline-block bg-transparent text-center outline-none ${o?"h-7 w-7 rounded border-2 px-0 text-sm font-semibold uppercase":"min-w-[4.5rem] border-0 border-b-2 px-1 text-base"} ${I?a?"border-green-500 bg-green-50 text-green-800":"border-red-500 bg-red-50 text-red-800":"border-slate-400"}`},`${t}-b${r.index}`)});if(o&&/\{\d+\}/.test(o)){const s=o.includes("\n")?o.split("\n"):[o];return r("div",{className:"space-y-3",children:[n.imageUrl?e("div",{className:"flex justify-center",children:e("img",{src:String(n.imageUrl),alt:"",className:"max-h-[200px] rounded-lg object-contain"})}):null,e("div",{className:"space-y-2 text-base leading-relaxed text-slate-800",children:s.map((r,t)=>e("div",{className:"flex flex-wrap items-baseline",children:b(r,`fill-l${t}`)},`fill-line-${t}`))}),I?r("div",{className:"rounded-lg border border-emerald-200 bg-emerald-50/80 p-2.5 text-sm text-emerald-800",children:[e("span",{className:"font-semibold",children:"Đáp án: "}),u.map((t,n)=>r("span",{className:"mr-2",children:["(",n+1,") ",e("span",{className:"font-bold underline",children:t||"—"})]},`ans-${n}`))]}):null,!I&&e(t,{onClick:()=>E?.(m),disabled:m.some(e=>!String(e??"").trim()),children:"Nộp đáp án"})]})}return r("div",{className:"space-y-4",children:[u.map((t,n)=>{const s=m[n]||"",a=I&&g(n,s);return r("div",{className:"flex items-center space-x-2",children:[r("span",{className:"text-sm font-medium",children:["Chỗ trống ",n+1,":"]}),e(i,{value:s,onChange:e=>p(n,e.target.value),placeholder:"Nhập đáp án...",className:"flex-1 "+(I?a?"border-green-500 bg-green-50":"border-red-500 bg-red-50":""),disabled:I}),I&&a&&e(l,{className:"h-4 w-4 text-green-600"}),I&&!a&&s&&e(d,{className:"h-4 w-4 text-red-600"})]},n)}),!I&&e(t,{onClick:()=>{E&&E(m)},disabled:m.some(e=>""===String(e??"").trim()),children:"Nộp đáp án"})]})})();case"TRUE_FALSE":return(()=>{const n=T.answer,{correctAnswer:s}=n;return r("div",{className:"space-y-3",children:[[{value:!0,label:"Đúng"},{value:!1,label:"Sai"}].map(t=>{const n=k===t.value;return e("div",{className:`flex cursor-pointer items-center rounded-lg border p-3 transition-colors ${n?"border-blue-500 bg-blue-50":"border-gray-200 hover:border-gray-300"} ${I&&t.value===s?"border-green-500 bg-green-50":I&&n&&t.value!==s?"border-red-500 bg-red-50":""}`,onClick:()=>!I&&W(t.value),children:r("div",{className:"flex w-full items-center",children:[e("div",{className:`mr-3 h-4 w-4 rounded-full border-2 ${n?"border-blue-500 bg-blue-500":"border-gray-300"} ${I&&t.value===s?"border-green-500 bg-green-500":""}`,children:n&&e("div",{className:"m-auto h-2 w-2 rounded-full bg-white"})}),e("span",{className:"flex-1",children:t.label}),I&&t.value===s&&e(l,{className:"ml-2 h-4 w-4 text-green-600"}),I&&n&&t.value!==s&&e(d,{className:"ml-2 h-4 w-4 text-red-600"})]})},t.value.toString())}),!I&&e(t,{onClick:()=>{E&&E(k)},disabled:null===k,children:"Nộp đáp án"})]})})();case"ESSAY":return(()=>{const n=T.answer,{minWords:s,maxWords:a}=n,o=k?k.trim().split(/\s+/).length:0;return r("div",{className:"space-y-4",children:[r("div",{className:"text-sm text-gray-600",children:[s&&a?`Số từ: ${s} - ${a} từ`:s?`Tối thiểu: ${s} từ`:a?`Tối đa: ${a} từ`:"",k&&r("span",{className:"ml-2 "+(o>=(s||0)&&o<=(a||1/0)?"text-green-600":"text-red-600"),children:["(",o," từ)"]})]}),e("textarea",{value:k||"",onChange:e=>W(e.target.value),placeholder:"Viết câu trả lời của bạn ở đây...",className:"h-32 w-full resize-none rounded-lg border border-gray-300 p-3 focus:border-blue-500 focus:ring-1 focus:ring-blue-500",disabled:I}),!I&&e(t,{onClick:()=>{E&&E(k)},disabled:!k||k.trim().length<(s||0),children:"Nộp đáp án"})]})})();case"LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE":return(()=>{const n=T.answer,{audioUrl:s,blanks:a}=n;return r("div",{className:"space-y-4",children:[r("div",{className:"flex items-center gap-4 rounded-lg bg-blue-50 p-4",children:[r(t,{onClick:V,variant:"outline",className:"gap-2",children:[e(c,{className:"h-5 w-5"}),"Phát âm thanh (",$,"/",n.maxPlayCount||3,")"]}),e("audio",{ref:U,src:s})]}),e("div",{className:"space-y-3",children:a.map((t,n)=>r("div",{className:"flex items-center gap-3",children:[r("span",{className:"w-20 font-medium",children:["Blank ",n+1,":"]}),e(i,{value:B[n],onChange:e=>{const r=[...B];r[n]=e.target.value,F(r),W(r)},placeholder:"Nhập câu trả lời...",disabled:I,className:I?B[n]?.toLowerCase()===a[n]?.toLowerCase()?"border-green-500 bg-green-50":"border-red-500 bg-red-50":""}),I&&r("span",{className:"text-sm text-gray-600",children:["Đáp án: ",e("strong",{children:a[n]})]})]},n))})]})})();case"TICK_TRUE_OR_FALSE":case"TICK_YES_OR_NO":return(()=>{const t=T.answer,{statements:n}=t;return e("div",{className:"space-y-3",children:n.map(t=>e("div",{className:`rounded-lg border-2 p-4 ${I&&q[t.id]===t.isCorrect?"border-green-500 bg-green-50":""} ${I&&q[t.id]!==t.isCorrect?"border-red-500 bg-red-50":"border-gray-200"} `,children:r("div",{className:"flex items-start gap-4",children:[r("div",{className:"mt-1 flex gap-2",children:[e("button",{onClick:()=>{const e={...q,[t.id]:!0};M(e),W(e)},disabled:I,className:`flex h-8 w-8 items-center justify-center rounded border-2 ${!0===q[t.id]?"border-green-500 bg-green-500 text-white":"border-gray-300"} `,children:e(l,{className:"h-5 w-5"})}),e("button",{onClick:()=>{const e={...q,[t.id]:!1};M(e),W(e)},disabled:I,className:`flex h-8 w-8 items-center justify-center rounded border-2 ${!1===q[t.id]?"border-red-500 bg-red-500 text-white":"border-gray-300"} `,children:e(d,{className:"h-5 w-5"})})]}),e("p",{className:"flex-1",children:t.text}),I&&e("span",{className:"text-sm font-medium",children:t.isCorrect?"✓ Đúng":"✗ Sai"})]})},t.id))})})();case"ARRANGE_LETTERS_INTO_WORDS":return(()=>{const r=T.answer,t=T.correctAnswer||T.correct_answer,n=(r?.subQuestions||[]).map(e=>{const r=t?.answers?.[e.id]||e.correctWord||"";return{...e,correctWord:r}});return e(h,{questionData:{subQuestions:n},onSubmit:e=>{W(e),E?.(e)},isReviewMode:I,userAnswer:O})})();case"READ_PASSAGE_AND_COMPLETE_STORY":return(()=>{const t=T.answer,{passage:n,blanks:s}=t,a=n.split(/\{(\d+)\}/);return e("div",{className:"space-y-4",children:e("div",{className:"prose max-w-none",children:e("div",{className:"text-lg leading-relaxed",children:a.map((t,n)=>{const a=parseInt(t);if(!isNaN(a)){const t=s.find(e=>e.index===a);return r("span",{className:"mx-1 inline-flex items-center",children:[e(i,{value:Q[a]||"",onChange:e=>{const r={...Q,[a]:e.target.value};G(r),W(r)},className:`inline-block h-8 w-32 text-center ${I&&Q[a]===t?.correctAnswer?"border-green-500 bg-green-50":""} ${I&&Q[a]!==t?.correctAnswer?"border-red-500 bg-red-50":""} `,disabled:I}),I&&r("span",{className:"ml-2 text-sm text-green-600",children:["(",t?.correctAnswer,")"]})]},n)}return e("span",{children:t},n)})})})})})();case"WRITE_SHORT_PARAGRAPH":return(()=>{const r=T.answer;return e(w,{questionData:{contexts:r?.contexts||[],minWords:r?.minWords||20,maxWords:r?.maxWords,instruction:r?.instruction||""},onSubmit:e=>{W(e),E?.(e)},isReviewMode:I,userAnswer:O})})();case"WRITE_A_SHORT_LETTER":return(()=>{const r=T.answer;return e(A,{questionData:{contexts:r?.contexts||[],informations:r?.informations||[],minWords:r?.minWords||20,maxWords:r?.maxWords,instruction:r?.instruction||""},onSubmit:e=>{W(e),E?.(e)},isReviewMode:I,userAnswer:O})})();case"LOOK_PICTURE_FILL_WORD_HINT":return(()=>{const r=T.answer,t=T.content,n=T.questionGroup;let s=[];r?.subQuestions&&r.subQuestions.length>0?s=r.subQuestions:t?.imageUrl&&t?.word&&(s=[{id:T.id,imageUrl:t.imageUrl,word:t.word,correctAnswer:r?.correctAnswer||"",groupNumber:n?.groupNumber||1}]);const a=n?.payload?.hintLetters||r?.hintLetters||t?.hintLetters||[],o=n?.groupNumber||1,i={};a.length>0&&(i[o]=a);const l={subQuestions:s,hintLetters:a,hintLettersByGroup:i,groups:[{number:o,questionCount:s.length}]};return e(N,{questionData:l,userAnswer:O,isReviewMode:I,explanation:T.explanation,onSubmit:e=>{W(e),E?.(e)}})})();case"LABEL_THE_PICTURE":return(()=>{const r=T.answer;return e(x,{questionData:r,userAnswer:O,isReviewMode:I,onSubmit:e=>{W(e),E?.(e)}})})();case"READ_AND_COLOR_OBJECTS":return(()=>{const r=T.answer;return e(b,{questionData:{backgroundImageUrl:r?.backgroundImageUrl||"",colorNodes:r?.colorNodes||[],regionNodes:r?.regionNodes||[],instructions:r?.instructions||[]},onSubmit:e=>{W(e),E?.(e)}})})();case"READ_PASSAGE_AND_ANSWER_QUESTIONS":return(()=>{const r=T.answer;return e(y,{questionData:{passage:r?.passage||"",passageTitle:r?.passageTitle||"",instructions:r?.instructions||"",subQuestions:r?.subQuestions||[]},userAnswer:O,isReviewMode:I,onSubmit:e=>{W(e),E?.(e)}})})();case"LOOK_PICTURE_CHOOSE_CORRECT_ANSWER":return(()=>{const r=T.content,t=T.answer,n=(r?.subQuestions||t?.subQuestions||[]).map(e=>{const r=t?.answers?.[e.id]||e.correctAnswer;return{...e,options:(e.options||[]).map(e=>({...e,isCorrect:e.id===r}))}});return e(v,{questionData:{subQuestions:n},userAnswer:O,isReviewMode:I,onSubmit:e=>{W(e),E?.(e)}})})();case"LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER":return(()=>{const r=T.content,t=T.answer,n=(r?.subQuestions||t?.subQuestions||[]).map(e=>{const r=t?.answers?.[e.id]||e.correctAnswer;return{...e,options:(e.options||[]).map(e=>({...e,isCorrect:e.id===r}))}});return e(S,{questionData:{subQuestions:n},userAnswer:O,isReviewMode:I,onSubmit:e=>{W(e),E?.(e)}})})();case"FILL_MISSING_WORDS_IN_GRID":return(()=>{const r=T.content,t=T.answer;return e(C,{questionData:{content:{grid:r?.grid||[],rows:r?.rows||3,columns:r?.columns||3,disabledCells:r?.disabledCells||[]},answer:{answers:t?.answers||{},missingLetters:t?.missingLetters||[],caseSensitive:t?.caseSensitive||!1}},userAnswer:O,isReviewMode:I,onSubmit:e=>{W(e),E?.(e)}})})();case"WORD_FILL_PARAGRAPH":return(()=>{const t=T.content&&"object"==typeof T.content?T.content:{},n=T.answer??{},s=String(t.paragraph||""),a=Array.isArray(n.answers)?n.answers.map(e=>String(e??"")):[],o=(Array.isArray(t.wordBank)?t.wordBank:[]).map(e=>{if("string"==typeof e)return{word:e,options:[]};const r=Array.isArray(e?.options)?e.options.map(String):[];return{word:String(e?.word??r[0]??""),options:r,isExample:Boolean(e?.isExample)}}),i=String(t.viewMode||(o.some(e=>e.options.length)?"WITH_OPTIONS":"DEFAULT")).toUpperCase(),l=[...s.matchAll(/\{(\d+)\}/g)].map(e=>Number(e[1])),c=l.length>0?Math.max(...l)+1:Math.max(a.length,o.length,1),d=Array.isArray(O)?O:Array.isArray(k)?k:Array.from({length:c},()=>""),u=(e,r)=>{const t=Array.from({length:c},(e,r)=>d[r]??"");t[e]=r,W(t)},m=(t,n)=>t.split(/(\{\d+\})/g).map((t,s)=>{const l=/^\{(\d+)\}$/.exec(t);if(!l)return e("span",{children:t},`${n}-t${s}`);const c=Number(l[1]),m=o[c],p=m?.options?.length?m.options:o.flatMap(e=>e.options).filter(Boolean),g=d[c]??"",b=a[c]??"",h=I&&g&&b&&g.toLowerCase()===b.toLowerCase();return"WITH_OPTIONS"===i&&p.length>0?r("select",{value:g,disabled:I,onChange:e=>u(c,e.target.value),className:"mx-1 inline-block min-w-[7rem] rounded border px-2 py-1 text-sm "+(I?h?"border-green-500 bg-green-50":"border-red-500 bg-red-50":"border-slate-300"),children:[e("option",{value:"",children:"—"}),p.map(r=>e("option",{value:r,children:r},r))]},`${n}-b${c}`):e("input",{type:"text",value:g,disabled:I,onChange:e=>u(c,e.target.value),className:"mx-1 inline-block min-w-[5rem] border-0 border-b-2 px-1 text-center outline-none "+(I?h?"border-green-500 bg-green-50":"border-red-500 bg-red-50":"border-slate-400")},`${n}-b${c}`)});return s.trim()?r("div",{className:"space-y-3",children:[t.title?e("h3",{className:"text-center text-lg font-bold uppercase text-slate-800",children:t.title}):null,t.imageUrl?e("div",{className:"flex justify-center",children:e("img",{src:String(t.imageUrl),alt:"",className:"max-h-[180px] rounded-lg object-contain"})}):null,e("div",{className:"space-y-2 text-base leading-relaxed text-slate-800",children:s.split("\n").map((r,t)=>e("div",{className:"flex flex-wrap items-baseline",children:m(r,`wfp-${t}`)},`wfp-l${t}`))}),I&&a.length>0?r("div",{className:"rounded-lg border border-emerald-200 bg-emerald-50/80 p-2.5 text-sm text-emerald-800",children:[e("span",{className:"font-semibold",children:"Đáp án: "}),a.map((t,n)=>r("span",{className:"mr-2",children:["(",n+1,") ",e("span",{className:"font-bold underline",children:t||"—"})]},`wfp-a${n}`))]}):null]}):e("div",{className:"text-sm text-gray-500",children:"Không có nội dung đoạn văn."})})();case"WORD_FILL_STRUCTURED_FORM":return(()=>{const r=T.content&&"object"==typeof T.content?T.content:{},t=T.answer??T.correctAnswer??{},n=t?.answers&&"object"==typeof t.answers&&!Array.isArray(t.answers)?t.answers:{},s=String(r.content||""),a=String(r.blankStyle||"").toLowerCase(),o="letter"===a||"box"===a?"letter":"phrase"===a||"sentence"===a?"phrase":"word",i=O&&"object"==typeof O&&!Array.isArray(O)?O:k&&"object"==typeof k&&!Array.isArray(k)?k:I?n:{},l="number"==typeof T.questionNumber&&T.questionNumber>0?T.questionNumber:void 0,c=Array.isArray(r.wordBank)?r.wordBank:void 0,d=c?.map(e=>{if(null==e||"object"!=typeof e)return null;const r=e;if(Array.isArray(r.options)){const e=r.options.map(e=>String(e??"").trim()).filter(Boolean);return e.length>=2?{options:e}:null}const t=String(r.word??"").trim();return t?r.isExample?{word:t,isExample:!0}:{word:t}:null}),u=Boolean(d?.some(e=>null!=e&&"options"in e&&Array.isArray(e.options)&&(e.options?.length??0)>=2)),m=Boolean(d?.some(e=>null!=e&&"word"in e&&e.word)),p=String(r.viewMode||"").trim()||(u?"WITH_OPTIONS":m?"WITH_WORD_BANK":void 0);return e(_,{questionData:{title:String(r.title||""),imageUrl:r.imageUrl?String(r.imageUrl):void 0,content:s,blankStyle:o,answers:n,caseSensitive:Boolean(t?.caseSensitive),explanation:T.explanation,...p?{viewMode:p}:{},...(u||m)&&d?{wordBank:d}:{}},userAnswer:i,isReviewMode:I,autoFillCorrectAnswers:I&&0===Object.keys(i).length,explanation:T.explanation,questionNumber:l,onAnswerChange:(e,r)=>{const t=k&&"object"==typeof k&&!Array.isArray(k)?k:{};W({...t,[e]:r})}})})();default:return r("div",{children:["Loại câu hỏi không được hỗ trợ: ",T.type]})}},J=(()=>{if("WORD_FILL_STRUCTURED_FORM"===T.type)return null;if("FILL_IN_BLANK"===T.type||"WORD_FILL_PARAGRAPH"===T.type)return"Câu hỏi";if("string"==typeof T.content)return L(T.content)||"Câu hỏi";const e=T.content,r=e?.title||e?.question||e?.paragraph||"";return e?.title?L(e.title)||"Câu hỏi":"string"==typeof r&&(/\{\d+\}/.test(r)||/\*\*/.test(r))?"Câu hỏi":L(r)||"Câu hỏi"})();return"WORD_FILL_STRUCTURED_FORM"===T.type?e("div",{className:"space-y-4",children:z()}):r(n,{children:[J?e(a,{children:r(o,{className:"flex items-center justify-between",children:[e("span",{className:"min-w-0 pr-2 text-base font-semibold leading-snug",children:J}),r("span",{className:"shrink-0 text-sm font-normal text-gray-500",children:[T.points," điểm"]})]})}):null,e(s,{className:J?"space-y-4":"space-y-4 pt-4",children:z()})]})}function L(e){return String(e||"").replace(/\*\*/g,"").replace(/\{(\d+)\}/g,"___").replace(/\s+/g," ").trim()}
|
|
1
|
+
"use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import{Button as s}from"../../../components/ui/button";import{Card as t,CardContent as n,CardHeader as o,CardTitle as a}from"../../../components/ui/card";import{Input as i}from"../../../components/ui/input";import{Check as c,Volume2 as l,X as d}from"lucide-react";import{useRef as u,useState as m}from"react";import{toast as p}from"sonner";import{t as g}from"../../../shared/lib/i18n";import{ReadAndColorObjectsClient as b}from"../types/read-and-color-objects/ReadAndColorObjectsClient";import{ArrangeLettersIntoWordsClient as h}from"../types/arrange-letters-into-words/ArrangeLettersIntoWordsClient";import{WriteShortParagraphClient as w}from"../types/write-short-paragraph/WriteShortParagraphClient";import{LabelThePictureClient as N}from"../types/label-the-picture/LabelThePictureClient";import{LookPictureFillWordHintClient as x}from"../types/look-picture-fill-word-hint/LookPictureFillWordHintClient";import{ReadPassageAndAnswerQuestionsClient as f}from"../types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsClient";import{ChooseTheCorrectAnswerClient as C}from"../types/choose-the-correct-answer/ChooseTheCorrectAnswerClient";import{WriteAShortLetterClient as A}from"../types/write-a-short-letter/WriteAShortLetterClient";import{LookPictureChooseCorrectAnswerClient as _}from"../types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerClient";import{LookPictureFillBlankChooseAnswerClient as y}from"../types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerClient";import{FillMissingWordsInGridClient as v}from"../types/fill-missing-words-in-grid/FillMissingWordsInGridClient";export function QuestionViewer({question:R,onSubmitAnswer:S,isReviewMode:E=!1,userAnswer:L}){const[T,O]=m(L||null),[I,W]=m(0),k=u(null),[q,D]=m(L||{}),P=R.answer,[U,Q]=m(L||Array(P?.blanks?.length||0).fill("")),[G,M]=m(L||{}),[H,$]=m(L||{}),[j,F]=m(L||{}),[B,K]=m(L||{}),Y=()=>{const e=R.answer.maxPlayCount||3;I>=e?p.warning(g("common.audio.maxPlayReached",{maxPlay:String(e)})):(k.current?.play(),W(I+1))},V=()=>{const t=R.answer,{blanks:n,caseSensitive:o=!1}=t;return r("div",{className:"space-y-4",children:[n.map((s,t)=>{const a=U[t]||"",l=E&&((e,r)=>{const s=n[e];return o?r===s:r.toLowerCase()===s.toLowerCase()})(t,a);return r("div",{className:"flex items-center space-x-2",children:[r("span",{className:"text-sm font-medium",children:["Chỗ trống ",t+1,":"]}),e(i,{value:a,onChange:e=>((e,r)=>{const s=[...U];s[e]=r,Q(s)})(t,e.target.value),placeholder:"Nhập đáp án...",className:"flex-1 "+(E?l?"border-green-500 bg-green-50":"border-red-500 bg-red-50":""),disabled:E}),E&&l&&e(c,{className:"h-4 w-4 text-green-600"}),E&&!l&&a&&e(d,{className:"h-4 w-4 text-red-600"})]},t)}),!E&&e(s,{onClick:()=>{S&&S(U)},disabled:U.some(e=>""===e.trim()),children:"Nộp đáp án"})]})};return r(t,{children:[e(o,{children:r(a,{className:"flex items-center justify-between",children:[e("span",{children:"string"==typeof R.content?R.content:R.content?.question||"Câu hỏi"}),r("span",{className:"text-sm font-normal text-gray-500",children:[R.points," điểm"]})]})}),r(n,{className:"space-y-4",children:[(()=>{switch(R.type){case"CHOOSE_THE_CORRECT_ANSWER":return(()=>{const r=R.answer,{isGroup:s,questionGroup:t}=R;let n={};return n=R.content&&"object"==typeof R.content?{...R.content,correctAnswer:R.correctAnswer?.answer??-1,id:R.id,isGroup:s,groupTitle:t?.payload?.title,groupContent:t?.payload?.content,groupImageUrl:t?.payload?.imageUrl,groupNumber:t?.groupNumber}:{...r,question:R.content||r?.question,id:R.id,isGroup:s,groupTitle:t?.payload?.title,groupContent:t?.payload?.content,groupImageUrl:t?.payload?.imageUrl,groupNumber:t?.groupNumber},e(C,{questionData:n,questionConfig:R.questionConfig,onSubmit:e=>{O(e),S?.(e)},isReviewMode:E,userAnswer:L})})();case"CHOOSE_THE_CORRECT_ANSWER_GROUP":return(()=>{const s=R.content,t=R.correctAnswer||R.correct_answer||R.answer,n=s?.items||[],o=Array.isArray(t?.answer)?t.answer:[];return e("div",{className:"space-y-5",children:n.map((s,t)=>{const n=o[t],a=B[t],i=s?.content?.options||[];return r("div",{className:"space-y-2",children:[e("p",{className:"text-sm font-medium leading-relaxed",children:s?.content?.question||""}),e("div",{className:"flex flex-wrap gap-2",children:i.map(e=>{const s="string"==typeof e?e:e?.id,o="string"==typeof e?e:e?.text||s,i=a===s,c=E&&s===n,l=E&&i&&s!==n;return r("button",{disabled:E,onClick:()=>{const e={...B,[t]:s};K(e),O(e),S?.(e)},className:["rounded-md border px-3 py-1.5 text-sm transition-colors",c?"border-green-500 bg-green-50 text-green-800 font-semibold":"",l?"border-red-500 bg-red-50 text-red-800":"",i&&!E?"border-blue-500 bg-blue-50 text-blue-800":"",i||E?"":"border-gray-200 hover:border-gray-400"].filter(Boolean).join(" "),children:[o,c&&" ✓",l&&" ✗"]},s)})}),E&&r("p",{className:"text-xs text-gray-500",children:["Đáp án: ",e("strong",{children:i.find(e=>(e?.id??e)===n)?.text??n})]})]},t)})})})();case"FILL_IN_BLANK":return V();case"TRUE_FALSE":return(()=>{const t=R.answer,{correctAnswer:n}=t;return r("div",{className:"space-y-3",children:[[{value:!0,label:"Đúng"},{value:!1,label:"Sai"}].map(s=>{const t=T===s.value;return e("div",{className:`flex cursor-pointer items-center rounded-lg border p-3 transition-colors ${t?"border-blue-500 bg-blue-50":"border-gray-200 hover:border-gray-300"} ${E&&s.value===n?"border-green-500 bg-green-50":E&&t&&s.value!==n?"border-red-500 bg-red-50":""}`,onClick:()=>!E&&O(s.value),children:r("div",{className:"flex w-full items-center",children:[e("div",{className:`mr-3 h-4 w-4 rounded-full border-2 ${t?"border-blue-500 bg-blue-500":"border-gray-300"} ${E&&s.value===n?"border-green-500 bg-green-500":""}`,children:t&&e("div",{className:"m-auto h-2 w-2 rounded-full bg-white"})}),e("span",{className:"flex-1",children:s.label}),E&&s.value===n&&e(c,{className:"ml-2 h-4 w-4 text-green-600"}),E&&t&&s.value!==n&&e(d,{className:"ml-2 h-4 w-4 text-red-600"})]})},s.value.toString())}),!E&&e(s,{onClick:()=>{S&&S(T)},disabled:null===T,children:"Nộp đáp án"})]})})();case"ESSAY":return(()=>{const t=R.answer,{minWords:n,maxWords:o}=t,a=T?T.trim().split(/\s+/).length:0;return r("div",{className:"space-y-4",children:[r("div",{className:"text-sm text-gray-600",children:[n&&o?`Số từ: ${n} - ${o} từ`:n?`Tối thiểu: ${n} từ`:o?`Tối đa: ${o} từ`:"",T&&r("span",{className:"ml-2 "+(a>=(n||0)&&a<=(o||1/0)?"text-green-600":"text-red-600"),children:["(",a," từ)"]})]}),e("textarea",{value:T||"",onChange:e=>O(e.target.value),placeholder:"Viết câu trả lời của bạn ở đây...",className:"h-32 w-full resize-none rounded-lg border border-gray-300 p-3 focus:border-blue-500 focus:ring-1 focus:ring-blue-500",disabled:E}),!E&&e(s,{onClick:()=>{S&&S(T)},disabled:!T||T.trim().length<(n||0),children:"Nộp đáp án"})]})})();case"LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE":return(()=>{const t=R.answer,{audioUrl:n,blanks:o}=t;return r("div",{className:"space-y-4",children:[r("div",{className:"flex items-center gap-4 rounded-lg bg-blue-50 p-4",children:[r(s,{onClick:Y,variant:"outline",className:"gap-2",children:[e(l,{className:"h-5 w-5"}),"Phát âm thanh (",I,"/",t.maxPlayCount||3,")"]}),e("audio",{ref:k,src:n})]}),e("div",{className:"space-y-3",children:o.map((s,t)=>r("div",{className:"flex items-center gap-3",children:[r("span",{className:"w-20 font-medium",children:["Blank ",t+1,":"]}),e(i,{value:U[t],onChange:e=>{const r=[...U];r[t]=e.target.value,Q(r),O(r)},placeholder:"Nhập câu trả lời...",disabled:E,className:E?U[t]?.toLowerCase()===o[t]?.toLowerCase()?"border-green-500 bg-green-50":"border-red-500 bg-red-50":""}),E&&r("span",{className:"text-sm text-gray-600",children:["Đáp án: ",e("strong",{children:o[t]})]})]},t))})]})})();case"TICK_TRUE_OR_FALSE":case"TICK_YES_OR_NO":return(()=>{const s=R.answer,{statements:t}=s;return e("div",{className:"space-y-3",children:t.map(s=>e("div",{className:`rounded-lg border-2 p-4 ${E&&q[s.id]===s.isCorrect?"border-green-500 bg-green-50":""} ${E&&q[s.id]!==s.isCorrect?"border-red-500 bg-red-50":"border-gray-200"} `,children:r("div",{className:"flex items-start gap-4",children:[r("div",{className:"mt-1 flex gap-2",children:[e("button",{onClick:()=>{const e={...q,[s.id]:!0};D(e),O(e)},disabled:E,className:`flex h-8 w-8 items-center justify-center rounded border-2 ${!0===q[s.id]?"border-green-500 bg-green-500 text-white":"border-gray-300"} `,children:e(c,{className:"h-5 w-5"})}),e("button",{onClick:()=>{const e={...q,[s.id]:!1};D(e),O(e)},disabled:E,className:`flex h-8 w-8 items-center justify-center rounded border-2 ${!1===q[s.id]?"border-red-500 bg-red-500 text-white":"border-gray-300"} `,children:e(d,{className:"h-5 w-5"})})]}),e("p",{className:"flex-1",children:s.text}),E&&e("span",{className:"text-sm font-medium",children:s.isCorrect?"✓ Đúng":"✗ Sai"})]})},s.id))})})();case"ARRANGE_LETTERS_INTO_WORDS":return(()=>{const r=R.answer,s=R.correctAnswer||R.correct_answer,t=(r?.subQuestions||[]).map(e=>{const r=s?.answers?.[e.id]||e.correctWord||"";return{...e,correctWord:r}});return e(h,{questionData:{subQuestions:t},onSubmit:e=>{O(e),S?.(e)},isReviewMode:E,userAnswer:L})})();case"READ_PASSAGE_AND_COMPLETE_STORY":return(()=>{const s=R.answer,{passage:t,blanks:n}=s,o=t.split(/\{(\d+)\}/);return e("div",{className:"space-y-4",children:e("div",{className:"prose max-w-none",children:e("div",{className:"text-lg leading-relaxed",children:o.map((s,t)=>{const o=parseInt(s);if(!isNaN(o)){const s=n.find(e=>e.index===o);return r("span",{className:"mx-1 inline-flex items-center",children:[e(i,{value:H[o]||"",onChange:e=>{const r={...H,[o]:e.target.value};$(r),O(r)},className:`inline-block h-8 w-32 text-center ${E&&H[o]===s?.correctAnswer?"border-green-500 bg-green-50":""} ${E&&H[o]!==s?.correctAnswer?"border-red-500 bg-red-50":""} `,disabled:E}),E&&r("span",{className:"ml-2 text-sm text-green-600",children:["(",s?.correctAnswer,")"]})]},t)}return e("span",{children:s},t)})})})})})();case"WRITE_SHORT_PARAGRAPH":return(()=>{const r=R.answer;return e(w,{questionData:{contexts:r?.contexts||[],minWords:r?.minWords||20,maxWords:r?.maxWords,instruction:r?.instruction||""},onSubmit:e=>{O(e),S?.(e)},isReviewMode:E,userAnswer:L})})();case"WRITE_A_SHORT_LETTER":return(()=>{const r=R.answer;return e(A,{questionData:{contexts:r?.contexts||[],informations:r?.informations||[],minWords:r?.minWords||20,maxWords:r?.maxWords,instruction:r?.instruction||""},onSubmit:e=>{O(e),S?.(e)},isReviewMode:E,userAnswer:L})})();case"LOOK_PICTURE_FILL_WORD_HINT":return(()=>{const r=R.answer,s=R.content,t=R.questionGroup;let n=[];r?.subQuestions&&r.subQuestions.length>0?n=r.subQuestions:s?.imageUrl&&s?.word&&(n=[{id:R.id,imageUrl:s.imageUrl,word:s.word,correctAnswer:r?.correctAnswer||"",groupNumber:t?.groupNumber||1}]);const o=t?.payload?.hintLetters||r?.hintLetters||s?.hintLetters||[],a=t?.groupNumber||1,i={};o.length>0&&(i[a]=o);const c={subQuestions:n,hintLetters:o,hintLettersByGroup:i,groups:[{number:a,questionCount:n.length}]};return e(x,{questionData:c,userAnswer:L,isReviewMode:E,explanation:R.explanation,onSubmit:e=>{O(e),S?.(e)}})})();case"LABEL_THE_PICTURE":return(()=>{const r=R.answer;return e(N,{questionData:r,userAnswer:L,isReviewMode:E,onSubmit:e=>{O(e),S?.(e)}})})();case"READ_AND_COLOR_OBJECTS":return(()=>{const r=R.answer;return e(b,{questionData:{backgroundImageUrl:r?.backgroundImageUrl||"",colorNodes:r?.colorNodes||[],regionNodes:r?.regionNodes||[],instructions:r?.instructions||[]},onSubmit:e=>{O(e),S?.(e)}})})();case"READ_PASSAGE_AND_ANSWER_QUESTIONS":return(()=>{const r=R.answer;return e(f,{questionData:{passage:r?.passage||"",passageTitle:r?.passageTitle||"",instructions:r?.instructions||"",subQuestions:r?.subQuestions||[]},userAnswer:L,isReviewMode:E,onSubmit:e=>{O(e),S?.(e)}})})();case"LOOK_PICTURE_CHOOSE_CORRECT_ANSWER":return(()=>{const r=R.content,s=R.answer,t=(r?.subQuestions||s?.subQuestions||[]).map(e=>{const r=s?.answers?.[e.id]||e.correctAnswer;return{...e,options:(e.options||[]).map(e=>({...e,isCorrect:e.id===r}))}});return e(_,{questionData:{subQuestions:t},userAnswer:L,isReviewMode:E,onSubmit:e=>{O(e),S?.(e)}})})();case"LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER":return(()=>{const r=R.content,s=R.answer,t=(r?.subQuestions||s?.subQuestions||[]).map(e=>{const r=s?.answers?.[e.id]||e.correctAnswer;return{...e,options:(e.options||[]).map(e=>({...e,isCorrect:e.id===r}))}});return e(y,{questionData:{subQuestions:t},userAnswer:L,isReviewMode:E,onSubmit:e=>{O(e),S?.(e)}})})();case"FILL_MISSING_WORDS_IN_GRID":return(()=>{const r=R.content,s=R.answer;return e(v,{questionData:{content:{grid:r?.grid||[],rows:r?.rows||3,columns:r?.columns||3,disabledCells:r?.disabledCells||[]},answer:{answers:s?.answers||{},missingLetters:s?.missingLetters||[],caseSensitive:s?.caseSensitive||!1}},userAnswer:L,isReviewMode:E,onSubmit:e=>{O(e),S?.(e)}})})();default:return r("div",{children:["Loại câu hỏi không được hỗ trợ: ",R.type]})}})(),!E&&e("div",{className:"flex justify-end border-t pt-4",children:e(s,{onClick:()=>{S?.(T)},className:"bg-blue-500 hover:bg-blue-600",children:"Xác nhận đáp án"})})]})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e}from"react/jsx-runtime";import{transformChooseCorrectAdjective as r,transformChooseCorrectAnswer as t,transformColorObjects as s,transformFillInBlank as
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import{transformChooseCorrectAdjective as r,transformChooseCorrectAnswer as t,transformChooseTheCorrectAnswerGroup as n,transformColorObjects as s,transformFillInBlank as i,transformWriteCorrectVerbForm as o}from"../../../components/exams/take/utils/question-transformers";import{normalizeColoringAssignments as a}from"../../../components/exams/take/utils/coloring-assignments";import{ReviewChooseAdjectiveRenderer as u}from"./ReviewChooseAdjectiveRenderer";import{ReviewChooseBestAnswerRenderer as c}from"./ReviewChooseBestAnswerRenderer";import{ReviewColoringRenderer as m}from"./ReviewColoringRenderer";import{ReviewListenAndWriteRenderer as p}from"./ReviewListenAndWriteRenderer";import{ReviewListenChooseAnswerGroupRenderer as _}from"./ReviewListenChooseAnswerGroupRenderer";import{ReviewListenChooseObjectsRenderer as N}from"./ReviewListenChooseObjectsRenderer";import{ReviewListenDragObjectsRenderer as E}from"./ReviewListenDragObjectsRenderer";import{ReviewSpeakingRenderer as A}from"./ReviewSpeakingRenderer";import{mapSpeakingReviewItems as C}from"./review-speaking-map";export function renderDedicatedReviewBody(R){const{part:l,answers:O,isCorrectMap:I,correctAnswerTextMap:d,correctOptionIdMap:T,rawCorrectAnswerMap:w,questionScoreMap:M,hidePerQuestionGrading:q}=R,{partNo:g,questionType:U,questions:D}=l,L=D.length,x=D;switch(U){case"FILL_IN_BLANK":{const r=i(x);return e(p,{partNumber:g,questionCount:L,partName:l.name,instruction:l.instructions||r.instruction,title:r.title,imageUrl:r.imageUrl,audioUrl:r.audioUrl,exampleText:r.exampleText,exampleHighlight:r.exampleHighlight,questions:r.questions,answers:O,isCorrectMap:I,correctAnswerTextMap:d})}case"WRITE_CORRECT_VERB_FORM":{const r=o(x);return e(p,{partNumber:g,questionCount:L,partName:l.name,instruction:l.instructions||r.instruction,title:r.title,questions:r.questions,answers:O,isCorrectMap:I,correctAnswerTextMap:d})}case"CHOOSE_THE_CORRECT_ANSWER":{const r=t(x);return e(c,{partNumber:g,questionCount:L,partName:l.name,instruction:l.instructions||r.instruction,imageUrl:r.groupImageUrl,audioUrl:r.audioUrl||l.audioUrl,groupContent:r.groupContent,articles:r.articles,questions:r.questions,answers:O,isCorrectMap:I,correctOptionIdMap:T,example:r.example})}case"CHOOSE_THE_CORRECT_ANSWER_GROUP":{const r=n(x);return e(c,{partNumber:g,questionCount:L,partName:l.name,instruction:l.instructions||r.instruction,questions:r.questions,answers:O,isCorrectMap:I,correctOptionIdMap:T,example:r.example})}case"CHOOSE_CORRECT_ADJECTIVE":{const t=r(x);return e(u,{partNumber:g,questionCount:L,partName:l.name,instruction:l.instructions||t.instruction,questions:t.questions,answers:O,isCorrectMap:I,correctOptionIdMap:T})}case"READ_AND_COLOR_OBJECTS":{const r=s(x),t=O,n=D[0],i=n?S(w[n.id]).answers:{};return e(m,{partNumber:g,questionCount:L,instructions:r.instructions,instruction:l.instructions||r.instruction,partName:l.name,imageUrl:r.imageUrl,audioUrl:r.audioUrl,hintItems:r.hintItems,regions:r.regions,assignments:t,correctAnswers:i||{}})}case"IMAGE_OBJECT_MATCHING":{const r=s(x),t=a(O,r.hintItems),n=D[0],i=n?S(w[n.id]).answers:{};return e(m,{partNumber:g,questionCount:L,instructions:r.instructions,instruction:l.instructions||r.instruction,partName:l.name,imageUrl:r.imageUrl,audioUrl:r.audioUrl||l.audioUrl,hintItems:r.hintItems,regions:r.regions,assignments:t,correctAnswers:i||{}})}case"LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE":return e(N,{partNumber:g,questionCount:L,partName:l.name,questions:D,studentAnswers:O,rawCorrectAnswerMap:w,isCorrectMap:I,questionScoreMap:M});case"LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP":return e(_,{partNumber:g,questionCount:L,partName:l.name,questions:D,studentAnswers:O,rawCorrectAnswerMap:w,isCorrectMap:I,questionScoreMap:M});case"LISTEN_AND_DRAG_OBJECTS_INTO_SCENE":return e(E,{partNumber:g,questionCount:L,partName:l.name,questions:D,studentAnswers:O,rawCorrectAnswerMap:w,isCorrectMap:I,questionScoreMap:M});case"READ_DISPLAYED_CONTENT":case"SPEAKING_DESCRIBE_IMAGE":case"SPEAKING_CUE_CARD":case"SPONTANEOUS_QA":case"LISTEN_AND_SPEAK_ANSWER":case"LISTEN_AND_SPEAK_IMAGE_GROUP":case"LISTEN_AND_SPEAK_QUESTION_LIST":case"LISTEN_AND_SPEAK_COMPARE_IMAGES":case"LISTEN_AND_SPEAK_WITH_STORY_IMAGES":case"LISTEN_AND_SPEAK_INFO_EXCHANGE":case"LISTEN_AND_SPEAK_ODD_ONE_OUT":{const r=C(D,U,O,I);return e(A,{partNumber:g,partName:l.name,questions:r,hidePerQuestionGrading:q})}default:return null}}function S(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=new Set(["READ_PASSAGE_AND_ANSWER_QUESTIONS","LOOK_PICTURE_FILL_WORD_HINT","LABEL_THE_PICTURE","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING"]);export function transformResultAnswersForReview(e,s=[]){const o=function(e){const r=new Map;return e.forEach(e=>{const t=[e.partId??"unknown",e.questionGroup?.id??"none",e.questionType].join(":");r.set(t,[...r.get(t)??[],e])}),r}(e),i={parts:[],studentAnswers:{},correctAnswersMap:new Map,isCorrectMap:{},correctAnswerTextMap:{},correctOptionIdMap:{},cellAnswersMap:{},essayGradingMap:{},partScoresMap:{},rawCorrectAnswerMap:{},rawStudentAnswerMap:{},questionScoreMap:{}},
|
|
1
|
+
const e=new Set(["READ_PASSAGE_AND_ANSWER_QUESTIONS","LOOK_PICTURE_FILL_WORD_HINT","LABEL_THE_PICTURE","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING","CHOOSE_THE_CORRECT_ANSWER_GROUP"]);export function transformResultAnswersForReview(e,s=[]){const o=function(e){const r=new Map;return e.forEach(e=>{const t=[e.partId??"unknown",e.questionGroup?.id??"none",e.questionType].join(":");r.set(t,[...r.get(t)??[],e])}),r}(e),i={parts:[],studentAnswers:{},correctAnswersMap:new Map,isCorrectMap:{},correctAnswerTextMap:{},correctOptionIdMap:{},cellAnswersMap:{},essayGradingMap:{},partScoresMap:{},rawCorrectAnswerMap:{},rawStudentAnswerMap:{},questionScoreMap:{}},c=[];for(const e of o.values()){e.sort((e,r)=>e.questionNumber-r.questionNumber);const o=e[0];if(!o)continue;const u=s.find(e=>String(e.id)===String(o.partId)),p=r(u,o.questionNumber),A=a(u?.name)??o.partNo??0;i.parts.push({partId:o.partId,partNo:A,questionType:o.questionType,name:u?.name,instructions:p?.name||p?.instructions||u?.instructions,audioUrl:u?.audioUrl,questions:e.map(t)});const _=e.filter(e=>!e.isExample);c.push({score:_.reduce((e,r)=>e+(r.score??0),0),maxScore:_.reduce((e,r)=>e+r.maxScore,0),correctCount:_.filter(e=>!0===e.isCorrect).length,totalCount:_.length}),e.forEach(e=>n(i,e))}const u=i.parts.map((e,r)=>r).sort((e,r)=>{const t=i.parts[e],n=i.parts[r];return t.partNo-n.partNo||(t.questions[0]?.question_number??0)-(n.questions[0]?.question_number??0)});return i.parts=u.map(e=>i.parts[e]),u.forEach((e,r)=>{i.partScoresMap[r]=c[e]}),i}export const transformDetailedResultForReview=transformResultAnswersForReview;function r(e,r){const t=r-1;return e?.sections?.find(e=>null!=e.startIndex&&null!=e.endIndex&&t>=e.startIndex&&t<=e.endIndex)}function t(e){const r=o(e.questionContent);return{id:e.questionId,content:{...r,_correctAnswer:e.correctAnswer},correct_answer:e.correctAnswer,total_points:String(e.maxScore),question_type:e.questionType,is_example:e.isExample??!1,explanation:e.explanation??"",difficult_level:"MEDIUM",question_skill_type:"",exam_id:"",part_id:e.partId??"",part_no:e.partNo??0,question_number:e.questionNumber,questionGroup:e.questionGroup??null,score:e.score}}function n(r,t){const n=function(e,r,t){if(null==t)return;const n=o(t);if("CHOOSE_THE_CORRECT_ANSWER_GROUP"===r){const r=n.answer;if(!Array.isArray(r))return;return Object.fromEntries(r.map((r,t)=>[`${e}-item-${t}`,"string"==typeof r?r:""]))}if("CHOOSE_THE_CORRECT_ANSWER"===r||"CHOOSE_CORRECT_ADJECTIVE"===r){const r=n.answer??n.optionId??n.optionIds,t=s(e,r);return t.length>1?t:t[0]}if("READ_PASSAGE_AND_ANSWER_QUESTIONS"===r&&i(n.subAnswers))return Object.fromEntries(Object.entries(n.subAnswers).map(([e,r])=>[e,"number"==typeof r?`${e}-opt-${r}`:r]));if("LABEL_THE_PICTURE"===r)return n.answers??t;if("LOOK_PICTURE_FILL_WORD_HINT"===r&&"string"==typeof n.answer&&n.answer.includes(","))return Object.fromEntries(n.answer.split(",").map((r,t)=>[`${e}-blank-${t}`,r.trim()]));if("WORD_FILL_PARAGRAPH"===r){if(Array.isArray(n.answers))return n.answers;if(Array.isArray(n.answer))return n.answer;if(Array.isArray(t))return t;if("string"==typeof t)return[t];return Object.keys(n).filter(e=>/^\d+$/.test(e)).sort((e,r)=>Number(e)-Number(r)).map(e=>n[e])}return"READ_AND_COLOR_OBJECTS"===r||"IMAGE_OBJECT_MATCHING"===r?n.answers??t:"WRITE_A_SHORT_LETTER"===r?"string"==typeof t?t:n.answer??"":n.answer??t}(t.questionId,t.questionType,t.studentAnswer);void 0!==n&&(e.has(t.questionType)&&i(n)?Object.assign(r.studentAnswers,n):r.studentAnswers[t.questionId]=n),r.correctAnswersMap.set(t.questionId,t.correctAnswer),r.isCorrectMap[t.questionId]=t.isCorrect,r.rawCorrectAnswerMap[t.questionId]=t.correctAnswer,r.rawStudentAnswerMap[t.questionId]=t.studentAnswer,r.questionScoreMap[t.questionId]={score:t.score,maxScore:t.maxScore},function(e,r){const t=o(r.correctAnswer),n=s(r.questionId,t.answer);n.length&&(e.correctOptionIdMap[r.questionId]=n.join(","));if("CHOOSE_THE_CORRECT_ANSWER_GROUP"===r.questionType){const n=Array.isArray(o(r.questionContent).items)?o(r.questionContent).items:[],s=Array.isArray(t.answer)?t.answer:[];n.forEach((t,n)=>{const o=`${r.questionId}-item-${n}`,i=t?.correctAnswer?.answer||s[n];"string"==typeof i&&i&&(e.correctOptionIdMap[o]=i)})}"READ_PASSAGE_AND_ANSWER_QUESTIONS"===r.questionType&&i(t.answers)&&Object.entries(t.answers).forEach(([r,t])=>{"number"==typeof t&&(e.correctOptionIdMap[r]=`${r}-opt-${t}`)});const a=function(e){if(Array.isArray(e.answers))return e.answers.map(String);if(i(e.answers))return Object.values(e.answers).map(String);const r=e.answer??e.correctAnswer;return null==r?[]:[String(r)]}(t);a[0]&&(e.correctAnswerTextMap[r.questionId]=a[0]);"WORD_FILL_PARAGRAPH"===r.questionType&&a.forEach((t,n)=>{e.correctAnswerTextMap[`${r.questionId}-blank-${n}`]=t});"LABEL_THE_PICTURE"===r.questionType&&i(t.labels)&&Object.entries(t.labels).forEach(([r,t])=>{e.correctAnswerTextMap[r]=String(t)});"FILL_MISSING_WORDS_IN_GRID"===r.questionType&&i(t.cells)&&(e.cellAnswersMap[r.questionId]={cells:t.cells,caseSensitive:!0===t.caseSensitive})}(r,t),"WRITE_A_SHORT_LETTER"!==t.questionType&&"WRITE_SHORT_PARAGRAPH"!==t.questionType||(r.essayGradingMap[t.questionId]={score:t.teacherScore??t.score,maxScore:t.maxScore,teacherFeedback:t.teacherFeedback??null,writingAssessment:t.writingAssessment??null})}function s(e,r){return(Array.isArray(r)?r:[r]).filter(e=>"number"==typeof e||"string"==typeof e).map(r=>"number"==typeof r?`${e}-opt-${r}`:r)}function o(e){return i(e)?e:{}}function i(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function a(e){const r=e?.match(/\d+/);return r?Number(r[0]):void 0}
|