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