1
Fork 0
mirror of https://github.com/pds-nest/nest.git synced 2024-11-26 06:54:18 +00:00

Merge remote-tracking branch 'origin/main' into main

This commit is contained in:
Lorenzo Balugani 2021-04-26 17:03:25 +02:00
commit eadff47422
6 changed files with 86 additions and 52 deletions

View file

@ -0,0 +1,30 @@
import React, { useContext } from "react"
import BoxFull from "./BoxFull"
import LoggedInUser from "./LoggedInUser"
import Button from "./Button"
import { faSignOutAlt } from "@fortawesome/free-solid-svg-icons"
import ContextLogin from "../contexts/ContextLogin"
import { useHistory } from "react-router"
import Style from "./BoxLoggedIn.module.css"
export default function BoxLoggedIn({ ...props }) {
const {logout} = useContext(ContextLogin)
const history = useHistory()
return (
<BoxFull header={"Logged in"} {...props}>
<div className={Style.BoxLoggedInContents}>
<div>
You are currently logged in as <LoggedInUser/>.
</div>
<div>
<Button color={"Red"} onClick={e => {
logout()
history.push("/login")
}} icon={faSignOutAlt}>Logout</Button>
</div>
</div>
</BoxFull>
)
}

View file

@ -0,0 +1,5 @@
.BoxLoggedInContents {
display: flex;
justify-content: space-between;
align-items: center;
}

View file

@ -7,6 +7,8 @@ import {createContext} from "react";
* - `server`: The base url of the N.E.S.T. backend * - `server`: The base url of the N.E.S.T. backend
* - `email`: The email of the account the user is logged in as * - `email`: The email of the account the user is logged in as
* - `token`: The bearer token to use in authenticated API requests * - `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` * - `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 * - `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 * - `fetch_unauth`: a variant of {@link fetch} which uses `state.server` as the base url, allowing only the API path

View file

@ -1,3 +1,4 @@
import {useState} from "react"
import useLocalStorageState from "./useLocalStorageState" import useLocalStorageState from "./useLocalStorageState"
@ -6,41 +7,53 @@ import useLocalStorageState from "./useLocalStorageState"
*/ */
export default function useSavedLogin() { export default function useSavedLogin() {
const [state, setState] = useLocalStorageState("login", null) const [state, setState] = useLocalStorageState("login", null)
const [working, setWorking] = useState(false)
const [error, setError] = useState(null)
const login = async (server, email, password) => { const login = async (server, email, password) => {
console.debug("Contacting server to login...") setWorking(true)
const response = await fetch(`${server}/api/login`, { try {
method: "POST", console.debug("Contacting server to login...")
cache: "no-cache", const response = await fetch(`${server}/api/login`, {
headers: { method: "POST",
"Content-Type": "application/json", cache: "no-cache",
}, headers: {
body: JSON.stringify({ "Content-Type": "application/json",
"email": email, },
"password": password, body: JSON.stringify({
"email": email,
"password": password,
})
}) })
})
console.debug("Decoding server response...") console.debug("Decoding server response...")
const data = await response.json() const data = await response.json()
console.debug("Ensuring the request was a success...") console.debug("Ensuring the request was a success...")
if(data["result"] !== "success") { if(data["result"] !== "success") {
console.error(`Login failed: ${data["msg"]}`) // noinspection ExceptionCaughtLocallyJS
return 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 = () => { const logout = () => {
@ -65,5 +78,5 @@ export default function useSavedLogin() {
return await fetch_unauth(path, init) return await fetch_unauth(path, init)
} }
return {state, login, logout, fetch_unauth, fetch_auth} return {state, working, error, login, logout, fetch_unauth, fetch_auth}
} }

View file

@ -16,7 +16,7 @@ export default function PageLogin({ className, ...props }) {
const [server, setServer] = useState("http://localhost:5000") const [server, setServer] = useState("http://localhost:5000")
const [email, setEmail] = useState("admin@admin.com") const [email, setEmail] = useState("admin@admin.com")
const [password, setPassword] = useState("password") const [password, setPassword] = useState("password")
const {login} = useContext(ContextLogin) const {login, working, error} = useContext(ContextLogin)
const history = useHistory() const history = useHistory()
return ( return (
@ -60,7 +60,8 @@ export default function PageLogin({ className, ...props }) {
history.push("/dashboard") history.push("/dashboard")
}} }}
icon={faArrowRight} icon={faArrowRight}
color={"Green"} color={error ? "Green" : "Red"}
disabled={working}
> >
Login Login
</Button> </Button>

View file

@ -1,34 +1,17 @@
import React, { useContext } from "react" import React from "react"
import Style from "./PageSettings.module.css" import Style from "./PageSettings.module.css"
import classNames from "classnames" import classNames from "classnames"
import BoxHeader from "../components/BoxHeader" import BoxHeader from "../components/BoxHeader"
import BoxFull from "../components/BoxFull" import BoxFull from "../components/BoxFull"
import SelectTheme from "../components/SelectTheme" import SelectTheme from "../components/SelectTheme"
import ContextLogin from "../contexts/ContextLogin" import BoxLoggedIn from "../components/BoxLoggedIn"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import { faSignOutAlt, faUser } from "@fortawesome/free-solid-svg-icons"
import Button from "../components/Button"
import LoggedInUser from "../components/LoggedInUser"
import { useHistory } from "react-router"
export default function PageSettings({ children, className, ...props }) { export default function PageSettings({ children, className, ...props }) {
const {logout} = useContext(ContextLogin)
const history = useHistory()
return ( return (
<div className={classNames(Style.PageSettings, className)} {...props}> <div className={classNames(Style.PageSettings, className)} {...props}>
<BoxFull header={"Logged in"}> <BoxLoggedIn/>
<div>
You are currently logged in as <LoggedInUser/>.
</div>
<div>
<Button color={"Red"} onClick={e => {
logout()
history.push("/login")
}} icon={faSignOutAlt}>Logout</Button>
</div>
</BoxFull>
<BoxHeader> <BoxHeader>
Switch theme: <SelectTheme/> Switch theme: <SelectTheme/>
</BoxHeader> </BoxHeader>