From b2a1b769aa5b1cb95084248fa554d9bbe988ce5f Mon Sep 17 00:00:00 2001 From: Yoan VALLET <ext.sopra.yvallet@grandlyon.com> Date: Wed, 27 May 2020 23:19:34 +0200 Subject: [PATCH] feat: use context for welcome modale --- .../ContainerComponents/Content/Content.tsx | 10 +++- .../ViewContainer/ViewContainer.tsx | 2 - .../WelcomeModalContainer.tsx | 52 +++---------------- .../Contexts/AppContextProvider.tsx | 34 +++++++++++- src/services/dataChallengeContracts.ts | 8 ++- src/services/userProfileDataManagerService.ts | 2 +- 6 files changed, 57 insertions(+), 51 deletions(-) diff --git a/src/components/ContainerComponents/Content/Content.tsx b/src/components/ContainerComponents/Content/Content.tsx index 339a57665..717da9b38 100644 --- a/src/components/ContainerComponents/Content/Content.tsx +++ b/src/components/ContainerComponents/Content/Content.tsx @@ -2,6 +2,7 @@ import React, { useContext } from 'react' import { AppContext } from 'components/Contexts/AppContextProvider' import { ScreenType } from 'enum/screen.enum' import SplashContainer from '../SplashContainer/SplashContainer' +import WelcomeModalContainer from '../WelcomeModalContainer/WelcomeModalContainer' interface ContentProps { children?: React.ReactNode @@ -14,13 +15,20 @@ const Content: React.FC<ContentProps> = ({ height = 0, background = 'inherit', }: ContentProps) => { - const { isContextLoaded, screenType } = useContext(AppContext) + const { + isContextLoaded, + screenType, + userProfile, + setWelcomeModalViewed, + } = useContext(AppContext) const cozyBarHeight = 48 const cozyNavHeight = 56 return ( <> {!isContextLoaded ? ( <SplashContainer /> + ) : userProfile && !userProfile.haveSeenWelcomeModal ? ( + <WelcomeModalContainer handleClose={setWelcomeModalViewed} /> ) : ( <div className="content-view" diff --git a/src/components/ContainerComponents/ViewContainer/ViewContainer.tsx b/src/components/ContainerComponents/ViewContainer/ViewContainer.tsx index 0ed47c2b0..84cc1c60d 100644 --- a/src/components/ContainerComponents/ViewContainer/ViewContainer.tsx +++ b/src/components/ContainerComponents/ViewContainer/ViewContainer.tsx @@ -18,7 +18,6 @@ import OngoingChallengeDetailsViewContainer from './OngoingChallengeDetailsViewC import LockedChallengeDetailsViewContainer from './LockedChallengeDetailsViewContainer' import AvailableChallengeDetailsViewContainer from './AvailableChallengeDetailsViewContainer' import SplashContainer from 'components/ContainerComponents/SplashContainer/SplashContainer' -import WelcomeModalContainer from '../WelcomeModalContainer/WelcomeModalContainer' export const history = createBrowserHistory() @@ -28,7 +27,6 @@ export const ViewContainer = () => { <Layout> <AppContextProvider> <Navbar /> - <WelcomeModalContainer /> <Main> <Content className="app-content"> <ScrollToTop> diff --git a/src/components/ContainerComponents/WelcomeModalContainer/WelcomeModalContainer.tsx b/src/components/ContainerComponents/WelcomeModalContainer/WelcomeModalContainer.tsx index be5d6aaea..9acb93382 100644 --- a/src/components/ContainerComponents/WelcomeModalContainer/WelcomeModalContainer.tsx +++ b/src/components/ContainerComponents/WelcomeModalContainer/WelcomeModalContainer.tsx @@ -1,66 +1,28 @@ -import React, { useState, useEffect } from 'react' +import React from 'react' +import { withClient, Client } from 'cozy-client' import Modal from 'components/CommonKit/Modal/Modal' import StyledButton from 'components/CommonKit/Button/StyledButton' import { translate } from 'cozy-ui/react/I18n' -import { withClient, Client } from 'cozy-client' -import { USERPROFILE_DOCTYPE } from 'doctypes' import useInstanceSettings from 'components/Hooks/userInstanceSettings' interface WelcomeModalContainerProps { + handleClose: () => void t: Function client: Client } const WelcomeModalContainer: React.FC<WelcomeModalContainerProps> = ({ + handleClose, t, client, }: WelcomeModalContainerProps) => { - const [modalOpen, setModalOpen] = useState<boolean>(false) - const [modalExist, setModalExist] = useState<boolean>(false) - const { data: instanceSettings } = useInstanceSettings(client) - async function updateWelcomeModalState() { - await client - .query(client.find(USERPROFILE_DOCTYPE).limitBy(1)) - .then(async ({ data }) => { - const doc = data[0] - await client.save({ - ...doc, - haveSeenWelcomeModal: true, - }) - }) - } - - const handleCloseClick = () => { - setModalOpen(false) - updateWelcomeModalState() - } - - useEffect(() => { - async function getWelcomeModalState() { - await client - .query(client.find(USERPROFILE_DOCTYPE).limitBy(1)) - .then(async ({ data }) => { - const welcomeModalState = data[0].haveSeenWelcomeModal - if (!welcomeModalState) { - setModalExist(true) - } - }) - } - getWelcomeModalState() - }, []) - - useEffect(() => { - if (modalExist) { - setModalOpen(true) - } - }, [modalExist]) return ( <React.Fragment> <Modal - open={modalOpen} - handleCloseClick={handleCloseClick} + open={true} + handleCloseClick={handleClose} yellowBorder="yellow-border" > <div className="wm-header text-24-bold"> @@ -78,7 +40,7 @@ const WelcomeModalContainer: React.FC<WelcomeModalContainerProps> = ({ <div className="wm-connect text-18-bold"> {t('COMMON.WELCOME_MODAL_CONNECT')} </div> - <StyledButton className="button-ok" onClick={handleCloseClick}> + <StyledButton className="button-ok" onClick={handleClose}> {t('COMMON.WELCOME_MODAL_OK')} </StyledButton> </Modal> diff --git a/src/components/Contexts/AppContextProvider.tsx b/src/components/Contexts/AppContextProvider.tsx index 7df2fdd39..dfc788f47 100644 --- a/src/components/Contexts/AppContextProvider.tsx +++ b/src/components/Contexts/AppContextProvider.tsx @@ -4,7 +4,8 @@ import { FluidType } from 'enum/fluid.enum' import { ScreenType } from 'enum/screen.enum' import InitDataManager from 'services/initDataManagerService' -import { UserChallenge } from 'services/dataChallengeContracts' +import UserProfileDataManager from 'services/userProfileDataManagerService' +import { UserChallenge, UserProfile } from 'services/dataChallengeContracts' interface AppContextProps { isIndexesLoading: boolean @@ -23,6 +24,8 @@ interface AppContextProps { isContextLoaded: boolean isError: boolean screenType: ScreenType + userProfile: UserProfile | null + setWelcomeModalViewed: Function } export const AppContext = React.createContext<AppContextProps>({ @@ -42,6 +45,8 @@ export const AppContext = React.createContext<AppContextProps>({ isContextLoaded: false, isError: false, screenType: ScreenType.MOBILE, + userProfile: null, + setWelcomeModalViewed: () => null, }) interface AppContextProviderProps { @@ -89,6 +94,7 @@ const AppContextProvider: React.FC<AppContextProviderProps> = ({ const [isContextLoaded, setContextLoaded] = useState<boolean>(false) const [isError, setError] = useState<boolean>(false) const [screenType, setScreenType] = useState<ScreenType>(ScreenType.MOBILE) + const [userProfile, setUserProfile] = useState<UserProfile | null>(null) const defineScreenType = () => { if (screen.width <= 768) { @@ -118,6 +124,16 @@ const AppContextProvider: React.FC<AppContextProviderProps> = ({ } } + const setWelcomeModalViewed = async () => { + const upm = new UserProfileDataManager(client) + const updatedUserProfile = await upm.updateUserProfile({ + haveSeenWelcomeModal: true, + }) + if (updatedUserProfile) { + setUserProfile(updatedUserProfile) + } + } + const refreshCurrentChallenge = async (): Promise<boolean> => { const im = new InitDataManager(client) try { @@ -150,6 +166,7 @@ const AppContextProvider: React.FC<AppContextProviderProps> = ({ handleResize() window.addEventListener('resize', handleResize) const im = new InitDataManager(client) + const updm = new UserProfileDataManager(client) async function loadData() { // Create missing indexes setIndexesLoading(true) @@ -221,6 +238,19 @@ const AppContextProvider: React.FC<AppContextProviderProps> = ({ } finally { setCurrentChallengeUpdateLoading(false) } + + //Retrieve the UserProfile + const loadedUserProfile = await updm.getUserProfile() + if (!loadedUserProfile) { + setError(true) + } + if (subscribed && loadedUserProfile) { + console.log( + '%c Context: UserProfile Loaded', + 'background: #222; color: white' + ) + setUserProfile(loadedUserProfile) + } } loadData() return () => { @@ -268,6 +298,8 @@ const AppContextProvider: React.FC<AppContextProviderProps> = ({ isContextLoaded, isError, screenType, + userProfile, + setWelcomeModalViewed, }} > {children} diff --git a/src/services/dataChallengeContracts.ts b/src/services/dataChallengeContracts.ts index 2d4739759..1300951bc 100644 --- a/src/services/dataChallengeContracts.ts +++ b/src/services/dataChallengeContracts.ts @@ -137,17 +137,20 @@ export class UserProfile { level: number challengeTypeHash: string ecogestureHash: string + haveSeenWelcomeModal: boolean constructor( id: string, level: number, challengeTypeHash: string, - ecogestureHash: string + ecogestureHash: string, + haveSeenWelcomeModal: boolean ) { this.id = id this.level = level this.challengeTypeHash = challengeTypeHash this.ecogestureHash = ecogestureHash + this.haveSeenWelcomeModal = haveSeenWelcomeModal } } @@ -181,4 +184,7 @@ export interface IChallengeManager { // eslint-disable-next-line @typescript-eslint/interface-name-prefix export interface IUserProfileManager { getUserProfile(): Promise<UserProfile | null> + updateUserProfile(attributes: { + [key: string]: string + }): Promise<UserProfile | null> } diff --git a/src/services/userProfileDataManagerService.ts b/src/services/userProfileDataManagerService.ts index 8e18fa014..8364ec1be 100644 --- a/src/services/userProfileDataManagerService.ts +++ b/src/services/userProfileDataManagerService.ts @@ -21,7 +21,7 @@ export default class UserProfileManager implements IUserProfileManager { } public async updateUserProfile(attributes: { - [key: string]: string + [key: string]: string | boolean }): Promise<UserProfile | null> { const { data: userProfile } = await this._client .query(this._client.find(USERPROFILE_DOCTYPE).limitBy(1)) -- GitLab