Skip to content

Commit 2888fa8

Browse files
committed
Add unauthorized and loading pages
1 parent e863d15 commit 2888fa8

File tree

9 files changed

+193
-26
lines changed

9 files changed

+193
-26
lines changed

frontend/package-lock.json

Lines changed: 140 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"markdown-to-jsx": "^7.5.0",
2626
"react": "^18.3.1",
2727
"react-dom": "^18.3.1",
28+
"react-loader-spinner": "^6.1.6",
2829
"react-router-dom": "^6.26.2",
2930
"react-toastify": "^10.0.5",
3031
"vite-plugin-svgr": "^4.2.0"

frontend/src/components/AppMargin/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Box } from "@mui/material";
2+
import { ToastContainer } from "react-toastify";
23

34
type AppMarginProps = { classname?: string; children: React.ReactNode };
45

@@ -13,6 +14,7 @@ const AppMargin: React.FC<AppMarginProps> = (props) => {
1314
})}
1415
>
1516
{children}
17+
<ToastContainer position="bottom-right" />
1618
</Box>
1719
);
1820
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Box, Typography } from "@mui/material";
2+
import { Oval } from "react-loader-spinner";
3+
4+
const Loader: React.FC = () => {
5+
return (
6+
<Box
7+
sx={{
8+
display: "flex",
9+
flexDirection: "column",
10+
minHeight: "100vh",
11+
minWidth: "755px",
12+
alignItems: "center",
13+
justifyContent: "center",
14+
}}
15+
>
16+
<Oval
17+
height="80"
18+
width="80"
19+
color="#8FB8ED"
20+
secondaryColor="#9E9E9E"
21+
/>
22+
<Typography
23+
variant="h4"
24+
sx={(theme) => ({ marginTop: theme.spacing(2) })}
25+
>Loading...</Typography>
26+
</Box>
27+
);
28+
};
29+
30+
export default Loader;

frontend/src/components/ProtectedRoutes/index.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Navigate, Outlet } from "react-router-dom";
22
import { useAuth } from "../../contexts/AuthContext";
33
import React from "react";
4+
import ServerError from "../ServerError";
45

56
type ProtectedRoutesProps = {
67
adminOnly?: boolean;
@@ -18,9 +19,12 @@ const ProtectedRoutes: React.FC<ProtectedRoutesProps> = ({ adminOnly = false })
1819
}
1920

2021
if (adminOnly && !user.isAdmin) {
21-
// TODO: unauthorized page
22-
console.log("unauthorized");
23-
return <></>;
22+
return (
23+
<ServerError
24+
title="Oops, access denied..."
25+
subtitle="Unfortunately, you do not have the permission to access this page 😥"
26+
/>
27+
);
2428
}
2529

2630
return <Outlet />;

frontend/src/contexts/AuthContext.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import { createContext, useContext, useEffect, useState } from "react";
44
import { userClient } from "../utils/api";
55
import { useNavigate } from "react-router-dom";
6-
import { Box } from "@mui/material";
76
import { toast } from "react-toastify";
7+
import Loader from "../components/Loader";
88

99
type User = {
1010
id: string;
@@ -48,9 +48,11 @@ const AuthProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
4848
})
4949
.then((res) => setUser(res.data.data))
5050
.catch(() => setUser(null))
51-
.finally(() => setLoading(false));
51+
.finally(() => {
52+
setTimeout(() => setLoading(false), 1500)
53+
});
5254
} else {
53-
setLoading(false);
55+
setTimeout(() => setLoading(false), 1500);
5456
}
5557
}, []);
5658

@@ -98,15 +100,11 @@ const AuthProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
98100
localStorage.removeItem("token");
99101
setUser(null);
100102
navigate("/");
103+
toast.success("Logged out successfully!");
101104
};
102105

103106
if (loading) {
104-
// TODO: loading page
105-
return (
106-
<Box>
107-
Loading...
108-
</Box>
109-
);
107+
return <Loader />;
110108
}
111109

112110
return (

frontend/src/pages/NewQuestion/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useNavigate } from "react-router-dom";
33
import { Autocomplete, Button, IconButton, Stack, TextField } from "@mui/material";
44
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
55
import axios from "axios";
6-
import { ToastContainer, toast } from "react-toastify";
6+
import { toast } from "react-toastify";
77
import "react-toastify/dist/ReactToastify.css";
88

99
import { questionClient } from "../../utils/api";
@@ -96,7 +96,7 @@ const NewQuestion = () => {
9696
options={complexityList}
9797
size="small"
9898
sx={{ marginTop: 2 }}
99-
onChange={(e, newcomplexitySelected) => {
99+
onChange={(_e, newcomplexitySelected) => {
100100
setselectedComplexity(newcomplexitySelected);
101101
}}
102102
renderInput={(params) => <TextField {...params} label="Complexity" />}
@@ -132,8 +132,6 @@ const NewQuestion = () => {
132132
{isPreviewQuestion ? "Edit Question" : "Preview Question"}
133133
</Button>
134134
</Stack>
135-
136-
<ToastContainer position="bottom-right" />
137135
</AppMargin>
138136
);
139137
};

frontend/src/pages/QuestionEdit/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from "@mui/material";
1010
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
1111
import axios from "axios";
12-
import { ToastContainer, toast } from "react-toastify";
12+
import { toast } from "react-toastify";
1313
import "react-toastify/dist/ReactToastify.css";
1414

1515
import { questionClient } from "../../utils/api";
@@ -142,7 +142,7 @@ const QuestionEdit = () => {
142142
size="small"
143143
sx={{ marginTop: 2 }}
144144
value={selectedComplexity}
145-
onChange={(e, newcomplexitySelected) => {
145+
onChange={(_e, newcomplexitySelected) => {
146146
setselectedComplexity(newcomplexitySelected);
147147
}}
148148
renderInput={(params) => (
@@ -186,8 +186,6 @@ const QuestionEdit = () => {
186186
{isPreviewQuestion ? "Edit Question" : "Preview Question"}
187187
</Button>
188188
</Stack>
189-
190-
<ToastContainer position="bottom-right" />
191189
</AppMargin>
192190
);
193191
};

0 commit comments

Comments
 (0)