138 lines
4.3 KiB
TypeScript
138 lines
4.3 KiB
TypeScript
import { Session } from "@/hooks/useSessions";
|
|
import { Assignment } from "@/interfaces/results";
|
|
import { User } from "@/interfaces/user";
|
|
import {
|
|
activeAssignmentFilter,
|
|
futureAssignmentFilter,
|
|
} from "@/utils/assignments";
|
|
import { sortByModuleName } from "@/utils/moduleUtils";
|
|
import clsx from "clsx";
|
|
import moment from "moment";
|
|
import { useRouter } from "next/router";
|
|
import { useMemo } from "react";
|
|
import Button from "../Low/Button";
|
|
import ModuleBadge from "../ModuleBadge";
|
|
|
|
interface Props {
|
|
assignment: Assignment;
|
|
user: User;
|
|
session?: Session;
|
|
startAssignment: (assignment: Assignment) => void;
|
|
resumeAssignment: (session: Session) => void;
|
|
}
|
|
|
|
export default function AssignmentCard({
|
|
user,
|
|
assignment,
|
|
session,
|
|
startAssignment,
|
|
resumeAssignment,
|
|
}: Props) {
|
|
const hasBeenSubmitted = useMemo(
|
|
() => assignment.results.map((r) => r.user).includes(user.id),
|
|
[assignment.results, user.id]
|
|
);
|
|
|
|
return (
|
|
<div
|
|
className={clsx(
|
|
"border-mti-gray-anti-flash flex min-w-[350px] flex-col gap-6 rounded-xl border p-4",
|
|
assignment.results.map((r) => r.user).includes(user.id) &&
|
|
"border-mti-green-light"
|
|
)}
|
|
key={assignment.id}
|
|
>
|
|
<div className="flex flex-col gap-1">
|
|
<h3 className="text-mti-black/90 text-xl font-semibold">
|
|
{assignment.name}
|
|
</h3>
|
|
<span className="flex justify-between gap-1 text-lg">
|
|
<span>{moment(assignment.startDate).format("DD/MM/YY, HH:mm")}</span>
|
|
<span>-</span>
|
|
<span>{moment(assignment.endDate).format("DD/MM/YY, HH:mm")}</span>
|
|
</span>
|
|
</div>
|
|
<div className="flex w-full items-center justify-between">
|
|
<div className="-md:mt-2 grid w-fit min-w-[140px] grid-cols-2 grid-rows-2 place-items-center justify-between gap-4">
|
|
{assignment.exams
|
|
.filter((e) => e.assignee === user.id)
|
|
.map((e) => e.module)
|
|
.sort(sortByModuleName)
|
|
.map((module) => (
|
|
<ModuleBadge
|
|
className="scale-110 w-full"
|
|
key={module}
|
|
module={module}
|
|
/>
|
|
))}
|
|
</div>
|
|
{futureAssignmentFilter(assignment) && !hasBeenSubmitted && (
|
|
<Button
|
|
color="rose"
|
|
className="-md:hidden h-full w-full max-w-[50%] !rounded-xl"
|
|
disabled
|
|
variant="outline"
|
|
>
|
|
Not yet started
|
|
</Button>
|
|
)}
|
|
{activeAssignmentFilter(assignment) && !hasBeenSubmitted && (
|
|
<>
|
|
<div
|
|
className="tooltip flex h-full w-full items-center justify-end pl-8 md:hidden"
|
|
data-tip="Your screen size is too small to perform an assignment"
|
|
>
|
|
<Button className="h-full w-full !rounded-xl" variant="outline">
|
|
Start
|
|
</Button>
|
|
</div>
|
|
{!session && (
|
|
<div
|
|
data-tip="You have already started this assignment!"
|
|
className={clsx(
|
|
"-md:hidden h-full w-full max-w-[50%] cursor-pointer",
|
|
!!session && "tooltip"
|
|
)}
|
|
>
|
|
<Button
|
|
className={clsx("w-full h-full !rounded-xl")}
|
|
onClick={() => startAssignment(assignment)}
|
|
variant="outline"
|
|
>
|
|
Start
|
|
</Button>
|
|
</div>
|
|
)}
|
|
{!!session && (
|
|
<div
|
|
className={clsx(
|
|
"-md:hidden h-full w-full max-w-[50%] cursor-pointer"
|
|
)}
|
|
>
|
|
<Button
|
|
className={clsx("w-full h-full !rounded-xl")}
|
|
onClick={() => resumeAssignment(session)}
|
|
color="green"
|
|
variant="outline"
|
|
>
|
|
Resume
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</>
|
|
)}
|
|
{hasBeenSubmitted && (
|
|
<Button
|
|
color="green"
|
|
className="-md:hidden h-full w-full max-w-[50%] !rounded-xl"
|
|
disabled
|
|
variant="outline"
|
|
>
|
|
Submitted
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|