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