Implemented a simple authentication scheme with Firebase and Iron Session
This commit is contained in:
@@ -4,22 +4,38 @@ import Navbar from "@/components/Navbar";
|
||||
import {useEffect, useState} from "react";
|
||||
import {Module} from "@/interfaces";
|
||||
|
||||
// TODO: Remove this import
|
||||
import JSON_USER from "@/demo/user.json";
|
||||
import JSON_READING from "@/demo/reading.json";
|
||||
import JSON_LISTENING from "@/demo/listening.json";
|
||||
import JSON_WRITING from "@/demo/writing.json";
|
||||
|
||||
import Selection from "@/exams/Selection";
|
||||
import Reading from "@/exams/Reading";
|
||||
import {Exam, ListeningExam, ReadingExam, UserSolution, WritingExam} from "@/interfaces/exam";
|
||||
import Listening from "@/exams/Listening";
|
||||
import Writing from "@/exams/Writing";
|
||||
import {ToastContainer} from "react-toastify";
|
||||
import Link from "next/link";
|
||||
import {ToastContainer, toast} from "react-toastify";
|
||||
import Finish from "@/exams/Finish";
|
||||
import axios from "axios";
|
||||
import {withIronSessionSsr} from "iron-session/next";
|
||||
import {sessionOptions} from "@/lib/session";
|
||||
import {User} from "@/interfaces/user";
|
||||
|
||||
export default function Home() {
|
||||
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
|
||||
const user = req.session.user;
|
||||
|
||||
if (!user) {
|
||||
res.setHeader("location", "/login");
|
||||
res.statusCode = 302;
|
||||
res.end();
|
||||
return {
|
||||
props: {
|
||||
user: null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
props: {user: req.session.user},
|
||||
};
|
||||
}, sessionOptions);
|
||||
|
||||
export default function Page({user}: {user: User}) {
|
||||
const [selectedModules, setSelectedModules] = useState<Module[]>([]);
|
||||
const [moduleIndex, setModuleIndex] = useState(0);
|
||||
const [exam, setExam] = useState<Exam>();
|
||||
@@ -27,21 +43,31 @@ export default function Home() {
|
||||
const [showSolutions, setShowSolutions] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedModules.length > 0 && moduleIndex < selectedModules.length) {
|
||||
const nextExam = getExam(selectedModules[moduleIndex]);
|
||||
setExam(nextExam ? updateExamWithUserSolutions(nextExam) : undefined);
|
||||
}
|
||||
(async () => {
|
||||
if (selectedModules.length > 0 && moduleIndex < selectedModules.length) {
|
||||
const nextExam = await getExam(selectedModules[moduleIndex]);
|
||||
setExam(nextExam ? updateExamWithUserSolutions(nextExam) : undefined);
|
||||
}
|
||||
})();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedModules, moduleIndex]);
|
||||
|
||||
const getExam = (module: Module): Exam | undefined => {
|
||||
const getExam = async (module: Module): Promise<Exam | undefined> => {
|
||||
const examRequest = await axios<Exam[]>(`/api/exam/${module}`);
|
||||
if (examRequest.status !== 200) {
|
||||
toast.error("Something went wrong!");
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const newExam = examRequest.data;
|
||||
|
||||
switch (module) {
|
||||
case "reading":
|
||||
return JSON_READING as ReadingExam;
|
||||
return newExam.shift() as ReadingExam;
|
||||
case "listening":
|
||||
return JSON_LISTENING as ListeningExam;
|
||||
return newExam.shift() as ListeningExam;
|
||||
case "writing":
|
||||
return JSON_WRITING as WritingExam;
|
||||
return newExam.shift() as WritingExam;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -63,13 +89,13 @@ export default function Home() {
|
||||
|
||||
const renderScreen = () => {
|
||||
if (selectedModules.length === 0) {
|
||||
return <Selection user={JSON_USER} onStart={setSelectedModules} />;
|
||||
return <Selection user={user} onStart={setSelectedModules} />;
|
||||
}
|
||||
|
||||
if (moduleIndex >= selectedModules.length) {
|
||||
return (
|
||||
<Finish
|
||||
user={JSON_USER}
|
||||
user={user}
|
||||
modules={selectedModules}
|
||||
onViewResults={() => {
|
||||
setShowSolutions(true);
|
||||
@@ -110,7 +136,7 @@ export default function Home() {
|
||||
</Head>
|
||||
<main className="w-full h-screen flex flex-col items-center bg-neutral-100 text-black">
|
||||
<ToastContainer />
|
||||
<Navbar profilePicture={JSON_USER.profilePicture} />
|
||||
<Navbar profilePicture={user.profilePicture} />
|
||||
{renderScreen()}
|
||||
</main>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user