From 8653ef400d1ec2b055bda8b65af894ea8730e2f7 Mon Sep 17 00:00:00 2001
From: "guilhem.carron" <gcarron@grandlyon.com>
Date: Wed, 15 Sep 2021 16:39:56 +0200
Subject: [PATCH] Change Terms and CGU to modal

---
 .../LegalNotice/legalNoticeLink.scss          |  3 +-
 .../LegalNotice/legalNoticeView.scss          |  2 +-
 src/components/Routes/Routes.tsx              |  6 --
 src/components/Terms/CGUModal.tsx             | 55 +++++++++++++++++++
 .../{CGUPublic.spec.tsx => CGUModalspec.tsx}  |  8 ++-
 src/components/Terms/CGUPublic.tsx            | 15 -----
 .../Terms/DataShareConsentContent.spec.tsx    |  8 +--
 ...lic.spec.tsx => LegalNoticeModal.spec.tsx} |  8 ++-
 src/components/Terms/LegalNoticeModal.tsx     | 54 ++++++++++++++++++
 src/components/Terms/LegalNoticePublic.tsx    | 15 -----
 src/components/Terms/TermsView.tsx            | 26 ++++++++-
 .../__snapshots__/CGUPublic.spec.tsx.snap     |  3 -
 .../DataShareConsentContent.spec.tsx.snap     |  4 +-
 .../LegalNoticeModal.spec.tsx.snap            |  8 +++
 .../LegalNoticePublic.spec.tsx.snap           |  3 -
 src/components/Terms/termsView.scss           |  9 +++
 src/locales/fr.json                           |  9 ++-
 src/utils/decoreText.tsx                      | 14 ++++-
 18 files changed, 186 insertions(+), 64 deletions(-)
 create mode 100644 src/components/Terms/CGUModal.tsx
 rename src/components/Terms/{CGUPublic.spec.tsx => CGUModalspec.tsx} (63%)
 delete mode 100644 src/components/Terms/CGUPublic.tsx
 rename src/components/Terms/{LegalNoticePublic.spec.tsx => LegalNoticeModal.spec.tsx} (59%)
 create mode 100644 src/components/Terms/LegalNoticeModal.tsx
 delete mode 100644 src/components/Terms/LegalNoticePublic.tsx
 delete mode 100644 src/components/Terms/__snapshots__/CGUPublic.spec.tsx.snap
 create mode 100644 src/components/Terms/__snapshots__/LegalNoticeModal.spec.tsx.snap
 delete mode 100644 src/components/Terms/__snapshots__/LegalNoticePublic.spec.tsx.snap

diff --git a/src/components/LegalNotice/legalNoticeLink.scss b/src/components/LegalNotice/legalNoticeLink.scss
index 56b8e1e7b..6998b06d0 100644
--- a/src/components/LegalNotice/legalNoticeLink.scss
+++ b/src/components/LegalNotice/legalNoticeLink.scss
@@ -14,7 +14,8 @@
     margin-bottom: 1.25rem;
   }
   .legal-notice-content {
-    width: 45.75rem;
+    max-width: 45.75rem;
+
     @media #{$large-phone} {
       width: 100%;
     }
diff --git a/src/components/LegalNotice/legalNoticeView.scss b/src/components/LegalNotice/legalNoticeView.scss
index b42dc7c02..232c4f03e 100644
--- a/src/components/LegalNotice/legalNoticeView.scss
+++ b/src/components/LegalNotice/legalNoticeView.scss
@@ -44,7 +44,7 @@
     .ln-contact {
       color: $multi-color;
     }
-    width: 45.75rem;
+    max-width: 45.75rem;
     @media #{$large-phone} {
       width: 100%;
     }
diff --git a/src/components/Routes/Routes.tsx b/src/components/Routes/Routes.tsx
index 5072f8292..0db7952b9 100644
--- a/src/components/Routes/Routes.tsx
+++ b/src/components/Routes/Routes.tsx
@@ -28,18 +28,12 @@ const ProfileTypeView = lazy(() =>
   import('components/ProfileType/ProfileTypeView')
 )
 const TermsView = lazy(() => import('components/Terms/TermsView'))
