diff --git a/package-lock.json b/package-lock.json index 529d2fc..3f47bf1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3670,6 +3670,14 @@ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" }, + "connected-react-router": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/connected-react-router/-/connected-react-router-6.8.0.tgz", + "integrity": "sha512-E64/6krdJM3Ag3MMmh2nKPtMbH15s3JQDuaYJvOVXzu6MbHbDyIvuwLOyhQIuP4Om9zqEfZYiVyflROibSsONg==", + "requires": { + "prop-types": "^15.7.2" + } + }, "console-browserify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", diff --git a/package.json b/package.json index 75c6697..1141563 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@testing-library/react": "^9.4.0", "@testing-library/user-event": "^7.2.1", "classnames": "^2.2.6", + "connected-react-router": "^6.8.0", "dotenv": "^8.2.0", "history": "^4.10.1", "jwt-decode": "^2.2.0", diff --git a/src/actions/user.actions.js b/src/actions/user.actions.js index 01d869f..d0569f9 100644 --- a/src/actions/user.actions.js +++ b/src/actions/user.actions.js @@ -1,7 +1,8 @@ +import { push } from 'connected-react-router' + import { tokensConstants, userConstants } from '../constants' import { usersService } from '../services' import { alertActions } from './' -import { history } from '../helpers' const requestTokenPair = () => ({ type: userConstants.REFRESH_TOKENS @@ -23,15 +24,16 @@ const login = (login, password) => async dispatch => { accessToken }) dispatch(alertActions.clear()) + dispatch(push('/')) } catch (err) { dispatch(failure()) dispatch(alertActions.error(err.statusText)) } } -const logout = () => { - history.push('/') - return logoutWithoutRedirect() +const logout = () => dispatch => { + dispatch(logoutWithoutRedirect()) + dispatch(push('/')) } const logoutWithoutRedirect = () => { @@ -51,6 +53,7 @@ const register = (email, login, password) => async dispatch => { dispatch(request()) await dispatch(success()) dispatch(alertActions.clear()) + dispatch(push('/')) } catch (err) { dispatch(failure()) dispatch(alertActions.error(err.statusText)) diff --git a/src/components/Root/Root.js b/src/components/Root/Root.js index c26f84e..d09a1a6 100644 --- a/src/components/Root/Root.js +++ b/src/components/Root/Root.js @@ -1,6 +1,6 @@ import React, { useMemo } from 'react' import { Provider } from 'react-redux' -import { Router } from 'react-router-dom' +import { ConnectedRouter } from 'connected-react-router' import { ThemeProvider, CssBaseline, @@ -11,9 +11,8 @@ import PropTypes from 'prop-types' import Header from '../Header' import Main from '../../pages/Main' -import { history } from '../../helpers' -const Root = props => { +const Root = ({ store, history }) => { const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)') const theme = useMemo( @@ -27,20 +26,21 @@ const Root = props => { ) return ( - + - +
- + ) } Root.propTypes = { - store: PropTypes.object.isRequired + store: PropTypes.object.isRequired, + history: PropTypes.object.isRequired } export default Root diff --git a/src/constants/alert.constants.js b/src/constants/alert.constants.js index f5273da..c017585 100644 --- a/src/constants/alert.constants.js +++ b/src/constants/alert.constants.js @@ -1,5 +1,5 @@ export const alertConstants = { - SUCCESS: 'ALERT_SUCCESS', - ERROR: 'ALERT_ERROR', - CLEAR: 'ALERT_CLEAR' + SUCCESS: 'alert/SUCCESS', + ERROR: 'alert/ERROR', + CLEAR: 'alert/CLEAR' } diff --git a/src/constants/cabinet.constants.js b/src/constants/cabinet.constants.js index 4dd7929..c320579 100644 --- a/src/constants/cabinet.constants.js +++ b/src/constants/cabinet.constants.js @@ -1,6 +1,6 @@ export const cabinetConstants = { - CABINET_REQUEST: 'CABINET_REQUEST', - CABINET_SUCCESS: 'CABINET_SUCCESS', - CABINET_FAILURE: 'CABINET_FAILURE', - CABINET_CLEAR: 'CABINET_CLEAR' + CABINET_REQUEST: 'cabinet/REQUEST', + CABINET_SUCCESS: 'cabinet/SUCCESS', + CABINET_FAILURE: 'cabinet/FAILURE', + CABINET_CLEAR: 'cabinet/CLEAR' } diff --git a/src/constants/react.constants.js b/src/constants/react.constants.js index 8eb399d..98fa5b7 100644 --- a/src/constants/react.constants.js +++ b/src/constants/react.constants.js @@ -1,5 +1,5 @@ export const reactConstants = { - FETCH_PENDING: 'FETCH_PENDING', - FETCH_SUCCESS: 'FETCH_SUCCESS', - FETCH_FAILURE: 'FETCH_FAILURE' + FETCH_PENDING: 'react/PENDING', + FETCH_SUCCESS: 'react/SUCCESS', + FETCH_FAILURE: 'react/FAILURE' } diff --git a/src/constants/tokens.constants.js b/src/constants/tokens.constants.js index 6467a85..9d2b019 100644 --- a/src/constants/tokens.constants.js +++ b/src/constants/tokens.constants.js @@ -1,9 +1,8 @@ export const tokensConstants = { - TOKENS_SET: 'TOKENS_SET', - REFRESH_TOKENS: 'REFRESH_TOKENS', + TOKENS_SET: 'tokens/SET', - TOKENS_REQUEST: 'TOKENS_REQUEST', - TOKENS_SUCCESS: 'TOKENS_SUCCESS', - TOKENS_FAILURE: 'TOKENS_FAILURE', - TOKENS_CLEAR: 'TOKENS_CLEAR' + TOKENS_REQUEST: 'tokens/REQUEST', + TOKENS_SUCCESS: 'tokens/SUCCESS', + TOKENS_FAILURE: 'tokens/FAILURE', + TOKENS_CLEAR: 'tokens/CLEAR' } diff --git a/src/constants/user.constants.js b/src/constants/user.constants.js index c8c8d39..4b095eb 100644 --- a/src/constants/user.constants.js +++ b/src/constants/user.constants.js @@ -1,11 +1,11 @@ export const userConstants = { - REGISTER_REQUEST: 'REGISTER_REQUEST', - REGISTER_SUCCESS: 'REGISTER_SUCCESS', - REGISTER_FAILURE: 'REGISTER_FAILURE', + REGISTER_REQUEST: 'user/register/REQUEST', + REGISTER_SUCCESS: 'user/register/SUCCESS', + REGISTER_FAILURE: 'user/register/FAILURE', - LOGIN_REQUEST: 'LOGIN_REQUEST', - LOGIN_SUCCESS: 'LOGIN_SUCCESS', - LOGIN_FAILURE: 'LOGIN_FAILURE', + LOGIN_REQUEST: 'user/login/REQUEST', + LOGIN_SUCCESS: 'user/login/SUCCESS', + LOGIN_FAILURE: 'user/login/FAILURE', - LOGOUT: 'LOGOUT' + LOGOUT: 'user/LOGOUT' } diff --git a/src/helpers/history.js b/src/helpers/history.js deleted file mode 100644 index ea922a8..0000000 --- a/src/helpers/history.js +++ /dev/null @@ -1,3 +0,0 @@ -import { createBrowserHistory } from 'history' - -export const history = createBrowserHistory() diff --git a/src/helpers/index.js b/src/helpers/index.js index fc300af..40544fb 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -1,3 +1,2 @@ -export * from './history' export * from './store' export * from './auth-header' diff --git a/src/helpers/store.js b/src/helpers/store.js index 8c8ced1..96d7a80 100644 --- a/src/helpers/store.js +++ b/src/helpers/store.js @@ -1,6 +1,14 @@ import { createStore } from 'redux' -import rootReducer from '../reducers' import { composeWithDevTools } from 'redux-devtools-extension' -import middleware from '../middleware' +import rootReducer from '../reducers' +import createMiddleware from '../middleware' +import { createBrowserHistory } from 'history' + +export const history = createBrowserHistory() -export const store = createStore(rootReducer, composeWithDevTools(middleware)) +export const configureStore = preloadedState => + createStore( + rootReducer(history), + preloadedState, + composeWithDevTools(createMiddleware(history)) + ) diff --git a/src/index.js b/src/index.js index d14c139..2c32895 100644 --- a/src/index.js +++ b/src/index.js @@ -3,9 +3,13 @@ import ReactDOM from 'react-dom' import Root from './components/Root/Root' import * as serviceWorker from './serviceWorker' -import { store } from './helpers' +import { configureStore, history } from './helpers' -ReactDOM.createRoot(document.getElementById('root')).render() +const store = configureStore() + +ReactDOM.createRoot(document.getElementById('root')).render( + +) // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. diff --git a/src/middleware/index.js b/src/middleware/index.js index c7505a8..ddbb0e4 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -1,5 +1,7 @@ import { applyMiddleware } from 'redux' import thunkMiddleware from 'redux-thunk' import { createLogger } from 'redux-logger' +import { routerMiddleware } from 'connected-react-router' -export default applyMiddleware(thunkMiddleware, createLogger()) +export default history => + applyMiddleware(thunkMiddleware, routerMiddleware(history), createLogger()) diff --git a/src/pages/Cabinet/index.js b/src/pages/Cabinet/index.js index d04e0c3..0d5d7c7 100644 --- a/src/pages/Cabinet/index.js +++ b/src/pages/Cabinet/index.js @@ -1,7 +1,6 @@ -import React, { Suspense } from 'react' +import React, { Suspense, useEffect, useState } from 'react' import { bindActionCreators } from 'redux' import { connect } from 'react-redux' -import { Redirect } from 'react-router-dom' import PropTypes from 'prop-types' import { userActions, cabinetActions, tokensActions, alertActions } from '../../actions' import { api } from './api' @@ -30,21 +29,17 @@ const CabinetPage = ({ clearCabinet, clearAlert }) => { - if ((tokensRefreshFailed || failedToLoad) && !alert.message) { - clearCabinet() - clearTokens() - logout() - return - } - return ( }> - {alert.message ? ( + {alert.message && (failedToLoad || tokensRefreshFailed) ? ( { clearAlert() + clearCabinet() + clearTokens() + logout() }} /> ) : ( @@ -82,7 +77,7 @@ const mapDispatchToProps = dispatch => bindActionCreators( { cabinetLoad: cabinetActions.load, - logout: userActions.logoutWithoutRedirect, + logout: userActions.logout, loadCabinet: api.loadCabinet, clearCabinet: cabinetActions.clear, clearTokens: tokensActions.clear, diff --git a/src/reducers/index.js b/src/reducers/index.js index 053192b..287f685 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,4 +1,5 @@ import { combineReducers } from 'redux' +import { connectRouter } from 'connected-react-router' import { auth } from './auth.reducer' import { alert } from './alert.reducer' @@ -6,12 +7,14 @@ import { tokens } from './tokens.reducer' import { cabinet } from './cabinet.reducer' import { react } from './react.reducer' -const rootReducer = combineReducers({ - auth, - tokens, - alert, - cabinet, - react -}) +const rootReducer = history => + combineReducers({ + router: connectRouter(history), + auth, + tokens, + alert, + cabinet, + react + }) export default rootReducer diff --git a/src/services/users.service.js b/src/services/users.service.js index dc77e09..decd88f 100644 --- a/src/services/users.service.js +++ b/src/services/users.service.js @@ -6,11 +6,9 @@ import { setRefreshToken, setUser } from '../utils' -import { history } from '../helpers' const register = async (email, login, password) => { await payloadFetch(`${config.api.url}/auth/register`, { email, login, password }) - history.push('/') } const login = async (login, password) => {