diff --git a/src/components/LegalNotice/legalNoticeLink.scss b/src/components/LegalNotice/legalNoticeLink.scss index 56b8e1e7bdab07d0b928c263d24c07d674458683..6998b06d085d3cafeee08915a25c4b6fb6ea6b3c 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 b42dc7c023ee085ad1e9c28dab96caff614e3b25..232c4f03ec71ef50e6266d6a5c6ccdc102ea2f35 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 5072f8292f90c79f5f1db6f2910b506e1863d17f..0db7952b9e47b6513e957d675883e9e124c379c4 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 0000000000000000000000000000000000000000..4c8fdbd4e5f1d88fb7733f0c9ecace7fdff84c28 --- /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 fc20cf9e01e5484a322aea628baaaece8d1f1e55..942fb2ac231fcbc511d714fc77aeb01aec4c7abf 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 98d157c31e7285fc931603fb1db29666468b641a..0000000000000000000000000000000000000000 --- 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 36df98d2bcbf35efa66aa0758c55167dd5c0da6b..2a7d74fe3058c5eb3283c21e8dbecfb752974f6e 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 11e7b4f694ea32830cd6d9f8ee66a8ebde2a2d90..0b2265820067ca2201b109621ed9722ca3dbdff2 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 0000000000000000000000000000000000000000..db727e26414c3bc32b9640b17b46e500f9ff451f --- /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 0003a5ed8c17e5618496d426973c79f26daa4123..0000000000000000000000000000000000000000 --- 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 459e9cb0644d7c3725e36b3400c37674e316a5eb..b88e451e86921a77d2f0ea284b68664120fcaddf 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 8a09eaf92b3174b7bdd01bcfc0d61f80cfd578cb..0000000000000000000000000000000000000000 --- 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 eed0cddcd50f00055839771d7c83d15f333c5411..44ab11704817fcc6382de1fbc866122ccb614503 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 0000000000000000000000000000000000000000..81b5dd5b17a74840e8d7cb7406111539dff88239 --- /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 58e79dc024eb10fbb37e26204fd0433082c0d62a..0000000000000000000000000000000000000000 --- 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 c8dbc82be36b495b7bd945a08989cc4c1fdfebbb..b3cc43d5a488965b7ca6d0ae3794b79f49f45264 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 274cbeaf3bf202268bd06d4780c7d7bdec3a9988..d59886d2b9057f6330a9369d10cf8a89e956d073 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 24172a2813b0710fa6ff0ea1978ec69d2427211a..3411858c455fe985bdf7f3d2dc1fe4dd48cdcc0b 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 }