/* 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 { ToastContainer } from "react-toastify"; import Layout from "@/components/High/Layout"; import { shouldRedirectHome } from "@/utils/navigation.disabled"; import { use, useEffect, useState } from "react"; import clsx from "clsx"; import { FaPlus } from "react-icons/fa"; import useRecordStore from "@/stores/recordStore"; import router from "next/router"; import useTrainingContentStore from "@/stores/trainingContentStore"; import axios from "axios"; import Select from "@/components/Low/Select"; import useUsers from "@/hooks/useUsers"; import useGroups from "@/hooks/useGroups"; import { ITrainingContent } from "@/training/TrainingInterfaces"; import moment from "moment"; import { uuidv4 } from "@firebase/util"; import TrainingScore from "@/training/TrainingScore"; import ModuleBadge from "@/components/ModuleBadge"; 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", }; const Training: React.FC<{ user: User }> = ({ user }) => { // Record stuff const { users } = useUsers(); const [selectedCorporate, setSelectedCorporate] = useState(defaultSelectableCorporate.value); const [statsUserId, setStatsUserId, setRecordTraining] = useRecordStore((state) => [state.selectedUser, state.setSelectedUser, state.setTraining]); const { groups: allGroups } = useGroups(); const groups = allGroups.filter((x) => x.admin === user.id); const [filter, setFilter] = useState<"months" | "weeks" | "days">(); const toggleFilter = (value: "months" | "weeks" | "days") => { setFilter((prev) => (prev === value ? undefined : value)); }; const [stats, setTrainingStats] = useTrainingContentStore((state) => [state.stats, state.setStats]); const [trainingContent, setTrainingContent] = useState([]); const [isNewContentLoading, setIsNewContentLoading] = useState(stats.length != 0); const [isLoading, setIsLoading] = useState(true); const [groupedByTrainingContent, setGroupedByTrainingContent] = useState<{ [key: string]: ITrainingContent }>(); useEffect(() => { const handleRouteChange = (url: string) => { setTrainingStats([]) } router.events.on('routeChangeStart', handleRouteChange) return () => { router.events.off('routeChangeStart', handleRouteChange) } }, [router.events, setTrainingStats]) useEffect(() => { const postStats = async () => { try { const response = await axios.post<{id: string}>(`/api/training`, stats); return response.data.id; } catch (error) { setIsNewContentLoading(false); } }; if (isNewContentLoading) { postStats().then( id => { setTrainingStats([]); if (id) { router.push(`/training/${id}`) } }); } }, [isNewContentLoading]) useEffect(() => { const loadTrainingContent = async () => { try { const response = await axios.get('/api/training'); setTrainingContent(response.data); setIsLoading(false); } catch (error) { setTrainingContent([]); setIsLoading(false); } }; loadTrainingContent(); }, []); const handleNewTrainingContent = () => { setRecordTraining(true); router.push('/record') } const filterTrainingContentByDate = (trainingContent: { [key: string]: ITrainingContent }) => { if (filter) { const filterDate = moment() .subtract({ [filter as string]: 1 }) .format("x"); const filteredTrainingContent: { [key: string]: ITrainingContent } = {}; Object.keys(trainingContent).forEach((timestamp) => { if (timestamp >= filterDate) filteredTrainingContent[timestamp] = trainingContent[timestamp]; }); return filteredTrainingContent; } return trainingContent; }; useEffect(() => { if (trainingContent.length > 0) { const grouped = trainingContent.reduce((acc, content) => { acc[content.created_at] = content; return acc; }, {} as { [key: number]: ITrainingContent }); setGroupedByTrainingContent(grouped); } }, [trainingContent]) // Record Stuff const selectableCorporates = [ defaultSelectableCorporate, ...users .filter((x) => x.type === "corporate") .map((x) => ({ value: x.id, label: `${x.name} - ${x.email}`, })), ]; 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: "", }; const formatTimestamp = (timestamp: string) => { const date = moment(parseInt(timestamp)); const formatter = "YYYY/MM/DD - HH:mm"; return date.format(formatter); }; const selectTrainingContent = (trainingContent: ITrainingContent) => { router.push(`/training/${trainingContent.id}`) }; const trainingContentContainer = (timestamp: string) => { if (!groupedByTrainingContent) return <>; const trainingContent: ITrainingContent = groupedByTrainingContent[timestamp]; return ( <>
selectTrainingContent(trainingContent)} role="button">
{formatTimestamp(timestamp)}
{Object.values(groupedByTrainingContent || {}).flatMap((content) => content.exams.map(({ module, id }) => ( )) )}
); }; return ( <> Training | EnCoach {(isNewContentLoading || isLoading ? (
{ isNewContentLoading && ( Assessing your exams, please be patient... )}
) : ( <>
{(user.type === "developer" || user.type === "admin") && ( <> 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, }), }} /> )} {(user.type === "student" && ( <>
Generate New Training Material
))}
{trainingContent.length == 0 && (
No training content to display...
)} {groupedByTrainingContent && Object.keys(groupedByTrainingContent).length > 0 && (
{Object.keys(filterTrainingContentByDate(groupedByTrainingContent)) .sort((a, b) => parseInt(b) - parseInt(a)) .map(trainingContentContainer)}
)} ))}
); } export default Training;