ENCOA-222 & ENCOA-223

ENCOA-222: Added an option for non-assignment exams to view the
transcript of a Listening audio;

ENCOA-223: Updated the Listening exam to show all of the
exercises/questions of each part on a single page;
This commit is contained in:
Tiago Ribeiro
2024-11-11 19:14:16 +00:00
parent 711a0743c2
commit 1787e3ed53
16 changed files with 661 additions and 607 deletions

View File

@@ -1,11 +1,11 @@
import {MatchSentenceExerciseSentence, MatchSentencesExercise} from "@/interfaces/exam";
import { MatchSentenceExerciseSentence, MatchSentencesExercise } from "@/interfaces/exam";
import clsx from "clsx";
import LineTo from "react-lineto";
import {CommonProps} from ".";
import {errorButtonStyle, infoButtonStyle} from "@/constants/buttonStyles";
import {mdiArrowLeft, mdiArrowRight} from "@mdi/js";
import { CommonProps } from ".";
import { errorButtonStyle, infoButtonStyle } from "@/constants/buttonStyles";
import { mdiArrowLeft, mdiArrowRight } from "@mdi/js";
import Icon from "@mdi/react";
import {Fragment} from "react";
import { Fragment } from "react";
import Button from "../Low/Button";
import Xarrow from "react-xarrows";
import useExamStore from "@/stores/examStore";
@@ -15,7 +15,7 @@ function QuestionSolutionArea({
userSolution,
}: {
question: MatchSentenceExerciseSentence;
userSolution?: {question: string; option: string};
userSolution?: { question: string; option: string };
}) {
return (
<div className="grid grid-cols-3 gap-4">
@@ -26,8 +26,8 @@ function QuestionSolutionArea({
!userSolution
? "bg-mti-gray-davy"
: userSolution.option.toString() === question.solution.toString()
? "bg-mti-purple"
: "bg-mti-rose",
? "bg-mti-purple"
: "bg-mti-rose",
"transition duration-300 ease-in-out",
)}>
{question.id}
@@ -40,8 +40,8 @@ function QuestionSolutionArea({
!userSolution
? "border-mti-gray-davy"
: userSolution.option.toString() === question.solution.toString()
? "border-mti-purple"
: "border-mti-rose",
? "border-mti-purple"
: "border-mti-rose",
)}>
<span className="line-through">
{userSolution && userSolution?.option.toString() !== question.solution.toString() && `Paragraph ${userSolution.option}`}
@@ -61,8 +61,9 @@ export default function MatchSentencesSolutions({
userSolutions,
onNext,
onBack,
disableProgressButtons = false
}: MatchSentencesExercise & CommonProps) {
const {questionIndex, setQuestionIndex, partIndex, exam} = useExamStore((state) => state);
const { questionIndex, setQuestionIndex, partIndex, exam } = useExamStore((state) => state);
const calculateScore = () => {
const total = sentences.length;
@@ -71,30 +72,34 @@ export default function MatchSentencesSolutions({
).length;
const missing = total - userSolutions.filter((x) => sentences.find((y) => y.id.toString() === x.question.toString())).length;
return {total, correct, missing};
return { total, correct, missing };
};
const progressButtons = () => (
<div className="flex justify-between w-full gap-8">
<Button
color="purple"
variant="outline"
onClick={() => onBack({ exercise: id, solutions: userSolutions, score: calculateScore(), type })}
className="max-w-[200px] w-full"
disabled={exam && typeof partIndex !== "undefined" && exam.module === "level" && questionIndex === 0 && partIndex === 0}>
Back
</Button>
<Button
color="purple"
onClick={() => onNext({ exercise: id, solutions: userSolutions, score: calculateScore(), type })}
className="max-w-[200px] self-end w-full">
Next
</Button>
</div>
)
return (
<div className="flex flex-col gap-4 mt-4">
<div className="flex justify-between w-full gap-8">
<Button
color="purple"
variant="outline"
onClick={() => onBack({exercise: id, solutions: userSolutions, score: calculateScore(), type})}
className="max-w-[200px] w-full"
disabled={exam && typeof partIndex !== "undefined" && exam.module === "level" && questionIndex === 0 && partIndex === 0}>
Back
</Button>
{!disableProgressButtons && progressButtons()}
<Button
color="purple"
onClick={() => onNext({exercise: id, solutions: userSolutions, score: calculateScore(), type})}
className="max-w-[200px] self-end w-full">
Next
</Button>
</div>
<div className="flex flex-col gap-4 mt-4 h-full w-full mb-20">
<div className={clsx("flex flex-col gap-4 mt-4 h-full w-full", !disableProgressButtons && "mb-20")}>
<span className="text-sm w-full leading-6">
{prompt.split("\\n").map((line, index) => (
<Fragment key={index}>
@@ -128,23 +133,7 @@ export default function MatchSentencesSolutions({
</div>
</div>
<div className="self-end flex justify-between w-full gap-8 absolute bottom-8 left-0 px-8">
<Button
color="purple"
variant="outline"
onClick={() => onBack({exercise: id, solutions: userSolutions, score: calculateScore(), type})}
className="max-w-[200px] w-full"
disabled={exam && typeof partIndex !== "undefined" && exam.module === "level" && questionIndex === 0 && partIndex === 0}>
Back
</Button>
<Button
color="purple"
onClick={() => onNext({exercise: id, solutions: userSolutions, score: calculateScore(), type})}
className="max-w-[200px] self-end w-full">
Next
</Button>
</div>
{!disableProgressButtons && progressButtons()}
</div>
);
}