242 lines
12 KiB
TypeScript
242 lines
12 KiB
TypeScript
/* eslint-disable @next/next/no-img-element */
|
|
import {useState} from "react";
|
|
import {Module} from "@/interfaces";
|
|
import clsx from "clsx";
|
|
import {User} from "@/interfaces/user";
|
|
import ProgressBar from "@/components/Low/ProgressBar";
|
|
import {BsBook, BsCheck, BsCheckCircle, BsClipboard, BsHeadphones, BsMegaphone, BsPen, BsXCircle} from "react-icons/bs";
|
|
import {totalExamsByModule} from "@/utils/stats";
|
|
import useStats from "@/hooks/useStats";
|
|
import Button from "@/components/Low/Button";
|
|
import {calculateAverageLevel} from "@/utils/score";
|
|
import {sortByModuleName} from "@/utils/moduleUtils";
|
|
import {capitalize} from "lodash";
|
|
import ProfileSummary from "@/components/ProfileSummary";
|
|
|
|
interface Props {
|
|
user: User;
|
|
page: "exercises" | "exams";
|
|
onStart: (modules: Module[], avoidRepeated: boolean) => void;
|
|
disableSelection?: boolean;
|
|
}
|
|
|
|
export default function Selection({user, page, onStart, disableSelection = false}: Props) {
|
|
const [selectedModules, setSelectedModules] = useState<Module[]>([]);
|
|
const [avoidRepeatedExams, setAvoidRepeatedExams] = useState(true);
|
|
const {stats} = useStats(user?.id);
|
|
|
|
const toggleModule = (module: Module) => {
|
|
const modules = selectedModules.filter((x) => x !== module);
|
|
setSelectedModules((prev) => (prev.includes(module) ? modules : [...modules, module]));
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="w-full h-full relative flex flex-col gap-8 md:gap-16">
|
|
{user && (
|
|
<ProfileSummary
|
|
user={user}
|
|
items={[
|
|
{
|
|
icon: <BsBook className="text-ielts-reading w-6 h-6 md:w-8 md:h-8" />,
|
|
label: "Reading",
|
|
value: totalExamsByModule(stats, "reading"),
|
|
},
|
|
{
|
|
icon: <BsHeadphones className="text-ielts-listening w-6 h-6 md:w-8 md:h-8" />,
|
|
label: "Listening",
|
|
value: totalExamsByModule(stats, "listening"),
|
|
},
|
|
{
|
|
icon: <BsPen className="text-ielts-writing w-6 h-6 md:w-8 md:h-8" />,
|
|
label: "Writing",
|
|
value: totalExamsByModule(stats, "writing"),
|
|
},
|
|
{
|
|
icon: <BsMegaphone className="text-ielts-speaking w-6 h-6 md:w-8 md:h-8" />,
|
|
label: "Speaking",
|
|
value: totalExamsByModule(stats, "speaking"),
|
|
},
|
|
{
|
|
icon: <BsClipboard className="text-ielts-level w-6 h-6 md:w-8 md:h-8" />,
|
|
label: "Level",
|
|
value: totalExamsByModule(stats, "level"),
|
|
},
|
|
]}
|
|
/>
|
|
)}
|
|
|
|
<section className="flex flex-col gap-3">
|
|
<span className="font-bold text-lg">About {capitalize(page)}</span>
|
|
<span className="text-mti-gray-taupe">
|
|
{page === "exercises" && (
|
|
<>
|
|
In the realm of language acquisition, practice makes perfect, and our exercises are the key to unlocking your full
|
|
potential. Dive into a world of interactive and engaging exercises that cater to diverse learning styles. From grammar
|
|
drills that build a strong foundation to vocabulary challenges that broaden your lexicon, our exercises are carefully
|
|
designed to make learning English both enjoyable and effective. Whether you're looking to reinforce specific
|
|
skills or embark on a holistic language journey, our exercises are your companions in the pursuit of excellence.
|
|
Embrace the joy of learning as you navigate through a variety of activities that cater to every facet of language
|
|
acquisition. Your linguistic adventure starts here!
|
|
</>
|
|
)}
|
|
{page === "exams" && (
|
|
<>
|
|
Welcome to the heart of success on your English language journey! Our exams are crafted with precision to assess and
|
|
enhance your language skills. Each test is a passport to your linguistic prowess, designed to challenge and elevate
|
|
your abilities. Whether you're a beginner or a seasoned learner, our exams cater to all levels, providing a
|
|
comprehensive evaluation of your reading, writing, speaking, and listening skills. Prepare to embark on a journey of
|
|
self-discovery and language mastery as you navigate through our thoughtfully curated exams. Your success is not just a
|
|
destination; it's a testament to your dedication and our commitment to empowering you with the English language.
|
|
</>
|
|
)}
|
|
</span>
|
|
</section>
|
|
<section className="w-full flex -lg:flex-col -lg:items-center -lg:gap-12 justify-between gap-8 mt-8">
|
|
<div
|
|
onClick={!disableSelection && !selectedModules.includes("level") ? () => toggleModule("reading") : undefined}
|
|
className={clsx(
|
|
"relative w-64 max-w-xs flex flex-col items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-2 pt-12 cursor-pointer",
|
|
selectedModules.includes("reading") || disableSelection ? "border-mti-purple-light" : "border-mti-gray-platinum",
|
|
)}>
|
|
<div className="absolute w-16 h-16 flex items-center justify-center rounded-full bg-ielts-reading top-0 -translate-y-1/2">
|
|
<BsBook className="text-white w-7 h-7" />
|
|
</div>
|
|
<span className="font-semibold">Reading:</span>
|
|
<p className="text-center text-xs">
|
|
Expand your vocabulary, improve your reading comprehension and improve your ability to interpret texts in English.
|
|
</p>
|
|
{!selectedModules.includes("reading") && !selectedModules.includes("level") && !disableSelection && (
|
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full mt-4" />
|
|
)}
|
|
{(selectedModules.includes("reading") || disableSelection) && (
|
|
<BsCheckCircle className="mt-4 text-mti-purple-light w-8 h-8" />
|
|
)}
|
|
{selectedModules.includes("level") && <BsXCircle className="mt-4 text-mti-red-light w-8 h-8" />}
|
|
</div>
|
|
<div
|
|
onClick={!disableSelection && !selectedModules.includes("level") ? () => toggleModule("listening") : undefined}
|
|
className={clsx(
|
|
"relative w-64 max-w-xs flex flex-col items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-2 pt-12 cursor-pointer",
|
|
selectedModules.includes("listening") || disableSelection ? "border-mti-purple-light" : "border-mti-gray-platinum",
|
|
)}>
|
|
<div className="absolute w-16 h-16 flex items-center justify-center rounded-full bg-ielts-listening top-0 -translate-y-1/2">
|
|
<BsHeadphones className="text-white w-7 h-7" />
|
|
</div>
|
|
<span className="font-semibold">Listening:</span>
|
|
<p className="text-center text-xs">
|
|
Improve your ability to follow conversations in English and your ability to understand different accents and intonations.
|
|
</p>
|
|
{!selectedModules.includes("listening") && !selectedModules.includes("level") && !disableSelection && (
|
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full mt-4" />
|
|
)}
|
|
{(selectedModules.includes("listening") || disableSelection) && (
|
|
<BsCheckCircle className="mt-4 text-mti-purple-light w-8 h-8" />
|
|
)}
|
|
{selectedModules.includes("level") && <BsXCircle className="mt-4 text-mti-red-light w-8 h-8" />}
|
|
</div>
|
|
<div
|
|
onClick={!disableSelection && !selectedModules.includes("level") ? () => toggleModule("writing") : undefined}
|
|
className={clsx(
|
|
"relative w-64 max-w-xs flex flex-col items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-2 pt-12 cursor-pointer",
|
|
selectedModules.includes("writing") || disableSelection ? "border-mti-purple-light" : "border-mti-gray-platinum",
|
|
)}>
|
|
<div className="absolute w-16 h-16 flex items-center justify-center rounded-full bg-ielts-writing top-0 -translate-y-1/2">
|
|
<BsPen className="text-white w-7 h-7" />
|
|
</div>
|
|
<span className="font-semibold">Writing:</span>
|
|
<p className="text-center text-xs">
|
|
Allow you to practice writing in a variety of formats, from simple paragraphs to complex essays.
|
|
</p>
|
|
{!selectedModules.includes("writing") && !selectedModules.includes("level") && !disableSelection && (
|
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full mt-4" />
|
|
)}
|
|
{(selectedModules.includes("writing") || disableSelection) && (
|
|
<BsCheckCircle className="mt-4 text-mti-purple-light w-8 h-8" />
|
|
)}
|
|
{selectedModules.includes("level") && <BsXCircle className="mt-4 text-mti-red-light w-8 h-8" />}
|
|
</div>
|
|
<div
|
|
onClick={!disableSelection && !selectedModules.includes("level") ? () => toggleModule("speaking") : undefined}
|
|
className={clsx(
|
|
"relative w-64 max-w-xs flex flex-col items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-2 pt-12 cursor-pointer",
|
|
selectedModules.includes("speaking") || disableSelection ? "border-mti-purple-light" : "border-mti-gray-platinum",
|
|
)}>
|
|
<div className="absolute w-16 h-16 flex items-center justify-center rounded-full bg-ielts-speaking top-0 -translate-y-1/2">
|
|
<BsMegaphone className="text-white w-7 h-7" />
|
|
</div>
|
|
<span className="font-semibold">Speaking:</span>
|
|
<p className="text-center text-xs">
|
|
You'll have access to interactive dialogs, pronunciation exercises and speech recordings.
|
|
</p>
|
|
{!selectedModules.includes("speaking") && !selectedModules.includes("level") && !disableSelection && (
|
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full mt-4" />
|
|
)}
|
|
{(selectedModules.includes("speaking") || disableSelection) && (
|
|
<BsCheckCircle className="mt-4 text-mti-purple-light w-8 h-8" />
|
|
)}
|
|
{selectedModules.includes("level") && <BsXCircle className="mt-4 text-mti-red-light w-8 h-8" />}
|
|
</div>
|
|
{!disableSelection && (
|
|
<div
|
|
onClick={selectedModules.length === 0 || selectedModules.includes("level") ? () => toggleModule("level") : undefined}
|
|
className={clsx(
|
|
"relative w-64 max-w-xs flex flex-col items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-2 pt-12 cursor-pointer",
|
|
selectedModules.includes("level") || disableSelection ? "border-mti-purple-light" : "border-mti-gray-platinum",
|
|
)}>
|
|
<div className="absolute w-16 h-16 flex items-center justify-center rounded-full bg-ielts-level top-0 -translate-y-1/2">
|
|
<BsClipboard className="text-white w-7 h-7" />
|
|
</div>
|
|
<span className="font-semibold">Level:</span>
|
|
<p className="text-center text-xs">You'll be able to test your english level with multiple choice questions.</p>
|
|
{!selectedModules.includes("level") && selectedModules.length === 0 && !disableSelection && (
|
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full mt-4" />
|
|
)}
|
|
{(selectedModules.includes("level") || disableSelection) && (
|
|
<BsCheckCircle className="mt-4 text-mti-purple-light w-8 h-8" />
|
|
)}
|
|
{!selectedModules.includes("level") && selectedModules.length > 0 && (
|
|
<BsXCircle className="mt-4 text-mti-red-light w-8 h-8" />
|
|
)}
|
|
</div>
|
|
)}
|
|
</section>
|
|
<div className="flex w-full -md:flex-col -md:gap-4 -md:justify-center md:justify-between items-center">
|
|
<div
|
|
className="flex gap-3 items-center text-mti-gray-dim text-sm cursor-pointer tooltip w-full -md:justify-center"
|
|
data-tip="If possible, the platform will choose exams not yet done"
|
|
onClick={() => setAvoidRepeatedExams((prev) => !prev)}>
|
|
<input type="checkbox" className="hidden" />
|
|
<div
|
|
className={clsx(
|
|
"w-6 h-6 rounded-md flex items-center justify-center border border-mti-purple-light bg-white",
|
|
"transition duration-300 ease-in-out",
|
|
avoidRepeatedExams && "!bg-mti-purple-light ",
|
|
)}>
|
|
<BsCheck color="white" className="w-full h-full" />
|
|
</div>
|
|
<span>Avoid Repeated Questions</span>
|
|
</div>
|
|
<div className="tooltip w-full" data-tip={`Your screen size is too small to do ${page}`}>
|
|
<Button color="purple" className="px-12 w-full max-w-xs md:hidden" disabled>
|
|
Start Exam
|
|
</Button>
|
|
</div>
|
|
<Button
|
|
onClick={() =>
|
|
onStart(
|
|
!disableSelection ? selectedModules.sort(sortByModuleName) : ["reading", "listening", "writing", "speaking"],
|
|
avoidRepeatedExams,
|
|
)
|
|
}
|
|
color="purple"
|
|
className="px-12 w-full max-w-xs md:self-end -md:hidden"
|
|
disabled={selectedModules.length === 0 && !disableSelection}>
|
|
Start Exam
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|