/* eslint-disable @next/next/no-img-element */ import Layout from "@/components/High/Layout"; import Button from "@/components/Low/Button"; import ProgressBar from "@/components/Low/ProgressBar"; import InviteWithUserCard from "@/components/Medium/InviteWithUserCard"; import ModuleBadge from "@/components/ModuleBadge"; import ProfileSummary from "@/components/ProfileSummary"; import { Session } from "@/hooks/useSessions"; import { Grading } from "@/interfaces"; import { EntityWithRoles } from "@/interfaces/entity"; import { Exam } from "@/interfaces/exam"; import { InviteWithEntity } from "@/interfaces/invite"; import { Assignment } from "@/interfaces/results"; import { Stat, User } from "@/interfaces/user"; import { sessionOptions } from "@/lib/session"; import useExamStore from "@/stores/exam"; import { findBy, mapBy, redirect, serialize } from "@/utils"; import { requestUser } from "@/utils/api"; import { activeAssignmentFilter } from "@/utils/assignments"; import { getAssignmentsByAssignee } from "@/utils/assignments.be"; import { getEntitiesWithRoles, getEntityWithRoles } from "@/utils/entities.be"; import { getExamsByIds } from "@/utils/exams.be"; import { getGradingSystemByEntity } from "@/utils/grading.be"; import { convertInvitersToEntity, getInvitesByInvitee } from "@/utils/invites.be"; import { countExamModules, countFullExams, MODULE_ARRAY, sortByModule, sortByModuleName } from "@/utils/moduleUtils"; import { checkAccess } from "@/utils/permissions"; import { getGradingLabel } from "@/utils/score"; import { getSessionsByUser } from "@/utils/sessions.be"; import { averageScore } from "@/utils/stats"; import { getStatsByUser } from "@/utils/stats.be"; import clsx from "clsx"; import { withIronSessionSsr } from "iron-session/next"; import { capitalize, uniqBy } from "lodash"; import moment from "moment"; import Head from "next/head"; import { useRouter } from "next/router"; import { useMemo } from "react"; import { BsBook, BsClipboard, BsFileEarmarkText, BsHeadphones, BsMegaphone, BsPen, BsPencil, BsStar } from "react-icons/bs"; import { ToastContainer } from "react-toastify"; interface Props { user: User; entities: EntityWithRoles[]; assignments: Assignment[]; stats: Stat[]; exams: Exam[]; sessions: Session[]; invites: InviteWithEntity[]; grading: Grading; } export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => { const user = await requestUser(req, res) if (!user || !user.isVerified) return redirect("/login") if (!checkAccess(user, ["admin", "developer", "student"])) return redirect("/") const entityIDS = mapBy(user.entities, "id") || []; const entities = await getEntitiesWithRoles(entityIDS); const assignments = await getAssignmentsByAssignee(user.id, { archived: { $ne: true } }); const stats = await getStatsByUser(user.id); const sessions = await getSessionsByUser(user.id, 10); const invites = await getInvitesByInvitee(user.id); const grading = await getGradingSystemByEntity(entityIDS[0] || ""); const formattedInvites = await Promise.all(invites.map(convertInvitersToEntity)); const examIDs = uniqBy( assignments.flatMap((a) => a.exams.filter((e) => e.assignee === user.id).map((e) => ({ module: e.module, id: e.id, key: `${e.module}_${e.id}` })), ), "key", ); const exams = await getExamsByIds(examIDs); return { props: serialize({ user, entities, assignments, stats, exams, sessions, invites: formattedInvites, grading }) }; }, sessionOptions); export default function Dashboard({ user, entities, assignments, stats, invites, grading, sessions, exams }: Props) { const router = useRouter(); const dispatch = useExamStore((state) => state.dispatch); const startAssignment = (assignment: Assignment) => { const assignmentExams = exams.filter(e => { const exam = findBy(assignment.exams, 'id', e.id) return !!exam && exam.module === e.module }) if (assignmentExams.every((x) => !!x)) { dispatch({ type: "INIT_EXAM", payload: { exams: assignmentExams.sort(sortByModule), modules: mapBy(assignmentExams.sort(sortByModule), 'module'), assignment } }) router.push("/exam"); } }; const studentAssignments = useMemo(() => assignments.filter(activeAssignmentFilter), [assignments]); return ( <> EnCoach {entities.length > 0 && (
{mapBy(entities, "label")?.join(", ")}
)} , value: countFullExams(stats), label: "Exams", tooltip: "Number of all conducted completed exams", }, { icon: , value: countExamModules(stats), label: "Modules", tooltip: "Number of all exam modules performed including Level Test", }, { icon: , value: `${stats.length > 0 ? averageScore(stats) : 0}%`, label: "Average Score", tooltip: "Average success rate for questions responded", }, ]} /> {/* Assignments */}
Assignments {studentAssignments.length === 0 && "Assignments will appear here. It seems that for now there are no assignments for you."} {studentAssignments .sort((a, b) => moment(a.startDate).diff(b.startDate)) .map((assignment) => (
r.user).includes(user.id) && "border-mti-green-light", )} key={assignment.id}>

{assignment.name}

{moment(assignment.startDate).format("DD/MM/YY, HH:mm")} - {moment(assignment.endDate).format("DD/MM/YY, HH:mm")}
{assignment.exams .filter((e) => e.assignee === user.id) .map((e) => e.module) .sort(sortByModuleName) .map((module) => ( ))}
{!assignment.results.map((r) => r.user).includes(user.id) && ( <>
x.assignment?.id === assignment.id).length > 0 && "tooltip", )}>
)} {assignment.results.map((r) => r.user).includes(user.id) && ( )}
))}
{/* Invites */} {invites.length > 0 && (
{invites.map((invite) => ( router.replace(router.asPath)} /> ))}
)} {/* Score History */}
Score History
{MODULE_ARRAY.map((module) => { const desiredLevel = user.desiredLevels[module] || 9; const level = user.levels[module] || 0; return (
{module === "reading" && } {module === "listening" && } {module === "writing" && } {module === "speaking" && } {module === "level" && }
{capitalize(module)} {module === "level" && !!grading && `English Level: ${getGradingLabel(level, grading.steps)}`} {module !== "level" && `Level ${level} / Level 9 (Desired Level: ${desiredLevel})`}
); })}
); }