From 7fd56357e0cdba4092214261e9002ee88b85865e Mon Sep 17 00:00:00 2001 From: Carlos Mesquita Date: Tue, 6 Aug 2024 17:02:17 +0100 Subject: [PATCH] UI changes to Solutions (Writing, Speaking and Interactive Speaking) as requested --- .../Solutions/InteractiveSpeaking.tsx | 113 +++++++----------- src/components/Solutions/Speaking.tsx | 59 ++++----- src/components/Solutions/Writing.tsx | 47 ++++---- src/interfaces/exam.ts | 28 +++-- 4 files changed, 115 insertions(+), 132 deletions(-) diff --git a/src/components/Solutions/InteractiveSpeaking.tsx b/src/components/Solutions/InteractiveSpeaking.tsx index f5c657d4..6038e1a9 100644 --- a/src/components/Solutions/InteractiveSpeaking.tsx +++ b/src/components/Solutions/InteractiveSpeaking.tsx @@ -24,7 +24,7 @@ export default function InteractiveSpeaking({ onBack, }: InteractiveSpeakingExercise & CommonProps) { const [solutionsURL, setSolutionsURL] = useState([]); - const [diffNumber, setDiffNumber] = useState<0 | 1 | 2 | 3>(0); + const [diffNumber, setDiffNumber] = useState(0); useEffect(() => { if (userSolutions && userSolutions.length > 0 && userSolutions[0].solution) { @@ -115,13 +115,13 @@ export default function InteractiveSpeaking({ {userSolutions && userSolutions.length > 0 && userSolutions[0].evaluation && - userSolutions[0].evaluation[`transcript_${(index + 1) as 1 | 2 | 3}`] && - userSolutions[0].evaluation[`fixed_text_${(index + 1) as 1 | 2 | 3}`] && ( + userSolutions[0].evaluation[`transcript_${(index + 1)}`] && + userSolutions[0].evaluation[`fixed_text_${(index + 1)}`] && ( )} @@ -144,9 +144,20 @@ export default function InteractiveSpeaking({ })} {userSolutions[0].evaluation && - Object.keys(userSolutions[0].evaluation).filter((x) => x.startsWith("perfect_answer")).length === 3 ? ( + Object.keys(userSolutions[0].evaluation).filter((x) => x.startsWith("perfect_answer")).length > 0 ? ( + + clsx( + "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", + "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", + "transition duration-300 ease-in-out", + selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", + ) + }> + General Feedback + clsx( @@ -158,70 +169,22 @@ export default function InteractiveSpeaking({ }> Evaluation - - clsx( - "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", - "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", - "transition duration-300 ease-in-out", - selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", - ) - }> - Recommended Answer (Prompt 1) - - - clsx( - "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", - "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", - "transition duration-300 ease-in-out", - selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", - ) - }> - Recommended Answer (Prompt 2) - - - clsx( - "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", - "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", - "transition duration-300 ease-in-out", - selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", - ) - }> - Recommended Answer (Prompt 3) - - - clsx( - "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", - "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", - "transition duration-300 ease-in-out", - selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", - ) - }> - Global Overview - + {Object.keys(userSolutions[0].evaluation).filter((x) => x.startsWith("perfect_answer")).map((key, index) => ( + + clsx( + "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", + "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", + "transition duration-300 ease-in-out", + selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", + ) + }> + Recommended Answer
(Prompt {index + 1}) +
+ ))}
- - {userSolutions[0].evaluation!.comment} - - - - {userSolutions[0].evaluation!.perfect_answer_1!.answer.replaceAll(/\s{2,}/g, "\n\n")} - - - - - {userSolutions[0].evaluation!.perfect_answer_2!.answer.replaceAll(/\s{2,}/g, "\n\n")} - - - - - {userSolutions[0].evaluation!.perfect_answer_3!.answer.replaceAll(/\s{2,}/g, "\n\n")} - -
{Object.keys(userSolutions[0].evaluation!.task_response).map((key) => { @@ -230,15 +193,25 @@ export default function InteractiveSpeaking({ return (
- +
{key}: Level {grade} - - {typeof taskResponse !== "number" && {taskResponse.comment}} +
+ {typeof taskResponse !== "number" && {taskResponse.comment}}
); })}
+ + {userSolutions[0].evaluation!.comment} + + {Object.keys(userSolutions[0].evaluation).filter((x) => x.startsWith("perfect_answer")).map((key, index) => ( + + + {userSolutions[0].evaluation![`perfect_answer_${(index + 1)}`].answer.replaceAll(/\s{2,}/g, "\n\n")} + + + ))}
) : ( diff --git a/src/components/Solutions/Speaking.tsx b/src/components/Solutions/Speaking.tsx index 6b1fef98..90501894 100644 --- a/src/components/Solutions/Speaking.tsx +++ b/src/components/Solutions/Speaking.tsx @@ -138,7 +138,7 @@ export default function Speaking({id, type, title, video_url, text, prompts, use })} {userSolutions[0].evaluation && - (userSolutions[0].evaluation.perfect_answer || userSolutions[0].evaluation.perfect_answer_1) ? ( + (userSolutions[0].evaluation.perfect_answer || userSolutions[0].evaluation.perfect_answer_1) ? ( + General Feedback + + + clsx( + "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", + "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", + "transition duration-300 ease-in-out", + selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", + ) + }> Evaluation + className={({ selected }) => clsx( "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", @@ -163,30 +174,9 @@ export default function Speaking({id, type, title, video_url, text, prompts, use }> Recommended Answer - - clsx( - "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", - "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", - "transition duration-300 ease-in-out", - selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", - ) - }> - Global Overview - - - {userSolutions[0].evaluation!.comment} - - - - {userSolutions[0].evaluation!.perfect_answer && - userSolutions[0].evaluation!.perfect_answer.replaceAll(/\s{2,}/g, "\n\n")} - {userSolutions[0].evaluation!.perfect_answer_1 && - userSolutions[0].evaluation!.perfect_answer_1.replaceAll(/\s{2,}/g, "\n\n")} - - + {/* General Feedback */}
{Object.keys(userSolutions[0].evaluation!.task_response).map((key) => { @@ -195,15 +185,28 @@ export default function Speaking({id, type, title, video_url, text, prompts, use return (
- +
{key}: Level {grade} - - {typeof taskResponse !== "number" && {taskResponse.comment}} +
+ {typeof taskResponse !== "number" && {taskResponse.comment}}
); })}
+ {/* Evaluation */} + + {userSolutions[0].evaluation!.comment} + + {/* Recommended Answer */} + + + {userSolutions[0].evaluation!.perfect_answer && + userSolutions[0].evaluation!.perfect_answer.replaceAll(/\s{2,}/g, "\n\n")} + {userSolutions[0].evaluation!.perfect_answer_1 && + userSolutions[0].evaluation!.perfect_answer_1.replaceAll(/\s{2,}/g, "\n\n")} + +
) : ( @@ -224,7 +227,7 @@ export default function Speaking({id, type, title, video_url, text, prompts, use onBack({ exercise: id, solutions: userSolutions, - score: {total: 100, missing: 0, correct: speakingReverseMarking[userSolutions[0]!.evaluation!.overall] || 0}, + score: { total: 100, missing: 0, correct: speakingReverseMarking[userSolutions[0]!.evaluation!.overall] || 0 }, type, }) } diff --git a/src/components/Solutions/Writing.tsx b/src/components/Solutions/Writing.tsx index e24aab44..37eea2cf 100644 --- a/src/components/Solutions/Writing.tsx +++ b/src/components/Solutions/Writing.tsx @@ -137,6 +137,17 @@ export default function Writing({id, type, prompt, attachment, userSolutions, on {userSolutions[0].evaluation && userSolutions[0].evaluation.perfect_answer ? ( + + clsx( + "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-writing/80", + "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-writing focus:outline-none focus:ring-2", + "transition duration-300 ease-in-out", + selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-writing", + ) + }> + General Feedback + clsx( @@ -159,17 +170,6 @@ export default function Writing({id, type, prompt, attachment, userSolutions, on }> Recommended Answer - - clsx( - "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-writing/80", - "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-writing focus:outline-none focus:ring-2", - "transition duration-300 ease-in-out", - selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-writing", - ) - }> - Global Overview - {aiEval && user?.type !== "student" && ( @@ -185,14 +185,7 @@ export default function Writing({id, type, prompt, attachment, userSolutions, on )} - - {userSolutions[0].evaluation!.comment} - - - - {userSolutions[0].evaluation!.perfect_answer.replaceAll(/\s{2,}/g, "\n\n").replaceAll("\\n", "\n")} - - + {/* Global */}
{Object.keys(userSolutions[0].evaluation!.task_response).map((key) => { @@ -201,15 +194,25 @@ export default function Writing({id, type, prompt, attachment, userSolutions, on return (
- +
{key}: Level {grade} - - {typeof taskResponse !== "number" && {taskResponse.comment}} +
+ {typeof taskResponse !== "number" && {taskResponse.comment}}
); })}
+ {/* Evaluation */} + + {userSolutions[0].evaluation!.comment} + + {/* Recommended Answer */} + + + {userSolutions[0].evaluation!.perfect_answer.replaceAll(/\s{2,}/g, "\n\n").replaceAll("\\n", "\n")} + + {aiEval && user?.type !== "student" && ( diff --git a/src/interfaces/exam.ts b/src/interfaces/exam.ts index a7756dc5..1918882d 100644 --- a/src/interfaces/exam.ts +++ b/src/interfaces/exam.ts @@ -1,4 +1,4 @@ -import {Module} from "."; +import { Module } from "."; export type Exam = ReadingExam | ListeningExam | WritingExam | SpeakingExam | LevelExam; export type Variant = "full" | "partial"; @@ -115,17 +115,21 @@ export interface Evaluation { misspelled_pairs?: {correction: string | null; misspelled: string}[]; } -interface InteractiveSpeakingEvaluation extends Evaluation { - perfect_answer_1?: {answer: string}; - transcript_1?: string; - fixed_text_1?: string; - perfect_answer_2?: {answer: string}; - transcript_2?: string; - fixed_text_2?: string; - perfect_answer_3?: {answer: string}; - transcript_3?: string; - fixed_text_3?: string; -} + +type InteractivePerfectAnswerKey = `perfect_answer_${number}`; +type InteractiveTranscriptKey = `transcript_${number}`; +type InteractiveFixedTextKey = `fixed_text_${number}`; + +type InteractivePerfectAnswerType = { [key in InteractivePerfectAnswerKey]: { answer: string } }; +type InteractiveTranscriptType = { [key in InteractiveTranscriptKey]?: string }; +type InteractiveFixedTextType = { [key in InteractiveFixedTextKey]?: string }; + +interface InteractiveSpeakingEvaluation extends Evaluation, +InteractivePerfectAnswerType, +InteractiveTranscriptType, +InteractiveFixedTextType +{} + interface SpeakingEvaluation extends CommonEvaluation { perfect_answer_1?: string;