Added the ability to view archived assignments and unarchive them

This commit is contained in:
Tiago Ribeiro
2024-05-05 12:02:53 +01:00
parent cbb61d18fe
commit 0e53b4a454
5 changed files with 227 additions and 152 deletions

View File

@@ -1,126 +1,105 @@
import ProgressBar from "@/components/Low/ProgressBar";
import useUsers from "@/hooks/useUsers";
import { Module } from "@/interfaces";
import { Assignment } from "@/interfaces/results";
import { calculateBandScore } from "@/utils/score";
import {Module} from "@/interfaces";
import {Assignment} from "@/interfaces/results";
import {calculateBandScore} from "@/utils/score";
import clsx from "clsx";
import moment from "moment";
import {
BsBook,
BsClipboard,
BsHeadphones,
BsMegaphone,
BsPen,
} from "react-icons/bs";
import { usePDFDownload } from "@/hooks/usePDFDownload";
import { useAssignmentArchive } from "@/hooks/useAssignmentArchive";
import { uniqBy } from "lodash";
import {BsBook, BsClipboard, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
import {usePDFDownload} from "@/hooks/usePDFDownload";
import {useAssignmentArchive} from "@/hooks/useAssignmentArchive";
import {uniqBy} from "lodash";
import {useAssignmentUnarchive} from "@/hooks/useAssignmentUnarchive";
interface Props {
onClick?: () => void;
allowDownload?: boolean;
reload?: Function;
allowArchive?: boolean;
onClick?: () => void;
allowDownload?: boolean;
reload?: Function;
allowArchive?: boolean;
allowUnarchive?: boolean;
}
export default function AssignmentCard({
id,
name,
assigner,
startDate,
endDate,
assignees,
results,
exams,
archived,
onClick,
allowDownload,
reload,
allowArchive,
id,
name,
assigner,
startDate,
endDate,
assignees,
results,
exams,
archived,
onClick,
allowDownload,
reload,
allowArchive,
allowUnarchive,
}: Assignment & Props) {
const renderPdfIcon = usePDFDownload("assignments");
const renderArchiveIcon = useAssignmentArchive(id, reload);
const renderPdfIcon = usePDFDownload("assignments");
const renderArchiveIcon = useAssignmentArchive(id, reload);
const renderUnarchiveIcon = useAssignmentUnarchive(id, reload);
const calculateAverageModuleScore = (module: Module) => {
const resultModuleBandScores = results.map((r) => {
const moduleStats = r.stats.filter((s) => s.module === module);
const calculateAverageModuleScore = (module: Module) => {
const resultModuleBandScores = results.map((r) => {
const moduleStats = r.stats.filter((s) => s.module === module);
const correct = moduleStats.reduce(
(acc, curr) => acc + curr.score.correct,
0
);
const total = moduleStats.reduce(
(acc, curr) => acc + curr.score.total,
0
);
return calculateBandScore(correct, total, module, r.type);
});
const correct = moduleStats.reduce((acc, curr) => acc + curr.score.correct, 0);
const total = moduleStats.reduce((acc, curr) => acc + curr.score.total, 0);
return calculateBandScore(correct, total, module, r.type);
});
return resultModuleBandScores.length === 0
? -1
: resultModuleBandScores.reduce((acc, curr) => acc + curr, 0) /
results.length;
};
return resultModuleBandScores.length === 0 ? -1 : resultModuleBandScores.reduce((acc, curr) => acc + curr, 0) / results.length;
};
return (
<div
onClick={onClick}
className="border-mti-gray-platinum flex h-fit w-[350px] cursor-pointer flex-col gap-6 rounded-xl border bg-white p-4 transition duration-300 ease-in-out hover:drop-shadow"
>
<div className="flex flex-col gap-3">
<div className="flex flex-row justify-between">
<h3 className="text-xl font-semibold">{name}</h3>
<div className="flex gap-2">
{allowDownload &&
renderPdfIcon(id, "text-mti-gray-dim", "text-mti-gray-dim")}
{allowArchive &&
!archived &&
renderArchiveIcon("text-mti-gray-dim", "text-mti-gray-dim")}
</div>
</div>
<ProgressBar
color={results.length / assignees.length < 0.5 ? "red" : "purple"}
percentage={(results.length / assignees.length) * 100}
label={`${results.length}/${assignees.length}`}
className="h-5"
textClassName={
results.length / assignees.length < 0.5
? "!text-mti-gray-dim font-light"
: "text-white"
}
/>
</div>
<span className="flex justify-between gap-1">
<span>{moment(startDate).format("DD/MM/YY, HH:mm")}</span>
<span>-</span>
<span>{moment(endDate).format("DD/MM/YY, HH:mm")}</span>
</span>
<div className="-md:mt-2 grid w-full grid-cols-4 place-items-start gap-2">
{uniqBy(exams, (x) => x.module).map(({ module }) => (
<div
key={module}
className={clsx(
"-md:px-4 flex w-fit items-center gap-2 rounded-xl py-2 text-white md:px-2 xl:px-4",
module === "reading" && "bg-ielts-reading",
module === "listening" && "bg-ielts-listening",
module === "writing" && "bg-ielts-writing",
module === "speaking" && "bg-ielts-speaking",
module === "level" && "bg-ielts-level"
)}
>
{module === "reading" && <BsBook className="h-4 w-4" />}
{module === "listening" && <BsHeadphones className="h-4 w-4" />}
{module === "writing" && <BsPen className="h-4 w-4" />}
{module === "speaking" && <BsMegaphone className="h-4 w-4" />}
{module === "level" && <BsClipboard className="h-4 w-4" />}
{calculateAverageModuleScore(module) > -1 && (
<span className="text-sm">
{calculateAverageModuleScore(module).toFixed(1)}
</span>
)}
</div>
))}
</div>
</div>
);
return (
<div
onClick={onClick}
className="border-mti-gray-platinum flex h-fit w-[350px] cursor-pointer flex-col gap-6 rounded-xl border bg-white p-4 transition duration-300 ease-in-out hover:drop-shadow">
<div className="flex flex-col gap-3">
<div className="flex flex-row justify-between">
<h3 className="text-xl font-semibold">{name}</h3>
<div className="flex gap-2">
{allowDownload && renderPdfIcon(id, "text-mti-gray-dim", "text-mti-gray-dim")}
{allowArchive && !archived && renderArchiveIcon("text-mti-gray-dim", "text-mti-gray-dim")}
{allowUnarchive && archived && renderUnarchiveIcon("text-mti-gray-dim", "text-mti-gray-dim")}
</div>
</div>
<ProgressBar
color={results.length / assignees.length < 0.5 ? "red" : "purple"}
percentage={(results.length / assignees.length) * 100}
label={`${results.length}/${assignees.length}`}
className="h-5"
textClassName={results.length / assignees.length < 0.5 ? "!text-mti-gray-dim font-light" : "text-white"}
/>
</div>
<span className="flex justify-between gap-1">
<span>{moment(startDate).format("DD/MM/YY, HH:mm")}</span>
<span>-</span>
<span>{moment(endDate).format("DD/MM/YY, HH:mm")}</span>
</span>
<div className="-md:mt-2 grid w-full grid-cols-4 place-items-start gap-2">
{uniqBy(exams, (x) => x.module).map(({module}) => (
<div
key={module}
className={clsx(
"-md:px-4 flex w-fit items-center gap-2 rounded-xl py-2 text-white md:px-2 xl:px-4",
module === "reading" && "bg-ielts-reading",
module === "listening" && "bg-ielts-listening",
module === "writing" && "bg-ielts-writing",
module === "speaking" && "bg-ielts-speaking",
module === "level" && "bg-ielts-level",
)}>
{module === "reading" && <BsBook className="h-4 w-4" />}
{module === "listening" && <BsHeadphones className="h-4 w-4" />}
{module === "writing" && <BsPen className="h-4 w-4" />}
{module === "speaking" && <BsMegaphone className="h-4 w-4" />}
{module === "level" && <BsClipboard className="h-4 w-4" />}
{calculateAverageModuleScore(module) > -1 && (
<span className="text-sm">{calculateAverageModuleScore(module).toFixed(1)}</span>
)}
</div>
))}
</div>
</div>
);
}