Updated the score to be reflective of the ungraded questions
This commit is contained in:
@@ -2,32 +2,32 @@ import Button from "@/components/Low/Button";
|
|||||||
import ProgressBar from "@/components/Low/ProgressBar";
|
import ProgressBar from "@/components/Low/ProgressBar";
|
||||||
import Modal from "@/components/Modal";
|
import Modal from "@/components/Modal";
|
||||||
import useUsers from "@/hooks/useUsers";
|
import useUsers from "@/hooks/useUsers";
|
||||||
import {Module} from "@/interfaces";
|
import { Module } from "@/interfaces";
|
||||||
import {Assignment} from "@/interfaces/results";
|
import { Assignment } from "@/interfaces/results";
|
||||||
import {Group, Stat, User} from "@/interfaces/user";
|
import { Group, Stat, User } from "@/interfaces/user";
|
||||||
import useExamStore from "@/stores/examStore";
|
import useExamStore from "@/stores/examStore";
|
||||||
import {getExamById} from "@/utils/exams";
|
import { getExamById } from "@/utils/exams";
|
||||||
import {sortByModule} from "@/utils/moduleUtils";
|
import { sortByModule } from "@/utils/moduleUtils";
|
||||||
import {calculateBandScore} from "@/utils/score";
|
import { calculateBandScore } from "@/utils/score";
|
||||||
import {convertToUserSolutions} from "@/utils/stats";
|
import { convertToUserSolutions } from "@/utils/stats";
|
||||||
import {getUserName} from "@/utils/users";
|
import { getUserName } from "@/utils/users";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import {capitalize, uniqBy} from "lodash";
|
import { capitalize, uniqBy } from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import {useRouter} from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import {BsBook, BsBuilding, BsChevronLeft, BsClipboard, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
|
import { BsBook, BsBuilding, BsChevronLeft, BsClipboard, BsHeadphones, BsMegaphone, BsPen } from "react-icons/bs";
|
||||||
import {toast} from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import {futureAssignmentFilter} from "@/utils/assignments";
|
import { futureAssignmentFilter } from "@/utils/assignments";
|
||||||
import {withIronSessionSsr} from "iron-session/next";
|
import { withIronSessionSsr } from "iron-session/next";
|
||||||
import {checkAccess, doesEntityAllow} from "@/utils/permissions";
|
import { checkAccess, doesEntityAllow } from "@/utils/permissions";
|
||||||
import {mapBy, redirect, serialize} from "@/utils";
|
import { mapBy, redirect, serialize } from "@/utils";
|
||||||
import {getAssignment} from "@/utils/assignments.be";
|
import { getAssignment } from "@/utils/assignments.be";
|
||||||
import {getEntitiesUsers, getEntityUsers, getUsers} from "@/utils/users.be";
|
import { getEntitiesUsers, getEntityUsers, getUsers } from "@/utils/users.be";
|
||||||
import {getEntitiesWithRoles, getEntityWithRoles} from "@/utils/entities.be";
|
import { getEntitiesWithRoles, getEntityWithRoles } from "@/utils/entities.be";
|
||||||
import {getGroups, getGroupsByEntities, getGroupsByEntity} from "@/utils/groups.be";
|
import { getGroups, getGroupsByEntities, getGroupsByEntity } from "@/utils/groups.be";
|
||||||
import {sessionOptions} from "@/lib/session";
|
import { sessionOptions } from "@/lib/session";
|
||||||
import {EntityWithRoles} from "@/interfaces/entity";
|
import { EntityWithRoles } from "@/interfaces/entity";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import Layout from "@/components/High/Layout";
|
import Layout from "@/components/High/Layout";
|
||||||
import Separator from "@/components/Low/Separator";
|
import Separator from "@/components/Low/Separator";
|
||||||
@@ -35,7 +35,7 @@ import Link from "next/link";
|
|||||||
import { requestUser } from "@/utils/api";
|
import { requestUser } from "@/utils/api";
|
||||||
import { useEntityPermission } from "@/hooks/useEntityPermissions";
|
import { useEntityPermission } from "@/hooks/useEntityPermissions";
|
||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({req, res, params}) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (!user) return redirect("/login")
|
if (!user) return redirect("/login")
|
||||||
|
|
||||||
@@ -44,22 +44,22 @@ export const getServerSideProps = withIronSessionSsr(async ({req, res, params})
|
|||||||
|
|
||||||
res.setHeader("Cache-Control", "public, s-maxage=10, stale-while-revalidate=59");
|
res.setHeader("Cache-Control", "public, s-maxage=10, stale-while-revalidate=59");
|
||||||
|
|
||||||
const {id} = params as {id: string};
|
const { id } = params as { id: string };
|
||||||
|
|
||||||
const assignment = await getAssignment(id);
|
const assignment = await getAssignment(id);
|
||||||
if (!assignment) return redirect("/assignments")
|
if (!assignment) return redirect("/assignments")
|
||||||
|
|
||||||
const entity = await getEntityWithRoles(assignment.entity || "")
|
const entity = await getEntityWithRoles(assignment.entity || "")
|
||||||
if (!entity){
|
if (!entity) {
|
||||||
const users = await getUsers()
|
const users = await getUsers()
|
||||||
return {props: serialize({user, users, assignment})};
|
return { props: serialize({ user, users, assignment }) };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!doesEntityAllow(user, entity, 'view_assignments')) return redirect("/assignments")
|
if (!doesEntityAllow(user, entity, 'view_assignments')) return redirect("/assignments")
|
||||||
|
|
||||||
const users = await (checkAccess(user, ["developer", "admin"]) ? getUsers() : getEntityUsers(entity.id));
|
const users = await (checkAccess(user, ["developer", "admin"]) ? getUsers() : getEntityUsers(entity.id));
|
||||||
|
|
||||||
return {props: serialize({user, users, entity, assignment})};
|
return { props: serialize({ user, users, entity, assignment }) };
|
||||||
}, sessionOptions);
|
}, sessionOptions);
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -69,7 +69,7 @@ interface Props {
|
|||||||
entity?: EntityWithRoles
|
entity?: EntityWithRoles
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AssignmentView({user, users, entity, assignment}: Props) {
|
export default function AssignmentView({ user, users, entity, assignment }: Props) {
|
||||||
const canDeleteAssignment = useEntityPermission(user, entity, 'delete_assignment')
|
const canDeleteAssignment = useEntityPermission(user, entity, 'delete_assignment')
|
||||||
const canStartAssignment = useEntityPermission(user, entity, 'start_assignment')
|
const canStartAssignment = useEntityPermission(user, entity, 'start_assignment')
|
||||||
|
|
||||||
@@ -128,9 +128,9 @@ export default function AssignmentView({user, users, entity, assignment}: Props)
|
|||||||
return resultModuleBandScores.length === 0 ? -1 : resultModuleBandScores.reduce((acc, curr) => acc + curr, 0) / assignment.results.length;
|
return resultModuleBandScores.length === 0 ? -1 : resultModuleBandScores.reduce((acc, curr) => acc + curr, 0) / assignment.results.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
const aggregateScoresByModule = (stats: Stat[]): {module: Module; total: number; missing: number; correct: number}[] => {
|
const aggregateScoresByModule = (stats: Stat[]): { module: Module; total: number; missing: number; correct: number }[] => {
|
||||||
const scores: {
|
const scores: {
|
||||||
[key in Module]: {total: number; missing: number; correct: number};
|
[key in Module]: { total: number; missing: number; correct: number };
|
||||||
} = {
|
} = {
|
||||||
reading: {
|
reading: {
|
||||||
total: 0,
|
total: 0,
|
||||||
@@ -159,7 +159,7 @@ export default function AssignmentView({user, users, entity, assignment}: Props)
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
stats.forEach((x) => {
|
stats.filter(x => !x.isPractice).forEach((x) => {
|
||||||
scores[x.module!] = {
|
scores[x.module!] = {
|
||||||
total: scores[x.module!].total + x.score.total,
|
total: scores[x.module!].total + x.score.total,
|
||||||
correct: scores[x.module!].correct + x.score.correct,
|
correct: scores[x.module!].correct + x.score.correct,
|
||||||
@@ -169,7 +169,7 @@ export default function AssignmentView({user, users, entity, assignment}: Props)
|
|||||||
|
|
||||||
return Object.keys(scores)
|
return Object.keys(scores)
|
||||||
.filter((x) => scores[x as Module].total > 0)
|
.filter((x) => scores[x as Module].total > 0)
|
||||||
.map((x) => ({module: x as Module, ...scores[x as Module]}));
|
.map((x) => ({ module: x as Module, ...scores[x as Module] }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const customContent = (stats: Stat[], user: string, focus: "academic" | "general") => {
|
const customContent = (stats: Stat[], user: string, focus: "academic" | "general") => {
|
||||||
@@ -228,7 +228,7 @@ export default function AssignmentView({user, users, entity, assignment}: Props)
|
|||||||
|
|
||||||
<div className="flex w-full flex-col gap-1">
|
<div className="flex w-full flex-col gap-1">
|
||||||
<div className="-md:mt-2 grid w-full grid-cols-4 place-items-start gap-2">
|
<div className="-md:mt-2 grid w-full grid-cols-4 place-items-start gap-2">
|
||||||
{aggregatedLevels.map(({module, level}) => (
|
{aggregatedLevels.map(({ module, level }) => (
|
||||||
<div
|
<div
|
||||||
key={module}
|
key={module}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
@@ -306,7 +306,7 @@ export default function AssignmentView({user, users, entity, assignment}: Props)
|
|||||||
if (!confirm(`Are you sure you want to remove ${inactiveAssignees.length} assignees?`)) return
|
if (!confirm(`Are you sure you want to remove ${inactiveAssignees.length} assignees?`)) return
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.patch(`/api/assignments/${assignment.id}`, {assignees: activeAssignees})
|
.patch(`/api/assignments/${assignment.id}`, { assignees: activeAssignees })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success(`The assignment "${assignment.name}" has been updated successfully!`);
|
toast.success(`The assignment "${assignment.name}" has been updated successfully!`);
|
||||||
router.replace(router.asPath);
|
router.replace(router.asPath);
|
||||||
@@ -388,7 +388,7 @@ export default function AssignmentView({user, users, entity, assignment}: Props)
|
|||||||
<span className="text-xl font-bold">Average Scores</span>
|
<span className="text-xl font-bold">Average Scores</span>
|
||||||
<div className="-md:mt-2 flex w-full items-center gap-4">
|
<div className="-md:mt-2 flex w-full items-center gap-4">
|
||||||
{assignment &&
|
{assignment &&
|
||||||
uniqBy(assignment.exams, (x) => x.module).map(({module}) => (
|
uniqBy(assignment.exams, (x) => x.module).map(({ module }) => (
|
||||||
<div
|
<div
|
||||||
data-tip={capitalize(module)}
|
data-tip={capitalize(module)}
|
||||||
key={module}
|
key={module}
|
||||||
|
|||||||
@@ -19,15 +19,16 @@ import { uniqBy } from "lodash";
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { getSessionByAssignment, getSessionsByUser } from "@/utils/sessions.be";
|
import { getSessionByAssignment, getSessionsByUser } from "@/utils/sessions.be";
|
||||||
import { Session } from "@/hooks/useSessions";
|
import { Session } from "@/hooks/useSessions";
|
||||||
import moment from "moment";
|
|
||||||
import { activeAssignmentFilter } from "@/utils/assignments";
|
import { activeAssignmentFilter } from "@/utils/assignments";
|
||||||
|
import { checkAccess } from "@/utils/permissions";
|
||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res, query }) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res, query }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
const loginDestination = Buffer.from(req.url || "/").toString("base64")
|
const loginDestination = Buffer.from(req.url || "/").toString("base64")
|
||||||
if (!user) return redirect(`/login?destination=${loginDestination}`)
|
if (!user) return redirect(`/login?destination=${loginDestination}`)
|
||||||
|
|
||||||
if (shouldRedirectHome(user)) return redirect("/")
|
if (shouldRedirectHome(user) || checkAccess(user, ["corporate", "mastercorporate"]))
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
const { assignment: assignmentID, destination } = query as { assignment?: string, destination?: string }
|
const { assignment: assignmentID, destination } = query as { assignment?: string, destination?: string }
|
||||||
const destinationURL = !!destination ? Buffer.from(destination, 'base64').toString() : undefined
|
const destinationURL = !!destination ? Buffer.from(destination, 'base64').toString() : undefined
|
||||||
|
|||||||
Reference in New Issue
Block a user