From b69f4e6ef1e5889f398e00705565a501cb0800a1 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi <256895@studenti.unimore.it> Date: Mon, 26 Apr 2021 16:35:00 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Add=20`working`=20and=20`error`?= =?UTF-8?q?=20to=20useSavedLogin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/frontend/src/contexts/ContextLogin.js | 2 + code/frontend/src/hooks/useSavedLogin.js | 73 +++++++++++++--------- code/frontend/src/routes/PageLogin.js | 5 +- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/code/frontend/src/contexts/ContextLogin.js b/code/frontend/src/contexts/ContextLogin.js index 0d8ea8d..69fe044 100644 --- a/code/frontend/src/contexts/ContextLogin.js +++ b/code/frontend/src/contexts/ContextLogin.js @@ -7,6 +7,8 @@ import {createContext} from "react"; * - `server`: The base url of the N.E.S.T. backend * - `email`: The email of the account the user is logged in as * - `token`: The bearer token to use in authenticated API requests + * - `working`: `true` if the login procedure is running, `false` otherwise + * - `error`: `null` if no login error happened, an instance of {@link Error} otherwise. * - `login`: an async function which logs in the user if given the following parameters: `server, email, password` * - `logout`: a function which logs out the user * - `fetch_unauth`: a variant of {@link fetch} which uses `state.server` as the base url, allowing only the API path diff --git a/code/frontend/src/hooks/useSavedLogin.js b/code/frontend/src/hooks/useSavedLogin.js index 89e65c6..76788ed 100644 --- a/code/frontend/src/hooks/useSavedLogin.js +++ b/code/frontend/src/hooks/useSavedLogin.js @@ -1,3 +1,4 @@ +import {useState} from "react" import useLocalStorageState from "./useLocalStorageState" @@ -6,41 +7,53 @@ import useLocalStorageState from "./useLocalStorageState" */ export default function useSavedLogin() { const [state, setState] = useLocalStorageState("login", null) + const [working, setWorking] = useState(false) + const [error, setError] = useState(null) const login = async (server, email, password) => { - console.debug("Contacting server to login...") - const response = await fetch(`${server}/api/login`, { - method: "POST", - cache: "no-cache", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - "email": email, - "password": password, + setWorking(true) + try { + console.debug("Contacting server to login...") + const response = await fetch(`${server}/api/login`, { + method: "POST", + cache: "no-cache", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + "email": email, + "password": password, + }) }) - }) - console.debug("Decoding server response...") - const data = await response.json() + console.debug("Decoding server response...") + const data = await response.json() - console.debug("Ensuring the request was a success...") - if(data["result"] !== "success") { - console.error(`Login failed: ${data["msg"]}`) - return + console.debug("Ensuring the request was a success...") + if(data["result"] !== "success") { + // noinspection ExceptionCaughtLocallyJS + throw new Error(data["msg"]) + } + + console.debug("Storing login state...") + setState({ + server: server, + email: data["user"]["email"], + isAdmin: data["user"]["isAdmin"], + username: data["user"]["username"], + token: data["access_token"], + }) + + console.debug("Clearing error...") + setError(null) + + console.info("Login successful!") + } catch(e) { + console.error(`Caught error while trying to login: ${e}`) + setError(e) + } finally { + setWorking(false) } - - console.debug("Storing login state...") - setState({ - server: server, - email: data["user"]["email"], - isAdmin: data["user"]["isAdmin"], - username: data["user"]["username"], - token: data["access_token"], - }) - console.debug("Stored login state!") - - console.info("Login successful!") } const logout = () => { @@ -65,5 +78,5 @@ export default function useSavedLogin() { return await fetch_unauth(path, init) } - return {state, login, logout, fetch_unauth, fetch_auth} + return {state, working, error, login, logout, fetch_unauth, fetch_auth} } \ No newline at end of file diff --git a/code/frontend/src/routes/PageLogin.js b/code/frontend/src/routes/PageLogin.js index 2274e5f..d88b26e 100644 --- a/code/frontend/src/routes/PageLogin.js +++ b/code/frontend/src/routes/PageLogin.js @@ -16,7 +16,7 @@ export default function PageLogin({ className, ...props }) { const [server, setServer] = useState("http://localhost:5000") const [email, setEmail] = useState("admin@admin.com") const [password, setPassword] = useState("password") - const {login} = useContext(ContextLogin) + const {login, working, error} = useContext(ContextLogin) const history = useHistory() return ( @@ -60,7 +60,8 @@ export default function PageLogin({ className, ...props }) { history.push("/dashboard") }} icon={faArrowRight} - color={"Green"} + color={error ? "Green" : "Red"} + disabled={working} > Login