/* eslint-disable @next/next/no-img-element */ import Modal from "@/components/Modal"; import useFilterRecordsByUser from "@/hooks/useFilterRecordsByUser"; import useUsers 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, } 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"; interface Props { user: CorporateUser; linkedCorporate?: CorporateUser | MasterCorporateUser; } type StudentPerformanceItem = User & {corporateName: string; group: string}; const StudentPerformanceList = ({items, stats, users}: {items: StudentPerformanceItem[]; stats: Stat[]; users: User[]}) => { const [isShowingAmount, setIsShowingAmount] = useState(false); const columnHelper = createColumnHelper(); const columns = [ columnHelper.accessor("name", { header: "Student Name", cell: (info) => info.getValue(), }), columnHelper.accessor("email", { header: "E-mail", cell: (info) => info.getValue(), }), columnHelper.accessor("demographicInformation.passport_id", { header: "ID", cell: (info) => info.getValue() || "N/A", }), columnHelper.accessor("group", { header: "Group", cell: (info) => info.getValue(), }), columnHelper.accessor("corporateName", { header: "Corporate", cell: (info) => info.getValue() || "N/A", }), columnHelper.accessor("levels.reading", { header: "Reading", cell: (info) => !isShowingAmount ? info.getValue() || 0 : `${Object.keys(groupByExam(stats.filter((x) => x.module === "reading" && x.user === info.row.original.id))).length} exams`, }), columnHelper.accessor("levels.listening", { header: "Listening", cell: (info) => !isShowingAmount ? info.getValue() || 0 : `${Object.keys(groupByExam(stats.filter((x) => x.module === "listening" && x.user === info.row.original.id))).length} exams`, }), columnHelper.accessor("levels.writing", { header: "Writing", cell: (info) => !isShowingAmount ? info.getValue() || 0 : `${Object.keys(groupByExam(stats.filter((x) => x.module === "writing" && x.user === info.row.original.id))).length} exams`, }), columnHelper.accessor("levels.speaking", { header: "Speaking", cell: (info) => !isShowingAmount ? info.getValue() || 0 : `${Object.keys(groupByExam(stats.filter((x) => x.module === "speaking" && x.user === info.row.original.id))).length} exams`, }), columnHelper.accessor("levels.level", { header: "Level", cell: (info) => !isShowingAmount ? info.getValue() || 0 : `${Object.keys(groupByExam(stats.filter((x) => x.module === "level" && x.user === info.row.original.id))).length} exams`, }), columnHelper.accessor("levels", { id: "overall_level", header: "Overall", cell: (info) => !isShowingAmount ? averageLevelCalculator( users, stats.filter((x) => x.user === info.row.original.id), ).toFixed(1) : `${Object.keys(groupByExam(stats.filter((x) => x.user === info.row.original.id))).length} exams`, }), ]; return (
Show Utilization data={items.sort( (a, b) => averageLevelCalculator( users, stats.filter((x) => x.user === b.id), ) - averageLevelCalculator( users, stats.filter((x) => x.user === a.id), ), )} columns={columns} />
); }; export default function CorporateDashboard({user, linkedCorporate}: Props) { const [selectedUser, setSelectedUser] = useState(); const [showModal, setShowModal] = useState(false); const {data: stats} = useFilterRecordsByUser(); const {users, reload, isLoading} = useUsers(); const {groups} = useGroups({admin: user.id}); const {assignments, isLoading: isAssignmentsLoading, reload: reloadAssignments} = useAssignments({corporate: user.id}); const {balance} = useUserBalance(); 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( () => users.filter( (x) => x.type === "student" && (!!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, users, selectedUser], ); useEffect(() => { setShowModal(!!selectedUser && router.asPath === "/#"); }, [selectedUser, router.asPath]); const studentFilter = (user: User) => user.type === "student" && groups.flatMap((g) => g.participants).includes(user.id); const teacherFilter = (user: User) => user.type === "teacher" && groups.flatMap((g) => g.participants).includes(user.id); 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}
); const StudentsList = () => { const filter = (x: User) => x.type === "student" && (!!selectedUser ? groups .filter((g) => g.admin === selectedUser.id) .flatMap((g) => g.participants) .includes(x.id) || false : groups.flatMap((g) => g.participants).includes(x.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

Students ({total})

)} /> ); }; const TeachersList = () => { const filter = (x: User) => x.type === "teacher" && (!!selectedUser ? groups .filter((g) => g.admin === selectedUser.id) .flatMap((g) => g.participants) .includes(x.id) || false : groups.flatMap((g) => g.participants).includes(x.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

Teachers ({total})

)} /> ); }; 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 StudentPerformancePage = () => { const students = users .filter((x) => x.type === "student" && groups.flatMap((g) => g.participants).includes(x.id)) .map((u) => ({ ...u, group: groups.find((x) => x.participants.includes(u.id))?.name || "N/A", corporateName: getUserCompanyName(u, users, groups), })); 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
Reload
); }; const averageLevelCalculator = (studentStats: Stat[]) => { const formattedStats = studentStats .map((s) => ({ focus: users.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); }; const DefaultDashboard = () => ( <> {!!linkedCorporate && (
Linked to: {linkedCorporate?.corporateInformation?.companyInformation.name || linkedCorporate.name}
)}
router.push("/#students")} Icon={BsPersonFill} label="Students" value={users.filter(studentFilter).length} color="purple" /> router.push("/#teachers")} Icon={BsPencilSquare} label="Teachers" value={users.filter(teacherFilter).length} 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")} />
Latest students
{users .filter(studentFilter) .sort((a, b) => dateSorter(a, b, "desc", "registrationDate")) .map((x) => ( ))}
Latest teachers
{users .filter(teacherFilter) .sort((a, b) => dateSorter(a, b, "desc", "registrationDate")) .map((x) => ( ))}
Highest level students
{users .filter(studentFilter) .sort((a, b) => calculateAverageLevel(b.levels) - calculateAverageLevel(a.levels)) .map((x) => ( ))}
Highest exam count students
{users .filter(studentFilter) .sort( (a, b) => Object.keys(groupByExam(getStatsByStudent(b))).length - Object.keys(groupByExam(getStatsByStudent(a))).length, ) .map((x) => ( ))}
); return ( <> setSelectedUser(undefined)}> <> {selectedUser && (
{ setSelectedUser(undefined); if (shouldReload) reload(); }} 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} />
)}
{router.asPath === "/#students" && } {router.asPath === "/#teachers" && } {router.asPath === "/#groups" && } {router.asPath === "/#assignments" && ( router.push("/")} /> )} {router.asPath === "/#studentsPerformance" && } {router.asPath === "/" && } ); }