From fccedac8f2e42d40922f6039f2f9fc8b55cebe9b Mon Sep 17 00:00:00 2001 From: Mateusz Tylka Date: Fri, 2 Jun 2023 12:13:05 +0200 Subject: [PATCH] App component structure refactor --- src/App.js | 232 ------------------ src/App/App.js | 33 +++ src/App/components/NavigationManager.js | 47 ++++ src/App/components/PopUpMessageManager.js | 41 ++++ src/App/components/RoutingManager.js | 108 ++++++++ src/App/functions/startApp.js | 29 +++ src/App/functions/startManage.js | 55 +++++ src/App/index.js | 1 + .../EntireScreenLoadingStyle.js | 14 ++ .../EntrieScreenLoading.js | 13 + .../generic/EntireScreenLoading/index.js | 0 src/components/generic/Logo.js | 25 +- src/components/navigation/NavBar/NavBar.js | 95 +++---- src/pages/LandingPage/LandingPage.js | 34 ++- src/utils/globals.js | 10 + 15 files changed, 439 insertions(+), 298 deletions(-) delete mode 100644 src/App.js create mode 100644 src/App/App.js create mode 100644 src/App/components/NavigationManager.js create mode 100644 src/App/components/PopUpMessageManager.js create mode 100644 src/App/components/RoutingManager.js create mode 100644 src/App/functions/startApp.js create mode 100644 src/App/functions/startManage.js create mode 100644 src/App/index.js create mode 100644 src/components/generic/EntireScreenLoading/EntireScreenLoadingStyle.js create mode 100644 src/components/generic/EntireScreenLoading/EntrieScreenLoading.js create mode 100644 src/components/generic/EntireScreenLoading/index.js diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 5a0c690..0000000 --- a/src/App.js +++ /dev/null @@ -1,232 +0,0 @@ -import { ThemeProvider } from 'styled-components'; -import theme from './utils/theme'; -import LandingPage from './pages/LandingPage'; -import Challenges from './pages/Challanges/Challenges'; -import { BrowserRouter, Route, Routes } from 'react-router-dom'; -import NavBar from './components/navigation/NavBar'; -import { - CHALLENGE_PAGE, - CHALLENGES_PAGE, - IS_MOBILE, - POLICY_PRIVACY_PAGE, - LOGIN_REQUIRED_PAGES, - ROOT_URL, - CHALLENGE_SECTIONS, -} from './utils/globals'; -import KeyCloakService from './services/KeyCloakService'; -import React from 'react'; -import LoggedBar from './components/navigation/LoggedBar'; -import addUser from './api/addUser'; -import Loading from './components/generic/Loading'; -import { FlexColumn } from './utils/containers'; -import PopupMessage from './components/generic/PopupMessage'; -import PolicyPrivacy from './pages/PolicyPrivacy'; -import Challenge from './pages/Challenge'; -import SESSION_STORAGE from './utils/sessionStorage'; - -const App = () => { - const [loggedBarVisible, setLoggedBarVisible] = React.useState('100vw'); - const [loggedBarHover, setLoggedBarHover] = React.useState(false); - const [popUpHeader, setPopUpHeader] = React.useState(''); - const [popUpMessage, setPopUpMessage] = React.useState(''); - const [confirmPopUpHandler, setConfirmPopUpHandler] = React.useState(null); - - React.useMemo(() => { - if ( - sessionStorage.getItem(SESSION_STORAGE.LOGOUT) === - SESSION_STORAGE.STATIC_VALUE.YES - ) { - const pageName = window.location.pathname.split('/').at(-1); - if (LOGIN_REQUIRED_PAGES.includes(pageName)) { - window.location.replace(`${ROOT_URL}/challenges`); - } - } - - if ( - sessionStorage.getItem(SESSION_STORAGE.LOGGED) !== - SESSION_STORAGE.STATIC_VALUE.YES - ) { - if (KeyCloakService.isLoggedIn()) { - sessionStorage.setItem( - SESSION_STORAGE.LOGGED, - SESSION_STORAGE.STATIC_VALUE.YES - ); - addUser(); - } - } - - if ( - sessionStorage.getItem(SESSION_STORAGE.LOGGED) === - SESSION_STORAGE.STATIC_VALUE.YES && - (window.location.pathname === `${POLICY_PRIVACY_PAGE}/login` || - window.location.pathname === `${POLICY_PRIVACY_PAGE}/register`) - ) { - window.location.replace(`${ROOT_URL}/challenges`); - } - - setTimeout(() => { - if ( - sessionStorage.getItem(SESSION_STORAGE.LOGGED) === - SESSION_STORAGE.STATIC_VALUE.YES - ) { - if (!KeyCloakService.isLoggedIn()) { - KeyCloakService.doLogin(); - } - } - }, 1500); - }, []); - - const popUpMessageHandler = (header, message, confirmHandler) => { - setPopUpHeader(header); - setPopUpMessage(message); - if (confirmHandler !== null && confirmHandler !== undefined) { - setConfirmPopUpHandler(() => confirmHandler()); - } else { - setConfirmPopUpHandler(null); - } - }; - - const popUpMessageRender = () => { - if (popUpHeader !== '' || popUpMessage !== '') { - return ( - - ); - } - }; - - const loggedBarVisibleHandler = React.useCallback(() => { - if (loggedBarVisible === '0' && !loggedBarHover) - setLoggedBarVisible('100vw'); - else setLoggedBarVisible('0'); - }, [loggedBarHover, loggedBarVisible]); - - const renderApp = () => { - return ( - - - {popUpMessageRender()} - - {!IS_MOBILE() && ( - setLoggedBarHover(true)} - loggedBarHoverFalse={() => setLoggedBarHover(false)} - username={KeyCloakService.getUsername()} - /> - )} - - } - /> - } - /> - } - /> - } - /> - - } - /> - } - /> - } - /> - } /> - - } - /> - - } - /> - - } - /> - {KeyCloakService.isLoggedIn() ? ( - <> - } /> - } /> - - ) : ( - <> - - } - /> - - } - /> - - )} - - - - ); - }; - - if ( - sessionStorage.getItem(SESSION_STORAGE.LOGGED) === - SESSION_STORAGE.STATIC_VALUE.YES - ) { - if (KeyCloakService.isLoggedIn()) { - return renderApp(); - } else { - return ( - - - - - - ); - } - } else { - return renderApp(); - } -}; - -export default App; diff --git a/src/App/App.js b/src/App/App.js new file mode 100644 index 0000000..76873fc --- /dev/null +++ b/src/App/App.js @@ -0,0 +1,33 @@ +import React from 'react'; +import { ThemeProvider } from 'styled-components'; +import theme from '../utils/theme'; +import PopUpMessageManager from './components/PopUpMessageManager'; +import RoutingManager from './components/RoutingManager'; +import NavigationManager from './components/NavigationManager'; +import { BrowserRouter } from 'react-router-dom'; +import startManage from './functions/startManage'; +import startApp from './functions/startApp'; + +const App = () => { + React.useMemo(() => { + startManage(); + }, []); + + const renderApp = React.useCallback(() => { + return ( + + + + + + + + + + ); + }, []); + + return startApp(renderApp); +}; + +export default App; diff --git a/src/App/components/NavigationManager.js b/src/App/components/NavigationManager.js new file mode 100644 index 0000000..fd70a49 --- /dev/null +++ b/src/App/components/NavigationManager.js @@ -0,0 +1,47 @@ +import React from 'react'; +import NavBar from '../../components/navigation/NavBar/NavBar'; +import LoggedBar from '../../components/navigation/LoggedBar'; +import KeyCloakService from '../../services/KeyCloakService'; +import { CHILDREN_WITH_PROPS, IS_MOBILE } from '../../utils/globals'; + +const NavigationManager = (props) => { + const [loggedBarVisible, setLoggedBarVisible] = React.useState('100vw'); + const [loggedBarHover, setLoggedBarHover] = React.useState(false); + const [navOptions, setNavOptions] = React.useState(true); + + const loggedBarVisibleHandler = React.useCallback(() => { + if (loggedBarVisible === '0' && !loggedBarHover) + setLoggedBarVisible('100vw'); + else setLoggedBarVisible('0'); + }, [loggedBarHover, loggedBarVisible]); + + const hideNavOptions = React.useCallback(() => { + setNavOptions(false); + }, []); + + const showNavOptions = React.useCallback(() => { + setNavOptions(true); + }, []); + + return ( + <> + + {!IS_MOBILE() && ( + setLoggedBarHover(true)} + loggedBarHoverFalse={() => setLoggedBarHover(false)} + username={KeyCloakService.getUsername()} + /> + )} + {CHILDREN_WITH_PROPS(props.children, { hideNavOptions, showNavOptions })} + + ); +}; + +export default NavigationManager; diff --git a/src/App/components/PopUpMessageManager.js b/src/App/components/PopUpMessageManager.js new file mode 100644 index 0000000..e8f3ed8 --- /dev/null +++ b/src/App/components/PopUpMessageManager.js @@ -0,0 +1,41 @@ +import React from 'react'; +import PopupMessage from '../../components/generic/PopupMessage'; +import { CHILDREN_WITH_PROPS } from '../../utils/globals'; + +const PopUpMessageManager = (props) => { + const [popUpHeader, setPopUpHeader] = React.useState(''); + const [popUpMessage, setPopUpMessage] = React.useState(''); + const [confirmPopUpHandler, setConfirmPopUpHandler] = React.useState(null); + + const popUpMessageHandler = (header, message, confirmHandler) => { + setPopUpHeader(header); + setPopUpMessage(message); + if (confirmHandler !== null && confirmHandler !== undefined) { + setConfirmPopUpHandler(() => confirmHandler()); + } else { + setConfirmPopUpHandler(null); + } + }; + + const popUpMessageRender = () => { + if (popUpHeader !== '' || popUpMessage !== '') { + return ( + + ); + } + }; + + return ( + <> + {popUpMessageRender()} + {CHILDREN_WITH_PROPS(props.children, { popUpMessageHandler })} + + ); +}; + +export default PopUpMessageManager; diff --git a/src/App/components/RoutingManager.js b/src/App/components/RoutingManager.js new file mode 100644 index 0000000..6d4d942 --- /dev/null +++ b/src/App/components/RoutingManager.js @@ -0,0 +1,108 @@ +import { Route, Routes } from 'react-router-dom'; +import { + CHALLENGES_PAGE, + CHALLENGE_PAGE, + CHALLENGE_SECTIONS, + POLICY_PRIVACY_PAGE, +} from '../../utils/globals'; +import Challenge from '../../pages/Challenge'; +import Challenges from '../../pages/Challanges'; +import PolicyPrivacy from '../../pages/PolicyPrivacy'; +import LandingPage from '../../pages/LandingPage'; +import KeyCloakService from '../../services/KeyCloakService'; + +const RoutingManager = (props) => { + return ( + + } + /> + } + /> + } + /> + } + /> + + } + /> + } + /> + } + /> + } /> + + } + /> + + } + /> + + } + /> + {KeyCloakService.isLoggedIn() ? ( + <> + } /> + } /> + + ) : ( + <> + + } + /> + + } + /> + + )} + + ); +}; + +export default RoutingManager; diff --git a/src/App/functions/startApp.js b/src/App/functions/startApp.js new file mode 100644 index 0000000..0208b5c --- /dev/null +++ b/src/App/functions/startApp.js @@ -0,0 +1,29 @@ +import Loading from '../../components/generic/Loading'; +import { FlexColumn } from '../../utils/containers'; +import SESSION_STORAGE from '../../utils/sessionStorage'; +import KeyCloakService from '../../services/KeyCloakService'; +import { ThemeProvider } from 'styled-components'; +import theme from '../../utils/theme'; + +const startApp = (renderApp) => { + if ( + sessionStorage.getItem(SESSION_STORAGE.LOGGED) === + SESSION_STORAGE.STATIC_VALUE.YES + ) { + if (KeyCloakService.isLoggedIn()) { + return renderApp(); + } else { + return ( + + + + + + ); + } + } else { + return renderApp(); + } +}; + +export default startApp; diff --git a/src/App/functions/startManage.js b/src/App/functions/startManage.js new file mode 100644 index 0000000..d1fdfae --- /dev/null +++ b/src/App/functions/startManage.js @@ -0,0 +1,55 @@ +import { + POLICY_PRIVACY_PAGE, + LOGIN_REQUIRED_PAGES, + ROOT_URL, +} from '../../utils/globals'; +import addUser from '../../api/addUser'; +import SESSION_STORAGE from '../../utils/sessionStorage'; +import KeyCloakService from '../../services/KeyCloakService'; + +const startManage = () => { + if ( + sessionStorage.getItem(SESSION_STORAGE.LOGOUT) === + SESSION_STORAGE.STATIC_VALUE.YES + ) { + const pageName = window.location.pathname.split('/').at(-1); + if (LOGIN_REQUIRED_PAGES.includes(pageName)) { + window.location.replace(`${ROOT_URL}/challenges`); + } + } + + if ( + sessionStorage.getItem(SESSION_STORAGE.LOGGED) !== + SESSION_STORAGE.STATIC_VALUE.YES + ) { + if (KeyCloakService.isLoggedIn()) { + sessionStorage.setItem( + SESSION_STORAGE.LOGGED, + SESSION_STORAGE.STATIC_VALUE.YES + ); + addUser(); + } + } + + if ( + sessionStorage.getItem(SESSION_STORAGE.LOGGED) === + SESSION_STORAGE.STATIC_VALUE.YES && + (window.location.pathname === `${POLICY_PRIVACY_PAGE}/login` || + window.location.pathname === `${POLICY_PRIVACY_PAGE}/register`) + ) { + window.location.replace(`${ROOT_URL}/challenges`); + } + + setTimeout(() => { + if ( + sessionStorage.getItem(SESSION_STORAGE.LOGGED) === + SESSION_STORAGE.STATIC_VALUE.YES + ) { + if (!KeyCloakService.isLoggedIn()) { + KeyCloakService.doLogin(); + } + } + }, 1500); +}; + +export default startManage; diff --git a/src/App/index.js b/src/App/index.js new file mode 100644 index 0000000..9122fa1 --- /dev/null +++ b/src/App/index.js @@ -0,0 +1 @@ +export { default } from './App'; diff --git a/src/components/generic/EntireScreenLoading/EntireScreenLoadingStyle.js b/src/components/generic/EntireScreenLoading/EntireScreenLoadingStyle.js new file mode 100644 index 0000000..42a20a8 --- /dev/null +++ b/src/components/generic/EntireScreenLoading/EntireScreenLoadingStyle.js @@ -0,0 +1,14 @@ +import styled from 'styled-components'; +import { FlexColumn } from '../../../utils/containers'; + +const EntireScreenLoadingStyle = styled(FlexColumn)` + width: 100%; + height: 100vh; + z-index: 1000; + position: fixed; + top: 0; + left: 0; + background-color: ${({ theme }) => theme.colors.white}; +`; + +export default EntireScreenLoadingStyle; diff --git a/src/components/generic/EntireScreenLoading/EntrieScreenLoading.js b/src/components/generic/EntireScreenLoading/EntrieScreenLoading.js new file mode 100644 index 0000000..b67c2c3 --- /dev/null +++ b/src/components/generic/EntireScreenLoading/EntrieScreenLoading.js @@ -0,0 +1,13 @@ +import React from 'react'; +import EntireScreenLoadingStyle from './EntireScreenLoadingStyle'; +import Loading from '../Loading'; + +const EntireScreenLoading = () => { + return ( + + + + ); +}; + +export default EntireScreenLoading; diff --git a/src/components/generic/EntireScreenLoading/index.js b/src/components/generic/EntireScreenLoading/index.js new file mode 100644 index 0000000..e69de29 diff --git a/src/components/generic/Logo.js b/src/components/generic/Logo.js index e21232b..aee18b4 100644 --- a/src/components/generic/Logo.js +++ b/src/components/generic/Logo.js @@ -1,24 +1,29 @@ import React from 'react'; -import {H1} from '../../utils/fonts'; +import { H1 } from '../../utils/fonts'; import theme from '../../utils/theme'; -import {Link} from 'react-router-dom'; +import { Link } from 'react-router-dom'; import styled from 'styled-components'; const LogoStyle = styled(H1)` font-size: 24px; - @media (min-width: ${({theme}) => theme.overMobile}) { + @media (min-width: ${({ theme }) => theme.overMobile}) { font-size: 32px; line-height: 32px; } `; -const Logo = () => { - return ( - - Gonito - - ); +const Logo = (props) => { + return ( + + Gonito + + ); }; -export default Logo; \ No newline at end of file +export default Logo; diff --git a/src/components/navigation/NavBar/NavBar.js b/src/components/navigation/NavBar/NavBar.js index fd992ca..697fa79 100644 --- a/src/components/navigation/NavBar/NavBar.js +++ b/src/components/navigation/NavBar/NavBar.js @@ -43,6 +43,7 @@ const NavBar = (props) => { const mobileMenuHoverFalse = () => { setMobileMenuHover(false); }; + const toggleNavMenu = () => { if (navMenuTranslateY === 'calc(-100vh - 42px)') setNavMenuTranslateY('0'); else if (!mobileMenuHover) setNavMenuTranslateY('calc(-100vh - 42px)'); @@ -51,51 +52,57 @@ const NavBar = (props) => { return ( - - - - - - Challenges - - - - Privacy policy - - {!KeyCloakService.isLoggedIn() ? ( - - props.popUpMessageHandler( - 'Reminder', - 'Remember to check your spam mailbox to confirm your account.', - () => KeyCloakService.doRegister - ) - } - gap="16px" - > - - Register + + {props.navOptions && ( + <> + + + + + Challenges + + + + Privacy policy + + {!KeyCloakService.isLoggedIn() && ( + + props.popUpMessageHandler( + 'Reminder', + 'Remember to check your spam mailbox to confirm your account.', + () => KeyCloakService.doRegister + ) + } + gap="16px" + > + + Register + + )} + {KeyCloakService.isLoggedIn() ? ( + + ) : ( + + + Sign in + + )} - ) : ( - '' - )} - {KeyCloakService.isLoggedIn() ? ( - - ) : ( - - - Sign in - - )} - + + )} { - return ( - - - - - - - - - - ); + const [show, setShow] = React.useState(false); + + React.useEffect(() => { + setTimeout(() => { + setShow(true); + }, 1000); + }, []); + + if (show) { + return ( + + + + + + + + + + ); + } else return ; }; export default LandingPage; diff --git a/src/utils/globals.js b/src/utils/globals.js index 3b478f4..2ae03c2 100644 --- a/src/utils/globals.js +++ b/src/utils/globals.js @@ -6,6 +6,7 @@ import cupIco from '../assets/cup_ico.svg'; import textIco from '../assets/text_ico.svg'; import imageIco from '../assets/image_ico.svg'; import tabularIco from '../assets/tabular_ico.svg'; +import React from 'react'; const ELEMENTS_PER_PAGE = 12; const MINI_DESCRIPTION_LENGTH = 70; @@ -119,6 +120,14 @@ const IS_MOBILE = () => { return document.body.clientWidth <= 1024; }; +const CHILDREN_WITH_PROPS = (propsChildren, props) => + React.Children.map(propsChildren, (child) => { + if (React.isValidElement(child)) { + return React.cloneElement(child, props); + } + return child; + }); + export { ELEMENTS_PER_PAGE, API, @@ -142,4 +151,5 @@ export { EVALUATIONS_FORMAT, PREVIOUS_PAGE, NEXT_PAGE, + CHILDREN_WITH_PROPS, };