diff --git a/src/pages/(admin)/UserCreator.tsx b/src/pages/(admin)/UserCreator.tsx index 7d758a0d..41c23d2c 100644 --- a/src/pages/(admin)/UserCreator.tsx +++ b/src/pages/(admin)/UserCreator.tsx @@ -1,273 +1,272 @@ import Button from "@/components/Low/Button"; import Checkbox from "@/components/Low/Checkbox"; -import { PERMISSIONS } from "@/constants/userPermissions"; -import { CorporateUser, TeacherUser, Type, User } from "@/interfaces/user"; -import { USER_TYPE_LABELS } from "@/resources/user"; +import {PERMISSIONS} from "@/constants/userPermissions"; +import {CorporateUser, TeacherUser, Type, User} from "@/interfaces/user"; +import {USER_TYPE_LABELS} from "@/resources/user"; import axios from "axios"; import clsx from "clsx"; -import { capitalize, uniqBy } from "lodash"; +import {capitalize, uniqBy} from "lodash"; import moment from "moment"; -import { useEffect, useState } from "react"; +import {useEffect, useState} from "react"; import ReactDatePicker from "react-datepicker"; -import { toast } from "react-toastify"; +import {toast} from "react-toastify"; import ShortUniqueId from "short-unique-id"; -import { checkAccess, getTypesOfUser } from "@/utils/permissions"; -import { PermissionType } from "@/interfaces/permissions"; +import {checkAccess, getTypesOfUser} from "@/utils/permissions"; +import {PermissionType} from "@/interfaces/permissions"; import usePermissions from "@/hooks/usePermissions"; import Input from "@/components/Low/Input"; import CountrySelect from "@/components/Low/CountrySelect"; import useGroups from "@/hooks/useGroups"; import useUsers from "@/hooks/useUsers"; -import { getUserName } from "@/utils/users"; +import {getUserName} from "@/utils/users"; import Select from "@/components/Low/Select"; -import { EntityWithRoles } from "@/interfaces/entity"; +import {EntityWithRoles} from "@/interfaces/entity"; import useEntitiesGroups from "@/hooks/useEntitiesGroups"; +import {mapBy} from "@/utils"; const USER_TYPE_PERMISSIONS: { - [key in Type]: { perm: PermissionType | undefined; list: Type[] }; + [key in Type]: {perm: PermissionType | undefined; list: Type[]}; } = { - student: { - perm: "createCodeStudent", - list: [], - }, - teacher: { - perm: "createCodeTeacher", - list: [], - }, - agent: { - perm: "createCodeCountryManager", - list: ["student", "teacher", "corporate", "mastercorporate"], - }, - corporate: { - perm: "createCodeCorporate", - list: ["student", "teacher"], - }, - mastercorporate: { - perm: undefined, - list: ["student", "teacher", "corporate"], - }, - admin: { - perm: "createCodeAdmin", - list: ["student", "teacher", "agent", "corporate", "admin", "mastercorporate"], - }, - developer: { - perm: undefined, - list: ["student", "teacher", "agent", "corporate", "admin", "developer", "mastercorporate"], - }, + student: { + perm: "createCodeStudent", + list: [], + }, + teacher: { + perm: "createCodeTeacher", + list: [], + }, + agent: { + perm: "createCodeCountryManager", + list: ["student", "teacher", "corporate", "mastercorporate"], + }, + corporate: { + perm: "createCodeCorporate", + list: ["student", "teacher"], + }, + mastercorporate: { + perm: undefined, + list: ["student", "teacher", "corporate"], + }, + admin: { + perm: "createCodeAdmin", + list: ["student", "teacher", "agent", "corporate", "admin", "mastercorporate"], + }, + developer: { + perm: undefined, + list: ["student", "teacher", "agent", "corporate", "admin", "developer", "mastercorporate"], + }, }; interface Props { - user: User; - users: User[]; - entities: EntityWithRoles[] - permissions: PermissionType[]; - onFinish: () => void; + user: User; + users: User[]; + entities: EntityWithRoles[]; + permissions: PermissionType[]; + onFinish: () => void; } -export default function UserCreator({ user, users, entities = [], permissions, onFinish }: Props) { - const [name, setName] = useState(); - const [email, setEmail] = useState(); - const [phone, setPhone] = useState(); - const [passportID, setPassportID] = useState(); - const [studentID, setStudentID] = useState(); - const [country, setCountry] = useState(user?.demographicInformation?.country); - const [group, setGroup] = useState(); - const [password, setPassword] = useState(); - const [confirmPassword, setConfirmPassword] = useState(); - const [expiryDate, setExpiryDate] = useState( - user?.subscriptionExpirationDate ? moment(user?.subscriptionExpirationDate).toDate() : null, - ); - const [isExpiryDateEnabled, setIsExpiryDateEnabled] = useState(true); - const [isLoading, setIsLoading] = useState(false); - const [type, setType] = useState("student"); - const [position, setPosition] = useState(); - const [entity, setEntity] = useState((entities || [])[0]?.id || undefined) +export default function UserCreator({user, users, entities = [], permissions, onFinish}: Props) { + const [name, setName] = useState(); + const [email, setEmail] = useState(); + const [phone, setPhone] = useState(); + const [passportID, setPassportID] = useState(); + const [studentID, setStudentID] = useState(); + const [country, setCountry] = useState(user?.demographicInformation?.country); + const [group, setGroup] = useState(); + const [password, setPassword] = useState(); + const [confirmPassword, setConfirmPassword] = useState(); + const [expiryDate, setExpiryDate] = useState( + user?.subscriptionExpirationDate ? moment(user?.subscriptionExpirationDate).toDate() : null, + ); + const [isExpiryDateEnabled, setIsExpiryDateEnabled] = useState(true); + const [isLoading, setIsLoading] = useState(false); + const [type, setType] = useState("student"); + const [position, setPosition] = useState(); + const [entity, setEntity] = useState((entities || [])[0]?.id || undefined); - const { groups } = useEntitiesGroups(); + const {groups} = useEntitiesGroups(); - useEffect(() => { - if (!isExpiryDateEnabled) setExpiryDate(null); - }, [isExpiryDateEnabled]); + useEffect(() => { + if (!isExpiryDateEnabled) setExpiryDate(null); + }, [isExpiryDateEnabled]); - const createUser = () => { - if (!name || name.trim().length === 0) return toast.error("Please enter a valid name!"); - if (!email || email.trim().length === 0) return toast.error("Please enter a valid e-mail address!"); - if (users.map((x) => x.email).includes(email.trim())) return toast.error("That e-mail is already in use!"); - if (!password || password.trim().length < 6) return toast.error("Please enter a valid password!"); - if (password !== confirmPassword) return toast.error("The passwords do not match!"); + const createUser = () => { + if (!name || name.trim().length === 0) return toast.error("Please enter a valid name!"); + if (!email || email.trim().length === 0) return toast.error("Please enter a valid e-mail address!"); + if (users.map((x) => x.email).includes(email.trim())) return toast.error("That e-mail is already in use!"); + if (!password || password.trim().length < 6) return toast.error("Please enter a valid password!"); + if (password !== confirmPassword) return toast.error("The passwords do not match!"); - setIsLoading(true); + setIsLoading(true); - const body = { - name, - email, - password, - groupID: group, - entity, - type, - studentID: type === "student" ? studentID : undefined, - expiryDate, - demographicInformation: { - passport_id: type === "student" ? passportID : undefined, - phone, - country, - position, - }, - }; + const body = { + name, + email, + password, + groupID: group, + entity, + type, + studentID: type === "student" ? studentID : undefined, + expiryDate, + demographicInformation: { + passport_id: type === "student" ? passportID : undefined, + phone, + country, + position, + }, + }; - axios - .post("/api/make_user", body) - .then(() => { - toast.success("That user has been created!"); - onFinish(); + axios + .post("/api/make_user", body) + .then(() => { + toast.success("That user has been created!"); + onFinish(); - setName(""); - setEmail(""); - setPhone(""); - setPassportID(""); - setStudentID(""); - setCountry(user?.demographicInformation?.country); - setGroup(null); - setEntity((entities || [])[0]?.id || undefined) - setExpiryDate(user?.subscriptionExpirationDate ? moment(user?.subscriptionExpirationDate).toDate() : null); - setIsExpiryDateEnabled(true); - setType("student"); - setPosition(undefined); - }) - .catch((error) => { - const data = error?.response?.data; - if (!!data?.message) return toast.error(data.message); - toast.error("Something went wrong! Please try again later!"); - }) - .finally(() => setIsLoading(false)); - }; + setName(""); + setEmail(""); + setPhone(""); + setPassportID(""); + setStudentID(""); + setCountry(user?.demographicInformation?.country); + setGroup(null); + setEntity((entities || [])[0]?.id || undefined); + setExpiryDate(user?.subscriptionExpirationDate ? moment(user?.subscriptionExpirationDate).toDate() : null); + setIsExpiryDateEnabled(true); + setType("student"); + setPosition(undefined); + }) + .catch((error) => { + const data = error?.response?.data; + if (!!data?.message) return toast.error(data.message); + toast.error("Something went wrong! Please try again later!"); + }) + .finally(() => setIsLoading(false)); + }; - return ( -
-
- - + return ( +
+
+ + - - + + -
- - -
+
+ + +
- + - {type === "student" && ( - <> - - - - )} + {type === "student" && ( + <> + + + + )} -
- - ({value: e.id, label: e.label}))} + onChange={(e) => setEntity(e?.value || undefined)} + isClearable={checkAccess(user, ["admin", "developer"])} + /> +
- {["corporate", "mastercorporate"].includes(type) && ( - - )} + {["corporate", "mastercorporate"].includes(type) && ( + + )} -
- - x.entity?.id === entity).map((g) => ({value: g.id, label: g.name}))} + onChange={(e) => setGroup(e?.value || undefined)} + isClearable + /> +
-
- - {user && ( - - )} -
+
+ + {user && ( + + )} +
-
- {user && checkAccess(user, ["developer", "admin", "corporate", "mastercorporate"]) && ( - <> -
- - - Enabled - -
- {isExpiryDateEnabled && ( - - moment(date).isAfter(new Date()) && - (user?.subscriptionExpirationDate ? moment(date).isBefore(user?.subscriptionExpirationDate) : true) - } - dateFormat="dd/MM/yyyy" - selected={expiryDate} - onChange={(date) => setExpiryDate(date)} - /> - )} - - )} -
-
+
+ {user && checkAccess(user, ["developer", "admin", "corporate", "mastercorporate"]) && ( + <> +
+ + + Enabled + +
+ {isExpiryDateEnabled && ( + + moment(date).isAfter(new Date()) && + (user?.subscriptionExpirationDate ? moment(date).isBefore(user?.subscriptionExpirationDate) : true) + } + dateFormat="dd/MM/yyyy" + selected={expiryDate} + onChange={(date) => setExpiryDate(date)} + /> + )} + + )} +
+
- -
- ); + +
+ ); } diff --git a/src/pages/dashboard/mastercorporate.tsx b/src/pages/dashboard/mastercorporate.tsx index 6559cce0..de3232ff 100644 --- a/src/pages/dashboard/mastercorporate.tsx +++ b/src/pages/dashboard/mastercorporate.tsx @@ -1,269 +1,216 @@ /* eslint-disable @next/next/no-img-element */ import UserDisplayList from "@/components/UserDisplayList"; import IconCard from "@/components/IconCard"; -import { useAllowedEntities } from "@/hooks/useEntityPermissions"; -import { EntityWithRoles } from "@/interfaces/entity"; -import { Stat, StudentUser, Type, User } from "@/interfaces/user"; -import { sessionOptions } from "@/lib/session"; -import { filterBy, mapBy, redirect, serialize } from "@/utils"; -import { requestUser } from "@/utils/api"; -import { countEntitiesAssignments } from "@/utils/assignments.be"; -import { getEntitiesWithRoles } from "@/utils/entities.be"; -import { countGroupsByEntities } from "@/utils/groups.be"; -import { - checkAccess, - groupAllowedEntitiesByPermissions, -} from "@/utils/permissions"; -import { groupByExam } from "@/utils/stats"; -import { countAllowedUsers, getUsers } from "@/utils/users.be"; -import { clsx } from "clsx"; -import { withIronSessionSsr } from "iron-session/next"; +import {useAllowedEntities} from "@/hooks/useEntityPermissions"; +import {EntityWithRoles} from "@/interfaces/entity"; +import {Stat, StudentUser, Type, User} from "@/interfaces/user"; +import {sessionOptions} from "@/lib/session"; +import {filterBy, mapBy, redirect, serialize} from "@/utils"; +import {requestUser} from "@/utils/api"; +import {countEntitiesAssignments} from "@/utils/assignments.be"; +import {getEntitiesWithRoles} from "@/utils/entities.be"; +import {countGroupsByEntities} from "@/utils/groups.be"; +import {checkAccess, groupAllowedEntitiesByPermissions} from "@/utils/permissions"; +import {groupByExam} from "@/utils/stats"; +import {countAllowedUsers, getUsers} from "@/utils/users.be"; +import {clsx} from "clsx"; +import {withIronSessionSsr} from "iron-session/next"; import moment from "moment"; import Head from "next/head"; -import { useRouter } from "next/router"; -import { useMemo } from "react"; -import { - BsBank, - BsClock, - BsEnvelopePaper, - BsPencilSquare, - BsPeople, - BsPeopleFill, - BsPersonFill, - BsPersonFillGear, -} from "react-icons/bs"; -import { ToastContainer } from "react-toastify"; -import { isAdmin } from "@/utils/users"; +import {useRouter} from "next/router"; +import {useMemo} from "react"; +import {BsBank, BsClock, BsEnvelopePaper, BsPencilSquare, BsPeople, BsPeopleFill, BsPersonFill, BsPersonFillGear} from "react-icons/bs"; +import {ToastContainer} from "react-toastify"; +import {isAdmin} from "@/utils/users"; interface Props { - user: User; - students: StudentUser[]; - latestStudents: User[]; - latestTeachers: User[]; - userCounts: { [key in Type]: number }; - entities: EntityWithRoles[]; - assignmentsCount: number; - stats: Stat[]; - groupsCount: number; + user: User; + students: StudentUser[]; + latestStudents: User[]; + latestTeachers: User[]; + userCounts: {[key in Type]: number}; + entities: EntityWithRoles[]; + assignmentsCount: number; + stats: Stat[]; + groupsCount: number; } -export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => { - const user = await requestUser(req, res); - if (!user || !user.isVerified) return redirect("/login"); +export const getServerSideProps = withIronSessionSsr(async ({req, res}) => { + const user = await requestUser(req, res); + if (!user || !user.isVerified) return redirect("/login"); - if (!checkAccess(user, ["admin", "developer", "mastercorporate"])) - return redirect("/"); + if (!checkAccess(user, ["admin", "developer", "mastercorporate"])) return redirect("/"); - const entityIDS = mapBy(user.entities, "id") || []; - const entities = await getEntitiesWithRoles( - isAdmin(user) ? undefined : entityIDS - ); - const { - ["view_students"]: allowedStudentEntities, - ["view_teachers"]: allowedTeacherEntities, - } = groupAllowedEntitiesByPermissions(user, entities, [ - "view_students", - "view_teachers", - ]); + const entityIDS = mapBy(user.entities, "id") || []; + const entities = await getEntitiesWithRoles(isAdmin(user) ? undefined : entityIDS); + const {["view_students"]: allowedStudentEntities, ["view_teachers"]: allowedTeacherEntities} = groupAllowedEntitiesByPermissions(user, entities, [ + "view_students", + "view_teachers", + ]); - const allowedStudentEntitiesIDS = mapBy(allowedStudentEntities, "id"); + const allowedStudentEntitiesIDS = mapBy(allowedStudentEntities, "id"); - const entitiesIDS = mapBy(entities, "id") || []; + const entitiesIDS = mapBy(entities, "id") || []; - const [ - students, - latestStudents, - latestTeachers, - userCounts, - assignmentsCount, - groupsCount, - ] = await Promise.all([ - getUsers( - { type: "student", "entities.id": { $in: allowedStudentEntitiesIDS } }, - 10, - { averageLevel: -1 }, - { _id: 0, id: 1, name: 1, email: 1, profilePicture: 1 } - ), - getUsers( - { type: "student", "entities.id": { $in: allowedStudentEntitiesIDS } }, - 10, - { registrationDate: -1 }, - { _id: 0, id: 1, name: 1, email: 1, profilePicture: 1 } - ), - getUsers( - { - type: "teacher", - "entities.id": { $in: mapBy(allowedTeacherEntities, "id") }, - }, - 10, - { registrationDate: -1 }, - { _id: 0, id: 1, name: 1, email: 1, profilePicture: 1 } - ), - countAllowedUsers(user, entities), - countEntitiesAssignments(entitiesIDS, { archived: { $ne: true } }), - countGroupsByEntities(entitiesIDS), - ]); + const [students, latestStudents, latestTeachers, userCounts, assignmentsCount, groupsCount] = await Promise.all([ + getUsers( + {type: "student", "entities.id": {$in: allowedStudentEntitiesIDS}}, + 10, + {averageLevel: -1}, + {_id: 0, id: 1, name: 1, email: 1, profilePicture: 1}, + ), + getUsers( + {type: "student", "entities.id": {$in: allowedStudentEntitiesIDS}}, + 10, + {registrationDate: -1}, + {_id: 0, id: 1, name: 1, email: 1, profilePicture: 1}, + ), + getUsers( + { + type: "teacher", + "entities.id": {$in: mapBy(allowedTeacherEntities, "id")}, + }, + 10, + {registrationDate: -1}, + {_id: 0, id: 1, name: 1, email: 1, profilePicture: 1}, + ), + countAllowedUsers(user, entities), + countEntitiesAssignments(entitiesIDS, {archived: {$ne: true}}), + countGroupsByEntities(entitiesIDS), + ]); - return { - props: serialize({ - user, - students, - latestStudents, - latestTeachers, - userCounts, - entities, - assignmentsCount, - groupsCount, - }), - }; + return { + props: serialize({ + user, + students, + latestStudents, + latestTeachers, + userCounts, + entities, + assignmentsCount, + groupsCount, + }), + }; }, sessionOptions); export default function Dashboard({ - user, - students, - latestStudents, - latestTeachers, - userCounts, - entities, - assignmentsCount, - stats = [], - groupsCount, + user, + students, + latestStudents, + latestTeachers, + userCounts, + entities, + assignmentsCount, + stats = [], + groupsCount, }: Props) { - - const totalCount = useMemo( - () => - userCounts.corporate + - userCounts.mastercorporate + - userCounts.student + - userCounts.teacher, - [userCounts] - ); + const totalCount = useMemo(() => userCounts.corporate + userCounts.mastercorporate + userCounts.student + userCounts.teacher, [userCounts]); - const totalLicenses = useMemo( - () => - entities.reduce( - (acc, curr) => acc + parseInt(curr.licenses.toString()), - 0 - ), - [entities] - ); + const totalLicenses = useMemo(() => entities.reduce((acc, curr) => acc + parseInt(curr.licenses.toString()), 0), [entities]); - const router = useRouter(); + const router = useRouter(); - const allowedEntityStatistics = useAllowedEntities( - user, - entities, - "view_entity_statistics" - ); - const allowedStudentPerformance = useAllowedEntities( - user, - entities, - "view_student_performance" - ); + const allowedEntityStatistics = useAllowedEntities(user, entities, "view_entity_statistics"); + const allowedStudentPerformance = useAllowedEntities(user, entities, "view_student_performance"); - return ( - <> - - EnCoach - - - - - - <> -
- router.push("/users?type=student")} - Icon={BsPersonFill} - label="Students" - value={userCounts.student} - color="purple" - /> - router.push("/users?type=teacher")} - Icon={BsPencilSquare} - label="Teachers" - value={userCounts.teacher} - color="purple" - /> - router.push("/users?type=corporate")} - Icon={BsBank} - label="Corporate Accounts" - value={userCounts.corporate} - color="purple" - /> - router.push("/classrooms")} - label="Classrooms" - value={groupsCount} - color="purple" - /> - router.push("/entities")} - label="Entities" - value={`${entities.length} - ${totalCount}/${totalLicenses}`} - color="purple" - /> - {allowedStudentPerformance.length > 0 && ( - router.push("/users/performance")} - label="Student Performance" - value={userCounts.student} - color="purple" - /> - )} - {allowedEntityStatistics.length > 0 && ( - router.push("/statistical")} - label="Entity Statistics" - value={allowedEntityStatistics.length} - color="purple" - /> - )} - router.push("/assignments")} - label="Assignments" - value={assignmentsCount} - className={clsx( - allowedEntityStatistics.length === 0 && "col-span-2" - )} - color="purple" - /> - -
+ return ( + <> + + EnCoach + + + + + + <> +
+ router.push("/users?type=student")} + Icon={BsPersonFill} + label="Students" + value={userCounts.student} + color="purple" + /> + router.push("/users?type=teacher")} + Icon={BsPencilSquare} + label="Teachers" + value={userCounts.teacher} + color="purple" + /> + router.push("/users?type=corporate")} + Icon={BsBank} + label="Corporate Accounts" + value={userCounts.corporate} + color="purple" + /> + router.push("/users?type=mastercorporate")} + label="Master Corporates" + value={userCounts.mastercorporate} + color="purple" + /> + router.push("/classrooms")} label="Classrooms" value={groupsCount} color="purple" /> + router.push("/entities")} + label="Entities" + value={`${entities.length} - ${totalCount}/${totalLicenses}`} + color="purple" + /> + {allowedStudentPerformance.length > 0 && ( + router.push("/users/performance")} + label="Student Performance" + value={userCounts.student} + color="purple" + /> + )} + {allowedEntityStatistics.length > 0 && ( + router.push("/statistical")} + label="Entity Statistics" + value={allowedEntityStatistics.length} + color="purple" + /> + )} + router.push("/assignments")} + label="Assignments" + value={assignmentsCount} + className={clsx(allowedEntityStatistics.length === 0 && "col-span-2")} + color="purple" + /> + +
-
- - - - - Object.keys(groupByExam(filterBy(stats, "user", b))).length - - Object.keys(groupByExam(filterBy(stats, "user", a))).length - )} - title="Highest exam count students" - /> -
- - - ); +
+ + + + + Object.keys(groupByExam(filterBy(stats, "user", b))).length - + Object.keys(groupByExam(filterBy(stats, "user", a))).length, + )} + title="Highest exam count students" + /> +
+ + + ); } diff --git a/src/pages/settings.tsx b/src/pages/settings.tsx index 8f98d394..64194125 100644 --- a/src/pages/settings.tsx +++ b/src/pages/settings.tsx @@ -1,268 +1,201 @@ /* eslint-disable @next/next/no-img-element */ import Head from "next/head"; -import { withIronSessionSsr } from "iron-session/next"; -import { sessionOptions } from "@/lib/session"; -import { ToastContainer } from "react-toastify"; +import {withIronSessionSsr} from "iron-session/next"; +import {sessionOptions} from "@/lib/session"; +import {ToastContainer} from "react-toastify"; import CodeGenerator from "./(admin)/CodeGenerator"; import ExamLoader from "./(admin)/ExamLoader"; import Lists from "./(admin)/Lists"; import BatchCodeGenerator from "./(admin)/BatchCodeGenerator"; -import { shouldRedirectHome } from "@/utils/navigation.disabled"; +import {shouldRedirectHome} from "@/utils/navigation.disabled"; import BatchCreateUser from "./(admin)/Lists/BatchCreateUser"; -import { checkAccess, getTypesOfUser } from "@/utils/permissions"; -import { useState } from "react"; +import {checkAccess, getTypesOfUser} from "@/utils/permissions"; +import {useEffect, useState} from "react"; import Modal from "@/components/Modal"; import IconCard from "@/components/IconCard"; -import { - BsCode, - BsCodeSquare, - BsGearFill, - BsPeopleFill, - BsPersonFill, -} from "react-icons/bs"; +import {BsCode, BsCodeSquare, BsGearFill, BsPeopleFill, BsPersonFill} from "react-icons/bs"; import UserCreator from "./(admin)/UserCreator"; import CorporateGradingSystem from "./(admin)/CorporateGradingSystem"; -import { CEFR_STEPS } from "@/resources/grading"; -import { User } from "@/interfaces/user"; -import { getUserPermissions } from "@/utils/permissions.be"; -import { PermissionType } from "@/interfaces/permissions"; -import { getUsers } from "@/utils/users.be"; -import { getEntitiesWithRoles } from "@/utils/entities.be"; -import { mapBy, serialize, redirect } from "@/utils"; -import { EntityWithRoles } from "@/interfaces/entity"; -import { requestUser } from "@/utils/api"; -import { isAdmin } from "@/utils/users"; -import { - getGradingSystemByEntities, - getGradingSystemByEntity, -} from "@/utils/grading.be"; -import { Grading } from "@/interfaces"; -import { useRouter } from "next/router"; -import { useAllowedEntities } from "@/hooks/useEntityPermissions"; +import {CEFR_STEPS} from "@/resources/grading"; +import {User} from "@/interfaces/user"; +import {getUserPermissions} from "@/utils/permissions.be"; +import {PermissionType} from "@/interfaces/permissions"; +import {getUsers} from "@/utils/users.be"; +import {getEntitiesWithRoles} from "@/utils/entities.be"; +import {mapBy, serialize, redirect, filterBy} from "@/utils"; +import {EntityWithRoles} from "@/interfaces/entity"; +import {requestUser} from "@/utils/api"; +import {isAdmin} from "@/utils/users"; +import {getGradingSystemByEntities, getGradingSystemByEntity} from "@/utils/grading.be"; +import {Grading} from "@/interfaces"; +import {useRouter} from "next/router"; +import {useAllowedEntities} from "@/hooks/useEntityPermissions"; -export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => { - const user = await requestUser(req, res); - if (!user) return redirect("/login"); +export const getServerSideProps = withIronSessionSsr(async ({req, res}) => { + const user = await requestUser(req, res); + if (!user) return redirect("/login"); - if ( - shouldRedirectHome(user) || - !checkAccess(user, [ - "admin", - "developer", - "corporate", - "teacher", - "mastercorporate", - ]) - ) - return redirect("/"); - const [permissions, entities, allUsers] = await Promise.all([ - getUserPermissions(user.id), - isAdmin(user) - ? await getEntitiesWithRoles() - : await getEntitiesWithRoles(mapBy(user.entities, "id")), - getUsers(), - ]); - const gradingSystems = await getGradingSystemByEntities( - mapBy(entities, "id") - ); - const entitiesGrading = entities.map( - (e) => - gradingSystems.find((g) => g.entity === e.id) || { - entity: e.id, - steps: CEFR_STEPS, - } - ); + if (shouldRedirectHome(user) || !checkAccess(user, ["admin", "developer", "corporate", "teacher", "mastercorporate"])) return redirect("/"); + const [permissions, entities, allUsers] = await Promise.all([ + getUserPermissions(user.id), + isAdmin(user) ? await getEntitiesWithRoles() : await getEntitiesWithRoles(mapBy(user.entities, "id")), + getUsers(), + ]); + const gradingSystems = await getGradingSystemByEntities(mapBy(entities, "id")); + const entitiesGrading = entities.map( + (e) => + gradingSystems.find((g) => g.entity === e.id) || { + entity: e.id, + steps: CEFR_STEPS, + }, + ); - return { - props: serialize({ - user, - permissions, - entities, - allUsers, - entitiesGrading, - }), - }; + return { + props: serialize({ + user, + permissions, + entities, + allUsers, + entitiesGrading, + }), + }; }, sessionOptions); interface Props { - user: User; - permissions: PermissionType[]; - entities: EntityWithRoles[]; - allUsers: User[]; - entitiesGrading: Grading[]; + user: User; + permissions: PermissionType[]; + entities: EntityWithRoles[]; + allUsers: User[]; + entitiesGrading: Grading[]; } -export default function Admin({ - user, - entities, - permissions, - allUsers, - entitiesGrading, -}: Props) { - const [modalOpen, setModalOpen] = useState(); - const router = useRouter(); +export default function Admin({user, entities, permissions, allUsers, entitiesGrading}: Props) { + const [modalOpen, setModalOpen] = useState(); + const router = useRouter(); - const entitiesAllowCreateUser = useAllowedEntities( - user, - entities, - "create_user" - ); - const entitiesAllowCreateUsers = useAllowedEntities( - user, - entities, - "create_user_batch" - ); - const entitiesAllowCreateCode = useAllowedEntities( - user, - entities, - "create_code" - ); - const entitiesAllowCreateCodes = useAllowedEntities( - user, - entities, - "create_code_batch" - ); - const entitiesAllowEditGrading = useAllowedEntities( - user, - entities, - "edit_grading_system" - ); + const entitiesAllowCreateUser = useAllowedEntities(user, entities, "create_user"); + const entitiesAllowCreateUsers = useAllowedEntities(user, entities, "create_user_batch"); + const entitiesAllowCreateCode = useAllowedEntities(user, entities, "create_code"); + const entitiesAllowCreateCodes = useAllowedEntities(user, entities, "create_code_batch"); + const entitiesAllowEditGrading = useAllowedEntities(user, entities, "edit_grading_system"); - return ( - <> - - Settings Panel | EnCoach - - - - - - <> - setModalOpen(undefined)} - maxWidth="max-w-[85%]" - > - setModalOpen(undefined)} - /> - - setModalOpen(undefined)} - > - setModalOpen(undefined)} - /> - - setModalOpen(undefined)} - > - setModalOpen(undefined)} - /> - - setModalOpen(undefined)} - > - setModalOpen(undefined)} - /> - - setModalOpen(undefined)} - > - router.replace(router.asPath)} - /> - + return ( + <> + + Settings Panel | EnCoach + + + + + + <> + setModalOpen(undefined)} maxWidth="max-w-[85%]"> + + e.licenses > 0 && + e.licenses > allUsers.filter((u) => !isAdmin(u) && (u.entities || []).some((ent) => ent.id === e.id)).length, + )} + permissions={permissions} + onFinish={() => setModalOpen(undefined)} + /> + + setModalOpen(undefined)}> + setModalOpen(undefined)} + /> + + setModalOpen(undefined)}> + setModalOpen(undefined)} + /> + + setModalOpen(undefined)}> + + e.licenses > 0 && + e.licenses > allUsers.filter((u) => !isAdmin(u) && (u.entities || []).some((ent) => ent.id === e.id)).length, + )} + users={allUsers} + permissions={permissions} + onFinish={() => setModalOpen(undefined)} + /> + + setModalOpen(undefined)}> + router.replace(router.asPath)} + /> + -
- - {checkAccess( - user, - getTypesOfUser(["teacher"]), - permissions, - "viewCodes" - ) && ( -
- setModalOpen("createCode")} - disabled={entitiesAllowCreateCode.length === 0} - /> - setModalOpen("batchCreateCode")} - disabled={entitiesAllowCreateCodes.length === 0} - /> - setModalOpen("createUser")} - disabled={entitiesAllowCreateUser.length === 0} - /> - setModalOpen("batchCreateUser")} - disabled={entitiesAllowCreateUsers.length === 0} - /> - {checkAccess(user, [ - "admin", - "corporate", - "developer", - "mastercorporate", - ]) && ( - setModalOpen("gradingSystem")} - disabled={entitiesAllowEditGrading.length === 0} - /> - )} -
- )} -
-
- -
- - - ); +
+ + {checkAccess(user, getTypesOfUser(["teacher"]), permissions, "viewCodes") && ( +
+ setModalOpen("createCode")} + disabled={entitiesAllowCreateCode.length === 0} + /> + setModalOpen("batchCreateCode")} + disabled={entitiesAllowCreateCodes.length === 0} + /> + setModalOpen("createUser")} + disabled={entitiesAllowCreateUser.length === 0} + /> + setModalOpen("batchCreateUser")} + disabled={entitiesAllowCreateUsers.length === 0} + /> + {checkAccess(user, ["admin", "corporate", "developer", "mastercorporate"]) && ( + setModalOpen("gradingSystem")} + disabled={entitiesAllowEditGrading.length === 0} + /> + )} +
+ )} +
+
+ +
+ + + ); }