@tinyweb_dev/oe-exam-sdk 0.1.27 → 0.1.28
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 +75 -2
- package/dist/components/questions/_shared/config/question-types.config.js +1 -1
- package/dist/components/questions/_shared/types/word-fill-structured-form.type.d.ts +1 -1
- package/dist/components/questions/types/choose-the-correct-answer-group/index.d.ts +1 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/index.js +1 -1
- package/dist/components/questions/types/choose-the-correct-answer-group/map-choose-the-correct-answer-group-data.d.ts +4 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/map-choose-the-correct-answer-group-data.js +1 -0
- package/dist/components/questions/types/choose-the-correct-answer-group/register.js +1 -1
- package/dist/components/questions/types/cross-out-word-group/index.d.ts +1 -0
- package/dist/components/questions/types/cross-out-word-group/index.js +1 -1
- package/dist/components/questions/types/cross-out-word-group/map-cross-out-word-group-data.d.ts +6 -0
- package/dist/components/questions/types/cross-out-word-group/map-cross-out-word-group-data.js +1 -0
- package/dist/components/questions/types/cross-out-word-group/register.js +1 -1
- package/dist/components/questions/types/true-false-group/index.d.ts +1 -0
- package/dist/components/questions/types/true-false-group/index.js +1 -1
- package/dist/components/questions/types/true-false-group/map-true-false-group-data.d.ts +4 -0
- package/dist/components/questions/types/true-false-group/map-true-false-group-data.js +1 -0
- package/dist/components/questions/types/true-false-group/register.js +1 -1
- package/dist/components/questions/types/word-fill-structured-form/index.d.ts +1 -0
- package/dist/components/questions/types/word-fill-structured-form/index.js +1 -1
- package/dist/components/questions/types/word-fill-structured-form/map-wfsf-question-data.d.ts +7 -0
- package/dist/components/questions/types/word-fill-structured-form/map-wfsf-question-data.js +1 -0
- package/dist/components/questions/types/word-fill-structured-form/register.js +1 -1
- package/dist/components/questions/types/word-fill-structured-form/transform.js +1 -1
- package/dist/components/questions/viewer/ChooseTheCorrectAnswerGroupViewer.d.ts +8 -0
- package/dist/components/questions/viewer/ChooseTheCorrectAnswerGroupViewer.js +1 -0
- package/dist/components/questions/viewer/CrossOutWordGroupViewer.d.ts +7 -0
- package/dist/components/questions/viewer/CrossOutWordGroupViewer.js +1 -0
- package/dist/components/questions/viewer/QuestionViewer.js +1 -1
- package/dist/components/questions/viewer/SpontaneousQaGroupViewer.d.ts +4 -0
- package/dist/components/questions/viewer/SpontaneousQaGroupViewer.js +1 -0
- package/dist/components/questions/viewer/TrueFalseGroupViewer.d.ts +8 -0
- package/dist/components/questions/viewer/TrueFalseGroupViewer.js +1 -0
- package/dist/components/questions/viewer/WordFillStructuredFormViewer.d.ts +9 -0
- package/dist/components/questions/viewer/WordFillStructuredFormViewer.js +1 -0
- package/dist/components/questions/viewer/WordOrderAndMatchGroupViewer.d.ts +4 -0
- package/dist/components/questions/viewer/WordOrderAndMatchGroupViewer.js +1 -0
- package/dist/components/questions/viewer/index.d.ts +6 -0
- package/dist/components/questions/viewer/index.js +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +1 -1
- package/dist/shared/constants/question-skills.js +1 -1
- package/dist/shared/types/common.types.d.ts +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -88,10 +88,10 @@ export function ResultReviewPage({ attemptId, token, router }) {
|
|
|
88
88
|
## Entry points
|
|
89
89
|
|
|
90
90
|
```txt
|
|
91
|
-
@tinyweb_dev/oe-exam-sdk # export tổng hợp
|
|
91
|
+
@tinyweb_dev/oe-exam-sdk # export tổng hợp browser-safe (UI + API)
|
|
92
92
|
@tinyweb_dev/oe-exam-sdk/api # API adapters, constants, types
|
|
93
93
|
@tinyweb_dev/oe-exam-sdk/shared # shared constants/types/helpers
|
|
94
|
-
@tinyweb_dev/oe-exam-sdk/mcp # MCP server
|
|
94
|
+
@tinyweb_dev/oe-exam-sdk/mcp # MCP server ONLY (Node/stdio) — không re-export từ root
|
|
95
95
|
@tinyweb_dev/oe-exam-sdk/components # shared UI components
|
|
96
96
|
@tinyweb_dev/oe-exam-sdk/components/exams # màn tạo đề / câu hỏi / làm bài / vào phòng
|
|
97
97
|
@tinyweb_dev/oe-exam-sdk/components/exams/entry # màn vào phòng (entry) + state machine
|
|
@@ -101,6 +101,8 @@ export function ResultReviewPage({ attemptId, token, router }) {
|
|
|
101
101
|
@tinyweb_dev/oe-exam-sdk/components/results # màn xem chi tiết kết quả
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
+
> **MCP:** import từ subpath `@tinyweb_dev/oe-exam-sdk/mcp` (CLI/bin `oe-exam-mcp`). Root barrel **không** export MCP để tránh kéo `node:fs` vào client Next.js (`UnhandledSchemeError`).
|
|
105
|
+
|
|
104
106
|
## API adapters
|
|
105
107
|
|
|
106
108
|
SDK không fix cứng API client. Host app có thể truyền adapter riêng qua prop `api`, hoặc dùng adapter mặc định:
|
|
@@ -329,12 +331,83 @@ import {
|
|
|
329
331
|
- Các tích hợp host-system nên đi qua props/API adapter.
|
|
330
332
|
- Upload file trong component mặc định dùng `blob:` URL cục bộ; API upload thật nên truyền từ host app khi cần.
|
|
331
333
|
|
|
334
|
+
## Dev local với host Next.js (không build tay mỗi lần sửa)
|
|
335
|
+
|
|
336
|
+
SDK **không** export thẳng `src/` vì source dùng path alias `@/` / `@oe/exam` (được `tsc-alias` rewrite lúc build). Host app luôn resolve `exports` → `dist/`.
|
|
337
|
+
|
|
338
|
+
Để sửa SDK và host nhận ngay:
|
|
339
|
+
|
|
340
|
+
### 1) Link package vào host
|
|
341
|
+
|
|
342
|
+
**Yarn (oe-school/frontend — đã cấu hình):**
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
// frontend/package.json
|
|
346
|
+
"@tinyweb_dev/oe-exam-sdk": "portal:../../oe-exam/sdk"
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
cd oe-school/frontend
|
|
351
|
+
yarn install
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**npm (host khác):**
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
cd oe-exam/sdk && npm link
|
|
358
|
+
cd /path/to/host-nextjs && npm link @tinyweb_dev/oe-exam-sdk
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### 2) Transpile package trong host Next.js
|
|
362
|
+
|
|
363
|
+
```ts
|
|
364
|
+
// next.config.ts
|
|
365
|
+
const nextConfig = {
|
|
366
|
+
transpilePackages: ['@tinyweb_dev/oe-exam-sdk'],
|
|
367
|
+
};
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
(`oe-school/frontend` đã có sẵn trong `transpilePackages`.)
|
|
371
|
+
|
|
372
|
+
### 3) Chạy watch build SDK (bắt buộc — cập nhật `dist/`)
|
|
373
|
+
|
|
374
|
+
Terminal 1 — SDK:
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
cd oe-exam/sdk
|
|
378
|
+
npm run dev
|
|
379
|
+
# initial build:ts (không minify) + tsc --watch
|
|
380
|
+
# → tsc-alias + check-aliases sau mỗi lần emit thành công + copy assets
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Terminal 2 — host:
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
cd oe-school/frontend # hoặc host Next.js khác
|
|
387
|
+
yarn dev # / npm run dev
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Luồng:
|
|
391
|
+
|
|
392
|
+
```txt
|
|
393
|
+
SDK src/** → npm run dev (watch) → dist/**
|
|
394
|
+
↑ portal/npm link symlink
|
|
395
|
+
host node_modules/@tinyweb_dev/oe-exam-sdk
|
|
396
|
+
→ Next transpilePackages + HMR
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Không cần: `npm pack` / publish / reinstall version mới mỗi lần sửa.
|
|
400
|
+
|
|
401
|
+
> Publish production vẫn dùng `npm run build` (có minify). `npm run dev` chỉ cho local.
|
|
402
|
+
|
|
332
403
|
## Kiểm tra local
|
|
333
404
|
|
|
334
405
|
Trong repo này:
|
|
335
406
|
|
|
336
407
|
```bash
|
|
337
408
|
npm --prefix sdk run build
|
|
409
|
+
# hoặc watch khi dev host:
|
|
410
|
+
npm --prefix sdk run dev
|
|
338
411
|
```
|
|
339
412
|
|
|
340
413
|
Nếu chạy app dev:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const QUESTION_TYPE_CONFIG={FILL_IN_BLANK:{label:"Điền vào chỗ trống",requiresContent:!0,hasDedicatedComponent:!0},TRUE_FALSE:{label:"Đúng/Sai",requiresContent:!0,hasDedicatedComponent:!0},MATCHING:{label:"Nối",requiresContent:!0,hasDedicatedComponent:!1},ORDERING:{label:"Sắp xếp",requiresContent:!0,hasDedicatedComponent:!1},LISTENING:{label:"Nghe",requiresContent:!0,hasDedicatedComponent:!1},COLORING:{label:"Tô màu",requiresContent:!0,hasDedicatedComponent:!1},ESSAY:{label:"Viết luận",requiresContent:!0,hasDedicatedComponent:!1},LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:{label:"Nghe - Điền chỗ trống",requiresContent:!0,hasDedicatedComponent:!1},LISTEN_AND_TICK_ANSWER:{label:"Nghe - Tick đáp án",requiresContent:!0,hasDedicatedComponent:!1},LISTEN_AND_FILL_NAME_NUMBER:{label:"Nghe - Điền tên/số",requiresContent:!0,hasDedicatedComponent:!1},TICK_TRUE_OR_FALSE:{label:"Đọc - Tick/Cross",requiresContent:!0,hasDedicatedComponent:!1},TICK_YES_OR_NO:{label:"Đọc - Tick/Cross (Yes/No)",requiresContent:!0,hasDedicatedComponent:!1},READING_TICK_CROSS:{label:"Đọc - Tick/Cross (Reading)",requiresContent:!0,hasDedicatedComponent:!1},ARRANGE_LETTERS_INTO_WORDS:{label:"Đọc - Sắp xếp chữ cái",requiresContent:!0,hasDedicatedComponent:!0},READ_PASSAGE_AND_COMPLETE_STORY:{label:"Đọc - Điền vào đoạn văn",requiresContent:!0,hasDedicatedComponent:!1},READ_PASSAGE_AND_ANSWER_QUESTIONS:{label:"Đọc đoạn văn và trả lời câu hỏi",requiresContent:!0,hasDedicatedComponent:!0},CLOZE_TEST_WITH_TICK_BOX:{label:"Cloze test với tick box",requiresContent:!0,hasDedicatedComponent:!1},READ_AND_CHOOSE_APPROPRIATE_WORD:{label:"Đọc - Chọn từ phù hợp",requiresContent:!0,hasDedicatedComponent:!1},WRITE_SHORT_PARAGRAPH:{label:"Viết - Đoạn văn ngắn",requiresContent:!0,hasDedicatedComponent:!0},FILL_MISSING_WORDS_IN_GRID:{label:"Điền từ còn thiếu vào grid",requiresContent:!0,hasDedicatedComponent:!0},LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:{label:"Nhìn tranh, chọn đáp án đúng",requiresContent:!0,hasDedicatedComponent:!0},LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:{label:"Nhìn tranh, điền chỗ trống, chọn đáp án",requiresContent:!0,hasDedicatedComponent:!0},LOOK_PICTURE_FILL_WORD_HINT:{label:"Nhìn tranh điền từ gợi ý",requiresContent:!0,hasDedicatedComponent:!0},LABEL_THE_PICTURE:{label:"Label the Picture",requiresContent:!0,hasDedicatedComponent:!0},READ_AND_COLOR_OBJECTS:{label:"Read and Color Objects",requiresContent:!0,hasDedicatedComponent:!0},IMAGE_OBJECT_MATCHING:{label:"Image Object Matching",requiresContent:!0,hasDedicatedComponent:!0},LISTENING_FILL_BLANK:{label:"Nghe - Điền vào chỗ trống",requiresContent:!0,hasDedicatedComponent:!1},LISTENING_COLOR:{label:"Nghe - Tô màu",requiresContent:!0,hasDedicatedComponent:!1},READING_LETTER_ARRANGE:{label:"Đọc - Sắp xếp chữ cái",requiresContent:!0,hasDedicatedComponent:!1},READING_PASSAGE_FILL:{label:"Đọc - Điền vào đoạn văn",requiresContent:!0,hasDedicatedComponent:!1},FILL_BLANK:{label:"Điền vào chỗ trống",requiresContent:!0,hasDedicatedComponent:!1},CHOOSE_THE_CORRECT_ANSWER:{label:"Choose the correct answer",requiresContent:!1,hasDedicatedComponent:!0},CHOOSE_THE_CORRECT_ANSWER_GROUP:{label:"Choose the correct answer (group)",requiresContent:!0,hasDedicatedComponent:!0},TRUE_FALSE_GROUP:{label:"Đúng/Sai (nhóm)",requiresContent:!0,hasDedicatedComponent:!0},CROSS_OUT_WORD_GROUP:{label:"Cross out word (group)",requiresContent:!0,hasDedicatedComponent:!0},WRITE_A_SHORT_LETTER:{label:"Write a Short Letter",requiresContent:!0,hasDedicatedComponent:!0},WRITE_CORRECT_VERB_FORM:{label:"Viết dạng đúng của động từ",requiresContent:!0,hasDedicatedComponent:!0},CHOOSE_CORRECT_ADJECTIVE:{label:"Chọn dạng đúng của tính từ",requiresContent:!0,hasDedicatedComponent:!0},ANSWER_THE_QUESTION:{label:"Nghe - Đọc câu hỏi và viết đáp án",requiresContent:!0,hasDedicatedComponent:!0},WORD_ORDERING:{label:"Sắp xếp từ",requiresContent:!0,hasDedicatedComponent:!0},WORD_FILL_PARAGRAPH:{label:"Điền từ vào đoạn văn",requiresContent:!0,hasDedicatedComponent:!0},MATCH_BY_WRITING_ANSWER:{label:"Ghép đáp án bằng cách viết",requiresContent:!0,hasDedicatedComponent:!0},WRITE_SENTENCES:{label:"Viết câu",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:{label:"Nghe và chọn trong nhóm đáp án",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:{label:"Nghe và chọn đối tượng trong cảnh",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:{label:"Nghe và kéo thả đối tượng vào cảnh",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_ANSWER:{label:"Nghe và trả lời (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_IMAGE_GROUP:{label:"Nghe, nhìn nhóm ảnh và trả lời (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_QUESTION_LIST:{label:"Nghe, chọn câu hỏi và trả lời (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_COMPARE_IMAGES:{label:"Nghe và So sánh điểm khác biệt (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_WITH_STORY_IMAGES:{label:"Nghe, nhìn ảnh truyện và kể lại (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_ODD_ONE_OUT:{label:"Nghe, chọn hình khác loại và giải thích (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_INFO_EXCHANGE:{label:"Trao đổi thông tin (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},READ_DISPLAYED_CONTENT:{label:"Đọc nội dung hiển thị (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},SPEAKING_DESCRIBE_IMAGE:{label:"Nhìn tranh mô tả (Speaking Part 2)",requiresContent:!0,hasDedicatedComponent:!0},SPONTANEOUS_QA:{label:"Hỏi đáp tự phát (Speaking Part 3)",requiresContent:!0,hasDedicatedComponent:!0},SPEAKING_CONVERSATION:{label:"Hội thoại Speaking (KFS Speaking)",requiresContent:!0,hasDedicatedComponent:!0},GN_SPEAKING_INTERVIEW:{label:"GN Speaking - Hỏi đáp (Virtual + Real)",requiresContent:!0,hasDedicatedComponent:!0},SPEAKING_CUE_CARD:{label:"IELTS Cue Card (Speaking Part 2)",requiresContent:!0,hasDedicatedComponent:!0},WORD_FILL_STRUCTURED_FORM:{label:"Điền từ vào biểu mẫu có cấu trúc",requiresContent:!0,hasDedicatedComponent:!0}};export const QUESTION_TYPES_WITH_DEDICATED_COMPONENTS=["FILL_IN_BLANK","ARRANGE_LETTERS_INTO_WORDS","WRITE_SHORT_PARAGRAPH","FILL_MISSING_WORDS_IN_GRID","LOOK_PICTURE_CHOOSE_CORRECT_ANSWER","LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER","LOOK_PICTURE_FILL_WORD_HINT","LABEL_THE_PICTURE","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING","READ_PASSAGE_AND_ANSWER_QUESTIONS","CHOOSE_THE_CORRECT_ANSWER","CHOOSE_THE_CORRECT_ANSWER_GROUP","TRUE_FALSE_GROUP","CROSS_OUT_WORD_GROUP","WRITE_A_SHORT_LETTER","WRITE_CORRECT_VERB_FORM","CHOOSE_CORRECT_ADJECTIVE","ANSWER_THE_QUESTION","TRUE_FALSE","WORD_ORDERING","WORD_FILL_PARAGRAPH","MATCH_BY_WRITING_ANSWER","WRITE_SENTENCES","LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP","LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE","LISTEN_AND_DRAG_OBJECTS_INTO_SCENE","LISTEN_AND_SPEAK_ANSWER","LISTEN_AND_SPEAK_IMAGE_GROUP","LISTEN_AND_SPEAK_QUESTION_LIST","LISTEN_AND_SPEAK_COMPARE_IMAGES","LISTEN_AND_SPEAK_WITH_STORY_IMAGES","LISTEN_AND_SPEAK_ODD_ONE_OUT","LISTEN_AND_SPEAK_INFO_EXCHANGE","READ_DISPLAYED_CONTENT","SPEAKING_DESCRIBE_IMAGE","SPONTANEOUS_QA","SPEAKING_CONVERSATION","GN_SPEAKING_INTERVIEW","SPEAKING_CUE_CARD","WORD_FILL_STRUCTURED_FORM"];export function getQuestionTypeLabel(e){return QUESTION_TYPE_CONFIG[e]?.label||e}
|
|
1
|
+
export const QUESTION_TYPE_CONFIG={FILL_IN_BLANK:{label:"Điền vào chỗ trống",requiresContent:!0,hasDedicatedComponent:!0},TRUE_FALSE:{label:"Đúng/Sai",requiresContent:!0,hasDedicatedComponent:!0},MATCHING:{label:"Nối",requiresContent:!0,hasDedicatedComponent:!1},ORDERING:{label:"Sắp xếp",requiresContent:!0,hasDedicatedComponent:!1},LISTENING:{label:"Nghe",requiresContent:!0,hasDedicatedComponent:!1},COLORING:{label:"Tô màu",requiresContent:!0,hasDedicatedComponent:!1},ESSAY:{label:"Viết luận",requiresContent:!0,hasDedicatedComponent:!1},LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:{label:"Nghe - Điền chỗ trống",requiresContent:!0,hasDedicatedComponent:!1},LISTEN_AND_TICK_ANSWER:{label:"Nghe - Tick đáp án",requiresContent:!0,hasDedicatedComponent:!1},LISTEN_AND_FILL_NAME_NUMBER:{label:"Nghe - Điền tên/số",requiresContent:!0,hasDedicatedComponent:!1},TICK_TRUE_OR_FALSE:{label:"Đọc - Tick/Cross",requiresContent:!0,hasDedicatedComponent:!1},TICK_YES_OR_NO:{label:"Đọc - Tick/Cross (Yes/No)",requiresContent:!0,hasDedicatedComponent:!1},READING_TICK_CROSS:{label:"Đọc - Tick/Cross (Reading)",requiresContent:!0,hasDedicatedComponent:!1},ARRANGE_LETTERS_INTO_WORDS:{label:"Đọc - Sắp xếp chữ cái",requiresContent:!0,hasDedicatedComponent:!0},READ_PASSAGE_AND_COMPLETE_STORY:{label:"Đọc - Điền vào đoạn văn",requiresContent:!0,hasDedicatedComponent:!1},READ_PASSAGE_AND_ANSWER_QUESTIONS:{label:"Đọc đoạn văn và trả lời câu hỏi",requiresContent:!0,hasDedicatedComponent:!0},CLOZE_TEST_WITH_TICK_BOX:{label:"Cloze test với tick box",requiresContent:!0,hasDedicatedComponent:!1},READ_AND_CHOOSE_APPROPRIATE_WORD:{label:"Đọc - Chọn từ phù hợp",requiresContent:!0,hasDedicatedComponent:!1},WRITE_SHORT_PARAGRAPH:{label:"Viết - Đoạn văn ngắn",requiresContent:!0,hasDedicatedComponent:!0},FILL_MISSING_WORDS_IN_GRID:{label:"Điền từ còn thiếu vào grid",requiresContent:!0,hasDedicatedComponent:!0},LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:{label:"Nhìn tranh, chọn đáp án đúng",requiresContent:!0,hasDedicatedComponent:!0},LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:{label:"Nhìn tranh, điền chỗ trống, chọn đáp án",requiresContent:!0,hasDedicatedComponent:!0},LOOK_PICTURE_FILL_WORD_HINT:{label:"Nhìn tranh điền từ gợi ý",requiresContent:!0,hasDedicatedComponent:!0},LABEL_THE_PICTURE:{label:"Label the Picture",requiresContent:!0,hasDedicatedComponent:!0},READ_AND_COLOR_OBJECTS:{label:"Read and Color Objects",requiresContent:!0,hasDedicatedComponent:!0},IMAGE_OBJECT_MATCHING:{label:"Image Object Matching",requiresContent:!0,hasDedicatedComponent:!0},LISTENING_FILL_BLANK:{label:"Nghe - Điền vào chỗ trống",requiresContent:!0,hasDedicatedComponent:!1},LISTENING_COLOR:{label:"Nghe - Tô màu",requiresContent:!0,hasDedicatedComponent:!1},READING_LETTER_ARRANGE:{label:"Đọc - Sắp xếp chữ cái",requiresContent:!0,hasDedicatedComponent:!1},READING_PASSAGE_FILL:{label:"Đọc - Điền vào đoạn văn",requiresContent:!0,hasDedicatedComponent:!1},FILL_BLANK:{label:"Điền vào chỗ trống",requiresContent:!0,hasDedicatedComponent:!1},CHOOSE_THE_CORRECT_ANSWER:{label:"Choose the correct answer",requiresContent:!1,hasDedicatedComponent:!0},CHOOSE_THE_CORRECT_ANSWER_GROUP:{label:"Choose the correct answer (group)",requiresContent:!0,hasDedicatedComponent:!0},TRUE_FALSE_GROUP:{label:"Đúng/Sai (nhóm)",requiresContent:!0,hasDedicatedComponent:!0},CROSS_OUT_WORD_GROUP:{label:"Cross out word (group)",requiresContent:!0,hasDedicatedComponent:!0},SPONTANEOUS_QA_GROUP:{label:"Hỏi đáp tự phát (nhóm)",requiresContent:!0,hasDedicatedComponent:!1},WORD_ORDER_AND_MATCH_GROUP:{label:"Sắp xếp từ và nối nhãn (nhóm)",requiresContent:!0,hasDedicatedComponent:!1},WRITE_A_SHORT_LETTER:{label:"Write a Short Letter",requiresContent:!0,hasDedicatedComponent:!0},WRITE_CORRECT_VERB_FORM:{label:"Viết dạng đúng của động từ",requiresContent:!0,hasDedicatedComponent:!0},CHOOSE_CORRECT_ADJECTIVE:{label:"Chọn dạng đúng của tính từ",requiresContent:!0,hasDedicatedComponent:!0},ANSWER_THE_QUESTION:{label:"Nghe - Đọc câu hỏi và viết đáp án",requiresContent:!0,hasDedicatedComponent:!0},WORD_ORDERING:{label:"Sắp xếp từ",requiresContent:!0,hasDedicatedComponent:!0},WORD_FILL_PARAGRAPH:{label:"Điền từ vào đoạn văn",requiresContent:!0,hasDedicatedComponent:!0},MATCH_BY_WRITING_ANSWER:{label:"Ghép đáp án bằng cách viết",requiresContent:!0,hasDedicatedComponent:!0},WRITE_SENTENCES:{label:"Viết câu",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:{label:"Nghe và chọn trong nhóm đáp án",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:{label:"Nghe và chọn đối tượng trong cảnh",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:{label:"Nghe và kéo thả đối tượng vào cảnh",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_ANSWER:{label:"Nghe và trả lời (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_IMAGE_GROUP:{label:"Nghe, nhìn nhóm ảnh và trả lời (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_QUESTION_LIST:{label:"Nghe, chọn câu hỏi và trả lời (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_COMPARE_IMAGES:{label:"Nghe và So sánh điểm khác biệt (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_WITH_STORY_IMAGES:{label:"Nghe, nhìn ảnh truyện và kể lại (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_ODD_ONE_OUT:{label:"Nghe, chọn hình khác loại và giải thích (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},LISTEN_AND_SPEAK_INFO_EXCHANGE:{label:"Trao đổi thông tin (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},READ_DISPLAYED_CONTENT:{label:"Đọc nội dung hiển thị (Speaking)",requiresContent:!0,hasDedicatedComponent:!0},SPEAKING_DESCRIBE_IMAGE:{label:"Nhìn tranh mô tả (Speaking Part 2)",requiresContent:!0,hasDedicatedComponent:!0},SPONTANEOUS_QA:{label:"Hỏi đáp tự phát (Speaking Part 3)",requiresContent:!0,hasDedicatedComponent:!0},SPEAKING_CONVERSATION:{label:"Hội thoại Speaking (KFS Speaking)",requiresContent:!0,hasDedicatedComponent:!0},GN_SPEAKING_INTERVIEW:{label:"GN Speaking - Hỏi đáp (Virtual + Real)",requiresContent:!0,hasDedicatedComponent:!0},SPEAKING_CUE_CARD:{label:"IELTS Cue Card (Speaking Part 2)",requiresContent:!0,hasDedicatedComponent:!0},WORD_FILL_STRUCTURED_FORM:{label:"Điền từ vào biểu mẫu có cấu trúc",requiresContent:!0,hasDedicatedComponent:!0}};export const QUESTION_TYPES_WITH_DEDICATED_COMPONENTS=["FILL_IN_BLANK","ARRANGE_LETTERS_INTO_WORDS","WRITE_SHORT_PARAGRAPH","FILL_MISSING_WORDS_IN_GRID","LOOK_PICTURE_CHOOSE_CORRECT_ANSWER","LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER","LOOK_PICTURE_FILL_WORD_HINT","LABEL_THE_PICTURE","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING","READ_PASSAGE_AND_ANSWER_QUESTIONS","CHOOSE_THE_CORRECT_ANSWER","CHOOSE_THE_CORRECT_ANSWER_GROUP","TRUE_FALSE_GROUP","CROSS_OUT_WORD_GROUP","WRITE_A_SHORT_LETTER","WRITE_CORRECT_VERB_FORM","CHOOSE_CORRECT_ADJECTIVE","ANSWER_THE_QUESTION","TRUE_FALSE","WORD_ORDERING","WORD_FILL_PARAGRAPH","MATCH_BY_WRITING_ANSWER","WRITE_SENTENCES","LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP","LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE","LISTEN_AND_DRAG_OBJECTS_INTO_SCENE","LISTEN_AND_SPEAK_ANSWER","LISTEN_AND_SPEAK_IMAGE_GROUP","LISTEN_AND_SPEAK_QUESTION_LIST","LISTEN_AND_SPEAK_COMPARE_IMAGES","LISTEN_AND_SPEAK_WITH_STORY_IMAGES","LISTEN_AND_SPEAK_ODD_ONE_OUT","LISTEN_AND_SPEAK_INFO_EXCHANGE","READ_DISPLAYED_CONTENT","SPEAKING_DESCRIBE_IMAGE","SPONTANEOUS_QA","SPEAKING_CONVERSATION","GN_SPEAKING_INTERVIEW","SPEAKING_CUE_CARD","WORD_FILL_STRUCTURED_FORM"];export function getQuestionTypeLabel(e){return QUESTION_TYPE_CONFIG[e]?.label||e}
|
|
@@ -24,7 +24,7 @@ export interface WordFillStructuredFormData {
|
|
|
24
24
|
explanation?: string;
|
|
25
25
|
caseSensitive?: boolean;
|
|
26
26
|
/** Free-type width hint when not WITH_OPTIONS. */
|
|
27
|
-
blankStyle?: 'letter' | 'word' | 'phrase';
|
|
27
|
+
blankStyle?: 'letter' | 'word' | 'phrase' | 'translate';
|
|
28
28
|
/** Discriminates wordBank shape (0024 / 0025). */
|
|
29
29
|
viewMode?: WfsfViewMode | null;
|
|
30
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./ChooseTheCorrectAnswerGroupCreator";export*from"./ChooseTheCorrectAnswerGroupClient";
|
|
1
|
+
export*from"./ChooseTheCorrectAnswerGroupCreator";export*from"./ChooseTheCorrectAnswerGroupClient";export*from"./map-choose-the-correct-answer-group-data";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ChooseTheCorrectAnswerGroupData, ChooseTheCorrectAnswerGroupItemData } from '../../_shared/types/choose-the-correct-answer-group.type';
|
|
2
|
+
export declare function createEmptyChooseAnswerGroupItem(questionNumber: number): ChooseTheCorrectAnswerGroupItemData;
|
|
3
|
+
export declare function mapChooseAnswerGroupItem(item: unknown, index: number, fallbackAnswer?: string): ChooseTheCorrectAnswerGroupItemData;
|
|
4
|
+
export declare function mapQuestionToChooseAnswerGroupData(question: Record<string, unknown> | null | undefined): ChooseTheCorrectAnswerGroupData;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function t(t){return function(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}(t)?t:{}}function e(t,e=""){return"string"==typeof t?t:e}export function createEmptyChooseAnswerGroupItem(t){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:t}}export function mapChooseAnswerGroupItem(o,n,r){const i=t(o),s=t(i.content),p=t(i.correctAnswer),a=Array.isArray(s.options)?s.options:[],u=a.length>=2?a.map((o,n)=>{const r=t(o);return{id:e(r.id,`opt-${n+1}`),text:e(r.text)}}):[{id:"opt-1",text:""},{id:"opt-2",text:""},{id:"opt-3",text:""}],c=!0===i.isExample;return{question:e(s.question)||e(i.question),optionType:"image"===e(s.optionType)?"image":"text",options:u,correctAnswer:e(p.answer)||r||u[0]?.id||"opt-1",isExample:c,points:c?0:"number"==typeof i.points?i.points:1,questionNumber:"number"==typeof i.questionNumber?i.questionNumber:n+1}}export function mapQuestionToChooseAnswerGroupData(o){const n=t(o),r=t(n.content),i=t(n.answer),s=t(n.correctAnswer??n.correct_answer??i.correctAnswer),p=String(n.explanation||i.explanation||""),a=Array.isArray(s.answer)?s.answer.map(t=>"string"==typeof t?t:void 0):[];if(Array.isArray(r.items)){const o=r.items.map((t,e)=>mapChooseAnswerGroupItem(t,e,a[e]));return{instruction:e(t(r.meta).instruction)||"Choose the correct answer.",items:o,explanation:p,points:o.reduce((t,e)=>e.isExample?t:t+(e.points||0),0)}}return Array.isArray(i.items)?{instruction:e(i.instruction,"Choose the correct answer."),items:i.items.map((t,e)=>mapChooseAnswerGroupItem(t,e,a[e])),explanation:p,points:"number"==typeof i.points?i.points:void 0}:{instruction:"Choose the correct answer.",items:[createEmptyChooseAnswerGroupItem(1)],explanation:p,points:1}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ChooseTheCorrectAnswerGroupCreator as t}from"./ChooseTheCorrectAnswerGroupCreator";
|
|
1
|
+
import{ChooseTheCorrectAnswerGroupCreator as t}from"./ChooseTheCorrectAnswerGroupCreator";import{mapQuestionToChooseAnswerGroupData as e}from"./map-choose-the-correct-answer-group-data";export const chooseTheCorrectAnswerGroupRegistration={component:t,transformInitialData:t=>e(t),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||""}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./CrossOutWordGroupCreator";export*from"./CrossOutWordGroupClient";export*from"./transform";export*from"./register";
|
|
1
|
+
export*from"./CrossOutWordGroupCreator";export*from"./CrossOutWordGroupClient";export*from"./transform";export*from"./register";export*from"./map-cross-out-word-group-data";
|
package/dist/components/questions/types/cross-out-word-group/map-cross-out-word-group-data.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CrossOutWordGroupData, CrossOutWordGroupItemAnswer, CrossOutWordGroupItemData, CrossOutWordItemMode } from '../../_shared/types/cross-out-word-group.type';
|
|
2
|
+
export declare const DEFAULT_CROSS_OUT_INSTRUCTION = "Cross out the extra or incorrect word. If the word is incorrect, write the correct word. If the line is correct, leave it blank.";
|
|
3
|
+
export declare function createCrossOutAnswer(type: CrossOutWordItemMode, crossOut?: string, replaceWith?: string): CrossOutWordGroupItemAnswer;
|
|
4
|
+
export declare function createEmptyCrossOutItem(questionNumber: number): CrossOutWordGroupItemData;
|
|
5
|
+
export declare function mapCrossOutWordGroupItem(item: unknown, index: number, fallbackAnswer?: CrossOutWordGroupItemAnswer): CrossOutWordGroupItemData;
|
|
6
|
+
export declare function mapQuestionToCrossOutWordGroupData(question: Record<string, unknown> | null | undefined): CrossOutWordGroupData;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DEFAULT_CROSS_OUT_INSTRUCTION="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 t(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function r(r){return t(r)?r:{}}function e(t,r=""){return"string"==typeof t?t:r}function n(t){return"CROSS_OUT_AND_REPLACE"===t?"CROSS_OUT_AND_REPLACE":"CROSS_OUT"}export function createCrossOutAnswer(t,r="",e=""){return"CROSS_OUT_AND_REPLACE"===t?{type:t,crossOut:r,replaceWith:e}:{type:"CROSS_OUT",crossOut:r}}export function createEmptyCrossOutItem(t){return{type:"CROSS_OUT",question:"",correctAnswer:createCrossOutAnswer("CROSS_OUT"),isExample:!1,points:1,questionNumber:t}}export function mapCrossOutWordGroupItem(o,s,i){const u=r(o),c=r(u.content),p=r(u.correctAnswer),a=t(p.answer)?p.answer:t(i)?i:{},O=n(c.type||a.type),m=!0===u.isExample;return{type:O,question:e(c.question)||e(u.question),correctAnswer:createCrossOutAnswer(O,e(a.crossOut),e(a.replaceWith)),isExample:m,points:m?0:"number"==typeof u.points?u.points:1,questionNumber:"number"==typeof u.questionNumber?u.questionNumber:s+1}}export function mapQuestionToCrossOutWordGroupData(o){const s=r(o),i=r(s.content),u=r(s.answer),c=r(s.correctAnswer??s.correct_answer??u.correctAnswer),p=String(s.explanation||u.explanation||""),a=Array.isArray(c.answer)?c.answer.map(r=>{if(t(r))return createCrossOutAnswer(n(r.type),e(r.crossOut),e(r.replaceWith))}):[];if(Array.isArray(i.items)){const t=i.items.map((t,r)=>mapCrossOutWordGroupItem(t,r,a[r]));return{instruction:e(r(i.meta).instruction)||DEFAULT_CROSS_OUT_INSTRUCTION,items:t,explanation:p,points:t.reduce((t,r)=>r.isExample?t:t+(r.points||0),0)}}return Array.isArray(u.items)?{instruction:e(u.instruction,DEFAULT_CROSS_OUT_INSTRUCTION),items:u.items.map((t,r)=>mapCrossOutWordGroupItem(t,r,a[r])),explanation:p,points:"number"==typeof u.points?u.points:void 0}:{instruction:DEFAULT_CROSS_OUT_INSTRUCTION,items:[createEmptyCrossOutItem(1)],explanation:p,points:1}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CrossOutWordGroupCreator as t}from"./CrossOutWordGroupCreator";
|
|
1
|
+
import{CrossOutWordGroupCreator as t}from"./CrossOutWordGroupCreator";import{mapQuestionToCrossOutWordGroupData as e}from"./map-cross-out-word-group-data";export const crossOutWordGroupRegistration={component:t,transformInitialData:t=>e(t),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||""}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./TrueFalseGroupCreator";export*from"./TrueFalseGroupClient";export*from"./transform";export*from"./register";
|
|
1
|
+
export*from"./TrueFalseGroupCreator";export*from"./TrueFalseGroupClient";export*from"./transform";export*from"./register";export*from"./map-true-false-group-data";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TrueFalseGroupData, TrueFalseGroupItemData } from '../../_shared/types/true-false-group.type';
|
|
2
|
+
export declare function createEmptyTrueFalseGroupItem(questionNumber: number): TrueFalseGroupItemData;
|
|
3
|
+
export declare function mapTrueFalseGroupItem(item: unknown, index: number, fallbackAnswer?: boolean): TrueFalseGroupItemData;
|
|
4
|
+
export declare function mapQuestionToTrueFalseGroupData(question: Record<string, unknown> | null | undefined): TrueFalseGroupData;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){return function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(e)?e:{}}function t(e,t=""){return"string"==typeof e?e:t}export function createEmptyTrueFalseGroupItem(e){return{question:"",correctAnswer:!0,isExample:!1,points:1,questionNumber:e}}export function mapTrueFalseGroupItem(r,n,o){const i=e(r),s=e(i.content),a=e(i.correctAnswer),u=!0===i.isExample,p="boolean"==typeof a.answer?a.answer:"boolean"!=typeof o||o;return{question:t(s.question)||t(i.question),correctAnswer:p,isExample:u,points:u?0:"number"==typeof i.points?i.points:1,questionNumber:"number"==typeof i.questionNumber?i.questionNumber:n+1}}export function mapQuestionToTrueFalseGroupData(r){const n=e(r),o=e(n.content),i=e(n.answer),s=e(n.correctAnswer??n.correct_answer??i.correctAnswer),a=String(n.explanation||i.explanation||""),u=Array.isArray(s.answer)?s.answer.map(e=>"boolean"==typeof e?e:void 0):[];if(Array.isArray(o.items)){const r=o.items.map((e,t)=>mapTrueFalseGroupItem(e,t,u[t]));return{instruction:t(e(o.meta).instruction)||"Tick True or False.",items:r,explanation:a,points:r.reduce((e,t)=>t.isExample?e:e+(t.points||0),0)}}return Array.isArray(i.items)?{instruction:t(i.instruction,"Tick True or False."),items:i.items.map((e,t)=>mapTrueFalseGroupItem(e,t,u[t])),explanation:a,points:"number"==typeof i.points?i.points:void 0}:{instruction:"Tick True or False.",items:[createEmptyTrueFalseGroupItem(1)],explanation:a,points:1}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{TrueFalseGroupCreator as t}from"./TrueFalseGroupCreator";
|
|
1
|
+
import{TrueFalseGroupCreator as t}from"./TrueFalseGroupCreator";import{mapQuestionToTrueFalseGroupData as e}from"./map-true-false-group-data";export const trueFalseGroupRegistration={component:t,transformInitialData:t=>e(t),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||""}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{WordFillStructuredFormCreator}from"./WordFillStructuredFormCreator";export{WordFillStructuredFormClient}from"./WordFillStructuredFormClient";
|
|
1
|
+
export{WordFillStructuredFormCreator}from"./WordFillStructuredFormCreator";export{WordFillStructuredFormClient}from"./WordFillStructuredFormClient";export{mapQuestionToWfsfData}from"./map-wfsf-question-data";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WordFillStructuredFormData } from '../../_shared/types/word-fill-structured-form.type';
|
|
2
|
+
export declare function extractWfsfBlankKeys(html: string): string[];
|
|
3
|
+
/**
|
|
4
|
+
* Map preview / exam / creator payloads onto WordFillStructuredFormClient data.
|
|
5
|
+
* School preview puts answers on `answer` + `correctAnswer`; creator uses `answer`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function mapQuestionToWfsfData(question: Record<string, unknown> | null | undefined): WordFillStructuredFormData;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{detectWfsfBankMode as t,normalizeOptionsWordBank as n,normalizeSharedWordBank as e}from"./wfsf-word-bank.utils";function r(t){return t&&"object"==typeof t&&!Array.isArray(t)?t:{}}function o(t){const n=r(t),e={};for(const[t,r]of Object.entries(n))"string"==typeof r&&(e[t]=r);return e}function i(t){if("letter"===t||"word"===t||"phrase"===t||"translate"===t)return t}export function extractWfsfBlankKeys(t){const n=new Set,e=/\{([\w\d]+)\}/g;let r;for(;null!==(r=e.exec(t));)n.add(r[1]);return Array.from(n).sort((t,n)=>{const e=parseInt(t,10),r=parseInt(n,10);return Number.isNaN(e)||Number.isNaN(r)?t.localeCompare(n):e-r})}export function mapQuestionToWfsfData(a){const s=r(a),l=r(s.content),c=r(s.answer),u=r(s.correctAnswer??s.correct_answer??c.correctAnswer??c),p=s.total_points?parseFloat(String(s.total_points)):c.points??s.points??1,g=Number.isFinite(Number(p))?Number(p):1,f=String(c.instruction||s.instruction||s.explanation||""),S=String(c.explanation||""),w=function(t,n){const e=t.content||n.content||"";if("string"==typeof e&&e)return e;const r=t.blocks||n.blocks;return r?.length?r.map(t=>(t.heading?`<h3>${t.heading}</h3>`:"")+(t.content||"")).join(""):"string"==typeof e?e:""}(l,c),m=l.wordBank??c.wordBank,b=l.viewMode??c.viewMode,d=t(b,m),y=extractWfsfBlankKeys(String(w||"")),k="FREE_TYPE"===d?void 0:d,N="WITH_WORD_BANK"===d?e(m):"WITH_OPTIONS"===d?n(m,y):void 0,v=r(r(s.questionGroup).payload);return{title:String(l.title||c.title||""),imageUrl:String(l.imageUrl||c.imageUrl||""),content:w,answers:o(u.answers||c.answers),caseSensitive:Boolean(u.caseSensitive??c.caseSensitive??!1),blankStyle:i(l.blankStyle??c.blankStyle),viewMode:k,wordBank:N,instruction:f,explanation:S,points:g,groupTitle:String(v.title||c.groupTitle||""),groupSubtitle:String(v.subtitle||c.groupSubtitle||""),groupContent:String(v.content||c.groupContent||""),groupImageUrl:String(v.imageUrl||c.groupImageUrl||"")}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WordFillStructuredFormCreator as t}from"./WordFillStructuredFormCreator";import{
|
|
1
|
+
import{WordFillStructuredFormCreator as t}from"./WordFillStructuredFormCreator";import{mapQuestionToWfsfData as e}from"./map-wfsf-question-data";export const wordFillStructuredFormRegistration={component:t,transformInitialData:t=>e(t),getExtraProps:t=>({onUnsavedChangesChange:t.onUnsavedChangesChange,validationRef:t.validationRef,groupConfig:t.groupConfig,groupType:t.groupType,groups:t.groups,questionIndexInPart:t.questionIndexInPart,partId:t.partId,viewMode:t.viewMode}),wrapOnSave:(t,e)=>({type:e.questionType,content:e.state.content,points:t?.points??e.state.points??1,level:e.state.level,difficulty:e.state.difficulty,skill:e.state.skill,answer:t,explanation:t?.explanation||""}),wrapOnChange:(t,e)=>({type:e.questionType,content:e.state.content,points:t?.points??e.state.points??1,level:e.state.level,difficulty:e.state.difficulty,skill:e.state.skill,answer:t,explanation:t?.explanation||""})};
|
|
@@ -1 +1 @@
|
|
|
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
|
+
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&&"translate"!==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}};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Question } from '../../../shared/types/entities/question.types';
|
|
2
|
+
type ChooseTheCorrectAnswerGroupViewerProps = {
|
|
3
|
+
question: Question;
|
|
4
|
+
isReviewMode?: boolean;
|
|
5
|
+
userAnswer?: string[];
|
|
6
|
+
};
|
|
7
|
+
export declare function ChooseTheCorrectAnswerGroupViewer({ question, isReviewMode, userAnswer, }: ChooseTheCorrectAnswerGroupViewerProps): import("react").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import{ChooseTheCorrectAnswerGroupClient as r}from"../types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupClient";import{mapQuestionToChooseAnswerGroupData as o}from"../types/choose-the-correct-answer-group/map-choose-the-correct-answer-group-data";export function ChooseTheCorrectAnswerGroupViewer({question:s,isReviewMode:t=!1,userAnswer:c}){const n=o(s),i=t&&!c?n.items.map(e=>e.correctAnswer):c;return e(r,{questionData:n,isReviewMode:t,userAnswers:i})}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Question } from '../../../shared/types/entities/question.types';
|
|
2
|
+
type CrossOutWordGroupViewerProps = {
|
|
3
|
+
question: Question;
|
|
4
|
+
isReviewMode?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare function CrossOutWordGroupViewer({ question, isReviewMode, }: CrossOutWordGroupViewerProps): import("react").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as o}from"react/jsx-runtime";import{CrossOutWordGroupClient as r}from"../types/cross-out-word-group/CrossOutWordGroupClient";import{mapQuestionToCrossOutWordGroupData as s}from"../types/cross-out-word-group/map-cross-out-word-group-data";export function CrossOutWordGroupViewer({question:e,isReviewMode:t=!1}){const u=s(e);return o(r,{questionData:u,isReviewMode:t,userAnswers:t?u.items.map(o=>o.correctAnswer):[]})}
|
|
@@ -1 +1 @@
|
|
|
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
|
+
"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 i}from"../../../components/ui/card";import{Input as a}from"../../../components/ui/input";import{Check as c,Volume2 as l,X as u}from"lucide-react";import{useRef as d,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 w}from"../types/arrange-letters-into-words/ArrangeLettersIntoWordsClient";import{WriteShortParagraphClient as h}from"../types/write-short-paragraph/WriteShortParagraphClient";import{LabelThePictureClient as N}from"../types/label-the-picture/LabelThePictureClient";import{LookPictureFillWordHintClient as _}from"../types/look-picture-fill-word-hint/LookPictureFillWordHintClient";import{ReadPassageAndAnswerQuestionsClient as C}from"../types/read-passage-and-answer-questions/ReadPassageAndAnswerQuestionsClient";import{ChooseTheCorrectAnswerClient as A}from"../types/choose-the-correct-answer/ChooseTheCorrectAnswerClient";import{WriteAShortLetterClient as R}from"../types/write-a-short-letter/WriteAShortLetterClient";import{LookPictureChooseCorrectAnswerClient as f}from"../types/look-picture-choose-correct-answer/LookPictureChooseCorrectAnswerClient";import{LookPictureFillBlankChooseAnswerClient as v}from"../types/look-picture-fill-blank-choose-answer/LookPictureFillBlankChooseAnswerClient";import{FillMissingWordsInGridClient as x}from"../types/fill-missing-words-in-grid/FillMissingWordsInGridClient";import{WordFillStructuredFormViewer as S}from"./WordFillStructuredFormViewer";import{ChooseTheCorrectAnswerGroupViewer as y}from"./ChooseTheCorrectAnswerGroupViewer";import{TrueFalseGroupViewer as E}from"./TrueFalseGroupViewer";import{CrossOutWordGroupViewer as O}from"./CrossOutWordGroupViewer";import{SpontaneousQaGroupViewer as T}from"./SpontaneousQaGroupViewer";import{WordOrderAndMatchGroupViewer as L}from"./WordOrderAndMatchGroupViewer";export function QuestionViewer({question:W,onSubmitAnswer:I,isReviewMode:D=!1,userAnswer:q}){const[U,P]=m(q||null),[k,G]=m(0),M=d(null),[Q,F]=m(q||{}),H=W.answer,[$,j]=m(q||Array(H?.blanks?.length||0).fill("")),[B,K]=m(q||{}),[V,Y]=m(q||{}),[z,J]=m(q||{}),X=()=>{const e=W.answer.maxPlayCount||3;k>=e?p.warning(g("common.audio.maxPlayReached",{maxPlay:String(e)})):(M.current?.play(),G(k+1))},Z=()=>{const t=W.answer,{blanks:n,caseSensitive:o=!1}=t;return r("div",{className:"space-y-4",children:[n.map((s,t)=>{const i=$[t]||"",l=D&&((e,r)=>{const s=n[e];return o?r===s:r.toLowerCase()===s.toLowerCase()})(t,i);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(a,{value:i,onChange:e=>((e,r)=>{const s=[...$];s[e]=r,j(s)})(t,e.target.value),placeholder:"Nhập đáp án...",className:"flex-1 "+(D?l?"border-green-500 bg-green-50":"border-red-500 bg-red-50":""),disabled:D}),D&&l&&e(c,{className:"h-4 w-4 text-green-600"}),D&&!l&&i&&e(u,{className:"h-4 w-4 text-red-600"})]},t)}),!D&&e(s,{onClick:()=>{I&&I($)},disabled:$.some(e=>""===e.trim()),children:"Nộp đáp án"})]})};return r(t,{children:[e(o,{children:r(i,{className:"flex items-center justify-between",children:[e("span",{children:"string"==typeof W.content?W.content:W.content?.question||W.content?.title||"Câu hỏi"}),r("span",{className:"text-sm font-normal text-gray-500",children:[W.points," điểm"]})]})}),r(n,{className:"space-y-4",children:[(()=>{switch(W.type){case"CHOOSE_THE_CORRECT_ANSWER":return(()=>{const r=W.answer,{isGroup:s,questionGroup:t}=W;let n={};return n=W.content&&"object"==typeof W.content?{...W.content,correctAnswer:W.correctAnswer?.answer??-1,id:W.id,isGroup:s,groupTitle:t?.payload?.title,groupContent:t?.payload?.content,groupImageUrl:t?.payload?.imageUrl,groupNumber:t?.groupNumber}:{...r,question:W.content||r?.question,id:W.id,isGroup:s,groupTitle:t?.payload?.title,groupContent:t?.payload?.content,groupImageUrl:t?.payload?.imageUrl,groupNumber:t?.groupNumber},e(A,{questionData:n,questionConfig:W.questionConfig,onSubmit:e=>{P(e),I?.(e)},isReviewMode:D,userAnswer:q})})();case"CHOOSE_THE_CORRECT_ANSWER_GROUP":return e(y,{question:W,isReviewMode:D,userAnswer:q});case"TRUE_FALSE_GROUP":return e(E,{question:W,isReviewMode:D,userAnswer:q});case"CROSS_OUT_WORD_GROUP":return e(O,{question:W,isReviewMode:D});case"SPONTANEOUS_QA_GROUP":return e(T,{question:W});case"WORD_ORDER_AND_MATCH_GROUP":return e(L,{question:W});case"FILL_IN_BLANK":return Z();case"TRUE_FALSE":return(()=>{const t=W.answer,{correctAnswer:n}=t;return r("div",{className:"space-y-3",children:[[{value:!0,label:"Đúng"},{value:!1,label:"Sai"}].map(s=>{const t=U===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"} ${D&&s.value===n?"border-green-500 bg-green-50":D&&t&&s.value!==n?"border-red-500 bg-red-50":""}`,onClick:()=>!D&&P(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"} ${D&&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}),D&&s.value===n&&e(c,{className:"ml-2 h-4 w-4 text-green-600"}),D&&t&&s.value!==n&&e(u,{className:"ml-2 h-4 w-4 text-red-600"})]})},s.value.toString())}),!D&&e(s,{onClick:()=>{I&&I(U)},disabled:null===U,children:"Nộp đáp án"})]})})();case"ESSAY":return(()=>{const t=W.answer,{minWords:n,maxWords:o}=t,i=U?U.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ừ`:"",U&&r("span",{className:"ml-2 "+(i>=(n||0)&&i<=(o||1/0)?"text-green-600":"text-red-600"),children:["(",i," từ)"]})]}),e("textarea",{value:U||"",onChange:e=>P(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:D}),!D&&e(s,{onClick:()=>{I&&I(U)},disabled:!U||U.trim().length<(n||0),children:"Nộp đáp án"})]})})();case"LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE":return(()=>{const t=W.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:X,variant:"outline",className:"gap-2",children:[e(l,{className:"h-5 w-5"}),"Phát âm thanh (",k,"/",t.maxPlayCount||3,")"]}),e("audio",{ref:M,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(a,{value:$[t],onChange:e=>{const r=[...$];r[t]=e.target.value,j(r),P(r)},placeholder:"Nhập câu trả lời...",disabled:D,className:D?$[t]?.toLowerCase()===o[t]?.toLowerCase()?"border-green-500 bg-green-50":"border-red-500 bg-red-50":""}),D&&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=W.answer,{statements:t}=s;return e("div",{className:"space-y-3",children:t.map(s=>e("div",{className:`rounded-lg border-2 p-4 ${D&&Q[s.id]===s.isCorrect?"border-green-500 bg-green-50":""} ${D&&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};F(e),P(e)},disabled:D,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};F(e),P(e)},disabled:D,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(u,{className:"h-5 w-5"})})]}),e("p",{className:"flex-1",children:s.text}),D&&e("span",{className:"text-sm font-medium",children:s.isCorrect?"✓ Đúng":"✗ Sai"})]})},s.id))})})();case"ARRANGE_LETTERS_INTO_WORDS":return(()=>{const r=W.answer,s=W.correctAnswer||W.correct_answer,t=(r?.subQuestions||[]).map(e=>{const r=s?.answers?.[e.id]||e.correctWord||"";return{...e,correctWord:r}});return e(w,{questionData:{subQuestions:t},onSubmit:e=>{P(e),I?.(e)},isReviewMode:D,userAnswer:q})})();case"READ_PASSAGE_AND_COMPLETE_STORY":return(()=>{const s=W.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(a,{value:V[o]||"",onChange:e=>{const r={...V,[o]:e.target.value};Y(r),P(r)},className:`inline-block h-8 w-32 text-center ${D&&V[o]===s?.correctAnswer?"border-green-500 bg-green-50":""} ${D&&V[o]!==s?.correctAnswer?"border-red-500 bg-red-50":""} `,disabled:D}),D&&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=W.answer;return e(h,{questionData:{contexts:r?.contexts||[],minWords:r?.minWords||20,maxWords:r?.maxWords,instruction:r?.instruction||""},onSubmit:e=>{P(e),I?.(e)},isReviewMode:D,userAnswer:q})})();case"WRITE_A_SHORT_LETTER":return(()=>{const r=W.answer;return e(R,{questionData:{contexts:r?.contexts||[],informations:r?.informations||[],minWords:r?.minWords||20,maxWords:r?.maxWords,instruction:r?.instruction||""},onSubmit:e=>{P(e),I?.(e)},isReviewMode:D,userAnswer:q})})();case"LOOK_PICTURE_FILL_WORD_HINT":return(()=>{const r=W.answer,s=W.content,t=W.questionGroup;let n=[];r?.subQuestions&&r.subQuestions.length>0?n=r.subQuestions:s?.imageUrl&&s?.word&&(n=[{id:W.id,imageUrl:s.imageUrl,word:s.word,correctAnswer:r?.correctAnswer||"",groupNumber:t?.groupNumber||1}]);const o=t?.payload?.hintLetters||r?.hintLetters||s?.hintLetters||[],i=t?.groupNumber||1,a={};o.length>0&&(a[i]=o);const c={subQuestions:n,hintLetters:o,hintLettersByGroup:a,groups:[{number:i,questionCount:n.length}]};return e(_,{questionData:c,userAnswer:q,isReviewMode:D,explanation:W.explanation,onSubmit:e=>{P(e),I?.(e)}})})();case"LABEL_THE_PICTURE":return(()=>{const r=W.answer;return e(N,{questionData:r,userAnswer:q,isReviewMode:D,onSubmit:e=>{P(e),I?.(e)}})})();case"READ_AND_COLOR_OBJECTS":return(()=>{const r=W.answer;return e(b,{questionData:{backgroundImageUrl:r?.backgroundImageUrl||"",colorNodes:r?.colorNodes||[],regionNodes:r?.regionNodes||[],instructions:r?.instructions||[]},onSubmit:e=>{P(e),I?.(e)}})})();case"READ_PASSAGE_AND_ANSWER_QUESTIONS":return(()=>{const r=W.answer;return e(C,{questionData:{passage:r?.passage||"",passageTitle:r?.passageTitle||"",instructions:r?.instructions||"",subQuestions:r?.subQuestions||[]},userAnswer:q,isReviewMode:D,onSubmit:e=>{P(e),I?.(e)}})})();case"LOOK_PICTURE_CHOOSE_CORRECT_ANSWER":return(()=>{const r=W.content,s=W.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(f,{questionData:{subQuestions:t},userAnswer:q,isReviewMode:D,onSubmit:e=>{P(e),I?.(e)}})})();case"LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER":return(()=>{const r=W.content,s=W.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(v,{questionData:{subQuestions:t},userAnswer:q,isReviewMode:D,onSubmit:e=>{P(e),I?.(e)}})})();case"FILL_MISSING_WORDS_IN_GRID":return(()=>{const r=W.content,s=W.answer;return e(x,{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:q,isReviewMode:D,onSubmit:e=>{P(e),I?.(e)}})})();case"WORD_FILL_STRUCTURED_FORM":return e(S,{question:W,isReviewMode:D,userAnswer:q,onSubmitAnswer:I});default:return r("div",{children:["Loại câu hỏi không được hỗ trợ: ",W.type]})}})(),!D&&e("div",{className:"flex justify-end border-t pt-4",children:e(s,{onClick:()=>{I?.(U)},className:"bg-blue-500 hover:bg-blue-600",children:"Xác nhận đáp án"})})]})]})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";function r(e){return function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(e)?e:{}}function n(e,t=""){return"string"==typeof e?e:t}function s(e,t){const s=r(e),i=r(s.content),o=r(s.correctAnswer),a=Array.isArray(o.expectedAnswers)?o.expectedAnswers.map(e=>String(e??"")):[];return{questionText:n(i.questionText)||n(i.question)||n(s.questionText),audioUrl:n(i.audioUrl)||void 0,expectedAnswers:a,isExample:!0===s.isExample,points:"number"==typeof s.points?s.points:1,questionNumber:"number"==typeof s.questionNumber?s.questionNumber:t+1}}export function SpontaneousQaGroupViewer({question:i}){const{instruction:o,items:a}=function(e){const t=r(e.content),i=r(e.spontaneousQAList??t.spontaneousQAList??t),o=Array.isArray(i.items)?i.items:Array.isArray(t.items)?t.items:[];return{instruction:n(r(i.meta).instruction)||n(r(t.meta).instruction)||n(e.explanation)||"Talk about the topic.",items:o.map(s)}}(i);return t("div",{className:"space-y-4",children:[o?e("div",{className:"rounded-xl border border-indigo-100 bg-indigo-50 px-4 py-3 text-sm font-medium text-indigo-800",children:o}):null,a.map((r,n)=>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-gray-50 px-4 py-2.5",children:[t("span",{className:"text-sm font-medium text-gray-700",children:["Câu ",r.questionNumber||n+1]}),t("span",{className:"text-xs text-gray-500",children:[r.points||0," điểm"]})]}),t("div",{className:"space-y-2 p-4",children:[e("p",{className:"text-sm font-semibold text-gray-800",children:r.questionText||"Câu hỏi chưa được nhập"}),r.audioUrl?t("p",{className:"text-xs text-gray-500",children:["Audio: ",r.audioUrl]}):null,r.expectedAnswers.length>0?t("div",{className:"rounded-lg border border-emerald-100 bg-emerald-50 px-3 py-2 text-sm text-emerald-800",children:[e("p",{className:"mb-1 font-medium",children:"Gợi ý đáp án"}),e("ul",{className:"list-disc space-y-1 pl-4",children:r.expectedAnswers.map(t=>e("li",{children:t},t))})]}):null]})]},`${r.questionNumber}-${n}`))]})}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Question } from '../../../shared/types/entities/question.types';
|
|
2
|
+
type TrueFalseGroupViewerProps = {
|
|
3
|
+
question: Question;
|
|
4
|
+
isReviewMode?: boolean;
|
|
5
|
+
userAnswer?: boolean[];
|
|
6
|
+
};
|
|
7
|
+
export declare function TrueFalseGroupViewer({ question, isReviewMode, userAnswer, }: TrueFalseGroupViewerProps): import("react").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import{TrueFalseGroupClient as r}from"../types/true-false-group/TrueFalseGroupClient";import{mapQuestionToTrueFalseGroupData as s}from"../types/true-false-group/map-true-false-group-data";export function TrueFalseGroupViewer({question:t,isReviewMode:o=!1,userAnswer:u}){const i=s(t),a=o&&!u?i.items.map(e=>e.correctAnswer):u;return e(r,{questionData:i,isReviewMode:o,userAnswers:a})}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Question } from '../../../shared/types/entities/question.types';
|
|
2
|
+
type WordFillStructuredFormViewerProps = {
|
|
3
|
+
question: Question;
|
|
4
|
+
isReviewMode?: boolean;
|
|
5
|
+
userAnswer?: Record<string, string>;
|
|
6
|
+
onSubmitAnswer?: (answer: Record<string, string>) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare function WordFillStructuredFormViewer({ question, isReviewMode, userAnswer, onSubmitAnswer, }: WordFillStructuredFormViewerProps): import("react").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as r}from"react/jsx-runtime";import{useState as e}from"react";import{WordFillStructuredFormClient as t}from"../types/word-fill-structured-form/WordFillStructuredFormClient";import{mapQuestionToWfsfData as o}from"../types/word-fill-structured-form/map-wfsf-question-data";export function WordFillStructuredFormViewer({question:i,isReviewMode:n=!1,userAnswer:s,onSubmitAnswer:u}){const m=o(i),[a,l]=e(()=>s??{});return r(t,{questionData:m,isReviewMode:n,userAnswer:s,autoFillCorrectAnswers:n&&!s,instruction:m.instruction,questionNumber:i.questionNumber,explanation:i.explanation,onAnswerChange:(r,e)=>{const t={...a,[r]:e};l(t),u?.(t)}})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";function t(e){return function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(e)?e:{}}function s(e,r=""){return"string"==typeof e?e:r}function a(e,r){const a=t(e),n=t(a.content),i=t(a.correctAnswer);return{scrambledWords:Array.isArray(n.scrambledWords)?n.scrambledWords.map(e=>String(e??"")):[],orderedPhrase:s(i.orderedPhrase),matchLabel:s(i.matchLabel),isExample:!0===a.isExample,points:"number"==typeof a.points?a.points:1,questionNumber:"number"==typeof a.questionNumber?a.questionNumber:r+1}}export function WordOrderAndMatchGroupViewer({question:n}){const{instruction:i,matchOptions:d,items:o}=function(e){const r=t(e.content),n=t(e.wordOrderMatchList??r.wordOrderMatchList??r),i=t(n.meta??r.meta),d=Array.isArray(n.items)?n.items:Array.isArray(r.items)?r.items:[];return{instruction:s(i.instruction)||s(e.explanation)||"Put the phrases in order, then match the labels.",matchOptions:Array.isArray(i.matchOptions)?i.matchOptions.map(e=>String(e??"")):[],items:d.map(a)}}(n);return r("div",{className:"space-y-4",children:[i?e("div",{className:"rounded-xl border border-indigo-100 bg-indigo-50 px-4 py-3 text-sm font-medium text-indigo-800",children:i}):null,d.length>0?e("div",{className:"flex flex-wrap gap-2",children:d.map(r=>e("span",{className:"rounded-md border border-gray-200 bg-white px-2 py-1 text-xs font-semibold text-gray-700",children:r},r))}):null,o.map((t,s)=>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-gray-50 px-4 py-2.5",children:[r("span",{className:"text-sm font-medium text-gray-700",children:["Câu ",t.questionNumber||s+1,t.isExample?" · Example":""]}),r("span",{className:"text-xs text-gray-500",children:[t.points||0," điểm"]})]}),r("div",{className:"space-y-2 p-4",children:[e("div",{className:"flex flex-wrap gap-1.5",children:t.scrambledWords.map((r,t)=>e("span",{className:"rounded-md border border-dashed border-teal-300 bg-teal-50 px-2 py-1 text-sm text-teal-800",children:r},`${r}-${t}`))}),r("p",{className:"text-sm text-gray-800",children:[e("span",{className:"font-medium text-gray-500",children:"Câu đúng: "}),t.orderedPhrase||"—"]}),r("p",{className:"text-sm text-gray-800",children:[e("span",{className:"font-medium text-gray-500",children:"Nhãn: "}),t.matchLabel||"—"]})]})]},`${t.questionNumber}-${s}`))]})}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export { QuestionViewer } from './QuestionViewer';
|
|
2
2
|
export { QuestionGroupViewer } from './QuestionGroupViewer';
|
|
3
|
+
export { WordFillStructuredFormViewer } from './WordFillStructuredFormViewer';
|
|
4
|
+
export { ChooseTheCorrectAnswerGroupViewer } from './ChooseTheCorrectAnswerGroupViewer';
|
|
5
|
+
export { TrueFalseGroupViewer } from './TrueFalseGroupViewer';
|
|
6
|
+
export { CrossOutWordGroupViewer } from './CrossOutWordGroupViewer';
|
|
7
|
+
export { SpontaneousQaGroupViewer } from './SpontaneousQaGroupViewer';
|
|
8
|
+
export { WordOrderAndMatchGroupViewer } from './WordOrderAndMatchGroupViewer';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{QuestionViewer}from"./QuestionViewer";export{QuestionGroupViewer}from"./QuestionGroupViewer";
|
|
1
|
+
export{QuestionViewer}from"./QuestionViewer";export{QuestionGroupViewer}from"./QuestionGroupViewer";export{WordFillStructuredFormViewer}from"./WordFillStructuredFormViewer";export{ChooseTheCorrectAnswerGroupViewer}from"./ChooseTheCorrectAnswerGroupViewer";export{TrueFalseGroupViewer}from"./TrueFalseGroupViewer";export{CrossOutWordGroupViewer}from"./CrossOutWordGroupViewer";export{SpontaneousQaGroupViewer}from"./SpontaneousQaGroupViewer";export{WordOrderAndMatchGroupViewer}from"./WordOrderAndMatchGroupViewer";
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*as Api from"./api";export*as Components from"./components";export*as
|
|
1
|
+
export*as Api from"./api";export*as Components from"./components";export*as Exams from"./components/exams";export*as Questions from"./components/questions";export*as Results from"./components/results";export*as Themes from"./components/themes";export*as Shared from"./shared";export{buildExamTemplatePayload,createContestRoomsApi,createExamCreateApi,createExamEntryApi,createExamQuestionsApi,createExamQuestionsFetchApi,createExamTakingApi,createMockContestRoomsApi,createMockCreateExamApi,createMockExamEntryApi,createMockExamQuestionsApi,createMockExamTakingApi,createMockResultReviewApi,createResultReviewApi}from"./api";export{CreateExamPageContainer,ExamPreviewDialog,ExamQuestionsPageContainer,ExamTakingPageContainer,ExamViewDialog,StudentContestRoomsPageContainer,StudentExamEntryPageContainer}from"./components/exams";export{ResultReviewPageContainer}from"./components/results";export{QuestionCreator}from"./components/questions/creator/QuestionCreator";export{QuestionGroupCreator}from"./components/questions/creator/QuestionGroupCreator";export{renderDedicatedComponent}from"./components/questions/creator/dedicated-component-router";export{questionTypeRegistry}from"./components/questions/creator/question-type-registry";export{QUESTION_TYPE_CONFIG,QUESTION_TYPES_WITH_DEDICATED_COMPONENTS}from"./components/questions/_shared/config/question-types.config";export{validateQuestion}from"./components/questions/_shared/utils/question-validation";export{buildAnswerPayload}from"./components/questions/_shared/utils/answer-builder";export*from"./components/questions/_shared/types";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{SkillEnum as E}from"../types/common.types";export const QUESTION_TYPE_SKILLS={LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:E.LISTENING,LISTEN_AND_TICK_ANSWER:E.LISTENING,LISTEN_AND_FILL_NAME_NUMBER:E.LISTENING,LISTENING_FILL_BLANK:E.LISTENING,LISTENING_COLOR:E.LISTENING,LISTENING:E.LISTENING,LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:E.SPEAKING,LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:E.SPEAKING,LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:E.SPEAKING,LISTEN_AND_SPEAK_ANSWER:E.SPEAKING,LISTEN_AND_SPEAK_IMAGE_GROUP:E.SPEAKING,LISTEN_AND_SPEAK_QUESTION_LIST:E.SPEAKING,LISTEN_AND_SPEAK_COMPARE_IMAGES:E.SPEAKING,LISTEN_AND_SPEAK_WITH_STORY_IMAGES:E.SPEAKING,LISTEN_AND_SPEAK_ODD_ONE_OUT:E.SPEAKING,LISTEN_AND_SPEAK_INFO_EXCHANGE:E.SPEAKING,READ_DISPLAYED_CONTENT:E.SPEAKING,SPEAKING_DESCRIBE_IMAGE:E.SPEAKING,SPONTANEOUS_QA:E.SPEAKING,SPEAKING_CONVERSATION:E.SPEAKING,SPEAKING_CUE_CARD:E.SPEAKING,GN_SPEAKING_INTERVIEW:E.SPEAKING,CHOOSE_THE_CORRECT_ANSWER:E.READING,CHOOSE_THE_CORRECT_ANSWER_GROUP:E.READING,CHOOSE_CORRECT_ADJECTIVE:E.READING,FILL_IN_BLANK:E.READING,FILL_MISSING_WORDS_IN_GRID:E.READING,READ_PASSAGE_AND_ANSWER_QUESTIONS:E.READING,ANSWER_THE_QUESTION:E.READING,WORD_ORDERING:E.READING,WORD_FILL_PARAGRAPH:E.READING,MATCH_BY_WRITING_ANSWER:E.READING,LABEL_THE_PICTURE:E.READING,LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:E.READING,LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:E.READING,LOOK_PICTURE_FILL_WORD_HINT:E.READING,READ_AND_COLOR_OBJECTS:E.READING,IMAGE_OBJECT_MATCHING:E.READING,TRUE_FALSE:E.READING,TRUE_FALSE_GROUP:E.READING,CROSS_OUT_WORD_GROUP:E.READING,MATCHING:E.READING,ORDERING:E.READING,TICK_TRUE_OR_FALSE:E.READING,TICK_YES_OR_NO:E.READING,READING_TICK_CROSS:E.READING,ARRANGE_LETTERS_INTO_WORDS:E.READING,READ_PASSAGE_AND_COMPLETE_STORY:E.READING,CLOZE_TEST_WITH_TICK_BOX:E.READING,READ_AND_CHOOSE_APPROPRIATE_WORD:E.READING,READING_LETTER_ARRANGE:E.READING,READING_PASSAGE_FILL:E.READING,FILL_BLANK:E.READING,WORD_FILL_STRUCTURED_FORM:E.READING,WRITE_A_SHORT_LETTER:E.WRITING,WRITE_CORRECT_VERB_FORM:E.WRITING,WRITE_SHORT_PARAGRAPH:E.WRITING,WRITE_SENTENCES:E.WRITING,ESSAY:E.WRITING,COLORING:E.WRITING};export function getQuestionTypeSkill(E){return QUESTION_TYPE_SKILLS[E]||"READING"}export function getQuestionTypesBySkill(E){return Object.entries(QUESTION_TYPE_SKILLS).filter(([_,N])=>N===E).map(([E,_])=>E)}export const QUESTION_TYPES_BY_SKILL={LISTENING:getQuestionTypesBySkill("LISTENING"),SPEAKING:getQuestionTypesBySkill("SPEAKING"),READING:getQuestionTypesBySkill("READING"),WRITING:getQuestionTypesBySkill("WRITING")};export const MARKETING_QUESTION_TYPES_BY_SKILL={[E.LISTENING]:[],[E.SPEAKING]:[],[E.READING]:["CHOOSE_THE_CORRECT_ANSWER","CHOOSE_CORRECT_ADJECTIVE","FILL_IN_BLANK","FILL_MISSING_WORDS_IN_GRID","LABEL_THE_PICTURE","LOOK_PICTURE_CHOOSE_CORRECT_ANSWER","LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER","LOOK_PICTURE_FILL_WORD_HINT","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING","READ_PASSAGE_AND_ANSWER_QUESTIONS"],[E.WRITING]:["WRITE_A_SHORT_LETTER","WRITE_CORRECT_VERB_FORM","WRITE_SENTENCES"]};export function isMarketingQuestionType(E){return Object.values(MARKETING_QUESTION_TYPES_BY_SKILL).flat().includes(E)}export const QUESTION_TYPE_LABELS={LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:"Nghe - Điền từ có hình",LISTEN_AND_TICK_ANSWER:"Nghe - Đánh dấu",LISTEN_AND_FILL_NAME_NUMBER:"Nghe - Điền tên/số",LISTENING_FILL_BLANK:"Nghe - Điền chỗ trống",LISTENING_COLOR:"Nghe - Tô màu",LISTENING:"Nghe",CHOOSE_THE_CORRECT_ANSWER:"Chọn đáp án đúng",CHOOSE_THE_CORRECT_ANSWER_GROUP:"Chọn đáp án đúng (nhóm)",CHOOSE_CORRECT_ADJECTIVE:"Chọn tính từ",FILL_IN_BLANK:"Điền vào chỗ trống",FILL_MISSING_WORDS_IN_GRID:"Điền từ vào lưới",READ_PASSAGE_AND_ANSWER_QUESTIONS:"Đọc hiểu - Trả lời",LABEL_THE_PICTURE:"Gắn nhãn hình ảnh",LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:"Nhìn ảnh - Chọn đáp án",LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:"Nhìn ảnh - Điền và chọn",LOOK_PICTURE_FILL_WORD_HINT:"Nhìn ảnh - Điền từ gợi ý",READ_AND_COLOR_OBJECTS:"Đọc - Tô màu",IMAGE_OBJECT_MATCHING:"Ghép hình ảnh - Đối tượng",TRUE_FALSE:"Đúng/Sai",TRUE_FALSE_GROUP:"Đúng/Sai (nhóm)",CROSS_OUT_WORD_GROUP:"Gạch từ / sửa từ (nhóm)",MATCHING:"Ghép nối",ORDERING:"Sắp xếp",TICK_TRUE_OR_FALSE:"Đánh dấu Đúng/Sai",TICK_YES_OR_NO:"Đánh dấu Có/Không",READING_TICK_CROSS:"Đọc - Đánh dấu",ARRANGE_LETTERS_INTO_WORDS:"Sắp xếp chữ cái thành từ",READ_PASSAGE_AND_COMPLETE_STORY:"Đọc - Hoàn thành câu chuyện",CLOZE_TEST_WITH_TICK_BOX:"Điền từ - Đánh dấu",READ_AND_CHOOSE_APPROPRIATE_WORD:"Đọc - Chọn từ phù hợp",READING_LETTER_ARRANGE:"Đọc - Sắp xếp chữ cái",READING_PASSAGE_FILL:"Đọc - Điền đoạn văn",FILL_BLANK:"Điền chỗ trống",ANSWER_THE_QUESTION:"Nghe - Đọc câu hỏi và viết đáp án",WORD_ORDERING:"Sắp xếp từ",WORD_FILL_PARAGRAPH:"Điền từ vào đoạn văn",MATCH_BY_WRITING_ANSWER:"Ghép đáp án bằng cách viết",WORD_FILL_STRUCTURED_FORM:"Điền từ vào biểu mẫu có cấu trúc",WRITE_A_SHORT_LETTER:"Viết thư",WRITE_CORRECT_VERB_FORM:"Chia động từ",WRITE_SHORT_PARAGRAPH:"Viết đoạn văn ngắn",WRITE_SENTENCES:"Viết câu",ESSAY:"Viết luận",COLORING:"Tô màu",LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:"Nghe và chọn trong nhóm đáp án",LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:"Nghe và chọn đối tượng trong cảnh",LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:"Nghe và kéo thả đối tượng vào cảnh",LISTEN_AND_SPEAK_ANSWER:"Nghe và trả lời (Speaking)",LISTEN_AND_SPEAK_IMAGE_GROUP:"Nghe, nhìn nhóm ảnh và trả lời (Speaking)",LISTEN_AND_SPEAK_QUESTION_LIST:"Nghe, chọn câu hỏi và trả lời (Speaking)",LISTEN_AND_SPEAK_COMPARE_IMAGES:"Nghe và so sánh ảnh (Speaking)",LISTEN_AND_SPEAK_WITH_STORY_IMAGES:"Nghe, nhìn ảnh truyện và kể lại (Speaking)",LISTEN_AND_SPEAK_ODD_ONE_OUT:"Nghe, chọn hình khác loại và giải thích (Speaking)",LISTEN_AND_SPEAK_INFO_EXCHANGE:"Trao đổi thông tin (Speaking)",READ_DISPLAYED_CONTENT:"Đọc nội dung hiển thị (Speaking)",SPEAKING_DESCRIBE_IMAGE:"Nhìn tranh và mô tả (Speaking Part 2)",SPONTANEOUS_QA:"Hỏi đáp tự phát (Speaking Part 3)",SPEAKING_CONVERSATION:"Hội thoại Speaking (KFS Speaking)",GN_SPEAKING_INTERVIEW:"GN Speaking - Hỏi đáp (Virtual + Real)"};export function getQuestionTypeLabel(E){return QUESTION_TYPE_LABELS[E]||E}export const SKILL_METADATA={[E.LISTENING]:{name:"Nghe",emoji:"🎧",color:"text-blue-600",bgColor:"bg-blue-50",borderColor:"border-blue-200",description:"Kỹ năng nghe hiểu"},[E.SPEAKING]:{name:"Nói",emoji:"🗣️",color:"text-green-600",bgColor:"bg-green-50",borderColor:"border-green-200",description:"Kỹ năng giao tiếp"},[E.READING]:{name:"Đọc",emoji:"📖",color:"text-purple-600",bgColor:"bg-purple-50",borderColor:"border-purple-200",description:"Kỹ năng đọc hiểu"},[E.WRITING]:{name:"Viết",emoji:"✏️",color:"text-orange-600",bgColor:"bg-orange-50",borderColor:"border-orange-200",description:"Kỹ năng viết"}};
|
|
1
|
+
import{SkillEnum as E}from"../types/common.types";export const QUESTION_TYPE_SKILLS={LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:E.LISTENING,LISTEN_AND_TICK_ANSWER:E.LISTENING,LISTEN_AND_FILL_NAME_NUMBER:E.LISTENING,LISTENING_FILL_BLANK:E.LISTENING,LISTENING_COLOR:E.LISTENING,LISTENING:E.LISTENING,LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:E.SPEAKING,LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:E.SPEAKING,LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:E.SPEAKING,LISTEN_AND_SPEAK_ANSWER:E.SPEAKING,LISTEN_AND_SPEAK_IMAGE_GROUP:E.SPEAKING,LISTEN_AND_SPEAK_QUESTION_LIST:E.SPEAKING,LISTEN_AND_SPEAK_COMPARE_IMAGES:E.SPEAKING,LISTEN_AND_SPEAK_WITH_STORY_IMAGES:E.SPEAKING,LISTEN_AND_SPEAK_ODD_ONE_OUT:E.SPEAKING,LISTEN_AND_SPEAK_INFO_EXCHANGE:E.SPEAKING,READ_DISPLAYED_CONTENT:E.SPEAKING,SPEAKING_DESCRIBE_IMAGE:E.SPEAKING,SPONTANEOUS_QA:E.SPEAKING,SPEAKING_CONVERSATION:E.SPEAKING,SPEAKING_CUE_CARD:E.SPEAKING,GN_SPEAKING_INTERVIEW:E.SPEAKING,CHOOSE_THE_CORRECT_ANSWER:E.READING,CHOOSE_THE_CORRECT_ANSWER_GROUP:E.READING,CHOOSE_CORRECT_ADJECTIVE:E.READING,FILL_IN_BLANK:E.READING,FILL_MISSING_WORDS_IN_GRID:E.READING,READ_PASSAGE_AND_ANSWER_QUESTIONS:E.READING,ANSWER_THE_QUESTION:E.READING,WORD_ORDERING:E.READING,WORD_FILL_PARAGRAPH:E.READING,MATCH_BY_WRITING_ANSWER:E.READING,LABEL_THE_PICTURE:E.READING,LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:E.READING,LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:E.READING,LOOK_PICTURE_FILL_WORD_HINT:E.READING,READ_AND_COLOR_OBJECTS:E.READING,IMAGE_OBJECT_MATCHING:E.READING,TRUE_FALSE:E.READING,TRUE_FALSE_GROUP:E.READING,CROSS_OUT_WORD_GROUP:E.READING,SPONTANEOUS_QA_GROUP:E.SPEAKING,WORD_ORDER_AND_MATCH_GROUP:E.READING,MATCHING:E.READING,ORDERING:E.READING,TICK_TRUE_OR_FALSE:E.READING,TICK_YES_OR_NO:E.READING,READING_TICK_CROSS:E.READING,ARRANGE_LETTERS_INTO_WORDS:E.READING,READ_PASSAGE_AND_COMPLETE_STORY:E.READING,CLOZE_TEST_WITH_TICK_BOX:E.READING,READ_AND_CHOOSE_APPROPRIATE_WORD:E.READING,READING_LETTER_ARRANGE:E.READING,READING_PASSAGE_FILL:E.READING,FILL_BLANK:E.READING,WORD_FILL_STRUCTURED_FORM:E.READING,WRITE_A_SHORT_LETTER:E.WRITING,WRITE_CORRECT_VERB_FORM:E.WRITING,WRITE_SHORT_PARAGRAPH:E.WRITING,WRITE_SENTENCES:E.WRITING,ESSAY:E.WRITING,COLORING:E.WRITING};export function getQuestionTypeSkill(E){return QUESTION_TYPE_SKILLS[E]||"READING"}export function getQuestionTypesBySkill(E){return Object.entries(QUESTION_TYPE_SKILLS).filter(([_,N])=>N===E).map(([E,_])=>E)}export const QUESTION_TYPES_BY_SKILL={LISTENING:getQuestionTypesBySkill("LISTENING"),SPEAKING:getQuestionTypesBySkill("SPEAKING"),READING:getQuestionTypesBySkill("READING"),WRITING:getQuestionTypesBySkill("WRITING")};export const MARKETING_QUESTION_TYPES_BY_SKILL={[E.LISTENING]:[],[E.SPEAKING]:[],[E.READING]:["CHOOSE_THE_CORRECT_ANSWER","CHOOSE_CORRECT_ADJECTIVE","FILL_IN_BLANK","FILL_MISSING_WORDS_IN_GRID","LABEL_THE_PICTURE","LOOK_PICTURE_CHOOSE_CORRECT_ANSWER","LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER","LOOK_PICTURE_FILL_WORD_HINT","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING","READ_PASSAGE_AND_ANSWER_QUESTIONS"],[E.WRITING]:["WRITE_A_SHORT_LETTER","WRITE_CORRECT_VERB_FORM","WRITE_SENTENCES"]};export function isMarketingQuestionType(E){return Object.values(MARKETING_QUESTION_TYPES_BY_SKILL).flat().includes(E)}export const QUESTION_TYPE_LABELS={LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:"Nghe - Điền từ có hình",LISTEN_AND_TICK_ANSWER:"Nghe - Đánh dấu",LISTEN_AND_FILL_NAME_NUMBER:"Nghe - Điền tên/số",LISTENING_FILL_BLANK:"Nghe - Điền chỗ trống",LISTENING_COLOR:"Nghe - Tô màu",LISTENING:"Nghe",CHOOSE_THE_CORRECT_ANSWER:"Chọn đáp án đúng",CHOOSE_THE_CORRECT_ANSWER_GROUP:"Chọn đáp án đúng (nhóm)",CHOOSE_CORRECT_ADJECTIVE:"Chọn tính từ",FILL_IN_BLANK:"Điền vào chỗ trống",FILL_MISSING_WORDS_IN_GRID:"Điền từ vào lưới",READ_PASSAGE_AND_ANSWER_QUESTIONS:"Đọc hiểu - Trả lời",LABEL_THE_PICTURE:"Gắn nhãn hình ảnh",LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:"Nhìn ảnh - Chọn đáp án",LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:"Nhìn ảnh - Điền và chọn",LOOK_PICTURE_FILL_WORD_HINT:"Nhìn ảnh - Điền từ gợi ý",READ_AND_COLOR_OBJECTS:"Đọc - Tô màu",IMAGE_OBJECT_MATCHING:"Ghép hình ảnh - Đối tượng",TRUE_FALSE:"Đúng/Sai",TRUE_FALSE_GROUP:"Đúng/Sai (nhóm)",CROSS_OUT_WORD_GROUP:"Gạch từ / sửa từ (nhóm)",SPONTANEOUS_QA_GROUP:"Hỏi đáp tự phát (nhóm)",WORD_ORDER_AND_MATCH_GROUP:"Sắp xếp từ và nối nhãn (nhóm)",MATCHING:"Ghép nối",ORDERING:"Sắp xếp",TICK_TRUE_OR_FALSE:"Đánh dấu Đúng/Sai",TICK_YES_OR_NO:"Đánh dấu Có/Không",READING_TICK_CROSS:"Đọc - Đánh dấu",ARRANGE_LETTERS_INTO_WORDS:"Sắp xếp chữ cái thành từ",READ_PASSAGE_AND_COMPLETE_STORY:"Đọc - Hoàn thành câu chuyện",CLOZE_TEST_WITH_TICK_BOX:"Điền từ - Đánh dấu",READ_AND_CHOOSE_APPROPRIATE_WORD:"Đọc - Chọn từ phù hợp",READING_LETTER_ARRANGE:"Đọc - Sắp xếp chữ cái",READING_PASSAGE_FILL:"Đọc - Điền đoạn văn",FILL_BLANK:"Điền chỗ trống",ANSWER_THE_QUESTION:"Nghe - Đọc câu hỏi và viết đáp án",WORD_ORDERING:"Sắp xếp từ",WORD_FILL_PARAGRAPH:"Điền từ vào đoạn văn",MATCH_BY_WRITING_ANSWER:"Ghép đáp án bằng cách viết",WORD_FILL_STRUCTURED_FORM:"Điền từ vào biểu mẫu có cấu trúc",WRITE_A_SHORT_LETTER:"Viết thư",WRITE_CORRECT_VERB_FORM:"Chia động từ",WRITE_SHORT_PARAGRAPH:"Viết đoạn văn ngắn",WRITE_SENTENCES:"Viết câu",ESSAY:"Viết luận",COLORING:"Tô màu",LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:"Nghe và chọn trong nhóm đáp án",LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:"Nghe và chọn đối tượng trong cảnh",LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:"Nghe và kéo thả đối tượng vào cảnh",LISTEN_AND_SPEAK_ANSWER:"Nghe và trả lời (Speaking)",LISTEN_AND_SPEAK_IMAGE_GROUP:"Nghe, nhìn nhóm ảnh và trả lời (Speaking)",LISTEN_AND_SPEAK_QUESTION_LIST:"Nghe, chọn câu hỏi và trả lời (Speaking)",LISTEN_AND_SPEAK_COMPARE_IMAGES:"Nghe và so sánh ảnh (Speaking)",LISTEN_AND_SPEAK_WITH_STORY_IMAGES:"Nghe, nhìn ảnh truyện và kể lại (Speaking)",LISTEN_AND_SPEAK_ODD_ONE_OUT:"Nghe, chọn hình khác loại và giải thích (Speaking)",LISTEN_AND_SPEAK_INFO_EXCHANGE:"Trao đổi thông tin (Speaking)",READ_DISPLAYED_CONTENT:"Đọc nội dung hiển thị (Speaking)",SPEAKING_DESCRIBE_IMAGE:"Nhìn tranh và mô tả (Speaking Part 2)",SPONTANEOUS_QA:"Hỏi đáp tự phát (Speaking Part 3)",SPEAKING_CONVERSATION:"Hội thoại Speaking (KFS Speaking)",GN_SPEAKING_INTERVIEW:"GN Speaking - Hỏi đáp (Virtual + Real)"};export function getQuestionTypeLabel(E){return QUESTION_TYPE_LABELS[E]||E}export const SKILL_METADATA={[E.LISTENING]:{name:"Nghe",emoji:"🎧",color:"text-blue-600",bgColor:"bg-blue-50",borderColor:"border-blue-200",description:"Kỹ năng nghe hiểu"},[E.SPEAKING]:{name:"Nói",emoji:"🗣️",color:"text-green-600",bgColor:"bg-green-50",borderColor:"border-green-200",description:"Kỹ năng giao tiếp"},[E.READING]:{name:"Đọc",emoji:"📖",color:"text-purple-600",bgColor:"bg-purple-50",borderColor:"border-purple-200",description:"Kỹ năng đọc hiểu"},[E.WRITING]:{name:"Viết",emoji:"✏️",color:"text-orange-600",bgColor:"bg-orange-50",borderColor:"border-orange-200",description:"Kỹ năng viết"}};
|
|
@@ -29,7 +29,7 @@ export declare enum StudentSelectionType {
|
|
|
29
29
|
}
|
|
30
30
|
export type ResultStatus = 'PENDING' | 'PARTIAL_GRADED' | 'GRADED';
|
|
31
31
|
export type StudentStatus = 'NOT_STARTED' | 'IN_PROGRESS' | 'SUBMITTED';
|
|
32
|
-
export type QuestionType = 'FILL_IN_BLANK' | 'TRUE_FALSE' | 'MATCHING' | 'ORDERING' | 'LISTENING' | 'COLORING' | 'ESSAY' | 'LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE' | 'LISTEN_AND_TICK_ANSWER' | 'LISTEN_AND_FILL_NAME_NUMBER' | 'LISTENING_FILL_BLANK' | 'LISTENING_COLOR' | 'TICK_TRUE_OR_FALSE' | 'TICK_YES_OR_NO' | 'READING_TICK_CROSS' | 'ARRANGE_LETTERS_INTO_WORDS' | 'READ_PASSAGE_AND_COMPLETE_STORY' | 'CLOZE_TEST_WITH_TICK_BOX' | 'READ_AND_CHOOSE_APPROPRIATE_WORD' | 'WRITE_SHORT_PARAGRAPH' | 'LABEL_THE_PICTURE' | 'READING_LETTER_ARRANGE' | 'READING_PASSAGE_FILL' | 'FILL_BLANK' | 'FILL_MISSING_WORDS_IN_GRID' | 'LOOK_PICTURE_CHOOSE_CORRECT_ANSWER' | 'LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER' | 'LOOK_PICTURE_FILL_WORD_HINT' | 'LABEL_THE_PICTURE' | 'READ_AND_COLOR_OBJECTS' | 'IMAGE_OBJECT_MATCHING' | 'READ_PASSAGE_AND_ANSWER_QUESTIONS' | 'CHOOSE_THE_CORRECT_ANSWER' | 'CHOOSE_THE_CORRECT_ANSWER_GROUP' | 'TRUE_FALSE_GROUP' | 'CROSS_OUT_WORD_GROUP' | 'WRITE_A_SHORT_LETTER' | 'WRITE_CORRECT_VERB_FORM' | 'CHOOSE_CORRECT_ADJECTIVE' | 'ANSWER_THE_QUESTION' | 'WORD_ORDERING' | 'WORD_FILL_PARAGRAPH' | 'MATCH_BY_WRITING_ANSWER' | 'WRITE_SENTENCES' | 'LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP' | 'LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE' | 'LISTEN_AND_DRAG_OBJECTS_INTO_SCENE' | 'LISTEN_AND_SPEAK_ANSWER' | 'LISTEN_AND_SPEAK_IMAGE_GROUP' | 'LISTEN_AND_SPEAK_QUESTION_LIST' | 'LISTEN_AND_SPEAK_COMPARE_IMAGES' | 'LISTEN_AND_SPEAK_WITH_STORY_IMAGES' | 'LISTEN_AND_SPEAK_ODD_ONE_OUT' | 'LISTEN_AND_SPEAK_INFO_EXCHANGE' | 'READ_DISPLAYED_CONTENT' | 'SPEAKING_DESCRIBE_IMAGE' | 'SPONTANEOUS_QA' | 'SPEAKING_CONVERSATION' | 'GN_SPEAKING_INTERVIEW' | 'SPEAKING_CUE_CARD' | 'WORD_FILL_STRUCTURED_FORM';
|
|
32
|
+
export type QuestionType = 'FILL_IN_BLANK' | 'TRUE_FALSE' | 'MATCHING' | 'ORDERING' | 'LISTENING' | 'COLORING' | 'ESSAY' | 'LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE' | 'LISTEN_AND_TICK_ANSWER' | 'LISTEN_AND_FILL_NAME_NUMBER' | 'LISTENING_FILL_BLANK' | 'LISTENING_COLOR' | 'TICK_TRUE_OR_FALSE' | 'TICK_YES_OR_NO' | 'READING_TICK_CROSS' | 'ARRANGE_LETTERS_INTO_WORDS' | 'READ_PASSAGE_AND_COMPLETE_STORY' | 'CLOZE_TEST_WITH_TICK_BOX' | 'READ_AND_CHOOSE_APPROPRIATE_WORD' | 'WRITE_SHORT_PARAGRAPH' | 'LABEL_THE_PICTURE' | 'READING_LETTER_ARRANGE' | 'READING_PASSAGE_FILL' | 'FILL_BLANK' | 'FILL_MISSING_WORDS_IN_GRID' | 'LOOK_PICTURE_CHOOSE_CORRECT_ANSWER' | 'LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER' | 'LOOK_PICTURE_FILL_WORD_HINT' | 'LABEL_THE_PICTURE' | 'READ_AND_COLOR_OBJECTS' | 'IMAGE_OBJECT_MATCHING' | 'READ_PASSAGE_AND_ANSWER_QUESTIONS' | 'CHOOSE_THE_CORRECT_ANSWER' | 'CHOOSE_THE_CORRECT_ANSWER_GROUP' | 'TRUE_FALSE_GROUP' | 'CROSS_OUT_WORD_GROUP' | 'SPONTANEOUS_QA_GROUP' | 'WORD_ORDER_AND_MATCH_GROUP' | 'WRITE_A_SHORT_LETTER' | 'WRITE_CORRECT_VERB_FORM' | 'CHOOSE_CORRECT_ADJECTIVE' | 'ANSWER_THE_QUESTION' | 'WORD_ORDERING' | 'WORD_FILL_PARAGRAPH' | 'MATCH_BY_WRITING_ANSWER' | 'WRITE_SENTENCES' | 'LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP' | 'LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE' | 'LISTEN_AND_DRAG_OBJECTS_INTO_SCENE' | 'LISTEN_AND_SPEAK_ANSWER' | 'LISTEN_AND_SPEAK_IMAGE_GROUP' | 'LISTEN_AND_SPEAK_QUESTION_LIST' | 'LISTEN_AND_SPEAK_COMPARE_IMAGES' | 'LISTEN_AND_SPEAK_WITH_STORY_IMAGES' | 'LISTEN_AND_SPEAK_ODD_ONE_OUT' | 'LISTEN_AND_SPEAK_INFO_EXCHANGE' | 'READ_DISPLAYED_CONTENT' | 'SPEAKING_DESCRIBE_IMAGE' | 'SPONTANEOUS_QA' | 'SPEAKING_CONVERSATION' | 'GN_SPEAKING_INTERVIEW' | 'SPEAKING_CUE_CARD' | 'WORD_FILL_STRUCTURED_FORM';
|
|
33
33
|
export type Level = 'Pre-A1' | 'A1' | 'A2' | 'B1' | 'B2' | 'C1' | 'C2';
|
|
34
34
|
export type Difficulty = 'EASY' | 'MEDIUM' | 'HARD';
|
|
35
35
|
export type Skill = 'LISTENING' | 'READING' | 'WRITING' | 'SPEAKING';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinyweb_dev/oe-exam-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"description": "Reusable OceanEdu question components.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"clean": "rm -rf dist",
|
|
21
21
|
"build:compile": "tsc -p tsconfig.build.json",
|
|
22
22
|
"build:alias": "tsc-alias -p tsconfig.build.json",
|
|
23
|
-
"build:
|
|
23
|
+
"build:check-aliases": "node ./scripts/check-aliases.mjs",
|
|
24
|
+
"build:ts": "npm run build:compile && npm run build:assets && npm run build:alias && npm run build:check-aliases",
|
|
24
25
|
"build:assets": "for d in cambridge-yle english-certification summer-sky; do [ -d src/components/themes/$d/assets ] && cp -R src/components/themes/$d/assets dist/components/themes/$d/ || true; done; [ -d src/components/shared/audio/assets ] && cp -R src/components/shared/audio/assets dist/components/shared/audio/ || true; [ -d src/components/results/report/assets ] && mkdir -p dist/components/results/report && cp -R src/components/results/report/assets dist/components/results/report/ || true; (cd src && find . -name '*.module.css' -exec cp --parents {} ../dist/ \\;); cp src/global.d.ts dist/global.d.ts",
|
|
25
26
|
"minify:js": "find dist -name '*.js' -type f -exec sh -c 'for f do terser \"$f\" --compress directives=false --mangle --module --comments false --output \"$f\"; done' sh {} +",
|
|
26
27
|
"build": "npm run clean && npm run build:ts && npm run minify:js",
|