/* eslint-disable @next/next/no-img-element */ import Head from "next/head"; import { withIronSessionSsr } from "iron-session/next"; import { sessionOptions } from "@/lib/session"; import { Stat, User } from "@/interfaces/user"; import { useEffect, useRef, useState } from "react"; import useStats from "@/hooks/useStats"; import { groupByDate } from "@/utils/stats"; import moment from "moment"; import useUsers from "@/hooks/useUsers"; import useExamStore from "@/stores/examStore"; import { ToastContainer } from "react-toastify"; import { useRouter } from "next/router"; import Layout from "@/components/High/Layout"; import clsx from "clsx"; import Select from "@/components/Low/Select"; import useGroups from "@/hooks/useGroups"; import { shouldRedirectHome } from "@/utils/navigation.disabled"; import useAssignments from "@/hooks/useAssignments"; import { uuidv4 } from "@firebase/util"; import { usePDFDownload } from "@/hooks/usePDFDownload"; import useRecordStore from "@/stores/recordStore"; import useTrainingContentStore from "@/stores/trainingContentStore"; import StatsGridItem from "@/components/StatGridItem"; export const getServerSideProps = withIronSessionSsr(({ req, res }) => { const user = req.session.user; if (!user || !user.isVerified) { return { redirect: { destination: "/login", permanent: false, }, }; } if (shouldRedirectHome(user)) { return { redirect: { destination: "/", permanent: false, }, }; } return { props: { user: req.session.user }, }; }, sessionOptions); const defaultSelectableCorporate = { value: "", label: "All", }; export default function History({ user }: { user: User }) { const [statsUserId, setStatsUserId, training, setTraining] = useRecordStore((state) => [state.selectedUser, state.setSelectedUser, state.training, state.setTraining]); // const [statsUserId, setStatsUserId] = useState(user.id); const [groupedStats, setGroupedStats] = useState<{ [key: string]: Stat[] }>(); const [filter, setFilter] = useState<"months" | "weeks" | "days" | "assignments">(); const { assignments } = useAssignments({}); const { users } = useUsers(); const { stats, isLoading: isStatsLoading } = useStats(statsUserId); const { groups: allGroups } = useGroups(); const groups = allGroups.filter((x) => x.admin === user.id); 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 setInactivity = useExamStore((state) => state.setInactivity); const setTimeSpent = useExamStore((state) => state.setTimeSpent); const renderPdfIcon = usePDFDownload("stats"); const router = useRouter(); useEffect(() => { if (stats && !isStatsLoading) { setGroupedStats( groupByDate( stats.filter((x) => { if ( (x.module === "writing" || x.module === "speaking") && !x.isDisabled && !x.solutions.every((y) => Object.keys(y).includes("evaluation")) ) return false; return true; }), ), ); } }, [stats, isStatsLoading]); // useEffect(() => { // // just set this initially // if (!statsUserId) setStatsUserId(user.id); // }, []); const toggleFilter = (value: "months" | "weeks" | "days" | "assignments") => { setFilter((prev) => (prev === value ? undefined : value)); }; const filterStatsByDate = (stats: { [key: string]: Stat[] }) => { if (filter && filter !== "assignments") { const filterDate = moment() .subtract({ [filter as string]: 1 }) .format("x"); const filteredStats: { [key: string]: Stat[] } = {}; Object.keys(stats).forEach((timestamp) => { if (timestamp >= filterDate) filteredStats[timestamp] = stats[timestamp]; }); return filteredStats; } if (filter && filter === "assignments") { const filteredStats: { [key: string]: Stat[] } = {}; Object.keys(stats).forEach((timestamp) => { if (stats[timestamp].map((s) => s.assignment === undefined).includes(false)) filteredStats[timestamp] = [...stats[timestamp].filter((s) => !!s.assignment)]; }); return filteredStats; } return stats; }; const MAX_TRAINING_EXAMS = 10; const [selectedTrainingExams, setSelectedTrainingExams] = useState([]); const setTrainingStats = useTrainingContentStore((state) => state.setStats); useEffect(() => { const handleRouteChange = (url: string) => { setTraining(false) } router.events.on('routeChangeStart', handleRouteChange) return () => { router.events.off('routeChangeStart', handleRouteChange) } }, [router.events, setTraining]) const handleTrainingContentSubmission = () => { if (groupedStats) { const groupedStatsByDate = filterStatsByDate(groupedStats); const allStats = Object.keys(groupedStatsByDate); const selectedStats = selectedTrainingExams.reduce>((accumulator, moduleAndTimestamp) => { const timestamp = moduleAndTimestamp.split("-")[1]; if (allStats.includes(timestamp) && !accumulator.hasOwnProperty(timestamp)) { accumulator[timestamp] = groupedStatsByDate[timestamp]; } return accumulator; }, {}); setTrainingStats(Object.values(selectedStats).flat()) router.push("/training"); } } const customContent = (timestamp: string) => { if (!groupedStats) return <>; const dateStats = groupedStats[timestamp]; return ( ); }; const selectableCorporates = [ defaultSelectableCorporate, ...users .filter((x) => x.type === "corporate") .map((x) => ({ value: x.id, label: `${x.name} - ${x.email}`, })), ]; const [selectedCorporate, setSelectedCorporate] = useState(defaultSelectableCorporate.value); const getUsersList = (): User[] => { if (selectedCorporate) { // get groups for that corporate const selectedCorporateGroups = allGroups.filter((x) => x.admin === selectedCorporate); // get the teacher ids for that group const selectedCorporateGroupsParticipants = selectedCorporateGroups.flatMap((x) => x.participants); // // search for groups for these teachers // const teacherGroups = allGroups.filter((x) => { // return selectedCorporateGroupsParticipants.includes(x.admin); // }); // const usersList = [ // ...selectedCorporateGroupsParticipants, // ...teacherGroups.flatMap((x) => x.participants), // ]; const userListWithUsers = selectedCorporateGroupsParticipants.map((x) => users.find((y) => y.id === x)) as User[]; return userListWithUsers.filter((x) => x); } return users || []; }; const corporateFilteredUserList = getUsersList(); const getSelectedUser = () => { if (selectedCorporate) { const userInCorporate = corporateFilteredUserList.find((x) => x.id === statsUserId); return userInCorporate || corporateFilteredUserList[0]; } return users.find((x) => x.id === statsUserId) || user; }; const selectedUser = getSelectedUser(); const selectedUserSelectValue = selectedUser ? { value: selectedUser.id, label: `${selectedUser.name} - ${selectedUser.email}`, } : { value: "", label: "", }; return ( <> Record | EnCoach {user && (
{(user.type === "developer" || user.type === "admin") && !training && ( <> groups.flatMap((y) => y.participants).includes(x.id)) .map((x) => ({ value: x.id, label: `${x.name} - ${x.email}`, }))} value={selectedUserSelectValue} onChange={(value) => setStatsUserId(value?.value!)} styles={{ menuPortal: (base) => ({ ...base, zIndex: 9999 }), option: (styles, state) => ({ ...styles, backgroundColor: state.isFocused ? "#D5D9F0" : state.isSelected ? "#7872BF" : "white", color: state.isFocused ? "black" : styles.color, }), }} /> )} {(training && (
Select up to 10 exercises {`(${selectedTrainingExams.length}/${MAX_TRAINING_EXAMS})`}
))}
{groupedStats && Object.keys(groupedStats).length > 0 && !isStatsLoading && (
{Object.keys(filterStatsByDate(groupedStats)) .sort((a, b) => parseInt(b) - parseInt(a)) .map(customContent)}
)} {groupedStats && Object.keys(groupedStats).length === 0 && !isStatsLoading && ( No record to display... )} {isStatsLoading && (
)}
)} ); }