From b1f6d6b22c099467e64faf225cea6865daa3ad7b Mon Sep 17 00:00:00 2001 From: Jagraj Aulakh Date: Mon, 20 Mar 2023 22:17:52 -0400 Subject: [PATCH 1/2] #24 Added courses widget with some dummy data --- frontend/src/components/CoursesWidget.jsx | 52 +++++++++++++++++++++++ frontend/src/pages/HomePage.jsx | 8 ++++ 2 files changed, 60 insertions(+) create mode 100644 frontend/src/components/CoursesWidget.jsx 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

+ +
); -- 2.49.1 From 214b1c86572282b48deabb8bf1ca44fb477949ff Mon Sep 17 00:00:00 2001 From: Jagraj Aulakh Date: Tue, 21 Mar 2023 12:22:38 -0400 Subject: [PATCH 2/2] #25 Moved sendLoginRequest and sendLogoutRequest to utils --- .../src/components/AuthenticatedRoute.jsx | 2 +- frontend/src/pages/LoginPage.jsx | 43 +++++++++---------- frontend/src/pages/LogoutPage.jsx | 15 +++---- frontend/src/utils.ts | 41 +++++++++++++++++- 4 files changed, 66 insertions(+), 35 deletions(-) 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/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 => { + const p: Promise = new Promise(async (res) => { + await makeRequest({ + url: "http://localhost:5000/login", + method: "POST", + body: { username, password }, + }) + .then((resp) => resp.json()) + .then((data) => { + if (data.error) { + res({ isError: true, ...data }); + } + res({ isError: false, ...data }); + }); + res({ isError: true }); + }); + return p; +}; + +const sendLogoutRequest = async (): Promise => { + const p: Promise = new Promise(async (res) => { + await makeRequest({ + url: "http://localhost:5000/logout", + method: "POST", + }) + .then((resp) => resp.json()) + .then((data) => { + res({ isError: false, ...data }); + }); + res({ isError: true }); + }); + return p; +}; + +export { makeRequest, sendLoginRequest, sendLogoutRequest }; -- 2.49.1