@tinyweb_dev/oe-exam-sdk 0.1.20 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/result-review.types.d.ts +1 -0
- package/dist/components/exams/ExamPreviewDialog.d.ts +6 -7
- package/dist/components/exams/ExamPreviewDialog.js +1 -1
- package/dist/components/exams/ExamPreviewPartContent.d.ts +18 -0
- package/dist/components/exams/ExamPreviewPartContent.js +1 -0
- package/dist/components/exams/ExamPreviewSidebar.d.ts +17 -0
- package/dist/components/exams/ExamPreviewSidebar.js +1 -0
- package/dist/components/exams/exam-preview.types.d.ts +34 -0
- package/dist/components/exams/exam-preview.types.js +1 -0
- package/dist/components/exams/index.d.ts +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.js +1 -1
- package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.js +1 -1
- package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.js +1 -1
- package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.js +1 -1
- package/dist/components/exams/take/exam-taking.utils.d.ts +13 -0
- package/dist/components/exams/take/exam-taking.utils.js +1 -1
- package/dist/components/exams/take/types.d.ts +3 -0
- package/dist/components/exams/take/utils/question-transformers.d.ts +13 -0
- package/dist/components/exams/take/utils/question-transformers.js +1 -1
- package/dist/components/questions/_shared/types/word-fill-structured-form.type.d.ts +25 -0
- package/dist/components/questions/_shared/utils/parseFillBlankStem.d.ts +30 -0
- package/dist/components/questions/_shared/utils/parseFillBlankStem.js +1 -0
- package/dist/components/questions/index.d.ts +1 -0
- package/dist/components/questions/index.js +1 -1
- package/dist/components/questions/question-bank/EditQuestionBankDialog.d.ts +2 -0
- package/dist/components/questions/question-bank/EditQuestionBankDialog.js +1 -0
- package/dist/components/questions/question-bank/QuestionEditorRenderer.d.ts +23 -0
- package/dist/components/questions/question-bank/QuestionEditorRenderer.js +1 -0
- package/dist/components/questions/question-bank/difficulty.d.ts +15 -0
- package/dist/components/questions/question-bank/difficulty.js +1 -0
- package/dist/components/questions/question-bank/editor-adapters/choice-adapters.d.ts +5 -0
- package/dist/components/questions/question-bank/editor-adapters/choice-adapters.js +1 -0
- package/dist/components/questions/question-bank/editor-adapters/index.d.ts +5 -0
- package/dist/components/questions/question-bank/editor-adapters/index.js +1 -0
- package/dist/components/questions/question-bank/editor-adapters/media-adapters.d.ts +6 -0
- package/dist/components/questions/question-bank/editor-adapters/media-adapters.js +1 -0
- package/dist/components/questions/question-bank/editor-adapters/types.d.ts +1 -0
- package/dist/components/questions/question-bank/editor-adapters/types.js +1 -0
- package/dist/components/questions/question-bank/editor-adapters/unsupported-fallback.d.ts +8 -0
- package/dist/components/questions/question-bank/editor-adapters/unsupported-fallback.js +1 -0
- package/dist/components/questions/question-bank/editor-adapters/writing-adapters.d.ts +5 -0
- package/dist/components/questions/question-bank/editor-adapters/writing-adapters.js +1 -0
- package/dist/components/questions/question-bank/index.d.ts +4 -0
- package/dist/components/questions/question-bank/index.js +1 -0
- package/dist/components/questions/question-bank/types.d.ts +59 -0
- package/dist/components/questions/question-bank/types.js +1 -0
- package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerCreator.js +1 -1
- package/dist/components/questions/types/choose-the-correct-answer/index.d.ts +1 -0
- package/dist/components/questions/types/choose-the-correct-answer/index.js +1 -1
- package/dist/components/questions/types/choose-the-correct-answer/normalize.d.ts +27 -0
- package/dist/components/questions/types/choose-the-correct-answer/normalize.js +1 -0
- package/dist/components/questions/types/choose-the-correct-answer/register.js +1 -1
- package/dist/components/questions/types/fill-in-blank/FillInBlankCreator.js +1 -1
- package/dist/components/questions/types/fill-in-blank/register.js +1 -1
- package/dist/components/questions/types/fill-in-blank/transform.js +1 -1
- package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormClient.d.ts +1 -1
- package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormClient.js +1 -1
- package/dist/components/questions/types/word-fill-structured-form/transform.js +1 -1
- package/dist/components/questions/viewer/QuestionViewer.js +1 -1
- package/dist/components/results/review-data.js +1 -1
- package/dist/components/themes/cambridge-yle/CambridgeYleAudioPlayer.d.ts +2 -1
- package/dist/components/themes/cambridge-yle/CambridgeYleAudioPlayer.js +1 -1
- package/dist/components/themes/english-certification/EcWordFillStructuredForm.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/shared/lib/i18n/messages/en/admin.d.ts +11 -1
- package/dist/shared/lib/i18n/messages/en/admin.js +1 -1
- package/dist/shared/lib/i18n/messages/en.d.ts +11 -1
- package/dist/shared/lib/i18n/messages/vi/admin.d.ts +11 -1
- package/dist/shared/lib/i18n/messages/vi/admin.js +1 -1
- package/dist/shared/lib/i18n/messages/vi.d.ts +11 -1
- package/package.json +1 -1
|
@@ -10,11 +10,10 @@ export interface ExamPreviewDialogProps {
|
|
|
10
10
|
title?: string;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Read-only popup that previews an exam
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* in review mode (correct answers highlighted).
|
|
13
|
+
* Read-only popup that previews an exam by id.
|
|
14
|
+
*
|
|
15
|
+
* UI mirrors the host app: one Part per screen (all questions of that part),
|
|
16
|
+
* Next/Prev navigates between parts. No attempt is created — data comes from
|
|
17
|
+
* {@link ExamQuestionsSdkApi}. Questions render via QuestionViewer in review mode.
|
|
19
18
|
*/
|
|
20
|
-
export declare function ExamPreviewDialog({ open, onOpenChange, examId, api, title }: ExamPreviewDialogProps): import("react").JSX.Element;
|
|
19
|
+
export declare function ExamPreviewDialog({ open, onOpenChange, examId, api, title, }: ExamPreviewDialogProps): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useEffect as a,useMemo as n,useRef as i,useState as s}from"react";import{ArrowLeft as r,ArrowRight as l,Eye as d,Loader2 as m}from"lucide-react";import{Badge as c}from"../../components/ui/badge";import{Button as o}from"../../components/ui/button";import{Card as p,CardContent as x,CardHeader as u,CardTitle as h}from"../../components/ui/card";import{Dialog as g,DialogContent as f,DialogHeader as N,DialogTitle as v}from"../../components/ui/dialog";import{Progress as b}from"../../components/ui/progress";import{useT as y}from"../../shared/lib/i18n";import{QuestionViewer as w}from"../questions/viewer/QuestionViewer";function j(e){return e&&"object"==typeof e&&"data"in e?e.data:e}function I(e){switch(e?.toUpperCase()){case"EASY":return"bg-green-100 text-green-800";case"MEDIUM":return"bg-orange-100 text-orange-800";case"HARD":return"bg-red-100 text-red-800";default:return"bg-gray-100 text-gray-800"}}export function ExamPreviewDialog({open:q,onOpenChange:S,examId:C,api:Q,title:k}){const E=y(),[P,z]=s(null),[A,M]=s([]),[$,D]=s(0),[T,O]=s("all"),[R,U]=s(!1),[H,V]=s(!1),[Y,B]=s(null),[F,G]=s(0),J=i(null);a(()=>{if(!q||!C)return;let e=!1;return V(!0),B(null),D(0),O("all"),(async()=>{try{const t=j(await Q.getExam(C)),a=Q.getQuestions?j(await Q.getQuestions(C)):[];if(e)return;const n=[...a].sort((e,t)=>(e.questionNumber??0)-(t.questionNumber??0));z(t),M(n)}catch{e||B(E("admin.exams.preview.loadError"))}finally{e||V(!1)}})(),()=>{e=!0}},[q,C,F,Q,E]),a(()=>{q||(z(null),M([]),D(0),O("all"),U(!1),B(null))},[q]);const K=n(()=>{const e=(P?.template?.parts??[]).map(e=>({id:e.id,name:e.name||e.title})),t=new Set(e.map(e=>e.id));for(const a of A){const n=a.partId??"";n&&!t.has(n)&&(t.add(n),e.push({id:n}))}return e},[P,A]),L=e=>{const t=K.findIndex(t=>t.id===(e??""));return t>=0?t+1:1},W=n(()=>{const e=new Map;for(const t of A){const a=t.partId??"";if(!e.has(a)){const t=K.findIndex(e=>e.id===a),n=t>=0?t+1:1;e.set(a,{partId:a,partNo:n,partName:K[t]?.name||`Part ${n}`,questions:[]})}e.get(a).questions.push(t)}return Array.from(e.values()).sort((e,t)=>e.partNo-t.partNo)},[A,K]),X=P?.name??k??"",Z=P?.template?.totalTime??P?.duration??0,_=function(e){return e.reduce((e,t)=>e+(Number(t.points)||0),0)}(A),ee=A[$],te=A.length>0?($+1)/A.length*100:0,ae=e=>{D(e),J.current?.scrollTo({top:0,behavior:"smooth"})},ne="all"===T?A:A.filter(e=>L(e.partId)===T);return e(g,{open:q,onOpenChange:S,children:t(f,{className:"max-h-[95vh] max-w-7xl overflow-y-auto",children:[e(N,{children:t(v,{className:"flex items-center gap-2",children:[e(d,{className:"h-5 w-5 text-blue-600"}),E("admin.exams.preview.title",{name:X})]})}),t("div",{className:"flex h-[80vh] flex-col gap-4 sm:flex-row",children:[e("div",{className:"w-full overflow-y-auto border-b border-gray-200 sm:w-80 sm:border-b-0 sm:border-r",children:t("div",{className:"space-y-4 p-4",children:[t(p,{children:[e(u,{className:"pb-3",children:e(h,{className:"text-base",children:E("admin.exams.preview.examInfo")})}),t(x,{className:"space-y-3",children:[t("div",{className:"flex items-center justify-between",children:[e("span",{className:"text-sm text-gray-600",children:E("admin.exams.preview.duration")}),e("span",{className:"text-sm font-medium",children:E("admin.exams.view.minutes",{count:String(Z)})})]}),t("div",{className:"flex items-center justify-between",children:[e("span",{className:"text-sm text-gray-600",children:E("admin.exams.preview.questionCount")}),e("span",{className:"text-sm font-medium",children:H?"...":E("admin.exams.preview.questions",{count:String(A.length)})})]}),t("div",{className:"flex items-center justify-between",children:[e("span",{className:"text-sm text-gray-600",children:E("admin.exams.preview.totalPoints")}),e("span",{className:"text-sm font-medium",children:E("admin.exams.preview.points",{count:String(_)})})]})]})]}),!H&&A.length>0&&e(p,{children:e(x,{className:"p-4",children:t("div",{className:"space-y-2",children:[t("div",{className:"flex justify-between text-sm",children:[e("span",{children:E("admin.exams.preview.progress")}),t("span",{className:"font-medium",children:[$+1,"/",A.length]})]}),e(b,{value:te,className:"h-2"})]})})}),H?e("div",{className:"flex items-center justify-center py-4",children:t("div",{className:"flex items-center gap-2 text-gray-500",children:[e(m,{className:"h-4 w-4 animate-spin"}),e("span",{className:"text-sm",children:E("admin.exams.preview.loading")})]})}):A.length>0&&t("div",{className:"space-y-3",children:[e("h4",{className:"text-sm font-medium text-gray-700",children:E("admin.exams.preview.questionNavigation")}),t("div",{className:"flex flex-wrap gap-2",children:[e(o,{variant:"all"===T?"default":"outline",size:"sm",onClick:()=>O("all"),className:"h-8 px-3 text-xs font-medium",children:E("admin.exams.preview.all")}),W.map(e=>t(o,{variant:T===e.partNo?"default":"outline",size:"sm",onClick:()=>{O(e.partNo);const t=e.questions[0];if(t){const e=A.findIndex(e=>e.id===t.id);-1!==e&&ae(e)}},className:"h-8 px-3 text-xs font-medium",children:["P",e.partNo]},e.partId||`part-${e.partNo}`))]}),e("div",{className:"rounded bg-gray-50 p-2 text-xs",children:e("span",{className:"font-medium",children:"all"===T?E("admin.exams.preview.allQuestions",{count:String(A.length)}):E("admin.exams.preview.partQuestions",{part:String(T),count:String(W.find(e=>e.partNo===T)?.questions.length??0)})})}),e("div",{className:"rounded-lg bg-gray-50 p-3",children:e("div",{className:"grid max-h-64 grid-cols-6 gap-2 overflow-y-auto pr-2",children:ne.map(t=>{const a=A.findIndex(e=>e.id===t.id);return e(o,{variant:"ghost",size:"sm",onClick:()=>ae(a),className:"h-8 w-full p-0 text-xs font-medium transition-all duration-200 "+(a===$?"border-2 border-blue-500 bg-blue-500 text-white hover:bg-blue-600":"border border-gray-300 bg-white hover:bg-gray-100"),children:t.questionNumber},t.id)})})})]}),!H&&A.length>0&&t("div",{children:[t("div",{className:"mb-2 flex items-center justify-between",children:[e("h4",{className:"text-sm font-medium text-gray-700",children:X}),e(o,{variant:"ghost",size:"sm",onClick:()=>U(e=>!e),className:"h-6 px-2 text-xs text-gray-600 hover:text-gray-900",children:E(R?"admin.exams.preview.collapse":"admin.exams.preview.detail")})]}),e("div",{className:"rounded-lg bg-gray-50 p-3",children:t("div",{className:"flex items-center justify-between",children:[t("div",{children:[t("span",{className:"text-sm font-medium text-gray-900",children:["Total: ",E("admin.exams.preview.questions",{count:String(A.length)})]}),e("div",{className:"mt-1 flex gap-3",children:t("span",{className:"text-xs text-gray-600",children:[W.length," part(s)"]})})]}),e("div",{className:"text-xs text-gray-500",children:E("admin.exams.view.minutes",{count:String(Z)})})]})}),R&&e("div",{className:"mt-3 space-y-2",children:W.map(a=>{const n=L(ee?.partId)===a.partNo;return e("div",{className:"cursor-pointer rounded-lg border-2 p-3 transition-all duration-200 "+(n?"border-blue-400 bg-blue-50 shadow-md":"border-gray-200 bg-white hover:border-gray-300"),onClick:()=>{const e=a.questions[0];if(e){const t=A.findIndex(t=>t.id===e.id);-1!==t&&(ae(t),O(a.partNo))}},children:t("div",{className:"flex items-center justify-between",children:[e("span",{className:"text-sm font-medium "+(n?"text-blue-900":"text-gray-900"),children:a.partName}),e(c,{variant:"secondary",className:"text-xs "+(n?"bg-blue-200 text-blue-800":"bg-gray-100 text-gray-700"),children:E("admin.exams.preview.questions",{count:String(a.questions.length)})})]})},a.partId||`part-${a.partNo}`)})})]})]})}),e("div",{className:"flex-1 overflow-y-auto",children:t("div",{className:"flex h-full flex-col",children:[t("div",{className:"flex items-center justify-between border-b pb-4",children:[t("div",{children:[e("h3",{className:"text-lg font-semibold",children:H?e("span",{className:"text-gray-400",children:E("admin.exams.preview.loading")}):A.length>0?E("admin.exams.preview.questionIndex",{index:String($+1),total:String(A.length)}):E("admin.exams.preview.noQuestions")}),ee&&e("div",{className:"mt-1 inline-flex items-center gap-2 rounded-lg border border-blue-200 bg-blue-50 px-3 py-1.5",children:e("span",{className:"text-sm font-semibold text-blue-700",children:(e=>{const t=K.findIndex(t=>t.id===(e??""));return K[t]?.name||`Part ${t>=0?t+1:1}`})(ee.partId)})})]}),ee&&t("div",{className:"flex items-center gap-2",children:[e(c,{variant:"outline",children:E("admin.exams.preview.points",{count:String(Number(ee.points)||1)})}),e(c,{className:I(ee.difficulty),children:ee.difficulty??"N/A"})]})]}),e("div",{ref:J,className:"flex-1 overflow-y-auto py-4",children:H?t("div",{className:"flex flex-col items-center justify-center space-y-4 py-12",children:[e(m,{className:"h-8 w-8 animate-spin text-blue-500"}),e("p",{className:"text-gray-600",children:E("admin.exams.preview.loadingQuestions")})]}):Y?e("div",{className:"flex flex-col items-center justify-center space-y-4 py-12",children:t("div",{className:"rounded-lg border border-red-200 bg-red-50 p-6 text-center",children:[e("p",{className:"font-medium text-red-800",children:Y}),e(o,{variant:"outline",onClick:()=>G(e=>e+1),className:"mt-4",children:E("admin.exams.preview.retry")})]})}):0===A.length?e("div",{className:"flex flex-col items-center justify-center space-y-4 py-12",children:e("div",{className:"rounded-lg border border-yellow-200 bg-yellow-50 p-6 text-center",children:e("p",{className:"font-medium text-yellow-800",children:E("admin.exams.preview.examNoQuestions")})})}):ee?e(w,{question:ee,isReviewMode:!0}):null}),!H&&A.length>0&&t("div",{className:"mt-auto flex items-center justify-between border-t border-gray-200 bg-gray-50 px-4 py-3",children:[t(o,{variant:"outline",onClick:()=>{$>0&&ae($-1)},disabled:0===$,className:"flex h-9 items-center gap-2 px-3 text-sm",children:[e(r,{className:"h-4 w-4"}),e("span",{className:"hidden sm:inline",children:E("admin.exams.preview.prevQuestion")}),e("span",{className:"sm:hidden",children:E("admin.exams.preview.prev")})]}),t("div",{className:"text-sm text-gray-600",children:[$+1," / ",A.length]}),t(o,{variant:"outline",onClick:()=>{$<A.length-1&&ae($+1)},disabled:$===A.length-1,className:"flex h-9 items-center gap-2 px-3 text-sm",children:[e("span",{className:"hidden sm:inline",children:E("admin.exams.preview.nextQuestion")}),e("span",{className:"sm:hidden",children:E("admin.exams.preview.next")}),e(l,{className:"h-4 w-4"})]})]})]})})]}),e("div",{className:"border-t pt-4",children:t("div",{className:"flex items-center justify-between",children:[e("div",{className:"text-sm text-gray-600",children:E("admin.exams.preview.footerNote")}),e(o,{variant:"outline",onClick:()=>S(!1),className:"border-gray-300",children:E("admin.exams.preview.close")})]})})]})})}
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useEffect as r,useMemo as a,useRef as n,useState as o}from"react";import{Eye as i}from"lucide-react";import{Button as l}from"../../components/ui/button";import{Dialog as s,DialogContent as m,DialogHeader as c,DialogTitle as u}from"../../components/ui/dialog";import{useT as p}from"../../shared/lib/i18n";import{ExamPreviewPartContent as d}from"./ExamPreviewPartContent";import{ExamPreviewSidebar as x}from"./ExamPreviewSidebar";import{buildOrderedParts as h,getQuestionNumber as f,getQuestionPoints as g,groupQuestionsByPart as P,sumQuestionPoints as v,unwrapApiData as w}from"./exam-preview.types";export function ExamPreviewDialog({open:N,onOpenChange:y,examId:b,api:E,title:T}){const j=p(),[q,C]=o(null),[D,I]=o([]),[Q,O]=o(0),[R,k]=o(!1),[B,G]=o(!1),[S,z]=o(null),[A,F]=o(0),H=n(null);r(()=>{if(!N||!b)return;let e=!1;return G(!0),z(null),O(0),(async()=>{try{const t=w(await E.getExam(b)),r=E.getQuestions?w(await E.getQuestions(b)):[];if(e)return;const a=[...r].sort((e,t)=>f(e)-f(t));C(t),I(a)}catch{e||z(j("admin.exams.preview.loadError"))}finally{e||G(!1)}})(),()=>{e=!0}},[N,b,A,E,j]),r(()=>{N||(C(null),I([]),O(0),k(!1),z(null))},[N]);const J=a(()=>h(q?.template?.parts??[],D),[q,D]),K=a(()=>P(D,J),[D,J]);r(()=>{0!==K.length?Q>K.length-1&&O(K.length-1):0!==Q&&O(0)},[Q,K.length]);const L=q?.name??T??"",M=q?.template?.totalTime??q?.duration??0,U=v(D),V=K[Q]??null,W=V?.questions??[],X=K.length,Y=X>0?(Q+1)/X*100:0,Z=V?.partName??"",$=W.reduce((e,t)=>e+g(t),0),_=()=>{H.current?.scrollTo({top:0,behavior:"smooth"})};return e(s,{open:N,onOpenChange:y,children:t(m,{className:"max-h-[95vh] max-w-7xl overflow-y-auto",children:[e(c,{children:t(u,{className:"flex items-center gap-2",children:[e(i,{className:"h-5 w-5 text-blue-600"}),j("admin.exams.preview.title",{name:L})]})}),t("div",{className:"flex h-[80vh] flex-col gap-4 sm:flex-row",children:[e(x,{examName:L,duration:M,totalPoints:U,questions:D,questionsByPart:K,currentPart:V,currentPartIndex:Q,totalParts:X,progress:Y,loading:B,showPartsDetail:R,onTogglePartsDetail:()=>k(e=>!e),onGoToPart:e=>{e<0||e>=X||(O(e),_())}}),e(d,{loading:B,error:S,questions:D,currentPart:V,currentPartQuestions:W,currentPartIndex:Q,totalParts:X,partDisplayName:Z,partTotalPoints:$,contentRef:H,onRetry:()=>F(e=>e+1),onPreviousPart:()=>{Q>0&&(O(Q-1),_())},onNextPart:()=>{Q<X-1&&(O(Q+1),_())}})]}),e("div",{className:"border-t pt-4",children:t("div",{className:"flex items-center justify-between",children:[e("div",{className:"text-sm text-gray-600",children:j("admin.exams.preview.footerNote")}),e(l,{variant:"outline",onClick:()=>y(!1),className:"border-gray-300",children:j("admin.exams.preview.close")})]})})]})})}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
import { type PreviewQuestion, type QuestionsByPart } from './exam-preview.types';
|
|
3
|
+
export interface ExamPreviewPartContentProps {
|
|
4
|
+
loading: boolean;
|
|
5
|
+
error: string | null;
|
|
6
|
+
questions: PreviewQuestion[];
|
|
7
|
+
currentPart: QuestionsByPart | null;
|
|
8
|
+
currentPartQuestions: PreviewQuestion[];
|
|
9
|
+
currentPartIndex: number;
|
|
10
|
+
totalParts: number;
|
|
11
|
+
partDisplayName: string;
|
|
12
|
+
partTotalPoints: number;
|
|
13
|
+
contentRef: RefObject<HTMLDivElement | null>;
|
|
14
|
+
onRetry: () => void;
|
|
15
|
+
onPreviousPart: () => void;
|
|
16
|
+
onNextPart: () => void;
|
|
17
|
+
}
|
|
18
|
+
export declare function ExamPreviewPartContent({ loading, error, questions, currentPart, currentPartQuestions, currentPartIndex, totalParts, partDisplayName, partTotalPoints, contentRef, onRetry, onPreviousPart, onNextPart, }: ExamPreviewPartContentProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as i}from"react/jsx-runtime";import{ArrowLeft as r,ArrowRight as n,Loader2 as t}from"lucide-react";import{Badge as a}from"../../components/ui/badge";import{Button as s}from"../../components/ui/button";import{QuestionViewer as l}from"../questions/viewer/QuestionViewer";import{useT as d}from"../../shared/lib/i18n";import{difficultyBadgeClass as m,getQuestionDifficulty as c,getQuestionNumber as o,getQuestionPoints as p}from"./exam-preview.types";export function ExamPreviewPartContent({loading:x,error:u,questions:h,currentPart:v,currentPartQuestions:b,currentPartIndex:f,totalParts:N,partDisplayName:g,partTotalPoints:w,contentRef:y,onRetry:P,onPreviousPart:j,onNextPart:q}){const S=d();return e("div",{className:"flex-1 overflow-y-auto",children:i("div",{className:"flex h-full flex-col",children:[i("div",{className:"flex items-center justify-between border-b pb-4",children:[i("div",{children:[e("h3",{className:"text-lg font-semibold",children:x?e("span",{className:"text-gray-400",children:S("admin.exams.preview.loading")}):N>0?S("admin.exams.preview.partIndex",{index:String(f+1),total:String(N)}):S("admin.exams.preview.noQuestions")}),v&&i("div",{className:"mt-1 inline-flex items-center gap-2 rounded-lg border border-blue-200 bg-blue-50 px-3 py-1.5",children:[e("span",{className:"text-sm font-semibold text-blue-700",children:g}),e("span",{className:"text-xs text-blue-600",children:S("admin.exams.preview.questions",{count:String(b.length)})})]})]}),v&&e("div",{className:"flex items-center gap-2",children:e(a,{variant:"outline",children:S("admin.exams.preview.points",{count:String(w)})})})]}),e("div",{ref:y,className:"flex-1 overflow-y-auto py-4",children:x?i("div",{className:"flex flex-col items-center justify-center space-y-4 py-12",children:[e(t,{className:"h-8 w-8 animate-spin text-blue-500"}),e("p",{className:"text-gray-600",children:S("admin.exams.preview.loadingQuestions")})]}):u?e("div",{className:"flex flex-col items-center justify-center space-y-4 py-12",children:i("div",{className:"rounded-lg border border-red-200 bg-red-50 p-6 text-center",children:[e("p",{className:"font-medium text-red-800",children:u}),e(s,{variant:"outline",onClick:P,className:"mt-4",children:S("admin.exams.preview.retry")})]})}):0===h.length?e("div",{className:"flex flex-col items-center justify-center space-y-4 py-12",children:e("div",{className:"rounded-lg border border-yellow-200 bg-yellow-50 p-6 text-center",children:e("p",{className:"font-medium text-yellow-800",children:S("admin.exams.preview.examNoQuestions")})})}):b.length>0?e("div",{className:"space-y-6",children:b.map(r=>{const n=o(r),t=c(r);return i("div",{id:`preview-q-${r.id}`,className:"rounded-xl border border-gray-200 bg-white p-4 shadow-sm",children:[i("div",{className:"mb-3 flex items-center justify-between gap-2 border-b border-gray-100 pb-3",children:[e("span",{className:"inline-flex h-7 min-w-7 items-center justify-center rounded-md bg-blue-100 px-2 text-xs font-bold text-blue-700",children:S("admin.exams.preview.questionLabel",{number:String(n)})}),i("div",{className:"flex items-center gap-2",children:[e(a,{variant:"outline",children:S("admin.exams.preview.points",{count:String(p(r))})}),e(a,{className:m(t),children:t})]})]}),e(l,{question:r,isReviewMode:!0})]},r.id)})}):null}),!x&&N>0&&i("div",{className:"mt-auto flex items-center justify-between border-t border-gray-200 bg-gray-50 px-4 py-3",children:[i(s,{variant:"outline",onClick:j,disabled:0===f,className:"flex h-9 items-center gap-2 px-3 text-sm",children:[e(r,{className:"h-4 w-4"}),e("span",{className:"hidden sm:inline",children:S("admin.exams.preview.prevPart")}),e("span",{className:"sm:hidden",children:S("admin.exams.preview.prev")})]}),i("div",{className:"text-sm text-gray-600",children:[f+1," / ",N]}),i(s,{variant:"outline",onClick:q,disabled:f===N-1,className:"flex h-9 items-center gap-2 px-3 text-sm",children:[e("span",{className:"hidden sm:inline",children:S("admin.exams.preview.nextPart")}),e("span",{className:"sm:hidden",children:S("admin.exams.preview.next")}),e(n,{className:"h-4 w-4"})]})]})]})})}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type PreviewQuestion, type QuestionsByPart } from './exam-preview.types';
|
|
2
|
+
export interface ExamPreviewSidebarProps {
|
|
3
|
+
examName: string;
|
|
4
|
+
duration: number;
|
|
5
|
+
totalPoints: number;
|
|
6
|
+
questions: PreviewQuestion[];
|
|
7
|
+
questionsByPart: QuestionsByPart[];
|
|
8
|
+
currentPart: QuestionsByPart | null;
|
|
9
|
+
currentPartIndex: number;
|
|
10
|
+
totalParts: number;
|
|
11
|
+
progress: number;
|
|
12
|
+
loading: boolean;
|
|
13
|
+
showPartsDetail: boolean;
|
|
14
|
+
onTogglePartsDetail: () => void;
|
|
15
|
+
onGoToPart: (index: number) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function ExamPreviewSidebar({ examName, duration, totalPoints, questions, questionsByPart, currentPart, currentPartIndex, totalParts, progress, loading, showPartsDetail, onTogglePartsDetail, onGoToPart, }: ExamPreviewSidebarProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Badge as t}from"../../components/ui/badge";import{Button as s}from"../../components/ui/button";import{Card as i,CardContent as r,CardHeader as n,CardTitle as m}from"../../components/ui/card";import{Progress as l}from"../../components/ui/progress";import{Loader2 as d}from"lucide-react";import{useT as c}from"../../shared/lib/i18n";import{getQuestionNumber as o}from"./exam-preview.types";export function ExamPreviewSidebar({examName:p,duration:x,totalPoints:h,questions:u,questionsByPart:g,currentPart:v,currentPartIndex:N,totalParts:f,progress:b,loading:y,showPartsDetail:w,onTogglePartsDetail:j,onGoToPart:q}){const P=c();return e("div",{className:"w-full overflow-y-auto border-b border-gray-200 sm:w-80 sm:border-b-0 sm:border-r",children:a("div",{className:"space-y-4 p-4",children:[a(i,{children:[e(n,{className:"pb-3",children:e(m,{className:"text-base",children:P("admin.exams.preview.examInfo")})}),a(r,{className:"space-y-3",children:[a("div",{className:"flex items-center justify-between",children:[e("span",{className:"text-sm text-gray-600",children:P("admin.exams.preview.duration")}),e("span",{className:"text-sm font-medium",children:P("admin.exams.view.minutes",{count:String(x)})})]}),a("div",{className:"flex items-center justify-between",children:[e("span",{className:"text-sm text-gray-600",children:P("admin.exams.preview.questionCount")}),e("span",{className:"text-sm font-medium",children:y?"...":P("admin.exams.preview.questions",{count:String(u.length)})})]}),a("div",{className:"flex items-center justify-between",children:[e("span",{className:"text-sm text-gray-600",children:P("admin.exams.preview.totalPoints")}),e("span",{className:"text-sm font-medium",children:P("admin.exams.preview.points",{count:String(h)})})]})]})]}),!y&&f>0&&e(i,{children:e(r,{className:"p-4",children:a("div",{className:"space-y-2",children:[a("div",{className:"flex justify-between text-sm",children:[e("span",{children:P("admin.exams.preview.progress")}),a("span",{className:"font-medium",children:[N+1,"/",f]})]}),e(l,{value:b,className:"h-2"})]})})}),y?e("div",{className:"flex items-center justify-center py-4",children:a("div",{className:"flex items-center gap-2 text-gray-500",children:[e(d,{className:"h-4 w-4 animate-spin"}),e("span",{className:"text-sm",children:P("admin.exams.preview.loading")})]})}):f>0&&a("div",{className:"space-y-3",children:[e("h4",{className:"text-sm font-medium text-gray-700",children:P("admin.exams.preview.questionNavigation")}),e("div",{className:"flex flex-wrap gap-2",children:g.map((e,t)=>a(s,{variant:t===N?"default":"outline",size:"sm",onClick:()=>q(t),className:"h-8 px-3 text-xs font-medium",children:["P",e.partNo]},e.partId||`part-${e.partNo}`))}),v&&e("div",{className:"rounded bg-gray-50 p-2 text-xs",children:e("span",{className:"font-medium",children:P("admin.exams.preview.partQuestions",{part:String(v.partNo),count:String(v.questions.length)})})}),v&&e("div",{className:"rounded-lg bg-gray-50 p-3",children:e("div",{className:"grid max-h-64 grid-cols-6 gap-2 overflow-y-auto pr-2",children:v.questions.map(a=>e(s,{variant:"ghost",size:"sm",onClick:()=>{const e=document.getElementById(`preview-q-${a.id}`);e?.scrollIntoView({behavior:"smooth",block:"start"})},className:"h-8 w-full border border-gray-300 bg-white p-0 text-xs font-medium transition-all duration-200 hover:bg-gray-100",children:o(a)},a.id))})})]}),!y&&u.length>0&&a("div",{children:[a("div",{className:"mb-2 flex items-center justify-between",children:[e("h4",{className:"text-sm font-medium text-gray-700",children:p}),e(s,{variant:"ghost",size:"sm",onClick:j,className:"h-6 px-2 text-xs text-gray-600 hover:text-gray-900",children:P(w?"admin.exams.preview.collapse":"admin.exams.preview.detail")})]}),e("div",{className:"rounded-lg bg-gray-50 p-3",children:a("div",{className:"flex items-center justify-between",children:[a("div",{children:[a("span",{className:"text-sm font-medium text-gray-900",children:["Total:"," ",P("admin.exams.preview.questions",{count:String(u.length)})]}),e("div",{className:"mt-1 flex gap-3",children:a("span",{className:"text-xs text-gray-600",children:[g.length," part(s)"]})})]}),e("div",{className:"text-xs text-gray-500",children:P("admin.exams.view.minutes",{count:String(x)})})]})}),w&&e("div",{className:"mt-3 space-y-2",children:g.map((s,i)=>{const r=i===N;return e("div",{className:"cursor-pointer rounded-lg border-2 p-3 transition-all duration-200 "+(r?"border-blue-400 bg-blue-50 shadow-md":"border-gray-200 bg-white hover:border-gray-300"),onClick:()=>q(i),children:a("div",{className:"flex items-center justify-between",children:[e("span",{className:"text-sm font-medium "+(r?"text-blue-900":"text-gray-900"),children:s.partName}),e(t,{variant:"secondary",className:"text-xs "+(r?"bg-blue-200 text-blue-800":"bg-gray-100 text-gray-700"),children:P("admin.exams.preview.questions",{count:String(s.questions.length)})})]})},s.partId||`part-detail-${s.partNo}`)})})]})]})})}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ExamPart, ExamQuestion } from '../../shared/types/entities/exam.types';
|
|
2
|
+
export type PreviewQuestion = Partial<ExamQuestion> & {
|
|
3
|
+
id?: string;
|
|
4
|
+
partId?: string;
|
|
5
|
+
questionNumber?: number;
|
|
6
|
+
points?: number | string;
|
|
7
|
+
difficulty?: string;
|
|
8
|
+
};
|
|
9
|
+
export interface QuestionsByPart {
|
|
10
|
+
partId: string;
|
|
11
|
+
partNo: number;
|
|
12
|
+
partName: string;
|
|
13
|
+
questions: PreviewQuestion[];
|
|
14
|
+
}
|
|
15
|
+
export interface OrderedPart {
|
|
16
|
+
id: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
}
|
|
19
|
+
/** SDK fetch helpers return either `{ data: T }` or the bare value. */
|
|
20
|
+
export declare function unwrapApiData<T>(res: {
|
|
21
|
+
data: T;
|
|
22
|
+
} | T): T;
|
|
23
|
+
export declare function sumQuestionPoints(questions: PreviewQuestion[]): number;
|
|
24
|
+
export declare function getQuestionPoints(question: PreviewQuestion): number;
|
|
25
|
+
export declare function getQuestionNumber(question: PreviewQuestion): number;
|
|
26
|
+
export declare function getQuestionDifficulty(question: PreviewQuestion): string;
|
|
27
|
+
export declare function difficultyBadgeClass(difficulty?: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Build ordered parts from template first, then any extra part ids on questions.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildOrderedParts(templateParts: Array<ExamPart & {
|
|
32
|
+
title?: string;
|
|
33
|
+
}> | undefined, questions: PreviewQuestion[]): OrderedPart[];
|
|
34
|
+
export declare function groupQuestionsByPart(questions: PreviewQuestion[], orderedParts: OrderedPart[]): QuestionsByPart[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function unwrapApiData(t){return t&&"object"==typeof t&&"data"in t?t.data:t}export function sumQuestionPoints(t){return t.reduce((t,e)=>t+(Number(e.points)||0),0)}export function getQuestionPoints(t){return Number(t.points)||1}export function getQuestionNumber(t){return t.questionNumber??0}export function getQuestionDifficulty(t){return t.difficulty??"N/A"}export function difficultyBadgeClass(t){switch(t?.toUpperCase()){case"EASY":return"bg-green-100 text-green-800";case"MEDIUM":return"bg-orange-100 text-orange-800";case"HARD":return"bg-red-100 text-red-800";default:return"bg-gray-100 text-gray-800"}}export function buildOrderedParts(t,e){const r=(t??[]).map(t=>({id:t.id,name:t.name||t.title})),n=new Set(r.map(t=>t.id));for(const t of e){const e=t.partId??"";e&&!n.has(e)&&(n.add(e),r.push({id:e}))}return r}export function groupQuestionsByPart(t,e){const r=new Map;for(const n of t){const t=n.partId??"";if(!r.has(t)){const n=e.findIndex(e=>e.id===t),o=n>=0?n+1:1;r.set(t,{partId:t,partNo:o,partName:e[n]?.name||`Part ${o}`,questions:[]})}r.get(t).questions.push(n)}return Array.from(r.values()).sort((t,e)=>t.partNo-e.partNo)}
|
|
@@ -32,4 +32,5 @@ export { EXAM_DIFFICULTY, ExamViewDialog } from './ExamViewDialog';
|
|
|
32
32
|
export type { ExamDifficulty, ExamViewDialogExam, ExamViewDialogProps } from './ExamViewDialog';
|
|
33
33
|
export { ExamPreviewDialog } from './ExamPreviewDialog';
|
|
34
34
|
export type { ExamPreviewDialogProps } from './ExamPreviewDialog';
|
|
35
|
+
export type { PreviewQuestion, QuestionsByPart } from './exam-preview.types';
|
|
35
36
|
export { QuestionStatus, clearQuestionStatuses, getQuestionStatus, initializeQuestionStatusesFromAPI, setQuestionStatus } from './exam-question-status';
|
package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import{ZoomIn as n}from"lucide-react";import{useState as l}from"react";import{cn as o}from"../../../../../shared/lib/utils";import{ResolvedImage as i}from"../../../../../components/common/ResolvedImage";import s from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import a from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";function c(e){if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return String(e);if(Array.isArray(e))return e.map(e=>c(e)).filter(Boolean).join(" ");if(e&&"object"==typeof e){const t=e;if("string"==typeof t.content)return t.content;if("string"==typeof t.question)return t.question;if("string"==typeof t.text)return t.text;const r=Object.entries(t).filter(([e,t])=>/^\d+$/.test(e)&&"string"==typeof t).sort(([e],[t])=>Number(e)-Number(t)).map(([,e])=>e);if(r.length>0)return r.join("")}return""}function m({imageUrl:o}){const[s,a]=l(!1);return t(r,{children:[t("div",{className:"relative flex items-center justify-center",children:[e(i,{src:o,alt:"Question illustration",className:"max-h-[250px] cursor-pointer rounded-lg object-contain shadow-md",onClick:()=>a(!0)}),e("button",{type:"button",onClick:()=>a(!0),className:"absolute right-2 top-2 rounded-full bg-white/80 p-1.5 shadow-md hover:bg-white","aria-label":"Zoom image",children:e(n,{className:"h-4 w-4 text-gray-600"})})]}),s&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70",onClick:()=>a(!1),children:e(i,{src:o,alt:"Question illustration (zoomed)",className:"max-h-[90vh] max-w-[90vw] rounded-lg object-contain",showLoadingState:!1})})]})}function u({example:r}){return t("div",{className:"rounded-lg border-2 border-orange-300 bg-white p-4",children:[e("p",{className:"mb-3 text-sm font-semibold text-gray-700",children:"Example:"}),t("p",{className:"mb-3 text-[19px] font-bold text-[#001590]",children:[r.questionNumber,". ",c(r.questionText)]}),r.imageUrl&&e("div",{className:"mb-3",children:e(m,{imageUrl:r.imageUrl})}),"image"===r.optionType?e("div",{className:"grid gap-3 px-2",style:{gridTemplateColumns:`repeat(${r.options.length}, minmax(0, 1fr))`},children:r.options.map(n=>{const l=n.id===r.correctOptionId;return t("div",{className:"relative flex flex-col items-center gap-1 rounded-[16px] border-[3px] p-4 pt-6 mt-3 transition-colors "+(l?"border-green-500 bg-green-50":"border-blue-200 bg-white"),children:[e("div",{className:"absolute -top-[14px] left-1/2 -translate-x-1/2 bg-blue-600 text-white w-[28px] h-[28px] rounded-full flex items-center justify-center font-bold text-[15px] shadow-sm",children:n.label}),e(i,{src:n.text,alt:`Option ${n.label}`,className:"w-40 rounded object-contain mb-2"}),e("div",{className:o("w-7 h-7 rounded-full flex items-center justify-center border-[3px] transition-all mt-auto",l?"bg-green-500 border-green-500 text-white":"border-gray-300 bg-white text-transparent"),children:e("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3.5",strokeLinecap:"round",strokeLinejoin:"round",children:e("polyline",{points:"20 6 9 17 4 12"})})})]},n.id)})}):e("div",{className:"flex flex-col gap-2 pl-2",children:r.options.map(n=>{const l=n.id===r.correctOptionId;return t("div",{className:"flex items-center gap-3 rounded-lg border-2 px-3 py-2 text-left transition-colors "+(l?"border-green-500 bg-green-50":"border-blue-200 bg-white"),children:[t("span",{className:"text-sm font-medium text-gray-600",children:[n.label,"."]}),e("span",{className:"flex-1 text-sm text-gray-700",children:c(n.text)}),e("div",{className:"flex h-5 w-5 items-center justify-center border-2 rounded-full "+(l?"border-green-500 bg-green-500":"border-gray-300 bg-white"),children:l&&e("div",{className:"h-2 w-2 rounded-full bg-white"})})]},n.id)})})]})}function p({question:r,selectedOptionIds:n,onSelect:l,isReviewMode:s,id:a}){const d=Boolean(r.multipleAnswers||r.correctOptionIds?.length),u=r.correctOptionIds?.length?r.correctOptionIds:r.correctOptionId?[r.correctOptionId]:[],p=e=>{const t=n.includes(e),r=u.includes(e);return s?r?"border-green-500 bg-green-50":t&&!r?"border-red-500 bg-red-50":"border-blue-200 bg-white":t?"border-blue-500 bg-[#f4f9ff]":"border-blue-200 bg-white hover:border-blue-300 hover:bg-blue-50/30"},b=e=>{const t=n.includes(e),r=u.includes(e);return s?r?"border-green-500 bg-green-500":t&&!r?"border-red-500 bg-red-500":"border-gray-300 bg-white":t?"border-blue-500 bg-blue-500":"border-gray-300 bg-white"},g=e=>s?n.includes(e)||u.includes(e):n.includes(e);return t("div",{id:a,className:"mb-6",children:[t("p",{className:"mb-3 text-[19px] font-bold text-[#001590]",children:[r.questionNumber,". ",c(r.questionText)]}),d&&e("p",{className:"mb-3 pl-2 text-sm font-medium text-blue-600",children:"Chọn nhiều đáp án"}),r.imageUrl&&e("div",{className:"mb-3",children:e(m,{imageUrl:r.imageUrl})}),"image"===r.optionType?e("div",{className:"grid gap-3 px-2",style:{gridTemplateColumns:`repeat(${r.options.length}, minmax(0, 1fr))`},children:r.options.map(r=>t("button",{type:"button",onClick:()=>!s&&l(r.id),disabled:s,className:`relative flex flex-col items-center gap-1 rounded-[16px] border-[3px] p-4 pt-6 mt-3 transition-colors ${p(r.id)} ${s?"cursor-default":"cursor-pointer"}`,children:[e("div",{className:"absolute -top-[14px] left-1/2 -translate-x-1/2 bg-blue-600 text-white w-[28px] h-[28px] rounded-full flex items-center justify-center font-bold text-[15px] shadow-sm",children:r.label}),e(i,{src:r.text,alt:`Option ${r.label}`,className:"w-35 rounded object-contain mb-2"}),e("div",{className:o("w-7 h-7 rounded-full flex items-center justify-center border-[3px] transition-all mt-auto",g(r.id)?"bg-blue-600 border-blue-600 text-white":"border-gray-300 bg-white text-transparent"),children:e("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3.5",strokeLinecap:"round",strokeLinejoin:"round",children:e("polyline",{points:"20 6 9 17 4 12"})})})]},r.id))}):e("div",{className:"flex flex-col gap-2 pl-2",children:r.options.map(r=>t("button",{type:"button",onClick:()=>!s&&l(r.id),disabled:s,className:`flex items-center gap-3 rounded-lg border-2 px-3 py-2 text-left transition-colors ${p(r.id)} ${s?"cursor-default":"cursor-pointer"}`,children:[t("span",{className:"text-sm font-medium text-gray-600",children:[r.label,"."]}),e("span",{className:"flex-1 text-sm text-gray-700",children:c(r.text)}),e("div",{className:`flex h-5 w-5 items-center justify-center border-2 ${d?"rounded-md":"rounded-full"} ${b(r.id)}`,children:g(r.id)&&e("div",{className:(d?"h-2.5 w-2.5 rounded-sm":"h-2 w-2 rounded-full")+" bg-white"})})]},r.id))})]})}function b({article:r,label:n}){return t("div",{className:"rounded-lg border border-gray-200 bg-white p-4 shadow-sm",children:[t("div",{className:"mb-2 flex items-center gap-2",children:[e("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-teal-500 text-xs font-bold text-white",children:n}),e("h3",{className:"text-sm font-bold text-gray-900",children:r.name})]}),r.imageUrl&&e("div",{className:"mb-2",children:e(i,{src:r.imageUrl,alt:r.name,className:"max-h-48 w-full rounded-md object-contain"})}),e("div",{className:"article-content text-sm leading-relaxed text-gray-700",dangerouslySetInnerHTML:{__html:r.content}})]})}export function MoversChooseBestAnswerRenderer({partNumber:r,partName:n,questionCount:l,instruction:o,imageUrl:c,groupTitle:m,groupContent:g,articles:x,audioUrl:h,example:f,questions:w,answers:
|
|
1
|
+
"use client";import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import{ZoomIn as n}from"lucide-react";import{useState as l}from"react";import{cn as o}from"../../../../../shared/lib/utils";import{ResolvedImage as i}from"../../../../../components/common/ResolvedImage";import s from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import a from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";function c(e){if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return String(e);if(Array.isArray(e))return e.map(e=>c(e)).filter(Boolean).join(" ");if(e&&"object"==typeof e){const t=e;if("string"==typeof t.content)return t.content;if("string"==typeof t.question)return t.question;if("string"==typeof t.text)return t.text;const r=Object.entries(t).filter(([e,t])=>/^\d+$/.test(e)&&"string"==typeof t).sort(([e],[t])=>Number(e)-Number(t)).map(([,e])=>e);if(r.length>0)return r.join("")}return""}function m({imageUrl:o}){const[s,a]=l(!1);return t(r,{children:[t("div",{className:"relative flex items-center justify-center",children:[e(i,{src:o,alt:"Question illustration",className:"max-h-[250px] cursor-pointer rounded-lg object-contain shadow-md",onClick:()=>a(!0)}),e("button",{type:"button",onClick:()=>a(!0),className:"absolute right-2 top-2 rounded-full bg-white/80 p-1.5 shadow-md hover:bg-white","aria-label":"Zoom image",children:e(n,{className:"h-4 w-4 text-gray-600"})})]}),s&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70",onClick:()=>a(!1),children:e(i,{src:o,alt:"Question illustration (zoomed)",className:"max-h-[90vh] max-w-[90vw] rounded-lg object-contain",showLoadingState:!1})})]})}function u({example:r}){return t("div",{className:"rounded-lg border-2 border-orange-300 bg-white p-4",children:[e("p",{className:"mb-3 text-sm font-semibold text-gray-700",children:"Example:"}),t("p",{className:"mb-3 text-[19px] font-bold text-[#001590]",children:[r.questionNumber,". ",c(r.questionText)]}),r.imageUrl&&e("div",{className:"mb-3",children:e(m,{imageUrl:r.imageUrl})}),"image"===r.optionType?e("div",{className:"grid gap-3 px-2",style:{gridTemplateColumns:`repeat(${r.options.length}, minmax(0, 1fr))`},children:r.options.map(n=>{const l=n.id===r.correctOptionId;return t("div",{className:"relative flex flex-col items-center gap-1 rounded-[16px] border-[3px] p-4 pt-6 mt-3 transition-colors "+(l?"border-green-500 bg-green-50":"border-blue-200 bg-white"),children:[e("div",{className:"absolute -top-[14px] left-1/2 -translate-x-1/2 bg-blue-600 text-white w-[28px] h-[28px] rounded-full flex items-center justify-center font-bold text-[15px] shadow-sm",children:n.label}),e(i,{src:n.text,alt:`Option ${n.label}`,className:"w-40 rounded object-contain mb-2"}),e("div",{className:o("w-7 h-7 rounded-full flex items-center justify-center border-[3px] transition-all mt-auto",l?"bg-green-500 border-green-500 text-white":"border-gray-300 bg-white text-transparent"),children:e("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3.5",strokeLinecap:"round",strokeLinejoin:"round",children:e("polyline",{points:"20 6 9 17 4 12"})})})]},n.id)})}):e("div",{className:"flex flex-col gap-2 pl-2",children:r.options.map(n=>{const l=n.id===r.correctOptionId;return t("div",{className:"flex items-center gap-3 rounded-lg border-2 px-3 py-2 text-left transition-colors "+(l?"border-green-500 bg-green-50":"border-blue-200 bg-white"),children:[t("span",{className:"text-sm font-medium text-gray-600",children:[n.label,"."]}),e("span",{className:"flex-1 text-sm text-gray-700",children:c(n.text)}),e("div",{className:"flex h-5 w-5 items-center justify-center border-2 rounded-full "+(l?"border-green-500 bg-green-500":"border-gray-300 bg-white"),children:l&&e("div",{className:"h-2 w-2 rounded-full bg-white"})})]},n.id)})})]})}function p({question:r,selectedOptionIds:n,onSelect:l,isReviewMode:s,id:a}){const d=Boolean(r.multipleAnswers||r.correctOptionIds?.length),u=r.correctOptionIds?.length?r.correctOptionIds:r.correctOptionId?[r.correctOptionId]:[],p=e=>{const t=n.includes(e),r=u.includes(e);return s?r?"border-green-500 bg-green-50":t&&!r?"border-red-500 bg-red-50":"border-blue-200 bg-white":t?"border-blue-500 bg-[#f4f9ff]":"border-blue-200 bg-white hover:border-blue-300 hover:bg-blue-50/30"},b=e=>{const t=n.includes(e),r=u.includes(e);return s?r?"border-green-500 bg-green-500":t&&!r?"border-red-500 bg-red-500":"border-gray-300 bg-white":t?"border-blue-500 bg-blue-500":"border-gray-300 bg-white"},g=e=>s?n.includes(e)||u.includes(e):n.includes(e);return t("div",{id:a,className:"mb-6",children:[t("p",{className:"mb-3 text-[19px] font-bold text-[#001590]",children:[r.questionNumber,". ",c(r.questionText)]}),d&&e("p",{className:"mb-3 pl-2 text-sm font-medium text-blue-600",children:"Chọn nhiều đáp án"}),r.imageUrl&&e("div",{className:"mb-3",children:e(m,{imageUrl:r.imageUrl})}),"image"===r.optionType?e("div",{className:"grid gap-3 px-2",style:{gridTemplateColumns:`repeat(${r.options.length}, minmax(0, 1fr))`},children:r.options.map(r=>t("button",{type:"button",onClick:()=>!s&&l(r.id),disabled:s,className:`relative flex flex-col items-center gap-1 rounded-[16px] border-[3px] p-4 pt-6 mt-3 transition-colors ${p(r.id)} ${s?"cursor-default":"cursor-pointer"}`,children:[e("div",{className:"absolute -top-[14px] left-1/2 -translate-x-1/2 bg-blue-600 text-white w-[28px] h-[28px] rounded-full flex items-center justify-center font-bold text-[15px] shadow-sm",children:r.label}),e(i,{src:r.text,alt:`Option ${r.label}`,className:"w-35 rounded object-contain mb-2"}),e("div",{className:o("w-7 h-7 rounded-full flex items-center justify-center border-[3px] transition-all mt-auto",g(r.id)?"bg-blue-600 border-blue-600 text-white":"border-gray-300 bg-white text-transparent"),children:e("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3.5",strokeLinecap:"round",strokeLinejoin:"round",children:e("polyline",{points:"20 6 9 17 4 12"})})})]},r.id))}):e("div",{className:"flex flex-col gap-2 pl-2",children:r.options.map(r=>t("button",{type:"button",onClick:()=>!s&&l(r.id),disabled:s,className:`flex items-center gap-3 rounded-lg border-2 px-3 py-2 text-left transition-colors ${p(r.id)} ${s?"cursor-default":"cursor-pointer"}`,children:[t("span",{className:"text-sm font-medium text-gray-600",children:[r.label,"."]}),e("span",{className:"flex-1 text-sm text-gray-700",children:c(r.text)}),e("div",{className:`flex h-5 w-5 items-center justify-center border-2 ${d?"rounded-md":"rounded-full"} ${b(r.id)}`,children:g(r.id)&&e("div",{className:(d?"h-2.5 w-2.5 rounded-sm":"h-2 w-2 rounded-full")+" bg-white"})})]},r.id))})]})}function b({article:r,label:n}){return t("div",{className:"rounded-lg border border-gray-200 bg-white p-4 shadow-sm",children:[t("div",{className:"mb-2 flex items-center gap-2",children:[e("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-teal-500 text-xs font-bold text-white",children:n}),e("h3",{className:"text-sm font-bold text-gray-900",children:r.name})]}),r.imageUrl&&e("div",{className:"mb-2",children:e(i,{src:r.imageUrl,alt:r.name,className:"max-h-48 w-full rounded-md object-contain"})}),e("div",{className:"article-content text-sm leading-relaxed text-gray-700",dangerouslySetInnerHTML:{__html:r.content}})]})}export function MoversChooseBestAnswerRenderer({partNumber:r,partName:n,questionCount:l,instruction:o,imageUrl:c,groupTitle:m,groupContent:g,articles:x,audioUrl:h,example:f,questions:w,answers:N,onAnswerChange:y,isReviewMode:v=!1}){const j=!!(h||c||x&&x.length>0||g);return t("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar relative",children:[t("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-2",children:[e(s,{partNumber:r,questionCount:l,partName:n,isReviewMode:v}),e(a,{instruction:o,isReviewMode:v}),m&&!(x&&x.length>0)&&e("h2",{className:"text-center text-xl font-bold uppercase text-coral-500",children:m})]}),j&&t("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-0 sticky top-0 z-20 bg-white/95 backdrop-blur pb-2 shadow-sm border-b border-gray-100",children:[h&&e(d,{audioSrc:h,compact:!0}),c&&e("div",{className:"flex items-center justify-center",children:e(i,{src:c,alt:"Shared illustration",className:"max-h-[250px] rounded-lg object-contain shadow-md"})}),x&&x.length>0?e("div",{className:"flex flex-col gap-3 max-h-[35vh] overflow-y-auto custom-scrollbar pr-2",children:x.map((t,r)=>e(b,{article:t,label:String.fromCharCode(65+r)},r))}):g?e("div",{className:"article-content rounded-lg bg-amber-50 p-3 sm:p-4 text-sm leading-relaxed text-gray-700 max-h-[35vh] overflow-y-auto pr-2 custom-scrollbar shadow-inner",dangerouslySetInnerHTML:{__html:g}}):null]}),f&&e("div",{className:"p-3 sm:px-6",children:e(u,{example:f})}),e("div",{className:"p-3 sm:pb-6 sm:px-6 "+(v?"grid grid-cols-1 md:grid-cols-2 gap-6":"flex flex-col gap-4"),children:w.map(t=>{const r=N[t.id],n=Array.isArray(r)?r:"string"==typeof r&&r?[r]:[];return e(p,{id:`question-${t.id}`,question:t,selectedOptionIds:n,onSelect:e=>{const r=t.multipleAnswers?n.includes(e)?n.filter(t=>t!==e):[...n,e]:e;y(t.id,r)},isReviewMode:v},t.id)})})]})}
|
package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as
|
|
1
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import{ResolvedImage as t}from"../../../../../components/common/ResolvedImage";import l from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import a from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import s from"../../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";import o from"../../../../../components/themes/cambridge-yle/CambridgeYleExampleText";export function MoversListenAndWriteRenderer({partNumber:i,partName:n,questionCount:d,instruction:m,imageUrl:c,audioUrl:b,title:x,exampleText:p,exampleHighlight:u,questions:h,answers:g,onAnswerChange:f,isReviewMode:w=!1,showHints:N=!1,groupContent:v,groupTitle:y}){const C=!!(b||c||v||p);return r("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar relative",children:[r("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-4",children:[e(l,{partNumber:i,questionCount:d,partName:n,isReviewMode:w}),e(a,{instruction:m,hasExample:!!p,isReviewMode:w})]}),C&&r("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-0 sticky top-0 z-20 bg-white/95 backdrop-blur pb-2 shadow-sm border-b border-gray-100",children:[b&&e(s,{audioSrc:b,compact:!0}),r("div",{className:"max-h-[35vh] overflow-y-auto custom-scrollbar pr-2 flex flex-col gap-3",children:[c&&e("div",{className:"flex items-center justify-center",children:e(t,{src:c,alt:"Shared illustration",className:"max-h-[200px] rounded-lg object-contain shadow-md"})}),v&&r("div",{className:"rounded-lg bg-amber-50 p-3 text-sm leading-relaxed text-gray-700 shadow-inner",children:[y&&e("h3",{className:"mb-2 font-semibold text-gray-800",children:y}),v]})]}),p&&e(o,{text:p,highlightedWord:u||""})]}),r("div",{className:"flex flex-col gap-4 p-3 sm:gap-6 sm:pb-6 sm:px-6",children:[x&&e("h2",{className:"text-center text-3xl font-bold uppercase text-coral-500",children:x}),e("div",{className:"flex flex-col gap-6 sm:gap-8",children:h.map(l=>{const a=l.isExample||!1,o=w||a,i=a&&l.correctAnswer?l.correctAnswer:g[l.id]||"",n=(g[l.id]||"").trim().toLowerCase(),d=(l.correctAnswer||"").trim().toLowerCase(),m=!!n,c=w&&!a&&m&&n===d,b=w&&!a&&m&&n!==d;return r("div",{id:`question-${l.id}`,className:"flex flex-col gap-4 rounded-2xl border p-4 sm:p-6 transition-all duration-200 hover:shadow-md "+(a?"border-amber-300 bg-amber-50/60 shadow-xs":"border-slate-200/80 bg-white shadow-xs hover:border-blue-300"),children:[r("div",{className:"flex items-center justify-between border-b border-slate-100 pb-3",children:[r("div",{className:"flex items-center gap-2",children:[e("span",{className:"inline-flex items-center justify-center rounded-full px-3.5 py-1 text-sm font-bold text-white shadow-xs "+(a?"bg-amber-500":w?c?"bg-emerald-500":b?"bg-rose-500":"bg-[#001590]":"bg-[#001590]"),children:a?"Ví dụ":`${l.questionNumber}.`}),a&&e("span",{className:"rounded-md bg-amber-100 px-2 py-0.5 text-xs font-semibold text-amber-700",children:"Example"})]}),w&&!a&&e("div",{children:e("span",c?{className:"inline-flex items-center gap-1 rounded-full bg-emerald-50 px-2.5 py-0.5 text-xs font-semibold text-emerald-700 border border-emerald-200",children:"✓ Đúng"}:b?{className:"inline-flex items-center gap-1 rounded-full bg-rose-50 px-2.5 py-0.5 text-xs font-semibold text-rose-700 border border-rose-200",children:"✕ Chưa đúng"}:{className:"inline-flex items-center gap-1 rounded-full bg-slate-100 px-2.5 py-0.5 text-xs font-medium text-slate-600",children:"Chưa trả lời"})})]}),l.audioUrl&&e("div",{className:"w-full my-1",children:e(s,{audioSrc:l.audioUrl,compact:!0,dense:!0})}),l.imageUrl&&e("div",{className:"flex items-center justify-center rounded-xl bg-slate-50/80 p-3 border border-slate-100 max-w-md mx-auto w-full",children:e(t,{src:l.imageUrl,alt:`Question ${l.questionNumber} illustration`,className:"max-h-[200px] sm:max-h-[220px] w-auto rounded-lg object-contain drop-shadow-xs"})}),r("div",{className:"flex flex-wrap items-baseline gap-2 text-base sm:text-lg leading-relaxed text-slate-800 pt-1",children:[l.textBefore&&e("span",{className:"font-medium",children:l.textBefore}),e("span",{className:"inline-block min-w-[140px] sm:min-w-[160px]",children:e("input",{type:"text",value:i,onChange:e=>f(l.id,e.target.value),disabled:o,placeholder:a?"":"...",className:`w-full rounded-lg border-2 px-3 py-1.5 text-center font-semibold outline-none transition-all ${a?"border-amber-300 bg-amber-100/50 text-amber-800 disabled:opacity-100":w?c?"border-emerald-400 bg-emerald-50 text-emerald-800":"border-rose-400 bg-rose-50 text-rose-800":"border-blue-200 bg-blue-50/30 text-blue-900 focus:border-blue-500 focus:bg-white focus:ring-4 focus:ring-blue-100"} ${o?"disabled:cursor-not-allowed disabled:opacity-75":""}`})}),l.textAfter&&e("span",{className:"font-medium",children:l.textAfter}),l.verbHint&&r("span",{className:"italic text-slate-500 font-normal",children:["(",l.verbHint,")"]})]}),N&&l.hints&&l.hints.length>0&&!w&&r("div",{className:"flex flex-wrap items-center gap-2 pt-2 border-t border-slate-100",children:[e("span",{className:"text-xs font-medium text-slate-500",children:"Gợi ý:"}),l.hints.map((r,t)=>e("button",{type:"button",onClick:()=>f(l.id,r),className:"rounded-full border border-blue-200 bg-blue-50 px-3 py-1 text-xs font-semibold text-blue-700 shadow-2xs transition-all hover:bg-blue-600 hover:text-white hover:border-blue-600 active:scale-95",children:r},t))]}),w&&!a&&l.correctAnswer&&e("div",{className:"mt-1 rounded-lg bg-emerald-50/80 p-2.5 text-sm border border-emerald-200/80",children:r("span",{className:"font-semibold text-emerald-800",children:["Đáp án đúng: ",e("span",{className:"font-bold underline",children:l.correctAnswer})]})})]},l.id)})})]})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useRef as r,useEffect as n,useMemo as a,useCallback as l,memo as s}from"react";import{ResolvedImage as i}from"../../../../../components/common/ResolvedImage";import o from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import c from"../../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";import{cn as u}from"../../../../../shared/lib/utils";function m(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function p(e,t){return e.replace(/\{([\w\d]+)\}/g,(e,r)=>{const n=function(e,t){if(!e?.length)return null;const r=Number(t),n=Number.isFinite(r)&&r>=0&&r<e.length?e[r]:null;return null!=n&&"options"in n&&n.options?.length&&n.options.length>=2?n.options:null}(t,r);if(n){return`\n <span class="structured-blank-wrapper" data-blank-wrapper="${r}">\n <select data-blank-key="${r}" class="structured-blank-input structured-blank-select">${['<option value="">—</option>',...n.map(e=>`<option value="${m(e)}">${m(e)}</option>`)].join("")}</select>\n <span class="structured-blank-hint" data-blank-hint="${r}"></span>\n </span>\n `}return`\n <span class="structured-blank-wrapper" data-blank-wrapper="${r}">\n <input type="text" data-blank-key="${r}" placeholder="" class="structured-blank-input" />\n <span class="structured-blank-hint" data-blank-hint="${r}"></span>\n </span>\n `})}function b(e,t){const r=e.trim();return t?r:r.toLowerCase()}const g={},x=s(function({question:l,initialAnswers:s,onBlankChange:o,isReviewMode:d}){const c=r(null),m=r(o);m.current=o;const g=r(!1),x=r(s),h=a(()=>p(l.content,l.wordBank),[l.content,l.wordBank]);return n(()=>{const e=c.current;if(!e)return;g.current||(e.innerHTML=h,g.current=!0);const t=e.querySelectorAll("input.structured-blank-input, select.structured-blank-input"),r=[];return t.forEach(t=>{const n=t.getAttribute("data-blank-key")||"",a=e.querySelector(`[data-blank-wrapper="${n}"]`),s=e.querySelector(`[data-blank-hint="${n}"]`),i=x.current[n]||"",o=l.answers[n]||"",c=i.trim().length>0,p=c&&b(i,l.caseSensitive)===b(o,l.caseSensitive),g=d&&!p&&o.trim().length>0;t.value=g?`${c?i:"(trống)"} → ${o}`:i,t.disabled=d;const h="SELECT"===t.tagName,f=l.blankStyle||"word",w="letter"===f,y="phrase"===f;w&&!h&&"maxLength"in t&&(t.maxLength=Math.max(1,(o||" ").trim().length||1)),t.className=u("structured-blank-input inline-block bg-slate-50/40 text-sm font-semibold outline-none transition-all align-baseline hover:bg-slate-100/60 focus:bg-teal-50/60 focus:ring-0",h?"min-w-[7rem] max-w-[14rem] rounded border px-2 py-1 text-center":w?"h-7 w-7 rounded border-2 px-0 text-center uppercase":y?"min-w-[140px] max-w-[280px] rounded-t border-b-2 px-2 py-0.5 text-center":"min-w-[90px] max-w-[160px] rounded-t border-b-2 px-2 py-0.5 text-center",d?p?"border-emerald-500 bg-emerald-50 text-emerald-800 font-bold":c?"border-rose-500 bg-rose-50 text-rose-800 font-bold":"border-amber-500 bg-amber-50 text-amber-800 font-bold":"border-slate-400 text-slate-800 focus:border-teal-600"),w&&(t.style.display="inline-block",t.style.width="1.75rem",t.style.height="1.75rem",t.style.minWidth="1.75rem",t.style.maxWidth="1.75rem",t.style.padding="0",t.style.margin="0 2px",t.style.borderWidth="2px",t.style.borderStyle="solid",t.style.borderRadius="4px",t.style.textAlign="center",t.style.fontWeight="700",t.style.textTransform="uppercase",t.style.boxSizing="border-box",t.style.verticalAlign="baseline"),a&&(a.className=u("structured-blank-wrapper inline-flex items-baseline align-baseline mx-1 my-0.5",d&&"mx-1 my-0.5")),s&&(s.textContent="",s.className="structured-blank-hint hidden");const k=e=>{const t=e.target;m.current(n,t.value)},v=h?"change":"input";t.addEventListener(v,k),r.push({el:t,handler:k,eventName:v})}),()=>{r.forEach(({el:e,handler:t,eventName:r})=>{e.removeEventListener(r,t)})}},[h,d]),t("div",{className:"space-y-3",children:[l.title&&e("h3",{className:"text-base font-semibold text-gray-800",children:l.title}),l.imageUrl&&e("div",{className:"flex justify-center",children:e("div",{className:"overflow-hidden rounded-lg border border-gray-200",children:e(i,{src:l.imageUrl,alt:l.title||"Question image",className:"max-h-48 w-auto object-contain"})})}),e("div",{ref:c,className:u("structured-form-content rounded-lg border border-gray-200 bg-gradient-to-r from-gray-50 to-slate-50 p-4 text-sm leading-relaxed text-gray-800","[&_.structured-blank-wrapper]:inline-flex [&_.structured-blank-wrapper]:align-baseline [&_.structured-blank-wrapper]:items-baseline [&_.structured-blank-hint]:max-w-[180px]","[&_table.dialogue]:w-full [&_table.dialogue]:border-collapse [&_table.dialogue]:table-fixed","[&_table.dialogue_td.speaker]:w-[1%] [&_table.dialogue_td.speaker]:whitespace-nowrap","[&_table.dialogue_td.speaker]:align-top [&_table.dialogue_td.speaker]:pr-3","[&_table.dialogue_td.speaker]:font-semibold [&_table.dialogue_td.speaker]:text-slate-900","[&_table.dialogue_td]:align-top [&_table.dialogue_td]:py-1.5")}),d&&t("div",{className:"space-y-2 rounded-lg border border-slate-200 bg-slate-50 p-3",children:[t("div",{className:"flex flex-wrap gap-2 text-[11px] font-medium",children:[t("span",{className:"inline-flex items-center gap-1 rounded-full bg-green-100 px-2 py-1 text-green-700",children:[e("span",{className:"h-2 w-2 rounded-full bg-green-500"}),"Đúng"]}),t("span",{className:"inline-flex items-center gap-1 rounded-full bg-red-100 px-2 py-1 text-red-700",children:[e("span",{className:"h-2 w-2 rounded-full bg-red-500"}),"Sai"]}),t("span",{className:"inline-flex items-center gap-1 rounded-full bg-amber-100 px-2 py-1 text-amber-700",children:[e("span",{className:"h-2 w-2 rounded-full bg-amber-500"}),"Chưa trả lời"]})]}),t("div",{children:[e("span",{className:"text-[10px] font-medium uppercase tracking-wider text-slate-500",children:"Đáp án đúng"}),e("div",{className:"mt-1 flex flex-wrap gap-1.5",children:Object.entries(l.answers).map(([e,r])=>t("span",{className:"rounded border border-green-300 bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800",children:[e,": ",r]},e))})]})]})]})});export function MoversWordFillStructuredFormRenderer({partNumber:n,partName:s,questionCount:u,instruction:m,audioUrl:p,groupTitle:b,groupContent:h,groupImageUrl:f,questions:w,answers:y,onAnswerChange:k,isReviewMode:v=!1}){const N=r(y);N.current=y;const _=r(k);_.current=k;const $=l((e,t,r)=>{const n=N.current[e]||{};_.current(e,{...n,[t]:r})},[]),C=a(()=>{const e={};return w.forEach(t=>{e[t.id]=(e,r)=>$(t.id,e,r)}),e},[w,$]);return t("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar",children:[t("div",{className:"flex flex-col gap-4 p-3 sm:px-6 sm:pt-2",children:[e(o,{partNumber:n,questionCount:u,partName:s,isReviewMode:v}),e(d,{instruction:m,isReviewMode:v}),b&&e("h2",{className:"text-center text-xl font-bold uppercase text-coral-500",children:b}),p&&e(c,{audioSrc:p,compact:!0}),f&&e("div",{className:"flex items-center justify-center",children:e(i,{src:f,alt:b||"Group image",className:"max-h-[300px] rounded-lg object-contain shadow-md"})}),h&&e("div",{className:"article-content rounded-lg bg-amber-50 p-4 text-sm leading-relaxed text-gray-700 max-h-[500px] overflow-y-auto pr-2 custom-scrollbar",dangerouslySetInnerHTML:{__html:h}})]}),w.length>0&&e("div",{className:"px-3 sm:px-6",children:e("hr",{className:"border-t border-slate-200/60 my-1"})}),e("div",{className:"grid grid-cols-1 gap-4 sm:gap-5 p-3 sm:px-6 sm:pb-6",children:w.map(r=>t("div",{id:`question-${r.id}`,className:"rounded-xl border border-gray-200 bg-white p-4 shadow-sm transition-all hover:border-indigo-200 hover:shadow-md",children:[e("div",{className:"mb-2 flex items-center gap-2",children:e("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-gradient-to-br from-indigo-500 to-violet-600 text-xs font-bold text-white shadow-sm",children:r.questionNumber})}),e(x,{question:r,initialAnswers:y[r.id]||g,onBlankChange:C[r.id],isReviewMode:v})]},r.id))})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useMemo as s}from"react";import{ResolvedImage as r}from"../../../../../components/common/ResolvedImage";import l from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import{HtmlOrText as i}from"../../../../../shared/lib/html-content";export function MoversWritingRenderer({partNumber:n,partName:c,instruction:
|
|
1
|
+
"use client";import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useMemo as s}from"react";import{ResolvedImage as r}from"../../../../../components/common/ResolvedImage";import l from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import{HtmlOrText as i}from"../../../../../shared/lib/html-content";export function MoversWritingRenderer({partNumber:n,partName:c,instruction:o,prompt:m,requirements:x,minWords:b,maxWords:p,answer:h,onAnswerChange:g,isReviewMode:u=!1,guideImages:f,teacherScore:N,maxScore:v,teacherFeedback:w,writingAssessment:y}){const F=s(()=>h&&h.trim()?h.trim().split(/\s+/).filter(Boolean).length:0,[h]);return t("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar relative",children:[t("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-4",children:[e(l,{partNumber:n,questionCount:1,partName:c,isReviewMode:u}),o&&e(d,{instruction:o,isReviewMode:u})]}),e("div",{className:"flex flex-col gap-4 p-3 sm:px-6 sm:pt-0 sticky top-0 z-20 bg-white/95 backdrop-blur pb-2 shadow-sm border-b border-gray-100",children:t("div",{className:"flex flex-col gap-4",children:[e("div",{className:"rounded-2xl border border-slate-200 bg-white p-5 shadow-sm",children:t("div",{className:"flex flex-col gap-4 text-base leading-relaxed text-gray-800",children:[t("div",{className:"space-y-3",children:[e("p",{className:"text-lg font-semibold text-slate-900",children:"Writing task"}),e(i,{value:m,className:"text-base leading-relaxed text-gray-800"})]}),x&&x.length>0&&t("div",{className:"rounded-xl bg-slate-50 p-4",children:[e("p",{className:"text-sm font-bold uppercase tracking-wide text-slate-700",children:"Include"}),e("ul",{className:"mt-3 space-y-2",children:x.map((a,s)=>t("li",{className:"flex items-start gap-2 text-sm text-slate-700",children:[e("span",{className:"mt-1.5 h-2 w-2 rounded-full bg-blue-500"}),e(i,{value:a,as:"span"})]},s))})]}),(b||p)&&t("div",{className:"flex flex-wrap gap-2",children:[b&&t("div",{className:"inline-flex items-center rounded-full border border-blue-200 bg-blue-50 px-3 py-1 text-sm font-medium text-blue-700",children:["Minimum: ",b," words"]}),p&&t("div",{className:"inline-flex items-center rounded-full border border-slate-200 bg-white px-3 py-1 text-sm font-medium text-slate-600",children:["Suggested max: ",p," words"]})]})]})}),f&&f.length>0&&t("div",{className:"rounded-2xl border border-slate-200 bg-white p-4 shadow-sm",children:[t("div",{className:"mb-3 flex items-center justify-between gap-3",children:[e("p",{className:"text-sm font-semibold uppercase tracking-wide text-slate-600",children:"Story pictures"}),e("p",{className:"text-xs text-slate-400",children:"Read the sequence from left to right"})]}),e("div",{className:"grid gap-4 "+(1===f.length?"grid-cols-1":"grid-cols-1 sm:grid-cols-2"),children:f.map((a,s)=>t("div",{className:"rounded-xl border border-slate-200 bg-slate-50/80 p-2 shadow-sm",children:[e(r,{src:a,alt:`Picture ${s+1}`,className:"w-full rounded-lg bg-white object-contain "+(1===f.length?"max-h-[400px]":"aspect-[4/3]")}),e("div",{className:"pt-2 text-center text-[13px] font-medium text-slate-500",children:f.length>1?`Picture ${s+1}`:"Reference Image"})]},s))})]})]})}),t("div",{className:"flex flex-col gap-3 p-3 sm:px-6 sm:pb-6",children:[t("div",{className:"rounded-2xl border border-slate-200 bg-white shadow-sm",children:[t("div",{className:"flex items-center justify-between gap-3 border-b border-slate-100 px-5 py-3 bg-slate-50/50 rounded-t-2xl",children:[t("div",{children:[e("p",{className:"text-sm font-semibold uppercase tracking-wide text-slate-500",children:"Your answer"}),e("p",{className:"text-xs text-slate-400",children:"Write clearly and organise your ideas in order."})]}),t("div",{className:"rounded-full px-3 py-1 text-sm font-semibold "+(b&&F<b?"border border-amber-200 bg-amber-50 text-amber-700":"border border-emerald-200 bg-emerald-50 text-emerald-700"),children:[F," words"]})]}),t("div",{className:"p-4",children:[e("textarea",{id:"writing-answer",name:"writing-answer",value:h,onChange:e=>{const t=e.target.value;if(p){const e=Number(p);if((t.trim()?t.trim().split(/\s+/).filter(Boolean).length:0)>e&&t.length>=(h?.length||0))return}g(t)},disabled:u,placeholder:"Write your answer here...",className:"min-h-[340px] w-full resize-y rounded-xl border border-slate-200 bg-slate-50/50 p-4 text-base leading-8 text-gray-800 outline-none transition focus:border-blue-400 focus:bg-white focus:ring-2 focus:ring-blue-100 disabled:bg-gray-50 disabled:text-gray-700"}),t("div",{className:"mt-3 flex flex-wrap items-center justify-between gap-3 text-sm",children:[e("p",{className:"text-slate-500",children:b||p?t(a,{children:[b&&t("span",{children:["Minimum required: ",t("span",{className:"font-semibold text-slate-700",children:[b," words"]})]}),b&&p&&e("span",{className:"mx-2 text-slate-300",children:"|"}),p&&t("span",{children:["Maximum allowed: ",t("span",{className:"font-semibold text-slate-700",children:[p," words"]})]})]}):"Write a complete answer."}),t("p",{className:"font-medium "+(p&&F>=p?"text-red-500":"text-slate-500"),children:["Word count: ",F," ",p&&`/ ${p}`]})]})]})]}),u&&t("div",{className:"space-y-3",children:[y&&y.criteria?.length>0&&(()=>{const a="ADULT_EMAIL"===y.taskType,s=a?10:9,r=a?"Đánh giá 4 tiêu chí Writing (Adult Placement)":`Đánh giá 4 tiêu chí IELTS Writing (${"TASK_2"===y.taskType?"Task 2":"Task 1"})`,l=a?"Total:":"Overall Band:",d=a?`${y.overallBand}`:y.overallBand.toFixed(1);return t("div",{className:"rounded-2xl border border-[#00AEEF]/30 bg-gradient-to-b from-[#F4F9FF] to-white p-4 space-y-3 shadow-xs",children:[t("div",{className:"flex flex-wrap items-center justify-between gap-2 border-b border-[#00AEEF]/20 pb-2.5",children:[t("div",{className:"flex items-center gap-2",children:[e("span",{className:"flex h-6 w-6 items-center justify-center rounded-full bg-[#0054A6] text-xs font-bold text-white",children:"AI"}),e("span",{className:"font-bold text-[#0054A6] text-sm sm:text-base",children:r})]}),t("div",{className:"flex items-center gap-1.5 rounded-lg bg-[#EAF6FF] border border-[#00AEEF]/30 px-3 py-1",children:[e("span",{className:"text-xs font-semibold text-[#0054A6]",children:l}),e("span",{className:"text-sm sm:text-base font-extrabold text-[#0054A6]",children:d}),t("span",{className:"text-xs text-slate-400",children:["/ ",s]})]})]}),e("div",{className:"grid gap-3 sm:grid-cols-2",children:y.criteria.map(s=>{const r=s.maxPoints??(a?2:9),l=r>0?Math.max(0,Math.min(100,s.band/r*100)):0,d=l>=85?"bg-emerald-500":l>=65?"bg-[#00AEEF]":l>=45?"bg-amber-500":"bg-rose-500",i=a?`${s.band} / ${r}`:`Band ${s.band.toFixed(1)}`;return t("div",{className:"rounded-xl border border-slate-200 bg-white p-3 space-y-2 shadow-2xs",children:[t("div",{className:"flex items-center justify-between",children:[t("div",{className:"flex items-center gap-2",children:[e("span",{className:"font-bold text-[#0054A6] bg-[#EAF6FF] px-2 py-0.5 rounded border border-[#00AEEF]/20 text-xs",children:s.code}),e("span",{className:"font-semibold text-slate-800 text-xs sm:text-sm",children:s.label})]}),e("span",{className:"font-extrabold text-[#0054A6] bg-slate-100 px-2 py-0.5 rounded text-xs sm:text-sm",children:i})]}),e("div",{className:"h-2 w-full rounded-full bg-slate-100 overflow-hidden",children:e("div",{className:`h-full rounded-full transition-all duration-500 ${d}`,style:{width:`${l}%`}})}),s.evidence&&e("p",{className:"text-xs text-slate-600 leading-relaxed pt-0.5",children:s.evidence})]},s.code)})}),(y.feedback?.vi||y.feedback?.en)&&t("div",{className:"rounded-xl bg-[#F4F9FF] border border-[#00AEEF]/20 p-3 text-xs sm:text-sm text-slate-700 space-y-1.5",children:[e("span",{className:"font-bold text-[#0054A6] block",children:"Nhận xét từ giám khảo AI:"}),y.feedback.vi&&e("p",{className:"leading-relaxed",children:y.feedback.vi}),y.feedback.en&&e("p",{className:"text-slate-500 italic border-t border-[#00AEEF]/10 pt-1.5 mt-1.5",children:y.feedback.en})]})]})})(),null!=N?t("div",{className:"rounded-2xl border border-green-200 bg-green-50 p-4",children:[e("div",{className:"mb-2 flex items-center gap-2",children:t("span",{className:"text-lg font-semibold text-green-700",children:["Điểm: ",N,"/",v]})}),w&&t("div",{className:"text-sm text-gray-700",children:[e("span",{className:"font-medium",children:"Nhận xét:"})," ",w]})]}):y?null:e("div",{className:"rounded-2xl border border-amber-200 bg-amber-50 p-4",children:t("div",{className:"flex items-center gap-2",children:[e("svg",{className:"h-5 w-5 shrink-0 text-amber-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:e("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"})}),e("span",{className:"text-sm font-medium text-amber-700",children:"Bài viết đang chờ giáo viên chấm điểm"})]})})]})]})]})}
|
|
@@ -11,6 +11,13 @@ export interface TemplateSection {
|
|
|
11
11
|
viewMode?: string;
|
|
12
12
|
wordBankConfig?: string[];
|
|
13
13
|
}
|
|
14
|
+
export type WfsfBlankStyle = 'letter' | 'word' | 'phrase';
|
|
15
|
+
export type WfsfWordBankEntry = {
|
|
16
|
+
options: string[];
|
|
17
|
+
} | {
|
|
18
|
+
word: string;
|
|
19
|
+
isExample?: boolean;
|
|
20
|
+
} | null;
|
|
14
21
|
export interface WordFillStructuredFormQuestion {
|
|
15
22
|
id: string;
|
|
16
23
|
content: string;
|
|
@@ -20,6 +27,9 @@ export interface WordFillStructuredFormQuestion {
|
|
|
20
27
|
caseSensitive?: boolean;
|
|
21
28
|
imageUrl?: string;
|
|
22
29
|
questionNumber?: number;
|
|
30
|
+
blankStyle?: WfsfBlankStyle;
|
|
31
|
+
viewMode?: string;
|
|
32
|
+
wordBank?: WfsfWordBankEntry[];
|
|
23
33
|
}
|
|
24
34
|
export interface ExamTakingPart {
|
|
25
35
|
id: string;
|
|
@@ -110,6 +120,8 @@ export declare function transformWordFillStructuredForm(questions: ExamTakingQue
|
|
|
110
120
|
groupContent: string;
|
|
111
121
|
groupImageUrl: string;
|
|
112
122
|
questions: {
|
|
123
|
+
wordBank?: WfsfWordBankEntry[];
|
|
124
|
+
viewMode?: string;
|
|
113
125
|
id: string;
|
|
114
126
|
title: string;
|
|
115
127
|
content: string;
|
|
@@ -117,5 +129,6 @@ export declare function transformWordFillStructuredForm(questions: ExamTakingQue
|
|
|
117
129
|
caseSensitive: boolean;
|
|
118
130
|
imageUrl: string;
|
|
119
131
|
questionNumber: number;
|
|
132
|
+
blankStyle: WfsfBlankStyle;
|
|
120
133
|
}[];
|
|
121
134
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function unwrap(t){return function(t){return"object"==typeof t&&null!==t&&"data"in t}(t)?t.data:t}export function unwrapAttempt(t){return"attempt"in t?t.attempt:t}export function groupQuestions(t){const n=t.examTemplate?.parts??[],e=new Map;for(const n of t.questions){const t=n.part_id??String(n.part_no??"default");e.set(t,[...e.get(t)??[],n])}return Array.from(e.entries()).map(([t,e])=>{const r=n.find(n=>String(n.id)===t);return{id:t,name:r?.name??`Part ${e[0]?.part_no??t}`,template:r,partId:t,partNo:e[0]?.part_no,instructions:r?.instructions,audioUrl:r?.audioUrl,questionType:r?.questionType??e[0]?.question_type,isGroup:r?.isGroup,group:r?.group,sections:r?.sections,viewMode:"string"==typeof r?.group?.viewMode?r.group.viewMode:void 0,startIndex:r?.startIndex,endIndex:r?.endIndex,questions:e.sort((t,n)=>t.question_number-n.question_number)}})}export function transformAnswerTheQuestion(t){return{instruction:n(t[0]?.content,"instruction"),imageUrl:n(t[0]?.content,"imageUrl"),title:n(t[0]?.content,"title"),groupContent:n(t[0]?.content,"groupContent"),questions:t.map(t=>({id:t.id,questionNumber:t.question_number,question:n(t.content,"question")||n(t.content,"text"),imageUrl:n(t.content,"imageUrl"),prefixText:n(t.content,"prefixText"),suffixText:n(t.content,"suffixText"),exampleAnswer:n(t.content,"exampleAnswer"),suggestedAnswers:r(t.content,"suggestedAnswers"),isExample:Boolean(t.is_example)}))}}export function transformMatchByWritingAnswer(t){return{instruction:n(t[0]?.content,"instruction"),groupImageUrl:n(t[0]?.content,"groupImageUrl"),options:o(t[0]?.content,"options").map(t=>({answer:String(t.answer??t.value??""),text:String(t.text??t.label??""),content:String(t.content??t.text??t.label??""),imageUrl:"string"==typeof t.imageUrl?t.imageUrl:void 0})),questions:t.map(t=>({id:t.id,questionNumber:t.question_number,question:n(t.content,"question")||n(t.content,"text"),imageUrl:n(t.content,"imageUrl"),exampleAnswer:n(t.content,"exampleAnswer"),isExample:Boolean(t.is_example)}))}}export function transformWordFillParagraph(t){const e=t[0];return{questionId:e?.id??"",paragraph:n(e?.content,"paragraph")||n(e?.content,"text"),title:n(e?.content,"title"),imageUrl:n(e?.content,"imageUrl"),wordBank:o(e?.content,"wordBank").map(t=>({word:String(t.word??t.text??""),isExample:Boolean(t.isExample)})),viewMode:n(e?.content,"viewMode"),instruction:n(e?.content,"instruction")}}export function transformWriteShortLetter(o){if(!o)return{prompt:"",requirements:[],minWords:void 0,maxWords:void 0,guideImages:[]};const i=t(o.content),s=t(i.instructions),
|
|
1
|
+
export function unwrap(t){return function(t){return"object"==typeof t&&null!==t&&"data"in t}(t)?t.data:t}export function unwrapAttempt(t){return"attempt"in t?t.attempt:t}export function groupQuestions(t){const n=t.examTemplate?.parts??[],e=new Map;for(const n of t.questions){const t=n.part_id??String(n.part_no??"default");e.set(t,[...e.get(t)??[],n])}return Array.from(e.entries()).map(([t,e])=>{const r=n.find(n=>String(n.id)===t);return{id:t,name:r?.name??`Part ${e[0]?.part_no??t}`,template:r,partId:t,partNo:e[0]?.part_no,instructions:r?.instructions,audioUrl:r?.audioUrl,questionType:r?.questionType??e[0]?.question_type,isGroup:r?.isGroup,group:r?.group,sections:r?.sections,viewMode:"string"==typeof r?.group?.viewMode?r.group.viewMode:void 0,startIndex:r?.startIndex,endIndex:r?.endIndex,questions:e.sort((t,n)=>t.question_number-n.question_number)}})}export function transformAnswerTheQuestion(t){return{instruction:n(t[0]?.content,"instruction"),imageUrl:n(t[0]?.content,"imageUrl"),title:n(t[0]?.content,"title"),groupContent:n(t[0]?.content,"groupContent"),questions:t.map(t=>({id:t.id,questionNumber:t.question_number,question:n(t.content,"question")||n(t.content,"text"),imageUrl:n(t.content,"imageUrl"),prefixText:n(t.content,"prefixText"),suffixText:n(t.content,"suffixText"),exampleAnswer:n(t.content,"exampleAnswer"),suggestedAnswers:r(t.content,"suggestedAnswers"),isExample:Boolean(t.is_example)}))}}export function transformMatchByWritingAnswer(t){return{instruction:n(t[0]?.content,"instruction"),groupImageUrl:n(t[0]?.content,"groupImageUrl"),options:o(t[0]?.content,"options").map(t=>({answer:String(t.answer??t.value??""),text:String(t.text??t.label??""),content:String(t.content??t.text??t.label??""),imageUrl:"string"==typeof t.imageUrl?t.imageUrl:void 0})),questions:t.map(t=>({id:t.id,questionNumber:t.question_number,question:n(t.content,"question")||n(t.content,"text"),imageUrl:n(t.content,"imageUrl"),exampleAnswer:n(t.content,"exampleAnswer"),isExample:Boolean(t.is_example)}))}}export function transformWordFillParagraph(t){const e=t[0];return{questionId:e?.id??"",paragraph:n(e?.content,"paragraph")||n(e?.content,"text"),title:n(e?.content,"title"),imageUrl:n(e?.content,"imageUrl"),wordBank:o(e?.content,"wordBank").map(t=>({word:String(t.word??t.text??""),isExample:Boolean(t.isExample)})),viewMode:n(e?.content,"viewMode"),instruction:n(e?.content,"instruction")}}export function transformWriteShortLetter(o){if(!o)return{prompt:"",requirements:[],minWords:void 0,maxWords:void 0,guideImages:[]};const i=t(o.content),s=t(i.instructions),a="string"==typeof s.mainInstruction?s.mainInstruction:"",u=Array.isArray(i.informations)?i.informations.filter(t=>"string"==typeof t):[],c=r(o.content,"guideImages"),p=e(o.content,"minWords"),m=e(o.content,"maxWords");if(a||u.length)return{prompt:a,requirements:u,minWords:p,maxWords:m,guideImages:c};return{prompt:(Array.isArray(i.contexts)?i.contexts:[]).map(t).filter(t=>"text"===t.type&&"string"==typeof t.text).map(t=>String(t.text)).join("\n")||n(o.content,"prompt")||n(o.content,"question"),requirements:r(o.content,"requirements"),minWords:p,maxWords:m,guideImages:c}}export function transformWordFillStructuredForm(e){const r=e[0],o=t=>{const n=String(t||"").toLowerCase();return"letter"===n||"box"===n?"letter":"phrase"===n||"sentence"===n?"phrase":"word"};return{instruction:n(r?.content,"instruction"),groupTitle:n(r?.content,"groupTitle"),groupContent:n(r?.content,"groupContent"),groupImageUrl:n(r?.content,"groupImageUrl"),questions:e.map(e=>{const r=e.content,s=e,a=s.correct_answer??s.answer,u=i(a,"answers"),c=Object.keys(u).length>0?u:i(r,"answers"),p=t(r),m=(t=>{if(!Array.isArray(t)||0===t.length)return;const n=t.map(t=>{if(null==t)return null;if("object"!=typeof t||Array.isArray(t))return null;const n=t;if(Array.isArray(n.options)){const t=n.options.map(t=>String(t??"").trim()).filter(t=>t.length>0);return t.length>=2?{options:t}:null}const e=String(n.word??"").trim();return e?n.isExample?{word:e,isExample:!0}:{word:e}:null});return n.some(t=>null!=t)?n:void 0})(p.wordBank),l=Boolean(m?.some(t=>null!=t&&"options"in t&&Array.isArray(t.options))),g=Boolean(m?.some(t=>null!=t&&"word"in t&&t.word)),d=n(r,"viewMode")||(l?"WITH_OPTIONS":g?"WITH_WORD_BANK":void 0);return{id:e.id,title:n(r,"title"),content:n(r,"content")||n(r,"html")||n(r,"text"),answers:c,caseSensitive:Boolean(t(a).caseSensitive??p.caseSensitive),imageUrl:n(r,"imageUrl"),questionNumber:e.question_number,blankStyle:o(n(r,"blankStyle")),...d?{viewMode:d}:{},...m?{wordBank:m}:{}}})}}function t(t){return"object"==typeof t&&null!==t?t:{}}function n(n,e){const r=t(n)[e];return"string"==typeof r?r:""}function e(n,e){const r=t(n)[e];return"number"==typeof r?r:void 0}function r(n,e){const r=t(n)[e];return Array.isArray(r)?r.filter(t=>"string"==typeof t):[]}function o(n,e){const r=t(n)[e];return Array.isArray(r)?r.map(t):[]}function i(n,e){const r=t(n)[e],o=t(r);return Object.fromEntries(Object.entries(o).map(([t,n])=>[t,String(n??"")]))}
|
|
@@ -10,6 +10,7 @@ export interface FillBlankQuestion {
|
|
|
10
10
|
verbHint?: string;
|
|
11
11
|
correctAnswer?: string;
|
|
12
12
|
imageUrl?: string;
|
|
13
|
+
audioUrl?: string;
|
|
13
14
|
hints?: string[];
|
|
14
15
|
isExample?: boolean;
|
|
15
16
|
}
|
|
@@ -123,6 +124,7 @@ export interface ChooseBestAnswerQuestion {
|
|
|
123
124
|
correctOptionId?: string;
|
|
124
125
|
correctOptionIds?: string[];
|
|
125
126
|
imageUrl?: string;
|
|
127
|
+
audioUrl?: string;
|
|
126
128
|
optionType?: 'text' | 'image';
|
|
127
129
|
multipleAnswers?: boolean;
|
|
128
130
|
explanation?: string;
|
|
@@ -134,6 +136,7 @@ export interface ChooseBestAnswerExample {
|
|
|
134
136
|
correctOptionId: string;
|
|
135
137
|
optionType?: 'text' | 'image';
|
|
136
138
|
imageUrl?: string;
|
|
139
|
+
audioUrl?: string;
|
|
137
140
|
}
|
|
138
141
|
export interface MoversChooseBestAnswerRendererProps {
|
|
139
142
|
partNumber: number;
|
|
@@ -313,6 +313,13 @@ export declare function transformWriteSentences(questions: ApiQuestion[]): {
|
|
|
313
313
|
title?: string;
|
|
314
314
|
groupContent?: string;
|
|
315
315
|
};
|
|
316
|
+
export type WfsfBlankStyle = 'letter' | 'word' | 'phrase';
|
|
317
|
+
export type WfsfWordBankEntry = {
|
|
318
|
+
options: string[];
|
|
319
|
+
} | {
|
|
320
|
+
word: string;
|
|
321
|
+
isExample?: boolean;
|
|
322
|
+
} | null;
|
|
316
323
|
export interface WordFillStructuredFormQuestion {
|
|
317
324
|
id: string;
|
|
318
325
|
questionNumber: number;
|
|
@@ -321,6 +328,12 @@ export interface WordFillStructuredFormQuestion {
|
|
|
321
328
|
content: string;
|
|
322
329
|
answers: Record<string, string>;
|
|
323
330
|
caseSensitive: boolean;
|
|
331
|
+
/** letter = square boxes; word / phrase = underline width */
|
|
332
|
+
blankStyle: WfsfBlankStyle;
|
|
333
|
+
/** WITH_OPTIONS when choice-inline options present (plan 0024). */
|
|
334
|
+
viewMode?: string;
|
|
335
|
+
/** Index i ↔ blank key "i" (or order of {n} appearance). */
|
|
336
|
+
wordBank?: WfsfWordBankEntry[];
|
|
324
337
|
}
|
|
325
338
|
export declare function transformWordFillStructuredForm(questions: ApiQuestion[]): {
|
|
326
339
|
questions: WordFillStructuredFormQuestion[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function groupQuestionsByPart(e,t){const n=new Map,o=new Map;for(const t of e){const e=o.get(t.part_id)||[];e.push(t),o.set(t.part_id,e)}for(const[e,r]of o.entries()){const o=[...r].sort((e,t)=>e.question_number-t.question_number),i=o[0];if(!i)continue;const s=t?.find(t=>String(t.id)===String(e)),a=void 0!==s?.id?Number(s.id):void 0,u=s?.name?.match(/\d+/),c=u?parseInt(u[0],10):i.part_no,l=s?.group,m=Boolean(s?.isGroup)&&"DOCUMENT"===l?.type,p=s?.sections??[],d=new Set(p.map(e=>e.questionType).filter(Boolean)),g=p.length>1&&d.size>1;if(m||g){const t=`${e}_part`;n.set(t,{partId:e,partNo:c,questionType:i.question_type,questions:o,name:s?.name,instructions:s?.instructions,audioUrl:s?.audioUrl,templateOrder:a,category:s?.category,points:s?.points,isGroup:!0,group:l,sections:s?.sections,startIndex:s?.startIndex,endIndex:s?.endIndex});continue}if(!s?.sections?.length){const t=`${e}_part`;n.set(t,{partId:e,partNo:c,questionType:i.question_type,questions:o,name:s?.name,instructions:s?.instructions,audioUrl:s?.audioUrl,templateOrder:a,category:s?.category,points:s?.points,isGroup:s?.isGroup,optionMode:s?.optionMode,optionCount:s?.optionCount,viewMode:s?.viewMode,defaultValue:s?.defaultValue,multipleAnswers:s?.multipleAnswers,questionConfig:s?.questionConfig,wordBankConfig:s?.wordBankConfig,group:s?.group,startIndex:s?.startIndex,endIndex:s?.endIndex});continue}for(const[t,r]of s.sections.entries()){const i=o.filter(e=>{const t=e.question_number-1;return t>=r.startIndex&&t<=r.endIndex});if(!i.length)continue;const u=`${e}_section_${t}`,l=Boolean(r.isGroup||r.group?.type);n.set(u,{partId:e,partNo:c,questionType:r.questionType||i[0].question_type,questions:i,name:s.name,instructions:r.instructions||r.name||s.instructions,audioUrl:s.audioUrl,templateOrder:a,category:s.category,points:s.points,sectionId:r.sectionId,isGroup:l,optionMode:r.optionMode,optionCount:r.optionCount,viewMode:r.viewMode,defaultValue:r.defaultValue,multipleAnswers:r.multipleAnswers,questionConfig:r.questionConfig,wordBankConfig:r.wordBankConfig,group:r.group,startIndex:r.startIndex,endIndex:r.endIndex})}}return Array.from(n.values()).sort((e,t)=>{const n=void 0===e.templateOrder||isNaN(e.templateOrder)?1/0:e.templateOrder,o=void 0===t.templateOrder||isNaN(t.templateOrder)?1/0:t.templateOrder;return n!==o?n-o:(e.questions[0]?.question_number||0)-(t.questions[0]?.question_number||0)})}export function transformFillInBlank(e){const t=e[0],n=t?.content,o=t?.questionGroup?.payload,r=[];for(const t of e){const e=t.content,n=t.is_example||!1,o=e.question||e.blanks?.[0]?.text||"";if([...o.matchAll(/\{(\d+)\}/g)].length>1){const i=o.split("\n").filter(e=>e.trim());for(const o of i){const i=o.match(/\{(\d+)\}/);if(!i)continue;const s=parseInt(i[1],10),a=o.split(/\{\d+\}/),u=a[0]?.trim()||"",c=a[1]?.trim()||"";r.push({id:`${t.id}-blank-${s}`,questionNumber:t.question_number,textBefore:u,textAfter:c,imageUrl:e.imageUrl,hints:e.hints,isExample:n,correctAnswer:n?t.correct_answer?.answers?.[s]:void 0})}}else{const i=o.match(/^(.*?)\{0\}(.*)$/),s=i?i[1].trim():o,a=i?i[2].trim():"";r.push({id:t.id,questionNumber:t.question_number,textBefore:s,textAfter:a,imageUrl:e.imageUrl,hints:e.hints,isExample:n,correctAnswer:n?t.correct_answer?.answers?.[0]:void 0})}}return{questions:r,title:n?.title||o?.title||"FILL IN THE BLANK",imageUrl:n?.imageUrl,audioUrl:n?.audioUrl,exampleText:n?.exampleText,exampleHighlight:n?.exampleHighlight,instruction:n?.instruction||"LISTEN AND WRITE",showHints:n?.showHints,groupContent:o?.content||o?.groupContent,groupTitle:o?.title,groupImageUrl:o?.mainImageUrl||o?.imageUrl}}export function transformWriteCorrectVerbForm(e){const t=e[0],n=t?.content;return{questions:e.map(e=>{const t=e.content,n=t.sentence||"",o=n.match(/^(.*?)\{0\}(.*)$/),r=o?o[1].trim():n,i=o?o[2].trim():"";return{id:e.id,questionNumber:e.question_number,textBefore:r,textAfter:i,verbHint:t.verbHint}}),title:"WRITE THE CORRECT VERB FORM",instruction:n?.instruction||"Write the correct form of the verb in parentheses."}}const e=["A","B","C","D","E","F"];export function transformChooseCorrectAnswer(t){const n=t[0]?.content,o=t[0]?.questionGroup?.payload,r=t.find(e=>e.is_example),i=t.filter(e=>!e.is_example);let s;if(r){const t=r.content,n=(t.options||[]).map((t,n)=>({id:`${r.id}-opt-${n}`,label:e[n]||String(n+1),text:t})),o="number"==typeof r.correct_answer?.answer?r.correct_answer.answer:-1;s={questionNumber:r.question_number,questionText:t.question||"",options:n,correctOptionId:o>=0?n[o]?.id||"":n[0]?.id||"",optionType:t.optionType||"text",imageUrl:t.imageUrl}}return{questions:i.map(t=>{const n=t.content,o=n.optionType||"text",r=(n.options||[]).map((n,o)=>({id:`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:n})),i=t.correct_answer?.answer,s=Array.isArray(i)?i.filter(e=>"number"==typeof e).map(e=>r[e]?.id).filter(e=>Boolean(e)):"number"==typeof i?[r[i]?.id].filter(e=>Boolean(e)):[];return{id:t.id,questionNumber:t.question_number,questionText:n.question||"",options:r,correctOptionId:s[0],correctOptionIds:s,imageUrl:n.imageUrl,optionType:o,multipleAnswers:Boolean(n.multipleAnswers||Array.isArray(i)),explanation:t.explanation}}),example:s,imageUrl:n?.imageUrl,groupImageUrl:o?.mainImageUrl||o?.imageUrl,groupTitle:o?.title,groupContent:o?.content,articles:o?.articles,audioUrl:n?.audioUrl,instruction:n?.instruction||"CHOOSE THE CORRECT ANSWER"}}export function transformChooseCorrectAdjective(t){return{questions:t.map(t=>{const n=t.content,o=n.sentence||"",r=o.match(/^(.*?)\{0\}(.*)$/),i=r?r[1]:o,s=r?r[2]:"";return{id:t.id,questionNumber:t.question_number,sentenceBefore:i,sentenceAfter:s,options:(n.options||[]).map((n,o)=>({id:`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:n}))}}),instruction:"CHOOSE THE CORRECT ADJECTIVE"}}export function transformWriteShortLetter(e){const t=e.content;if(t.instructions?.mainInstruction||t.informations?.length)return{prompt:t.instructions?.mainInstruction||"",requirements:t.informations,minWords:t.minWords,maxWords:t.maxWords,guideImages:t.guideImages};return{prompt:t.contexts?.filter(e=>"text"===e.type).map(e=>e.text).join("\n")||"",minWords:t.minWords,maxWords:t.maxWords,guideImages:t.guideImages}}export function transformColorObjects(e){const t=e[0],n=t?.content,o=n?.colorNodes?.map(e=>({id:e.id,color:e.color,label:e.label}))||n?.hintItems||[],r=n?.regionNodes?.map(e=>({id:e.id,x:e.x,y:e.y,width:e.width,height:e.height,correctHintId:e.linkedColorNodeId}))||n?.regions||[],i=n?.instructions;return{instruction:(i&&i.length>0?i.join(" "):n?.instruction)||"READ AND COLOR THE OBJECTS",instructions:i,imageUrl:n?.backgroundImageUrl||n?.imageUrl||"",audioUrl:n?.audioUrl,hintItems:o,regions:r}}export function transformPictureChoose(t){const n=t[0]?.content;return{subQuestions:t.map(t=>{const n=t.content;return{id:t.id,questionNumber:t.question_number,imageUrl:n.imageUrl||"",questionText:n.questionText,options:(n.options||[]).map((n,o)=>({id:n.id||`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:"string"==typeof n?n:n.text}))}}),instruction:n?.instruction||"LOOK AT THE PICTURE AND CHOOSE THE CORRECT ANSWER"}}export function transformPictureFillBlankChoose(t){const n=t[0]?.content;return{subQuestions:t.map(t=>{const n=t.content;return{id:t.id,questionNumber:t.question_number,imageUrl:n.imageUrl||"",question:n.question||"",options:(n.options||[]).map((n,o)=>({id:n.id||`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:"string"==typeof n?n:n.text}))}}),instruction:n?.instruction||"LOOK AT THE PICTURE, FILL IN THE BLANK AND CHOOSE THE ANSWER"}}export function transformReadingPassage(t){if(function(e){const t=e[0];if(!t)return!1;const n=t.content;return void 0!==n?.question&&!n?.questions&&void 0!==t.questionGroup?.payload?.passage}(t)){const n=t[0],o=n.questionGroup?.payload||{},r=t.map(t=>{const n=t.content;return{id:t.id,questionNumber:t.question_number,questionText:n?.question||"",options:(n?.options||[]).map((n,o)=>({id:`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:"string"==typeof n?n:String(n)}))}});return{passage:o.passage||"",passageTitle:o.passageTitle,passageImageUrl:o.passageImageUrl||o.mainImageUrl,instruction:o.instructions||"READ THE PASSAGE AND ANSWER QUESTIONS",questions:r}}const n=t[0],o=n?.content,r=o?.questions?.map((t,o)=>({id:t.id||`${n.id}-sq-${o}`,questionNumber:o+1,questionText:t.question,options:(t.options||[]).map((o,r)=>({id:`${t.id||n.id}-opt-${r}`,label:e[r]||String(r+1),text:o}))}))||[];return{passage:o?.passage||"",passageTitle:o?.passageTitle,passageImageUrl:o?.passageImageUrl||o?.mainImageUrl,instruction:o?.instructions?.mainInstruction||"READ THE PASSAGE AND ANSWER QUESTIONS",questions:r}}export function transformLabelPicture(e){const t=e[0],n=t?.content;return{imageUrl:n?.imageUrl||"",wordBank:n?.wordBank||[],labels:n?.labels?.map(e=>({id:e.id,number:e.number,isPreFilled:e.isPreFilled||!1,correctAnswer:e.correctAnswer}))||[],instruction:n?.instruction||"LABEL THE PICTURE"}}function t(e){return e&&"string"==typeof e.word&&!e.subQuestions}export function transformFillWordHint(e){const n=e[0],o=n?.content;if(e.length>1&&e.every(e=>t(e.content))){const t=n.questionGroup?.payload?.hintLetters||[];return{subQuestions:e.map(e=>{const t=e.content,n=t.word.replace(/\{\d+\}/,"_");return{id:e.id,questionNumber:e.question_number,imageUrl:t.imageUrl||"",word:n}}),hintLetters:t,instruction:o?.instruction||"LOOK AT THE PICTURE AND FILL IN THE MISSING LETTER"}}if(t(o)){const e=o,t=n.questionGroup?.payload?.hintLetters||[];return{subQuestions:function(e){const t=[],n=e.split(",").map(e=>e.trim());for(const e of n){let n;const o=/\{(\d+)\}/g;for(;null!==(n=o.exec(e));){const o=parseInt(n[1],10),r=e.replace(n[0],"_");t.push({index:o,displayWord:r})}}return t.sort((e,t)=>e.index-t.index),t}(e.word).map(t=>({id:`${n.id}-blank-${t.index}`,questionNumber:n.question_number,imageUrl:e.imageUrl||"",word:t.displayWord,blankIndex:t.index})),hintLetters:t,instruction:e.instruction||"LOOK AT THE PICTURE AND FILL IN THE MISSING LETTER"}}const r=o;return{subQuestions:r?.subQuestions?.map((e,t)=>({id:e.id,questionNumber:n.question_number+t,imageUrl:e.imageUrl||"",word:e.word||""}))||[],hintLetters:r?.hintLetters||n.questionGroup?.payload?.hintLetters||[],instruction:r?.instruction||"LOOK AT THE PICTURE AND FILL IN THE MISSING LETTER"}}export function transformGridFill(e){const t=e[0],n=t?.content;return{grid:n?.grid||[],rows:n?.rows||0,columns:n?.columns||0,instruction:n?.instruction||"FILL IN THE MISSING WORDS",disabledCells:n?.disabledCells||[]}}export function transformAnswerTheQuestion(e){const t=e[0],n=t?.questionGroup?.payload,o=t?.content;return{questions:e.map(e=>{const t=e.content,n=e.is_example||t.isExample||!1;return{id:e.id,questionNumber:e.question_number,question:(t.question||"").replace(/\{\d+\}/g,"______"),imageUrl:t.imageUrl,prefixText:t.prefixText,suffixText:t.suffixText,suggestedAnswers:t.suggestedAnswers,isExample:n,exampleAnswer:n?e.correct_answer?.answer:void 0}}),instruction:"ANSWER THE QUESTION",imageUrl:n?.mainImageUrl||n?.imageUrl||o?.imageUrl,title:o?.title,groupContent:n?.groupContent||o?.groupContent}}export function transformTrueFalse(e){const t=e[0]?.questionGroup?.payload;return{questions:e.map(e=>{const t=e.content,n=e.is_example||t.isExample||!1,o=n&&"boolean"==typeof e.correct_answer?.answer?e.correct_answer.answer:void 0;return{id:e.id,questionNumber:e.question_number,question:t.question||"",imageUrl:t.imageUrl,isExample:n,exampleCorrectAnswer:o}}),instruction:"READ AND CHOOSE TRUE OR FALSE",imageUrl:t?.mainImageUrl||t?.imageUrl,groupContent:t?.content||t?.groupContent}}export function transformWordOrdering(e){return{questions:e.map(e=>{const t=e.content,n=e.is_example||t.isExample||!1,o=Array.isArray(e.correct_answer?.answer)?e.correct_answer.answer:Array.isArray(t.answer)?t.answer:void 0;return{id:e.id,questionNumber:e.question_number,words:t.words||[],imageUrl:t.imageUrl,isExample:n,exampleAnswer:n?o:void 0}}),instruction:"ARRANGE THE LETTERS TO MAKE A WORD"}}export function transformWordFillParagraph(e){const t=e[0],n=t?.questionGroup?.payload,o=t?.content,r=o?.title||n?.title||e.find(e=>e.content?.title)?.content?.title,i=o?.wordBank||[],s=i.map(e=>"string"==typeof e?{word:e}:e),a=o?.viewMode,u=void 0!==o?.wordBank?.[0]?.options;let c;c="EMAIL"===a?"EMAIL":a||!o?.emailFrom&&!o?.emailTo?"DEFAULT"===a?"DEFAULT":"WITH_OPTIONS"===a||u?"WITH_OPTIONS":a||0!==i.length?"WITH_WORD_BANK":"DEFAULT":"EMAIL";const l=o?.emailFrom||o?.metadata?.emailFrom,m=o?.emailTo||o?.metadata?.emailTo;return{questionId:t?.id||"",paragraph:o?.paragraph||"",title:r,imageUrl:o?.imageUrl,wordBank:s,viewMode:c,instruction:"READ AND FILL IN THE BLANKS",exampleAnswer:o?.exampleAnswer,emailFrom:l,emailTo:m}}export function transformMatchByWritingAnswer(e){const t=e[0]?.questionGroup?.payload,n=e.some(e=>!!e.content?.askerName),o=e.map(e=>{const t=e.content,n=e.is_example||t.isExample||!1;return{id:e.id,questionNumber:e.question_number,question:t.question||"",imageUrl:t.imageUrl,isExample:n,exampleAnswer:n?e.correct_answer?.answer:void 0,askerName:t.askerName,answererName:t.answererName}}),r=t?.options?.map(e=>({answer:e.answer,imageUrl:e.imageUrl||"",content:e.content||""}))||[],i=n?e[0]?.content:void 0;return{questions:o,options:r,instruction:"LOOK AND WRITE THE ANSWER",viewMode:n?"CONVERSATION":"DEFAULT",groupImageUrl:t?.groupImageUrl||"",askerName:i?.askerName,answererName:i?.answererName}}export function transformWriteSentences(e){const t=e[0],n=t?.content,o=t?.questionGroup?.payload;return{questions:e.map(e=>({id:e.id,questionNumber:e.question_number})),instruction:n?.instruction||"WRITE SENTENCES ABOUT THE PICTURE",imageUrl:o?.mainImageUrl||o?.imageUrl||n?.imageUrl,title:n?.title,groupContent:o?.groupContent||n?.groupContent}}export function transformWordFillStructuredForm(e){const t=e[0],n=t?.questionGroup?.payload;return{questions:e.map(e=>{const t=e.content,n=e.correct_answer||{};let o=t?.content||"";const r=t?.blocks;return!o&&r?.length&&(o=r.map(e=>(e.heading?`<h3>${e.heading}</h3>`:"")+(e.content||"")).join("")),{id:e.id,questionNumber:e.question_number,title:t?.title||"",imageUrl:t?.imageUrl,content:o,answers:n?.answers||{},caseSensitive:n?.caseSensitive??t?.caseSensitive??!1}}),instruction:n?.instructions||"COMPLETE THE FORM BELOW",groupTitle:n?.title,groupContent:n?.content,groupImageUrl:n?.imageUrl,audioUrl:t?.audio_url||n?.audioUrl}}export function transformListenChooseObjects(e){const t=e[0],n=t?.content,o=t?.questionGroup?.payload||{};return{audioUrl:n?.audioUrl||"",backgroundImageUrl:o.backgroundImageUrl||"",objectNodes:o.objectNodes||[],correctObjectId:t?.correctAnswer?.objectId||t?.correct_answer?.objectId||"",isBackup:n?.isBackup||!1,instruction:"LISTEN AND CHOOSE THE CORRECT OBJECT"}}export function transformListenSpeakAnswer(e){return{questions:e.map(e=>{const t=e.content,n=e.questionGroup?.payload||{};return{id:e.id,questionNumber:e.question_number,audioUrl:t?.audioUrl||"",arrowNode:t?.arrowNode,backgroundImageUrl:n.backgroundImageUrl||n.imageUrl||"",isBackup:t?.isBackup||!1}}),instruction:"LISTEN AND SPEAK YOUR ANSWER"}}
|
|
1
|
+
export function groupQuestionsByPart(t,e){const n=new Map,o=new Map;for(const e of t){const t=o.get(e.part_id)||[];t.push(e),o.set(e.part_id,t)}for(const[t,r]of o.entries()){const o=[...r].sort((t,e)=>t.question_number-e.question_number),i=o[0];if(!i)continue;const s=e?.find(e=>String(e.id)===String(t)),a=void 0!==s?.id?Number(s.id):void 0,u=s?.name?.match(/\d+/),l=u?parseInt(u[0],10):i.part_no,c=s?.group,m=Boolean(s?.isGroup)&&"DOCUMENT"===c?.type,p=s?.sections??[],d=new Set(p.map(t=>t.questionType).filter(Boolean)),g=p.length>1&&d.size>1;if(m||g){const e=`${t}_part`;n.set(e,{partId:t,partNo:l,questionType:i.question_type,questions:o,name:s?.name,instructions:s?.instructions,audioUrl:s?.audioUrl,templateOrder:a,category:s?.category,points:s?.points,isGroup:!0,group:c,sections:s?.sections,startIndex:s?.startIndex,endIndex:s?.endIndex});continue}if(!s?.sections?.length){const e=`${t}_part`;n.set(e,{partId:t,partNo:l,questionType:i.question_type,questions:o,name:s?.name,instructions:s?.instructions,audioUrl:s?.audioUrl,templateOrder:a,category:s?.category,points:s?.points,isGroup:s?.isGroup,optionMode:s?.optionMode,optionCount:s?.optionCount,viewMode:s?.viewMode,defaultValue:s?.defaultValue,multipleAnswers:s?.multipleAnswers,questionConfig:s?.questionConfig,wordBankConfig:s?.wordBankConfig,group:s?.group,startIndex:s?.startIndex,endIndex:s?.endIndex});continue}for(const[e,r]of s.sections.entries()){const i=o.filter(t=>{const e=t.question_number-1;return e>=r.startIndex&&e<=r.endIndex});if(!i.length)continue;const u=`${t}_section_${e}`,c=Boolean(r.isGroup||r.group?.type);n.set(u,{partId:t,partNo:l,questionType:r.questionType||i[0].question_type,questions:i,name:s.name,instructions:r.instructions||r.name||s.instructions,audioUrl:s.audioUrl,templateOrder:a,category:s.category,points:s.points,sectionId:r.sectionId,isGroup:c,optionMode:r.optionMode,optionCount:r.optionCount,viewMode:r.viewMode,defaultValue:r.defaultValue,multipleAnswers:r.multipleAnswers,questionConfig:r.questionConfig,wordBankConfig:r.wordBankConfig,group:r.group,startIndex:r.startIndex,endIndex:r.endIndex})}}return Array.from(n.values()).sort((t,e)=>{const n=void 0===t.templateOrder||isNaN(t.templateOrder)?1/0:t.templateOrder,o=void 0===e.templateOrder||isNaN(e.templateOrder)?1/0:e.templateOrder;return n!==o?n-o:(t.questions[0]?.question_number||0)-(e.questions[0]?.question_number||0)})}export function transformFillInBlank(t){const e=t[0],n=e?.content,o=e?.questionGroup?.payload,r=[],i=t=>t.replace(/\*\*/g,"");for(const e of t){const t=e.content,n=e.is_example||!1,o=t.question||t.blanks?.[0]?.text||"";if([...o.matchAll(/\{(\d+)\}/g)].length>1){const s=o.split("\n").filter(t=>t.trim());for(const o of s){const s=o.match(/\{(\d+)\}/);if(!s)continue;const a=parseInt(s[1],10),u=o.split(/\{\d+\}/),l=i(u[0]?.trim()||""),c=i(u[1]?.trim()||"");r.push({id:`${e.id}-blank-${a}`,questionNumber:e.question_number,textBefore:l,textAfter:c,imageUrl:t.imageUrl,hints:t.hints,isExample:n,correctAnswer:n?e.correct_answer?.answers?.[a]:void 0})}}else{const s=o.match(/^(.*?)\{0\}(.*)$/),a=i(s?s[1].trim():o),u=i(s?s[2].trim():"");r.push({id:e.id,questionNumber:e.question_number,textBefore:a,textAfter:u,imageUrl:t.imageUrl,hints:t.hints,isExample:n,correctAnswer:n?e.correct_answer?.answers?.[0]:void 0})}}return{questions:r,title:n?.title||o?.title||"",imageUrl:o?n?.imageUrl:void 0,audioUrl:n?.audioUrl,exampleText:n?.exampleText,exampleHighlight:n?.exampleHighlight,instruction:n?.instruction||"LISTEN AND WRITE",showHints:n?.showHints,groupContent:o?.content||o?.groupContent,groupTitle:o?.title,groupImageUrl:o?.mainImageUrl||o?.imageUrl}}export function transformWriteCorrectVerbForm(t){const e=t[0],n=e?.content;return{questions:t.map(t=>{const e=t.content,n=e.sentence||"",o=n.match(/^(.*?)\{0\}(.*)$/),r=o?o[1].trim():n,i=o?o[2].trim():"";return{id:t.id,questionNumber:t.question_number,textBefore:r,textAfter:i,verbHint:e.verbHint}}),title:"WRITE THE CORRECT VERB FORM",instruction:n?.instruction||"Write the correct form of the verb in parentheses."}}const t=["A","B","C","D","E","F"];export function transformChooseCorrectAnswer(e){const n=e[0]?.content,o=e[0]?.questionGroup?.payload,r=e.find(t=>t.is_example),i=e.filter(t=>!t.is_example);let s;if(r){const e=r.content,n=(e.options||[]).map((e,n)=>{const o="object"==typeof e&&null!==e,i=o&&e.id?String(e.id):`${r.id}-opt-${n}`,s=o?e.text??e.content??"":String(e),a=o?e.imageUrl:void 0;return{id:i,label:t[n]||String(n+1),text:s,...a?{imageUrl:a}:{}}}),o=r.correct_answer?.answer??r.correct_answer?.optionId;let i="";if("string"==typeof o&&o){const t=n.find(t=>t.id===o);i=t?t.id:o}else"number"==typeof o&&o>=0&&o<n.length&&(i=n[o]?.id||"");s={questionNumber:r.question_number,questionText:e.question||"",options:n,correctOptionId:i||n[0]?.id||"",optionType:e.optionType||"text",imageUrl:e.imageUrl,audioUrl:e.audioUrl}}const a=i.map(e=>{const n=e.content,o=n.optionType||"text",r=(n.options||[]).map((n,o)=>{const r="object"==typeof n&&null!==n,i=r&&n.id?String(n.id):`${e.id}-opt-${o}`,s=r?n.text??n.content??"":String(n),a=r?n.imageUrl:void 0;return{id:i,label:t[o]||String(o+1),text:s,...a?{imageUrl:a}:{}}}),i=e.correct_answer?.answer??e.correct_answer?.optionId??e.correct_answer?.optionIds,s=t=>{if(null==t)return;const e=String(t),n=r.find(t=>t.id===e);if(n)return n.id;const o=e.match(/-opt-(\d+)$/);if(o){const t=parseInt(o[1],10);if(t>=0&&t<r.length)return r[t]?.id}if("number"==typeof t&&t>=0&&t<r.length)return r[t]?.id;const i=parseInt(e,10);return!isNaN(i)&&i>=0&&i<r.length&&!e.startsWith("opt-")?r[i]?.id:e};let a=[];if(Array.isArray(i))a=i.map(s).filter(t=>Boolean(t));else{const t=s(i);t&&(a=[t])}return{id:e.id,questionNumber:e.question_number,questionText:n.question||"",options:r,correctOptionId:a[0],correctOptionIds:a,imageUrl:n.imageUrl,audioUrl:n.audioUrl,optionType:o,multipleAnswers:Boolean(n.multipleAnswers||Array.isArray(i)),explanation:e.explanation}}),u=a.some(t=>!!t.audioUrl?.trim())||!!s?.audioUrl?.trim();return{questions:a,example:s,imageUrl:n?.imageUrl,groupImageUrl:o?.mainImageUrl||o?.imageUrl,groupTitle:o?.title,groupContent:o?.content,articles:o?.articles,audioUrl:u?void 0:n?.audioUrl,instruction:n?.instruction||"CHOOSE THE CORRECT ANSWER"}}export function transformChooseCorrectAdjective(e){return{questions:e.map(e=>{const n=e.content,o=n.sentence||"",r=o.match(/^(.*?)\{0\}(.*)$/),i=r?r[1]:o,s=r?r[2]:"";return{id:e.id,questionNumber:e.question_number,sentenceBefore:i,sentenceAfter:s,options:(n.options||[]).map((n,o)=>({id:`${e.id}-opt-${o}`,label:t[o]||String(o+1),text:n}))}}),instruction:"CHOOSE THE CORRECT ADJECTIVE"}}export function transformWriteShortLetter(t){const e=t.content;if(e.instructions?.mainInstruction||e.informations?.length)return{prompt:e.instructions?.mainInstruction||"",requirements:e.informations,minWords:e.minWords,maxWords:e.maxWords,guideImages:e.guideImages};return{prompt:e.contexts?.filter(t=>"text"===t.type).map(t=>t.text).join("\n")||"",minWords:e.minWords,maxWords:e.maxWords,guideImages:e.guideImages}}export function transformColorObjects(t){const e=t[0],n=e?.content,o=n?.colorNodes?.map(t=>({id:t.id,color:t.color,label:t.label}))||n?.hintItems||[],r=n?.regionNodes?.map(t=>({id:t.id,x:t.x,y:t.y,width:t.width,height:t.height,correctHintId:t.linkedColorNodeId}))||n?.regions||[],i=n?.instructions;return{instruction:(i&&i.length>0?i.join(" "):n?.instruction)||"READ AND COLOR THE OBJECTS",instructions:i,imageUrl:n?.backgroundImageUrl||n?.imageUrl||"",audioUrl:n?.audioUrl,hintItems:o,regions:r}}export function transformPictureChoose(e){const n=e[0]?.content;return{subQuestions:e.map(e=>{const n=e.content;return{id:e.id,questionNumber:e.question_number,imageUrl:n.imageUrl||"",questionText:n.questionText,options:(n.options||[]).map((n,o)=>({id:n.id||`${e.id}-opt-${o}`,label:t[o]||String(o+1),text:"string"==typeof n?n:n.text}))}}),instruction:n?.instruction||"LOOK AT THE PICTURE AND CHOOSE THE CORRECT ANSWER"}}export function transformPictureFillBlankChoose(e){const n=e[0]?.content;return{subQuestions:e.map(e=>{const n=e.content;return{id:e.id,questionNumber:e.question_number,imageUrl:n.imageUrl||"",question:n.question||"",options:(n.options||[]).map((n,o)=>({id:n.id||`${e.id}-opt-${o}`,label:t[o]||String(o+1),text:"string"==typeof n?n:n.text}))}}),instruction:n?.instruction||"LOOK AT THE PICTURE, FILL IN THE BLANK AND CHOOSE THE ANSWER"}}export function transformReadingPassage(e){if(function(t){const e=t[0];if(!e)return!1;const n=e.content;return void 0!==n?.question&&!n?.questions&&void 0!==e.questionGroup?.payload?.passage}(e)){const n=e[0],o=n.questionGroup?.payload||{},r=e.map(e=>{const n=e.content;return{id:e.id,questionNumber:e.question_number,questionText:n?.question||"",options:(n?.options||[]).map((n,o)=>({id:`${e.id}-opt-${o}`,label:t[o]||String(o+1),text:"string"==typeof n?n:String(n)}))}});return{passage:o.passage||"",passageTitle:o.passageTitle,passageImageUrl:o.passageImageUrl||o.mainImageUrl,instruction:o.instructions||"READ THE PASSAGE AND ANSWER QUESTIONS",questions:r}}const n=e[0],o=n?.content,r=o?.questions?.map((e,o)=>({id:e.id||`${n.id}-sq-${o}`,questionNumber:o+1,questionText:e.question,options:(e.options||[]).map((o,r)=>({id:`${e.id||n.id}-opt-${r}`,label:t[r]||String(r+1),text:o}))}))||[];return{passage:o?.passage||"",passageTitle:o?.passageTitle,passageImageUrl:o?.passageImageUrl||o?.mainImageUrl,instruction:o?.instructions?.mainInstruction||"READ THE PASSAGE AND ANSWER QUESTIONS",questions:r}}export function transformLabelPicture(t){const e=t[0],n=e?.content;return{imageUrl:n?.imageUrl||"",wordBank:n?.wordBank||[],labels:n?.labels?.map(t=>({id:t.id,number:t.number,isPreFilled:t.isPreFilled||!1,correctAnswer:t.correctAnswer}))||[],instruction:n?.instruction||"LABEL THE PICTURE"}}function e(t){return t&&"string"==typeof t.word&&!t.subQuestions}export function transformFillWordHint(t){const n=t[0],o=n?.content;if(t.length>1&&t.every(t=>e(t.content))){const e=n.questionGroup?.payload?.hintLetters||[];return{subQuestions:t.map(t=>{const e=t.content,n=e.word.replace(/\{\d+\}/,"_");return{id:t.id,questionNumber:t.question_number,imageUrl:e.imageUrl||"",word:n}}),hintLetters:e,instruction:o?.instruction||"LOOK AT THE PICTURE AND FILL IN THE MISSING LETTER"}}if(e(o)){const t=o,e=n.questionGroup?.payload?.hintLetters||[];return{subQuestions:function(t){const e=[],n=t.split(",").map(t=>t.trim());for(const t of n){let n;const o=/\{(\d+)\}/g;for(;null!==(n=o.exec(t));){const o=parseInt(n[1],10),r=t.replace(n[0],"_");e.push({index:o,displayWord:r})}}return e.sort((t,e)=>t.index-e.index),e}(t.word).map(e=>({id:`${n.id}-blank-${e.index}`,questionNumber:n.question_number,imageUrl:t.imageUrl||"",word:e.displayWord,blankIndex:e.index})),hintLetters:e,instruction:t.instruction||"LOOK AT THE PICTURE AND FILL IN THE MISSING LETTER"}}const r=o;return{subQuestions:r?.subQuestions?.map((t,e)=>({id:t.id,questionNumber:n.question_number+e,imageUrl:t.imageUrl||"",word:t.word||""}))||[],hintLetters:r?.hintLetters||n.questionGroup?.payload?.hintLetters||[],instruction:r?.instruction||"LOOK AT THE PICTURE AND FILL IN THE MISSING LETTER"}}export function transformGridFill(t){const e=t[0],n=e?.content;return{grid:n?.grid||[],rows:n?.rows||0,columns:n?.columns||0,instruction:n?.instruction||"FILL IN THE MISSING WORDS",disabledCells:n?.disabledCells||[]}}export function transformAnswerTheQuestion(t){const e=t[0],n=e?.questionGroup?.payload,o=e?.content;return{questions:t.map(t=>{const e=t.content,n=t.is_example||e.isExample||!1;return{id:t.id,questionNumber:t.question_number,question:(e.question||"").replace(/\{\d+\}/g,"______"),imageUrl:e.imageUrl,prefixText:e.prefixText,suffixText:e.suffixText,suggestedAnswers:e.suggestedAnswers,isExample:n,exampleAnswer:n?t.correct_answer?.answer:void 0}}),instruction:"ANSWER THE QUESTION",imageUrl:n?.mainImageUrl||n?.imageUrl||o?.imageUrl,title:o?.title,groupContent:n?.groupContent||o?.groupContent}}export function transformTrueFalse(t){const e=t[0]?.questionGroup?.payload;return{questions:t.map(t=>{const e=t.content,n=t.is_example||e.isExample||!1,o=n&&"boolean"==typeof t.correct_answer?.answer?t.correct_answer.answer:void 0;return{id:t.id,questionNumber:t.question_number,question:e.question||"",imageUrl:e.imageUrl,isExample:n,exampleCorrectAnswer:o}}),instruction:"READ AND CHOOSE TRUE OR FALSE",imageUrl:e?.mainImageUrl||e?.imageUrl,groupContent:e?.content||e?.groupContent}}export function transformWordOrdering(t){return{questions:t.map(t=>{const e=t.content,n=t.is_example||e.isExample||!1,o=Array.isArray(t.correct_answer?.answer)?t.correct_answer.answer:Array.isArray(e.answer)?e.answer:void 0;return{id:t.id,questionNumber:t.question_number,words:e.words||[],imageUrl:e.imageUrl,isExample:n,exampleAnswer:n?o:void 0}}),instruction:"ARRANGE THE LETTERS TO MAKE A WORD"}}export function transformWordFillParagraph(t){const e=t[0],n=e?.questionGroup?.payload,o=e?.content,r=o?.title||n?.title||t.find(t=>t.content?.title)?.content?.title,i=o?.wordBank||[],s=i.map(t=>"string"==typeof t?{word:t}:t),a=o?.viewMode,u=void 0!==o?.wordBank?.[0]?.options;let l;l="EMAIL"===a?"EMAIL":a||!o?.emailFrom&&!o?.emailTo?"DEFAULT"===a?"DEFAULT":"WITH_OPTIONS"===a||u?"WITH_OPTIONS":a||0!==i.length?"WITH_WORD_BANK":"DEFAULT":"EMAIL";const c=o?.emailFrom||o?.metadata?.emailFrom,m=o?.emailTo||o?.metadata?.emailTo;return{questionId:e?.id||"",paragraph:o?.paragraph||"",title:r,imageUrl:o?.imageUrl,wordBank:s,viewMode:l,instruction:"READ AND FILL IN THE BLANKS",exampleAnswer:o?.exampleAnswer,emailFrom:c,emailTo:m}}export function transformMatchByWritingAnswer(t){const e=t[0]?.questionGroup?.payload,n=t.some(t=>!!t.content?.askerName),o=t.map(t=>{const e=t.content,n=t.is_example||e.isExample||!1;return{id:t.id,questionNumber:t.question_number,question:e.question||"",imageUrl:e.imageUrl,isExample:n,exampleAnswer:n?t.correct_answer?.answer:void 0,askerName:e.askerName,answererName:e.answererName}}),r=e?.options?.map(t=>({answer:t.answer,imageUrl:t.imageUrl||"",content:t.content||""}))||[],i=n?t[0]?.content:void 0;return{questions:o,options:r,instruction:"LOOK AND WRITE THE ANSWER",viewMode:n?"CONVERSATION":"DEFAULT",groupImageUrl:e?.groupImageUrl||"",askerName:i?.askerName,answererName:i?.answererName}}export function transformWriteSentences(t){const e=t[0],n=e?.content,o=e?.questionGroup?.payload;return{questions:t.map(t=>({id:t.id,questionNumber:t.question_number})),instruction:n?.instruction||"WRITE SENTENCES ABOUT THE PICTURE",imageUrl:o?.mainImageUrl||o?.imageUrl||n?.imageUrl,title:n?.title,groupContent:o?.groupContent||n?.groupContent}}function n(t){const e=String(t||"").toLowerCase();return"letter"===e||"box"===e?"letter":"phrase"===e||"sentence"===e?"phrase":"word"}export function transformWordFillStructuredForm(t){const e=t[0],o=e?.questionGroup?.payload;return{questions:t.map(t=>{const e=t.content,o=t.correct_answer||{};let r=e?.content||"";const i=e?.blocks;!r&&i?.length&&(r=i.map(t=>(t.heading?`<h3>${t.heading}</h3>`:"")+(t.content||"")).join(""));const s=function(t){if(!Array.isArray(t)||0===t.length)return;const e=t.map(t=>{if(null==t)return null;if("object"!=typeof t||Array.isArray(t))return null;const e=t;if(Array.isArray(e.options)){const t=e.options.map(t=>String(t??"").trim()).filter(t=>t.length>0);return t.length>=2?{options:t}:null}const n=String(e.word??"").trim();return n?e.isExample?{word:n,isExample:!0}:{word:n}:null});return e.some(t=>null!=t)?e:void 0}(e?.wordBank),a=Boolean(s?.some(t=>null!=t&&"options"in t&&Array.isArray(t.options))),u=Boolean(s?.some(t=>null!=t&&"word"in t&&t.word)),l=e?.viewMode||(a?"WITH_OPTIONS":u?"WITH_WORD_BANK":void 0);return{id:t.id,questionNumber:t.question_number,title:e?.title||"",imageUrl:e?.imageUrl,content:r,answers:o?.answers||{},caseSensitive:o?.caseSensitive??e?.caseSensitive??!1,blankStyle:n(e?.blankStyle),...l?{viewMode:l}:{},...s?{wordBank:s}:{}}}),instruction:o?.instructions||"COMPLETE THE FORM BELOW",groupTitle:o?.title,groupContent:o?.content,groupImageUrl:o?.imageUrl,audioUrl:e?.audio_url||o?.audioUrl}}export function transformListenChooseObjects(t){const e=t[0],n=e?.content,o=e?.questionGroup?.payload||{};return{audioUrl:n?.audioUrl||"",backgroundImageUrl:o.backgroundImageUrl||"",objectNodes:o.objectNodes||[],correctObjectId:e?.correctAnswer?.objectId||e?.correct_answer?.objectId||"",isBackup:n?.isBackup||!1,instruction:"LISTEN AND CHOOSE THE CORRECT OBJECT"}}export function transformListenSpeakAnswer(t){return{questions:t.map(t=>{const e=t.content,n=t.questionGroup?.payload||{};return{id:t.id,questionNumber:t.question_number,audioUrl:e?.audioUrl||"",arrowNode:e?.arrowNode,backgroundImageUrl:n.backgroundImageUrl||n.imageUrl||"",isBackup:e?.isBackup||!1}}),instruction:"LISTEN AND SPEAK YOUR ANSWER"}}
|