From f8643e6bd88c20cc13383a86f457d909cdd6ae6e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 6 Jun 2020 15:38:59 -0700 Subject: Use proper session state --- modern/src/LoginPage.js | 7 ++++++- modern/src/MainMap.js | 4 ++-- modern/src/MainPage.js | 29 ++++++++++++++++------------- modern/src/MainToolbar.js | 5 ++++- modern/src/store/index.js | 3 +++ modern/src/store/session.js | 16 ++++++++++++++++ 6 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 modern/src/store/session.js diff --git a/modern/src/LoginPage.js b/modern/src/LoginPage.js index 99ff95b6..20375b98 100644 --- a/modern/src/LoginPage.js +++ b/modern/src/LoginPage.js @@ -1,5 +1,7 @@ import React, { useState } from 'react'; +import { useDispatch } from 'react-redux'; import { useHistory } from 'react-router-dom'; +import { sessionActions } from './store'; import Button from '@material-ui/core/Button'; import FormHelperText from '@material-ui/core/FormHelperText'; import FormControl from '@material-ui/core/FormControl'; @@ -44,6 +46,8 @@ const useStyles = makeStyles(theme => ({ })); const LoginPage = () => { + const dispatch = useDispatch(); + const [failed, setFailed] = useState(false); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); @@ -67,7 +71,8 @@ const LoginPage = () => { event.preventDefault(); fetch('/api/session', { method: 'POST', body: new URLSearchParams(`email=${email}&password=${password}`) }).then(response => { if (response.ok) { - history.push('/'); // TODO: Avoid calling sessions twice + dispatch(sessionActions.authenticated(true)); + history.push('/'); } else { setFailed(true); setPassword(''); diff --git a/modern/src/MainMap.js b/modern/src/MainMap.js index fdc193c2..35e5348a 100644 --- a/modern/src/MainMap.js +++ b/modern/src/MainMap.js @@ -11,14 +11,14 @@ const calculateMapCenter = (state) => { } } return null; -} +}; const mapFeatureProperties = (state, position) => { const device = state.devices.items[position.deviceId] || null; return { name: device ? device.name : '' } -} +}; const mapStateToProps = state => ({ mapCenter: calculateMapCenter(state), diff --git a/modern/src/MainPage.js b/modern/src/MainPage.js index f81d5e74..ebc20051 100644 --- a/modern/src/MainPage.js +++ b/modern/src/MainPage.js @@ -1,4 +1,6 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { sessionActions } from './store'; import { useHistory } from 'react-router-dom'; import { isWidthUp, makeStyles, withWidth } from '@material-ui/core'; import Drawer from '@material-ui/core/Drawer'; @@ -9,7 +11,6 @@ import MainMap from './MainMap'; import MainToobar from './MainToolbar'; import SocketController from './SocketController'; - const useStyles = makeStyles(theme => ({ root: { height: "100vh", @@ -40,22 +41,24 @@ const useStyles = makeStyles(theme => ({ })); const MainPage = ({ width }) => { - const [loading, setLoading] = useState(!document.authenticated); + const dispatch = useDispatch(); + const authenticated = useSelector(state => state.session.authenticated); const classes = useStyles(); const history = useHistory(); useEffect(() => { - fetch('/api/session').then(response => { - if (response.ok) { - document.authenticated = true; - setLoading(false); - } else { - history.push('/login'); - } - }); - }, [history]); + if (!authenticated) { + fetch('/api/session').then(response => { + if (response.ok) { + dispatch(sessionActions.authenticated(true)); + } else { + history.push('/login'); + } + }); + } + }, [authenticated, history]); - return loading ? (
Loading...
) : ( + return !authenticated ? (
Loading...
) : (
diff --git a/modern/src/MainToolbar.js b/modern/src/MainToolbar.js index 038ab30a..2368a82d 100644 --- a/modern/src/MainToolbar.js +++ b/modern/src/MainToolbar.js @@ -1,6 +1,8 @@ import React, { useState } from 'react'; import { useHistory } from 'react-router-dom'; import { makeStyles } from '@material-ui/core/styles'; +import { useDispatch } from 'react-redux'; +import { sessionActions } from './store'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; import Typography from '@material-ui/core/Typography'; @@ -36,6 +38,7 @@ const useStyles = makeStyles(theme => ({ })); const MainToolbar = () => { + const dispatch = useDispatch(); const [drawer, setDrawer] = useState(false); const classes = useStyles(); const history = useHistory(); @@ -46,7 +49,7 @@ const MainToolbar = () => { const handleLogout = () => { fetch('/api/session', { method: 'DELETE' }).then(response => { if (response.ok) { - document.authenticated = false; + dispatch(sessionActions.authenticated(false)); history.push('/login'); } }) diff --git a/modern/src/store/index.js b/modern/src/store/index.js index 86de31a9..432ef78e 100644 --- a/modern/src/store/index.js +++ b/modern/src/store/index.js @@ -1,13 +1,16 @@ import { combineReducers, configureStore } from '@reduxjs/toolkit'; +import { sessionReducer as session } from './session'; import { devicesReducer as devices } from './devices'; import { positionsReducer as positions } from './positions'; const reducer = combineReducers({ + session, devices, positions, }); +export { sessionActions } from './session'; export { devicesActions } from './devices'; export { positionsActions } from './positions'; diff --git a/modern/src/store/session.js b/modern/src/store/session.js new file mode 100644 index 00000000..772368c4 --- /dev/null +++ b/modern/src/store/session.js @@ -0,0 +1,16 @@ +import { createSlice } from '@reduxjs/toolkit'; + +const { reducer, actions } = createSlice({ + name: 'session', + initialState: { + authenticated: false, + }, + reducers: { + authenticated(state, action) { + state.authenticated = action.payload; + }, + } +}); + +export { actions as sessionActions }; +export { reducer as sessionReducer }; -- cgit v1.2.3