diff --git a/client/.eslintrc.json b/client/.eslintrc.json index 932d693..5e87096 100644 --- a/client/.eslintrc.json +++ b/client/.eslintrc.json @@ -15,6 +15,7 @@ "semi": ["error", "never"], "no-unused-vars": "error", "no-undef": "error", + "no-trailing-spaces": "error", "no-console": ["error", { "allow": ["error"] }] } } diff --git a/client/src/common/auth/protectedpage/index.js b/client/src/common/auth/protectedpage/index.js new file mode 100644 index 0000000..9864ba0 --- /dev/null +++ b/client/src/common/auth/protectedpage/index.js @@ -0,0 +1,43 @@ +import { useEffect } from 'react' +import { useRouter } from 'next/router' +import { useAuth } from '@/lib/hooks/useAuth' + +import LoadingCover from '@/common/layout/loadingcover' + +/** + * HOC that listens for the Firebase user auth info from the global "user" redux states set by the useAuth() hook. + * Displays a loading cover page while waiting for the remote authentication info to settle in. + * Displays and returns the Component parameter if there is user data from the remote auth. + * Redirect to the /login page if there is no user info after the remote auth settles in. + * @param {Component} Component + * @returns {Component} (Component parameter or a Loading placeholder component) + * Usage: export default ProtectedPage(MyComponent) + */ +function ProtectedPage (Component) { + function AuthListener (props) { + const router = useRouter() + const { authLoading, authError, authUser } = useAuth() + + useEffect(() => { + if (!authLoading && !authUser) { + router.push('/login') + } + }, [authUser, authLoading, router]) + + const ItemComponent = () => { + if (authLoading) { + return + } else if (authUser) { + return + } else { + return + } + } + + return () + } + + return AuthListener +} + +export default ProtectedPage diff --git a/client/src/common/layout/header/index.js b/client/src/common/layout/header/index.js index 35fbf5a..6736cc9 100644 --- a/client/src/common/layout/header/index.js +++ b/client/src/common/layout/header/index.js @@ -1,8 +1,10 @@ // REACT import { useState } from 'react' +import { useDispatch } from 'react-redux' // NEXT import Link from 'next/link' +import { useRouter } from 'next/router' // MUI import AppBar from '@mui/material/AppBar' @@ -25,18 +27,37 @@ import HowToRegIcon from '@mui/icons-material/HowToReg' // LIB import { Avalon } from '@/lib/mui/theme' import { useSyncLocalStorage } from '@/lib/hooks/useSync' +import { useAuth } from '@/lib/hooks/useAuth' // VARIABLES const pages = ['about'] -const settings = ['Profile', 'Account', 'Dashboard', 'Logout'] +const settings = [ + { + name: 'Profile', + route: 'userProfile' + }, + { + name: 'Account', + route: '/' + }, + { + name: 'Dashboard', + route: 'dashboard' + }, + { + name: 'Logout', + route: '#' + } +] function Header() { // HOOKS const [anchorElNav, setAnchorElNav] = useState(null) const [anchorElUser, setAnchorElUser] = useState(null) - const [isLoggedIn] = useState(false) const [activeTheme, setActiveTheme] = useSyncLocalStorage('activeTheme') - + const { authUser, authSignOut } = useAuth() + const dispatch = useDispatch() + const router = useRouter() class eventsHandler { static themeHandler = () => { @@ -54,8 +75,11 @@ function Header() { static handleCloseUserMenu = () => { setAnchorElUser(null) } + static handleClickNavMenu = (route) => { + router.push(route) + } } - const {themeHandler, handleOpenNavMenu, handleOpenUserMenu, handleCloseNavMenu, handleCloseUserMenu} = eventsHandler + const {themeHandler, handleOpenNavMenu, handleOpenUserMenu, handleCloseNavMenu, handleCloseUserMenu, handleClickNavMenu} = eventsHandler return ( - {isLoggedIn + {(authUser !== null) ? @@ -177,11 +201,15 @@ function Header() { open={Boolean(anchorElUser)} onClose={handleCloseUserMenu} > - {settings.map((setting) => ( - - {setting} - - ))} + {settings.map((setting, id) => { + return (setting.name === 'Logout') + ? dispatch(authSignOut())}> + {setting.name} + + : handleClickNavMenu(setting.route)}> + {setting.name} + + })} : @@ -190,7 +218,7 @@ function Header() { }}> + } {errorMessage && - + } diff --git a/client/src/components/userProfile/index.js b/client/src/components/userProfile/index.js index 805f066..3b5e218 100644 --- a/client/src/components/userProfile/index.js +++ b/client/src/components/userProfile/index.js @@ -25,7 +25,7 @@ export const UserProfileComponent = ({state, eventsHandler}) => { backdropFilter:'contrast(120%)' }}> my Profile - { height:'100%' }} onClick={profilePictureHandler} - /> + /> @@ -60,7 +60,7 @@ export const UserProfileComponent = ({state, eventsHandler}) => { /> Email Address - { /> Contact No - { /> {state.profileChanged ? -