-const LegalNoticePublic = lazy(() =>
-  import('components/Terms/LegalNoticePublic')
-)
-const CGUPublic = lazy(() => import('components/Terms/CGUPublic'))
 
 const Routes = () => {
   return (
     <Suspense fallback={<div></div>}>
       <Switch>
         <Route path="/terms" component={TermsView} />
-        <Route path="/legal" component={LegalNoticePublic} />
-        <Route path="/cgu" component={CGUPublic} />
         <PrivateRoute
           path="/consumption"
           render={({ match: { url } }) => (
diff --git a/src/components/Terms/CGUModal.tsx b/src/components/Terms/CGUModal.tsx
new file mode 100644
index 000000000..4c8fdbd4e
--- /dev/null
+++ b/src/components/Terms/CGUModal.tsx
@@ -0,0 +1,55 @@
+import GCUContent from 'components/GCU/GCUContent'
+import React from 'react'
+import './termsView.scss'
+import Dialog from '@material-ui/core/Dialog'
+import { Button, IconButton } from '@material-ui/core'
+import Icon from 'cozy-ui/transpiled/react/Icon'
+import { useI18n } from 'cozy-ui/transpiled/react/I18n'
+import CloseIcon from 'assets/icons/ico/close.svg'
+
+interface CGUModalProps {
+  open: boolean
+  handleCloseClick: () => void
+}
+const CGUModal: React.FC<CGUModalProps> = ({
+  open,
+  handleCloseClick,
+}: CGUModalProps) => {
+  const { t } = useI18n()
+  return (
+    <Dialog
+      open={open}
+      onClose={handleCloseClick}
+      aria-labelledby={'accessibility-title'}
+      classes={{
+        root: 'modal-root',
+        paper: 'modal-paper',
+      }}
+    >
+      <div id={'accessibility-title'}>
+        {t('feedback.accessibility.window_title')}
+      </div>
+      <IconButton
+        aria-label={t('feedback.accessibility.button_close')}
+        className="modal-paper-close-button"
+        onClick={handleCloseClick}
+      >
+        <Icon icon={CloseIcon} size={16} />
+      </IconButton>
+      <GCUContent />
+      <Button
+        aria-label={t('gcu_modal.accessibility.button_accept')}
+        onClick={handleCloseClick}
+        className="gcu-modal-button"
+        classes={{
+          root: 'btn-profile-next rounded',
+          label: 'text-16-bold',
+        }}
+      >
+        {t('legal.accessibility.button_close')}
+      </Button>
+    </Dialog>
+  )
+}
+
+export default CGUModal
diff --git a/src/components/Terms/CGUPublic.spec.tsx b/src/components/Terms/CGUModalspec.tsx
similarity index 63%
rename from src/components/Terms/CGUPublic.spec.tsx
rename to src/components/Terms/CGUModalspec.tsx
index fc20cf9e0..942fb2ac2 100644
--- a/src/components/Terms/CGUPublic.spec.tsx
+++ b/src/components/Terms/CGUModalspec.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import { mount } from 'enzyme'
-import CGUPublic from './CGUPublic'
+import CGUModal from './CGUModal'
 
 jest.mock('cozy-ui/transpiled/react/I18n', () => {
   return {
@@ -12,9 +12,11 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
   }
 })
 
-describe('CGUPublic component', () => {
+describe('CGUModal component', () => {
   it('should be rendered correctly', () => {
-    const component = mount(<CGUPublic />).getElement()
+    const component = mount(
+      <CGUModal open={true} handleCloseClick={jest.fn()} />
+    ).getElement()
     expect(component).toMatchSnapshot()
   })
 })
diff --git a/src/components/Terms/CGUPublic.tsx b/src/components/Terms/CGUPublic.tsx
deleted file mode 100644
index 98d157c31..000000000
--- a/src/components/Terms/CGUPublic.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import GCUContent from 'components/GCU/GCUContent'
-import React from 'react'
-import './termsView.scss'
-
-const CGUPublic: React.FC = () => {
-  return (
-    <div className="terms-wrapper">
-      <div className="terms-content">
-        <GCUContent />
-      </div>
-    </div>
-  )
-}
-
-export default CGUPublic
diff --git a/src/components/Terms/DataShareConsentContent.spec.tsx b/src/components/Terms/DataShareConsentContent.spec.tsx
index 36df98d2b..2a7d74fe3 100644
--- a/src/components/Terms/DataShareConsentContent.spec.tsx
+++ b/src/components/Terms/DataShareConsentContent.spec.tsx
@@ -16,8 +16,6 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
 })
 const mockStore = configureStore([])
 
-const mockDecoreText = jest.fn()
-
 describe('DataShareConsentContent component', () => {
   it('should be rendered correctly with first connexion text', () => {
     const store = mockStore({
@@ -27,12 +25,12 @@ describe('DataShareConsentContent component', () => {
     })
     const component = mount(
       <Provider store={store}>
-        <DataShareConsentContent decoreText={mockDecoreText} />
+        <DataShareConsentContent />
       </Provider>
     ).getElement()
     expect(component).toMatchSnapshot()
   })
-  it('should be rendered correctly with first connexion text', () => {
+  it('should be rendered correctly without first connexion text', () => {
     profileData.isFirstConnection = false
     const store = mockStore({
       ecolyo: {
@@ -41,7 +39,7 @@ describe('DataShareConsentContent component', () => {
     })
     const component = mount(
       <Provider store={store}>
-        <DataShareConsentContent decoreText={mockDecoreText} />
+        <DataShareConsentContent />
       </Provider>
     )
     expect(
diff --git a/src/components/Terms/LegalNoticePublic.spec.tsx b/src/components/Terms/LegalNoticeModal.spec.tsx
similarity index 59%
rename from src/components/Terms/LegalNoticePublic.spec.tsx
rename to src/components/Terms/LegalNoticeModal.spec.tsx
index 11e7b4f69..0b2265820 100644
--- a/src/components/Terms/LegalNoticePublic.spec.tsx
+++ b/src/components/Terms/LegalNoticeModal.spec.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import { mount } from 'enzyme'
-import LegalNoticePublic from './LegalNoticePublic'
+import LegalNoticeModal from './LegalNoticeModal'
 
 jest.mock('cozy-ui/transpiled/react/I18n', () => {
   return {
@@ -12,9 +12,11 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
   }
 })
 
-describe('LegalNoticePublic component', () => {
+describe('LegalNoticeModal component', () => {
   it('should be rendered correctly', () => {
-    const component = mount(<LegalNoticePublic />).getElement()
+    const component = mount(
+      <LegalNoticeModal open={true} handleCloseClick={jest.fn()} />
+    ).getElement()
     expect(component).toMatchSnapshot()
   })
 })
diff --git a/src/components/Terms/LegalNoticeModal.tsx b/src/components/Terms/LegalNoticeModal.tsx
new file mode 100644
index 000000000..db727e264
--- /dev/null
+++ b/src/components/Terms/LegalNoticeModal.tsx
@@ -0,0 +1,54 @@
+import React from 'react'
+import LegalNoticeContent from 'components/LegalNotice/LegalNoticeContent'
+import './termsView.scss'
+import Dialog from '@material-ui/core/Dialog'
+import { Button, IconButton } from '@material-ui/core'
+import Icon from 'cozy-ui/transpiled/react/Icon'
+import { useI18n } from 'cozy-ui/transpiled/react/I18n'
+import CloseIcon from 'assets/icons/ico/close.svg'
+
+interface LegalNoticeModalProps {
+  open: boolean
+  handleCloseClick: () => void
+}
+
+const LegalNoticeModal: React.FC<LegalNoticeModalProps> = ({
+  open,
+  handleCloseClick,
+}: LegalNoticeModalProps) => {
+  const { t } = useI18n()
+  return (
+    <Dialog
+      open={open}
+      onClose={handleCloseClick}
+      aria-labelledby={'accessibility-title'}
+      classes={{
+        root: 'modal-root',
+        paper: 'modal-paper',
+      }}
+    >
+      <div id={'accessibility-title'}>{t('legal.title_legal')}</div>
+      <IconButton
+        aria-label={t('feedback.accessibility.button_close')}
+        className="modal-paper-close-button"
+        onClick={handleCloseClick}
+      >
+        <Icon icon={CloseIcon} size={16} />
+      </IconButton>
+      <LegalNoticeContent />
+      <Button
+        aria-label={t('gcu_modal.accessibility.button_accept')}
+        onClick={handleCloseClick}
+        className="gcu-modal-button"
+        classes={{
+          root: 'btn-profile-next rounded',
+          label: 'text-16-bold',
+        }}
+      >
+        {t('legal.accessibility.button_close')}
+      </Button>
+    </Dialog>
+  )
+}
+
+export default LegalNoticeModal
diff --git a/src/components/Terms/LegalNoticePublic.tsx b/src/components/Terms/LegalNoticePublic.tsx
deleted file mode 100644
index 0003a5ed8..000000000
--- a/src/components/Terms/LegalNoticePublic.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import LegalNoticeContent from 'components/LegalNotice/LegalNoticeContent'
-import React from 'react'
-import './termsView.scss'
-
-const LegalNoticePublic: React.FC = () => {
-  return (
-    <div className="terms-wrapper">
-      <div className="terms-content">
-        <LegalNoticeContent />
-      </div>
-    </div>
-  )
-}
-
-export default LegalNoticePublic
diff --git a/src/components/Terms/TermsView.tsx b/src/components/Terms/TermsView.tsx
index 459e9cb06..b88e451e8 100644
--- a/src/components/Terms/TermsView.tsx
+++ b/src/components/Terms/TermsView.tsx
@@ -10,6 +10,8 @@ import './termsView.scss'
 import { useHistory } from 'react-router-dom'
 import { decoreText } from 'utils/decoreText'
 import { updateTermValidation } from 'store/global/global.actions'
+import CGUModal from './CGUModal'
+import LegalNoticeModal from './LegalNoticeModal'
 
 const TermsView: React.FC = () => {
   const { t } = useI18n()
@@ -20,6 +22,19 @@ const TermsView: React.FC = () => {
   const [dataConsentValidation, setDataConsentValidation] = useState<boolean>(
     false
   )
+  const [openCGUModal, setOpenCGUModal] = useState<boolean>(false)
+  const [openLegalNoticeModal, setOpenLegalNoticeModal] = useState<boolean>(
+    false
+  )
+
+  const toggleCGUModal = () => {
+    setOpenCGUModal(prev => !prev)
+  }
+
+  const toggleLegalNoticeModal = () => {
+    setOpenLegalNoticeModal(prev => !prev)
+  }
+
   const handleGCUValidate = useCallback(() => {
     setGCUValidation(prev => !prev)
   }, [])
@@ -65,8 +80,10 @@ const TermsView: React.FC = () => {
             checked={GCUValidation}
           />
           <span>
-            {decoreText(t('dataShare.validCGU'))}
-            {decoreText(t('dataShare.validLegal'))}
+            {decoreText(t('dataShare.validCGU'), () => toggleCGUModal())}
+            {decoreText(t('dataShare.validLegal'), () =>
+              toggleLegalNoticeModal()
+            )}
           </span>
         </label>
       </div>
@@ -87,6 +104,11 @@ const TermsView: React.FC = () => {
           {t('tutorial_welcome.accessibility.finish')}
         </Button>
       </div>
+      <CGUModal open={openCGUModal} handleCloseClick={toggleCGUModal} />
+      <LegalNoticeModal
+        open={openLegalNoticeModal}
+        handleCloseClick={toggleLegalNoticeModal}
+      />
     </div>
   )
 }
diff --git a/src/components/Terms/__snapshots__/CGUPublic.spec.tsx.snap b/src/components/Terms/__snapshots__/CGUPublic.spec.tsx.snap
deleted file mode 100644
index 8a09eaf92..000000000
--- a/src/components/Terms/__snapshots__/CGUPublic.spec.tsx.snap
+++ /dev/null
@@ -1,3 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`CGUPublic component should be rendered correctly 1`] = `<CGUPublic />`;
diff --git a/src/components/Terms/__snapshots__/DataShareConsentContent.spec.tsx.snap b/src/components/Terms/__snapshots__/DataShareConsentContent.spec.tsx.snap
index eed0cddcd..44ab11704 100644
--- a/src/components/Terms/__snapshots__/DataShareConsentContent.spec.tsx.snap
+++ b/src/components/Terms/__snapshots__/DataShareConsentContent.spec.tsx.snap
@@ -13,8 +13,6 @@ exports[`DataShareConsentContent component should be rendered correctly with fir
     }
   }
 >
-  <DataShareConsentContent
-    decoreText={[MockFunction]}
-  />
+  <DataShareConsentContent />
 </Provider>
 `;
diff --git a/src/components/Terms/__snapshots__/LegalNoticeModal.spec.tsx.snap b/src/components/Terms/__snapshots__/LegalNoticeModal.spec.tsx.snap
new file mode 100644
index 000000000..81b5dd5b1
--- /dev/null
+++ b/src/components/Terms/__snapshots__/LegalNoticeModal.spec.tsx.snap
@@ -0,0 +1,8 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`LegalNoticeModal component should be rendered correctly 1`] = `
+<LegalNoticeModal
+  handleCloseClick={[MockFunction]}
+  open={true}
+/>
+`;
diff --git a/src/components/Terms/__snapshots__/LegalNoticePublic.spec.tsx.snap b/src/components/Terms/__snapshots__/LegalNoticePublic.spec.tsx.snap
deleted file mode 100644
index 58e79dc02..000000000
--- a/src/components/Terms/__snapshots__/LegalNoticePublic.spec.tsx.snap
+++ /dev/null
@@ -1,3 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`LegalNoticePublic component should be rendered correctly 1`] = `<LegalNoticePublic />`;
diff --git a/src/components/Terms/termsView.scss b/src/components/Terms/termsView.scss
index c8dbc82be..b3cc43d5a 100644
--- a/src/components/Terms/termsView.scss
+++ b/src/components/Terms/termsView.scss
@@ -89,3 +89,12 @@
     }
   }
 }
+button.action {
+  appearance: none;
+  cursor: pointer;
+  display: contents;
+  background: transparent;
+  border: none;
+  padding: 0;
+  color: $gold-shadow;
+}
diff --git a/src/locales/fr.json b/src/locales/fr.json
index 274cbeaf3..d59886d2b 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -404,8 +404,8 @@
     "part10": "ou en ligne, au moyen du formulaire disponible à l'adresse suivante : ",
     "link1": "<a href=\"https://demarches.toodego.com/sve/proteger-mes-donnees-personnelles/\">https://demarches.toodego.com/sve/proteger-mes-donnees-personnelles/</a>",
     "validDataConsent": "Je consens au traitement de mes données tel que décrit ci-dessus.",
-    "validCGU": "Je valide les <a href=\"#/cgu\">Conditions Générales d’Utilisation</a> ",
-    "validLegal": " du service et ai pris connaissance des <a href=\"#/legal\"> Mentions Légales </a> de celui-ci."
+    "validCGU": "Je valide les <span class=\"action\">Conditions Générales d’Utilisation</span> ",
+    "validLegal": " du service et ai pris connaissance des <span class=\"action\"> Mentions Légales </span> de celui-ci."
   },
   "gcu": {
     "title": "Conditions générales d’utilisation du service",
@@ -595,7 +595,10 @@
     "part8": "Les liens hypertextes mis en œuvre au sein du site en direction d’autres sites et/ou de pages personnelles et d’une manière générale vers toutes ressources existantes sur internet ne sauraient engager la responsabilité de la Métropole de Lyon quant aux liens qu’ils contiennent ou aux changements ou mises à jour qui leur sont apportés.",
     "title9": "Mise en garde générale",
     "part9-1": "Nos services mettent tout en œuvre pour offrir aux visiteurs de ce site web des informations fiables et vérifiées. Cependant, malgré tous les soins apportés, le site peut comporter des inexactitudes, des défauts de mise à jour ou des erreurs.",
-    "part9-2": "Nous remercions les utilisateurs du site de nous faire part d’éventuelles omissions, erreurs ou corrections par mail sur la boite aux lettres du webmestre ou directement via le formulaire proposé dans le service."
+    "part9-2": "Nous remercions les utilisateurs du site de nous faire part d’éventuelles omissions, erreurs ou corrections par mail sur la boite aux lettres du webmestre ou directement via le formulaire proposé dans le service.",
+    "accessibility": {
+      "button_close": "Fermer la fenêtre"
+    }
   },
   "navigation": {
     "consumption": "Conso",
diff --git a/src/utils/decoreText.tsx b/src/utils/decoreText.tsx
index 24172a281..3411858c4 100644
--- a/src/utils/decoreText.tsx
+++ b/src/utils/decoreText.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 
-export const decoreText = (line: string) => {
+export const decoreText = (line: string, action?: () => void) => {
   if (line.includes('<a href="')) {
     const indexRefStart = line.indexOf('<a href="')
     const indexRefEnd = line.indexOf('">')
@@ -18,6 +18,18 @@ export const decoreText = (line: string) => {
         {line.substring(indexEnd + 4, line.length)}
       </>
     )
+  } else if (line.includes('<span class="action">')) {
+    const indexStart = line.indexOf('<span class="action">')
+    const indexEnd = line.indexOf('</span>')
+    return (
+      <>
+        {line.substring(0, indexStart)}
+        <button className="action" onClick={action && action}>
+          {line.substring(indexStart + 21, indexEnd)}
+        </button>
+        {line.substring(indexEnd + 7, line.length)}
+      </>
+    )
   } else {
     return line
   }
-- 
GitLab