Skip to content

Commit 90c23c9

Browse files
Merge branch 'sean/auth-guard-2' into staging
2 parents 9853f61 + 6bf0943 commit 90c23c9

File tree

4 files changed

+135
-110
lines changed

4 files changed

+135
-110
lines changed

apps/frontend/src/app/page.tsx

Lines changed: 121 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
SearchOutlined,
2626
} from "@ant-design/icons";
2727
import "./styles.scss";
28-
import { useEffect, useState } from "react";
28+
import { useEffect, useState, useLayoutEffect } from "react";
2929
import {
3030
DeleteQuestion as DeleteQuestionByDocref,
3131
GetQuestions,
@@ -42,6 +42,8 @@ import {
4242
import Link from "next/link";
4343
import TextArea from "antd/es/input/TextArea";
4444
import { title } from "process";
45+
import { isAuthenticated, isAdmin } from "@/utils/Auth";
46+
import { redirect } from 'next/navigation';
4547

4648
/**
4749
* defines the State of the page whe a user is deleing an object. Has 3 general states:
@@ -72,7 +74,7 @@ function DeleteModal({
7274
onOk={okHandler}
7375
onCancel={cancelHandler}
7476
confirmLoading={isDeleting}
75-
okButtonProps={{ danger: true }}
77+
okButtonProps={{ danger: true }}
7678
cancelButtonProps={{ disabled: isDeleting }}
7779
>
7880
<p>{text}</p>
@@ -117,6 +119,13 @@ export default function Home() {
117119
// State for refreshing data
118120
const [refresh, setRefresh] = useState(false);
119121

122+
useLayoutEffect(() => {
123+
const isAuth = isAuthenticated;
124+
if(!isAuth){
125+
redirect("/login")
126+
}
127+
}, [])
128+
120129
const handleEditClick = (index: number, question: Question) => {
121130
// Open the modal for the specific question
122131
const updatedModals =
@@ -295,7 +304,6 @@ export default function Home() {
295304
dataIndex: "id",
296305
render: (_: number, question: Question, index: number) => (
297306
<div>
298-
{/* TODO (Sean): Include Logic to handle retrieving of editable data here and display in a modal component */}
299307
<Modal
300308
title="Edit Problem"
301309
open={isEditModalOpen && isEditModalOpen[index]}
@@ -390,11 +398,14 @@ export default function Home() {
390398
</Form.Item>
391399
</Form>
392400
</Modal>
393-
<Button
394-
className="edit-button"
395-
icon={<EditOutlined />}
396-
onClick={() => handleEditClick(index, question)}
397-
></Button>
401+
{
402+
isAdmin &&
403+
<Button
404+
className="edit-button"
405+
icon={<EditOutlined />}
406+
onClick={() => handleEditClick(index, question)}
407+
></Button>
408+
}
398409
{/* TODO (Ryan): Include Pop-up confirmation for delete when clicked and link to delete API --> can also explore success notification or look into react-toast*/}
399410
<Button
400411
className="delete-button"
@@ -484,115 +495,117 @@ export default function Home() {
484495
<div className="content-card">
485496
<div className="content-row-1">
486497
<div className="content-title">Problems</div>
487-
<div className="create-button">
488-
{/* TODO (Sean): Launch a popup modal that links to the backend api to create a new entry in db, --> look into success/error notification/react toast */}
489-
<Button
490-
type="primary"
491-
icon={<PlusCircleOutlined />}
492-
onClick={showNewProblemModal}
493-
>
494-
Create New Problem
495-
</Button>
496-
<Modal
497-
title="Create New Problem"
498-
open={isNewProblemModalOpen}
499-
// onOk={() => setIsNewProblemModelOpen(false)} // Replace with handleSubmit
500-
onCancel={() => setIsNewProblemModelOpen(false)}
501-
footer={null}
502-
width={600}
503-
>
504-
<Form
505-
name="create-form"
506-
{...layout}
507-
form={form}
508-
onFinish={(values) => {
509-
handleCreateQuestion(values);
510-
}}
498+
{
499+
isAdmin &&
500+
<div className="create-button">
501+
<Button
502+
type="primary"
503+
icon={<PlusCircleOutlined />}
504+
onClick={showNewProblemModal}
511505
>
512-
<Form.Item
513-
name="title"
514-
label="Title"
515-
rules={[
516-
{
517-
required: true,
518-
message: "Please enter question title!",
519-
},
520-
]}
521-
>
522-
<Input name="title" />
523-
</Form.Item>
524-
<Form.Item
525-
name="description"
526-
label="Description"
527-
rules={[
528-
{
529-
required: true,
530-
message: "Please enter question description!",
531-
},
532-
]}
533-
>
534-
<TextArea name="description" />
535-
</Form.Item>
536-
<Form.Item
537-
name="complexity"
538-
label="Complexity"
539-
rules={[
540-
{
541-
required: true,
542-
message: "Please select a complexity!",
543-
},
544-
]}
506+
Create New Problem
507+
</Button>
508+
<Modal
509+
title="Create New Problem"
510+
open={isNewProblemModalOpen}
511+
// onOk={() => setIsNewProblemModelOpen(false)} // Replace with handleSubmit
512+
onCancel={() => setIsNewProblemModelOpen(false)}
513+
footer={null}
514+
width={600}
515+
>
516+
<Form
517+
name="create-form"
518+
{...layout}
519+
form={form}
520+
onFinish={(values) => {
521+
handleCreateQuestion(values);
522+
}}
545523
>
546-
<Select
547-
options={[
524+
<Form.Item
525+
name="title"
526+
label="Title"
527+
rules={[
548528
{
549-
label: "Easy",
550-
value: "easy",
529+
required: true,
530+
message: "Please enter question title!",
551531
},
532+
]}
533+
>
534+
<Input name="title" />
535+
</Form.Item>
536+
<Form.Item
537+
name="description"
538+
label="Description"
539+
rules={[
552540
{
553-
label: "Medium",
554-
value: "medium",
541+
required: true,
542+
message: "Please enter question description!",
555543
},
544+
]}
545+
>
546+
<TextArea name="description" />
547+
</Form.Item>
548+
<Form.Item
549+
name="complexity"
550+
label="Complexity"
551+
rules={[
556552
{
557-
label: "Hard",
558-
value: "hard",
553+
required: true,
554+
message: "Please select a complexity!",
559555
},
560556
]}
561-
onChange={(value) =>
562-
form.setFieldValue("complexity", value)
563-
}
564-
allowClear
565-
/>
566-
</Form.Item>
567-
<Form.Item
568-
name="categories"
569-
label="Categories"
570-
rules={[
571-
{
572-
required: true,
573-
message: "Please select the relevant categories!",
574-
},
575-
]}
576-
>
577-
<Select
578-
mode="multiple"
579-
options={CategoriesOption}
580-
onChange={(value) =>
581-
form.setFieldValue("categories", value)
582-
}
583-
allowClear
584-
/>
585-
</Form.Item>
586-
<Form.Item
587-
style={{ display: "flex", justifyContent: "flex-end" }}
588-
>
589-
<Button type="primary" htmlType="submit">
590-
Create
591-
</Button>
592-
</Form.Item>
593-
</Form>
594-
</Modal>
595-
</div>
557+
>
558+
<Select
559+
options={[
560+
{
561+
label: "Easy",
562+
value: "easy",
563+
},
564+
{
565+
label: "Medium",
566+
value: "medium",
567+
},
568+
{
569+
label: "Hard",
570+
value: "hard",
571+
},
572+
]}
573+
onChange={(value) =>
574+
form.setFieldValue("complexity", value)
575+
}
576+
allowClear
577+
/>
578+
</Form.Item>
579+
<Form.Item
580+
name="categories"
581+
label="Categories"
582+
rules={[
583+
{
584+
required: true,
585+
message: "Please select the relevant categories!",
586+
},
587+
]}
588+
>
589+
<Select
590+
mode="multiple"
591+
options={CategoriesOption}
592+
onChange={(value) =>
593+
form.setFieldValue("categories", value)
594+
}
595+
allowClear
596+
/>
597+
</Form.Item>
598+
<Form.Item
599+
style={{ display: "flex", justifyContent: "flex-end" }}
600+
>
601+
<Button type="primary" htmlType="submit">
602+
Create
603+
</Button>
604+
</Form.Item>
605+
</Form>
606+
</Modal>
607+
</div>
608+
}
596609
</div>
597610
{/* TODO (Ben/Ryan): Include and link search & filter parameters */}
598611
<div className="content-filter">

apps/frontend/src/app/question/[id]/page.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ import {
2525
CheckCircleOutlined,
2626
} from "@ant-design/icons";
2727
import "./styles.scss";
28-
import { useEffect, useState } from "react";
28+
import { useEffect, useState, useLayoutEffect } from "react";
2929
import { Question, GetSingleQuestion } from "../../services/question";
3030
import React from "react";
3131
import TextArea from "antd/es/input/TextArea";
3232
import { useSearchParams } from "next/navigation";
3333
import { ProgrammingLanguageOptions } from "@/utils/SelectOptions";
34+
import { isAuthenticated } from "@/utils/Auth";
35+
import { redirect } from 'next/navigation';
3436

3537
export default function Home() {
3638
const [isLoading, setIsLoading] = useState<boolean>(true); // Store the states related to table's loading
@@ -58,6 +60,13 @@ export default function Home() {
5860
const [description, setDescription] = useState<string | undefined>(undefined);
5961
const [selectedItem, setSelectedItem] = useState("python"); // State to hold the selected language item
6062

63+
useLayoutEffect(() => {
64+
const isAuth = isAuthenticated;
65+
if(!isAuth){
66+
redirect("/login")
67+
}
68+
}, [])
69+
6170
// When code editor page is initialised, fetch the particular question, and display in code editor
6271
useEffect(() => {
6372
if (!isLoading) {

apps/frontend/src/utils/Auth.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const isAuthenticated = true;
2+
export const isUser = false; // i think we can delete this if we are not using
3+
export const isAdmin = true;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# please add all private keys here
2-
2+
cs3219-g24-staging-firebase-adminsdk-suafv-9c0d1b2299.json
33
cs3219-g24-firebase-adminsdk-9cm7h-b1675603ab.json
44
cs3219-g24-staging-firebase-adminsdk-suafv-9c0d1b2299.json
55

0 commit comments

Comments
 (0)