Updated the assignments to work with the level exams
This commit is contained in:
@@ -7,7 +7,7 @@ import {calculateBandScore} from "@/utils/score";
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
import {BsBook, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
|
import {BsBook, BsClipboard, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
@@ -57,11 +57,13 @@ export default function AssignmentCard({id, name, assigner, startDate, endDate,
|
|||||||
module === "listening" && "bg-ielts-listening",
|
module === "listening" && "bg-ielts-listening",
|
||||||
module === "writing" && "bg-ielts-writing",
|
module === "writing" && "bg-ielts-writing",
|
||||||
module === "speaking" && "bg-ielts-speaking",
|
module === "speaking" && "bg-ielts-speaking",
|
||||||
|
module === "level" && "bg-ielts-level",
|
||||||
)}>
|
)}>
|
||||||
{module === "reading" && <BsBook className="w-4 h-4" />}
|
{module === "reading" && <BsBook className="w-4 h-4" />}
|
||||||
{module === "listening" && <BsHeadphones className="w-4 h-4" />}
|
{module === "listening" && <BsHeadphones className="w-4 h-4" />}
|
||||||
{module === "writing" && <BsPen className="w-4 h-4" />}
|
{module === "writing" && <BsPen className="w-4 h-4" />}
|
||||||
{module === "speaking" && <BsMegaphone className="w-4 h-4" />}
|
{module === "speaking" && <BsMegaphone className="w-4 h-4" />}
|
||||||
|
{module === "level" && <BsClipboard className="w-4 h-4" />}
|
||||||
{calculateAverageModuleScore(module) > -1 && (
|
{calculateAverageModuleScore(module) > -1 && (
|
||||||
<span className="text-sm">{calculateAverageModuleScore(module).toFixed(1)}</span>
|
<span className="text-sm">{calculateAverageModuleScore(module).toFixed(1)}</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Modal from "@/components/Modal";
|
|||||||
import {Module} from "@/interfaces";
|
import {Module} from "@/interfaces";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
import {BsBook, BsCheckCircle, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
|
import {BsBook, BsCheckCircle, BsClipboard, BsHeadphones, BsMegaphone, BsPen, BsXCircle} from "react-icons/bs";
|
||||||
import {generate} from "random-words";
|
import {generate} from "random-words";
|
||||||
import {capitalize} from "lodash";
|
import {capitalize} from "lodash";
|
||||||
import useUsers from "@/hooks/useUsers";
|
import useUsers from "@/hooks/useUsers";
|
||||||
@@ -99,59 +99,96 @@ export default function AssignmentCreator({isCreating, assignment, assigner, gro
|
|||||||
return (
|
return (
|
||||||
<Modal isOpen={isCreating} onClose={cancelCreation} title="New Assignment">
|
<Modal isOpen={isCreating} onClose={cancelCreation} title="New Assignment">
|
||||||
<div className="w-full flex flex-col gap-4">
|
<div className="w-full flex flex-col gap-4">
|
||||||
<section className="w-full grid -md:grid-cols-1 md:grid-cols-2 place-items-center lg:grid-cols-4 -md:flex-col -md:items-center -md:gap-12 justify-between gap-8 mt-8 px-8">
|
<section className="w-full grid -md:grid-cols-1 md:grid-cols-2 place-items-center lg:grid-cols-6 -md:flex-col -md:items-center -md:gap-12 justify-between gap-8 mt-8 px-8">
|
||||||
<div
|
<div
|
||||||
onClick={() => toggleModule("reading")}
|
onClick={!selectedModules.includes("level") ? () => toggleModule("reading") : undefined}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"w-52 relative max-w-xs flex items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-8 cursor-pointer",
|
"w-52 relative max-w-xs flex items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-8 cursor-pointer",
|
||||||
|
"lg:col-span-2",
|
||||||
selectedModules.includes("reading") ? "border-mti-purple-light" : "border-mti-gray-platinum",
|
selectedModules.includes("reading") ? "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-1/2 -translate-y-1/2 left-0 -translate-x-1/2">
|
<div className="absolute w-16 h-16 flex items-center justify-center rounded-full bg-ielts-reading top-1/2 -translate-y-1/2 left-0 -translate-x-1/2">
|
||||||
<BsBook className="text-white w-7 h-7" />
|
<BsBook className="text-white w-7 h-7" />
|
||||||
</div>
|
</div>
|
||||||
<span className="ml-8 font-semibold">Reading</span>
|
<span className="ml-8 font-semibold">Reading</span>
|
||||||
{!selectedModules.includes("reading") && <div className="border border-mti-gray-platinum w-8 h-8 rounded-full" />}
|
{!selectedModules.includes("reading") && !selectedModules.includes("level") && (
|
||||||
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full" />
|
||||||
|
)}
|
||||||
|
{selectedModules.includes("level") && <BsXCircle className="text-mti-red-light w-8 h-8" />}
|
||||||
{selectedModules.includes("reading") && <BsCheckCircle className="text-mti-purple-light w-8 h-8" />}
|
{selectedModules.includes("reading") && <BsCheckCircle className="text-mti-purple-light w-8 h-8" />}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() => toggleModule("listening")}
|
onClick={!selectedModules.includes("level") ? () => toggleModule("listening") : undefined}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"w-52 relative max-w-xs flex items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-8 cursor-pointer",
|
"w-52 relative max-w-xs flex items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-8 cursor-pointer",
|
||||||
|
"lg:col-span-2",
|
||||||
selectedModules.includes("listening") ? "border-mti-purple-light" : "border-mti-gray-platinum",
|
selectedModules.includes("listening") ? "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-1/2 -translate-y-1/2 left-0 -translate-x-1/2">
|
<div className="absolute w-16 h-16 flex items-center justify-center rounded-full bg-ielts-listening top-1/2 -translate-y-1/2 left-0 -translate-x-1/2">
|
||||||
<BsHeadphones className="text-white w-7 h-7" />
|
<BsHeadphones className="text-white w-7 h-7" />
|
||||||
</div>
|
</div>
|
||||||
<span className="ml-8 font-semibold">Listening</span>
|
<span className="ml-8 font-semibold">Listening</span>
|
||||||
{!selectedModules.includes("listening") && <div className="border border-mti-gray-platinum w-8 h-8 rounded-full" />}
|
{!selectedModules.includes("listening") && !selectedModules.includes("level") && (
|
||||||
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full" />
|
||||||
|
)}
|
||||||
|
{selectedModules.includes("level") && <BsXCircle className="text-mti-red-light w-8 h-8" />}
|
||||||
{selectedModules.includes("listening") && <BsCheckCircle className="text-mti-purple-light w-8 h-8" />}
|
{selectedModules.includes("listening") && <BsCheckCircle className="text-mti-purple-light w-8 h-8" />}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() => toggleModule("writing")}
|
onClick={!selectedModules.includes("level") ? () => toggleModule("writing") : undefined}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"w-52 relative max-w-xs flex lg:flex-row-reverse items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-8 cursor-pointer",
|
"w-52 relative max-w-xs flex items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-8 cursor-pointer",
|
||||||
|
"lg:col-span-2",
|
||||||
selectedModules.includes("writing") ? "border-mti-purple-light" : "border-mti-gray-platinum",
|
selectedModules.includes("writing") ? "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-1/2 -translate-y-1/2 -lg:left-0 -lg:-translate-x-1/2 lg:right-0 lg:translate-x-1/2">
|
<div className="absolute w-16 h-16 flex items-center justify-center rounded-full bg-ielts-writing top-1/2 -translate-y-1/2 left-0 -translate-x-1/2">
|
||||||
<BsPen className="text-white w-7 h-7" />
|
<BsPen className="text-white w-7 h-7" />
|
||||||
</div>
|
</div>
|
||||||
<span className="lg:mr-8 -lg:ml-8 font-semibold">Writing</span>
|
<span className="ml-8 font-semibold">Writing</span>
|
||||||
{!selectedModules.includes("writing") && <div className="border border-mti-gray-platinum w-8 h-8 rounded-full" />}
|
{!selectedModules.includes("writing") && !selectedModules.includes("level") && (
|
||||||
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full" />
|
||||||
|
)}
|
||||||
|
{selectedModules.includes("level") && <BsXCircle className="text-mti-red-light w-8 h-8" />}
|
||||||
{selectedModules.includes("writing") && <BsCheckCircle className="text-mti-purple-light w-8 h-8" />}
|
{selectedModules.includes("writing") && <BsCheckCircle className="text-mti-purple-light w-8 h-8" />}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() => toggleModule("speaking")}
|
onClick={!selectedModules.includes("level") ? () => toggleModule("speaking") : undefined}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"w-52 relative max-w-xs flex lg:flex-row-reverse items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-8 cursor-pointer",
|
"w-52 relative max-w-xs flex items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-8 cursor-pointer",
|
||||||
|
"lg:col-span-3",
|
||||||
selectedModules.includes("speaking") ? "border-mti-purple-light" : "border-mti-gray-platinum",
|
selectedModules.includes("speaking") ? "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-1/2 -translate-y-1/2 -lg:left-0 -lg:-translate-x-1/2 lg:right-0 lg:translate-x-1/2">
|
<div className="absolute w-16 h-16 flex items-center justify-center rounded-full bg-ielts-speaking top-1/2 -translate-y-1/2 left-0 -translate-x-1/2">
|
||||||
<BsMegaphone className="text-white w-7 h-7 lg:-scale-x-100" />
|
<BsMegaphone className="text-white w-7 h-7" />
|
||||||
</div>
|
</div>
|
||||||
<span className="lg:mr-8 -lg:ml-8 font-semibold">Speaking</span>
|
<span className="ml-8 font-semibold">Speaking</span>
|
||||||
{!selectedModules.includes("speaking") && <div className="border border-mti-gray-platinum w-8 h-8 rounded-full" />}
|
{!selectedModules.includes("speaking") && !selectedModules.includes("level") && (
|
||||||
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full" />
|
||||||
|
)}
|
||||||
|
{selectedModules.includes("level") && <BsXCircle className="text-mti-red-light w-8 h-8" />}
|
||||||
{selectedModules.includes("speaking") && <BsCheckCircle className="text-mti-purple-light w-8 h-8" />}
|
{selectedModules.includes("speaking") && <BsCheckCircle className="text-mti-purple-light w-8 h-8" />}
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
onClick={
|
||||||
|
(!selectedModules.includes("level") && selectedModules.length === 0) || selectedModules.includes("level")
|
||||||
|
? () => toggleModule("level")
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
className={clsx(
|
||||||
|
"w-52 relative max-w-xs flex items-center bg-mti-white-alt transition duration-300 ease-in-out border p-5 rounded-xl gap-8 cursor-pointer",
|
||||||
|
"lg:col-span-3",
|
||||||
|
selectedModules.includes("level") ? "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-1/2 -translate-y-1/2 left-0 -translate-x-1/2">
|
||||||
|
<BsClipboard className="text-white w-7 h-7" />
|
||||||
|
</div>
|
||||||
|
<span className="ml-8 font-semibold">Level</span>
|
||||||
|
{!selectedModules.includes("level") && selectedModules.length === 0 && (
|
||||||
|
<div className="border border-mti-gray-platinum w-8 h-8 rounded-full" />
|
||||||
|
)}
|
||||||
|
{!selectedModules.includes("level") && selectedModules.length > 0 && <BsXCircle className="text-mti-red-light w-8 h-8" />}
|
||||||
|
{selectedModules.includes("level") && <BsCheckCircle className="text-mti-purple-light w-8 h-8" />}
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<Input type="text" name="name" onChange={(e) => setName(e)} defaultValue={name} label="Assignment Name" required />
|
<Input type="text" name="name" onChange={(e) => setName(e)} defaultValue={name} label="Assignment Name" required />
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {sortByModule} from "@/utils/moduleUtils";
|
|||||||
import {calculateBandScore} from "@/utils/score";
|
import {calculateBandScore} from "@/utils/score";
|
||||||
import {convertToUserSolutions} from "@/utils/stats";
|
import {convertToUserSolutions} from "@/utils/stats";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import {uniqBy} from "lodash";
|
import {capitalize, uniqBy} from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import {useRouter} from "next/router";
|
import {useRouter} from "next/router";
|
||||||
import {BsBook, BsClipboard, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
|
import {BsBook, BsClipboard, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
|
||||||
@@ -239,9 +239,10 @@ export default function AssignmentView({isOpen, assignment, onClose}: Props) {
|
|||||||
<div className="grid grid-cols-4 gap-2 place-items-start w-full -md:mt-2">
|
<div className="grid grid-cols-4 gap-2 place-items-start w-full -md:mt-2">
|
||||||
{assignment?.exams.map(({module}) => (
|
{assignment?.exams.map(({module}) => (
|
||||||
<div
|
<div
|
||||||
|
data-tip={capitalize(module)}
|
||||||
key={module}
|
key={module}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"flex gap-2 items-center w-fit text-white -md:px-4 xl:px-4 md:px-2 py-2 rounded-xl",
|
"flex gap-2 items-center w-fit text-white -md:px-4 xl:px-4 md:px-2 py-2 rounded-xl tooltip",
|
||||||
module === "reading" && "bg-ielts-reading",
|
module === "reading" && "bg-ielts-reading",
|
||||||
module === "listening" && "bg-ielts-listening",
|
module === "listening" && "bg-ielts-listening",
|
||||||
module === "writing" && "bg-ielts-writing",
|
module === "writing" && "bg-ielts-writing",
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ import {Assignment} from "@/interfaces/results";
|
|||||||
import {User} from "@/interfaces/user";
|
import {User} from "@/interfaces/user";
|
||||||
import useExamStore from "@/stores/examStore";
|
import useExamStore from "@/stores/examStore";
|
||||||
import {getExamById} from "@/utils/exams";
|
import {getExamById} from "@/utils/exams";
|
||||||
import {MODULE_ARRAY, sortByModule} from "@/utils/moduleUtils";
|
import {MODULE_ARRAY, sortByModule, sortByModuleName} from "@/utils/moduleUtils";
|
||||||
import {averageScore, groupBySession} from "@/utils/stats";
|
import {averageScore, groupBySession} from "@/utils/stats";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import {capitalize} from "lodash";
|
import {capitalize} from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import {useRouter} from "next/router";
|
import {useRouter} from "next/router";
|
||||||
import {BsArrowRepeat, BsBook, BsFileEarmarkText, BsHeadphones, BsMegaphone, BsPen, BsPencil, BsStar} from "react-icons/bs";
|
import {BsArrowRepeat, BsBook, BsClipboard, BsFileEarmarkText, BsHeadphones, BsMegaphone, BsPen, BsPencil, BsStar} from "react-icons/bs";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
user: User;
|
user: User;
|
||||||
@@ -115,34 +115,28 @@ export default function StudentDashboard({user}: Props) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between w-full items-center">
|
<div className="flex justify-between w-full items-center">
|
||||||
<div className="grid grid-cols-2 gap-2 place-items-center justify-center w-fit min-w-[104px] -md:mt-2">
|
<div className="grid grid-cols-2 gap-2 place-items-center justify-center w-fit min-w-[104px] -md:mt-2">
|
||||||
{MODULE_ARRAY.map((module) => (
|
{assignment.exams
|
||||||
<div
|
.map((e) => e.module)
|
||||||
key={module}
|
.sort(sortByModuleName)
|
||||||
className={clsx(
|
.map((module) => (
|
||||||
"flex gap-2 items-center w-fit text-white -md:px-4 xl:px-4 md:px-2 py-2 rounded-xl",
|
<div
|
||||||
module === "reading" &&
|
key={module}
|
||||||
(assignment.exams.map((e) => e.module).includes("reading")
|
data-tip={capitalize(module)}
|
||||||
? "bg-ielts-reading"
|
className={clsx(
|
||||||
: "bg-mti-black/40"),
|
"flex gap-2 items-center w-fit text-white -md:px-4 xl:px-4 md:px-2 py-2 rounded-xl tooltip",
|
||||||
module === "listening" &&
|
module === "reading" && "bg-ielts-reading",
|
||||||
(assignment.exams.map((e) => e.module).includes("listening")
|
module === "listening" && "bg-ielts-listening",
|
||||||
? "bg-ielts-listening"
|
module === "writing" && "bg-ielts-writing",
|
||||||
: "bg-mti-black/40"),
|
module === "speaking" && "bg-ielts-speaking",
|
||||||
module === "writing" &&
|
module === "level" && "bg-ielts-level",
|
||||||
(assignment.exams.map((e) => e.module).includes("writing")
|
)}>
|
||||||
? "bg-ielts-writing"
|
{module === "reading" && <BsBook className="w-4 h-4" />}
|
||||||
: "bg-mti-black/40"),
|
{module === "listening" && <BsHeadphones className="w-4 h-4" />}
|
||||||
module === "speaking" &&
|
{module === "writing" && <BsPen className="w-4 h-4" />}
|
||||||
(assignment.exams.map((e) => e.module).includes("speaking")
|
{module === "speaking" && <BsMegaphone className="w-4 h-4" />}
|
||||||
? "bg-ielts-speaking"
|
{module === "level" && <BsClipboard className="w-4 h-4" />}
|
||||||
: "bg-mti-black/40"),
|
</div>
|
||||||
)}>
|
))}
|
||||||
{module === "reading" && <BsBook className="w-4 h-4" />}
|
|
||||||
{module === "listening" && <BsHeadphones className="w-4 h-4" />}
|
|
||||||
{module === "writing" && <BsPen className="w-4 h-4" />}
|
|
||||||
{module === "speaking" && <BsMegaphone className="w-4 h-4" />}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
{!assignment.results.map((r) => r.user).includes(user.id) && (
|
{!assignment.results.map((r) => r.user).includes(user.id) && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
Reference in New Issue
Block a user