diff --git a/sports-matcher/client/src/Layout.js b/sports-matcher/client/src/Layout.js
index f93165e..9864c39 100644
--- a/sports-matcher/client/src/Layout.js
+++ b/sports-matcher/client/src/Layout.js
@@ -1,6 +1,6 @@
import "./styles/Layout.css";
import "./styles/extra.css";
-import React, { useEffect, useState } from "react";
+import { useEffect, useState } from "react";
import { NavLink, Route, Routes, useNavigate } from "react-router-dom";
import Welcome from "./pages/Welcome";
import Navbar from "react-bootstrap/Navbar";
@@ -10,11 +10,11 @@ import NavbarCollapse from "react-bootstrap/esm/NavbarCollapse";
import Dashboard from "./pages/Dashboard";
import Login from "./pages/Login";
import { apiClient } from "./utils/httpClients";
+import { globalContext } from "./context.js";
export default function layout() {
const navigate = useNavigate();
- const navigationContext = React.createContext(navigate);
const [state, setState] = useState({
user: null,
});
@@ -58,7 +58,7 @@ export default function layout() {
return (
-
+
@@ -85,7 +85,7 @@ export default function layout() {
-
+
);
}
\ No newline at end of file
diff --git a/sports-matcher/client/src/components/MatchInfoCard.js b/sports-matcher/client/src/components/MatchInfoCard.js
index f99832f..f7deb91 100644
--- a/sports-matcher/client/src/components/MatchInfoCard.js
+++ b/sports-matcher/client/src/components/MatchInfoCard.js
@@ -9,7 +9,6 @@ export default class MatchInfoCard extends React.Component {
getParticipants() {
let participants = [];
- console.log(this.props);
this.props.match.participants.forEach(user => {
participants.push(user.firstName);
});
diff --git a/sports-matcher/client/src/context.js b/sports-matcher/client/src/context.js
new file mode 100644
index 0000000..8f6e61c
--- /dev/null
+++ b/sports-matcher/client/src/context.js
@@ -0,0 +1,3 @@
+import React from "react";
+
+export const globalContext = React.createContext({});
diff --git a/sports-matcher/client/src/pages/Login.js b/sports-matcher/client/src/pages/Login.js
index a74018d..a7f5793 100644
--- a/sports-matcher/client/src/pages/Login.js
+++ b/sports-matcher/client/src/pages/Login.js
@@ -1,40 +1,74 @@
import React from "react";
-import { Button, Card, Form } from "react-bootstrap";
+import { Button, Card, Container, Form } from "react-bootstrap";
+import { globalContext } from "../context";
import { apiClient } from "../utils/httpClients";
import { guard } from "../utils/routing";
export default class Login extends React.Component {
constructor(props) {
super(props);
+ this.state = {
+ email: "",
+ password: ""
+ };
+
+ this.attemptLogin = this.attemptLogin.bind(this);
}
+ static contextType = globalContext;
+
async componentDidMount() {
- const getUserResponse = await apiClient.get("/user");
- guard(() => getUserResponse.status === 401, "/dashboard"); // If it's not 401, then we redirect to dashboard.
+ try {
+ const getUserResponse = await apiClient.get("/user");
+ guard(this.context.navigate, () => getUserResponse.status === 401, "/dashboard"); // If it's not 401, then we redirect to dashboard.
+ } catch (error) {
+ if (error.message !== "Request failed with status code 401") {
+ throw error;
+ }
+ }
+ }
+
+ async attemptLogin(e) {
+ e.preventDefault();
+ const loginResponse = await apiClient.post("/user/login", {
+ email: this.state.email,
+ password: this.state.password,
+ });
+
+ if (loginResponse.status === 200) {
+ this.context.navigate("/dashboard", { replace: true });
+ }
}
render() {
return (
-
-
-
- Login
- Welcome back!
-
- E-mail
-
-
-
- Password
-
-
-
-
-
-
+
+
+
+
+ Login
+ Welcome back!
+
+ E-mail
+ {
+ this.setState({ email: e.target.value });
+ }} />
+
+
+ Password
+ {
+ this.setState({ password: e.target.value });
+ }} />
+
+
+
+
+
+
);
}
diff --git a/sports-matcher/client/src/pages/Logout.js b/sports-matcher/client/src/pages/Logout.js
new file mode 100644
index 0000000..517d95c
--- /dev/null
+++ b/sports-matcher/client/src/pages/Logout.js
@@ -0,0 +1,36 @@
+import React from "react";
+import { useNavigate } from "react-router-dom";
+import { apiClient } from "../utils/httpClients";
+
+export default class Logout extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+
+ async componentDidMount() {
+ const logoutResponse = await apiClient.get("/user/logout");
+ let navigation = useNavigate();
+ if (logoutResponse.status === 401) {
+ navigation("/dashboard", { replace: true });
+ } else {
+ this.redirectTimer = setTimeout(() => {
+ navigation("/", { replace: true });
+ }, 2000);
+ }
+ }
+
+ async componentWillUnmount() {
+ clearTimeout(this.redirectTimer);
+ }
+
+ render() {
+ return (
+
+
+
You are now logged out. See you later!
+
We will redirect you shortly...
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/sports-matcher/client/src/utils/routing.js b/sports-matcher/client/src/utils/routing.js
index 94c328e..46caad9 100644
--- a/sports-matcher/client/src/utils/routing.js
+++ b/sports-matcher/client/src/utils/routing.js
@@ -1,7 +1,6 @@
-import { useNavigate } from "react-router-dom";
import { apiClient } from "./httpClients";
-export function guard(evaluator, redirect, navigateOptions, onRedirect) {
+export function guard(navigator, evaluator, redirect, navigateOptions, onRedirect) {
if (!evaluator) throw new Error("evaluator required.");
if (!redirect) throw new Error("redirect required.");
if (!navigateOptions) {
@@ -9,16 +8,15 @@ export function guard(evaluator, redirect, navigateOptions, onRedirect) {
replace: true
};
}
- let navigate = useNavigate();
let redirecting = !evaluator();
if (redirecting) {
if (onRedirect) onRedirect();
- navigate(redirect, navigateOptions);
+ navigator(redirect, navigateOptions);
}
}
-export async function needUser() {
+export async function needUser(navigator) {
let userDataResponse = await apiClient.get("/user");
- guard(() => userDataResponse.status === 200, "/login");
+ guard(navigator, () => userDataResponse.status === 200, "/login");
return userDataResponse.data;
}
\ No newline at end of file