/* eslint-disable @next/next/no-img-element */ import Modal from "@/components/Modal"; import useFilterRecordsByUser from "@/hooks/useFilterRecordsByUser"; import useUsers, { userHashStudent, userHashTeacher, userHashCorporate, } from "@/hooks/useUsers"; import { CorporateUser, Group, MasterCorporateUser, Stat, User, } from "@/interfaces/user"; import UserList from "@/pages/(admin)/Lists/UserList"; import { dateSorter } from "@/utils"; import moment from "moment"; import { useEffect, useMemo, useState } from "react"; import { BsArrowLeft, BsClipboard2Data, BsClipboard2DataFill, BsClock, BsGlobeCentralSouthAsia, BsPaperclip, BsPerson, BsPersonAdd, BsPersonFill, BsPersonFillGear, BsPersonGear, BsPencilSquare, BsPersonBadge, BsPersonCheck, BsPeople, BsArrowRepeat, BsPlus, BsEnvelopePaper, BsDatabase, } from "react-icons/bs"; import UserCard from "@/components/UserCard"; import useGroups from "@/hooks/useGroups"; import { averageLevelCalculator, calculateAverageLevel, calculateBandScore, } from "@/utils/score"; import { MODULE_ARRAY } from "@/utils/moduleUtils"; import { Module } from "@/interfaces"; import { groupByExam } from "@/utils/stats"; import IconCard from "../IconCard"; import GroupList from "@/pages/(admin)/Lists/GroupList"; import useFilterStore from "@/stores/listFilterStore"; import { useRouter } from "next/router"; import useCodes from "@/hooks/useCodes"; import { getUserCorporate } from "@/utils/groups"; import useAssignments from "@/hooks/useAssignments"; import { Assignment } from "@/interfaces/results"; import AssignmentView from "../AssignmentView"; import AssignmentCreator from "../AssignmentCreator"; import clsx from "clsx"; import AssignmentCard from "../AssignmentCard"; import { createColumnHelper } from "@tanstack/react-table"; import Checkbox from "@/components/Low/Checkbox"; import List from "@/components/List"; import { getUserCompanyName } from "@/resources/user"; import { futureAssignmentFilter, pastAssignmentFilter, archivedAssignmentFilter, activeAssignmentFilter, } from "@/utils/assignments"; import useUserBalance from "@/hooks/useUserBalance"; import AssignmentsPage from "../views/AssignmentsPage"; import StudentPerformancePage from "./StudentPerformancePage"; import MasterStatistical from "../MasterCorporate/MasterStatistical"; interface Props { user: CorporateUser; linkedCorporate?: CorporateUser | MasterCorporateUser; } const studentHash = { type: "student", orderBy: "registrationDate", size: 25, }; const teacherHash = { type: "teacher", orderBy: "registrationDate", size: 25, }; export default function CorporateDashboard({ user, linkedCorporate }: Props) { const [selectedUser, setSelectedUser] = useState(); const [showModal, setShowModal] = useState(false); const { data: stats } = useFilterRecordsByUser(); const { groups } = useGroups({ admin: user.id }); const { assignments, isLoading: isAssignmentsLoading, reload: reloadAssignments, } = useAssignments({ corporate: user.id }); const { balance } = useUserBalance(); const { users: students, total: totalStudents, reload: reloadStudents, isLoading: isStudentsLoading, } = useUsers(studentHash); const { users: teachers, total: totalTeachers, reload: reloadTeachers, isLoading: isTeachersLoading, } = useUsers(teacherHash); const appendUserFilters = useFilterStore((state) => state.appendUserFilter); const router = useRouter(); const assignmentsGroups = useMemo( () => groups.filter( (x) => x.admin === user.id || x.participants.includes(user.id) ), [groups, user.id] ); const assignmentsUsers = useMemo( () => [...teachers, ...students].filter((x) => !!selectedUser ? groups .filter((g) => g.admin === selectedUser.id) .flatMap((g) => g.participants) .includes(x.id) || false : groups.flatMap((g) => g.participants).includes(x.id) ), [groups, teachers, students, selectedUser] ); useEffect(() => { setShowModal(!!selectedUser && router.asPath === "/#"); }, [selectedUser, router.asPath]); const getStatsByStudent = (user: User) => stats.filter((s) => s.user === user.id); const UserDisplay = (displayUser: User) => (
setSelectedUser(displayUser)} className="flex w-full p-4 gap-4 items-center hover:bg-mti-purple-ultralight cursor-pointer transition ease-in-out duration-300" > {displayUser.name}
{displayUser.name} {displayUser.email}
); // this workaround will allow us toreuse the master statistical due to master corporate restraints // while still being able to use the corporate user const groupedByNameCorporateIds = useMemo( () => ({ [user.corporateInformation?.companyInformation?.name || user.name]: [ user.id, ], }), [user] ); const teachersAndStudents = useMemo( () => [...students, ...teachers], [students, teachers] ); const MasterStatisticalPage = () => { return ( <>
router.push("/")} className="flex gap-2 items-center text-mti-purple-light cursor-pointer hover:text-mti-purple-dark transition ease-in-out duration-300" > Back

