From 40f8f20bd9ba8cccf9a10838ea75ce38ba6b9b04 Mon Sep 17 00:00:00 2001 From: IrynaSlavinska <133566139+IrynaSlavinska@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:39:52 +0200 Subject: [PATCH] updates --- src/components/App.jsx | 34 ++++++++++++++------ src/components/AppBar/AppBar.jsx | 2 +- src/components/AppBar/Navigation.jsx | 13 ++++++-- src/components/AppBar/UserMenu.jsx | 2 +- src/hooks/useAuth.js | 12 ++----- src/pages/HomePage/HomePage.jsx | 4 +-- src/pages/NotAuthPage/NotAuthPage.jsx | 20 ++++++++++++ src/pages/NotAuthPage/NotAuthPage.styled.jsx | 22 +++++++++++++ src/pages/NotFound/NotFound.styled.jsx | 2 +- src/redux/auth/authSelectors.js | 6 ++-- src/redux/auth/authSlice.js | 8 +++++ src/routes/PrivateRoute.js | 9 ++++++ 12 files changed, 104 insertions(+), 30 deletions(-) create mode 100644 src/pages/NotAuthPage/NotAuthPage.jsx create mode 100644 src/pages/NotAuthPage/NotAuthPage.styled.jsx create mode 100644 src/routes/PrivateRoute.js diff --git a/src/components/App.jsx b/src/components/App.jsx index 0494193..bf33ccd 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -1,32 +1,46 @@ -import { lazy } from 'react'; -import { Routes, Route } from 'react-router-dom'; - -import { useEffect } from 'react'; +import { lazy, useEffect } from 'react'; import { useDispatch } from 'react-redux'; +import { Routes, Route } from 'react-router-dom'; import Layout from './Layout/Layout'; -import ContactsPage from 'pages/ContactsPage/ContactsPage'; -import RegisterPage from 'pages/RegisterPage/RegisterPage'; -import NotFound from 'pages/NotFound/NotFound'; - +import { PrivateRoute } from '../routes/PrivateRoute'; +// import { RestrictedRoute } from './RestrictedRoute'; +import { useAuth } from '../hooks/useAuth'; import operations from '../redux/auth/authOperations'; const HomePage = lazy(() => import('pages/HomePage/HomePage')); const LoginPage = lazy(() => import('pages/LoginPage/LoginPage')); +const ContactsPage = lazy(() => import('pages/ContactsPage/ContactsPage')); +const RegisterPage = lazy(() => import('pages/RegisterPage/RegisterPage')); +const NotFound = lazy(() => import('pages/NotFound/NotFound')); +const NotAuthPage = lazy(() => import('pages/NotAuthPage/NotAuthPage')); const App = () => { const dispatch = useDispatch(); + const { isRefreshing } = useAuth(); + useEffect(() => { dispatch(operations.refreshUser()); }, [dispatch]); - return ( + return isRefreshing ? ( + Refreshing user... + ) : ( }> } /> } /> } /> - } /> + } /> + } + /> + } + /> }> diff --git a/src/components/AppBar/AppBar.jsx b/src/components/AppBar/AppBar.jsx index a3eb7f4..6402772 100644 --- a/src/components/AppBar/AppBar.jsx +++ b/src/components/AppBar/AppBar.jsx @@ -5,7 +5,7 @@ import { AuthNav } from './AuthNav'; import { UserMenu } from 'components/AppBar/UserMenu'; import { Header } from './AppBar.styled'; -import authSelectors from '../../redux/auth/authSelectors'; +import { authSelectors } from '../../redux/auth/authSelectors'; export const AppBar = () => { const isLoggedIn = useSelector(authSelectors.selectIsLoggedIn); diff --git a/src/components/AppBar/Navigation.jsx b/src/components/AppBar/Navigation.jsx index 69f17ba..0775bcb 100644 --- a/src/components/AppBar/Navigation.jsx +++ b/src/components/AppBar/Navigation.jsx @@ -1,3 +1,6 @@ +import { useSelector } from 'react-redux'; +import { authSelectors } from '../../redux/auth/authSelectors'; + import { NavigationMenu, NavItem, @@ -5,15 +8,19 @@ import { } from 'components/AppBar/AppBar.styled'; export const Navigation = () => { + const isLoggedIn = useSelector(authSelectors.selectIsLoggedIn); + return ( Home - - Contacts - + {isLoggedIn && ( + + Contacts + + )} ); }; diff --git a/src/components/AppBar/UserMenu.jsx b/src/components/AppBar/UserMenu.jsx index eb38edc..3ee5918 100644 --- a/src/components/AppBar/UserMenu.jsx +++ b/src/components/AppBar/UserMenu.jsx @@ -1,5 +1,5 @@ import { useDispatch, useSelector } from 'react-redux'; -import authSelectors from '../../redux/auth/authSelectors'; +import { authSelectors } from '../../redux/auth/authSelectors'; import operations from '../../redux/auth/authOperations'; import { IconContext } from 'react-icons'; diff --git a/src/hooks/useAuth.js b/src/hooks/useAuth.js index 1d717c8..019e308 100644 --- a/src/hooks/useAuth.js +++ b/src/hooks/useAuth.js @@ -1,18 +1,12 @@ import { useSelector } from 'react-redux'; -import { - selectUser, - selectIsLoggedIn, - selectIsRefreshing, -} from '../redux/auth/selectors'; +import { authSelectors } from '../redux/auth/authSelectors'; export const useAuth = () => { - const isLoggedIn = useSelector(selectIsLoggedIn); - const isRefreshing = useSelector(selectIsRefreshing); - const user = useSelector(selectUser); + const isLoggedIn = useSelector(authSelectors.selectIsLoggedIn); + const user = useSelector(authSelectors.selectUserName); return { isLoggedIn, - isRefreshing, user, }; }; diff --git a/src/pages/HomePage/HomePage.jsx b/src/pages/HomePage/HomePage.jsx index 45d5777..9afb601 100644 --- a/src/pages/HomePage/HomePage.jsx +++ b/src/pages/HomePage/HomePage.jsx @@ -1,12 +1,12 @@ import { useSelector } from 'react-redux'; -import authSelectors from '../../redux/auth/authSelectors'; +import { authSelectors } from '../../redux/auth/authSelectors'; import { Title } from './HomePage.styled'; const HomePage = () => { const name = useSelector(authSelectors.selectUserName); - return Hello {name}; + return Wellcome to Our Application {name}; }; export default HomePage; diff --git a/src/pages/NotAuthPage/NotAuthPage.jsx b/src/pages/NotAuthPage/NotAuthPage.jsx new file mode 100644 index 0000000..2753290 --- /dev/null +++ b/src/pages/NotAuthPage/NotAuthPage.jsx @@ -0,0 +1,20 @@ +import { + NotAuthContainer, + Title, + Text, + StyledLink, +} from './NotAuthPage.styled'; + +const NotAuthPage = () => { + return ( + + Unauthorized user + You have profile + Log in + Register now + Register + + ); +}; + +export default NotAuthPage; diff --git a/src/pages/NotAuthPage/NotAuthPage.styled.jsx b/src/pages/NotAuthPage/NotAuthPage.styled.jsx new file mode 100644 index 0000000..5d76820 --- /dev/null +++ b/src/pages/NotAuthPage/NotAuthPage.styled.jsx @@ -0,0 +1,22 @@ +import styled from '@emotion/styled'; +import { NavLink } from 'react-router-dom'; + +export const NotAuthContainer = styled.div` + text-align: center; + background-color: #1dacd6; + padding: 20px; + border-radius: 4px; +`; + +export const Title = styled.h1` + font-size: 60px; +`; + +export const Text = styled.p` + font-size: 18px; +`; + +export const StyledLink = styled(NavLink)` + color: #000000; + font-size: 44px; +`; diff --git a/src/pages/NotFound/NotFound.styled.jsx b/src/pages/NotFound/NotFound.styled.jsx index 7827af4..f592b1e 100644 --- a/src/pages/NotFound/NotFound.styled.jsx +++ b/src/pages/NotFound/NotFound.styled.jsx @@ -3,7 +3,7 @@ import { NavLink } from 'react-router-dom'; export const ErrorContainer = styled.div` text-align: center; - background-color: #78a1bb; + background-color: #1dacd6; padding: 20px; border-radius: 4px; `; diff --git a/src/redux/auth/authSelectors.js b/src/redux/auth/authSelectors.js index 36762c9..160c542 100644 --- a/src/redux/auth/authSelectors.js +++ b/src/redux/auth/authSelectors.js @@ -2,9 +2,9 @@ const selectIsLoggedIn = state => state.auth.isLoggedIn; const selectUserName = state => state.auth.user.name; -const authSelectors = { +export const selectIsRefreshing = state => state.auth.isRefreshing; + +export const authSelectors = { selectIsLoggedIn, selectUserName, }; - -export default authSelectors; diff --git a/src/redux/auth/authSlice.js b/src/redux/auth/authSlice.js index 48c3222..c0f9ffd 100644 --- a/src/redux/auth/authSlice.js +++ b/src/redux/auth/authSlice.js @@ -5,6 +5,7 @@ const initialState = { user: { name: null, email: null }, token: null, isLoggedIn: false, + isRefreshing: false, }; const authSlice = createSlice({ @@ -27,9 +28,16 @@ const authSlice = createSlice({ state.token = null; state.isLoggedIn = false; }) + .addCase(operations.refreshUser.pending, state => { + state.isRefreshing = true; + }) .addCase(operations.refreshUser.fulfilled, (state, action) => { state.user = action.payload; state.isLoggedIn = true; + state.isRefreshing = false; + }) + .addCase(operations.refreshUser.rejected, state => { + state.isRefreshing = false; }); }, }); diff --git a/src/routes/PrivateRoute.js b/src/routes/PrivateRoute.js new file mode 100644 index 0000000..143e2ec --- /dev/null +++ b/src/routes/PrivateRoute.js @@ -0,0 +1,9 @@ +import { Navigate } from 'react-router-dom'; +import { useAuth } from '../hooks/useAuth'; + +export const PrivateRoute = ({ component: Component, redirectTo = '/' }) => { + const { isLoggedIn, isRefreshing } = useAuth(); + const shouldRedirect = !isLoggedIn && !isRefreshing; + + return shouldRedirect ? : Component; +};