Implemented the Reading and Listening initial screens according to the new designs, creating new components as needed

This commit is contained in:
Tiago Ribeiro
2023-06-15 14:43:29 +01:00
parent 65ebdd7dde
commit 2d46bad40f
13 changed files with 272 additions and 85 deletions

View File

@@ -6,6 +6,9 @@ import clsx from "clsx";
import {infoButtonStyle} from "@/constants/buttonStyles";
import {renderExercise} from "@/components/Exercises";
import {renderSolution} from "@/components/Solutions";
import ModuleTitle from "@/components/Medium/ModuleTitle";
import AudioPlayer from "@/components/Low/AudioPlayer";
import Button from "@/components/Low/Button";
interface Props {
exam: ListeningExam;
@@ -42,37 +45,31 @@ export default function Listening({exam, showSolutions = false, onFinish}: Props
};
const renderAudioPlayer = () => (
<>
{exerciseIndex === -1 && (
<div className="flex flex-col">
<span className="text-lg font-semibold">Please listen to the following audio attentively.</span>
{exam.audio.repeatableTimes > 0 ? (
<span className="self-center text-sm">
You will only be allowed to listen to the audio {exam.audio.repeatableTimes} time(s).
</span>
) : (
<span className="self-center text-sm">You may listen to the audio as many times as you would like.</span>
)}
</div>
)}
<div className="rounded-xl flex flex-col gap-4 items-center w-full overflow-auto">
{exam.audio.repeatableTimes > 0 && (
<>{exam.audio.repeatableTimes <= timesListened && <span>You are no longer allowed to listen to the audio again.</span>}</>
)}
{exam.audio.repeatableTimes > 0 && timesListened < exam.audio.repeatableTimes && (
<audio preload="auto" controls autoPlay onPlay={() => setTimesListened((prev) => prev + 1)}>
<source src={exam.audio.source} type="audio/mpeg" />
Your browser does not support the audio element
</audio>
)}
<div className="flex flex-col gap-8 w-full bg-mti-gray-seasalt rounded-xl py-8 px-16">
<div className="flex flex-col w-full gap-2">
<h4 className="text-xl font-semibold">Please listen to the following audio attentively.</h4>
<span className="text-base">
{exam.audio.repeatableTimes > 0
? `You will only be allowed to listen to the audio ${exam.audio.repeatableTimes - timesListened} time(s).`
: "You may listen to the audio as many times as you would like."}
</span>
</div>
</>
<div className="rounded-xl flex flex-col gap-4 items-center w-full h-fit">
<AudioPlayer
src="https://assets.mixkit.co/active_storage/sfx/213/213-preview.mp3"
color="listening"
onEnd={() => setTimesListened((prev) => prev + 1)}
disabled={timesListened === exam.audio.repeatableTimes}
/>
</div>
</div>
);
return (
<>
<div className="w-full relative flex flex-col gap-8 items-center justify-center p-8 px-16 overflow-hidden">
{renderAudioPlayer()}
<div className="flex flex-col h-full w-full gap-8 justify-between">
<ModuleTitle exerciseIndex={exerciseIndex + 1} minTimer={exam.minTimer} module="listening" totalExercises={exam.exercises.length} />
{exerciseIndex === -1 && renderAudioPlayer()}
{exerciseIndex > -1 &&
exerciseIndex < exam.exercises.length &&
!showSolutions &&
@@ -81,17 +78,13 @@ export default function Listening({exam, showSolutions = false, onFinish}: Props
exerciseIndex < exam.exercises.length &&
showSolutions &&
renderSolution(exam.exercises[exerciseIndex], nextExercise, previousExercise)}
{exerciseIndex === -1 && (
<button
className={clsx("btn md:btn-wide w-full gap-4 relative text-white self-end", infoButtonStyle)}
onClick={() => nextExercise()}>
Next
<div className="absolute right-4">
<Icon path={mdiArrowRight} color="white" size={1} />
</div>
</button>
)}
</div>
{exerciseIndex === -1 && (
<Button color="green" onClick={() => nextExercise()} className="max-w-[200px] self-end w-full justify-self-end">
Start now
</Button>
)}
</>
);
}

View File

@@ -9,6 +9,11 @@ import {renderExercise} from "@/components/Exercises";
import {renderSolution} from "@/components/Solutions";
import {Panel} from "primereact/panel";
import {Steps} from "primereact/steps";
import {BsAlarm, BsBook, BsClock, BsStopwatch} from "react-icons/bs";
import ProgressBar from "@/components/Low/ProgressBar";
import ModuleTitle from "@/components/Medium/ModuleTitle";
import {Divider} from "primereact/divider";
import Button from "@/components/Low/Button";
interface Props {
exam: ReadingExam;
@@ -102,27 +107,30 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
};
const renderText = () => (
<div className="flex flex-col gap-4 w-full">
<div className="flex flex-col gap-6 w-full bg-mti-gray-seasalt rounded-xl py-8 px-16">
<div className="flex flex-col w-full gap-2">
<span className="text-base md:text-lg font-semibold">
<h4 className="text-xl font-semibold">
Please read the following excerpt attentively, you will then be asked questions about the text you&apos;ve read.
</span>
<span className="self-end text-sm">You will be allowed to read the text while doing the exercises</span>
</h4>
<span className="text-base">You will be allowed to read the text while doing the exercises</span>
</div>
<Panel header={exam.text.title}>
<p className="overflow-auto">
<div className="flex flex-col gap-2 w-full">
<h3 className="text-xl font-semibold">{exam.text.title}</h3>
<div className="border border-mti-gray-dim w-full rounded-full opacity-10" />
<span className="overflow-auto">
{exam.text.content.split("\\n").map((line, index) => (
<p key={index}>{line}</p>
))}
</p>
</Panel>
</span>
</div>
</div>
);
return (
<>
<TextModal {...exam.text} isOpen={showTextModal} onClose={() => setShowTextModal(false)} />
<div className="w-full h-full relative flex flex-col gap-8 items-center justify-center p-2 md:p-8 px-4 md:px-16 overflow-hidden">
<div className="flex flex-col h-full w-full gap-8">
<TextModal {...exam.text} isOpen={showTextModal} onClose={() => setShowTextModal(false)} />
<ModuleTitle minTimer={exam.minTimer} exerciseIndex={exerciseIndex + 1} module="reading" totalExercises={exam.exercises.length} />
{exerciseIndex === -1 && renderText()}
{exerciseIndex > -1 &&
exerciseIndex < exam.exercises.length &&
@@ -132,33 +140,12 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
exerciseIndex < exam.exercises.length &&
showSolutions &&
renderSolution(exam.exercises[exerciseIndex], nextExercise, previousExercise)}
<div
className={clsx("flex gap-8", exerciseIndex > -1 ? "w-full justify-center md:justify-between" : "self-end w-full md:w-fit flex")}>
{exerciseIndex > -1 && (
<button
className={clsx(
"btn btn-wide gap-4 relative text-white",
"border-2 border-ielts-reading hover:bg-ielts-reading hover:border-ielts-reading bg-ielts-reading-transparent",
)}
onClick={() => setShowTextModal(true)}>
Read Text
<div className="absolute right-4">
<Icon path={mdiNotebook} color="white" size={1} />
</div>
</button>
)}
{exerciseIndex === -1 && (
<button
className={clsx("btn w-full md:btn-wide gap-4 relative text-white self-end", infoButtonStyle)}
onClick={() => nextExercise()}>
Next
<div className="absolute right-4">
<Icon path={mdiArrowRight} color="white" size={1} />
</div>
</button>
)}
</div>
</div>
{exerciseIndex === -1 && (
<Button color="green" onClick={() => nextExercise()} className="max-w-[200px] self-end w-full">
Start now
</Button>
)}
</>
);
}