Master Statistical

); }; const GroupsList = () => { const filter = (x: Group) => x.admin === user.id || x.participants.includes(user.id); return ( <>
router.push("/")} className="flex gap-2 items-center text-mti-purple-light cursor-pointer hover:text-mti-purple-dark transition ease-in-out duration-300" > Back

Groups ({groups.filter(filter).length})

); }; const averageLevelCalculator = (studentStats: Stat[]) => { const formattedStats = studentStats .map((s) => ({ focus: students.find((u) => u.id === s.user)?.focus, score: s.score, module: s.module, })) .filter((f) => !!f.focus); const bandScores = formattedStats.map((s) => ({ module: s.module, level: calculateBandScore( s.score.correct, s.score.total, s.module, s.focus! ), })); const levels: { [key in Module]: number } = { reading: 0, listening: 0, writing: 0, speaking: 0, level: 0, }; bandScores.forEach((b) => (levels[b.module] += b.level)); return calculateAverageLevel(levels); }; if (router.asPath === "/#students") return ( (
router.push("/")} className="flex gap-2 items-center text-mti-purple-light cursor-pointer hover:text-mti-purple-dark transition ease-in-out duration-300" > Back

Students ({total})

)} /> ); if (router.asPath === "/#teachers") return ( (
router.push("/")} className="flex gap-2 items-center text-mti-purple-light cursor-pointer hover:text-mti-purple-dark transition ease-in-out duration-300" > Back

Teachers ({total})

)} /> ); if (router.asPath === "/#groups") return ; if (router.asPath === "/#studentsPerformance") return ; if (router.asPath === "/#assignments") return ( router.push("/")} /> ); if (router.asPath === "/#statistical") return ; return ( <> setSelectedUser(undefined)}> <> {selectedUser && (
{ setSelectedUser(undefined); if (shouldReload && selectedUser!.type === "student") reloadStudents(); if (shouldReload && selectedUser!.type === "teacher") reloadTeachers(); }} onViewStudents={ selectedUser.type === "corporate" || selectedUser.type === "teacher" ? () => { appendUserFilters({ id: "view-students", filter: (x: User) => x.type === "student", }); appendUserFilters({ id: "belongs-to-admin", filter: (x: User) => groups .filter( (g) => g.admin === selectedUser.id || g.participants.includes(selectedUser.id) ) .flatMap((g) => g.participants) .includes(x.id), }); router.push("/list/users"); } : undefined } onViewTeachers={ selectedUser.type === "corporate" || selectedUser.type === "student" ? () => { appendUserFilters({ id: "view-teachers", filter: (x: User) => x.type === "teacher", }); appendUserFilters({ id: "belongs-to-admin", filter: (x: User) => groups .filter( (g) => g.admin === selectedUser.id || g.participants.includes(selectedUser.id) ) .flatMap((g) => g.participants) .includes(x.id), }); router.push("/list/users"); } : undefined } user={selectedUser} />
)}
<> {!!linkedCorporate && (
Linked to:{" "} {linkedCorporate?.corporateInformation?.companyInformation.name || linkedCorporate.name}
)}
router.push("/#students")} isLoading={isStudentsLoading} Icon={BsPersonFill} label="Students" value={totalStudents} color="purple" /> router.push("/#teachers")} isLoading={isTeachersLoading} Icon={BsPencilSquare} label="Teachers" value={totalTeachers} color="purple" /> groups.flatMap((g) => g.participants).includes(s.user) ).length } color="purple" /> groups.flatMap((g) => g.participants).includes(s.user) ) ).toFixed(1)} color="purple" /> router.push("/#groups")} Icon={BsPeople} label="Groups" value={groups.length} color="purple" /> router.push("/#studentsPerformance")} /> router.push("/#statistical")} />
Latest students
{students .sort((a, b) => dateSorter(a, b, "desc", "registrationDate")) .map((x) => ( ))}
Latest teachers
{teachers .sort((a, b) => dateSorter(a, b, "desc", "registrationDate")) .map((x) => ( ))}
Highest level students
{students .sort( (a, b) => calculateAverageLevel(b.levels) - calculateAverageLevel(a.levels) ) .map((x) => ( ))}
Highest exam count students
{students .sort( (a, b) => Object.keys(groupByExam(getStatsByStudent(b))).length - Object.keys(groupByExam(getStatsByStudent(a))).length ) .map((x) => ( ))}
); }