diff --git a/frontend/src/components/AuthenticatedRoute.jsx b/frontend/src/components/AuthenticatedRoute.jsx
index 9d7b5bc..5626f9a 100644
--- a/frontend/src/components/AuthenticatedRoute.jsx
+++ b/frontend/src/components/AuthenticatedRoute.jsx
@@ -12,7 +12,7 @@ const AuthenticatedRoute = ({ children, isAuthenticated }) => {
} else if (!isAuthenticated && currentUser?.id) {
setLocation("/");
}
- }, [currentUser]);
+ }, [currentUser, setLocation, isAuthenticated]);
return children;
};
diff --git a/frontend/src/components/CoursesWidget.jsx b/frontend/src/components/CoursesWidget.jsx
new file mode 100644
index 0000000..c938e9a
--- /dev/null
+++ b/frontend/src/components/CoursesWidget.jsx
@@ -0,0 +1,52 @@
+import { Card, Container } from "react-bootstrap";
+import { Link } from "wouter";
+
+const CoursesWidget = ({ className = "" }) => {
+ const dummyData = [
+ {
+ course_id: 1,
+ course_title: "Advanced Website Design",
+ couse_code: "COMP 2707",
+ instructor: "Saja Al Mamoori",
+ },
+ {
+ course_id: 2,
+ course_title: "Introduction to Roman Civilization",
+ couse_code: "GRST 1200",
+ instructor: "Max Nelson",
+ },
+ {
+ course_id: 3,
+ course_title: "Software Verification and Testing",
+ couse_code: "COMP 4110",
+ instructor: "Serif Saad",
+ },
+ {
+ course_id: 1,
+ course_title: "Advanced Website Design",
+ couse_code: "COMP 2707",
+ instructor: "Saja Al Mamoori",
+ },
+ ];
+ return (
+
+ {dummyData.map((course, i) => {
+ return (
+
+
+ {course.couse_code}
+
+ {course.course_title}
+ {course.instructor}
+
+
+
+ );
+ })}
+
+ );
+};
+
+export default CoursesWidget;
diff --git a/frontend/src/pages/HomePage.jsx b/frontend/src/pages/HomePage.jsx
index 467f6d8..0c517d0 100644
--- a/frontend/src/pages/HomePage.jsx
+++ b/frontend/src/pages/HomePage.jsx
@@ -1,5 +1,6 @@
import { useContext } from "react";
import { Container } from "react-bootstrap";
+import CoursesWidget from "../components/CoursesWidget";
import MyNavbar from "../components/MyNavbar";
import UserContext from "../contexts/UserContext";
@@ -13,6 +14,13 @@ const HomePage = () => {
Welcome back {currentUser?.username}!
+
+
+
+
+
Courses
+
+
);
diff --git a/frontend/src/pages/LoginPage.jsx b/frontend/src/pages/LoginPage.jsx
index 5f55e96..89b2cf0 100644
--- a/frontend/src/pages/LoginPage.jsx
+++ b/frontend/src/pages/LoginPage.jsx
@@ -3,7 +3,7 @@ import { Button, Col, Container, Form, Row, Alert } from "react-bootstrap";
import { Link, useLocation } from "wouter";
import MyNavbar from "../components/MyNavbar";
import UserContext from "../contexts/UserContext";
-import { makeRequest } from "../utils.ts";
+import { sendLogoutRequest, sendLoginRequest } from "../utils.ts";
const LoginPage = () => {
const [username, setUsername] = useState("");
@@ -15,29 +15,28 @@ const LoginPage = () => {
useEffect(() => {
if (currentUser?.id) {
- gotoHome();
+ setLocation("/");
}
- }, [currentUser]);
+ }, [currentUser, setLocation]);
- const gotoHome = () => {
- setLocation("/");
- };
-
- const sendLoginRequest = async (e) => {
+ const formCb = async (e) => {
e?.preventDefault();
- await makeRequest({
- url: "http://localhost:5000/login",
- method: "POST",
- body: { username, password },
- })
- .then((resp) => resp.json())
- .then((data) => {
- if (data.error) {
- setError(data);
- return;
- }
- setCurrentUser(data);
- });
+ const res = await sendLoginRequest(username, password);
+
+ if (res?.isError) {
+ if (res.message.includes("already")) {
+ setError({
+ ...res,
+ message: "An error occured. Try logging in again.",
+ });
+ await sendLogoutRequest();
+ return;
+ }
+ setError(res);
+ return;
+ }
+ setCurrentUser(res);
+ setLocation("/");
};
return (
@@ -53,7 +52,7 @@ const LoginPage = () => {
)}
Login
-
Username
diff --git a/frontend/src/pages/LogoutPage.jsx b/frontend/src/pages/LogoutPage.jsx
index 8512700..afcaa46 100644
--- a/frontend/src/pages/LogoutPage.jsx
+++ b/frontend/src/pages/LogoutPage.jsx
@@ -3,23 +3,18 @@ import { useContext, useEffect } from "react";
import { Container } from "react-bootstrap";
import MyNavbar from "../components/MyNavbar";
import UserContext from "../contexts/UserContext";
-import { makeRequest } from "../utils.ts";
+import { sendLogoutRequest } from "../utils.ts";
const LogoutPage = () => {
const { setCurrentUser } = useContext(UserContext);
useEffect(() => {
- const cleanup = async () => {
- await makeRequest({
- url: "http://localhost:5000/logout",
- method: "POST",
- });
-
+ (async () => {
+ await sendLogoutRequest();
await setCurrentUser({});
localStorage.removeItem("currentUser");
window.location.href = "/login";
- };
- cleanup();
- }, []);
+ })();
+ }, [setCurrentUser]);
return (
diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts
index c7b116f..5daef16 100644
--- a/frontend/src/utils.ts
+++ b/frontend/src/utils.ts
@@ -1,4 +1,4 @@
-const makeRequest = ({ url, method, body }): Promise => {
+const makeRequest = ({ url, method, body = {} }): Promise => {
return fetch(url, {
method: method,
credentials: "include",
@@ -8,4 +8,41 @@ const makeRequest = ({ url, method, body }): Promise => {
});
};
-export { makeRequest };
+const sendLoginRequest = async (
+ username: string,
+ password: string
+): Promise