Add context to pass the user token through components

This commit is contained in:
Miguel de la Cruz 2021-09-13 11:21:26 +02:00
parent 9a5dcac620
commit 57dbfc8a87
7 changed files with 70 additions and 28 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
/server/craban
/server/craban.sqlite
/server/web/static/*
/webapp/node_modules/

Binary file not shown.

View file

@ -1,14 +1,13 @@
export class Client {
login(username, password) {
console.log('Logging with', username)
// ToDo: handle error
return fetch("/api/login", {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
}).then(r => r.text()).then(token => {
console.log("GOT TOKEN")
localStorage.setItem('token', token)
return token
})
}
}

View file

@ -1,3 +1,4 @@
import { useState, useContext } from 'react'
import ReactDOM from 'react-dom'
import {
BrowserRouter as Router,
@ -9,12 +10,13 @@ import {
import { CssBaseline } from '@material-ui/core';
import UserContext from './user-context'
import Login from './pages/login'
import Home from './pages/home'
const Secure = ({children}) => {
const token = localStorage.getItem('token')
const { token } = useContext(UserContext)
if (!token) {
return <Redirect to="/login" />
}
@ -22,26 +24,26 @@ const Secure = ({children}) => {
return children
}
const Home = () => {
return <h1>Home</h1>
}
const App = () => {
return (
<Router>
<CssBaseline />
<Switch>
<Route path="/login">
<Login />
</Route>
const [token, setToken] = useState(localStorage.getItem('token'))
<Route path="/">
<Secure>
<Home />
</Secure>
</Route>
</Switch>
</Router>
return (
<UserContext.Provider value={{ token, setToken }}>
<Router>
<CssBaseline />
<Switch>
<Route path="/login">
<Login />
</Route>
<Route path="/">
<Secure>
<Home />
</Secure>
</Route>
</Switch>
</Router>
</UserContext.Provider>
)
}

33
webapp/src/pages/home.js Normal file
View file

@ -0,0 +1,33 @@
import { useContext } from 'react'
import {
Box,
Button
} from '@material-ui/core';
import UserContext from '../user-context'
const Home = () => {
const { token, setToken } = useContext(UserContext)
const handleLogout = (e) => {
e.preventDefault()
localStorage.removeItem('token')
setToken(null)
}
return (
<Box>
<h1>Home</h1>
<Button
variant="contained"
color="secondary"
onClick={handleLogout}>
Logout
</Button>
</Box>
)
}
export default Home

View file

@ -1,4 +1,4 @@
import { useState } from 'react'
import { useState, useContext } from 'react'
import { Redirect } from 'react-router-dom'
import {
Box,
@ -7,9 +7,12 @@ import {
} from '@material-ui/core';
import client from '../client'
import UserContext from '../user-context'
const Login = () => {
if (localStorage.getItem('token')) {
const { token, setToken } = useContext(UserContext)
if (token) {
return <Redirect to='/' />
}
@ -18,9 +21,8 @@ const Login = () => {
const handleSubmit = (e) => {
e.preventDefault()
client.login(username, password).then(() => {
setUsername('')
setPassword('')
client.login(username, password).then(token => {
setToken(token)
})
}

View file

@ -0,0 +1,5 @@
import React from 'react'
const UserContext = React.createContext()
export default UserContext