From 2a6928ab9e1797eb2e4e16180f1d24c0a76b026d Mon Sep 17 00:00:00 2001 From: Adel LAKHDAR <alakhdar@grandlyon.com> Date: Thu, 25 Jul 2024 09:14:53 +0000 Subject: [PATCH] feat(ecogestures): unify ecogesture init modal components --- .../EcogestureInitModal.spec.tsx | 67 +++++++++--- .../EcogestureInitModal.tsx | 48 +++------ .../EcogestureInitModal.spec.tsx.snap | 4 +- .../Ecogesture/EcogestureTabsView.tsx | 15 ++- .../EcogestureFormSingleChoice.spec.tsx | 4 +- .../EcogestureFormView.spec.tsx | 4 +- .../EcogestureForm/EcogestureFormView.tsx | 15 ++- .../EcogestureLaunchFormModal.spec.tsx | 29 ----- .../EcogestureLaunchFormModal.tsx | 56 ---------- .../EcogestureLaunchFormModal.spec.tsx.snap | 101 ------------------ .../ecogestureLaunchFormModal.scss | 11 -- .../EcogestureFormView.spec.tsx.snap | 2 +- src/locales/fr.json | 5 +- 13 files changed, 101 insertions(+), 260 deletions(-) delete mode 100644 src/components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal.spec.tsx delete mode 100644 src/components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal.tsx delete mode 100644 src/components/EcogestureForm/EcogestureLaunchFormModal/__snapshots__/EcogestureLaunchFormModal.spec.tsx.snap delete mode 100644 src/components/EcogestureForm/EcogestureLaunchFormModal/ecogestureLaunchFormModal.scss diff --git a/src/components/Ecogesture/EcogestureInitModal/EcogestureInitModal.spec.tsx b/src/components/Ecogesture/EcogestureInitModal/EcogestureInitModal.spec.tsx index bd3c32ab0..38ecf44a0 100644 --- a/src/components/Ecogesture/EcogestureInitModal/EcogestureInitModal.spec.tsx +++ b/src/components/Ecogesture/EcogestureInitModal/EcogestureInitModal.spec.tsx @@ -1,14 +1,17 @@ import { act, render, screen } from '@testing-library/react' -import { userEvent } from '@testing-library/user-event' +import userEvent from '@testing-library/user-event' import React from 'react' import { Provider } from 'react-redux' import * as storeHooks from 'store/hooks' import { createMockEcolyoStore } from 'tests/__mocks__/store' import EcogestureInitModal from './EcogestureInitModal' - -const mockAppDispatch = jest.spyOn(storeHooks, 'useAppDispatch') +import '../../../locales/fr.json' +import { useI18n } from 'cozy-ui/transpiled/react/I18n' const mockedNavigate = jest.fn() +const mockOnClose = jest.fn() +const mockOnAccept = jest.fn() + jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useNavigate: () => mockedNavigate, @@ -16,39 +19,75 @@ jest.mock('react-router-dom', () => ({ describe('EcogestureInitModal component', () => { const store = createMockEcolyoStore() + const { t } = useI18n() beforeEach(() => { jest.clearAllMocks() }) - it('should be rendered correctly', () => { + + it('should not render the modal when open is false', () => { + const { queryByRole } = render( + <Provider store={store}> + <EcogestureInitModal + open={false} + onClose={mockOnClose} + onAccept={mockOnAccept} + /> + </Provider> + ) + expect(queryByRole('dialog')).toBeNull() + }) + + it('should render correctly when open is true', () => { const { baseElement } = render( <Provider store={store}> - <EcogestureInitModal /> + <EcogestureInitModal + open={true} + onClose={mockOnClose} + onAccept={mockOnAccept} + /> </Provider> ) expect(baseElement).toMatchSnapshot() }) - it('should close modal', async () => { + + it('should call onAccept and navigate to /ecogesture-form?modal=false when the accept button is clicked', async () => { render( <Provider store={store}> - <EcogestureInitModal /> + <EcogestureInitModal + open={true} + onClose={mockOnClose} + onAccept={() => { + mockOnAccept() + mockedNavigate('/ecogesture-form?modal=false') + }} + /> </Provider> ) await act(async () => { - await userEvent.click(screen.getByText('ecogesture.initModal.btn1')) + await userEvent.click(screen.getByText(t('ecogesture.initModal.btn2'))) }) - expect(mockAppDispatch).toHaveBeenCalledTimes(1) + expect(mockedNavigate).toHaveBeenCalledWith('/ecogesture-form?modal=false') + expect(mockOnAccept).toHaveBeenCalled() }) - it('should close modal and launch form', async () => { + + it('should call onClose and navigate to /ecogestures when the close button is clicked', async () => { render( <Provider store={store}> - <EcogestureInitModal /> + <EcogestureInitModal + open={true} + onClose={() => { + mockOnClose() + mockedNavigate('/ecogestures') + }} + onAccept={mockOnAccept} + /> </Provider> ) await act(async () => { - await userEvent.click(screen.getByText('ecogesture.initModal.btn2')) + await userEvent.click(screen.getByText(t('ecogesture.initModal.btn1'))) }) - expect(mockedNavigate).toHaveBeenCalledWith('/ecogesture-form?modal=false') - expect(mockAppDispatch).toHaveBeenCalledTimes(1) + expect(mockedNavigate).toHaveBeenCalledWith('/ecogestures') + expect(mockOnClose).toHaveBeenCalled() }) }) diff --git a/src/components/Ecogesture/EcogestureInitModal/EcogestureInitModal.tsx b/src/components/Ecogesture/EcogestureInitModal/EcogestureInitModal.tsx index 509ef939a..1495524a9 100644 --- a/src/components/Ecogesture/EcogestureInitModal/EcogestureInitModal.tsx +++ b/src/components/Ecogesture/EcogestureInitModal/EcogestureInitModal.tsx @@ -4,33 +4,25 @@ import CloseIcon from 'assets/icons/ico/close.svg' import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import React from 'react' -import { useNavigate } from 'react-router-dom' -import { useAppDispatch, useAppSelector } from 'store/hooks' -import { updateProfile } from 'store/profile/profile.slice' import './ecogestureInitModal.scss' -const EcogestureInitModal = () => { - const { t } = useI18n() - const navigate = useNavigate() - const dispatch = useAppDispatch() - const { haveSeenEcogestureModal } = useAppSelector( - state => state.ecolyo.profile - ) - const openEcogestureInitModal = !haveSeenEcogestureModal - - const handleLaunchForm = () => { - dispatch(updateProfile({ haveSeenEcogestureModal: true })) - navigate('/ecogesture-form?modal=false') - } +interface EcogestureInitModalProps { + open: boolean + onClose: () => void + onAccept: () => void +} - const handleCloseEcogestureInitModal = () => { - dispatch(updateProfile({ haveSeenEcogestureModal: true })) - } +const EcogestureInitModal = ({ + open, + onClose, + onAccept, +}: EcogestureInitModalProps) => { + const { t } = useI18n() return ( <Dialog - open={openEcogestureInitModal} - onClose={handleCloseEcogestureInitModal} + open={open} + onClose={onClose} aria-labelledby="accessibility-title" classes={{ root: 'modal-root', @@ -42,7 +34,7 @@ const EcogestureInitModal = () => { </div> <StyledIconButton icon={CloseIcon} - onClick={handleCloseEcogestureInitModal} + onClick={onClose} aria-label={t('feedback.accessibility.button_close')} className="modal-paper-close-button" /> @@ -53,18 +45,10 @@ const EcogestureInitModal = () => { <div className="text-16-normal">{t('ecogesture.initModal.text1')}</div> <div className="text-16-normal">{t('ecogesture.initModal.text2')}</div> <div className="buttons-container"> - <Button - aria-label={t('ecogesture.initModal.btn2')} - onClick={handleLaunchForm} - className="btnPrimary" - > + <Button onClick={onAccept} className="btnPrimary"> {t('ecogesture.initModal.btn2')} </Button> - <Button - aria-label={t('ecogesture.initModal.btn1')} - onClick={handleCloseEcogestureInitModal} - className="btnSecondary" - > + <Button onClick={onClose} className="btnSecondary"> {t('ecogesture.initModal.btn1')} </Button> </div> diff --git a/src/components/Ecogesture/EcogestureInitModal/__snapshots__/EcogestureInitModal.spec.tsx.snap b/src/components/Ecogesture/EcogestureInitModal/__snapshots__/EcogestureInitModal.spec.tsx.snap index 0a28b093d..6f5526868 100644 --- a/src/components/Ecogesture/EcogestureInitModal/__snapshots__/EcogestureInitModal.spec.tsx.snap +++ b/src/components/Ecogesture/EcogestureInitModal/__snapshots__/EcogestureInitModal.spec.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`EcogestureInitModal component should be rendered correctly 1`] = ` +exports[`EcogestureInitModal component should render correctly when open is true 1`] = ` <body style="padding-right: 0px; overflow: hidden;" > @@ -83,7 +83,6 @@ exports[`EcogestureInitModal component should be rendered correctly 1`] = ` class="buttons-container" > <button - aria-label="ecogesture.initModal.btn2" class="MuiButtonBase-root MuiButton-root MuiButton-text btnPrimary" tabindex="0" type="button" @@ -98,7 +97,6 @@ exports[`EcogestureInitModal component should be rendered correctly 1`] = ` /> </button> <button - aria-label="ecogesture.initModal.btn1" class="MuiButtonBase-root MuiButton-root MuiButton-text btnSecondary" tabindex="0" type="button" diff --git a/src/components/Ecogesture/EcogestureTabsView.tsx b/src/components/Ecogesture/EcogestureTabsView.tsx index d5327b447..4553e7e28 100644 --- a/src/components/Ecogesture/EcogestureTabsView.tsx +++ b/src/components/Ecogesture/EcogestureTabsView.tsx @@ -46,7 +46,6 @@ const EcogestureTabsView = () => { const { profile, profileEcogesture, profileType } = useAppSelector( state => state.ecolyo ) - const [tabValue, setTabValue] = useState<EcogestureTab>( tab ? parseInt(tab) : EcogestureTab.OBJECTIVE ) @@ -147,6 +146,13 @@ const EcogestureTabsView = () => { ecogestureService, ]) + const handleCloseInitModal = (redirect: boolean) => { + dispatch(updateProfile({ haveSeenEcogestureModal: true })) + if (redirect) { + navigate('/ecogesture-form?modal=false') + } + } + return ( <> <CozyBar titleKey="common.title_ecogestures" /> @@ -265,8 +271,11 @@ const EcogestureTabsView = () => { </TabPanel> </> )} - <EcogestureInitModal /> - + <EcogestureInitModal + open={!profile.haveSeenEcogestureModal} + onClose={() => handleCloseInitModal(false)} + onAccept={() => handleCloseInitModal(true)} + /> {openEcResetModal && ( <EcogestureResetModal open={openEcResetModal} diff --git a/src/components/EcogestureForm/EcogestureFormSingleChoice/EcogestureFormSingleChoice.spec.tsx b/src/components/EcogestureForm/EcogestureFormSingleChoice/EcogestureFormSingleChoice.spec.tsx index ae223e032..8cd8520a1 100644 --- a/src/components/EcogestureForm/EcogestureFormSingleChoice/EcogestureFormSingleChoice.spec.tsx +++ b/src/components/EcogestureForm/EcogestureFormSingleChoice/EcogestureFormSingleChoice.spec.tsx @@ -10,8 +10,8 @@ import { createMockEcolyoStore } from 'tests/__mocks__/store' import EcogestureFormSingleChoice from './EcogestureFormSingleChoice' jest.mock( - 'components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal', - () => 'mock-ecogesturelaunchmodal' + 'components/Ecogesture/EcogestureInitModal/EcogestureInitModal', + () => 'mock-ecogestureinitmodal' ) const mockHandleNextStep = jest.fn() diff --git a/src/components/EcogestureForm/EcogestureFormView.spec.tsx b/src/components/EcogestureForm/EcogestureFormView.spec.tsx index d3aac9ddd..f040f1797 100644 --- a/src/components/EcogestureForm/EcogestureFormView.spec.tsx +++ b/src/components/EcogestureForm/EcogestureFormView.spec.tsx @@ -11,8 +11,8 @@ jest.mock('components/Header/CozyBar', () => 'mock-cozybar') jest.mock('components/Header/Header', () => 'mock-header') jest.mock('components/Content/Content', () => 'mock-content') jest.mock( - 'components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal', - () => 'mock-ecogesturelaunchmodal' + 'components/Ecogesture/EcogestureInitModal/EcogestureInitModal', + () => 'mock-ecogestureinitmodal' ) const mockAppDispatch = jest.spyOn(storeHooks, 'useAppDispatch') diff --git a/src/components/EcogestureForm/EcogestureFormView.tsx b/src/components/EcogestureForm/EcogestureFormView.tsx index 337592ae8..456b90389 100644 --- a/src/components/EcogestureForm/EcogestureFormView.tsx +++ b/src/components/EcogestureForm/EcogestureFormView.tsx @@ -13,7 +13,7 @@ import { updateProfile } from 'store/profile/profile.slice' import { newProfileEcogestureEntry } from 'store/profileEcogesture/profileEcogesture.slice' import EcogestureFormEquipment from './EcogestureFormEquipment/EcogestureFormEquipment' import EcogestureFormSingleChoice from './EcogestureFormSingleChoice/EcogestureFormSingleChoice' -import EcogestureLaunchFormModal from './EcogestureLaunchFormModal/EcogestureLaunchFormModal' +import EcogestureInitModal from '../Ecogesture/EcogestureInitModal/EcogestureInitModal' const EcogestureFormView = () => { const navigate = useNavigate() @@ -92,6 +92,14 @@ const EcogestureFormView = () => { return <ProfileTypeView /> } + const handleCloseInitModal = (redirect: boolean) => { + setOpenLaunchModal(false) + dispatch(updateProfile({ haveSeenEcogestureModal: true })) + if (redirect) { + navigate('/ecogestures') + } + } + return ( <> <CozyBar titleKey="common.title_ecogestures" /> @@ -124,9 +132,10 @@ const EcogestureFormView = () => { </> )} </Content> - <EcogestureLaunchFormModal + <EcogestureInitModal open={openLaunchModal} - handleCloseClick={() => setOpenLaunchModal(false)} + onClose={() => handleCloseInitModal(true)} + onAccept={() => handleCloseInitModal(false)} /> </> ) diff --git a/src/components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal.spec.tsx b/src/components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal.spec.tsx deleted file mode 100644 index 23c365172..000000000 --- a/src/components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal.spec.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { act, render, screen } from '@testing-library/react' -import { userEvent } from '@testing-library/user-event' -import React from 'react' -import EcogestureLaunchFormModal from './EcogestureLaunchFormModal' - -const mockHandleClose = jest.fn() -describe('EcogestureLaunchFormModal component', () => { - it('should be rendered correctly', () => { - const { baseElement } = render( - <EcogestureLaunchFormModal - open={true} - handleCloseClick={mockHandleClose} - /> - ) - expect(baseElement).toMatchSnapshot() - }) - it('should close modal', async () => { - render( - <EcogestureLaunchFormModal - open={true} - handleCloseClick={mockHandleClose} - /> - ) - await act(async () => { - await userEvent.click(screen.getByText('ecogesture.initModal.btn2')) - }) - expect(mockHandleClose).toHaveBeenCalledTimes(1) - }) -}) diff --git a/src/components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal.tsx b/src/components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal.tsx deleted file mode 100644 index c71271c7e..000000000 --- a/src/components/EcogestureForm/EcogestureLaunchFormModal/EcogestureLaunchFormModal.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { Button } from '@material-ui/core' -import Dialog from '@material-ui/core/Dialog' -import CloseIcon from 'assets/icons/ico/close.svg' -import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton' -import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import React from 'react' -import './ecogestureLaunchFormModal.scss' - -interface EcogestureLaunchFormModalProps { - open: boolean - handleCloseClick: () => void -} -const EcogestureLaunchFormModal = ({ - open, - handleCloseClick, -}: EcogestureLaunchFormModalProps) => { - 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> - <StyledIconButton - icon={CloseIcon} - onClick={handleCloseClick} - aria-label={t('feedback.accessibility.button_close')} - className="modal-paper-close-button" - /> - <div className="eg-init-modal"> - <div className="title text-20-bold"> - {t('ecogesture.initModal.title')} - </div> - <div className="text-16-normal"> - {t('ecogesture.initModal.launchForm')} - </div> - <Button - aria-label={t('ecogesture.initModal.btn2')} - onClick={handleCloseClick} - className="btnPrimary" - > - {t('ecogesture.initModal.btn2')} - </Button> - </div> - </Dialog> - ) -} - -export default EcogestureLaunchFormModal diff --git a/src/components/EcogestureForm/EcogestureLaunchFormModal/__snapshots__/EcogestureLaunchFormModal.spec.tsx.snap b/src/components/EcogestureForm/EcogestureLaunchFormModal/__snapshots__/EcogestureLaunchFormModal.spec.tsx.snap deleted file mode 100644 index 5cf6f6fea..000000000 --- a/src/components/EcogestureForm/EcogestureLaunchFormModal/__snapshots__/EcogestureLaunchFormModal.spec.tsx.snap +++ /dev/null @@ -1,101 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EcogestureLaunchFormModal component should be rendered correctly 1`] = ` -<body - style="padding-right: 0px; overflow: hidden;" -> - <div - aria-hidden="true" - /> - <div - class="MuiDialog-root modal-root" - role="presentation" - style="position: fixed; z-index: 1300; right: 0px; bottom: 0px; top: 0px; left: 0px;" - > - <div - aria-hidden="true" - class="MuiBackdrop-root" - style="opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;" - /> - <div - data-test="sentinelStart" - tabindex="0" - /> - <div - class="MuiDialog-container MuiDialog-scrollPaper" - role="none presentation" - style="opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;" - tabindex="-1" - > - <div - aria-labelledby="accessibility-title" - class="MuiPaper-root MuiDialog-paper modal-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm MuiPaper-elevation24 MuiPaper-rounded" - role="dialog" - > - <div - id="accessibility-title" - > - feedback.accessibility.window_title - </div> - <button - aria-label="feedback.accessibility.button_close" - class="MuiButtonBase-root MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1 modal-paper-close-button" - tabindex="0" - type="button" - > - <span - class="MuiIconButton-label" - > - <svg - aria-hidden="true" - class="styles__icon___23x3R" - height="16" - width="16" - > - <use - xlink:href="#test-file-stub" - /> - </svg> - </span> - <span - class="MuiTouchRipple-root" - /> - </button> - <div - class="eg-init-modal" - > - <div - class="title text-20-bold" - > - ecogesture.initModal.title - </div> - <div - class="text-16-normal" - > - ecogesture.initModal.launchForm - </div> - <button - aria-label="ecogesture.initModal.btn2" - class="MuiButtonBase-root MuiButton-root MuiButton-text btnPrimary" - tabindex="0" - type="button" - > - <span - class="MuiButton-label" - > - ecogesture.initModal.btn2 - </span> - <span - class="MuiTouchRipple-root" - /> - </button> - </div> - </div> - </div> - <div - data-test="sentinelEnd" - tabindex="0" - /> - </div> -</body> -`; diff --git a/src/components/EcogestureForm/EcogestureLaunchFormModal/ecogestureLaunchFormModal.scss b/src/components/EcogestureForm/EcogestureLaunchFormModal/ecogestureLaunchFormModal.scss deleted file mode 100644 index cbbceeafb..000000000 --- a/src/components/EcogestureForm/EcogestureLaunchFormModal/ecogestureLaunchFormModal.scss +++ /dev/null @@ -1,11 +0,0 @@ -@import 'src/styles/base/color'; - -.eg-init-modal { - display: flex; - flex-direction: column; - gap: 1rem; - .title { - text-align: center; - color: $gold-shadow; - } -} diff --git a/src/components/EcogestureForm/__snapshots__/EcogestureFormView.spec.tsx.snap b/src/components/EcogestureForm/__snapshots__/EcogestureFormView.spec.tsx.snap index 843e5be16..cc7a4efcf 100644 --- a/src/components/EcogestureForm/__snapshots__/EcogestureFormView.spec.tsx.snap +++ b/src/components/EcogestureForm/__snapshots__/EcogestureFormView.spec.tsx.snap @@ -75,7 +75,7 @@ exports[`EcogestureFormView component should be rendered correctly 1`] = ` </div> </div> </mock-content> - <mock-ecogesturelaunchmodal + <mock-ecogestureinitmodal open="true" /> </div> diff --git a/src/locales/fr.json b/src/locales/fr.json index 205ca19d0..95b49a62f 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -505,9 +505,8 @@ }, "initModal": { "title": "Sélectionner mes astuces", - "text1": "Les astuces présentées sont des actions qui vous permettent de réduire vos consommations et donc vos factures. On parle parfois d’écogestes ", - "text2": "Vous pouvez sélectionner celles à mettre en objectifs et celles que vous appliquez déjà.", - "launchForm": "Afin de pré-sélectionner les astuces correspondant à votre consommation, merci de répondre à quelques rapides questions.", + "text1": "Les astuces présentées dans cette page sont des actions qui vous permettent de réduire vos consommations. Elles sont appelées parfois aussi écogestes.", + "text2": "Répondez à un court questionnaire pour générer une liste d'astuces adaptée à votre profil puis sélectionnez celles que vous suivez déjà et celles que vous voulez vous mettre en objectif !", "btn1": "Plus tard", "btn2": "C'est parti !" }, -- GitLab