Created a Finish screen for when a user finishes an exam

This commit is contained in:
Tiago Ribeiro
2023-04-11 22:08:25 +01:00
parent 49c515b02a
commit 503a265da0
3 changed files with 112 additions and 14 deletions

View File

@@ -0,0 +1,93 @@
import ProfileLevel from "@/components/ProfileLevel";
import {errorButtonStyle, infoButtonStyle} from "@/constants/buttonStyles";
import {Module} from "@/interfaces";
import {User} from "@/interfaces/user";
import {ICONS} from "@/resources/modules";
import {mdiArrowLeft, mdiArrowRight} from "@mdi/js";
import Icon from "@mdi/react";
import clsx from "clsx";
import Link from "next/link";
import router from "next/router";
interface Props {
user: User;
modules: Module[];
scores: {
module?: Module;
correct: number;
total: number;
}[];
onViewResults: () => void;
}
export default function Finish({user, scores, modules, onViewResults}: Props) {
const renderModuleScore = (module: Module) => {
const moduleScores = scores.filter((x) => x.module === module);
if (moduleScores.length === 0) {
return <>0</>;
}
return moduleScores.map((x, index) => (
<span key={index}>
{x.correct} / {x.total}
</span>
));
};
const renderModuleTotal = (module: Module) => {
const moduleScores = scores.filter((x) => x.module === module);
if (moduleScores.length === 0) {
return <>0</>;
}
const total = moduleScores.reduce((accumulator, current) => accumulator + current.total, 0);
const correct = moduleScores.reduce((accumulator, current) => accumulator + current.correct, 0);
return (
<span>
{correct} / {total} | {Math.floor((correct / total) * 100)}%
</span>
);
};
return (
<div className="w-full h-full relative">
<section className="h-full w-full flex flex-col items-center justify-center">
<ProfileLevel user={user} className="h-1/2" />
<div className="h-2/3 w-1/2 flex flex-col items-center gap-4">
<h1>You have finished the exam!</h1>
<div className="rounded-xl p-4 items-center flex justify-center gap-4">
{modules.map((module) => (
<div
className={`flex flex-col gap-12 min-w-[176px] items-center justify-center border-2 border-ielts-${module} bg-ielts-${module}-transparent p-4 rounded-xl text-white font-semibold`}
key={module}>
<div className="flex flex-col items-center">
<Icon path={ICONS[module]} color="white" size={2} />
<span>{module.toUpperCase()}</span>
</div>
<div className="flex flex-col">{renderModuleScore(module)}</div>
<div>TOTAL: {renderModuleTotal(module)}</div>
</div>
))}
</div>
<div className="w-full flex justify-between mt-24">
<Link href="/">
<button className={clsx("btn btn-wide gap-4 relative text-white", errorButtonStyle)}>
<div className="absolute left-4">
<Icon path={mdiArrowLeft} color="white" size={1} />
</div>
Go Home
</button>
</Link>
<button className={clsx("btn btn-wide gap-4 relative text-white", infoButtonStyle)} onClick={onViewResults}>
View Solutions
<div className="absolute right-4">
<Icon path={mdiArrowRight} color="white" size={1} />
</div>
</button>
</div>
</div>
</section>
</div>
);
}

View File

@@ -17,6 +17,7 @@ import Listening from "@/exams/Listening";
import Writing from "@/exams/Writing"; import Writing from "@/exams/Writing";
import {ToastContainer} from "react-toastify"; import {ToastContainer} from "react-toastify";
import Link from "next/link"; import Link from "next/link";
import Finish from "@/exams/Finish";
export default function Home() { export default function Home() {
const [selectedModules, setSelectedModules] = useState<Module[]>([]); const [selectedModules, setSelectedModules] = useState<Module[]>([]);
@@ -67,20 +68,15 @@ export default function Home() {
if (moduleIndex >= selectedModules.length) { if (moduleIndex >= selectedModules.length) {
return ( return (
<> <Finish
Finished!{" "} user={JSON_USER}
<button modules={selectedModules}
className="btn btn-wide" onViewResults={() => {
onClick={() => {
setShowSolutions(true); setShowSolutions(true);
setModuleIndex(0); setModuleIndex(0);
}}> }}
View Solutions scores={userSolutions.map((x) => ({...x.score, module: x.module}))}
</button> />
<Link href="/">
<button className="btn btn-wide">Go Home</button>
</Link>
</>
); );
} }

9
src/resources/modules.ts Normal file
View File

@@ -0,0 +1,9 @@
import {Module} from "@/interfaces";
import {mdiAccountVoice, mdiBookOpen, mdiHeadphones, mdiPen} from "@mdi/js";
export const ICONS: {[key in Module]: string} = {
listening: mdiHeadphones,
reading: mdiBookOpen,
speaking: mdiAccountVoice,
writing: mdiPen,
};