diff --git a/src/pages/dashboard/corporate.tsx b/src/pages/dashboard/corporate.tsx index 544ca49a..4ef1e2ff 100644 --- a/src/pages/dashboard/corporate.tsx +++ b/src/pages/dashboard/corporate.tsx @@ -68,6 +68,7 @@ export default function Dashboard({ user, users, userCounts, entities, assignmen const teachers = useMemo(() => users.filter((u) => u.type === "teacher"), [users]); const allowedEntityStatistics = useAllowedEntities(user, entities, 'view_entity_statistics') + const allowedStudentPerformance = useAllowedEntities(user, entities, 'view_student_performance') const router = useRouter(); @@ -127,12 +128,14 @@ export default function Dashboard({ user, users, userCounts, entities, assignmen color="purple" /> )} - router.push("/users/performance")} - label="Student Performance" - value={userCounts.student} - color="purple" - /> + {allowedStudentPerformance.length > 0 && ( + router.push("/users/performance")} + label="Student Performance" + value={students.length} + color="purple" + /> + )} ( -
- {displayUser.name} -
- {displayUser.name} - {displayUser.email} -
-
- ); + const allowedStudentPerformance = useAllowedEntities(user, entities, 'view_student_performance') return ( <> @@ -131,12 +122,14 @@ export default function Dashboard({ user, users, entities, assignments, stats, g color="purple" /> - router.push("/users/performance")} - label="Student Performance" - value={students.length} - color="purple" - /> + {allowedStudentPerformance.length > 0 && ( + router.push("/users/performance")} + label="Student Performance" + value={students.length} + color="purple" + /> + )} {allowedEntityStatistics.length > 0 && ( router.push("/statistical")} diff --git a/src/pages/dashboard/teacher.tsx b/src/pages/dashboard/teacher.tsx index 14b52e48..5843ac7d 100644 --- a/src/pages/dashboard/teacher.tsx +++ b/src/pages/dashboard/teacher.tsx @@ -60,31 +60,7 @@ export default function Dashboard({ user, users, entities, assignments, stats, g const router = useRouter(); const allowedEntityStatistics = useAllowedEntities(user, entities, 'view_entity_statistics') - - const averageLevelCalculator = (studentStats: Stat[]) => { - const formattedStats = studentStats - .map((s) => ({ - focus: students.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 allowedStudentPerformance = useAllowedEntities(user, entities, 'view_student_performance') return ( <> @@ -121,6 +97,14 @@ export default function Dashboard({ user, users, entities, assignments, stats, g color="purple" /> + {allowedStudentPerformance.length > 0 && ( + router.push("/users/performance")} + label="Student Performance" + value={students.length} + color="purple" + /> + )} {allowedEntityStatistics.length > 0 && ( router.push("/statistical")} diff --git a/src/pages/entities/[id]/roles/[role].tsx b/src/pages/entities/[id]/roles/[role].tsx index 3b0d2f86..ec8f445c 100644 --- a/src/pages/entities/[id]/roles/[role].tsx +++ b/src/pages/entities/[id]/roles/[role].tsx @@ -93,7 +93,8 @@ const ENTITY_MANAGEMENT: PermissionLayout[] = [ { label: "Assign Role to User", key: "assign_to_role" }, { label: "Delete Entity Role", key: "delete_entity_role" }, { label: "Download Statistics Report", key: "download_statistics_report" }, - { label: "Edit Grading System", key: "edit_grading_system" } + { label: "Edit Grading System", key: "edit_grading_system" }, + { label: "View Student Performance", key: "view_student_performance" } ] const ASSIGNMENT_MANAGEMENT: PermissionLayout[] = [ diff --git a/src/pages/users/performance.tsx b/src/pages/users/performance.tsx index 0ccd1773..4653c959 100644 --- a/src/pages/users/performance.tsx +++ b/src/pages/users/performance.tsx @@ -1,17 +1,17 @@ import useFilterRecordsByUser from "@/hooks/useFilterRecordsByUser"; import useGroups from "@/hooks/useGroups"; -import useUsers, {userHashStudent} from "@/hooks/useUsers"; -import {Group, Stat, StudentUser, User} from "@/interfaces/user"; -import {getUserCompanyName} from "@/resources/user"; +import useUsers, { userHashStudent } from "@/hooks/useUsers"; +import { Group, Stat, StudentUser, User } from "@/interfaces/user"; +import { getUserCompanyName } from "@/resources/user"; import clsx from "clsx"; -import {useRouter} from "next/router"; -import {BsArrowLeft, BsArrowRepeat, BsChevronLeft} from "react-icons/bs"; +import { useRouter } from "next/router"; +import { BsArrowLeft, BsArrowRepeat, BsChevronLeft } from "react-icons/bs"; import { mapBy, serialize } from "@/utils"; -import {withIronSessionSsr} from "iron-session/next"; +import { withIronSessionSsr } from "iron-session/next"; import { getEntitiesUsers, getUsers } from "@/utils/users.be"; import { sessionOptions } from "@/lib/session"; -import { checkAccess } from "@/utils/permissions"; -import { getEntities } from "@/utils/entities.be"; +import { checkAccess, findAllowedEntities } from "@/utils/permissions"; +import { getEntities, getEntitiesWithRoles } from "@/utils/entities.be"; import { Entity } from "@/interfaces/entity"; import { getParticipantGroups, getParticipantsGroups } from "@/utils/groups.be"; import StudentPerformanceList from "../(admin)/Lists/StudentPerformanceList"; @@ -21,21 +21,25 @@ import Layout from "@/components/High/Layout"; import { requestUser } from "@/utils/api"; import { redirect } from "@/utils"; -export const getServerSideProps = withIronSessionSsr(async ({req, res, query}) => { +export const getServerSideProps = withIronSessionSsr(async ({ req, res, query }) => { const user = await requestUser(req, res) if (!user) return redirect("/login") const entityIDs = mapBy(user.entities, 'id') - const entities = await getEntities(checkAccess(user, ["admin", 'developer']) ? undefined : entityIDs) + const entities = await getEntitiesWithRoles(checkAccess(user, ["admin", 'developer']) ? undefined : entityIDs) + const allowedEntities = findAllowedEntities(user, entities, "view_student_performance") + + if (allowedEntities.length === 0) return redirect("/") + const students = await (checkAccess(user, ["admin", 'developer']) - ? getUsers({type: 'student'}) - : getEntitiesUsers(entityIDs, {type: 'student'}) + ? getUsers({ type: 'student' }) + : getEntitiesUsers(mapBy(allowedEntities, 'id'), { type: 'student' }) ) const groups = await getParticipantsGroups(mapBy(students, 'id')) return { - props: serialize({user, students, entities, groups}), + props: serialize({ user, students, entities, groups }), }; }, sessionOptions); @@ -46,8 +50,8 @@ interface Props { groups: Group[] } -const StudentPerformance = ({user, students, entities, groups}: Props) => { - const {data: stats} = useFilterRecordsByUser(); +const StudentPerformance = ({ user, students, entities, groups }: Props) => { + const { data: stats } = useFilterRecordsByUser(); const router = useRouter(); @@ -58,7 +62,7 @@ const StudentPerformance = ({user, students, entities, groups}: Props) => { })); return ( - <> + <> EnCoach { - +
-

Student Performance ({ students.length })

+

Student Performance ({students.length})

- +
); diff --git a/src/resources/entityPermissions.ts b/src/resources/entityPermissions.ts index 27b94e7e..ddcfbf5a 100644 --- a/src/resources/entityPermissions.ts +++ b/src/resources/entityPermissions.ts @@ -58,7 +58,8 @@ export type RolePermission = "delete_code" | "view_statistics" | "download_statistics_report" | - "edit_grading_system" + "edit_grading_system" | + "view_student_performance" export const DEFAULT_PERMISSIONS: RolePermission[] = [ "view_students", @@ -130,5 +131,6 @@ export const ADMIN_PERMISSIONS: RolePermission[] = [ "delete_code", "view_statistics", "download_statistics_report", - "edit_grading_system" + "edit_grading_system", + "view_student_performance" ]