import React from "react"; import { CorporateUser, User } from "@/interfaces/user"; import { BsBank, BsPersonFill } from "react-icons/bs"; import IconCard from "./IconCard"; import useAssignmentsCorporates from "@/hooks/useAssignmentCorporates"; import ReactDatePicker from "react-datepicker"; import moment from "moment"; import { Assignment, AssignmentWithCorporateId } from "@/interfaces/results"; import { CellContext, createColumnHelper, flexRender, getCoreRowModel, HeaderGroup, Table, useReactTable, } from "@tanstack/react-table"; import Checkbox from "@/components/Low/Checkbox"; interface Props { corporateUsers: User[]; users: User[]; } interface TableData { user: string; correct: number; corporate: string; submitted: boolean; date: moment.Moment; assignment: string; corporateId: string; } interface UserCount { userCount: number; maxUserCount: number; } const MasterStatistical = (props: Props) => { const { users, corporateUsers } = props; const corporateRelevantUsers = React.useMemo( () => corporateUsers.filter((x) => x.type !== "student") as CorporateUser[], [corporateUsers] ); const corporates = React.useMemo( () => corporateRelevantUsers.map((x) => x.id), [corporateRelevantUsers] ); const [selectedCorporates, setSelectedCorporates] = React.useState(corporates); const [startDate, setStartDate] = React.useState( moment("01/01/2023").toDate() ); const [endDate, setEndDate] = React.useState( moment().endOf("year").toDate() ); const { assignments } = useAssignmentsCorporates({ // corporates: [...corporates, "tYU0HTiJdjMsS8SB7XJsUdMMP892"], corporates: selectedCorporates, startDate, endDate, }); const tableResults = React.useMemo( () => assignments.reduce((accmA: TableData[], a: AssignmentWithCorporateId) => { const userResults = a.assignees.map((assignee) => { const userStats = a.results.find((r) => r.user === assignee)?.stats || []; const userName = users.find((u) => u.id === assignee)?.name || ""; const corporate = users.find((u) => u.id === a.assigner)?.name || ""; const commonData = { user: userName, corporateId: a.corporateId, corporate, assignment: a.name, }; if (userStats.length === 0) { return { ...commonData, correct: 0, submitted: false, // date: moment(), }; } return { ...commonData, correct: userStats.reduce((n, e) => n + e.score.correct, 0), submitted: true, date: moment.max(userStats.map((e) => moment(e.date))), }; }) as TableData[]; return [...accmA, ...userResults]; }, []), [assignments, users] ); const getCorporateScores = (corporateId: string): UserCount => { const corporateAssignmentsUsers = assignments .filter((a) => a.corporateId === corporateId) .reduce((acc, a) => acc + a.assignees.length, 0); const corporateResults = tableResults.filter( (r) => r.corporateId === corporateId ).length; return { maxUserCount: corporateAssignmentsUsers, userCount: corporateResults, }; }; const corporateScores = corporates.reduce( (accm, id) => ({ ...accm, [id]: getCorporateScores(id), }), {} ) as Record; const consolidateScore = Object.values(corporateScores).reduce( (acc: UserCount, { userCount, maxUserCount }: UserCount) => ({ userCount: acc.userCount + userCount, maxUserCount: acc.maxUserCount + maxUserCount, }), { userCount: 0, maxUserCount: 0 } ); const getConsolidateScoreStr = (data: UserCount) => `${data.userCount}/${data.maxUserCount}`; const columnHelper = createColumnHelper(); const defaultColumns = [ columnHelper.accessor("user", { header: "User", id: "user", cell: (info) => { return {info.getValue()}; }, }), columnHelper.accessor("corporate", { header: "Corporate", id: "corporate", cell: (info) => { return {info.getValue()}; }, }), columnHelper.accessor("assignment", { header: "Assignment", id: "assignment", cell: (info) => { return {info.getValue()}; }, }), columnHelper.accessor("submitted", { header: "Submitted", id: "submitted", cell: (info) => { return ( {}}> ); }, }), columnHelper.accessor("correct", { header: "Correct", id: "correct", cell: (info) => { return {info.getValue()}; }, }), columnHelper.accessor("date", { header: "Date", id: "date", cell: (info) => { const date = info.getValue(); if (date) { return {date.format("DD/MM/YYYY")}; } return {""}; }, }), ]; const table = useReactTable({ data: tableResults, columns: defaultColumns, getCoreRowModel: getCoreRowModel(), }); const areAllSelected = selectedCorporates.length === corporates.length; const getStudentsConsolidateScore = () => { if (tableResults.length === 0) { return { highest: null, lowest: null }; } // Find the student with the highest and lowest score return tableResults.reduce( (acc, curr) => { if (curr.correct > acc.highest.correct) { acc.highest = curr; } if (curr.correct < acc.lowest.correct) { acc.lowest = curr; } return acc; }, { highest: tableResults[0], lowest: tableResults[0] } ); }; const consolidateResults = getStudentsConsolidateScore(); return ( <>
{ if (areAllSelected) { setSelectedCorporates([]); return; } setSelectedCorporates(corporates); }} isSelected={areAllSelected} /> {corporateRelevantUsers.map((group) => { const isSelected = selectedCorporates.includes(group.id); return ( { if (isSelected) { setSelectedCorporates( selectedCorporates.filter((x) => x !== group.id) ); return; } setSelectedCorporates([...selectedCorporates, group.id]); }} isSelected={isSelected} /> ); })}
{ setStartDate(initialDate ?? moment("01/01/2023").toDate()); if (finalDate) { // basicly selecting a final day works as if I'm selecting the first // minute of that day. this way it covers the whole day setEndDate(moment(finalDate).endOf("day").toDate()); return; } setEndDate(null); }} />
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( ))} ))}
{header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext() )}
{flexRender(cell.column.columnDef.cell, cell.getContext())}
{consolidateResults.highest && ( {}} Icon={BsPersonFill} label={`Highest result: ${consolidateResults.highest.user}`} color="purple" /> )} {consolidateResults.lowest && ( {}} Icon={BsPersonFill} label={`Lowest result: ${consolidateResults.lowest.user}`} color="purple" /> )}
); }; export default MasterStatistical;