diff --git a/src/dashboards/AssignmentView.tsx b/src/dashboards/AssignmentView.tsx
index 03f5baff..7426b19d 100644
--- a/src/dashboards/AssignmentView.tsx
+++ b/src/dashboards/AssignmentView.tsx
@@ -2,329 +2,435 @@ import Button from "@/components/Low/Button";
import ProgressBar from "@/components/Low/ProgressBar";
import Modal from "@/components/Modal";
import useUsers from "@/hooks/useUsers";
-import {Module} from "@/interfaces";
-import {Assignment} from "@/interfaces/results";
-import {Stat, User} from "@/interfaces/user";
+import { Module } from "@/interfaces";
+import { Assignment } from "@/interfaces/results";
+import { Stat, User } from "@/interfaces/user";
import useExamStore from "@/stores/examStore";
-import {getExamById} from "@/utils/exams";
-import {sortByModule} from "@/utils/moduleUtils";
-import {calculateBandScore} from "@/utils/score";
-import {convertToUserSolutions} from "@/utils/stats";
-import {getUserName} from "@/utils/users";
+import { getExamById } from "@/utils/exams";
+import { sortByModule } from "@/utils/moduleUtils";
+import { calculateBandScore } from "@/utils/score";
+import { convertToUserSolutions } from "@/utils/stats";
+import { getUserName } from "@/utils/users";
import axios from "axios";
import clsx from "clsx";
-import {capitalize, uniqBy} from "lodash";
+import { capitalize, uniqBy } from "lodash";
import moment from "moment";
-import {useRouter} from "next/router";
-import {BsBook, BsClipboard, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
-import {toast} from "react-toastify";
+import { useRouter } from "next/router";
+import {
+ BsBook,
+ BsClipboard,
+ BsHeadphones,
+ BsMegaphone,
+ BsPen,
+} from "react-icons/bs";
+import { toast } from "react-toastify";
+import { activeAssignmentFilter } from "@/utils/assignments";
interface Props {
- isOpen: boolean;
- assignment?: Assignment;
- onClose: () => void;
+ isOpen: boolean;
+ assignment?: Assignment;
+ onClose: () => void;
}
-export default function AssignmentView({isOpen, assignment, onClose}: Props) {
- const {users} = useUsers();
- const router = useRouter();
+export default function AssignmentView({ isOpen, assignment, onClose }: Props) {
+ const { users } = useUsers();
+ const router = useRouter();
- const setExams = useExamStore((state) => state.setExams);
- const setShowSolutions = useExamStore((state) => state.setShowSolutions);
- const setUserSolutions = useExamStore((state) => state.setUserSolutions);
- const setSelectedModules = useExamStore((state) => state.setSelectedModules);
+ const setExams = useExamStore((state) => state.setExams);
+ const setShowSolutions = useExamStore((state) => state.setShowSolutions);
+ const setUserSolutions = useExamStore((state) => state.setUserSolutions);
+ const setSelectedModules = useExamStore((state) => state.setSelectedModules);
- const deleteAssignment = async () => {
- if (!confirm("Are you sure you want to delete this assignment?")) return;
+ const deleteAssignment = async () => {
+ if (!confirm("Are you sure you want to delete this assignment?")) return;
- axios
- .delete(`/api/assignments/${assignment?.id}`)
- .then(() => toast.success(`Successfully deleted the assignment "${assignment?.name}".`))
- .catch(() => toast.error("Something went wrong, please try again later."))
- .finally(onClose);
- };
+ axios
+ .delete(`/api/assignments/${assignment?.id}`)
+ .then(() =>
+ toast.success(
+ `Successfully deleted the assignment "${assignment?.name}".`
+ )
+ )
+ .catch(() => toast.error("Something went wrong, please try again later."))
+ .finally(onClose);
+ };
- const startAssignment = () => {
- if (assignment) {
- axios
- .post(`/api/assignments/${assignment.id}/start`)
- .then(() => {
- toast.success(`The assignment "${assignment.name}" has been started successfully!`);
- })
- .catch((e) => {
- console.log(e);
- toast.error("Something went wrong, please try again later!");
- });
- }
- };
+ const startAssignment = () => {
+ if (assignment) {
+ axios
+ .post(`/api/assignments/${assignment.id}/start`)
+ .then(() => {
+ toast.success(
+ `The assignment "${assignment.name}" has been started successfully!`
+ );
+ })
+ .catch((e) => {
+ console.log(e);
+ toast.error("Something went wrong, please try again later!");
+ });
+ }
+ };
- const formatTimestamp = (timestamp: string) => {
- const date = moment(parseInt(timestamp));
- const formatter = "YYYY/MM/DD - HH:mm";
+ const formatTimestamp = (timestamp: string) => {
+ const date = moment(parseInt(timestamp));
+ const formatter = "YYYY/MM/DD - HH:mm";
- return date.format(formatter);
- };
+ return date.format(formatter);
+ };
- const calculateAverageModuleScore = (module: Module) => {
- if (!assignment) return -1;
+ const calculateAverageModuleScore = (module: Module) => {
+ if (!assignment) return -1;
- const resultModuleBandScores = assignment.results.map((r) => {
- const moduleStats = r.stats.filter((s) => s.module === module);
+ const resultModuleBandScores = assignment.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) / assignment.results.length;
- };
+ return resultModuleBandScores.length === 0
+ ? -1
+ : resultModuleBandScores.reduce((acc, curr) => acc + curr, 0) /
+ assignment.results.length;
+ };
- const aggregateScoresByModule = (stats: Stat[]): {module: Module; total: number; missing: number; correct: number}[] => {
- const scores: {
- [key in Module]: {total: number; missing: number; correct: number};
- } = {
- reading: {
- total: 0,
- correct: 0,
- missing: 0,
- },
- listening: {
- total: 0,
- correct: 0,
- missing: 0,
- },
- writing: {
- total: 0,
- correct: 0,
- missing: 0,
- },
- speaking: {
- total: 0,
- correct: 0,
- missing: 0,
- },
- level: {
- total: 0,
- correct: 0,
- missing: 0,
- },
- };
+ const aggregateScoresByModule = (
+ stats: Stat[]
+ ): { module: Module; total: number; missing: number; correct: number }[] => {
+ const scores: {
+ [key in Module]: { total: number; missing: number; correct: number };
+ } = {
+ reading: {
+ total: 0,
+ correct: 0,
+ missing: 0,
+ },
+ listening: {
+ total: 0,
+ correct: 0,
+ missing: 0,
+ },
+ writing: {
+ total: 0,
+ correct: 0,
+ missing: 0,
+ },
+ speaking: {
+ total: 0,
+ correct: 0,
+ missing: 0,
+ },
+ level: {
+ total: 0,
+ correct: 0,
+ missing: 0,
+ },
+ };
- stats.forEach((x) => {
- scores[x.module!] = {
- total: scores[x.module!].total + x.score.total,
- correct: scores[x.module!].correct + x.score.correct,
- missing: scores[x.module!].missing + x.score.missing,
- };
- });
+ stats.forEach((x) => {
+ scores[x.module!] = {
+ total: scores[x.module!].total + x.score.total,
+ correct: scores[x.module!].correct + x.score.correct,
+ missing: scores[x.module!].missing + x.score.missing,
+ };
+ });
- return Object.keys(scores)
- .filter((x) => scores[x as Module].total > 0)
- .map((x) => ({module: x as Module, ...scores[x as Module]}));
- };
+ return Object.keys(scores)
+ .filter((x) => scores[x as Module].total > 0)
+ .map((x) => ({ module: x as Module, ...scores[x as Module] }));
+ };
- const customContent = (stats: Stat[], user: string, focus: "academic" | "general") => {
- const correct = stats.reduce((accumulator, current) => accumulator + current.score.correct, 0);
- const total = stats.reduce((accumulator, current) => accumulator + current.score.total, 0);
- const aggregatedScores = aggregateScoresByModule(stats).filter((x) => x.total > 0);
+ const customContent = (
+ stats: Stat[],
+ user: string,
+ focus: "academic" | "general"
+ ) => {
+ const correct = stats.reduce(
+ (accumulator, current) => accumulator + current.score.correct,
+ 0
+ );
+ const total = stats.reduce(
+ (accumulator, current) => accumulator + current.score.total,
+ 0
+ );
+ const aggregatedScores = aggregateScoresByModule(stats).filter(
+ (x) => x.total > 0
+ );
- const aggregatedLevels = aggregatedScores.map((x) => ({
- module: x.module,
- level: calculateBandScore(x.correct, x.total, x.module, focus),
- }));
+ const aggregatedLevels = aggregatedScores.map((x) => ({
+ module: x.module,
+ level: calculateBandScore(x.correct, x.total, x.module, focus),
+ }));
- const timeSpent = stats[0].timeSpent;
+ const timeSpent = stats[0].timeSpent;
- const selectExam = () => {
- const examPromises = uniqBy(stats, "exam").map((stat) => getExamById(stat.module, stat.exam));
+ const selectExam = () => {
+ const examPromises = uniqBy(stats, "exam").map((stat) =>
+ getExamById(stat.module, stat.exam)
+ );
- Promise.all(examPromises).then((exams) => {
- if (exams.every((x) => !!x)) {
- setUserSolutions(convertToUserSolutions(stats));
- setShowSolutions(true);
- setExams(exams.map((x) => x!).sort(sortByModule));
- setSelectedModules(
- exams
- .map((x) => x!)
- .sort(sortByModule)
- .map((x) => x!.module),
- );
- router.push("/exercises");
- }
- });
- };
+ Promise.all(examPromises).then((exams) => {
+ if (exams.every((x) => !!x)) {
+ setUserSolutions(convertToUserSolutions(stats));
+ setShowSolutions(true);
+ setExams(exams.map((x) => x!).sort(sortByModule));
+ setSelectedModules(
+ exams
+ .map((x) => x!)
+ .sort(sortByModule)
+ .map((x) => x!.module)
+ );
+ router.push("/exercises");
+ }
+ });
+ };
- const content = (
- <>
-
-
- {formatTimestamp(stats[0].date.toString())}
- {timeSpent && (
- <>
- •
- {Math.floor(timeSpent / 60)} minutes
- >
- )}
-
-
= 0.7 && "text-mti-purple",
- correct / total >= 0.3 && correct / total < 0.7 && "text-mti-red",
- correct / total < 0.3 && "text-mti-rose",
- )}>
- Level{" "}
- {(aggregatedLevels.reduce((accumulator, current) => accumulator + current.level, 0) / aggregatedLevels.length).toFixed(1)}
-
-
+ const content = (
+ <>
+
+
+
+ {formatTimestamp(stats[0].date.toString())}
+
+ {timeSpent && (
+ <>
+ •
+
+ {Math.floor(timeSpent / 60)} minutes
+
+ >
+ )}
+
+
= 0.7 && "text-mti-purple",
+ correct / total >= 0.3 && correct / total < 0.7 && "text-mti-red",
+ correct / total < 0.3 && "text-mti-rose"
+ )}
+ >
+ Level{" "}
+ {(
+ aggregatedLevels.reduce(
+ (accumulator, current) => accumulator + current.level,
+ 0
+ ) / aggregatedLevels.length
+ ).toFixed(1)}
+
+
-
-
- {aggregatedLevels.map(({module, level}) => (
-
- {module === "reading" && }
- {module === "listening" && }
- {module === "writing" && }
- {module === "speaking" && }
- {module === "level" && }
- {level.toFixed(1)}
-
- ))}
-
-
- >
- );
+
+
+ {aggregatedLevels.map(({ module, level }) => (
+
+ {module === "reading" && }
+ {module === "listening" && }
+ {module === "writing" && }
+ {module === "speaking" && }
+ {module === "level" && }
+ {level.toFixed(1)}
+
+ ))}
+
+
+ >
+ );
- return (
-
-
- {(() => {
- const student = users.find((u) => u.id === user);
- return `${student?.name} (${student?.email})`;
- })()}
-
-
= 0.7 && "hover:border-mti-purple",
- correct / total >= 0.3 && correct / total < 0.7 && "hover:border-mti-red",
- correct / total < 0.3 && "hover:border-mti-rose",
- )}
- onClick={selectExam}
- role="button">
- {content}
-
-
= 0.7 && "hover:border-mti-purple",
- correct / total >= 0.3 && correct / total < 0.7 && "hover:border-mti-red",
- correct / total < 0.3 && "hover:border-mti-rose",
- )}
- data-tip="Your screen size is too small to view previous exams."
- role="button">
- {content}
-
-
- );
- };
+ return (
+
+
+ {(() => {
+ const student = users.find((u) => u.id === user);
+ return `${student?.name} (${student?.email})`;
+ })()}
+
+
= 0.7 && "hover:border-mti-purple",
+ correct / total >= 0.3 &&
+ correct / total < 0.7 &&
+ "hover:border-mti-red",
+ correct / total < 0.3 && "hover:border-mti-rose"
+ )}
+ onClick={selectExam}
+ role="button"
+ >
+ {content}
+
+
= 0.7 && "hover:border-mti-purple",
+ correct / total >= 0.3 &&
+ correct / total < 0.7 &&
+ "hover:border-mti-red",
+ correct / total < 0.3 && "hover:border-mti-rose"
+ )}
+ data-tip="Your screen size is too small to view previous exams."
+ role="button"
+ >
+ {content}
+
+
+ );
+ };
- return (
-
-
-
-
-
- Start Date: {moment(assignment?.startDate).format("DD/MM/YY, HH:mm")}
- End Date: {moment(assignment?.endDate).format("DD/MM/YY, HH:mm")}
-
-
-
- Assignees:{" "}
- {users
- .filter((u) => assignment?.assignees.includes(u.id))
- .map((u) => `${u.name} (${u.email})`)
- .join(", ")}
-
- Assigner: {getUserName(users.find((x) => x.id === assignment?.assigner))}
-
-
-
-
Average Scores
-
- {assignment &&
- uniqBy(assignment.exams, (x) => x.module).map(({module}) => (
-
- {module === "reading" && }
- {module === "listening" && }
- {module === "writing" && }
- {module === "speaking" && }
- {module === "level" && }
- {calculateAverageModuleScore(module) > -1 && (
- {calculateAverageModuleScore(module).toFixed(1)}
- )}
-
- ))}
-
-
-
-
- Results ({assignment?.results.length}/{assignment?.assignees.length})
-
-
- {assignment && assignment?.results.length > 0 && (
-
- {assignment.results.map((r) => customContent(r.stats, r.user, r.type))}
-
- )}
- {assignment && assignment?.results.length === 0 &&
No results yet...}
-
-
+ const shouldRenderStart = () => {
+ if (assignment) {
+ if (activeAssignmentFilter(assignment)) {
+ return false;
+ }
-
- {assignment && (assignment.results.length === assignment.assignees.length || moment().isAfter(moment(assignment.endDate))) && (
-
- )}
- {assignment && (assignment.results.length === 0 || moment().isAfter(moment(assignment.startDate))) && (
-
- )}
-
-
-
-
- );
+ return assignment.results.length === 0;
+ }
+
+ return false;
+ };
+
+ return (
+
+
+
+
+
+
+ Start Date:{" "}
+ {moment(assignment?.startDate).format("DD/MM/YY, HH:mm")}
+
+
+ End Date: {moment(assignment?.endDate).format("DD/MM/YY, HH:mm")}
+
+
+
+
+ Assignees:{" "}
+ {users
+ .filter((u) => assignment?.assignees.includes(u.id))
+ .map((u) => `${u.name} (${u.email})`)
+ .join(", ")}
+
+
+ Assigner:{" "}
+ {getUserName(users.find((x) => x.id === assignment?.assigner))}
+
+
+
+
+
Average Scores
+
+ {assignment &&
+ uniqBy(assignment.exams, (x) => x.module).map(({ module }) => (
+
+ {module === "reading" && }
+ {module === "listening" && (
+
+ )}
+ {module === "writing" && }
+ {module === "speaking" && }
+ {module === "level" && }
+ {calculateAverageModuleScore(module) > -1 && (
+
+ {calculateAverageModuleScore(module).toFixed(1)}
+
+ )}
+
+ ))}
+
+
+
+
+ Results ({assignment?.results.length}/{assignment?.assignees.length}
+ )
+
+
+ {assignment && assignment?.results.length > 0 && (
+
+ {assignment.results.map((r) =>
+ customContent(r.stats, r.user, r.type)
+ )}
+
+ )}
+ {assignment && assignment?.results.length === 0 && (
+
No results yet...
+ )}
+
+
+
+
+ {assignment &&
+ (assignment.results.length === assignment.assignees.length ||
+ moment().isAfter(moment(assignment.endDate))) && (
+
+ )}
+ {/** if the assignment is not deemed as active yet, display start */}
+ {shouldRenderStart() && (
+
+ )}
+
+
+
+
+ );
}
diff --git a/src/dashboards/views/AssignmentsPage.tsx b/src/dashboards/views/AssignmentsPage.tsx
index c6ff9a10..19e0a8d0 100644
--- a/src/dashboards/views/AssignmentsPage.tsx
+++ b/src/dashboards/views/AssignmentsPage.tsx
@@ -1,150 +1,229 @@
-import {Assignment} from "@/interfaces/results";
-import {CorporateUser, Group, User} from "@/interfaces/user";
-import {getUserCompanyName} from "@/resources/user";
-import {activeAssignmentFilter, archivedAssignmentFilter, futureAssignmentFilter, pastAssignmentFilter} from "@/utils/assignments";
+import { Assignment } from "@/interfaces/results";
+import { CorporateUser, Group, User } from "@/interfaces/user";
+import { getUserCompanyName } from "@/resources/user";
+import {
+ activeAssignmentFilter,
+ archivedAssignmentFilter,
+ futureAssignmentFilter,
+ pastAssignmentFilter,
+ unstartedAssignmentFilter,
+} from "@/utils/assignments";
import clsx from "clsx";
-import {groupBy} from "lodash";
-import {useState} from "react";
-import {BsArrowLeft, BsArrowRepeat, BsPlus} from "react-icons/bs";
+import { groupBy } from "lodash";
+import { useState } from "react";
+import { BsArrowLeft, BsArrowRepeat, BsPlus } from "react-icons/bs";
import AssignmentCard from "../AssignmentCard";
import AssignmentCreator from "../AssignmentCreator";
import AssignmentView from "../AssignmentView";
interface Props {
- assignments: Assignment[];
- corporateAssignments?: ({corporate?: CorporateUser} & Assignment)[];
- groups: Group[];
- users: User[];
- isLoading: boolean;
- user: User;
- onBack: () => void;
- reloadAssignments: () => void;
+ assignments: Assignment[];
+ corporateAssignments?: ({ corporate?: CorporateUser } & Assignment)[];
+ groups: Group[];
+ users: User[];
+ isLoading: boolean;
+ user: User;
+ onBack: () => void;
+ reloadAssignments: () => void;
}
-export default function AssignmentsPage({assignments, corporateAssignments, user, groups, users, isLoading, onBack, reloadAssignments}: Props) {
- const [selectedAssignment, setSelectedAssignment] = useState();
- const [isCreatingAssignment, setIsCreatingAssignment] = useState(false);
+export default function AssignmentsPage({
+ assignments,
+ corporateAssignments,
+ user,
+ groups,
+ users,
+ isLoading,
+ onBack,
+ reloadAssignments,
+}: Props) {
+ const [selectedAssignment, setSelectedAssignment] = useState();
+ const [isCreatingAssignment, setIsCreatingAssignment] = useState(false);
- return (
- <>
- {
- setSelectedAssignment(undefined);
- setIsCreatingAssignment(false);
- reloadAssignments();
- }}
- assignment={selectedAssignment}
- />
- {/** I'll be using this is creating assingment as a workaround for a key to trigger a new rendering */}
- {isCreatingAssignment && {
- setIsCreatingAssignment(false);
- setSelectedAssignment(undefined);
- reloadAssignments();
- }}
- />}
-
-
-
- Back
-
-
- Reload
-
-
-
-
-
Active Assignments Status
-
-
- Total: {assignments.filter(activeAssignmentFilter).reduce((acc, curr) => acc + curr.results.length, 0)}/
- {assignments.filter(activeAssignmentFilter).reduce((acc, curr) => curr.exams.length + acc, 0)}
-
- {Object.keys(groupBy(corporateAssignments, (x) => x.corporate?.id)).map((x) => (
-
- {getUserCompanyName(users.find((u) => u.id === x)!, users, groups)}:
-
- {groupBy(corporateAssignments, (x) => x.corporate?.id)[x].reduce((acc, curr) => curr.results.length + acc, 0)}/
- {groupBy(corporateAssignments, (x) => x.corporate?.id)[x].reduce((acc, curr) => curr.exams.length + acc, 0)}
-
-
- ))}
-
-
-
- Active Assignments ({assignments.filter(activeAssignmentFilter).length})
-
- {assignments.filter(activeAssignmentFilter).map((a) => (
-
setSelectedAssignment(a)} key={a.id} />
- ))}
-
-
-
- Planned Assignments ({assignments.filter(futureAssignmentFilter).length})
-
-
setIsCreatingAssignment(true)}
- className="w-[250px] h-[200px] flex flex-col gap-2 items-center justify-center bg-white hover:bg-mti-purple-ultralight text-mti-purple-light hover:text-mti-purple-dark border border-mti-gray-platinum hover:drop-shadow p-4 cursor-pointer rounded-xl transition ease-in-out duration-300">
-
- New Assignment
-
- {assignments.filter(futureAssignmentFilter).map((a) => (
-
{
- setSelectedAssignment(a);
- setIsCreatingAssignment(true);
- }}
- key={a.id}
- />
- ))}
-
-
-
- Past Assignments ({assignments.filter(pastAssignmentFilter).length})
-
- {assignments.filter(pastAssignmentFilter).map((a) => (
-
setSelectedAssignment(a)}
- key={a.id}
- allowDownload
- reload={reloadAssignments}
- allowArchive
- allowExcelDownload
- />
- ))}
-
-
-
- Archived Assignments ({assignments.filter(archivedAssignmentFilter).length})
-
- {assignments.filter(archivedAssignmentFilter).map((a) => (
-
setSelectedAssignment(a)}
- key={a.id}
- allowDownload
- reload={reloadAssignments}
- allowUnarchive
- allowExcelDownload
- />
- ))}
-
-
- >
- );
+ const unstartedAssignments = assignments.filter(unstartedAssignmentFilter);
+
+ const displayAssignmentView = !!selectedAssignment && !isCreatingAssignment;
+
+ return (
+ <>
+ {displayAssignmentView && (
+ {
+ setSelectedAssignment(undefined);
+ setIsCreatingAssignment(false);
+ reloadAssignments();
+ }}
+ assignment={selectedAssignment}
+ />
+ )}
+ {/** I'll be using this is creating assingment as a workaround for a key to trigger a new rendering */}
+ {isCreatingAssignment && (
+ {
+ setIsCreatingAssignment(false);
+ setSelectedAssignment(undefined);
+ reloadAssignments();
+ }}
+ />
+ )}
+
+
+
+ Back
+
+
+ Reload
+
+
+
+
+
Active Assignments Status
+
+
+ Total:{" "}
+ {assignments
+ .filter(activeAssignmentFilter)
+ .reduce((acc, curr) => acc + curr.results.length, 0)}
+ /
+ {assignments
+ .filter(activeAssignmentFilter)
+ .reduce((acc, curr) => curr.exams.length + acc, 0)}
+
+ {Object.keys(
+ groupBy(corporateAssignments, (x) => x.corporate?.id)
+ ).map((x) => (
+
+
+ {getUserCompanyName(
+ users.find((u) => u.id === x)!,
+ users,
+ groups
+ )}
+ :{" "}
+
+
+ {groupBy(corporateAssignments, (x) => x.corporate?.id)[
+ x
+ ].reduce((acc, curr) => curr.results.length + acc, 0)}
+ /
+ {groupBy(corporateAssignments, (x) => x.corporate?.id)[
+ x
+ ].reduce((acc, curr) => curr.exams.length + acc, 0)}
+
+
+ ))}
+
+
+
+
+ Active Assignments (
+ {assignments.filter(activeAssignmentFilter).length})
+
+
+ {assignments.filter(activeAssignmentFilter).map((a) => (
+
setSelectedAssignment(a)}
+ key={a.id}
+ />
+ ))}
+
+
+
+
+ Active Assignments Pending Start ({unstartedAssignments.length})
+
+
+ {unstartedAssignments.map((a) => (
+
setSelectedAssignment(a)}
+ key={a.id}
+ />
+ ))}
+
+
+
+
+ Planned Assignments (
+ {assignments.filter(futureAssignmentFilter).length})
+
+
+
setIsCreatingAssignment(true)}
+ className="w-[250px] h-[200px] flex flex-col gap-2 items-center justify-center bg-white hover:bg-mti-purple-ultralight text-mti-purple-light hover:text-mti-purple-dark border border-mti-gray-platinum hover:drop-shadow p-4 cursor-pointer rounded-xl transition ease-in-out duration-300"
+ >
+
+ New Assignment
+
+ {assignments.filter(futureAssignmentFilter).map((a) => (
+
{
+ setSelectedAssignment(a);
+ setIsCreatingAssignment(true);
+ }}
+ key={a.id}
+ />
+ ))}
+
+
+
+
+ Past Assignments ({assignments.filter(pastAssignmentFilter).length})
+
+
+ {assignments.filter(pastAssignmentFilter).map((a) => (
+
setSelectedAssignment(a)}
+ key={a.id}
+ allowDownload
+ reload={reloadAssignments}
+ allowArchive
+ allowExcelDownload
+ />
+ ))}
+
+
+
+
+ Archived Assignments (
+ {assignments.filter(archivedAssignmentFilter).length})
+
+
+ {assignments.filter(archivedAssignmentFilter).map((a) => (
+
setSelectedAssignment(a)}
+ key={a.id}
+ allowDownload
+ reload={reloadAssignments}
+ allowUnarchive
+ allowExcelDownload
+ />
+ ))}
+
+
+ >
+ );
}
diff --git a/src/utils/assignments.ts b/src/utils/assignments.ts
index a4584981..6bfc6fa5 100644
--- a/src/utils/assignments.ts
+++ b/src/utils/assignments.ts
@@ -38,3 +38,14 @@ export const activeAssignmentFilter = (a: Assignment) => {
return false;
};
+
+export const unstartedAssignmentFilter = (a: Assignment) => {
+ const currentDate = moment();
+ if(moment(a.endDate).isBefore(currentDate)) return false;
+ if(a.archived) return false;
+
+ if(a.autoStart && a.autoStartDate && moment(a.autoStartDate).isBefore(currentDate)) return false;
+
+ if(!a.start) return true;
+ return false;
+}
\ No newline at end of file