ENCOA-279
This commit is contained in:
@@ -1,15 +1,15 @@
|
|||||||
/* eslint-disable @next/next/no-img-element */
|
/* eslint-disable @next/next/no-img-element */
|
||||||
import {toast, ToastContainer} from "react-toastify";
|
import { toast, ToastContainer } from "react-toastify";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {FormEvent, useEffect, useState} from "react";
|
import { FormEvent, useEffect, useState } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import useUser from "@/hooks/useUser";
|
import useUser from "@/hooks/useUser";
|
||||||
import {Divider} from "primereact/divider";
|
import { Divider } from "primereact/divider";
|
||||||
import Button from "@/components/Low/Button";
|
import Button from "@/components/Low/Button";
|
||||||
import {BsArrowRepeat} from "react-icons/bs";
|
import { BsArrowRepeat } from "react-icons/bs";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Input from "@/components/Low/Input";
|
import Input from "@/components/Low/Input";
|
||||||
import {useRouter} from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
export function getServerSideProps({
|
export function getServerSideProps({
|
||||||
query,
|
query,
|
||||||
@@ -35,12 +35,12 @@ export function getServerSideProps({
|
|||||||
props: {
|
props: {
|
||||||
code: query.oobCode,
|
code: query.oobCode,
|
||||||
mode: query.mode,
|
mode: query.mode,
|
||||||
...(query.continueUrl ? {continueUrl: query.continueUrl} : {}),
|
...(query.continueUrl ? { continueUrl: query.continueUrl } : {}),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Reset({code, mode, continueUrl}: {code: string; mode: string; continueUrl?: string}) {
|
export default function Reset({ code, mode, continueUrl }: { code: string; mode: string; continueUrl?: string }) {
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ export default function Reset({code, mode, continueUrl}: {code: string; mode: st
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mode === "signIn") {
|
if (mode === "signIn") {
|
||||||
axios
|
axios
|
||||||
.post<{ok: boolean}>("/api/reset/verify", {
|
.post<{ ok: boolean }>("/api/reset/verify", {
|
||||||
email: continueUrl?.replace("https://platform.encoach.com/", "").replace("https://staging.encoach.com/", ""),
|
email: continueUrl?.replace("https://platform.encoach.com/", "").replace("https://staging.encoach.com/", ""),
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
@@ -64,7 +64,7 @@ export default function Reset({code, mode, continueUrl}: {code: string; mode: st
|
|||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
router.push("/");
|
router.push("/");
|
||||||
}, 1000);
|
}, 500);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ export default function Reset({code, mode, continueUrl}: {code: string; mode: st
|
|||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
axios
|
axios
|
||||||
.post<{ok: boolean}>("/api/reset/confirm", {code, password})
|
.post<{ ok: boolean }>("/api/reset/confirm", { code, password })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.data.ok) {
|
if (response.data.ok) {
|
||||||
toast.success("Your password has been reset!", {
|
toast.success("Your password has been reset!", {
|
||||||
@@ -98,10 +98,10 @@ export default function Reset({code, mode, continueUrl}: {code: string; mode: st
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
toast.error("Something went wrong! Please make sure to click the link in your e-mail again!", {toastId: "reset-error"});
|
toast.error("Something went wrong! Please make sure to click the link in your e-mail again!", { toastId: "reset-error" });
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Something went wrong! Please make sure to click the link in your e-mail again!", {toastId: "reset-error"});
|
toast.error("Something went wrong! Please make sure to click the link in your e-mail again!", { toastId: "reset-error" });
|
||||||
})
|
})
|
||||||
.finally(() => setIsLoading(false));
|
.finally(() => setIsLoading(false));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -73,9 +73,8 @@ async function registerIndividual(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
...(passport_id ? { demographicInformation: { passport_id } } : {}),
|
...(passport_id ? { demographicInformation: { passport_id } } : {}),
|
||||||
registrationDate: new Date().toISOString(),
|
registrationDate: new Date().toISOString(),
|
||||||
status: code ? "active" : "paymentDue",
|
status: code ? "active" : "paymentDue",
|
||||||
// apparently there's an issue with the verification email system
|
entities: [],
|
||||||
// therefore we will skip this requirement for now
|
isVerified: !!codeDoc,
|
||||||
isVerified: true,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
await db.collection("users").insertOne(user);
|
await db.collection("users").insertOne(user);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ interface Props {
|
|||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (!user) return redirect("/login")
|
if (!user || !user.isVerified) return redirect("/login")
|
||||||
|
|
||||||
if (!checkAccess(user, ["admin", "developer"])) return redirect("/")
|
if (!checkAccess(user, ["admin", "developer"])) return redirect("/")
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ interface Props {
|
|||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (!user) return redirect("/login")
|
if (!user || !user.isVerified) return redirect("/login")
|
||||||
|
|
||||||
if (!checkAccess(user, ["admin", "developer", "corporate"])) return redirect("/")
|
if (!checkAccess(user, ["admin", "developer", "corporate"])) return redirect("/")
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ interface Props {
|
|||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (!user) return redirect("/login")
|
if (!user || !user.isVerified) return redirect("/login")
|
||||||
|
|
||||||
if (!checkAccess(user, ["admin", "developer"])) return redirect("/")
|
if (!checkAccess(user, ["admin", "developer"])) return redirect("/")
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {User} from "@/interfaces/user";
|
import { User } from "@/interfaces/user";
|
||||||
import {sessionOptions} from "@/lib/session";
|
import { sessionOptions } from "@/lib/session";
|
||||||
import { redirect } from "@/utils";
|
import { redirect } from "@/utils";
|
||||||
import { requestUser } from "@/utils/api";
|
import { requestUser } from "@/utils/api";
|
||||||
import {withIronSessionSsr} from "iron-session/next";
|
import { withIronSessionSsr } from "iron-session/next";
|
||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({req, res}) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (!user) return redirect("/login")
|
if (!user || !user.isVerified) return redirect("/login")
|
||||||
|
|
||||||
return redirect(`/dashboard/${user.type}`)
|
return redirect(`/dashboard/${user.type}`)
|
||||||
}, sessionOptions);
|
}, sessionOptions);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ interface Props {
|
|||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (!user) return redirect("/login")
|
if (!user || !user.isVerified) return redirect("/login")
|
||||||
|
|
||||||
if (!checkAccess(user, ["admin", "developer", "mastercorporate"]))
|
if (!checkAccess(user, ["admin", "developer", "mastercorporate"]))
|
||||||
return redirect("/")
|
return redirect("/")
|
||||||
|
|||||||
@@ -5,38 +5,38 @@ import ProgressBar from "@/components/Low/ProgressBar";
|
|||||||
import InviteWithUserCard from "@/components/Medium/InviteWithUserCard";
|
import InviteWithUserCard from "@/components/Medium/InviteWithUserCard";
|
||||||
import ModuleBadge from "@/components/ModuleBadge";
|
import ModuleBadge from "@/components/ModuleBadge";
|
||||||
import ProfileSummary from "@/components/ProfileSummary";
|
import ProfileSummary from "@/components/ProfileSummary";
|
||||||
import {Session} from "@/hooks/useSessions";
|
import { Session } from "@/hooks/useSessions";
|
||||||
import {Grading} from "@/interfaces";
|
import { Grading } from "@/interfaces";
|
||||||
import {EntityWithRoles} from "@/interfaces/entity";
|
import { EntityWithRoles } from "@/interfaces/entity";
|
||||||
import {Exam} from "@/interfaces/exam";
|
import { Exam } from "@/interfaces/exam";
|
||||||
import { InviteWithEntity } from "@/interfaces/invite";
|
import { InviteWithEntity } from "@/interfaces/invite";
|
||||||
import {Assignment} from "@/interfaces/results";
|
import { Assignment } from "@/interfaces/results";
|
||||||
import {Stat, User} from "@/interfaces/user";
|
import { Stat, User } from "@/interfaces/user";
|
||||||
import {sessionOptions} from "@/lib/session";
|
import { sessionOptions } from "@/lib/session";
|
||||||
import useExamStore from "@/stores/exam";
|
import useExamStore from "@/stores/exam";
|
||||||
import {findBy, mapBy, redirect, serialize} from "@/utils";
|
import { findBy, mapBy, redirect, serialize } from "@/utils";
|
||||||
import { requestUser } from "@/utils/api";
|
import { requestUser } from "@/utils/api";
|
||||||
import {activeAssignmentFilter} from "@/utils/assignments";
|
import { activeAssignmentFilter } from "@/utils/assignments";
|
||||||
import {getAssignmentsByAssignee} from "@/utils/assignments.be";
|
import { getAssignmentsByAssignee } from "@/utils/assignments.be";
|
||||||
import {getEntitiesWithRoles, getEntityWithRoles} from "@/utils/entities.be";
|
import { getEntitiesWithRoles, getEntityWithRoles } from "@/utils/entities.be";
|
||||||
import {getExamsByIds} from "@/utils/exams.be";
|
import { getExamsByIds } from "@/utils/exams.be";
|
||||||
import {getGradingSystemByEntity} from "@/utils/grading.be";
|
import { getGradingSystemByEntity } from "@/utils/grading.be";
|
||||||
import {convertInvitersToEntity, getInvitesByInvitee} from "@/utils/invites.be";
|
import { convertInvitersToEntity, getInvitesByInvitee } from "@/utils/invites.be";
|
||||||
import {countExamModules, countFullExams, MODULE_ARRAY, sortByModule, sortByModuleName} from "@/utils/moduleUtils";
|
import { countExamModules, countFullExams, MODULE_ARRAY, sortByModule, sortByModuleName } from "@/utils/moduleUtils";
|
||||||
import {checkAccess} from "@/utils/permissions";
|
import { checkAccess } from "@/utils/permissions";
|
||||||
import {getGradingLabel} from "@/utils/score";
|
import { getGradingLabel } from "@/utils/score";
|
||||||
import {getSessionsByUser} from "@/utils/sessions.be";
|
import { getSessionsByUser } from "@/utils/sessions.be";
|
||||||
import {averageScore} from "@/utils/stats";
|
import { averageScore } from "@/utils/stats";
|
||||||
import {getStatsByUser} from "@/utils/stats.be";
|
import { getStatsByUser } from "@/utils/stats.be";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import {withIronSessionSsr} from "iron-session/next";
|
import { withIronSessionSsr } from "iron-session/next";
|
||||||
import {capitalize, uniqBy} from "lodash";
|
import { capitalize, uniqBy } from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import {useRouter} from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import {BsBook, BsClipboard, BsFileEarmarkText, BsHeadphones, BsMegaphone, BsPen, BsPencil, BsStar} from "react-icons/bs";
|
import { BsBook, BsClipboard, BsFileEarmarkText, BsHeadphones, BsMegaphone, BsPen, BsPencil, BsStar } from "react-icons/bs";
|
||||||
import {ToastContainer} from "react-toastify";
|
import { ToastContainer } from "react-toastify";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
user: User;
|
user: User;
|
||||||
@@ -49,9 +49,9 @@ interface Props {
|
|||||||
grading: Grading;
|
grading: Grading;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({req, res}) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (!user) return redirect("/login")
|
if (!user || !user.isVerified) return redirect("/login")
|
||||||
|
|
||||||
if (!checkAccess(user, ["admin", "developer", "student"]))
|
if (!checkAccess(user, ["admin", "developer", "student"]))
|
||||||
return redirect("/")
|
return redirect("/")
|
||||||
@@ -59,7 +59,7 @@ export const getServerSideProps = withIronSessionSsr(async ({req, res}) => {
|
|||||||
const entityIDS = mapBy(user.entities, "id") || [];
|
const entityIDS = mapBy(user.entities, "id") || [];
|
||||||
|
|
||||||
const entities = await getEntitiesWithRoles(entityIDS);
|
const entities = await getEntitiesWithRoles(entityIDS);
|
||||||
const assignments = await getAssignmentsByAssignee(user.id, {archived: {$ne: true}});
|
const assignments = await getAssignmentsByAssignee(user.id, { archived: { $ne: true } });
|
||||||
const stats = await getStatsByUser(user.id);
|
const stats = await getStatsByUser(user.id);
|
||||||
const sessions = await getSessionsByUser(user.id, 10);
|
const sessions = await getSessionsByUser(user.id, 10);
|
||||||
const invites = await getInvitesByInvitee(user.id);
|
const invites = await getInvitesByInvitee(user.id);
|
||||||
@@ -69,16 +69,16 @@ export const getServerSideProps = withIronSessionSsr(async ({req, res}) => {
|
|||||||
|
|
||||||
const examIDs = uniqBy(
|
const examIDs = uniqBy(
|
||||||
assignments.flatMap((a) =>
|
assignments.flatMap((a) =>
|
||||||
a.exams.filter((e) => e.assignee === user.id).map((e) => ({module: e.module, id: e.id, key: `${e.module}_${e.id}`})),
|
a.exams.filter((e) => e.assignee === user.id).map((e) => ({ module: e.module, id: e.id, key: `${e.module}_${e.id}` })),
|
||||||
),
|
),
|
||||||
"key",
|
"key",
|
||||||
);
|
);
|
||||||
const exams = await getExamsByIds(examIDs);
|
const exams = await getExamsByIds(examIDs);
|
||||||
|
|
||||||
return {props: serialize({user, entities, assignments, stats, exams, sessions, invites: formattedInvites, grading})};
|
return { props: serialize({ user, entities, assignments, stats, exams, sessions, invites: formattedInvites, grading }) };
|
||||||
}, sessionOptions);
|
}, sessionOptions);
|
||||||
|
|
||||||
export default function Dashboard({user, entities, assignments, stats, invites, grading, sessions, exams}: Props) {
|
export default function Dashboard({ user, entities, assignments, stats, invites, grading, sessions, exams }: Props) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const dispatch = useExamStore((state) => state.dispatch);
|
const dispatch = useExamStore((state) => state.dispatch);
|
||||||
@@ -90,11 +90,13 @@ export default function Dashboard({user, entities, assignments, stats, invites,
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (assignmentExams.every((x) => !!x)) {
|
if (assignmentExams.every((x) => !!x)) {
|
||||||
dispatch({type: "INIT_EXAM", payload: {
|
dispatch({
|
||||||
exams: assignmentExams.sort(sortByModule),
|
type: "INIT_EXAM", payload: {
|
||||||
modules: mapBy(assignmentExams.sort(sortByModule), 'module'),
|
exams: assignmentExams.sort(sortByModule),
|
||||||
assignment
|
modules: mapBy(assignmentExams.sort(sortByModule), 'module'),
|
||||||
}})
|
assignment
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
router.push("/exam");
|
router.push("/exam");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ interface Props {
|
|||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (!user) return redirect("/login")
|
if (!user || !user.isVerified) return redirect("/login")
|
||||||
|
|
||||||
if (!checkAccess(user, ["admin", "developer", "teacher"]))
|
if (!checkAccess(user, ["admin", "developer", "teacher"]))
|
||||||
return redirect("/")
|
return redirect("/")
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {User} from "@/interfaces/user";
|
import { User } from "@/interfaces/user";
|
||||||
import {sessionOptions} from "@/lib/session";
|
import { sessionOptions } from "@/lib/session";
|
||||||
import { redirect } from "@/utils";
|
import { redirect } from "@/utils";
|
||||||
import { requestUser } from "@/utils/api";
|
import { requestUser } from "@/utils/api";
|
||||||
import {withIronSessionSsr} from "iron-session/next";
|
import { withIronSessionSsr } from "iron-session/next";
|
||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({req, res}) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (!user) return redirect("/login")
|
if (!user || !user.isVerified) return redirect("/login")
|
||||||
|
|
||||||
return redirect(`/dashboard/${user.type}`)
|
return redirect(`/dashboard/${user.type}`)
|
||||||
}, sessionOptions);
|
}, sessionOptions);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const EMAIL_REGEX = new RegExp(/^[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*@[a-zA-Z0-9]+(?:
|
|||||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res, query }) => {
|
export const getServerSideProps = withIronSessionSsr(async ({ req, res, query }) => {
|
||||||
const destination = !query.destination ? "/" : Buffer.from(query.destination as string, 'base64').toString()
|
const destination = !query.destination ? "/" : Buffer.from(query.destination as string, 'base64').toString()
|
||||||
const user = await requestUser(req, res)
|
const user = await requestUser(req, res)
|
||||||
if (user) return redirect(destination)
|
if (user && user.isVerified) return redirect(destination)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: { user: null, destination },
|
props: { user: null, destination },
|
||||||
@@ -39,13 +39,10 @@ export default function Login({ destination = "/" }: { destination?: string }) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const isOfficialExamLogin = useMemo(() => destination.startsWith("/official-exam"), [destination])
|
const isOfficialExamLogin = useMemo(() => destination.startsWith("/official-exam"), [destination])
|
||||||
|
|
||||||
const { user, mutateUser } = useUser({
|
const { user, mutateUser } = useUser();
|
||||||
redirectTo: destination,
|
|
||||||
redirectIfFound: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user) router.push(destination);
|
if (user && user.isVerified) router.push(destination);
|
||||||
}, [router, user, destination]);
|
}, [router, user, destination]);
|
||||||
|
|
||||||
const forgotPassword = () => {
|
const forgotPassword = () => {
|
||||||
@@ -173,7 +170,7 @@ export default function Login({ destination = "/" }: { destination?: string }) {
|
|||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{/* {user && !user.isVerified && <EmailVerification user={user} isLoading={isLoading} setIsLoading={setIsLoading} />} */}
|
{user && !user.isVerified && <EmailVerification user={user} isLoading={isLoading} setIsLoading={setIsLoading} />}
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user