From c062e48a88f5445c872832255a47be0deb78c08d Mon Sep 17 00:00:00 2001 From: "guilhem.carron" <gcarron@grandlyon.com> Date: Thu, 20 Jan 2022 14:32:08 +0100 Subject: [PATCH] feat(ecogestures): Create ecogesture form -create ecogestureProfile -generate filtered list by equipments and usages --- .../visu/equipments/AIR_CONDITIONING.svg | 11 + src/assets/icons/visu/equipments/BOILER.svg | 4 + src/assets/icons/visu/equipments/COMPUTER.svg | 4 + .../icons/visu/equipments/COOKING_PLATES.svg | 6 + src/assets/icons/visu/equipments/CURTAIN.svg | 8 + .../icons/visu/equipments/DISHWASHER.svg | 4 + src/assets/icons/visu/equipments/DRYER.svg | 4 + src/assets/icons/visu/equipments/FAN.svg | 4 + src/assets/icons/visu/equipments/FREEZER.svg | 7 + src/assets/icons/visu/equipments/GARDEN.svg | 8 + .../visu/equipments/HYDRAULIC_HEATING.svg | 8 + .../icons/visu/equipments/INTERNET_BOX.svg | 11 + .../icons/visu/equipments/MICROWAVE.svg | 4 + .../icons/visu/equipments/REFREGIRATOR.svg | 4 + .../icons/visu/equipments/VENTILATION.svg | 4 + .../icons/visu/equipments/WASHING_MACHINE.svg | 4 + src/components/App.tsx | 9 +- .../Ecogesture/EcogestureEmptyList.spec.tsx | 12 +- .../Ecogesture/EcogestureEmptyList.tsx | 5 +- .../Ecogesture/EcogestureInitModal.spec.tsx | 27 +- .../Ecogesture/EcogestureInitModal.tsx | 13 +- src/components/Ecogesture/EcogestureView.tsx | 10 +- .../EcogestureInitModal.spec.tsx.snap | 11 +- .../EcogestureList.spec.tsx.snap | 12 +- .../EcogestureView.spec.tsx.snap | 6 +- src/components/Ecogesture/ecogestureView.scss | 4 + .../Ecogesture/singleEcogesture.scss | 4 + .../EcogestureFormEquipment.spec.tsx | 145 +++ .../EcogestureFormEquipment.tsx | 115 +++ .../EcogestureFormSingleChoice.spec.tsx | 147 +++ .../EcogestureFormSingleChoice.tsx | 99 ++ .../EcogestureFormView.spec.tsx | 136 +++ .../EcogestureForm/EcogestureFormView.tsx | 154 +++ .../EcogestureLaunchFormModal.spec.tsx | 41 + .../EcogestureLaunchFormModal.tsx | 60 ++ .../EcogestureForm/EcogestureSelection.tsx | 33 + .../EcogestureForm/EquipmentIcon.spec.tsx | 48 + .../EcogestureForm/EquipmentIcon.tsx | 45 + .../EcogestureFormEquipment.spec.tsx.snap | 587 +++++++++++ .../EcogestureFormSingleChoice.spec.tsx.snap | 304 ++++++ .../EcogestureFormView.spec.tsx.snap | 321 ++++++ .../EcogestureLaunchFormModal.spec.tsx.snap | 963 ++++++++++++++++++ .../__snapshots__/EquipmentIcon.spec.tsx.snap | 38 + .../ecogestureFormEquipment.scss | 48 + .../ecogestureFormSingleChoice.scss | 6 + .../EcogestureForm/ecogestureFormView.scss | 12 + .../ecogestureLaunchFormModal.scss | 16 + ...ation.spec.tsx => FormNavigation.spec.tsx} | 6 +- ...eTypeNavigation.tsx => FormNavigation.tsx} | 19 +- .../ProfileTypeFormDateSelection.tsx | 4 +- .../ProfileTypeFormMultiChoice.tsx | 4 +- .../ProfileType/ProfileTypeFormNumber.tsx | 4 +- .../ProfileTypeFormNumberSelection.tsx | 4 +- .../ProfileTypeFormSingleChoice.tsx | 4 +- .../ProfileType/ProfileTypeView.tsx | 2 +- ...ypeNavigation.scss => formNavigation.scss} | 2 +- src/components/Routes/Routes.tsx | 14 +- src/components/Splash/SplashRoot.tsx | 5 + src/db/ecogestureData.json | 80 +- .../com-grandlyon-ecolyo-profileecogesture.ts | 2 + src/doctypes/index.ts | 7 + src/enum/ecogesture.enum.ts | 33 +- src/enum/ecogestureForm.enum.ts | 10 + src/locales/fr.json | 47 + src/models/profile.model.ts | 1 + src/models/profileEcogesture.model.ts | 40 + src/services/ecogesture.service.spec.ts | 298 +++--- src/services/ecogesture.service.ts | 155 +-- src/services/initialization.service.ts | 13 + .../profileEcogesture.service.spec.ts | 50 + src/services/profileEcogesture.service.ts | 50 + src/services/profileEcogestureForm.service.ts | 105 ++ src/store/index.ts | 4 + src/store/profile/profile.reducer.ts | 1 + .../profileEcogesture.action.spec.ts | 45 + .../profileEcogesture.actions.ts | 69 ++ .../profileEcogesture.reducer.spec.ts | 31 + .../profileEcogesture.reducer.ts | 31 + src/utils/hash.spec.ts | 2 +- tests/__mocks__/ecogesturesData.mock.ts | 57 ++ tests/__mocks__/profile.mock.ts | 1 + tests/__mocks__/profileEcogesture.mock.ts | 29 + tests/__mocks__/store.ts | 4 +- 83 files changed, 4393 insertions(+), 366 deletions(-) create mode 100644 src/assets/icons/visu/equipments/AIR_CONDITIONING.svg create mode 100644 src/assets/icons/visu/equipments/BOILER.svg create mode 100644 src/assets/icons/visu/equipments/COMPUTER.svg create mode 100644 src/assets/icons/visu/equipments/COOKING_PLATES.svg create mode 100644 src/assets/icons/visu/equipments/CURTAIN.svg create mode 100644 src/assets/icons/visu/equipments/DISHWASHER.svg create mode 100644 src/assets/icons/visu/equipments/DRYER.svg create mode 100644 src/assets/icons/visu/equipments/FAN.svg create mode 100644 src/assets/icons/visu/equipments/FREEZER.svg create mode 100644 src/assets/icons/visu/equipments/GARDEN.svg create mode 100644 src/assets/icons/visu/equipments/HYDRAULIC_HEATING.svg create mode 100644 src/assets/icons/visu/equipments/INTERNET_BOX.svg create mode 100644 src/assets/icons/visu/equipments/MICROWAVE.svg create mode 100644 src/assets/icons/visu/equipments/REFREGIRATOR.svg create mode 100644 src/assets/icons/visu/equipments/VENTILATION.svg create mode 100644 src/assets/icons/visu/equipments/WASHING_MACHINE.svg create mode 100644 src/components/EcogestureForm/EcogestureFormEquipment.spec.tsx create mode 100644 src/components/EcogestureForm/EcogestureFormEquipment.tsx create mode 100644 src/components/EcogestureForm/EcogestureFormSingleChoice.spec.tsx create mode 100644 src/components/EcogestureForm/EcogestureFormSingleChoice.tsx create mode 100644 src/components/EcogestureForm/EcogestureFormView.spec.tsx create mode 100644 src/components/EcogestureForm/EcogestureFormView.tsx create mode 100644 src/components/EcogestureForm/EcogestureLaunchFormModal.spec.tsx create mode 100644 src/components/EcogestureForm/EcogestureLaunchFormModal.tsx create mode 100644 src/components/EcogestureForm/EcogestureSelection.tsx create mode 100644 src/components/EcogestureForm/EquipmentIcon.spec.tsx create mode 100644 src/components/EcogestureForm/EquipmentIcon.tsx create mode 100644 src/components/EcogestureForm/__snapshots__/EcogestureFormEquipment.spec.tsx.snap create mode 100644 src/components/EcogestureForm/__snapshots__/EcogestureFormSingleChoice.spec.tsx.snap create mode 100644 src/components/EcogestureForm/__snapshots__/EcogestureFormView.spec.tsx.snap create mode 100644 src/components/EcogestureForm/__snapshots__/EcogestureLaunchFormModal.spec.tsx.snap create mode 100644 src/components/EcogestureForm/__snapshots__/EquipmentIcon.spec.tsx.snap create mode 100644 src/components/EcogestureForm/ecogestureFormEquipment.scss create mode 100644 src/components/EcogestureForm/ecogestureFormSingleChoice.scss create mode 100644 src/components/EcogestureForm/ecogestureFormView.scss create mode 100644 src/components/EcogestureForm/ecogestureLaunchFormModal.scss rename src/components/ProfileType/{ProfileTypeNavigation.spec.tsx => FormNavigation.spec.tsx} (90%) rename src/components/ProfileType/{ProfileTypeNavigation.tsx => FormNavigation.tsx} (72%) rename src/components/ProfileType/{profileTypeNavigation.scss => formNavigation.scss} (95%) create mode 100644 src/doctypes/com-grandlyon-ecolyo-profileecogesture.ts create mode 100644 src/enum/ecogestureForm.enum.ts create mode 100644 src/models/profileEcogesture.model.ts create mode 100644 src/services/profileEcogesture.service.spec.ts create mode 100644 src/services/profileEcogesture.service.ts create mode 100644 src/services/profileEcogestureForm.service.ts create mode 100644 src/store/profileEcogesture/profileEcogesture.action.spec.ts create mode 100644 src/store/profileEcogesture/profileEcogesture.actions.ts create mode 100644 src/store/profileEcogesture/profileEcogesture.reducer.spec.ts create mode 100644 src/store/profileEcogesture/profileEcogesture.reducer.ts create mode 100644 tests/__mocks__/profileEcogesture.mock.ts diff --git a/src/assets/icons/visu/equipments/AIR_CONDITIONING.svg b/src/assets/icons/visu/equipments/AIR_CONDITIONING.svg new file mode 100644 index 000000000..5205f7bbd --- /dev/null +++ b/src/assets/icons/visu/equipments/AIR_CONDITIONING.svg @@ -0,0 +1,11 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<g clip-path="url(#clip0_11856_14985)"> +<path d="M30.7429 21.0755C34.5566 18.1256 38.6962 21.7274 39.6252 27.3338C40.326 27.3338 41.0105 27.5294 41.6298 27.8879C42.4773 26.9101 43.2269 25.5737 42.9336 24.0743C42.2491 20.5703 46.1768 17.7345 49.909 22.5749C52.8589 26.3885 49.2571 30.5281 43.6344 31.4571C43.6344 32.1579 43.4551 32.8587 43.0803 33.478C44.0581 34.3092 45.3945 35.0589 46.8939 34.7655C50.3653 34.081 53.2174 37.9925 48.377 41.7409C44.5634 44.6908 40.4238 41.089 39.4948 35.4826C38.794 35.4826 38.1095 35.2708 37.5065 34.9122C36.659 35.8901 35.893 37.2428 36.1864 38.7422C36.8709 42.2299 32.9431 45.0819 29.211 40.2415C26.2448 36.4116 29.8629 32.272 35.4856 31.3593C35.4856 30.6585 35.6974 29.974 36.056 29.3547C35.0781 28.5235 33.7417 27.7575 32.226 28.0509C28.7546 28.7354 25.9025 24.824 30.7429 21.0755ZM28.1516 46.0761H31.4112C32.2756 46.0761 33.1047 46.4195 33.716 47.0308C34.3273 47.6421 34.6707 48.4711 34.6707 49.3356V59.1142H31.4112V55.8547H28.1516V59.1142H24.8921V49.3356C24.8921 48.4711 25.2355 47.6421 25.8468 47.0308C26.4581 46.4195 27.2871 46.0761 28.1516 46.0761ZM28.1516 49.3356V52.5952H31.4112V49.3356H28.1516ZM41.0757 46.0761H44.4493L39.6741 59.1142H36.3004L41.0757 46.0761ZM49.3386 46.0761H54.2279V49.3356H49.3386V55.8547H54.2279V59.1142H49.3386C48.4741 59.1142 47.645 58.7708 47.0337 58.1595C46.4225 57.5482 46.079 56.7192 46.079 55.8547V49.3356C46.079 48.4711 46.4225 47.6421 47.0337 47.0308C47.645 46.4195 48.4741 46.0761 49.3386 46.0761Z" fill="black"/> +</g> +<defs> +<clipPath id="clip0_11856_14985"> +<rect width="40" height="40" fill="white" transform="translate(20 20)"/> +</clipPath> +</defs> +</svg> diff --git a/src/assets/icons/visu/equipments/BOILER.svg b/src/assets/icons/visu/equipments/BOILER.svg new file mode 100644 index 000000000..4dd459049 --- /dev/null +++ b/src/assets/icons/visu/equipments/BOILER.svg @@ -0,0 +1,4 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M30 22C28.8954 22 28 22.8954 28 24V55C28 55.9835 28.7099 56.8012 29.6452 56.9686C29.6576 56.9349 29.6707 56.9012 29.6844 56.8676L32.13 50.8676C32.5904 49.7383 33.6886 49 34.9081 49L45.1646 49.0001C46.3025 49.0001 47.3425 49.6438 47.8498 50.6623L50.839 56.6622C50.8597 56.7039 50.8794 56.7456 50.898 56.7876C51.5516 56.4586 52 55.7816 52 55V24C52 22.8954 51.1046 22 50 22H30ZM50.4248 56.9548C50.4141 56.9315 50.403 56.9083 50.3914 56.8852L47.4023 50.8853C46.9795 50.0365 46.1129 49.5001 45.1646 49.5001L34.9081 49.5C33.8918 49.5 32.9767 50.1152 32.5931 51.0564L30.1704 57H50C50.1458 57 50.2879 56.9844 50.4248 56.9548ZM36.5 55C37.3284 55 38 54.3284 38 53.5C38 52.6716 37.3284 52 36.5 52C35.6716 52 35 52.6716 35 53.5C35 54.3284 35.6716 55 36.5 55ZM45 53.5C45 54.3284 44.3284 55 43.5 55C42.6716 55 42 54.3284 42 53.5C42 52.6716 42.6716 52 43.5 52C44.3284 52 45 52.6716 45 53.5ZM40.8549 28.4812L40 29L39.1451 28.4812L40 27.0726L40.8549 28.4812ZM40 43C37.5838 43 35.625 41.0412 35.625 38.625C35.625 36.7598 38.232 32.0388 39.4211 29.9825C39.7724 29.3749 40 29 40 29C40 29 40.2275 29.3749 40.5789 29.9825C41.768 32.0388 44.375 36.7598 44.375 38.625C44.375 41.0412 42.4162 43 40 43ZM40 43C38.5503 43 37.375 41.8982 37.375 40.5391C37.375 39.1799 40 35.125 40 35.125C40 35.125 42.625 39.1799 42.625 40.5391C42.625 41.8982 41.4497 43 40 43ZM40.855 28.4814C40.8549 28.4813 40.8549 28.4812 40 29C39.1451 28.4812 39.1451 28.4813 39.145 28.4814L39.1448 28.4818L39.144 28.483L39.1413 28.4874L39.1313 28.504L39.0934 28.5669C39.0605 28.6218 39.0126 28.702 38.9518 28.8046C38.8302 29.0097 38.657 29.3046 38.4494 29.6658C38.0347 30.3873 37.4805 31.3768 36.9252 32.4452C36.3715 33.5105 35.8084 34.6697 35.3814 35.7273C34.9725 36.7397 34.625 37.8061 34.625 38.625C34.625 41.5935 37.0315 44 40 44C42.9685 44 45.375 41.5935 45.375 38.625C45.375 37.8061 45.0275 36.7397 44.6186 35.7273C44.1916 34.6697 43.6285 33.5105 43.0748 32.4452C42.5195 31.3768 41.9653 30.3873 41.5506 29.6658C41.343 29.3046 41.1698 29.0097 41.0482 28.8046C40.9874 28.702 40.9395 28.6218 40.9066 28.5669L40.8687 28.504L40.8587 28.4874L40.856 28.483L40.8552 28.4818L40.855 28.4814Z" fill="#121212"/> +</svg> diff --git a/src/assets/icons/visu/equipments/COMPUTER.svg b/src/assets/icons/visu/equipments/COMPUTER.svg new file mode 100644 index 000000000..31de04839 --- /dev/null +++ b/src/assets/icons/visu/equipments/COMPUTER.svg @@ -0,0 +1,4 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M25.2595 49.8167H54.5953V28.6298C54.5953 28.1975 54.4236 27.783 54.118 27.4773C53.8123 27.1717 53.3978 27 52.9655 27H26.8893C26.4571 27 26.0425 27.1717 25.7369 27.4773C25.4312 27.783 25.2595 28.1975 25.2595 28.6298V49.8167ZM23.6298 53.0762H56.2251C57.8548 53.0762 57.8548 51.4465 57.8548 51.4465H22C22 51.4465 22 53.0762 23.6298 53.0762Z" stroke="black" stroke-width="2"/> +</svg> diff --git a/src/assets/icons/visu/equipments/COOKING_PLATES.svg b/src/assets/icons/visu/equipments/COOKING_PLATES.svg new file mode 100644 index 000000000..d952c919a --- /dev/null +++ b/src/assets/icons/visu/equipments/COOKING_PLATES.svg @@ -0,0 +1,6 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M37 33C37 34.6569 35.6569 36 34 36C32.3431 36 31 34.6569 31 33C31 31.3431 32.3431 30 34 30C35.6569 30 37 31.3431 37 33Z" fill="black"/> +<path d="M34 50C35.6569 50 37 48.6569 37 47C37 45.3431 35.6569 44 34 44C32.3431 44 31 45.3431 31 47C31 48.6569 32.3431 50 34 50Z" fill="black"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M24 52L24 28C24 26.9391 24.3477 25.9217 24.9665 25.1716C25.5854 24.4214 26.4248 24 27.3 24L53.7 24C54.5752 24 55.4146 24.4214 56.0334 25.1716C56.6523 25.9217 57 26.9391 57 28V52C57 53.0609 56.6523 54.0783 56.0334 54.8284C55.4146 55.5786 54.5752 56 53.7 56H27.3C26.4248 56 25.5854 55.5786 24.9665 54.8284C24.3477 54.0783 24 53.0609 24 52ZM52 33C52 34.1046 51.1046 35 50 35C48.8954 35 48 34.1046 48 33C48 31.8954 48.8954 31 50 31C51.1046 31 52 31.8954 52 33ZM40 33C40 36.3137 37.3137 39 34 39C30.6863 39 28 36.3137 28 33C28 29.6863 30.6863 27 34 27C37.3137 27 40 29.6863 40 33ZM34 53C37.3137 53 40 50.3137 40 47C40 43.6863 37.3137 41 34 41C30.6863 41 28 43.6863 28 47C28 50.3137 30.6863 53 34 53ZM50 49C51.1046 49 52 48.1046 52 47C52 45.8954 51.1046 45 50 45C48.8954 45 48 45.8954 48 47C48 48.1046 48.8954 49 50 49Z" fill="black"/> +</svg> diff --git a/src/assets/icons/visu/equipments/CURTAIN.svg b/src/assets/icons/visu/equipments/CURTAIN.svg new file mode 100644 index 000000000..c78577fe3 --- /dev/null +++ b/src/assets/icons/visu/equipments/CURTAIN.svg @@ -0,0 +1,8 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<rect x="23" y="28" width="34" height="1" rx="0.5" fill="#121212"/> +<path d="M27 30V53H33C33 50 32 47.5 30 45.5C37.5 42 40 33.3333 40 30H27Z" fill="#121212"/> +<path d="M53 30V53H46.5C46.5 50 48 47.5 50 45.5C42.5 42 40 33.3333 40 30H53Z" fill="#121212"/> +<circle cx="24.5" cy="28.5" r="1.5" fill="#121212"/> +<circle cx="55.5" cy="28.5" r="1.5" fill="#121212"/> +</svg> diff --git a/src/assets/icons/visu/equipments/DISHWASHER.svg b/src/assets/icons/visu/equipments/DISHWASHER.svg new file mode 100644 index 000000000..5f1a3de3c --- /dev/null +++ b/src/assets/icons/visu/equipments/DISHWASHER.svg @@ -0,0 +1,4 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M49.4529 23.2598H29.8958C29.0313 23.2598 28.2022 23.6032 27.5909 24.2145C26.9796 24.8257 26.6362 25.6548 26.6362 26.5193V52.5955C26.6362 53.46 26.9796 54.2891 27.5909 54.9004C28.2022 55.5117 29.0313 55.8551 29.8958 55.8551H49.4529C50.3174 55.8551 51.1465 55.5117 51.7578 54.9004C52.3691 54.2891 52.7125 53.46 52.7125 52.5955V26.5193C52.7125 25.6548 52.3691 24.8257 51.7578 24.2145C51.1465 23.6032 50.3174 23.2598 49.4529 23.2598ZM36.4148 26.5193C36.8471 26.5193 37.2616 26.691 37.5672 26.9966C37.8729 27.3023 38.0446 27.7168 38.0446 28.1491C38.0446 28.5813 37.8729 28.9958 37.5672 29.3015C37.2616 29.6071 36.8471 29.7788 36.4148 29.7788C35.9826 29.7788 35.568 29.6071 35.2624 29.3015C34.9568 28.9958 34.7851 28.5813 34.7851 28.1491C34.7851 27.7168 34.9568 27.3023 35.2624 26.9966C35.568 26.691 35.9826 26.5193 36.4148 26.5193ZM31.5255 26.5193C31.9578 26.5193 32.3723 26.691 32.6779 26.9966C32.9836 27.3023 33.1553 27.7168 33.1553 28.1491C33.1553 28.5813 32.9836 28.9958 32.6779 29.3015C32.3723 29.6071 31.9578 29.7788 31.5255 29.7788C31.0933 29.7788 30.6787 29.6071 30.3731 29.3015C30.0675 28.9958 29.8958 28.5813 29.8958 28.1491C29.8958 27.7168 30.0675 27.3023 30.3731 26.9966C30.6787 26.691 31.0933 26.5193 31.5255 26.5193ZM49.4529 52.5955H29.8958V33.0384H49.4529V52.5955ZM44.0258 44.9845C44.0584 46.1254 43.6021 47.2336 42.7872 48.0485C42.3785 48.4575 41.8933 48.782 41.3592 49.0033C40.825 49.2247 40.2525 49.3387 39.6744 49.3387C39.0962 49.3387 38.5237 49.2247 37.9895 49.0033C37.4554 48.782 36.9702 48.4575 36.5615 48.0485C35.7466 47.2336 35.2903 46.1254 35.3229 44.9845C35.437 43.8274 35.8118 42.7192 36.4148 41.725C37.0178 40.3723 37.7349 39.1174 38.5824 37.9277L39.6744 36.2979C42.5916 40.519 44.0258 43.4037 44.0258 44.9845Z" fill="black"/> +</svg> diff --git a/src/assets/icons/visu/equipments/DRYER.svg b/src/assets/icons/visu/equipments/DRYER.svg new file mode 100644 index 000000000..9046a92ce --- /dev/null +++ b/src/assets/icons/visu/equipments/DRYER.svg @@ -0,0 +1,4 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M30.2595 24H49.8167C50.6812 24 51.5103 24.3434 52.1215 24.9547C52.7328 25.566 53.0762 26.395 53.0762 27.2595V53.3358C53.0762 54.2003 52.7328 55.0293 52.1215 55.6406C51.5103 56.2519 50.6812 56.5953 49.8167 56.5953H30.2595C29.395 56.5953 28.566 56.2519 27.9547 55.6406C27.3434 55.0293 27 54.2003 27 53.3358V27.2595C27 26.395 27.3434 25.566 27.9547 24.9547C28.566 24.3434 29.395 24 30.2595 24ZM31.8893 27.2595C31.4571 27.2595 31.0425 27.4312 30.7369 27.7369C30.4312 28.0425 30.2595 28.4571 30.2595 28.8893C30.2595 29.3215 30.4312 29.7361 30.7369 30.0417C31.0425 30.3474 31.4571 30.5191 31.8893 30.5191C32.3215 30.5191 32.7361 30.3474 33.0417 30.0417C33.3474 29.7361 33.5191 29.3215 33.5191 28.8893C33.5191 28.4571 33.3474 28.0425 33.0417 27.7369C32.7361 27.4312 32.3215 27.2595 31.8893 27.2595ZM36.7786 27.2595C36.3464 27.2595 35.9318 27.4312 35.6262 27.7369C35.3205 28.0425 35.1488 28.4571 35.1488 28.8893C35.1488 29.3215 35.3205 29.7361 35.6262 30.0417C35.9318 30.3474 36.3464 30.5191 36.7786 30.5191C37.2108 30.5191 37.6254 30.3474 37.931 30.0417C38.2366 29.7361 38.4084 29.3215 38.4084 28.8893C38.4084 28.4571 38.2366 28.0425 37.931 27.7369C37.6254 27.4312 37.2108 27.2595 36.7786 27.2595ZM40.0381 33.7786C37.4447 33.7786 34.9575 34.8088 33.1236 36.6427C31.2898 38.4765 30.2595 40.9637 30.2595 43.5572C30.2595 46.1506 31.2898 48.6379 33.1236 50.4717C34.9575 52.3055 37.4447 53.3358 40.0381 53.3358C42.6316 53.3358 45.1188 52.3055 46.9526 50.4717C48.7865 48.6379 49.8167 46.1506 49.8167 43.5572C49.8167 40.9637 48.7865 38.4765 46.9526 36.6427C45.1188 34.8088 42.6316 33.7786 40.0381 33.7786ZM33.6063 38.7135C33.6394 38.2179 34.0668 37.853 34.5636 37.853H35.5897C36.2105 37.853 36.6723 38.4133 36.6389 39.0332C36.5557 40.5803 36.9578 41.5812 37.7239 42.4C39.337 43.9692 40.132 45.9079 39.9545 48.4061C39.9194 48.8995 39.4931 49.2614 38.9984 49.2614H37.9675C37.3467 49.2614 36.8849 48.7011 36.9183 48.0812C37.0015 46.534 36.5994 45.5332 35.8333 44.7143C34.2213 43.1462 33.4394 41.2092 33.6063 38.7135ZM40.1254 38.7135C40.1585 38.2179 40.5859 37.853 41.0826 37.853H42.1087C42.7295 37.853 43.1913 38.4133 43.158 39.0332C43.0747 40.5803 43.4769 41.5812 44.2429 42.4C45.8561 43.9692 46.6511 45.9079 46.4736 48.4061C46.4385 48.8995 46.0121 49.2614 45.5174 49.2614H44.4866C43.8658 49.2614 43.404 48.7011 43.4373 48.0812C43.5206 46.534 43.1184 45.5332 42.3524 44.7143C40.7403 43.1462 39.9585 41.2092 40.1254 38.7135Z" fill="black"/> +</svg> diff --git a/src/assets/icons/visu/equipments/FAN.svg b/src/assets/icons/visu/equipments/FAN.svg new file mode 100644 index 000000000..223faf7dc --- /dev/null +++ b/src/assets/icons/visu/equipments/FAN.svg @@ -0,0 +1,4 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M40 23.0013C32.8224 23.0013 27 28.7863 27 35.9253C27 43.0604 32.8237 48.8481 40 48.8507C47.175 48.8481 53 43.0604 53 35.9253C53 28.785 47.1723 23 40 23V23.0013ZM40 24.4831C46.351 24.4831 51.5096 29.6069 51.5096 35.9253C51.5096 42.2425 46.3536 47.3662 40 47.3689C36.9476 47.3689 34.0203 46.1633 31.8619 44.0173C29.7036 41.8714 28.491 38.9608 28.491 35.926C28.491 32.8912 29.7036 29.9806 31.8619 27.8347C34.0203 25.6887 36.9476 24.4831 40 24.4831ZM36.7291 26.6644C35.1712 26.8158 33.6172 28.8113 34.5764 30.6159C35.4772 32.3071 37.3531 32.1438 37.9294 34.0734C38.4659 33.3411 39.5271 32.5139 41.3248 33.374C42.4879 29.0906 40.0331 26.3509 36.7291 26.6644ZM47.3684 33.9088C45.4475 33.8363 44.6168 35.5276 42.6495 35.0613C43.0165 35.8871 43.2218 37.2346 41.5725 38.3542C44.7215 41.4956 48.309 40.7383 49.6881 37.7365C50.3359 36.3205 49.4218 33.9825 47.3697 33.9088H47.3684ZM39.6688 34.2381C38.8872 34.3961 38.303 35.1008 38.303 35.9253C38.303 36.8684 39.0515 37.6126 40 37.6126C40.9485 37.6126 41.697 36.8684 41.697 35.9253C41.697 34.9823 40.9485 34.2381 40 34.2381C39.8808 34.2381 39.7801 34.2143 39.6688 34.2381ZM37.1014 36.0492C32.7906 37.1885 31.6566 40.6869 33.5828 43.3752C34.4916 44.641 37.0034 44.9822 38.095 43.2514C39.119 41.6339 38.0287 40.1034 39.4198 38.6413C38.5176 38.5452 37.2511 38.0275 37.1014 36.0492ZM37.3505 50.4142C37.3505 53.0498 32.0514 53.5016 32.0514 55.6828V57H47.9486V55.6828C47.9486 53.5016 42.6495 53.0498 42.6495 50.4142C42.6495 50.4142 42.1475 50.8264 40 50.8264C37.8525 50.8264 37.3505 50.4142 37.3505 50.4142Z" fill="black"/> +</svg> diff --git a/src/assets/icons/visu/equipments/FREEZER.svg b/src/assets/icons/visu/equipments/FREEZER.svg new file mode 100644 index 000000000..745f827e0 --- /dev/null +++ b/src/assets/icons/visu/equipments/FREEZER.svg @@ -0,0 +1,7 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M27 57H31C31 57.5523 30.5523 58 30 58H28C27.4477 58 27 57.5523 27 57Z" fill="black"/> +<path d="M49 57H53C53 57.5523 52.5523 58 52 58H50C49.4477 58 49 57.5523 49 57Z" fill="black"/> +<path d="M24 35C24 34.4477 24.4477 34 25 34H55C55.5523 34 56 34.4477 56 35V38H24V35Z" fill="black"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M24 39H56V56C56 56.5523 55.5523 57 55 57H25C24.4477 57 24 56.5523 24 56V39ZM35.0502 43.5355C34.855 43.3403 34.855 43.0237 35.0502 42.8284C35.2455 42.6332 35.5621 42.6332 35.7573 42.8284L36.8989 43.97L37.1196 43.1467C37.1553 43.0133 37.2924 42.9342 37.4257 42.9699C37.5591 43.0056 37.6383 43.1427 37.6025 43.2761L37.3072 44.3783L38.0746 45.1457L38.2686 44.4218L38.1204 44.3363C38.0009 44.2673 37.9599 44.1144 38.0289 43.9948C38.098 43.8752 38.2509 43.8342 38.3704 43.9033L38.4026 43.9218L38.4122 43.886C38.4479 43.7526 38.585 43.6735 38.7184 43.7092C38.8517 43.745 38.9309 43.8821 38.8951 44.0154L38.8509 44.1807L39.4999 44.5554V43.47L38.5117 42.8995C38.3921 42.8305 38.3511 42.6776 38.4202 42.558C38.4892 42.4384 38.6421 42.3974 38.7617 42.4665L39.4999 42.8927V41.2782C39.4999 41.2609 39.5007 41.2439 39.5025 41.2271C39.5281 40.9749 39.741 40.7782 39.9999 40.7782C40.276 40.7782 40.4999 41.002 40.4999 41.2782V42.8927L41.2381 42.4665C41.3576 42.3974 41.5105 42.4384 41.5796 42.558C41.6486 42.6776 41.6076 42.8305 41.4881 42.8995L40.4999 43.47V44.5554L41.1489 44.1807L41.1046 44.0154C41.0689 43.8821 41.148 43.745 41.2814 43.7092C41.4147 43.6735 41.5518 43.7526 41.5876 43.886L41.5972 43.9218L41.6293 43.9033C41.7489 43.8342 41.9018 43.8752 41.9708 43.9948C42.0399 44.1144 41.9989 44.2673 41.8793 44.3363L41.7311 44.4218L41.9251 45.1457L42.6926 44.3783L42.3972 43.2761C42.3615 43.1427 42.4406 43.0056 42.574 42.9699C42.7074 42.9342 42.8445 43.0133 42.8802 43.1467L43.1008 43.97L44.2424 42.8284C44.4377 42.6332 44.7543 42.6332 44.9495 42.8284C45.1448 43.0237 45.1448 43.3403 44.9495 43.5355L44.9495 43.5355L43.8079 44.6771L44.6313 44.8978C44.7646 44.9335 44.8438 45.0706 44.808 45.2039C44.7723 45.3373 44.6352 45.4165 44.5019 45.3807L43.3997 45.0854L42.6322 45.8528L43.3563 46.0469L43.4418 45.8988C43.5108 45.7792 43.6637 45.7382 43.7833 45.8072C43.9028 45.8763 43.9438 46.0292 43.8748 46.1488L43.8563 46.1808L43.8919 46.1904C44.0253 46.2261 44.1044 46.3632 44.0687 46.4966C44.033 46.6299 43.8959 46.7091 43.7625 46.6734L43.5974 46.6291L43.2227 47.2782H44.308L44.8786 46.29C44.9476 46.1704 45.1005 46.1295 45.2201 46.1985C45.3397 46.2675 45.3806 46.4204 45.3116 46.54L44.8854 47.2782H46.4999C46.776 47.2782 46.9999 47.5021 46.9999 47.7782C46.9999 48.0543 46.776 48.2782 46.4999 48.2782H44.8854L45.3116 49.0164C45.3806 49.136 45.3397 49.2889 45.2201 49.3579C45.1005 49.4269 44.9476 49.386 44.8786 49.2664L44.308 48.2782H43.2227L43.5974 48.9272L43.7626 48.8829C43.896 48.8472 44.0331 48.9263 44.0688 49.0597C44.1046 49.1931 44.0254 49.3301 43.8921 49.3659L43.8562 49.3755L43.8748 49.4076C43.9438 49.5272 43.9028 49.6801 43.7833 49.7491C43.6637 49.8182 43.5108 49.7772 43.4418 49.6576L43.3562 49.5095L42.6323 49.7034L43.3998 50.4709L44.502 50.1755C44.6353 50.1398 44.7724 50.219 44.8082 50.3523C44.8439 50.4857 44.7647 50.6228 44.6314 50.6585L43.808 50.8791L44.9496 52.0207C45.1449 52.216 45.1449 52.5326 44.9496 52.7278C44.7544 52.9231 44.4378 52.9231 44.2425 52.7278L43.1009 51.5862L42.8803 52.4096C42.8446 52.5429 42.7075 52.6221 42.5741 52.5864C42.4408 52.5506 42.3616 52.4135 42.3973 52.2802L42.6927 51.178L41.9252 50.4105L41.7312 51.1346L41.8793 51.2201C41.9989 51.2891 42.0399 51.442 41.9708 51.5616C41.9018 51.6812 41.7489 51.7221 41.6293 51.6531L41.5972 51.6346L41.5877 51.6703C41.5519 51.8036 41.4149 51.8828 41.2815 51.847C41.1481 51.8113 41.069 51.6742 41.1047 51.5408L41.1489 51.3758L40.4999 51.001V52.0864L41.4881 52.6569C41.6076 52.7259 41.6486 52.8788 41.5796 52.9984C41.5105 53.118 41.3576 53.1589 41.2381 53.0899L40.4999 52.6637V54.2782C40.4999 54.5543 40.276 54.7782 39.9999 54.7782C39.7237 54.7782 39.4999 54.5543 39.4999 54.2782V52.6637L38.7617 53.0899C38.6421 53.1589 38.4892 53.118 38.4202 52.9984C38.3511 52.8788 38.3921 52.7259 38.5117 52.6569L39.4999 52.0864V51.001L38.8508 51.3758L38.895 51.5408C38.9308 51.6742 38.8516 51.8113 38.7183 51.847C38.5849 51.8828 38.4478 51.8036 38.4121 51.6703L38.4025 51.6346L38.3704 51.6531C38.2509 51.7221 38.098 51.6812 38.0289 51.5616C37.9599 51.442 38.0009 51.2891 38.1204 51.2201L38.2685 51.1346L38.0745 50.4105L37.3071 51.178L37.6024 52.2802C37.6381 52.4135 37.559 52.5506 37.4256 52.5864C37.2923 52.6221 37.1552 52.5429 37.1194 52.4096L36.8988 51.5862L35.7572 52.7278C35.562 52.9231 35.2454 52.9231 35.0501 52.7278C34.8548 52.5326 34.8548 52.216 35.0501 52.0207L36.1917 50.8791L35.3684 50.6585C35.235 50.6228 35.1559 50.4857 35.1916 50.3523C35.2273 50.219 35.3644 50.1398 35.4978 50.1755L36.6 50.4709L37.3674 49.7034L36.6435 49.5095L36.558 49.6576C36.4889 49.7772 36.336 49.8182 36.2165 49.7491C36.0969 49.6801 36.0559 49.5272 36.125 49.4076L36.1435 49.3755L36.1077 49.3659C35.9743 49.3301 35.8952 49.1931 35.9309 49.0597C35.9667 48.9263 36.1037 48.8472 36.2371 48.8829L36.4023 48.9272L36.777 48.2782H35.6917L35.1212 49.2664C35.0521 49.386 34.8992 49.4269 34.7797 49.3579C34.6601 49.2889 34.6191 49.136 34.6882 49.0164L35.1144 48.2782H33.4999C33.2237 48.2782 32.9999 48.0543 32.9999 47.7782C32.9999 47.5021 33.2237 47.2782 33.4999 47.2782H35.1144L34.6882 46.54C34.6191 46.4204 34.6601 46.2675 34.7797 46.1985C34.8992 46.1295 35.0521 46.1704 35.1212 46.29L35.6917 47.2782H36.777L36.4023 46.6291L36.2372 46.6734C36.1039 46.7091 35.9668 46.6299 35.931 46.4966C35.8953 46.3632 35.9744 46.2261 36.1078 46.1904L36.1435 46.1808L36.125 46.1488C36.0559 46.0292 36.0969 45.8763 36.2165 45.8072C36.336 45.7382 36.4889 45.7792 36.558 45.8988L36.6435 46.0469L37.3675 45.8528L36.6001 45.0854L35.4979 45.3807C35.3645 45.4165 35.2274 45.3373 35.1917 45.2039C35.156 45.0706 35.2351 44.9335 35.3685 44.8978L36.1918 44.6771L35.0502 43.5355ZM40.4999 45.1327L41.2828 44.6807L41.5169 45.554L40.4999 46.571V45.1327ZM42.224 46.2611L41.2069 47.2782H42.6453L43.0974 46.4951L42.224 46.2611ZM38.7926 48.2782L37.7757 49.2952L36.9023 49.0612L37.3544 48.2782H38.7926ZM39.4999 48.9852L38.4828 50.0023L38.7168 50.8758L39.4999 50.4237V48.9852ZM41.517 50.0023L41.2829 50.8758L40.4999 50.4237V48.9852L41.517 50.0023ZM39.4999 46.571V45.1327L38.7169 44.6807L38.4829 45.554L39.4999 46.571ZM42.6453 48.2782H41.2071L42.2241 49.2952L43.0974 49.0612L42.6453 48.2782ZM38.7929 47.2782H37.3544L36.9023 46.4951L37.7758 46.2611L38.7929 47.2782Z" fill="black"/> +</svg> diff --git a/src/assets/icons/visu/equipments/GARDEN.svg b/src/assets/icons/visu/equipments/GARDEN.svg new file mode 100644 index 000000000..beccf9fd1 --- /dev/null +++ b/src/assets/icons/visu/equipments/GARDEN.svg @@ -0,0 +1,8 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M28 30.0563L30.1425 26.4855C30.5309 25.8382 31.4691 25.8382 31.8575 26.4855L34 30.0563V36H28V30.0563ZM28 40V45H34V40H28ZM28 49H34V54.0563H28V49Z" fill="#121212"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M37 30.0563L39.1425 26.4855C39.5309 25.8382 40.4691 25.8382 40.8575 26.4855L43 30.0563V36H37V30.0563ZM37 40V45H43V40H37ZM37 49H43V54.0563H37V49Z" fill="#121212"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M46 30.0563L48.1425 26.4855C48.5309 25.8382 49.4691 25.8382 49.8575 26.4855L52 30.0563V36H46V30.0563ZM46 40V45H52V40H46ZM46 49H52V54.0563H46V49Z" fill="#121212"/> +<rect x="25" y="37.0566" width="30" height="3" fill="#121212"/> +<rect x="25" y="46.0566" width="30" height="3" fill="#121212"/> +</svg> diff --git a/src/assets/icons/visu/equipments/HYDRAULIC_HEATING.svg b/src/assets/icons/visu/equipments/HYDRAULIC_HEATING.svg new file mode 100644 index 000000000..90729613e --- /dev/null +++ b/src/assets/icons/visu/equipments/HYDRAULIC_HEATING.svg @@ -0,0 +1,8 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M30 36C30 35.4477 30.4477 35 31 35H34C34.5523 35 35 35.4477 35 36V38H36V36C36 35.4477 36.4477 35 37 35H40C40.5523 35 41 35.4477 41 36V38H42V36C42 35.4477 42.4477 35 43 35H46C46.5523 35 47 35.4477 47 36V38H48V36C48 35.4477 48.4477 35 49 35H52C52.5523 35 53 35.4477 53 36V38H54C54.5523 38 55 38.4477 55 39C55 39.5523 54.5523 40 54 40H53V47H54C54.5523 47 55 47.4477 55 48C55 48.5523 54.5523 49 54 49H53V51C53 51.5523 52.5523 52 52 52H49C48.4477 52 48 51.5523 48 51V49H47V51C47 51.5523 46.5523 52 46 52H43C42.4477 52 42 51.5523 42 51V49H41V51C41 51.5523 40.5523 52 40 52H37C36.4477 52 36 51.5523 36 51V49H35V51C35 51.3706 34.7984 51.6941 34.4989 51.8668C34.4996 51.8279 34.5 51.789 34.5 51.75C34.5 49.913 33.2795 48.5575 32.229 47.3906L32.1159 47.2649C31.3601 46.424 30.5995 45.5709 30 44.5358L30 40C29.4477 40 29 39.5523 29 39C29 38.4477 29.4477 38 30 38V36ZM30 46.3203C30.4497 46.9071 30.923 47.4337 31.3712 47.9323L31.372 47.9333C32.5182 49.209 33.5 50.3019 33.5 51.75C33.5 51.8336 33.498 51.9169 33.4941 52H31C30.4477 52 30 51.5523 30 51L30 49C29.4477 49 29 48.5523 29 48C29 47.4477 29.4477 47 30 47L30 46.3203ZM48 40V47H47V40H48ZM42 40V47H41V40H42ZM36 40V47H35V40H36Z" fill="#121212"/> +<path d="M35.3106 24H34.9556C34.4583 24 34.0287 24.3655 34.0072 24.8623C33.9257 26.743 34.5375 28.2145 35.7586 29.4129C36.3158 30.0138 36.6267 30.739 36.615 31.8197C36.6083 32.4399 37.0646 33 37.6848 33H38.0445C38.5397 33 38.9683 32.6375 38.9916 32.1428C39.0805 30.2597 38.4589 28.7866 37.2368 27.5871C36.6796 26.9862 36.3686 26.261 36.3804 25.1803C36.3871 24.5601 35.9307 24 35.3106 24Z" fill="black"/> +<path d="M40.3106 24H39.9556C39.4583 24 39.0287 24.3655 39.0072 24.8623C38.9257 26.743 39.5375 28.2145 40.7586 29.4129C41.3158 30.0138 41.6267 30.739 41.615 31.8197C41.6083 32.4399 42.0646 33 42.6848 33H43.0445C43.5397 33 43.9683 32.6375 43.9916 32.1428C44.0805 30.2597 43.4589 28.7866 42.2368 27.5871C41.6796 26.9862 41.3686 26.261 41.3804 25.1803C41.3871 24.5601 40.9307 24 40.3106 24Z" fill="black"/> +<path d="M45.3106 24H44.9556C44.4583 24 44.0287 24.3655 44.0072 24.8623C43.9257 26.743 44.5375 28.2145 45.7586 29.4129C46.3158 30.0138 46.6267 30.739 46.615 31.8197C46.6083 32.4399 47.0646 33 47.6848 33H48.0445C48.5397 33 48.9683 32.6375 48.9916 32.1428C49.0805 30.2597 48.4589 28.7866 47.2368 27.5871C46.6796 26.9862 46.3686 26.261 46.3804 25.1803C46.3871 24.5601 45.9307 24 45.3106 24Z" fill="black"/> +<path d="M28.25 57C29.6424 57 30.9777 56.4469 31.9623 55.4623C32.9469 54.4777 33.5 53.1424 33.5 51.75C33.5 50.3019 32.5182 49.209 31.372 47.9332C30.2222 46.654 28.9062 45.1901 28.25 43C28.25 43 23 47.9752 23 51.75C23 53.1424 23.5531 54.4777 24.5377 55.4623C25.5223 56.4469 26.8576 57 28.25 57ZM27.0652 47.0652L27.6848 47.6848C27.431 47.9385 26.6978 48.8319 26.0161 50.196L25.2339 49.804C25.9514 48.3681 26.7362 47.3951 27.0652 47.0652Z" fill="black"/> +</svg> diff --git a/src/assets/icons/visu/equipments/INTERNET_BOX.svg b/src/assets/icons/visu/equipments/INTERNET_BOX.svg new file mode 100644 index 000000000..5bb72ae4d --- /dev/null +++ b/src/assets/icons/visu/equipments/INTERNET_BOX.svg @@ -0,0 +1,11 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<rect x="26" y="44" width="2" height="2" rx="1" fill="#121212"/> +<rect x="52" y="44" width="2" height="2" rx="1" fill="#121212"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M23 39C23 37.8954 23.8954 37 25 37H55C56.1046 37 57 37.8954 57 39V44C57 44.5523 56.5523 45 56 45H24C23.4477 45 23 44.5523 23 44V39ZM26 39H36V43H26V39ZM46 41C45.4477 41 45 41.4477 45 42C45 42.5523 45.4477 43 46 43C46.5523 43 47 42.5523 47 42C47 41.4477 46.5523 41 46 41ZM49 42C49 41.4477 49.4477 41 50 41C50.5523 41 51 41.4477 51 42C51 42.5523 50.5523 43 50 43C49.4477 43 49 42.5523 49 42ZM54 41C53.4477 41 53 41.4477 53 42C53 42.5523 53.4477 43 54 43C54.5523 43 55 42.5523 55 42C55 41.4477 54.5523 41 54 41Z" fill="#121212"/> +<rect x="27" y="40" width="1" height="2" fill="#121212"/> +<rect x="31" y="40" width="1" height="2" fill="#121212"/> +<rect x="34" y="40" width="1" height="2" fill="#121212"/> +<rect x="30" y="40" width="1" height="1" fill="#121212"/> +<rect x="28" y="41" width="1" height="1" fill="#121212"/> +</svg> diff --git a/src/assets/icons/visu/equipments/MICROWAVE.svg b/src/assets/icons/visu/equipments/MICROWAVE.svg new file mode 100644 index 000000000..5036c0f7d --- /dev/null +++ b/src/assets/icons/visu/equipments/MICROWAVE.svg @@ -0,0 +1,4 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M32.1661 36.5298C31.6463 36.8436 30.9296 36.91 30.4988 36.4822L29.6591 35.6484C29.2807 35.2727 29.2596 34.6597 29.6679 34.3168C30.4005 33.7013 31.5055 33.0381 32.8624 33.0381C34.1662 33.0381 35.1277 33.6737 35.8122 34.13C36.3175 34.4723 36.6434 34.6679 36.9368 34.6679C37.1637 34.6679 37.4045 34.5732 37.6296 34.4378C38.1511 34.1241 38.87 34.0587 39.3004 34.489L40.1285 35.3171C40.5045 35.6932 40.5245 36.3043 40.1177 36.6468C39.386 37.2628 38.2833 37.9274 36.9368 37.9274C35.6493 37.9274 34.704 37.3081 34.0195 36.8518C33.4817 36.4932 33.172 36.2976 32.8624 36.2976C32.6343 36.2976 32.3922 36.3932 32.1661 36.5298ZM32.8624 44.4465C33.172 44.4465 33.4817 44.642 34.0195 45.0006C34.704 45.4569 35.6493 46.0762 36.9368 46.0762C38.2941 46.0762 39.391 45.4125 40.1189 44.7969C40.525 44.4535 40.5045 43.842 40.1285 43.4659L39.3004 42.6378C38.87 42.2075 38.1481 42.2696 37.627 42.5839C37.4001 42.7208 37.1591 42.8167 36.9368 42.8167C36.6434 42.8167 36.3175 42.6211 35.8122 42.2789C35.1277 41.8225 34.1662 41.1869 32.8624 41.1869C31.504 41.1869 30.398 41.8517 29.6653 42.4677C29.2583 42.81 29.2783 43.4211 29.6544 43.7972L30.5078 44.6506C30.9292 45.072 31.6235 45.0166 32.129 44.7008C32.3663 44.5526 32.6221 44.4465 32.8624 44.4465ZM56.0865 29.7786V49.3358C56.0865 51.1285 54.6197 52.5953 52.827 52.5953H26.7507C24.958 52.5953 23.4912 51.1285 23.4912 49.3358V29.7786C23.4912 27.9858 24.958 26.519 26.7507 26.519H52.827C54.6197 26.519 56.0865 27.9858 56.0865 29.7786ZM43.0484 29.7786H26.7507V49.3358H43.0484V29.7786ZM51.1972 46.0762C51.1972 45.1799 50.4638 44.4465 49.5675 44.4465C48.6711 44.4465 47.9377 45.1799 47.9377 46.0762C47.9377 46.9726 48.6711 47.706 49.5675 47.706C50.4638 47.706 51.1972 46.9726 51.1972 46.0762ZM51.1972 39.5572C51.1972 38.6608 50.4638 37.9274 49.5675 37.9274C48.6711 37.9274 47.9377 38.6608 47.9377 39.5572C47.9377 40.4535 48.6711 41.1869 49.5675 41.1869C50.4638 41.1869 51.1972 40.4535 51.1972 39.5572ZM51.1972 31.4083H47.9377V34.6679H51.1972V31.4083Z" fill="black"/> +</svg> diff --git a/src/assets/icons/visu/equipments/REFREGIRATOR.svg b/src/assets/icons/visu/equipments/REFREGIRATOR.svg new file mode 100644 index 000000000..0701bef10 --- /dev/null +++ b/src/assets/icons/visu/equipments/REFREGIRATOR.svg @@ -0,0 +1,4 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M32.2595 21H48.5572C49.4217 21 50.2507 21.3434 50.862 21.9547C51.4733 22.566 51.8167 23.395 51.8167 24.2595V32.4084H29V24.2595C29 23.395 29.3434 22.566 29.9547 21.9547C30.566 21.3434 31.395 21 32.2595 21ZM51.8167 54.1107C51.8167 54.9752 51.4733 55.8043 50.862 56.4155C50.2507 57.0268 49.4217 57.3702 48.5572 57.3702V59H45.2977V57.3702H35.5191V59H32.2595V57.3702C31.395 57.3702 30.566 57.0268 29.9547 56.4155C29.3434 55.8043 29 54.9752 29 54.1107V34.0381H51.8167V54.1107ZM33.8893 25.8893V29.1488H37.1488V25.8893H33.8893ZM33.8893 37.2977V42.1869H37.1488V37.2977H33.8893Z" fill="black"/> +</svg> diff --git a/src/assets/icons/visu/equipments/VENTILATION.svg b/src/assets/icons/visu/equipments/VENTILATION.svg new file mode 100644 index 000000000..6998a08c0 --- /dev/null +++ b/src/assets/icons/visu/equipments/VENTILATION.svg @@ -0,0 +1,4 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M43.6437 50.9951C43.1757 52.4827 41.9554 53.703 40.4677 54.171C37.9437 54.9734 35.5534 53.7866 34.4669 51.7974C33.8818 50.7109 34.751 49.4071 35.988 49.4071H36.0047C36.573 49.4071 37.1413 49.6745 37.4088 50.176C37.693 50.7109 38.2446 51.0786 38.8965 51.0786C39.8158 51.0786 40.568 50.3264 40.568 49.4071C40.568 48.4877 39.8158 47.7355 38.8965 47.7355H24.6716C23.7522 47.7355 23 46.9833 23 46.064C23 45.1446 23.7522 44.3924 24.6716 44.3924H38.8798C42.156 44.3924 44.7302 47.5684 43.6437 50.9951ZM51.266 30.4684C51.0146 29.4218 50.4788 28.4651 49.7177 27.704C48.9566 26.9429 47.9999 26.4071 46.9534 26.1558C44.0114 25.4871 41.3202 27.0417 40.2337 29.4654C39.7155 30.5854 40.5179 31.8558 41.7381 31.8558C42.39 31.8558 42.9918 31.488 43.2425 30.903C43.4317 30.4425 43.7537 30.0487 44.1675 29.7718C44.5813 29.495 45.0681 29.3476 45.566 29.3484C46.9534 29.3484 48.0733 30.4684 48.0733 31.8558C48.0733 33.2432 46.9534 34.3631 45.566 34.3631H24.6716C23.7522 34.3631 23 35.1153 23 36.0347C23 36.954 23.7522 37.7062 24.6716 37.7062H45.566C49.2434 37.7062 52.1352 34.2962 51.266 30.4684ZM50.4135 39.3778H24.6716C23.7522 39.3778 23 40.13 23 41.0493C23 41.9687 23.7522 42.7209 24.6716 42.7209H50.5806C51.968 42.7209 53.088 43.8408 53.088 45.2282C53.0888 45.7261 52.9414 46.2129 52.6646 46.6267C52.3877 47.0405 51.9939 47.3625 51.5334 47.5517C50.9317 47.8024 50.5806 48.4042 50.5806 49.0561C50.5806 50.2763 51.851 51.0786 52.971 50.5772C54.1951 50.0292 55.1946 49.0784 55.8029 47.8831C56.4112 46.6878 56.5916 45.3201 56.3141 44.008C55.7457 41.2666 53.205 39.3778 50.4135 39.3778Z" fill="black"/> +</svg> diff --git a/src/assets/icons/visu/equipments/WASHING_MACHINE.svg b/src/assets/icons/visu/equipments/WASHING_MACHINE.svg new file mode 100644 index 000000000..bce9a3fe4 --- /dev/null +++ b/src/assets/icons/visu/equipments/WASHING_MACHINE.svg @@ -0,0 +1,4 @@ +<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="80" height="80" rx="4" fill="#E0E0E0"/> +<path d="M44.6504 38.9449C45.8713 40.1694 46.5569 41.828 46.5569 43.5572C46.5569 45.2863 45.8713 46.945 44.6504 48.1694C43.4259 49.3904 41.7673 50.076 40.0381 50.076C38.309 50.076 36.6503 49.3904 35.4259 48.1694L44.6504 38.9449ZM30.2595 24H49.8167C50.6812 24 51.5103 24.3434 52.1215 24.9547C52.7328 25.566 53.0762 26.395 53.0762 27.2595V53.3358C53.0762 54.2003 52.7328 55.0293 52.1215 55.6406C51.5103 56.2519 50.6812 56.5953 49.8167 56.5953H30.2595C29.395 56.5953 28.566 56.2519 27.9547 55.6406C27.3434 55.0293 27 54.2003 27 53.3358V27.2595C27 26.395 27.3434 25.566 27.9547 24.9547C28.566 24.3434 29.395 24 30.2595 24ZM31.8893 27.2595C31.4571 27.2595 31.0425 27.4312 30.7369 27.7369C30.4312 28.0425 30.2595 28.4571 30.2595 28.8893C30.2595 29.3215 30.4312 29.7361 30.7369 30.0417C31.0425 30.3474 31.4571 30.5191 31.8893 30.5191C32.3215 30.5191 32.7361 30.3474 33.0417 30.0417C33.3474 29.7361 33.5191 29.3215 33.5191 28.8893C33.5191 28.4571 33.3474 28.0425 33.0417 27.7369C32.7361 27.4312 32.3215 27.2595 31.8893 27.2595ZM36.7786 27.2595C36.3464 27.2595 35.9318 27.4312 35.6262 27.7369C35.3205 28.0425 35.1488 28.4571 35.1488 28.8893C35.1488 29.3215 35.3205 29.7361 35.6262 30.0417C35.9318 30.3474 36.3464 30.5191 36.7786 30.5191C37.2108 30.5191 37.6254 30.3474 37.931 30.0417C38.2366 29.7361 38.4084 29.3215 38.4084 28.8893C38.4084 28.4571 38.2366 28.0425 37.931 27.7369C37.6254 27.4312 37.2108 27.2595 36.7786 27.2595ZM40.0381 33.7786C37.4447 33.7786 34.9575 34.8088 33.1236 36.6427C31.2898 38.4765 30.2595 40.9637 30.2595 43.5572C30.2595 46.1506 31.2898 48.6379 33.1236 50.4717C34.9575 52.3055 37.4447 53.3358 40.0381 53.3358C42.6316 53.3358 45.1188 52.3055 46.9526 50.4717C48.7865 48.6379 49.8167 46.1506 49.8167 43.5572C49.8167 40.9637 48.7865 38.4765 46.9526 36.6427C45.1188 34.8088 42.6316 33.7786 40.0381 33.7786Z" fill="black"/> +</svg> diff --git a/src/components/App.tsx b/src/components/App.tsx index 171fcd7bc..86d54f5d4 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -16,7 +16,9 @@ import WelcomeModal from 'components/Onboarding/WelcomeModal' export const history = createBrowserHistory() export const App = () => { - const { onboarding } = useSelector((state: AppStore) => state.ecolyo.profile) + const { onboarding, isProfileEcogestureCompleted } = useSelector( + (state: AppStore) => state.ecolyo.profile + ) const { termsStatus } = useSelector((state: AppStore) => state.ecolyo.global) return ( @@ -34,7 +36,10 @@ export const App = () => { )} <Main> <Content className="app-content"> - <Routes termsStatus={termsStatus} /> + <Routes + termsStatus={termsStatus} + isProfileEcogestureCompleted={isProfileEcogestureCompleted} + /> </Content> </Main> </SplashRoot> diff --git a/src/components/Ecogesture/EcogestureEmptyList.spec.tsx b/src/components/Ecogesture/EcogestureEmptyList.spec.tsx index 79aa75d28..f629d559a 100644 --- a/src/components/Ecogesture/EcogestureEmptyList.spec.tsx +++ b/src/components/Ecogesture/EcogestureEmptyList.spec.tsx @@ -17,7 +17,13 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => { }), } }) - +const mockHistoryPush = jest.fn() +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useHistory: () => ({ + push: mockHistoryPush, + }), +})) const mockStore = configureStore([]) const mockChangeTab = jest.fn() describe('EcogestureEmptyList component', () => { @@ -53,7 +59,7 @@ describe('EcogestureEmptyList component', () => { .simulate('click') expect(mockChangeTab).toHaveBeenCalledTimes(1) }) - it('should return to all ecogestures', () => { + it('should launch ecogesture form', () => { const store = mockStore({ ecolyo: { profile: profileData, @@ -69,6 +75,6 @@ describe('EcogestureEmptyList component', () => { .find(Button) .at(1) .simulate('click') - //test tinder launch + expect(mockHistoryPush).toHaveBeenCalledWith('/ecogesture-form') }) }) diff --git a/src/components/Ecogesture/EcogestureEmptyList.tsx b/src/components/Ecogesture/EcogestureEmptyList.tsx index 1e79cd763..11140d735 100644 --- a/src/components/Ecogesture/EcogestureEmptyList.tsx +++ b/src/components/Ecogesture/EcogestureEmptyList.tsx @@ -6,6 +6,7 @@ import doingIcon from 'assets/icons/ico/doing-enabled.svg' import objectiveIcon from 'assets/icons/ico/objective-enabled.svg' import './ecogestureEmptyList.scss' +import { useHistory } from 'react-router-dom' interface EcogestureEmptyListProps { setTab: React.Dispatch<React.SetStateAction<number>> @@ -16,7 +17,7 @@ const EcogestureEmptyList: React.FC<EcogestureEmptyListProps> = ({ isObjective, }: EcogestureEmptyListProps) => { const { t } = useI18n() - + const history = useHistory() return ( <div className="ec-empty-container"> <div className="ec-empty-content"> @@ -49,7 +50,7 @@ const EcogestureEmptyList: React.FC<EcogestureEmptyListProps> = ({ <Button aria-label={t('ecogesture.emptyList.btn2')} onClick={() => { - console.log('tinder') + history.push('/ecogesture-form') }} classes={{ root: 'btn-highlight', diff --git a/src/components/Ecogesture/EcogestureInitModal.spec.tsx b/src/components/Ecogesture/EcogestureInitModal.spec.tsx index 5a87a6f1e..298dd9d93 100644 --- a/src/components/Ecogesture/EcogestureInitModal.spec.tsx +++ b/src/components/Ecogesture/EcogestureInitModal.spec.tsx @@ -36,6 +36,7 @@ jest.mock('react-router-dom', () => ({ const mockStore = configureStore([]) const mockHandleClose = jest.fn() +const mockHandleLaunchForm = jest.fn() describe('EcogestureInitModal component', () => { it('should be rendered correctly', () => { const store = mockStore({ @@ -48,12 +49,16 @@ describe('EcogestureInitModal component', () => { const wrapper = mount( <Provider store={store}> - <EcogestureInitModal open={true} handleCloseClick={mockHandleClose} /> + <EcogestureInitModal + open={true} + handleCloseClick={mockHandleClose} + handleLaunchForm={mockHandleLaunchForm} + /> </Provider> ) expect(toJson(wrapper)).toMatchSnapshot() }) - it('should go back ', () => { + it('should close modal ', () => { const store = mockStore({ ecolyo: { global: globalStateData, @@ -64,16 +69,20 @@ describe('EcogestureInitModal component', () => { const wrapper = mount( <Provider store={store}> - <EcogestureInitModal open={true} handleCloseClick={mockHandleClose} /> + <EcogestureInitModal + open={true} + handleCloseClick={mockHandleClose} + handleLaunchForm={mockHandleLaunchForm} + /> </Provider> ) wrapper .find(Button) .first() .simulate('click') - expect(mockHistoryPush).toHaveBeenCalledWith('/consumption') + expect(mockHandleClose).toHaveBeenCalledTimes(1) }) - it('should close modal and update profile', async () => { + it('should close modal and maunch form', async () => { const store = mockStore({ ecolyo: { global: globalStateData, @@ -84,13 +93,17 @@ describe('EcogestureInitModal component', () => { const wrapper = mount( <Provider store={store}> - <EcogestureInitModal open={true} handleCloseClick={mockHandleClose} /> + <EcogestureInitModal + open={true} + handleCloseClick={mockHandleClose} + handleLaunchForm={mockHandleLaunchForm} + /> </Provider> ) wrapper .find(Button) .at(1) .simulate('click') - expect(mockHandleClose).toHaveBeenCalledTimes(1) + expect(mockHandleLaunchForm).toHaveBeenCalledTimes(1) }) }) diff --git a/src/components/Ecogesture/EcogestureInitModal.tsx b/src/components/Ecogesture/EcogestureInitModal.tsx index 6eebbbfac..3993af59e 100644 --- a/src/components/Ecogesture/EcogestureInitModal.tsx +++ b/src/components/Ecogesture/EcogestureInitModal.tsx @@ -1,24 +1,21 @@ -import React, { useCallback } from 'react' +import React from 'react' 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' import './ecogestureInitModal.scss' -import { useHistory } from 'react-router-dom' interface EcogestureInitModalProps { open: boolean handleCloseClick: () => void + handleLaunchForm: () => void } const EcogestureInitModal: React.FC<EcogestureInitModalProps> = ({ open, handleCloseClick, + handleLaunchForm, }: EcogestureInitModalProps) => { - const history = useHistory() const { t } = useI18n() - const goBack = useCallback(() => { - history.push('/consumption') - }, [history]) return ( <Dialog open={open} @@ -52,7 +49,7 @@ const EcogestureInitModal: React.FC<EcogestureInitModalProps> = ({ <div className="buttons-container"> <Button aria-label={t('ecogesture.initModal.btn1')} - onClick={goBack} + onClick={handleCloseClick} className="btn1" classes={{ root: 'btn-secondary-negative', @@ -63,7 +60,7 @@ const EcogestureInitModal: React.FC<EcogestureInitModalProps> = ({ </Button> <Button aria-label={t('ecogesture.initModal.btn2')} - onClick={handleCloseClick} + onClick={handleLaunchForm} classes={{ root: 'btn-profile-next rounded', label: 'text-16-bold', diff --git a/src/components/Ecogesture/EcogestureView.tsx b/src/components/Ecogesture/EcogestureView.tsx index 94c4a3381..5e52ea9e4 100644 --- a/src/components/Ecogesture/EcogestureView.tsx +++ b/src/components/Ecogesture/EcogestureView.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react' -import { useClient, useQuery } from 'cozy-client' +import { useClient } from 'cozy-client' import EcogestureList from 'components/Ecogesture/EcogestureList' import CozyBar from 'components/Header/CozyBar' import Header from 'components/Header/Header' @@ -73,10 +73,15 @@ const EcogestureView: React.FC = () => { boolean >(!haveSeenEcogestureModal) + const handleLaunchForm = useCallback(async () => { + dispatch(updateProfile({ haveSeenEcogestureModal: true })) + setOpenEcogestureInitModal(false) + history.push('/ecogesture-form?modal=false') + }, [dispatch, history]) + const handleCloseEcogestureInitModal = useCallback(async () => { dispatch(updateProfile({ haveSeenEcogestureModal: true })) setOpenEcogestureInitModal(false) - //TODO go to tinder ecogesture }, [dispatch]) const handleChange = useCallback( @@ -214,6 +219,7 @@ const EcogestureView: React.FC = () => { <EcogestureInitModal open={openEcogestureInitModal} handleCloseClick={handleCloseEcogestureInitModal} + handleLaunchForm={handleLaunchForm} /> )} </> diff --git a/src/components/Ecogesture/__snapshots__/EcogestureInitModal.spec.tsx.snap b/src/components/Ecogesture/__snapshots__/EcogestureInitModal.spec.tsx.snap index e5b3f77a5..84d7f0843 100644 --- a/src/components/Ecogesture/__snapshots__/EcogestureInitModal.spec.tsx.snap +++ b/src/components/Ecogesture/__snapshots__/EcogestureInitModal.spec.tsx.snap @@ -15,6 +15,7 @@ exports[`EcogestureInitModal component should be rendered correctly 1`] = ` > <EcogestureInitModal handleCloseClick={[MockFunction]} + handleLaunchForm={[MockFunction]} open={true} > <WithStyles(ForwardRef(Dialog)) @@ -861,7 +862,7 @@ exports[`EcogestureInitModal component should be rendered correctly 1`] = ` "root": "btn-secondary-negative", } } - onClick={[Function]} + onClick={[MockFunction]} > <ForwardRef(Button) aria-label="ecogesture.initModal.btn1" @@ -899,7 +900,7 @@ exports[`EcogestureInitModal component should be rendered correctly 1`] = ` "textSizeSmall": "MuiButton-textSizeSmall", } } - onClick={[Function]} + onClick={[MockFunction]} > <WithStyles(ForwardRef(ButtonBase)) aria-label="ecogesture.initModal.btn1" @@ -908,7 +909,7 @@ exports[`EcogestureInitModal component should be rendered correctly 1`] = ` disabled={false} focusRipple={true} focusVisibleClassName="Mui-focusVisible" - onClick={[Function]} + onClick={[MockFunction]} type="button" > <ForwardRef(ButtonBase) @@ -925,7 +926,7 @@ exports[`EcogestureInitModal component should be rendered correctly 1`] = ` disabled={false} focusRipple={true} focusVisibleClassName="Mui-focusVisible" - onClick={[Function]} + onClick={[MockFunction]} type="button" > <button @@ -933,7 +934,7 @@ exports[`EcogestureInitModal component should be rendered correctly 1`] = ` className="MuiButtonBase-root MuiButton-root btn-secondary-negative MuiButton-text btn1" disabled={false} onBlur={[Function]} - onClick={[Function]} + onClick={[MockFunction]} onDragLeave={[Function]} onFocus={[Function]} onKeyDown={[Function]} diff --git a/src/components/Ecogesture/__snapshots__/EcogestureList.spec.tsx.snap b/src/components/Ecogesture/__snapshots__/EcogestureList.spec.tsx.snap index 5bd3246ca..530fde834 100644 --- a/src/components/Ecogesture/__snapshots__/EcogestureList.spec.tsx.snap +++ b/src/components/Ecogesture/__snapshots__/EcogestureList.spec.tsx.snap @@ -82,7 +82,7 @@ exports[`EcogesturesList component should be rendered correctly 1`] = ` "equipment": true, "equipmentInstallation": true, "equipmentType": Array [ - 0, + "AIR_CONDITIONING", ], "fluidTypes": Array [ 0, @@ -113,8 +113,8 @@ exports[`EcogesturesList component should be rendered correctly 1`] = ` "equipment": false, "equipmentInstallation": true, "equipmentType": Array [ - 4, - 5, + "WASHING_MACHINE", + "DISHWASHER", ], "fluidTypes": Array [ 1, @@ -1880,7 +1880,7 @@ exports[`EcogesturesList component should be rendered correctly 1`] = ` "equipment": true, "equipmentInstallation": true, "equipmentType": Array [ - 0, + "AIR_CONDITIONING", ], "fluidTypes": Array [ 0, @@ -1916,8 +1916,8 @@ exports[`EcogesturesList component should be rendered correctly 1`] = ` "equipment": false, "equipmentInstallation": true, "equipmentType": Array [ - 4, - 5, + "WASHING_MACHINE", + "DISHWASHER", ], "fluidTypes": Array [ 1, diff --git a/src/components/Ecogesture/__snapshots__/EcogestureView.spec.tsx.snap b/src/components/Ecogesture/__snapshots__/EcogestureView.spec.tsx.snap index 2930dc1c9..d915c155c 100644 --- a/src/components/Ecogesture/__snapshots__/EcogestureView.spec.tsx.snap +++ b/src/components/Ecogesture/__snapshots__/EcogestureView.spec.tsx.snap @@ -1286,7 +1286,7 @@ exports[`EcogestureView component should be rendered correctly 1`] = ` "equipment": true, "equipmentInstallation": true, "equipmentType": Array [ - 0, + "AIR_CONDITIONING", ], "fluidTypes": Array [ 0, @@ -1317,8 +1317,8 @@ exports[`EcogestureView component should be rendered correctly 1`] = ` "equipment": false, "equipmentInstallation": true, "equipmentType": Array [ - 4, - 5, + "WASHING_MACHINE", + "DISHWASHER", ], "fluidTypes": Array [ 1, diff --git a/src/components/Ecogesture/ecogestureView.scss b/src/components/Ecogesture/ecogestureView.scss index 048a4fc2d..9206f18f6 100644 --- a/src/components/Ecogesture/ecogestureView.scss +++ b/src/components/Ecogesture/ecogestureView.scss @@ -1,4 +1,5 @@ @import 'src/styles/base/color'; +@import 'src/styles/base/breakpoint'; .ecogesture-spinner { display: flex; @@ -6,6 +7,9 @@ justify-content: center; align-items: center; min-height: inherit; + @media all and(min-width: $width-tablet) { + min-height: 80vh; + } } .ecogestures-tabs { background: transparent; diff --git a/src/components/Ecogesture/singleEcogesture.scss b/src/components/Ecogesture/singleEcogesture.scss index 2c4d323fc..0ae3efe90 100644 --- a/src/components/Ecogesture/singleEcogesture.scss +++ b/src/components/Ecogesture/singleEcogesture.scss @@ -1,10 +1,14 @@ @import 'src/styles/base/color'; +@import 'src/styles/base/breakpoint'; .se-loader-container { min-height: inherit; display: flex; justify-content: center; align-items: center; + @media all and(min-width: $width-tablet) { + min-height: 80vh; + } } .single-ecogesture { color: $grey-bright; diff --git a/src/components/EcogestureForm/EcogestureFormEquipment.spec.tsx b/src/components/EcogestureForm/EcogestureFormEquipment.spec.tsx new file mode 100644 index 000000000..b03d7b959 --- /dev/null +++ b/src/components/EcogestureForm/EcogestureFormEquipment.spec.tsx @@ -0,0 +1,145 @@ +import React from 'react' +import { mount } from 'enzyme' +import * as reactRedux from 'react-redux' +import toJson from 'enzyme-to-json' +import { Provider } from 'react-redux' +import configureStore from 'redux-mock-store' +import { challengeStateData } from '../../../tests/__mocks__/challengeStateData.mock' +import { globalStateData } from '../../../tests/__mocks__/globalStateData.mock' +import { waitForComponentToPaint } from '../../../tests/__mocks__/testUtils' +import EcogestureFormEquipment from './EcogestureFormEquipment' +import { mockProfileEcogesture } from '../../../tests/__mocks__/profileEcogesture.mock' +import { Button } from '@material-ui/core' + +jest.mock('cozy-ui/transpiled/react/I18n', () => { + return { + useI18n: jest.fn(() => { + return { + t: (str: string) => str, + } + }), + } +}) +const mockStore = configureStore([]) +const mockSetPreviousStep = jest.fn() + +const mockHistoryPush = jest.fn() +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useHistory: () => ({ + push: mockHistoryPush, + }), +})) +jest.mock('./EquipmentIcon', () => 'mock-equipment-icon') +const mockUseDispatch = jest.spyOn(reactRedux, 'useDispatch') + +describe('EcogestureFormEquipment component', () => { + it('should be rendered correctly', async () => { + const store = mockStore({ + ecolyo: { + global: globalStateData, + challenge: challengeStateData, + }, + }) + const wrapper = mount( + <Provider store={store}> + <EcogestureFormEquipment + profileEcogesture={mockProfileEcogesture} + setPreviousStep={mockSetPreviousStep} + /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + expect(toJson(wrapper)).toMatchSnapshot() + }) + it('should finish the form', async () => { + const store = mockStore({ + ecolyo: { + global: globalStateData, + challenge: challengeStateData, + }, + }) + mockUseDispatch.mockReturnValue(jest.fn()) + + const wrapper = mount( + <Provider store={store}> + <EcogestureFormEquipment + profileEcogesture={mockProfileEcogesture} + setPreviousStep={mockSetPreviousStep} + /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + wrapper + .find(Button) + .at(1) + .simulate('click') + expect(mockUseDispatch).toHaveBeenCalledTimes(2) + }) + it('should select equipment and unselect it', async () => { + const store = mockStore({ + ecolyo: { + global: globalStateData, + challenge: challengeStateData, + }, + }) + + const wrapper = mount( + <Provider store={store}> + <EcogestureFormEquipment + profileEcogesture={mockProfileEcogesture} + setPreviousStep={mockSetPreviousStep} + /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + wrapper + .find('.item-eq') + .first() + .simulate('change') + await waitForComponentToPaint(wrapper) + + expect( + wrapper + .find('.item-eq') + .first() + .hasClass('checked') + ).toBeTruthy + wrapper + .find('.checked') + .first() + .simulate('change') + await waitForComponentToPaint(wrapper) + expect( + wrapper + .find('.item-eq') + .first() + .hasClass('checked') + ).toBeFalsy() + }) + + it('should click on disabled back button', async () => { + const store = mockStore({ + ecolyo: { + global: globalStateData, + challenge: challengeStateData, + }, + }) + const wrapper = mount( + <Provider store={store}> + <EcogestureFormEquipment + profileEcogesture={mockProfileEcogesture} + setPreviousStep={mockSetPreviousStep} + /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + wrapper + .find(Button) + .first() + .simulate('click') + await waitForComponentToPaint(wrapper) + + expect(wrapper.find('.icons-container').exists()).toBeTruthy() + }) +}) diff --git a/src/components/EcogestureForm/EcogestureFormEquipment.tsx b/src/components/EcogestureForm/EcogestureFormEquipment.tsx new file mode 100644 index 000000000..e25e9b52a --- /dev/null +++ b/src/components/EcogestureForm/EcogestureFormEquipment.tsx @@ -0,0 +1,115 @@ +import React, { useCallback, useState } from 'react' +import 'components/ProfileType/profileTypeForm.scss' +import { useI18n } from 'cozy-ui/transpiled/react/I18n' +import FormNavigation from 'components/ProfileType/FormNavigation' +import { EcogestureStepForm } from 'enum/ecogestureForm.enum' +import { ProfileEcogesture } from 'models/profileEcogesture.model' +import { EquipmentType } from 'enum/ecogesture.enum' +import EquipmentIcon from './EquipmentIcon' +import './ecogestureFormEquipment.scss' +import { newProfileEcogestureEntry } from 'store/profileEcogesture/profileEcogesture.actions' +import { useDispatch } from 'react-redux' +import { updateProfile } from 'store/profile/profile.actions' +import { useHistory } from 'react-router-dom' + +interface EcogestureFormEquipmentProps { + profileEcogesture: ProfileEcogesture + setPreviousStep: Function +} + +const EcogestureFormEquipment: React.FC<EcogestureFormEquipmentProps> = ({ + profileEcogesture, + setPreviousStep, +}: EcogestureFormEquipmentProps) => { + const { t } = useI18n() + const dispatch = useDispatch() + const history = useHistory() + const [answer, setAnswer] = useState<string[]>([]) + + const handlePrevious = useCallback(() => { + setPreviousStep(profileEcogesture) + }, [profileEcogesture, setPreviousStep]) + + const handleFinish = useCallback(() => { + profileEcogesture.equipments = answer + dispatch(newProfileEcogestureEntry(profileEcogesture)) + dispatch(updateProfile({ isProfileEcogestureCompleted: true })) + history.push('/ecogesture-selection') + }, [profileEcogesture, answer, dispatch, history]) + + const isChecked = useCallback( + (value: string): boolean => { + if (answer.includes(value)) { + return true + } else { + return false + } + }, + [answer] + ) + + const handleChange = useCallback( + (value: string) => { + const tempAnswer: string[] = [...answer] + if (tempAnswer.includes(value)) { + const index = tempAnswer.indexOf(value) + if (index > -1) tempAnswer.splice(index, 1) + } else { + tempAnswer.push(value) + } + setAnswer(tempAnswer) + }, + [answer] + ) + + return ( + <> + <div className={'equipment-form-container'}> + <div className={'equipment-label text-22-normal'}> + {t( + `ecogesture_profile.${EcogestureStepForm[ + EcogestureStepForm.EQUIPMENTS + ].toLowerCase()}.question` + )} + </div> + <div className={'equipment-hint text-16-normal'}> + {t( + `ecogesture_profile.${EcogestureStepForm[ + EcogestureStepForm.EQUIPMENTS + ].toLowerCase()}.hint` + )} + </div> + <div className="icons-container"> + {Object.values(EquipmentType).map((equipment, index) => { + return ( + <label key={index} className={'checkbox-equipment'}> + <input + type={'checkbox'} + value={equipment} + name={equipment.toString()} + onChange={() => handleChange(equipment)} + checked={isChecked(equipment)} + className={ + isChecked(equipment) ? 'item-eq checked' : 'item-eq' + } + /> + <EquipmentIcon + equipment={equipment} + isChecked={answer.includes(equipment)} + /> + </label> + ) + })} + </div> + </div> + <FormNavigation + step={EcogestureStepForm.EQUIPMENTS} + handlePrevious={handlePrevious} + handleNext={handleFinish} + disableNextButton={answer === []} + /> + </> + ) +} + +export default EcogestureFormEquipment diff --git a/src/components/EcogestureForm/EcogestureFormSingleChoice.spec.tsx b/src/components/EcogestureForm/EcogestureFormSingleChoice.spec.tsx new file mode 100644 index 000000000..09853bbc8 --- /dev/null +++ b/src/components/EcogestureForm/EcogestureFormSingleChoice.spec.tsx @@ -0,0 +1,147 @@ +/* eslint-disable react/display-name */ +import React from 'react' +import { mount } from 'enzyme' +import { Provider } from 'react-redux' +import { + createMockStore, + mockInitialEcolyoState, +} from '../../../tests/__mocks__/store' +import toJson from 'enzyme-to-json' + +import { waitForComponentToPaint } from '../../../tests/__mocks__/testUtils' +import EcogestureFormSingleChoice from './EcogestureFormSingleChoice' +import { + mockEcogestureAnswer, + mockProfileEcogesture, +} from '../../../tests/__mocks__/profileEcogesture.mock' +import { Button } from '@material-ui/core' + +jest.mock('cozy-ui/transpiled/react/I18n', () => { + return { + useI18n: jest.fn(() => { + return { + t: (str: string) => str, + } + }), + } +}) + +jest.mock( + 'components/EcogestureForm/EcogestureLaunchFormModal', + () => 'mock-ecogesturelaunchmodal' +) + +const mockHandleNextStep = jest.fn() +const mockHandlePreviousStep = jest.fn() +describe('EcogestureFormSingleChoice component', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let store: any + beforeEach(() => { + store = createMockStore(mockInitialEcolyoState) + }) + + it('should be rendered correctly', async () => { + const wrapper = mount( + <Provider store={store}> + <EcogestureFormSingleChoice + step={0} + viewedStep={-1} + setNextStep={mockHandleNextStep} + setPrevioustStep={mockHandlePreviousStep} + profileEcogesture={mockProfileEcogesture} + answerType={mockEcogestureAnswer} + /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + expect(toJson(wrapper)).toMatchSnapshot() + }) + it('should click on disabled button', async () => { + const wrapper = mount( + <Provider store={store}> + <EcogestureFormSingleChoice + step={0} + viewedStep={-1} + setNextStep={mockHandleNextStep} + setPrevioustStep={mockHandlePreviousStep} + profileEcogesture={mockProfileEcogesture} + answerType={mockEcogestureAnswer} + /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + wrapper + .find(Button) + .first() + .simulate('click') + expect(mockHandlePreviousStep).toHaveBeenCalledTimes(0) + }) + + it('should pick a choice and go next', async () => { + const wrapper = mount( + <Provider store={store}> + <EcogestureFormSingleChoice + step={0} + viewedStep={-1} + setNextStep={mockHandleNextStep} + setPrevioustStep={mockHandlePreviousStep} + profileEcogesture={mockProfileEcogesture} + answerType={mockEcogestureAnswer} + /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + wrapper + .find('input') + .first() + .simulate('change') + await waitForComponentToPaint(wrapper) + wrapper + .find(Button) + .at(1) + .simulate('click') + + expect(mockHandleNextStep).toHaveBeenCalledTimes(1) + }) + it('should go back', async () => { + const wrapper = mount( + <Provider store={store}> + <EcogestureFormSingleChoice + step={1} + viewedStep={0} + setNextStep={mockHandleNextStep} + setPrevioustStep={mockHandlePreviousStep} + profileEcogesture={mockProfileEcogesture} + answerType={mockEcogestureAnswer} + /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + wrapper + .find(Button) + .first() + .simulate('click') + expect(mockHandlePreviousStep).toHaveBeenCalledTimes(1) + }) + it('should keep previous answer', async () => { + const wrapper = mount( + <Provider store={store}> + <EcogestureFormSingleChoice + step={0} + viewedStep={1} + setNextStep={mockHandleNextStep} + setPrevioustStep={mockHandlePreviousStep} + profileEcogesture={mockProfileEcogesture} + answerType={mockEcogestureAnswer} + /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + expect( + wrapper + .find('input') + .first() + .hasClass('checked-input') + ).toBe(true) + }) +}) diff --git a/src/components/EcogestureForm/EcogestureFormSingleChoice.tsx b/src/components/EcogestureForm/EcogestureFormSingleChoice.tsx new file mode 100644 index 000000000..8b3e538ab --- /dev/null +++ b/src/components/EcogestureForm/EcogestureFormSingleChoice.tsx @@ -0,0 +1,99 @@ +import React, { useCallback, useEffect, useState } from 'react' +import 'components/ProfileType/profileTypeForm.scss' +import { useI18n } from 'cozy-ui/transpiled/react/I18n' +import classNames from 'classnames' +import FormNavigation from 'components/ProfileType/FormNavigation' +import { EcogestureStepForm } from 'enum/ecogestureForm.enum' +import { + ProfileEcogesture, + ProfileEcogestureAnswer, + ProfileEcogestureAnswerChoices, +} from 'models/profileEcogesture.model' +import './ecogestureFormSingleChoice.scss' +interface EcogestureFormSingleChoiceProps { + step: EcogestureStepForm + viewedStep: EcogestureStepForm + profileEcogesture: ProfileEcogesture + answerType: ProfileEcogestureAnswer + setNextStep: Function + setPrevioustStep: Function +} + +const EcogestureFormSingleChoice: React.FC<EcogestureFormSingleChoiceProps> = ({ + step, + viewedStep, + profileEcogesture, + answerType, + setNextStep, + setPrevioustStep, +}: EcogestureFormSingleChoiceProps) => { + const { t } = useI18n() + const [answer, setAnswer] = useState<ProfileEcogestureAnswerChoices>('') + + const handlePrevious = useCallback(() => { + setPrevioustStep(profileEcogesture) + }, [profileEcogesture, setPrevioustStep]) + + const handleAnswer = useCallback((value: ProfileEcogestureAnswerChoices) => { + setAnswer(value) + }, []) + + const handleNext = useCallback(() => { + profileEcogesture[answerType.attribute] = answer + setNextStep(profileEcogesture) + }, [profileEcogesture, setNextStep, answer, answerType.attribute]) + + useEffect(() => { + if (step < viewedStep) { + setAnswer(profileEcogesture[answerType.attribute]) + } + }, [step, viewedStep, profileEcogesture, answerType]) + + return ( + <> + <div className={'profile-form-container ecogesture-form-single'}> + <div className={'profile-question-label'}> + {t( + `ecogesture_form.${EcogestureStepForm[step].toLowerCase()}.question` + )} + </div> + {answerType.choices.map( + (value: ProfileEcogestureAnswerChoices, index: number) => { + return value || value === 0 ? ( + <label + key={index} + className={classNames({ + ['radio_short']: answerType.choices.length < 5, + ['radio_long']: answerType.choices.length > 4, + ['answer-checked']: answer === value, + })} + > + <input + type={'radio'} + value={value} + name={value.toString()} + onChange={() => handleAnswer(value)} + checked={answer === value ? true : false} + className={answer === value ? 'checked-input' : ''} + /> + {t( + `ecogesture_form.${EcogestureStepForm[ + step + ].toLowerCase()}.${value}` + )} + </label> + ) : null + } + )} + </div> + <FormNavigation + step={step} + handlePrevious={handlePrevious} + handleNext={handleNext} + disableNextButton={answer === ''} + /> + </> + ) +} + +export default EcogestureFormSingleChoice diff --git a/src/components/EcogestureForm/EcogestureFormView.spec.tsx b/src/components/EcogestureForm/EcogestureFormView.spec.tsx new file mode 100644 index 000000000..8d6c77f09 --- /dev/null +++ b/src/components/EcogestureForm/EcogestureFormView.spec.tsx @@ -0,0 +1,136 @@ +/* eslint-disable react/display-name */ +import React from 'react' +import { mount } from 'enzyme' +import { Provider } from 'react-redux' +import { + createMockStore, + mockInitialEcolyoState, +} from '../../../tests/__mocks__/store' +import toJson from 'enzyme-to-json' + +import { waitForComponentToPaint } from '../../../tests/__mocks__/testUtils' +import EcogestureFormView from './EcogestureFormView' +import { Profile } from 'models' +import { Button } from '@material-ui/core' + +jest.mock('cozy-ui/transpiled/react/I18n', () => { + return { + useI18n: jest.fn(() => { + return { + t: (str: string) => str, + } + }), + } +}) + +jest.mock('components/Header/CozyBar', () => 'mock-cozybar') +jest.mock('components/Header/Header', () => 'mock-header') +jest.mock( + 'components/EcogestureForm/EcogestureLaunchFormModal', + () => 'mock-ecogesturelaunchmodal' +) +jest.mock( + 'components/EcogestureForm/EcogestureFormEquipment', + () => 'mock-ecogestureformequipment' +) +jest.mock('components/Content/Content', () => 'mock-content') + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useLocation: () => { + return { + search: '', + } + }, +})) +describe('EcogestureFormView component', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let store: any + beforeEach(() => { + store = createMockStore(mockInitialEcolyoState) + }) + + it('should be rendered correctly', async () => { + const wrapper = mount( + <Provider store={store}> + <EcogestureFormView /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + expect(toJson(wrapper)).toMatchSnapshot() + }) + it('should render singlechoice', async () => { + const wrapper = mount( + <Provider store={store}> + <EcogestureFormView /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + expect(wrapper.find('.ecogesture-form-single').exists()).toBeTruthy() + }) + it('should render equipment step because profiletype is completed', async () => { + const updatedProfile: Profile = { + ...mockInitialEcolyoState.profile, + isProfileTypeCompleted: true, + } + const updatedStore = { ...mockInitialEcolyoState, profile: updatedProfile } + const wrapper = mount( + <Provider store={createMockStore(updatedStore)}> + <EcogestureFormView /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + expect( + wrapper + .find('mock-ecogestureformequipment') + .first() + .exists() + ).toBeTruthy() + }) + it('should go to next step', async () => { + const wrapper = mount( + <Provider store={store}> + <EcogestureFormView /> + </Provider> + ) + await waitForComponentToPaint(wrapper) + wrapper + .find('input') + .first() + .simulate('change') + await waitForComponentToPaint(wrapper) + console.log(wrapper.debug()) + wrapper + .find(Button) + .at(1) + .simulate('click') + await waitForComponentToPaint(wrapper) + expect(wrapper.find('.ecogesture-form-single').exists()).toBeTruthy() + }) + it('should go to previous step', async () => { + const wrapper = mount( + <Provider store={store}> + <EcogestureFormView /> + </Provider> + ) + //go first to next step + await waitForComponentToPaint(wrapper) + wrapper + .find('input') + .first() + .simulate('change') + await waitForComponentToPaint(wrapper) + console.log(wrapper.debug()) + wrapper + .find(Button) + .at(1) + .simulate('click') + await waitForComponentToPaint(wrapper) + //then go back + wrapper + .find(Button) + .first() + .simulate('click') + expect(wrapper.find('.ecogesture-form-single').exists()).toBeTruthy() + }) +}) diff --git a/src/components/EcogestureForm/EcogestureFormView.tsx b/src/components/EcogestureForm/EcogestureFormView.tsx new file mode 100644 index 000000000..5f5e80505 --- /dev/null +++ b/src/components/EcogestureForm/EcogestureFormView.tsx @@ -0,0 +1,154 @@ +import React, { useCallback, useEffect, useState } from 'react' +import CozyBar from 'components/Header/CozyBar' +import Header from 'components/Header/Header' +import Content from 'components/Content/Content' +import { useSelector } from 'react-redux' +import { AppStore } from 'store' +import { + ProfileEcogestureAnswerType, + EcogestureStepForm, +} from 'enum/ecogestureForm.enum' +import EcogestureFormSingleChoice from 'components/EcogestureForm/EcogestureFormSingleChoice' +import EcogestureLaunchFormModal from 'components/EcogestureForm/EcogestureLaunchFormModal' +import EcogestureFormEquipment from 'components/EcogestureForm/EcogestureFormEquipment' +import { + ProfileEcogesture, + ProfileEcogestureAnswer, +} from 'models/profileEcogesture.model' +import { Profile, ProfileType } from 'models' +import ProfileEcogestureFormService from 'services/profileEcogestureForm.service' +import StyledSpinner from 'components/CommonKit/Spinner/StyledSpinner' +import { FluidType } from 'enum/fluid.enum' +import './ecogestureFormView.scss' +import { useLocation } from 'react-router-dom' + +const EcogestureFormView: React.FC = () => { + const [headerHeight, setHeaderHeight] = useState<number>(0) + const defineHeaderHeight = (height: number) => { + setHeaderHeight(height) + } + const { isProfileTypeCompleted }: Profile = useSelector( + (state: AppStore) => state.ecolyo.profile + ) + const curProfileEcogesture: ProfileEcogesture = useSelector( + (state: AppStore) => state.ecolyo.profileEcogesture + ) + const profileType: ProfileType = useSelector( + (state: AppStore) => state.ecolyo.profileType + ) + const shouldOpenModal = new URLSearchParams(useLocation().search).get('modal') + const [step, setStep] = useState<EcogestureStepForm>( + EcogestureStepForm.HEATING_TYPE + ) + const [answerType, setAnswerType] = useState<ProfileEcogestureAnswer>({ + type: ProfileEcogestureAnswerType.SINGLE_CHOICE, + attribute: '', + choices: [], + }) + + const [isLoading, setIsLoading] = useState<boolean>(true) + const [openLaunchModal, setOpenLaunchModal] = useState<boolean>( + shouldOpenModal !== 'false' ? true : false + ) + const [viewedStep, setViewedStep] = useState<number>(-1) + const [profileEcogesture, setProfileEcogesture] = useState<ProfileEcogesture>( + curProfileEcogesture + ) + const setNextStep = useCallback( + (_profileEcogesture: ProfileEcogesture) => { + setProfileEcogesture(_profileEcogesture) + const pefs = new ProfileEcogestureFormService(_profileEcogesture) + const nextStep: EcogestureStepForm = pefs.getNextFormStep(step) + setIsLoading(true) + if (nextStep > viewedStep) { + setViewedStep(nextStep) + } + const _answerType: ProfileEcogestureAnswer = ProfileEcogestureFormService.getAnswerForStep( + isProfileTypeCompleted ? EcogestureStepForm.EQUIPMENTS : nextStep + ) + setAnswerType(_answerType) + setStep(nextStep) + }, + [isProfileTypeCompleted, step, viewedStep] + ) + const setPreviousStep = useCallback( + (_profileEcogesture: ProfileEcogesture) => { + setProfileEcogesture(_profileEcogesture) + const pefs = new ProfileEcogestureFormService(_profileEcogesture) + const previousStep: EcogestureStepForm = pefs.getPreviousFormStep(step) + setIsLoading(true) + const _answerType: ProfileEcogestureAnswer = ProfileEcogestureFormService.getAnswerForStep( + previousStep + ) + setAnswerType(_answerType) + setStep(previousStep) + }, + [step] + ) + + useEffect(() => { + let subscribed = true + if (isProfileTypeCompleted) { + if (subscribed) { + curProfileEcogesture.heating = profileType.heating + curProfileEcogesture.hotWater = profileType.hotWater + curProfileEcogesture.warmingFluid = profileType.warmingFluid + setStep(EcogestureStepForm.EQUIPMENTS) + } + } + const _answerType: ProfileEcogestureAnswer = ProfileEcogestureFormService.getAnswerForStep( + isProfileTypeCompleted ? EcogestureStepForm.EQUIPMENTS : step + ) + setAnswerType(_answerType) + if (subscribed) { + setAnswerType(_answerType) + setIsLoading(false) + } + return () => { + subscribed = false + } + }, [step, curProfileEcogesture, isProfileTypeCompleted, profileType]) + + if (isLoading) { + return ( + <Content height={headerHeight}> + <div className="se-loader-container"> + <StyledSpinner size="5em" fluidType={FluidType.MULTIFLUID} /> + </div> + </Content> + ) + } + return ( + <> + <CozyBar titleKey={'common.title_ecogestures'} /> + <Header + setHeaderHeight={defineHeaderHeight} + desktopTitleKey={'common.title_ecogestures'} + ></Header> + <Content height={headerHeight}> + {step === EcogestureStepForm.EQUIPMENTS && ( + <EcogestureFormEquipment + profileEcogesture={profileEcogesture} + setPreviousStep={setPreviousStep} + /> + )} + {step !== EcogestureStepForm.EQUIPMENTS && ( + <EcogestureFormSingleChoice + step={step} + viewedStep={viewedStep} + profileEcogesture={profileEcogesture} + answerType={answerType} + setNextStep={setNextStep} + setPrevioustStep={setPreviousStep} + /> + )} + </Content> + <EcogestureLaunchFormModal + open={openLaunchModal} + handleCloseClick={() => setOpenLaunchModal(false)} + /> + </> + ) +} + +export default EcogestureFormView diff --git a/src/components/EcogestureForm/EcogestureLaunchFormModal.spec.tsx b/src/components/EcogestureForm/EcogestureLaunchFormModal.spec.tsx new file mode 100644 index 000000000..33e0bbaa3 --- /dev/null +++ b/src/components/EcogestureForm/EcogestureLaunchFormModal.spec.tsx @@ -0,0 +1,41 @@ +import React from 'react' +import { mount } from 'enzyme' +import toJson from 'enzyme-to-json' +import EcogestureLaunchFormModal from './EcogestureLaunchFormModal' +import { Button } from '@material-ui/core' + +jest.mock('cozy-ui/transpiled/react/I18n', () => { + return { + useI18n: jest.fn(() => { + return { + t: (str: string) => str, + } + }), + } +}) + +const mockHandleClose = jest.fn() +describe('EcogestureLaunchFormModal component', () => { + it('should be rendered correctly', () => { + const wrapper = mount( + <EcogestureLaunchFormModal + open={true} + handleCloseClick={mockHandleClose} + /> + ) + expect(toJson(wrapper)).toMatchSnapshot() + }) + it('should close modal', async () => { + const wrapper = mount( + <EcogestureLaunchFormModal + open={true} + handleCloseClick={mockHandleClose} + /> + ) + wrapper + .find(Button) + .first() + .simulate('click') + expect(mockHandleClose).toHaveBeenCalledTimes(1) + }) +}) diff --git a/src/components/EcogestureForm/EcogestureLaunchFormModal.tsx b/src/components/EcogestureForm/EcogestureLaunchFormModal.tsx new file mode 100644 index 000000000..1a0ff36d5 --- /dev/null +++ b/src/components/EcogestureForm/EcogestureLaunchFormModal.tsx @@ -0,0 +1,60 @@ +import React from 'react' +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' +import './ecogestureLaunchFormModal.scss' + +interface EcogestureLaunchFormModalProps { + open: boolean + handleCloseClick: () => void +} +const EcogestureLaunchFormModal: React.FC<EcogestureLaunchFormModalProps> = ({ + 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> + <IconButton + aria-label={t('feedback.accessibility.button_close')} + className="modal-paper-close-button" + onClick={handleCloseClick} + > + <Icon icon={CloseIcon} size={16} /> + </IconButton> + <div className="eg-init-modal"> + <div className="title text-20-bold"> + {t('ecogesture.initModal.title')} + </div> + <div className="text-16-normal text"> + {t('ecogesture.initModal.text3')} + </div> + <Button + aria-label={t('ecogesture.initModal.btn2')} + onClick={handleCloseClick} + classes={{ + root: 'btn-profile-next rounded', + label: 'text-16-bold', + }} + > + {t('ecogesture.initModal.btn2')} + </Button> + </div> + </Dialog> + ) +} + +export default EcogestureLaunchFormModal diff --git a/src/components/EcogestureForm/EcogestureSelection.tsx b/src/components/EcogestureForm/EcogestureSelection.tsx new file mode 100644 index 000000000..1cb1fa2cf --- /dev/null +++ b/src/components/EcogestureForm/EcogestureSelection.tsx @@ -0,0 +1,33 @@ +import React, { useEffect, useMemo } from 'react' +import 'components/ProfileType/profileTypeForm.scss' +import { useI18n } from 'cozy-ui/transpiled/react/I18n' +import { useClient } from 'cozy-client' +import EcogestureService from 'services/ecogesture.service' +import { ProfileEcogesture } from 'models/profileEcogesture.model' +import { useSelector } from 'react-redux' +import { AppStore } from 'store' + +const EcogestureSelection: React.FC = () => { + const { t } = useI18n() + const client = useClient() + + const ecogestureService = useMemo(() => new EcogestureService(client), [ + client, + ]) + const profileEcogesture: ProfileEcogesture = useSelector( + (state: AppStore) => state.ecolyo.profileEcogesture + ) + useEffect(() => { + async function getFilteredList() { + const filteredList = await ecogestureService.getEcogestureListByProfile( + profileEcogesture + ) + console.log('filtered', filteredList) + } + getFilteredList() + }, [ecogestureService, profileEcogesture]) + + return <div className="ecogesture-selection">Tinderr</div> +} + +export default EcogestureSelection diff --git a/src/components/EcogestureForm/EquipmentIcon.spec.tsx b/src/components/EcogestureForm/EquipmentIcon.spec.tsx new file mode 100644 index 000000000..8e341372e --- /dev/null +++ b/src/components/EcogestureForm/EquipmentIcon.spec.tsx @@ -0,0 +1,48 @@ +/* eslint-disable react/display-name */ +import React from 'react' +import { mount } from 'enzyme' +import toJson from 'enzyme-to-json' +import { waitForComponentToPaint } from '../../../tests/__mocks__/testUtils' +import EquipmentIcon from './EquipmentIcon' +import { EquipmentType } from 'enum/ecogesture.enum' + +jest.mock('cozy-ui/transpiled/react/I18n', () => { + return { + useI18n: jest.fn(() => { + return { + t: (str: string) => str, + } + }), + } +}) +const mockImportIconbyId = jest.fn() +jest.mock('utils/utils', () => { + return { + importIconbyId: jest.fn(() => { + return mockImportIconbyId + }), + } +}) +describe('EcogestureFormSingleChoice component', () => { + it('should be rendered correctly', async () => { + mockImportIconbyId.mockReturnValue('') + const wrapper = mount( + <EquipmentIcon equipment={EquipmentType.BOILER} isChecked={false} /> + ) + await waitForComponentToPaint(wrapper) + expect(toJson(wrapper)).toMatchSnapshot() + }) + it('should render checked icon', async () => { + mockImportIconbyId.mockReturnValue('') + const wrapper = mount( + <EquipmentIcon equipment={EquipmentType.BOILER} isChecked={true} /> + ) + await waitForComponentToPaint(wrapper) + expect( + wrapper + .find('.checked') + .first() + .exists() + ).toBeTruthy() + }) +}) diff --git a/src/components/EcogestureForm/EquipmentIcon.tsx b/src/components/EcogestureForm/EquipmentIcon.tsx new file mode 100644 index 000000000..945d3ea11 --- /dev/null +++ b/src/components/EcogestureForm/EquipmentIcon.tsx @@ -0,0 +1,45 @@ +import React, { useEffect, useState } from 'react' +import 'components/ProfileType/profileTypeForm.scss' +import { useI18n } from 'cozy-ui/transpiled/react/I18n' +import { importIconbyId } from 'utils/utils' +import Icon from 'cozy-ui/transpiled/react/Icon' + +interface EquipmentIconProps { + equipment: string + isChecked: boolean +} + +const EquipmentIcon: React.FC<EquipmentIconProps> = ({ + equipment, + isChecked, +}: EquipmentIconProps) => { + const { t } = useI18n() + const [icon, setIcon] = useState<string>('') + useEffect(() => { + let subscribed = true + async function getIcon() { + const svg = await importIconbyId(equipment, 'equipments') + if (subscribed && svg) { + setIcon(svg) + } + } + getIcon() + return () => { + subscribed = false + } + }, [equipment]) + return ( + <> + <Icon + icon={icon} + size={80} + className={isChecked ? 'equipmentIcon checked' : 'equipmentIcon'} + /> + <div className="text text-14-normal"> + {t(`ecogesture_profile.equipments.${equipment.toLocaleLowerCase()}`)} + </div> + </> + ) +} + +export default EquipmentIcon diff --git a/src/components/EcogestureForm/__snapshots__/EcogestureFormEquipment.spec.tsx.snap b/src/components/EcogestureForm/__snapshots__/EcogestureFormEquipment.spec.tsx.snap new file mode 100644 index 000000000..fb4b342c2 --- /dev/null +++ b/src/components/EcogestureForm/__snapshots__/EcogestureFormEquipment.spec.tsx.snap @@ -0,0 +1,587 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EcogestureFormEquipment component should be rendered correctly 1`] = ` +<Provider + store={ + Object { + "clearActions": [Function], + "dispatch": [Function], + "getActions": [Function], + "getState": [Function], + "replaceReducer": [Function], + "subscribe": [Function], + } + } +> + <EcogestureFormEquipment + profileEcogesture={ + Object { + "equipments": Array [], + "heating": "individual", + "hotWater": "individual", + "warmingFluid": 0, + } + } + setPreviousStep={[MockFunction]} + > + <div + className="equipment-form-container" + > + <div + className="equipment-label text-22-normal" + > + ecogesture_profile.equipments.question + </div> + <div + className="equipment-hint text-16-normal" + > + ecogesture_profile.equipments.hint + </div> + <div + className="icons-container" + > + <label + className="checkbox-equipment" + key="0" + > + <input + checked={false} + className="item-eq" + name="AIR_CONDITIONING" + onChange={[Function]} + type="checkbox" + value="AIR_CONDITIONING" + /> + <mock-equipment-icon + equipment="AIR_CONDITIONING" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="1" + > + <input + checked={false} + className="item-eq" + name="COMPUTER" + onChange={[Function]} + type="checkbox" + value="COMPUTER" + /> + <mock-equipment-icon + equipment="COMPUTER" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="2" + > + <input + checked={false} + className="item-eq" + name="MICROWAVE" + onChange={[Function]} + type="checkbox" + value="MICROWAVE" + /> + <mock-equipment-icon + equipment="MICROWAVE" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="3" + > + <input + checked={false} + className="item-eq" + name="WASHING_MACHINE" + onChange={[Function]} + type="checkbox" + value="WASHING_MACHINE" + /> + <mock-equipment-icon + equipment="WASHING_MACHINE" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="4" + > + <input + checked={false} + className="item-eq" + name="DISHWASHER" + onChange={[Function]} + type="checkbox" + value="DISHWASHER" + /> + <mock-equipment-icon + equipment="DISHWASHER" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="5" + > + <input + checked={false} + className="item-eq" + name="COOKING_PLATES" + onChange={[Function]} + type="checkbox" + value="COOKING_PLATES" + /> + <mock-equipment-icon + equipment="COOKING_PLATES" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="6" + > + <input + checked={false} + className="item-eq" + name="DRYER" + onChange={[Function]} + type="checkbox" + value="DRYER" + /> + <mock-equipment-icon + equipment="DRYER" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="7" + > + <input + checked={false} + className="item-eq" + name="REFREGIRATOR" + onChange={[Function]} + type="checkbox" + value="REFREGIRATOR" + /> + <mock-equipment-icon + equipment="REFREGIRATOR" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="8" + > + <input + checked={false} + className="item-eq" + name="FAN" + onChange={[Function]} + type="checkbox" + value="FAN" + /> + <mock-equipment-icon + equipment="FAN" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="9" + > + <input + checked={false} + className="item-eq" + name="CURTAIN" + onChange={[Function]} + type="checkbox" + value="CURTAIN" + /> + <mock-equipment-icon + equipment="CURTAIN" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="10" + > + <input + checked={false} + className="item-eq" + name="INTERNET_BOX" + onChange={[Function]} + type="checkbox" + value="INTERNET_BOX" + /> + <mock-equipment-icon + equipment="INTERNET_BOX" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="11" + > + <input + checked={false} + className="item-eq" + name="VENTILATION" + onChange={[Function]} + type="checkbox" + value="VENTILATION" + /> + <mock-equipment-icon + equipment="VENTILATION" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="12" + > + <input + checked={false} + className="item-eq" + name="FREEZER" + onChange={[Function]} + type="checkbox" + value="FREEZER" + /> + <mock-equipment-icon + equipment="FREEZER" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="13" + > + <input + checked={false} + className="item-eq" + name="BOILER" + onChange={[Function]} + type="checkbox" + value="BOILER" + /> + <mock-equipment-icon + equipment="BOILER" + isChecked={false} + /> + </label> + <label + className="checkbox-equipment" + key="14" + > + <input + checked={false} + className="item-eq" + name="HYDRAULIC_HEATING" + onChange={[Function]} + type="checkbox" + value="HYDRAULIC_HEATING" + /> + <mock-equipment-icon + equipment="HYDRAULIC_HEATING" + isChecked={false} + /> + </label> + </div> + </div> + <FormNavigation + disableNextButton={false} + handleNext={[Function]} + handlePrevious={[Function]} + step={3} + > + <div + className="profile-navigation" + > + <WithStyles(ForwardRef(Button)) + aria-label="profile_type.accessibility.button_previous" + className="profile-navigation-button" + classes={ + Object { + "label": "text-16-normal", + "root": "btn-profile-back", + } + } + disabled={false} + onClick={[Function]} + > + <ForwardRef(Button) + aria-label="profile_type.accessibility.button_previous" + className="profile-navigation-button" + classes={ + Object { + "colorInherit": "MuiButton-colorInherit", + "contained": "MuiButton-contained", + "containedPrimary": "MuiButton-containedPrimary", + "containedSecondary": "MuiButton-containedSecondary", + "containedSizeLarge": "MuiButton-containedSizeLarge", + "containedSizeSmall": "MuiButton-containedSizeSmall", + "disableElevation": "MuiButton-disableElevation", + "disabled": "Mui-disabled", + "endIcon": "MuiButton-endIcon", + "focusVisible": "Mui-focusVisible", + "fullWidth": "MuiButton-fullWidth", + "iconSizeLarge": "MuiButton-iconSizeLarge", + "iconSizeMedium": "MuiButton-iconSizeMedium", + "iconSizeSmall": "MuiButton-iconSizeSmall", + "label": "MuiButton-label text-16-normal", + "outlined": "MuiButton-outlined", + "outlinedPrimary": "MuiButton-outlinedPrimary", + "outlinedSecondary": "MuiButton-outlinedSecondary", + "outlinedSizeLarge": "MuiButton-outlinedSizeLarge", + "outlinedSizeSmall": "MuiButton-outlinedSizeSmall", + "root": "MuiButton-root btn-profile-back", + "sizeLarge": "MuiButton-sizeLarge", + "sizeSmall": "MuiButton-sizeSmall", + "startIcon": "MuiButton-startIcon", + "text": "MuiButton-text", + "textPrimary": "MuiButton-textPrimary", + "textSecondary": "MuiButton-textSecondary", + "textSizeLarge": "MuiButton-textSizeLarge", + "textSizeSmall": "MuiButton-textSizeSmall", + } + } + disabled={false} + onClick={[Function]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="profile_type.accessibility.button_previous" + className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button" + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <ForwardRef(ButtonBase) + aria-label="profile_type.accessibility.button_previous" + className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <button + aria-label="profile_type.accessibility.button_previous" + className="MuiButtonBase-root MuiButton-root btn-profile-back MuiButton-text profile-navigation-button" + disabled={false} + onBlur={[Function]} + onClick={[Function]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={0} + type="button" + > + <span + className="MuiButton-label text-16-normal" + > + < profile_type.form.button_previous + </span> + <NoSsr> + <WithStyles(memo) + center={false} + > + <ForwardRef(TouchRipple) + center={false} + classes={ + Object { + "child": "MuiTouchRipple-child", + "childLeaving": "MuiTouchRipple-childLeaving", + "childPulsate": "MuiTouchRipple-childPulsate", + "ripple": "MuiTouchRipple-ripple", + "ripplePulsate": "MuiTouchRipple-ripplePulsate", + "rippleVisible": "MuiTouchRipple-rippleVisible", + "root": "MuiTouchRipple-root", + } + } + > + <span + className="MuiTouchRipple-root" + > + <TransitionGroup + childFactory={[Function]} + component={null} + exit={true} + /> + </span> + </ForwardRef(TouchRipple)> + </WithStyles(memo)> + </NoSsr> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> + <WithStyles(ForwardRef(Button)) + aria-label="profile_type.accessibility.button_end" + className="profile-navigation-button" + classes={ + Object { + "label": "text-16-normal", + "root": "btn-profile-next rounded", + } + } + disabled={false} + onClick={[Function]} + > + <ForwardRef(Button) + aria-label="profile_type.accessibility.button_end" + className="profile-navigation-button" + classes={ + Object { + "colorInherit": "MuiButton-colorInherit", + "contained": "MuiButton-contained", + "containedPrimary": "MuiButton-containedPrimary", + "containedSecondary": "MuiButton-containedSecondary", + "containedSizeLarge": "MuiButton-containedSizeLarge", + "containedSizeSmall": "MuiButton-containedSizeSmall", + "disableElevation": "MuiButton-disableElevation", + "disabled": "Mui-disabled", + "endIcon": "MuiButton-endIcon", + "focusVisible": "Mui-focusVisible", + "fullWidth": "MuiButton-fullWidth", + "iconSizeLarge": "MuiButton-iconSizeLarge", + "iconSizeMedium": "MuiButton-iconSizeMedium", + "iconSizeSmall": "MuiButton-iconSizeSmall", + "label": "MuiButton-label text-16-normal", + "outlined": "MuiButton-outlined", + "outlinedPrimary": "MuiButton-outlinedPrimary", + "outlinedSecondary": "MuiButton-outlinedSecondary", + "outlinedSizeLarge": "MuiButton-outlinedSizeLarge", + "outlinedSizeSmall": "MuiButton-outlinedSizeSmall", + "root": "MuiButton-root btn-profile-next rounded", + "sizeLarge": "MuiButton-sizeLarge", + "sizeSmall": "MuiButton-sizeSmall", + "startIcon": "MuiButton-startIcon", + "text": "MuiButton-text", + "textPrimary": "MuiButton-textPrimary", + "textSecondary": "MuiButton-textSecondary", + "textSizeLarge": "MuiButton-textSizeLarge", + "textSizeSmall": "MuiButton-textSizeSmall", + } + } + disabled={false} + onClick={[Function]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="profile_type.accessibility.button_end" + className="MuiButton-root btn-profile-next rounded MuiButton-text profile-navigation-button" + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <ForwardRef(ButtonBase) + aria-label="profile_type.accessibility.button_end" + className="MuiButton-root btn-profile-next rounded MuiButton-text profile-navigation-button" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <button + aria-label="profile_type.accessibility.button_end" + className="MuiButtonBase-root MuiButton-root btn-profile-next rounded MuiButton-text profile-navigation-button" + disabled={false} + onBlur={[Function]} + onClick={[Function]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={0} + type="button" + > + <span + className="MuiButton-label text-16-normal" + > + profile_type.form.button_end + </span> + <NoSsr> + <WithStyles(memo) + center={false} + > + <ForwardRef(TouchRipple) + center={false} + classes={ + Object { + "child": "MuiTouchRipple-child", + "childLeaving": "MuiTouchRipple-childLeaving", + "childPulsate": "MuiTouchRipple-childPulsate", + "ripple": "MuiTouchRipple-ripple", + "ripplePulsate": "MuiTouchRipple-ripplePulsate", + "rippleVisible": "MuiTouchRipple-rippleVisible", + "root": "MuiTouchRipple-root", + } + } + > + <span + className="MuiTouchRipple-root" + > + <TransitionGroup + childFactory={[Function]} + component={null} + exit={true} + /> + </span> + </ForwardRef(TouchRipple)> + </WithStyles(memo)> + </NoSsr> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> + </div> + </FormNavigation> + </EcogestureFormEquipment> +</Provider> +`; diff --git a/src/components/EcogestureForm/__snapshots__/EcogestureFormSingleChoice.spec.tsx.snap b/src/components/EcogestureForm/__snapshots__/EcogestureFormSingleChoice.spec.tsx.snap new file mode 100644 index 000000000..e56e00d42 --- /dev/null +++ b/src/components/EcogestureForm/__snapshots__/EcogestureFormSingleChoice.spec.tsx.snap @@ -0,0 +1,304 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EcogestureFormSingleChoice component should be rendered correctly 1`] = ` +<Provider + store={ + Object { + "clearActions": [Function], + "dispatch": [Function], + "getActions": [Function], + "getState": [Function], + "replaceReducer": [Function], + "subscribe": [Function], + } + } +> + <EcogestureFormSingleChoice + answerType={ + Object { + "attribute": "heating", + "choices": Array [ + "individual", + "collective", + ], + "type": 0, + } + } + profileEcogesture={ + Object { + "equipments": Array [], + "heating": "individual", + "hotWater": "individual", + "warmingFluid": 0, + } + } + setNextStep={[MockFunction]} + setPrevioustStep={[MockFunction]} + step={0} + viewedStep={-1} + > + <div + className="profile-form-container ecogesture-form-single" + > + <div + className="profile-question-label" + > + ecogesture_form.heating_type.question + </div> + <label + className="radio_short" + key="0" + > + <input + checked={false} + className="" + name="individual" + onChange={[Function]} + type="radio" + value="individual" + /> + ecogesture_form.heating_type.individual + </label> + <label + className="radio_short" + key="1" + > + <input + checked={false} + className="" + name="collective" + onChange={[Function]} + type="radio" + value="collective" + /> + ecogesture_form.heating_type.collective + </label> + </div> + <FormNavigation + disableNextButton={true} + handleNext={[Function]} + handlePrevious={[Function]} + step={0} + > + <div + className="profile-navigation" + > + <WithStyles(ForwardRef(Button)) + aria-label="profile_type.accessibility.button_previous" + className="profile-navigation-button" + classes={ + Object { + "label": "text-16-normal", + "root": "btn-profile-back", + } + } + disabled={true} + onClick={[Function]} + > + <ForwardRef(Button) + aria-label="profile_type.accessibility.button_previous" + className="profile-navigation-button" + classes={ + Object { + "colorInherit": "MuiButton-colorInherit", + "contained": "MuiButton-contained", + "containedPrimary": "MuiButton-containedPrimary", + "containedSecondary": "MuiButton-containedSecondary", + "containedSizeLarge": "MuiButton-containedSizeLarge", + "containedSizeSmall": "MuiButton-containedSizeSmall", + "disableElevation": "MuiButton-disableElevation", + "disabled": "Mui-disabled", + "endIcon": "MuiButton-endIcon", + "focusVisible": "Mui-focusVisible", + "fullWidth": "MuiButton-fullWidth", + "iconSizeLarge": "MuiButton-iconSizeLarge", + "iconSizeMedium": "MuiButton-iconSizeMedium", + "iconSizeSmall": "MuiButton-iconSizeSmall", + "label": "MuiButton-label text-16-normal", + "outlined": "MuiButton-outlined", + "outlinedPrimary": "MuiButton-outlinedPrimary", + "outlinedSecondary": "MuiButton-outlinedSecondary", + "outlinedSizeLarge": "MuiButton-outlinedSizeLarge", + "outlinedSizeSmall": "MuiButton-outlinedSizeSmall", + "root": "MuiButton-root btn-profile-back", + "sizeLarge": "MuiButton-sizeLarge", + "sizeSmall": "MuiButton-sizeSmall", + "startIcon": "MuiButton-startIcon", + "text": "MuiButton-text", + "textPrimary": "MuiButton-textPrimary", + "textSecondary": "MuiButton-textSecondary", + "textSizeLarge": "MuiButton-textSizeLarge", + "textSizeSmall": "MuiButton-textSizeSmall", + } + } + disabled={true} + onClick={[Function]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="profile_type.accessibility.button_previous" + className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button Mui-disabled" + component="button" + disabled={true} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <ForwardRef(ButtonBase) + aria-label="profile_type.accessibility.button_previous" + className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button Mui-disabled" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={true} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <button + aria-label="profile_type.accessibility.button_previous" + className="MuiButtonBase-root MuiButton-root btn-profile-back MuiButton-text profile-navigation-button Mui-disabled Mui-disabled" + disabled={true} + onBlur={[Function]} + onClick={[Function]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={-1} + type="button" + > + <span + className="MuiButton-label text-16-normal" + > + < profile_type.form.button_previous + </span> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> + <WithStyles(ForwardRef(Button)) + aria-label="profile_type.accessibility.button_next" + className="profile-navigation-button disabled" + classes={ + Object { + "label": "text-16-normal", + "root": "btn-profile-next rounded", + } + } + disabled={true} + onClick={[Function]} + > + <ForwardRef(Button) + aria-label="profile_type.accessibility.button_next" + className="profile-navigation-button disabled" + classes={ + Object { + "colorInherit": "MuiButton-colorInherit", + "contained": "MuiButton-contained", + "containedPrimary": "MuiButton-containedPrimary", + "containedSecondary": "MuiButton-containedSecondary", + "containedSizeLarge": "MuiButton-containedSizeLarge", + "containedSizeSmall": "MuiButton-containedSizeSmall", + "disableElevation": "MuiButton-disableElevation", + "disabled": "Mui-disabled", + "endIcon": "MuiButton-endIcon", + "focusVisible": "Mui-focusVisible", + "fullWidth": "MuiButton-fullWidth", + "iconSizeLarge": "MuiButton-iconSizeLarge", + "iconSizeMedium": "MuiButton-iconSizeMedium", + "iconSizeSmall": "MuiButton-iconSizeSmall", + "label": "MuiButton-label text-16-normal", + "outlined": "MuiButton-outlined", + "outlinedPrimary": "MuiButton-outlinedPrimary", + "outlinedSecondary": "MuiButton-outlinedSecondary", + "outlinedSizeLarge": "MuiButton-outlinedSizeLarge", + "outlinedSizeSmall": "MuiButton-outlinedSizeSmall", + "root": "MuiButton-root btn-profile-next rounded", + "sizeLarge": "MuiButton-sizeLarge", + "sizeSmall": "MuiButton-sizeSmall", + "startIcon": "MuiButton-startIcon", + "text": "MuiButton-text", + "textPrimary": "MuiButton-textPrimary", + "textSecondary": "MuiButton-textSecondary", + "textSizeLarge": "MuiButton-textSizeLarge", + "textSizeSmall": "MuiButton-textSizeSmall", + } + } + disabled={true} + onClick={[Function]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="profile_type.accessibility.button_next" + className="MuiButton-root btn-profile-next rounded MuiButton-text profile-navigation-button disabled Mui-disabled" + component="button" + disabled={true} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <ForwardRef(ButtonBase) + aria-label="profile_type.accessibility.button_next" + className="MuiButton-root btn-profile-next rounded MuiButton-text profile-navigation-button disabled Mui-disabled" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={true} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <button + aria-label="profile_type.accessibility.button_next" + className="MuiButtonBase-root MuiButton-root btn-profile-next rounded MuiButton-text profile-navigation-button disabled Mui-disabled Mui-disabled" + disabled={true} + onBlur={[Function]} + onClick={[Function]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={-1} + type="button" + > + <span + className="MuiButton-label text-16-normal" + > + profile_type.form.button_next > + </span> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> + </div> + </FormNavigation> + </EcogestureFormSingleChoice> +</Provider> +`; diff --git a/src/components/EcogestureForm/__snapshots__/EcogestureFormView.spec.tsx.snap b/src/components/EcogestureForm/__snapshots__/EcogestureFormView.spec.tsx.snap new file mode 100644 index 000000000..0131c2279 --- /dev/null +++ b/src/components/EcogestureForm/__snapshots__/EcogestureFormView.spec.tsx.snap @@ -0,0 +1,321 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EcogestureFormView component should be rendered correctly 1`] = ` +<Provider + store={ + Object { + "clearActions": [Function], + "dispatch": [Function], + "getActions": [Function], + "getState": [Function], + "replaceReducer": [Function], + "subscribe": [Function], + } + } +> + <EcogestureFormView> + <mock-cozybar + titleKey="common.title_ecogestures" + /> + <mock-header + desktopTitleKey="common.title_ecogestures" + setHeaderHeight={[Function]} + /> + <mock-content + height={0} + > + <EcogestureFormSingleChoice + answerType={ + Object { + "attribute": "heating", + "choices": Array [ + "individual", + "collective", + ], + "type": 0, + } + } + profileEcogesture={ + Object { + "equipments": Array [], + "heating": "individual", + "hotWater": "individual", + "warmingFluid": 0, + } + } + setNextStep={[Function]} + setPrevioustStep={[Function]} + step={0} + viewedStep={-1} + > + <div + className="profile-form-container ecogesture-form-single" + > + <div + className="profile-question-label" + > + ecogesture_form.heating_type.question + </div> + <label + className="radio_short" + key="0" + > + <input + checked={false} + className="" + name="individual" + onChange={[Function]} + type="radio" + value="individual" + /> + ecogesture_form.heating_type.individual + </label> + <label + className="radio_short" + key="1" + > + <input + checked={false} + className="" + name="collective" + onChange={[Function]} + type="radio" + value="collective" + /> + ecogesture_form.heating_type.collective + </label> + </div> + <FormNavigation + disableNextButton={true} + handleNext={[Function]} + handlePrevious={[Function]} + step={0} + > + <div + className="profile-navigation" + > + <WithStyles(ForwardRef(Button)) + aria-label="profile_type.accessibility.button_previous" + className="profile-navigation-button" + classes={ + Object { + "label": "text-16-normal", + "root": "btn-profile-back", + } + } + disabled={true} + onClick={[Function]} + > + <ForwardRef(Button) + aria-label="profile_type.accessibility.button_previous" + className="profile-navigation-button" + classes={ + Object { + "colorInherit": "MuiButton-colorInherit", + "contained": "MuiButton-contained", + "containedPrimary": "MuiButton-containedPrimary", + "containedSecondary": "MuiButton-containedSecondary", + "containedSizeLarge": "MuiButton-containedSizeLarge", + "containedSizeSmall": "MuiButton-containedSizeSmall", + "disableElevation": "MuiButton-disableElevation", + "disabled": "Mui-disabled", + "endIcon": "MuiButton-endIcon", + "focusVisible": "Mui-focusVisible", + "fullWidth": "MuiButton-fullWidth", + "iconSizeLarge": "MuiButton-iconSizeLarge", + "iconSizeMedium": "MuiButton-iconSizeMedium", + "iconSizeSmall": "MuiButton-iconSizeSmall", + "label": "MuiButton-label text-16-normal", + "outlined": "MuiButton-outlined", + "outlinedPrimary": "MuiButton-outlinedPrimary", + "outlinedSecondary": "MuiButton-outlinedSecondary", + "outlinedSizeLarge": "MuiButton-outlinedSizeLarge", + "outlinedSizeSmall": "MuiButton-outlinedSizeSmall", + "root": "MuiButton-root btn-profile-back", + "sizeLarge": "MuiButton-sizeLarge", + "sizeSmall": "MuiButton-sizeSmall", + "startIcon": "MuiButton-startIcon", + "text": "MuiButton-text", + "textPrimary": "MuiButton-textPrimary", + "textSecondary": "MuiButton-textSecondary", + "textSizeLarge": "MuiButton-textSizeLarge", + "textSizeSmall": "MuiButton-textSizeSmall", + } + } + disabled={true} + onClick={[Function]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="profile_type.accessibility.button_previous" + className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button Mui-disabled" + component="button" + disabled={true} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <ForwardRef(ButtonBase) + aria-label="profile_type.accessibility.button_previous" + className="MuiButton-root btn-profile-back MuiButton-text profile-navigation-button Mui-disabled" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={true} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <button + aria-label="profile_type.accessibility.button_previous" + className="MuiButtonBase-root MuiButton-root btn-profile-back MuiButton-text profile-navigation-button Mui-disabled Mui-disabled" + disabled={true} + onBlur={[Function]} + onClick={[Function]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={-1} + type="button" + > + <span + className="MuiButton-label text-16-normal" + > + < profile_type.form.button_previous + </span> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> + <WithStyles(ForwardRef(Button)) + aria-label="profile_type.accessibility.button_next" + className="profile-navigation-button disabled" + classes={ + Object { + "label": "text-16-normal", + "root": "btn-profile-next rounded", + } + } + disabled={true} + onClick={[Function]} + > + <ForwardRef(Button) + aria-label="profile_type.accessibility.button_next" + className="profile-navigation-button disabled" + classes={ + Object { + "colorInherit": "MuiButton-colorInherit", + "contained": "MuiButton-contained", + "containedPrimary": "MuiButton-containedPrimary", + "containedSecondary": "MuiButton-containedSecondary", + "containedSizeLarge": "MuiButton-containedSizeLarge", + "containedSizeSmall": "MuiButton-containedSizeSmall", + "disableElevation": "MuiButton-disableElevation", + "disabled": "Mui-disabled", + "endIcon": "MuiButton-endIcon", + "focusVisible": "Mui-focusVisible", + "fullWidth": "MuiButton-fullWidth", + "iconSizeLarge": "MuiButton-iconSizeLarge", + "iconSizeMedium": "MuiButton-iconSizeMedium", + "iconSizeSmall": "MuiButton-iconSizeSmall", + "label": "MuiButton-label text-16-normal", + "outlined": "MuiButton-outlined", + "outlinedPrimary": "MuiButton-outlinedPrimary", + "outlinedSecondary": "MuiButton-outlinedSecondary", + "outlinedSizeLarge": "MuiButton-outlinedSizeLarge", + "outlinedSizeSmall": "MuiButton-outlinedSizeSmall", + "root": "MuiButton-root btn-profile-next rounded", + "sizeLarge": "MuiButton-sizeLarge", + "sizeSmall": "MuiButton-sizeSmall", + "startIcon": "MuiButton-startIcon", + "text": "MuiButton-text", + "textPrimary": "MuiButton-textPrimary", + "textSecondary": "MuiButton-textSecondary", + "textSizeLarge": "MuiButton-textSizeLarge", + "textSizeSmall": "MuiButton-textSizeSmall", + } + } + disabled={true} + onClick={[Function]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="profile_type.accessibility.button_next" + className="MuiButton-root btn-profile-next rounded MuiButton-text profile-navigation-button disabled Mui-disabled" + component="button" + disabled={true} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <ForwardRef(ButtonBase) + aria-label="profile_type.accessibility.button_next" + className="MuiButton-root btn-profile-next rounded MuiButton-text profile-navigation-button disabled Mui-disabled" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={true} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[Function]} + type="button" + > + <button + aria-label="profile_type.accessibility.button_next" + className="MuiButtonBase-root MuiButton-root btn-profile-next rounded MuiButton-text profile-navigation-button disabled Mui-disabled Mui-disabled" + disabled={true} + onBlur={[Function]} + onClick={[Function]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={-1} + type="button" + > + <span + className="MuiButton-label text-16-normal" + > + profile_type.form.button_next > + </span> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> + </div> + </FormNavigation> + </EcogestureFormSingleChoice> + </mock-content> + <mock-ecogesturelaunchmodal + handleCloseClick={[Function]} + open={true} + /> + </EcogestureFormView> +</Provider> +`; diff --git a/src/components/EcogestureForm/__snapshots__/EcogestureLaunchFormModal.spec.tsx.snap b/src/components/EcogestureForm/__snapshots__/EcogestureLaunchFormModal.spec.tsx.snap new file mode 100644 index 000000000..df7346335 --- /dev/null +++ b/src/components/EcogestureForm/__snapshots__/EcogestureLaunchFormModal.spec.tsx.snap @@ -0,0 +1,963 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EcogestureLaunchFormModal component should be rendered correctly 1`] = ` +<EcogestureLaunchFormModal + handleCloseClick={[MockFunction]} + open={true} +> + <WithStyles(ForwardRef(Dialog)) + aria-labelledby="accessibility-title" + classes={ + Object { + "paper": "modal-paper", + "root": "modal-root", + } + } + onClose={[MockFunction]} + open={true} + > + <ForwardRef(Dialog) + aria-labelledby="accessibility-title" + classes={ + Object { + "container": "MuiDialog-container", + "paper": "MuiDialog-paper modal-paper", + "paperFullScreen": "MuiDialog-paperFullScreen", + "paperFullWidth": "MuiDialog-paperFullWidth", + "paperScrollBody": "MuiDialog-paperScrollBody", + "paperScrollPaper": "MuiDialog-paperScrollPaper", + "paperWidthFalse": "MuiDialog-paperWidthFalse", + "paperWidthLg": "MuiDialog-paperWidthLg", + "paperWidthMd": "MuiDialog-paperWidthMd", + "paperWidthSm": "MuiDialog-paperWidthSm", + "paperWidthXl": "MuiDialog-paperWidthXl", + "paperWidthXs": "MuiDialog-paperWidthXs", + "root": "MuiDialog-root modal-root", + "scrollBody": "MuiDialog-scrollBody", + "scrollPaper": "MuiDialog-scrollPaper", + } + } + onClose={[MockFunction]} + open={true} + > + <ForwardRef(Modal) + BackdropComponent={ + Object { + "$$typeof": Symbol(react.forward_ref), + "Naked": Object { + "$$typeof": Symbol(react.forward_ref), + "propTypes": Object { + "children": [Function], + "className": [Function], + "classes": [Function], + "invisible": [Function], + "open": [Function], + "transitionDuration": [Function], + }, + "render": [Function], + }, + "displayName": "WithStyles(ForwardRef(Backdrop))", + "options": Object { + "defaultTheme": Object { + "breakpoints": Object { + "between": [Function], + "down": [Function], + "keys": Array [ + "xs", + "sm", + "md", + "lg", + "xl", + ], + "only": [Function], + "up": [Function], + "values": Object { + "lg": 1280, + "md": 960, + "sm": 600, + "xl": 1920, + "xs": 0, + }, + "width": [Function], + }, + "direction": "ltr", + "mixins": Object { + "gutters": [Function], + "toolbar": Object { + "@media (min-width:0px) and (orientation: landscape)": Object { + "minHeight": 48, + }, + "@media (min-width:600px)": Object { + "minHeight": 64, + }, + "minHeight": 56, + }, + }, + "overrides": Object {}, + "palette": Object { + "action": Object { + "active": "rgba(0, 0, 0, 0.54)", + "disabled": "rgba(0, 0, 0, 0.26)", + "disabledBackground": "rgba(0, 0, 0, 0.12)", + "hover": "rgba(0, 0, 0, 0.08)", + "hoverOpacity": 0.08, + "selected": "rgba(0, 0, 0, 0.14)", + }, + "augmentColor": [Function], + "background": Object { + "default": "#fafafa", + "paper": "#fff", + }, + "common": Object { + "black": "#000", + "white": "#fff", + }, + "contrastThreshold": 3, + "divider": "rgba(0, 0, 0, 0.12)", + "error": Object { + "contrastText": "#fff", + "dark": "#d32f2f", + "light": "#e57373", + "main": "#f44336", + }, + "getContrastText": [Function], + "grey": Object { + "100": "#f5f5f5", + "200": "#eeeeee", + "300": "#e0e0e0", + "400": "#bdbdbd", + "50": "#fafafa", + "500": "#9e9e9e", + "600": "#757575", + "700": "#616161", + "800": "#424242", + "900": "#212121", + "A100": "#d5d5d5", + "A200": "#aaaaaa", + "A400": "#303030", + "A700": "#616161", + }, + "info": Object { + "contrastText": "#fff", + "dark": "#1976d2", + "light": "#64b5f6", + "main": "#2196f3", + }, + "primary": Object { + "contrastText": "#fff", + "dark": "#303f9f", + "light": "#7986cb", + "main": "#3f51b5", + }, + "secondary": Object { + "contrastText": "#fff", + "dark": "#c51162", + "light": "#ff4081", + "main": "#f50057", + }, + "success": Object { + "contrastText": "rgba(0, 0, 0, 0.87)", + "dark": "#388e3c", + "light": "#81c784", + "main": "#4caf50", + }, + "text": Object { + "disabled": "rgba(0, 0, 0, 0.38)", + "hint": "rgba(0, 0, 0, 0.38)", + "primary": "rgba(0, 0, 0, 0.87)", + "secondary": "rgba(0, 0, 0, 0.54)", + }, + "tonalOffset": 0.2, + "type": "light", + "warning": Object { + "contrastText": "rgba(0, 0, 0, 0.87)", + "dark": "#f57c00", + "light": "#ffb74d", + "main": "#ff9800", + }, + }, + "props": Object {}, + "shadows": Array [ + "none", + "0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)", + "0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)", + "0px 3px 3px -2px rgba(0,0,0,0.2),0px 3px 4px 0px rgba(0,0,0,0.14),0px 1px 8px 0px rgba(0,0,0,0.12)", + "0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)", + "0px 3px 5px -1px rgba(0,0,0,0.2),0px 5px 8px 0px rgba(0,0,0,0.14),0px 1px 14px 0px rgba(0,0,0,0.12)", + "0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)", + "0px 4px 5px -2px rgba(0,0,0,0.2),0px 7px 10px 1px rgba(0,0,0,0.14),0px 2px 16px 1px rgba(0,0,0,0.12)", + "0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12)", + "0px 5px 6px -3px rgba(0,0,0,0.2),0px 9px 12px 1px rgba(0,0,0,0.14),0px 3px 16px 2px rgba(0,0,0,0.12)", + "0px 6px 6px -3px rgba(0,0,0,0.2),0px 10px 14px 1px rgba(0,0,0,0.14),0px 4px 18px 3px rgba(0,0,0,0.12)", + "0px 6px 7px -4px rgba(0,0,0,0.2),0px 11px 15px 1px rgba(0,0,0,0.14),0px 4px 20px 3px rgba(0,0,0,0.12)", + "0px 7px 8px -4px rgba(0,0,0,0.2),0px 12px 17px 2px rgba(0,0,0,0.14),0px 5px 22px 4px rgba(0,0,0,0.12)", + "0px 7px 8px -4px rgba(0,0,0,0.2),0px 13px 19px 2px rgba(0,0,0,0.14),0px 5px 24px 4px rgba(0,0,0,0.12)", + "0px 7px 9px -4px rgba(0,0,0,0.2),0px 14px 21px 2px rgba(0,0,0,0.14),0px 5px 26px 4px rgba(0,0,0,0.12)", + "0px 8px 9px -5px rgba(0,0,0,0.2),0px 15px 22px 2px rgba(0,0,0,0.14),0px 6px 28px 5px rgba(0,0,0,0.12)", + "0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12)", + "0px 8px 11px -5px rgba(0,0,0,0.2),0px 17px 26px 2px rgba(0,0,0,0.14),0px 6px 32px 5px rgba(0,0,0,0.12)", + "0px 9px 11px -5px rgba(0,0,0,0.2),0px 18px 28px 2px rgba(0,0,0,0.14),0px 7px 34px 6px rgba(0,0,0,0.12)", + "0px 9px 12px -6px rgba(0,0,0,0.2),0px 19px 29px 2px rgba(0,0,0,0.14),0px 7px 36px 6px rgba(0,0,0,0.12)", + "0px 10px 13px -6px rgba(0,0,0,0.2),0px 20px 31px 3px rgba(0,0,0,0.14),0px 8px 38px 7px rgba(0,0,0,0.12)", + "0px 10px 13px -6px rgba(0,0,0,0.2),0px 21px 33px 3px rgba(0,0,0,0.14),0px 8px 40px 7px rgba(0,0,0,0.12)", + "0px 10px 14px -6px rgba(0,0,0,0.2),0px 22px 35px 3px rgba(0,0,0,0.14),0px 8px 42px 7px rgba(0,0,0,0.12)", + "0px 11px 14px -7px rgba(0,0,0,0.2),0px 23px 36px 3px rgba(0,0,0,0.14),0px 9px 44px 8px rgba(0,0,0,0.12)", + "0px 11px 15px -7px rgba(0,0,0,0.2),0px 24px 38px 3px rgba(0,0,0,0.14),0px 9px 46px 8px rgba(0,0,0,0.12)", + ], + "shape": Object { + "borderRadius": 4, + }, + "spacing": [Function], + "transitions": Object { + "create": [Function], + "duration": Object { + "complex": 375, + "enteringScreen": 225, + "leavingScreen": 195, + "short": 250, + "shorter": 200, + "shortest": 150, + "standard": 300, + }, + "easing": Object { + "easeIn": "cubic-bezier(0.4, 0, 1, 1)", + "easeInOut": "cubic-bezier(0.4, 0, 0.2, 1)", + "easeOut": "cubic-bezier(0.0, 0, 0.2, 1)", + "sharp": "cubic-bezier(0.4, 0, 0.6, 1)", + }, + "getAutoHeightDuration": [Function], + }, + "typography": Object { + "body1": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "1rem", + "fontWeight": 400, + "letterSpacing": "0.00938em", + "lineHeight": 1.5, + }, + "body2": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.875rem", + "fontWeight": 400, + "letterSpacing": "0.01071em", + "lineHeight": 1.43, + }, + "button": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.875rem", + "fontWeight": 500, + "letterSpacing": "0.02857em", + "lineHeight": 1.75, + "textTransform": "uppercase", + }, + "caption": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.75rem", + "fontWeight": 400, + "letterSpacing": "0.03333em", + "lineHeight": 1.66, + }, + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": 14, + "fontWeightBold": 700, + "fontWeightLight": 300, + "fontWeightMedium": 500, + "fontWeightRegular": 400, + "h1": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "6rem", + "fontWeight": 300, + "letterSpacing": "-0.01562em", + "lineHeight": 1.167, + }, + "h2": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "3.75rem", + "fontWeight": 300, + "letterSpacing": "-0.00833em", + "lineHeight": 1.2, + }, + "h3": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "3rem", + "fontWeight": 400, + "letterSpacing": "0em", + "lineHeight": 1.167, + }, + "h4": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "2.125rem", + "fontWeight": 400, + "letterSpacing": "0.00735em", + "lineHeight": 1.235, + }, + "h5": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "1.5rem", + "fontWeight": 400, + "letterSpacing": "0em", + "lineHeight": 1.334, + }, + "h6": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "1.25rem", + "fontWeight": 500, + "letterSpacing": "0.0075em", + "lineHeight": 1.6, + }, + "htmlFontSize": 16, + "overline": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.75rem", + "fontWeight": 400, + "letterSpacing": "0.08333em", + "lineHeight": 2.66, + "textTransform": "uppercase", + }, + "pxToRem": [Function], + "round": [Function], + "subtitle1": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "1rem", + "fontWeight": 400, + "letterSpacing": "0.00938em", + "lineHeight": 1.75, + }, + "subtitle2": Object { + "fontFamily": "\\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif", + "fontSize": "0.875rem", + "fontWeight": 500, + "letterSpacing": "0.00714em", + "lineHeight": 1.57, + }, + }, + "zIndex": Object { + "appBar": 1100, + "drawer": 1200, + "mobileStepper": 1000, + "modal": 1300, + "snackbar": 1400, + "speedDial": 1050, + "tooltip": 1500, + }, + }, + "name": "MuiBackdrop", + }, + "propTypes": Object { + "classes": [Function], + "innerRef": [Function], + }, + "render": [Function], + "useStyles": [Function], + } + } + BackdropProps={ + Object { + "transitionDuration": Object { + "enter": 225, + "exit": 195, + }, + } + } + className="MuiDialog-root modal-root" + closeAfterTransition={true} + disableBackdropClick={false} + disableEscapeKeyDown={false} + onClose={[MockFunction]} + open={true} + > + <ForwardRef(Portal) + disablePortal={false} + > + <Portal + containerInfo={ + <body + style="padding-right: 0px; overflow: hidden;" + > + <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 modal-paper-close-button" + tabindex="0" + type="button" + > + <span + class="MuiIconButton-label" + > + <svg + 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 text" + > + ecogesture.initModal.text3 + </div> + <button + aria-label="ecogesture.initModal.btn2" + class="MuiButtonBase-root MuiButton-root btn-profile-next rounded MuiButton-text" + tabindex="0" + type="button" + > + <span + class="MuiButton-label text-16-bold" + > + ecogesture.initModal.btn2 + </span> + <span + class="MuiTouchRipple-root" + /> + </button> + </div> + </div> + </div> + <div + data-test="sentinelEnd" + tabindex="0" + /> + </div> + </body> + } + > + <div + className="MuiDialog-root modal-root" + onKeyDown={[Function]} + role="presentation" + style={ + Object { + "bottom": 0, + "left": 0, + "position": "fixed", + "right": 0, + "top": 0, + "zIndex": 1300, + } + } + > + <WithStyles(ForwardRef(Backdrop)) + onClick={[Function]} + open={true} + transitionDuration={ + Object { + "enter": 225, + "exit": 195, + } + } + > + <ForwardRef(Backdrop) + classes={ + Object { + "invisible": "MuiBackdrop-invisible", + "root": "MuiBackdrop-root", + } + } + onClick={[Function]} + open={true} + transitionDuration={ + Object { + "enter": 225, + "exit": 195, + } + } + > + <ForwardRef(Fade) + in={true} + onClick={[Function]} + timeout={ + Object { + "enter": 225, + "exit": 195, + } + } + > + <Transition + appear={true} + enter={true} + exit={true} + in={true} + mountOnEnter={false} + onClick={[Function]} + onEnter={[Function]} + onEntered={[Function]} + onEntering={[Function]} + onExit={[Function]} + onExited={[Function]} + onExiting={[Function]} + timeout={ + Object { + "enter": 225, + "exit": 195, + } + } + unmountOnExit={false} + > + <div + aria-hidden={true} + className="MuiBackdrop-root" + onClick={[Function]} + style={ + Object { + "opacity": 1, + "visibility": undefined, + } + } + /> + </Transition> + </ForwardRef(Fade)> + </ForwardRef(Backdrop)> + </WithStyles(ForwardRef(Backdrop))> + <TrapFocus + disableAutoFocus={false} + disableEnforceFocus={false} + disableRestoreFocus={false} + getDoc={[Function]} + isEnabled={[Function]} + open={true} + > + <div + data-test="sentinelStart" + tabIndex={0} + /> + <ForwardRef(Fade) + appear={true} + in={true} + onEnter={[Function]} + onExited={[Function]} + role="none presentation" + tabIndex="-1" + timeout={ + Object { + "enter": 225, + "exit": 195, + } + } + > + <Transition + appear={true} + enter={true} + exit={true} + in={true} + mountOnEnter={false} + onEnter={[Function]} + onEntered={[Function]} + onEntering={[Function]} + onExit={[Function]} + onExited={[Function]} + onExiting={[Function]} + role="none presentation" + tabIndex="-1" + timeout={ + Object { + "enter": 225, + "exit": 195, + } + } + unmountOnExit={false} + > + <div + className="MuiDialog-container MuiDialog-scrollPaper" + onClick={[Function]} + onMouseDown={[Function]} + role="none presentation" + style={ + Object { + "opacity": 1, + "visibility": undefined, + } + } + tabIndex="-1" + > + <WithStyles(ForwardRef(Paper)) + aria-labelledby="accessibility-title" + className="MuiDialog-paper modal-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm" + elevation={24} + role="dialog" + > + <ForwardRef(Paper) + aria-labelledby="accessibility-title" + className="MuiDialog-paper modal-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm" + classes={ + Object { + "elevation0": "MuiPaper-elevation0", + "elevation1": "MuiPaper-elevation1", + "elevation10": "MuiPaper-elevation10", + "elevation11": "MuiPaper-elevation11", + "elevation12": "MuiPaper-elevation12", + "elevation13": "MuiPaper-elevation13", + "elevation14": "MuiPaper-elevation14", + "elevation15": "MuiPaper-elevation15", + "elevation16": "MuiPaper-elevation16", + "elevation17": "MuiPaper-elevation17", + "elevation18": "MuiPaper-elevation18", + "elevation19": "MuiPaper-elevation19", + "elevation2": "MuiPaper-elevation2", + "elevation20": "MuiPaper-elevation20", + "elevation21": "MuiPaper-elevation21", + "elevation22": "MuiPaper-elevation22", + "elevation23": "MuiPaper-elevation23", + "elevation24": "MuiPaper-elevation24", + "elevation3": "MuiPaper-elevation3", + "elevation4": "MuiPaper-elevation4", + "elevation5": "MuiPaper-elevation5", + "elevation6": "MuiPaper-elevation6", + "elevation7": "MuiPaper-elevation7", + "elevation8": "MuiPaper-elevation8", + "elevation9": "MuiPaper-elevation9", + "outlined": "MuiPaper-outlined", + "root": "MuiPaper-root", + "rounded": "MuiPaper-rounded", + } + } + elevation={24} + role="dialog" + > + <div + aria-labelledby="accessibility-title" + className="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> + <WithStyles(ForwardRef(IconButton)) + aria-label="feedback.accessibility.button_close" + className="modal-paper-close-button" + onClick={[MockFunction]} + > + <ForwardRef(IconButton) + aria-label="feedback.accessibility.button_close" + className="modal-paper-close-button" + classes={ + Object { + "colorInherit": "MuiIconButton-colorInherit", + "colorPrimary": "MuiIconButton-colorPrimary", + "colorSecondary": "MuiIconButton-colorSecondary", + "disabled": "Mui-disabled", + "edgeEnd": "MuiIconButton-edgeEnd", + "edgeStart": "MuiIconButton-edgeStart", + "label": "MuiIconButton-label", + "root": "MuiIconButton-root", + "sizeSmall": "MuiIconButton-sizeSmall", + } + } + onClick={[MockFunction]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="feedback.accessibility.button_close" + centerRipple={true} + className="MuiIconButton-root modal-paper-close-button" + disabled={false} + focusRipple={true} + onClick={[MockFunction]} + > + <ForwardRef(ButtonBase) + aria-label="feedback.accessibility.button_close" + centerRipple={true} + className="MuiIconButton-root modal-paper-close-button" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + disabled={false} + focusRipple={true} + onClick={[MockFunction]} + > + <button + aria-label="feedback.accessibility.button_close" + className="MuiButtonBase-root MuiIconButton-root modal-paper-close-button" + disabled={false} + onBlur={[Function]} + onClick={[MockFunction]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={0} + type="button" + > + <span + className="MuiIconButton-label" + > + <Icon + icon="test-file-stub" + size={16} + spin={false} + > + <Component + className="styles__icon___23x3R" + height={16} + style={Object {}} + width={16} + > + <svg + className="styles__icon___23x3R" + height={16} + style={Object {}} + width={16} + > + <use + xlinkHref="#test-file-stub" + /> + </svg> + </Component> + </Icon> + </span> + <NoSsr> + <WithStyles(memo) + center={true} + > + <ForwardRef(TouchRipple) + center={true} + classes={ + Object { + "child": "MuiTouchRipple-child", + "childLeaving": "MuiTouchRipple-childLeaving", + "childPulsate": "MuiTouchRipple-childPulsate", + "ripple": "MuiTouchRipple-ripple", + "ripplePulsate": "MuiTouchRipple-ripplePulsate", + "rippleVisible": "MuiTouchRipple-rippleVisible", + "root": "MuiTouchRipple-root", + } + } + > + <span + className="MuiTouchRipple-root" + > + <TransitionGroup + childFactory={[Function]} + component={null} + exit={true} + /> + </span> + </ForwardRef(TouchRipple)> + </WithStyles(memo)> + </NoSsr> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(IconButton)> + </WithStyles(ForwardRef(IconButton))> + <div + className="eg-init-modal" + > + <div + className="title text-20-bold" + > + ecogesture.initModal.title + </div> + <div + className="text-16-normal text" + > + ecogesture.initModal.text3 + </div> + <WithStyles(ForwardRef(Button)) + aria-label="ecogesture.initModal.btn2" + classes={ + Object { + "label": "text-16-bold", + "root": "btn-profile-next rounded", + } + } + onClick={[MockFunction]} + > + <ForwardRef(Button) + aria-label="ecogesture.initModal.btn2" + classes={ + Object { + "colorInherit": "MuiButton-colorInherit", + "contained": "MuiButton-contained", + "containedPrimary": "MuiButton-containedPrimary", + "containedSecondary": "MuiButton-containedSecondary", + "containedSizeLarge": "MuiButton-containedSizeLarge", + "containedSizeSmall": "MuiButton-containedSizeSmall", + "disableElevation": "MuiButton-disableElevation", + "disabled": "Mui-disabled", + "endIcon": "MuiButton-endIcon", + "focusVisible": "Mui-focusVisible", + "fullWidth": "MuiButton-fullWidth", + "iconSizeLarge": "MuiButton-iconSizeLarge", + "iconSizeMedium": "MuiButton-iconSizeMedium", + "iconSizeSmall": "MuiButton-iconSizeSmall", + "label": "MuiButton-label text-16-bold", + "outlined": "MuiButton-outlined", + "outlinedPrimary": "MuiButton-outlinedPrimary", + "outlinedSecondary": "MuiButton-outlinedSecondary", + "outlinedSizeLarge": "MuiButton-outlinedSizeLarge", + "outlinedSizeSmall": "MuiButton-outlinedSizeSmall", + "root": "MuiButton-root btn-profile-next rounded", + "sizeLarge": "MuiButton-sizeLarge", + "sizeSmall": "MuiButton-sizeSmall", + "startIcon": "MuiButton-startIcon", + "text": "MuiButton-text", + "textPrimary": "MuiButton-textPrimary", + "textSecondary": "MuiButton-textSecondary", + "textSizeLarge": "MuiButton-textSizeLarge", + "textSizeSmall": "MuiButton-textSizeSmall", + } + } + onClick={[MockFunction]} + > + <WithStyles(ForwardRef(ButtonBase)) + aria-label="ecogesture.initModal.btn2" + className="MuiButton-root btn-profile-next rounded MuiButton-text" + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[MockFunction]} + type="button" + > + <ForwardRef(ButtonBase) + aria-label="ecogesture.initModal.btn2" + className="MuiButton-root btn-profile-next rounded MuiButton-text" + classes={ + Object { + "disabled": "Mui-disabled", + "focusVisible": "Mui-focusVisible", + "root": "MuiButtonBase-root", + } + } + component="button" + disabled={false} + focusRipple={true} + focusVisibleClassName="Mui-focusVisible" + onClick={[MockFunction]} + type="button" + > + <button + aria-label="ecogesture.initModal.btn2" + className="MuiButtonBase-root MuiButton-root btn-profile-next rounded MuiButton-text" + disabled={false} + onBlur={[Function]} + onClick={[MockFunction]} + onDragLeave={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseLeave={[Function]} + onMouseUp={[Function]} + onTouchEnd={[Function]} + onTouchMove={[Function]} + onTouchStart={[Function]} + tabIndex={0} + type="button" + > + <span + className="MuiButton-label text-16-bold" + > + ecogesture.initModal.btn2 + </span> + <NoSsr> + <WithStyles(memo) + center={false} + > + <ForwardRef(TouchRipple) + center={false} + classes={ + Object { + "child": "MuiTouchRipple-child", + "childLeaving": "MuiTouchRipple-childLeaving", + "childPulsate": "MuiTouchRipple-childPulsate", + "ripple": "MuiTouchRipple-ripple", + "ripplePulsate": "MuiTouchRipple-ripplePulsate", + "rippleVisible": "MuiTouchRipple-rippleVisible", + "root": "MuiTouchRipple-root", + } + } + > + <span + className="MuiTouchRipple-root" + > + <TransitionGroup + childFactory={[Function]} + component={null} + exit={true} + /> + </span> + </ForwardRef(TouchRipple)> + </WithStyles(memo)> + </NoSsr> + </button> + </ForwardRef(ButtonBase)> + </WithStyles(ForwardRef(ButtonBase))> + </ForwardRef(Button)> + </WithStyles(ForwardRef(Button))> + </div> + </div> + </ForwardRef(Paper)> + </WithStyles(ForwardRef(Paper))> + </div> + </Transition> + </ForwardRef(Fade)> + <div + data-test="sentinelEnd" + tabIndex={0} + /> + </TrapFocus> + </div> + </Portal> + </ForwardRef(Portal)> + </ForwardRef(Modal)> + </ForwardRef(Dialog)> + </WithStyles(ForwardRef(Dialog))> +</EcogestureLaunchFormModal> +`; diff --git a/src/components/EcogestureForm/__snapshots__/EquipmentIcon.spec.tsx.snap b/src/components/EcogestureForm/__snapshots__/EquipmentIcon.spec.tsx.snap new file mode 100644 index 000000000..266d737b1 --- /dev/null +++ b/src/components/EcogestureForm/__snapshots__/EquipmentIcon.spec.tsx.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EcogestureFormSingleChoice component should be rendered correctly 1`] = ` +<EquipmentIcon + equipment="BOILER" + isChecked={false} +> + <Icon + className="equipmentIcon" + icon="" + size={80} + spin={false} + > + <Component + className="equipmentIcon styles__icon___23x3R" + height={80} + style={Object {}} + width={80} + > + <svg + className="equipmentIcon styles__icon___23x3R" + height={80} + style={Object {}} + width={80} + > + <use + xlinkHref="#" + /> + </svg> + </Component> + </Icon> + <div + className="text text-14-normal" + > + ecogesture_profile.equipments.boiler + </div> +</EquipmentIcon> +`; diff --git a/src/components/EcogestureForm/ecogestureFormEquipment.scss b/src/components/EcogestureForm/ecogestureFormEquipment.scss new file mode 100644 index 000000000..4836e1a48 --- /dev/null +++ b/src/components/EcogestureForm/ecogestureFormEquipment.scss @@ -0,0 +1,48 @@ +@import 'src/styles/base/color'; +@import '../../styles/base/breakpoint'; + +.equipment-form-container { + padding: 1.5rem; + color: $grey-bright; + .equipment-label { + @media (min-width: $width-large-phone) { + text-align: center; + } + } + .equipment-hint { + margin: 1rem 0; + @media (min-width: $width-large-phone) { + text-align: center; + } + } + .icons-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: repeat(5, 1fr); + grid-column-gap: 32px; + grid-row-gap: 32px; + max-width: 400px; + margin: 1.5rem auto 3rem auto; + .checkbox-equipment { + cursor: pointer; + max-width: 80px; + text-align: center; + margin: 0 auto; + .text { + margin-top: 0.5rem; + text-align: center; + } + } + input.item-eq { + display: none; + } + .equipmentIcon { + transition: all 200ms ease; + box-sizing: border-box; + &.checked { + border: solid 3px $gold-shadow; + border-radius: 5px; + } + } + } +} diff --git a/src/components/EcogestureForm/ecogestureFormSingleChoice.scss b/src/components/EcogestureForm/ecogestureFormSingleChoice.scss new file mode 100644 index 000000000..66ea0d2b5 --- /dev/null +++ b/src/components/EcogestureForm/ecogestureFormSingleChoice.scss @@ -0,0 +1,6 @@ +.ecogesture-form-single { + color: #ffffff; + margin: 1rem 1rem 3.5rem; + width: auto; + max-width: 90%; +} diff --git a/src/components/EcogestureForm/ecogestureFormView.scss b/src/components/EcogestureForm/ecogestureFormView.scss new file mode 100644 index 000000000..c63af75be --- /dev/null +++ b/src/components/EcogestureForm/ecogestureFormView.scss @@ -0,0 +1,12 @@ +@import 'src/styles/base/color'; +@import 'src/styles/base/breakpoint'; + +.se-loader-container { + min-height: inherit; + display: flex; + justify-content: center; + align-items: center; + @media all and(min-width: $width-tablet) { + min-height: 80vh; + } +} diff --git a/src/components/EcogestureForm/ecogestureLaunchFormModal.scss b/src/components/EcogestureForm/ecogestureLaunchFormModal.scss new file mode 100644 index 000000000..c3e52eacf --- /dev/null +++ b/src/components/EcogestureForm/ecogestureLaunchFormModal.scss @@ -0,0 +1,16 @@ +@import '../../styles/base/color'; + +.eg-init-modal { + color: $grey-bright; + margin: 1rem 0; + .title { + text-align: center; + color: $gold-shadow; + } + .text { + margin: 1rem 0; + } + button { + min-height: 45px; + } +} diff --git a/src/components/ProfileType/ProfileTypeNavigation.spec.tsx b/src/components/ProfileType/FormNavigation.spec.tsx similarity index 90% rename from src/components/ProfileType/ProfileTypeNavigation.spec.tsx rename to src/components/ProfileType/FormNavigation.spec.tsx index 601d53936..01d0dc8bb 100644 --- a/src/components/ProfileType/ProfileTypeNavigation.spec.tsx +++ b/src/components/ProfileType/FormNavigation.spec.tsx @@ -6,7 +6,7 @@ import { createMockStore, mockInitialEcolyoState, } from '../../../tests/__mocks__/store' -import ProfileTypeNavigation from './ProfileTypeNavigation' +import FormNavigation from './FormNavigation' import { ProfileTypeStepForm } from 'enum/profileType.enum' jest.mock('cozy-ui/transpiled/react/I18n', () => { @@ -19,7 +19,7 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => { } }) -describe('ProfileTypeNavigation component', () => { +describe('FormNavigation component', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any let store: any beforeEach(() => { @@ -31,7 +31,7 @@ describe('ProfileTypeNavigation component', () => { const mockhandleNext = jest.fn() const wrapper = mount( <Provider store={store}> - <ProfileTypeNavigation + <FormNavigation step={ProfileTypeStepForm.COOKING_FLUID} handlePrevious={mockhandlePrevious} handleNext={mockhandleNext} diff --git a/src/components/ProfileType/ProfileTypeNavigation.tsx b/src/components/ProfileType/FormNavigation.tsx similarity index 72% rename from src/components/ProfileType/ProfileTypeNavigation.tsx rename to src/components/ProfileType/FormNavigation.tsx index d7011eede..13f347200 100644 --- a/src/components/ProfileType/ProfileTypeNavigation.tsx +++ b/src/components/ProfileType/FormNavigation.tsx @@ -1,23 +1,24 @@ import React from 'react' -import 'components/ProfileType/profileTypeNavigation.scss' +import 'components/ProfileType/formNavigation.scss' import classNames from 'classnames' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import Button from '@material-ui/core/Button' import { ProfileTypeStepForm } from 'enum/profileType.enum' +import { EcogestureStepForm } from 'enum/ecogestureForm.enum' -interface ProfileTypeNavigationProps { - step: ProfileTypeStepForm +interface FormNavigationProps { + step: ProfileTypeStepForm | EcogestureStepForm handlePrevious: Function handleNext: Function disableNextButton: boolean } -const ProfileTypeNavigation: React.FC<ProfileTypeNavigationProps> = ({ +const FormNavigation: React.FC<FormNavigationProps> = ({ step, handlePrevious, handleNext, disableNextButton, -}: ProfileTypeNavigationProps) => { +}: FormNavigationProps) => { const { t } = useI18n() const handlePreviousClick = () => { @@ -43,7 +44,8 @@ const ProfileTypeNavigation: React.FC<ProfileTypeNavigationProps> = ({ </Button> <Button aria-label={ - step === ProfileTypeStepForm.UPDATE_DATE + step === ProfileTypeStepForm.UPDATE_DATE || + step === EcogestureStepForm.EQUIPMENTS ? t('profile_type.accessibility.button_end') : t('profile_type.accessibility.button_next') } @@ -57,7 +59,8 @@ const ProfileTypeNavigation: React.FC<ProfileTypeNavigationProps> = ({ label: 'text-16-normal', }} > - {step === ProfileTypeStepForm.UPDATE_DATE + {step === ProfileTypeStepForm.UPDATE_DATE || + step === EcogestureStepForm.EQUIPMENTS ? t('profile_type.form.button_end') : `${t('profile_type.form.button_next')} >`} </Button> @@ -65,4 +68,4 @@ const ProfileTypeNavigation: React.FC<ProfileTypeNavigationProps> = ({ ) } -export default ProfileTypeNavigation +export default FormNavigation diff --git a/src/components/ProfileType/ProfileTypeFormDateSelection.tsx b/src/components/ProfileType/ProfileTypeFormDateSelection.tsx index 268a7f363..693413cf5 100644 --- a/src/components/ProfileType/ProfileTypeFormDateSelection.tsx +++ b/src/components/ProfileType/ProfileTypeFormDateSelection.tsx @@ -4,7 +4,7 @@ import React, { useCallback, useEffect, useState } from 'react' import 'components/ProfileType/profileTypeForm.scss' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import ProfileTypeProgress from 'components/ProfileType/ProfileTypeProgress' -import ProfileTypeNavigation from 'components/ProfileType/ProfileTypeNavigation' +import FormNavigation from 'components/ProfileType/FormNavigation' import { ProfileTypeStepForm } from 'enum/profileType.enum' import { ProfileType, @@ -238,7 +238,7 @@ const ProfileTypeFormDateSelection: React.FC<ProfileTypeFormDateSelectionProps> </div> ) : null} </div> - <ProfileTypeNavigation + <FormNavigation step={step} handlePrevious={handlePrevious} handleNext={handleNext} diff --git a/src/components/ProfileType/ProfileTypeFormMultiChoice.tsx b/src/components/ProfileType/ProfileTypeFormMultiChoice.tsx index 1924a877d..93b0da660 100644 --- a/src/components/ProfileType/ProfileTypeFormMultiChoice.tsx +++ b/src/components/ProfileType/ProfileTypeFormMultiChoice.tsx @@ -3,7 +3,7 @@ import 'components/ProfileType/profileTypeForm.scss' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import classNames from 'classnames' import ProfileTypeProgress from 'components/ProfileType/ProfileTypeProgress' -import ProfileTypeNavigation from 'components/ProfileType/ProfileTypeNavigation' +import FormNavigation from 'components/ProfileType/FormNavigation' import { remove } from 'lodash' import { IndividualInsulationWork, @@ -118,7 +118,7 @@ const ProfileTypeFormMultiChoice: React.FC<ProfileTypeFormMultiChoiceProps> = ({ } )} </div> - <ProfileTypeNavigation + <FormNavigation step={step} handlePrevious={handlePrevious} handleNext={handleNext} diff --git a/src/components/ProfileType/ProfileTypeFormNumber.tsx b/src/components/ProfileType/ProfileTypeFormNumber.tsx index c5acc3d34..18f54f4c4 100644 --- a/src/components/ProfileType/ProfileTypeFormNumber.tsx +++ b/src/components/ProfileType/ProfileTypeFormNumber.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react' import 'components/ProfileType/profileTypeForm.scss' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import ProfileTypeProgress from 'components/ProfileType/ProfileTypeProgress' -import ProfileTypeNavigation from 'components/ProfileType/ProfileTypeNavigation' +import FormNavigation from 'components/ProfileType/FormNavigation' import { ProfileTypeStepForm } from 'enum/profileType.enum' import { ProfileType, @@ -69,7 +69,7 @@ const ProfileTypeFormNumber: React.FC<ProfileTypeFormNumberProps> = ({ </label> ) : null} </div> - <ProfileTypeNavigation + <FormNavigation step={step} handlePrevious={handlePrevious} handleNext={handleNext} diff --git a/src/components/ProfileType/ProfileTypeFormNumberSelection.tsx b/src/components/ProfileType/ProfileTypeFormNumberSelection.tsx index a11ea926e..9f8ffeabe 100644 --- a/src/components/ProfileType/ProfileTypeFormNumberSelection.tsx +++ b/src/components/ProfileType/ProfileTypeFormNumberSelection.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react' import 'components/ProfileType/profileTypeForm.scss' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import ProfileTypeProgress from 'components/ProfileType/ProfileTypeProgress' -import ProfileTypeNavigation from 'components/ProfileType/ProfileTypeNavigation' +import FormNavigation from 'components/ProfileType/FormNavigation' import { ProfileTypeStepForm } from 'enum/profileType.enum' import { ProfileType, @@ -100,7 +100,7 @@ const ProfileTypeFormNumberSelection: React.FC<ProfileTypeFormNumberSelectionPro </div> ) : null} </div> - <ProfileTypeNavigation + <FormNavigation step={step} handlePrevious={handlePrevious} handleNext={handleNext} diff --git a/src/components/ProfileType/ProfileTypeFormSingleChoice.tsx b/src/components/ProfileType/ProfileTypeFormSingleChoice.tsx index 2f31a2dd1..0c6265ad5 100644 --- a/src/components/ProfileType/ProfileTypeFormSingleChoice.tsx +++ b/src/components/ProfileType/ProfileTypeFormSingleChoice.tsx @@ -3,7 +3,7 @@ import 'components/ProfileType/profileTypeForm.scss' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import classNames from 'classnames' import ProfileTypeProgress from 'components/ProfileType/ProfileTypeProgress' -import ProfileTypeNavigation from 'components/ProfileType/ProfileTypeNavigation' +import FormNavigation from 'components/ProfileType/FormNavigation' import { ProfileTypeStepForm } from 'enum/profileType.enum' import { ProfileType, @@ -85,7 +85,7 @@ const ProfileTypeFormSingleChoice: React.FC<ProfileTypeFormSingleChoiceProps> = } )} </div> - <ProfileTypeNavigation + <FormNavigation step={step} handlePrevious={handlePrevious} handleNext={handleNext} diff --git a/src/components/ProfileType/ProfileTypeView.tsx b/src/components/ProfileType/ProfileTypeView.tsx index 4b6d4c614..76689e60a 100644 --- a/src/components/ProfileType/ProfileTypeView.tsx +++ b/src/components/ProfileType/ProfileTypeView.tsx @@ -89,7 +89,7 @@ const ProfileTypeView = () => { } setStep(nextStep) }, - [step, viewedStep] + [profile.isProfileTypeCompleted, step, viewedStep] ) const setPrevioustStep = useCallback( diff --git a/src/components/ProfileType/profileTypeNavigation.scss b/src/components/ProfileType/formNavigation.scss similarity index 95% rename from src/components/ProfileType/profileTypeNavigation.scss rename to src/components/ProfileType/formNavigation.scss index a3903835e..b3baeff5f 100644 --- a/src/components/ProfileType/profileTypeNavigation.scss +++ b/src/components/ProfileType/formNavigation.scss @@ -13,7 +13,7 @@ align-items: flex-start; padding: 0 0 env(safe-area-inset-bottom) 0; @media (min-width: $width-tablet) { - background: none; + background: $dark-light-2; height: 3rem; } .rounded { diff --git a/src/components/Routes/Routes.tsx b/src/components/Routes/Routes.tsx index 2401f45d1..c87fc67ac 100644 --- a/src/components/Routes/Routes.tsx +++ b/src/components/Routes/Routes.tsx @@ -9,7 +9,8 @@ import ActionView from 'components/Action/ActionView' import UnSubscribe from 'components/Options/UnSubscribe' import TermsView from 'components/Terms/TermsView' import { TermsStatus } from 'models' -import { EcogestureStatus } from 'enum/ecogesture.enum' +import EcogestureFormView from 'components/EcogestureForm/EcogestureFormView' +import EcogestureSelection from 'components/EcogestureForm/EcogestureSelection' const ConsumptionView = lazy(() => import('components/Home/ConsumptionView')) @@ -32,8 +33,12 @@ const ProfileTypeView = lazy(() => interface RouteProps { termsStatus: TermsStatus + isProfileEcogestureCompleted: boolean } -const Routes: React.FC<RouteProps> = ({ termsStatus }: RouteProps) => { +const Routes: React.FC<RouteProps> = ({ + termsStatus, + isProfileEcogestureCompleted, +}: RouteProps) => { return ( <Suspense fallback={<div></div>}> <Switch> @@ -63,6 +68,11 @@ const Routes: React.FC<RouteProps> = ({ termsStatus }: RouteProps) => { <Route path={`/challenges/exploration`} component={ExplorationView} /> <Route path={`/challenges/action`} exact component={ActionView} /> <Route path={`/challenges/`} component={ChallengeView} exact /> + {!isProfileEcogestureCompleted && ( + <Route path="/ecogesture-form" component={EcogestureFormView} /> + )} + <Route path="/ecogesture-selection" component={EcogestureSelection} /> + <Route path="/ecogesture/:id/:tab" component={SingleEcogesture} /> <Route path="/ecogesture/:id" component={SingleEcogesture} /> <Route path={`/ecogestures`} component={EcogestureView} /> <Route path={`/ecogestures`} component={EcogestureView} /> diff --git a/src/components/Splash/SplashRoot.tsx b/src/components/Splash/SplashRoot.tsx index f5ab859bc..6f17748c3 100644 --- a/src/components/Splash/SplashRoot.tsx +++ b/src/components/Splash/SplashRoot.tsx @@ -58,6 +58,7 @@ import { ReleaseNotes } from 'models/releaseNotes.model' import PartnersInfoService from 'services/partnersInfo.service' import FluidService from 'services/fluid.service' import { PartnersInfo } from 'models/partnersInfo.model' +import { updateProfileEcogesture } from 'store/profileEcogesture/profileEcogesture.actions' interface SplashRootProps { fadeTimer?: number @@ -125,6 +126,7 @@ const SplashRoot = ({ // Init profile and update ecogestures, challenges, analysis const profile = await initializationService.initProfile() const profileType = await initializationService.initProfileType() + const profileEcogesture = await initializationService.initProfileEcogesture() if (subscribed && profile) { setValidExploration(UserExplorationID.EXPLORATION007) const [ @@ -153,6 +155,9 @@ const SplashRoot = ({ if (profileType) { dispatch(updateProfileType(profileType)) } + if (profileEcogesture) { + dispatch(updateProfileEcogesture(profileEcogesture)) + } dispatch(toggleAnalysisNotification(!profile.haveSeenLastAnalysis)) } // Init Fluid status && lastDate for the chart diff --git a/src/db/ecogestureData.json b/src/db/ecogestureData.json index 72a25a2c1..a32e71fcf 100644 --- a/src/db/ecogestureData.json +++ b/src/db/ecogestureData.json @@ -34,7 +34,7 @@ "room": [0], "season": "Eté", "equipment": true, - "equipmentType": [0], + "equipmentType": ["AIR_CONDITIONING"], "equipmentInstallation": true, "investment": null, "action": false, @@ -122,7 +122,7 @@ "room": [0], "season": "Sans saison", "equipment": false, - "equipmentType": [1], + "equipmentType": ["COMPUTER"], "equipmentInstallation": true, "investment": null, "action": true, @@ -144,7 +144,7 @@ "room": [2], "season": "Sans saison", "equipment": true, - "equipmentType": [2], + "equipmentType": ["MICROWAVE"], "equipmentInstallation": true, "investment": null, "action": false, @@ -254,7 +254,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [3], + "equipmentType": [], "equipmentInstallation": true, "investment": null, "action": false, @@ -276,7 +276,7 @@ "room": [1, 2, 3], "season": "Sans saison", "equipment": false, - "equipmentType": [4, 5], + "equipmentType": ["WASHING_MACHINE", "DISHWASHER"], "equipmentInstallation": true, "investment": null, "action": true, @@ -298,7 +298,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [], + "equipmentType": ["REFREGIRATOR"], "equipmentInstallation": true, "investment": null, "action": true, @@ -364,7 +364,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [3], + "equipmentType": [], "equipmentInstallation": true, "investment": null, "action": false, @@ -386,7 +386,7 @@ "room": [1, 2, 3], "season": "Sans saison", "equipment": false, - "equipmentType": [4, 5], + "equipmentType": ["WASHING_MACHINE", "DISHWASHER"], "equipmentInstallation": true, "investment": null, "action": true, @@ -408,7 +408,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [6], + "equipmentType": ["COOKING_PLATES"], "equipmentInstallation": true, "investment": null, "action": false, @@ -430,7 +430,7 @@ "room": [1, 2, 3], "season": "Sans saison", "equipment": false, - "equipmentType": [4, 5], + "equipmentType": ["WASHING_MACHINE", "DISHWASHER"], "equipmentInstallation": true, "investment": null, "action": false, @@ -452,7 +452,7 @@ "room": [1, 2, 3], "season": "Sans saison", "equipment": true, - "equipmentType": [7], + "equipmentType": ["DRYER"], "equipmentInstallation": true, "investment": null, "action": false, @@ -474,7 +474,7 @@ "room": [1, 2, 3], "season": "Sans saison", "equipment": false, - "equipmentType": [4, 5], + "equipmentType": ["WASHING_MACHINE", "DISHWASHER"], "equipmentInstallation": true, "investment": null, "action": true, @@ -496,7 +496,7 @@ "room": [1, 2, 3], "season": "Sans saison", "equipment": true, - "equipmentType": [4, 5], + "equipmentType": ["WASHING_MACHINE", "DISHWASHER"], "equipmentInstallation": false, "investment": "Vinaigre blanc ou produit de détartrage", "action": false, @@ -518,7 +518,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [6], + "equipmentType": ["COOKING_PLATES"], "equipmentInstallation": true, "investment": null, "action": false, @@ -606,7 +606,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [], + "equipmentType": ["REFREGIRATOR"], "equipmentInstallation": true, "investment": null, "action": true, @@ -628,7 +628,7 @@ "room": [1, 2, 3], "season": "Sans saison", "equipment": false, - "equipmentType": [4], + "equipmentType": ["WASHING_MACHINE"], "equipmentInstallation": true, "investment": null, "action": true, @@ -650,7 +650,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [], + "equipmentType": ["REFREGIRATOR"], "equipmentInstallation": true, "investment": null, "action": true, @@ -738,7 +738,7 @@ "room": [0], "season": "Eté", "equipment": false, - "equipmentType": [0, 11], + "equipmentType": ["AIR_CONDITIONING", "FAN"], "equipmentInstallation": true, "investment": null, "action": false, @@ -760,7 +760,7 @@ "room": [0], "season": "Eté", "equipment": false, - "equipmentType": [0], + "equipmentType": ["AIR_CONDITIONING"], "equipmentInstallation": true, "investment": null, "action": false, @@ -980,7 +980,7 @@ "room": [], "season": "Sans saison", "equipment": true, - "equipmentType": [9], + "equipmentType": [], "equipmentInstallation": false, "investment": "Seau/ Bac de récupération", "action": false, @@ -1002,7 +1002,7 @@ "room": [1, 2, 3], "season": "Sans saison", "equipment": true, - "equipmentType": [10], + "equipmentType": ["BOILER"], "equipmentInstallation": true, "investment": null, "action": false, @@ -1024,7 +1024,7 @@ "room": [0], "season": "Sans saison", "equipment": true, - "equipmentType": [12], + "equipmentType": ["CURTAIN"], "equipmentInstallation": true, "investment": null, "action": false, @@ -1046,7 +1046,7 @@ "room": [0], "season": "Sans saison", "equipment": false, - "equipmentType": [13], + "equipmentType": ["INTERNET_BOX"], "equipmentInstallation": false, "investment": "Multiprise avec interrupteur marche/arrêt", "action": false, @@ -1068,7 +1068,7 @@ "room": [2], "season": "Sans saison", "equipment": true, - "equipmentType": [2], + "equipmentType": ["MICROWAVE"], "equipmentInstallation": true, "investment": null, "action": false, @@ -1090,7 +1090,7 @@ "room": [0], "season": "Sans saison", "equipment": true, - "equipmentType": [], + "equipmentType": ["VENTILATION"], "equipmentInstallation": true, "investment": null, "action": false, @@ -1134,7 +1134,7 @@ "room": [3], "season": "Sans saison", "equipment": false, - "equipmentType": [7], + "equipmentType": ["DRYER"], "equipmentInstallation": false, "investment": "Etendage", "action": false, @@ -1200,7 +1200,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [15], + "equipmentType": ["REFREGIRATOR", "FREEZER"], "equipmentInstallation": true, "investment": null, "action": true, @@ -1244,7 +1244,7 @@ "room": [0], "season": "Sans saison", "equipment": true, - "equipmentType": [], + "equipmentType": ["VENTILATION"], "equipmentInstallation": true, "investment": null, "action": false, @@ -1310,7 +1310,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [15], + "equipmentType": ["REFREGIRATOR", "FREEZER"], "equipmentInstallation": true, "investment": null, "action": true, @@ -1332,7 +1332,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [15], + "equipmentType": ["REFREGIRATOR", "FREEZER"], "equipmentInstallation": false, "investment": "Thermomètre", "action": false, @@ -1354,7 +1354,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [], + "equipmentType": ["REFREGIRATOR"], "equipmentInstallation": true, "investment": null, "action": true, @@ -1376,7 +1376,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [15], + "equipmentType": ["REFREGIRATOR", "FREEZER"], "equipmentInstallation": true, "investment": null, "action": false, @@ -1398,7 +1398,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [3], + "equipmentType": [], "equipmentInstallation": true, "investment": null, "action": false, @@ -1441,8 +1441,8 @@ "difficulty": 3, "room": [1, 2, 3], "season": "Sans saison", - "equipment": true, - "equipmentType": [16], + "equipment": false, + "equipmentType": [], "equipmentInstallation": false, "investment": "Faire appel à un pro", "action": false, @@ -1486,7 +1486,7 @@ "room": [1, 2, 3], "season": "Sans saison", "equipment": true, - "equipmentType": [10], + "equipmentType": ["BOILER"], "equipmentInstallation": false, "investment": "Faire appel à un pro", "action": false, @@ -1530,7 +1530,7 @@ "room": [0], "season": "Sans saison", "equipment": true, - "equipmentType": [17], + "equipmentType": ["HYDRAULIC_HEATING"], "equipmentInstallation": false, "investment": "Faire appel à un pro", "action": false, @@ -1574,7 +1574,7 @@ "room": [0], "season": "Sans saison", "equipment": true, - "equipmentType": [17], + "equipmentType": ["HYDRAULIC_HEATING"], "equipmentInstallation": false, "investment": "Isolant", "action": false, @@ -1596,7 +1596,7 @@ "room": [0], "season": "Sans saison", "equipment": true, - "equipmentType": [17], + "equipmentType": ["HYDRAULIC_HEATING"], "equipmentInstallation": false, "investment": "Faire appel à un pro", "action": false, @@ -1662,7 +1662,7 @@ "room": [2], "season": "Sans saison", "equipment": false, - "equipmentType": [], + "equipmentType": ["REFREGIRATOR"], "equipmentInstallation": true, "investment": null, "action": false, diff --git a/src/doctypes/com-grandlyon-ecolyo-profileecogesture.ts b/src/doctypes/com-grandlyon-ecolyo-profileecogesture.ts new file mode 100644 index 000000000..6a312fe7d --- /dev/null +++ b/src/doctypes/com-grandlyon-ecolyo-profileecogesture.ts @@ -0,0 +1,2 @@ +export const PROFILEECOGESTURE_DOCTYPE = + 'com.grandlyon.ecolyo.profileecogesture' diff --git a/src/doctypes/index.ts b/src/doctypes/index.ts index a52d25ff8..eb711a242 100644 --- a/src/doctypes/index.ts +++ b/src/doctypes/index.ts @@ -28,6 +28,7 @@ import { EGL_YEAR_DOCTYPE } from './com-grandlyon-egl-year' import { EGL_MONTH_DOCTYPE } from './com-grandlyon-egl-month' import { ENEDIS_MONTHLY_ANALYSIS_DATA_DOCTYPE } from './com-grandlyon-enedis-monthly-analysis-data' import { ENEDIS_MAXPOWER_DOCTYPE } from './com-grandlyon-enedis-maxpower' +import { PROFILEECOGESTURE_DOCTYPE } from './com-grandlyon-ecolyo-profileecogesture' // the documents schema, necessary for CozyClient const doctypes = { @@ -179,6 +180,11 @@ const doctypes = { attributes: {}, relationships: {}, }, + profileecogesture: { + doctype: PROFILEECOGESTURE_DOCTYPE, + attributes: {}, + relationships: {}, + }, } export default doctypes @@ -217,3 +223,4 @@ export * from './com-grandlyon-ecolyo-duel' export * from './com-grandlyon-ecolyo-quiz' export * from './com-grandlyon-ecolyo-exploration' export * from './com-grandlyon-ecolyo-usageevent' +export * from './com-grandlyon-ecolyo-profileecogesture' diff --git a/src/enum/ecogesture.enum.ts b/src/enum/ecogesture.enum.ts index 4ea5854e5..c14162c8e 100644 --- a/src/enum/ecogesture.enum.ts +++ b/src/enum/ecogesture.enum.ts @@ -23,24 +23,21 @@ export enum Season { } export enum EquipmentType { - AIR_CONDITIONING = 0, - COMPUTER = 1, - MICROWAVE = 2, - OVEN = 3, - WASHING_MACHINE = 4, - DISHWASHER = 5, - COOKING_PLATES = 6, - DRYER = 7, - REFREGIRATOR = 8, - GARDEN = 9, - WATER_HEATER = 10, - FAN = 11, - CURTAIN = 12, - INTERNET_BOX = 13, - VENTILATION = 14, - FREEZER = 15, - BOILER = 16, - HYDRAULIC_HEATING = 17, + AIR_CONDITIONING = 'AIR_CONDITIONING', + COMPUTER = 'COMPUTER', + MICROWAVE = 'MICROWAVE', + WASHING_MACHINE = 'WASHING_MACHINE', + DISHWASHER = 'DISHWASHER', + COOKING_PLATES = 'COOKING_PLATES', + DRYER = 'DRYER', + REFREGIRATOR = 'REFREGIRATOR', + FAN = 'FAN', + CURTAIN = 'CURTAIN', + INTERNET_BOX = 'INTERNET_BOX', + VENTILATION = 'VENTILATION', + FREEZER = 'FREEZER', + BOILER = 'BOILER', + HYDRAULIC_HEATING = 'HYDRAULIC_HEATING', } export enum EcogestureStatus { diff --git a/src/enum/ecogestureForm.enum.ts b/src/enum/ecogestureForm.enum.ts new file mode 100644 index 000000000..556793f50 --- /dev/null +++ b/src/enum/ecogestureForm.enum.ts @@ -0,0 +1,10 @@ +export enum EcogestureStepForm { + HEATING_TYPE = 0, + WARMING_FLUID = 1, + HOT_WATER_TYPE = 2, + EQUIPMENTS = 3, +} +export enum ProfileEcogestureAnswerType { + SINGLE_CHOICE = 0, + MULTI_CHOICE = 1, +} diff --git a/src/locales/fr.json b/src/locales/fr.json index 0dbcc50fc..aa1afa255 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -393,6 +393,7 @@ "title": "Sélectionner mes écogestes", "text1": "Les écogestes sont des actions qui vous permettent de réduire vos consommations et donc vos factures.", "text2": "Vous pouvez sélectionner ceux à mettre en objectifs et ceux que vous appliquez déjà.", + "text3": "Afin de savoir quels écogestes correspondent à votre consommation, merci de répondre à quelques rapides questions.", "btn1": "Plus tard", "btn2": "C'est parti !" } @@ -421,6 +422,52 @@ "button_close": "Fermer la fenêtre" } }, + "ecogesture_form": { + "heating_type": { + "title": "Chauffage", + "question": "Quel est votre type de chauffage ?", + "individual": "Individuel", + "collective": "Collectif" + }, + "warming_fluid": { + "title": "Source chauffage", + "question": "Quelle source d’énergie principale utilisez-vous pour votre chauffage ?", + "0": "Électricité", + "2": "Gaz", + "3": "Bois", + "4": "Fioul" + }, + "hot_water_type": { + "title": "Eau chaude", + "question": "Quel est votre type de production d’eau chaude ?", + "individual": "Individuelle", + "collective": "Collective" + } + }, + "ecogesture_profile": { + "equipments": { + "question": "Quels équipements possédez-vous ?", + "hint": "Plusieurs réponses possibles", + "air_conditioning": "Climatisation", + "computer": "Ordinateur", + "microwave": "Micro-ondes", + "oven": "Four", + "washing_machine": "Lave-linge", + "dishwasher": "Lave-vaisselle", + "cooking_plates": "Plaques électriques", + "garden": "Jardin", + "dryer": "Sèche-linge", + "refregirator": "Réfrégirateur", + "fan": "Ventilateur", + "water_heater": "Chauffe-eau", + "curtain": "Rideaux", + "internet_box": "Box internet", + "ventilation": "VMC", + "freezer": "Congélateur", + "boiler": "Chaudière", + "hydraulic_heating": "Chauffage hydraulique" + } + }, "exploration": { "global_error": "Oups. Une erreur est survenue. Veuillez retourner à l'écran d’accueil des défis", "button_go_back": "Retour", diff --git a/src/models/profile.model.ts b/src/models/profile.model.ts index 616295738..5f1741939 100644 --- a/src/models/profile.model.ts +++ b/src/models/profile.model.ts @@ -19,6 +19,7 @@ export interface ProfileEntity { sendConsumptionAlert: boolean waterDailyConsumptionLimit: number isProfileTypeCompleted: boolean + isProfileEcogestureCompleted: boolean onboarding: Onboarding mailToken: string partnersIssueDate: string diff --git a/src/models/profileEcogesture.model.ts b/src/models/profileEcogesture.model.ts new file mode 100644 index 000000000..08187ec48 --- /dev/null +++ b/src/models/profileEcogesture.model.ts @@ -0,0 +1,40 @@ +import { EquipmentType } from 'enum/ecogesture.enum' +import { ProfileEcogestureAnswerType } from 'enum/ecogestureForm.enum' +import { FluidType } from 'enum/fluid.enum' +import { + IndividualOrCollective, + HotWaterEquipment, + WarmingType, +} from 'enum/profileType.enum' + +interface ProfileEcogestureIndexableTypes { + [key: string]: + | IndividualOrCollective + | FluidType + | WarmingType + | EquipmentType[] + | string + | null +} +export type ProfileEcogestureAnswerChoices = + | string + | IndividualOrCollective + | HotWaterEquipment + | FluidType + | WarmingType + | EquipmentType[] + | number + | null + +export interface ProfileEcogestureAnswer { + type: ProfileEcogestureAnswerType + attribute: string + choices: ProfileEcogestureAnswerChoices[] +} + +export interface ProfileEcogesture extends ProfileEcogestureIndexableTypes { + heating: IndividualOrCollective + warmingFluid: WarmingType | null + hotWater: IndividualOrCollective + equipments: EquipmentType[] +} diff --git a/src/services/ecogesture.service.spec.ts b/src/services/ecogesture.service.spec.ts index 0647b039e..0b6742693 100644 --- a/src/services/ecogesture.service.spec.ts +++ b/src/services/ecogesture.service.spec.ts @@ -3,22 +3,19 @@ import { Ecogesture } from 'models' import EcogestureService from './ecogesture.service' import mockClient from '../../tests/__mocks__/client' import { - ecogesturesAirConditioningData, - ecogesturesColdWaterData, - ecogesturesCookingData, + BoilerEcogesture, + BoilerEcogestureFalse, ecogesturesData, ecogesturesECSData, - ecogesturesElecSpecificData, ecogesturesHeatingData, } from '../../tests/__mocks__/ecogesturesData.mock' -import { ProfileType } from 'models/profileType.model' import { IndividualOrCollective, WarmingType } from 'enum/profileType.enum' -import { FluidType } from 'enum/fluid.enum' -import { mockProfileType2 } from '../../tests/__mocks__/profileType.mock' +import { mockProfileEcogesture } from '../../tests/__mocks__/profileEcogesture.mock' +import { ProfileEcogesture } from 'models/profileEcogesture.model' +import { EquipmentType } from 'enum/ecogesture.enum' describe('Ecogesture service', () => { const ecogestureService = new EcogestureService(mockClient) - describe('getAllEcogestures', () => { it('should return all ecogestures', async () => { const mockQueryResult: QueryResult<Ecogesture[]> = { @@ -81,184 +78,129 @@ describe('Ecogesture service', () => { expect(result).toBe(false) }) }) - - describe('filteredEcogestureList', () => { - describe('usage heating', () => { - it('should return ecogesture with electricity', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesHeatingData - const mockProfileType: ProfileType = { - ...mockProfileType2, - heating: IndividualOrCollective.INDIVIDUAL, - warmingFluid: WarmingType.ELECTRICITY, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([mockEcogestureList[0], mockEcogestureList[2]]) - }) - it('should return ecogesture with gas', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesHeatingData - const mockProfileType: ProfileType = { - ...mockProfileType2, - heating: IndividualOrCollective.INDIVIDUAL, - warmingFluid: WarmingType.GAS, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([mockEcogestureList[1], mockEcogestureList[2]]) - }) - it('should not return ecogesture when profile heating is collective', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesHeatingData - const mockProfileType: ProfileType = { - ...mockProfileType2, - heating: IndividualOrCollective.COLLECTIVE, - warmingFluid: WarmingType.ELECTRICITY, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([]) - }) + describe('filterByUsage', () => { + it('should return ecogesture list including ECS ecogestures', async () => { + const mockEcogestureList: Ecogesture[] = ecogesturesECSData + const mockProfileEcogesture1: ProfileEcogesture = { + ...mockProfileEcogesture, + hotWater: IndividualOrCollective.INDIVIDUAL, + } + const result = ecogestureService.filterByUsage( + mockEcogestureList, + mockProfileEcogesture1 + ) + expect(result.includes(ecogesturesECSData[0])).toBeTruthy() }) - - describe('usage ECS', () => { - it('should return ecogesture with electricity', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesECSData - const mockProfileType: ProfileType = { - ...mockProfileType2, - hotWater: IndividualOrCollective.INDIVIDUAL, - hotWaterFluid: FluidType.ELECTRICITY, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([mockEcogestureList[0], mockEcogestureList[2]]) - }) - it('should return ecogesture with gas', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesECSData - const mockProfileType: ProfileType = { - ...mockProfileType2, - hotWater: IndividualOrCollective.INDIVIDUAL, - hotWaterFluid: FluidType.GAS, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([mockEcogestureList[1], mockEcogestureList[2]]) - }) - it('should not return ecogesture when profile warming is collective', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesECSData - const mockProfileType: ProfileType = { - ...mockProfileType2, - hotWater: IndividualOrCollective.COLLECTIVE, - hotWaterFluid: FluidType.ELECTRICITY, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([]) - }) + it('should return ecogesture list excluding ECS ecogestures', async () => { + const mockEcogestureList: Ecogesture[] = ecogesturesECSData + const mockProfileEcogesture1: ProfileEcogesture = { + ...mockProfileEcogesture, + hotWater: IndividualOrCollective.COLLECTIVE, + } + const result = ecogestureService.filterByUsage( + mockEcogestureList, + mockProfileEcogesture1 + ) + expect(result.includes(ecogesturesECSData[1])).toBeFalsy() }) - - describe('usage COOKING', () => { - it('should return ecogesture with electricity', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesCookingData - const mockProfileType: ProfileType = { - ...mockProfileType2, - cookingFluid: FluidType.ELECTRICITY, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([mockEcogestureList[0], mockEcogestureList[2]]) - }) - it('should return ecogesture with gas', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesCookingData - const mockProfileType: ProfileType = { - ...mockProfileType2, - cookingFluid: FluidType.GAS, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([mockEcogestureList[1], mockEcogestureList[2]]) - }) + it('should return ecogesture list including HEATING ecogestures', async () => { + const mockEcogestureList: Ecogesture[] = ecogesturesHeatingData + const mockProfileEcogesture2: ProfileEcogesture = { + ...mockProfileEcogesture, + heating: IndividualOrCollective.INDIVIDUAL, + warmingFluid: WarmingType.ELECTRICITY, + } + const result = ecogestureService.filterByUsage( + mockEcogestureList, + mockProfileEcogesture2 + ) + expect(result.includes(ecogesturesHeatingData[0])).toBeTruthy() }) - - describe('usage COLD_WATER', () => { - it('should return all water ecogestures', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesColdWaterData - const mockProfileType: ProfileType = { - ...mockProfileType2, - coldWater: IndividualOrCollective.INDIVIDUAL, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual(mockEcogestureList) - }) - it('should not return water ecogestures', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesColdWaterData - const mockProfileType: ProfileType = { - ...mockProfileType2, - coldWater: IndividualOrCollective.COLLECTIVE, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([]) - }) + it('should return ecogesture list excluding HEATING ecogestures', async () => { + const mockEcogestureList: Ecogesture[] = ecogesturesHeatingData + const mockProfileEcogesture2: ProfileEcogesture = { + ...mockProfileEcogesture, + heating: IndividualOrCollective.COLLECTIVE, + } + const result = ecogestureService.filterByUsage( + mockEcogestureList, + mockProfileEcogesture2 + ) + expect(result.includes(ecogesturesHeatingData[0])).toBeFalsy() }) - - describe('usage ELECTRICITY_SPECIFIC', () => { - it('should return all ecogestures', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesElecSpecificData - const mockProfileType: ProfileType = { - ...mockProfileType2, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual(mockEcogestureList) - }) + }) + describe('filterByEquipment', () => { + it('should return ecogesture list including BOILER equipment and equipment veriication to true', async () => { + const mockProfileEcogestureBOILER: ProfileEcogesture = { + ...mockProfileEcogesture, + equipments: [EquipmentType.BOILER], + } + const result = ecogestureService.filterByEquipment( + BoilerEcogesture, + mockProfileEcogestureBOILER + ) + expect(result.includes(BoilerEcogesture[0])).toBeTruthy() + }) + it('should return ecogesture list excluding BOILER equipment and equipment veriication to true', async () => { + const mockProfileEcogestureBOILER: ProfileEcogesture = { + ...mockProfileEcogesture, + } + const result = ecogestureService.filterByEquipment( + BoilerEcogesture, + mockProfileEcogestureBOILER + ) + expect(result.includes(BoilerEcogesture[0])).toBeFalsy() + }) + it('should return ecogesture list including BOILER equipment with equipment veriication to false but equipment to BOILER', async () => { + const mockProfileEcogestureBOILER: ProfileEcogesture = { + ...mockProfileEcogesture, + equipments: [EquipmentType.BOILER], + } + const result = ecogestureService.filterByEquipment( + BoilerEcogestureFalse, + mockProfileEcogestureBOILER + ) + expect(result.includes(BoilerEcogestureFalse[0])).toBeTruthy() }) + }) + describe('getEcogestureListByProfile', () => { + it('should return ecogesture list according to profile ecogesture, sorted and filtered', async () => { + const mockProfileEcogestureFull: ProfileEcogesture = { + ...mockProfileEcogesture, + equipments: [EquipmentType.WASHING_MACHINE, EquipmentType.DISHWASHER], + } + const mockQueryResult: QueryResult<Ecogesture[]> = { + data: ecogesturesData, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) - describe('usage AIR_CONDITIONING', () => { - it('should not return ecogestures', async () => { - const mockEcogestureList: Ecogesture[] = ecogesturesAirConditioningData - const mockProfileType: ProfileType = { - ...mockProfileType2, - } - const result = EcogestureService.getEcogestureListByProfile( - mockEcogestureList, - mockProfileType - ) - expect(result).toEqual([]) - }) + const result = await ecogestureService.getEcogestureListByProfile( + mockProfileEcogestureFull + ) + expect(result.length).toBe(2) + expect(result[0]).toBe(ecogesturesData[0]) }) }) + describe('getEcogesturesByIds', () => { + it('Should return corresponding ecogestures', async () => { + const mockQueryResult: QueryResult<Ecogesture[]> = { + data: ecogesturesECSData, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) - it('should update an ecogesture', async () => { - const mockQueryResult: QueryResult<Ecogesture> = { - data: ecogesturesData[0], - bookmark: '', - next: false, - skip: 0, - } - mockClient.save.mockResolvedValueOnce(mockQueryResult) - const result = await ecogestureService.updateEcogesture(ecogesturesData[0]) - expect(result).toEqual(ecogesturesData[0]) + const result = await ecogestureService.getEcogesturesByIds([ + 'ECOGESTURE0001', + 'ECOGESTURE0002', + 'ECOGESTURE0013', + ]) + expect(result.length).toBe(3) + expect(result).toBe(ecogesturesECSData) + }) }) }) diff --git a/src/services/ecogesture.service.ts b/src/services/ecogesture.service.ts index 5ce03fe1e..ee4f73171 100644 --- a/src/services/ecogesture.service.ts +++ b/src/services/ecogesture.service.ts @@ -5,7 +5,8 @@ import { FluidType } from 'enum/fluid.enum' import { IndividualOrCollective, WarmingType } from 'enum/profileType.enum' import { Season } from 'enum/ecogesture.enum' import { Ecogesture } from 'models' -import { ProfileType } from 'models/profileType.model' +import { ProfileEcogesture } from 'models/profileEcogesture.model' +import { orderBy } from 'lodash' export default class EcogestureService { private readonly _client: Client @@ -72,79 +73,103 @@ export default class EcogestureService { } /** - * Return duel with updated thrshold and fluidTypes - * @param {UserDuel} userDuel - userDuel to update - * @returns {UserDuel} + * Removes ecogestures from the list that doesn't fit with user's usages + * @param {Ecogesture[]} ecogestureList + * @param {ProfileEcogesture} profileEcogesture + * @returns {Ecogesture[]} */ - static getEcogestureListByProfile( + public filterByUsage( ecogestureList: Ecogesture[], - profileType: ProfileType + profileEcogesture: ProfileEcogesture ): Ecogesture[] { - const filteredEcogestureList: Ecogesture[] = ecogestureList.filter( - ecogesture => { - switch (ecogesture.usage) { - case Usage.HEATING: - if ( - ecogesture.fluidTypes.includes(FluidType.ELECTRICITY) && - profileType.heating === IndividualOrCollective.INDIVIDUAL && - profileType.warmingFluid === WarmingType.ELECTRICITY - ) { - return true - } else if ( - ecogesture.fluidTypes.includes(FluidType.GAS) && - profileType.heating === IndividualOrCollective.INDIVIDUAL && - profileType.warmingFluid === WarmingType.GAS - ) { - return true - } else { - return false - } - case Usage.ECS: - if ( - ecogesture.fluidTypes.includes(FluidType.ELECTRICITY) && - profileType.hotWater === IndividualOrCollective.INDIVIDUAL && - profileType.hotWaterFluid === FluidType.ELECTRICITY - ) { - return true - } else if ( - ecogesture.fluidTypes.includes(FluidType.GAS) && - profileType.hotWater === IndividualOrCollective.INDIVIDUAL && - profileType.hotWaterFluid === FluidType.GAS - ) { - return true - } else { - return false - } - case Usage.COOKING: - if ( - ecogesture.fluidTypes.includes(FluidType.ELECTRICITY) && - profileType.cookingFluid === FluidType.ELECTRICITY - ) { - return true - } else if ( - ecogesture.fluidTypes.includes(FluidType.GAS) && - profileType.cookingFluid === FluidType.GAS - ) { - return true - } else { - return false - } - case Usage.COLD_WATER: - if (profileType.coldWater === IndividualOrCollective.INDIVIDUAL) { - return true - } else { - return false - } - case Usage.ELECTRICITY_SPECIFIC: + const filteredByUsage: Ecogesture[] = ecogestureList.filter(ecogesture => { + switch (ecogesture.usage) { + case Usage.HEATING: + if ( + ecogesture.fluidTypes.includes(FluidType.ELECTRICITY) && + profileEcogesture.heating === IndividualOrCollective.INDIVIDUAL && + profileEcogesture.warmingFluid === WarmingType.ELECTRICITY + ) { return true - case Usage.AIR_CONDITIONING: - default: + } else if ( + ecogesture.fluidTypes.includes(FluidType.GAS) && + profileEcogesture.heating === IndividualOrCollective.INDIVIDUAL && + profileEcogesture.warmingFluid === WarmingType.GAS + ) { + return true + } else { + return false + } + case Usage.ECS: + if ( + profileEcogesture.hotWater === IndividualOrCollective.INDIVIDUAL + ) { + return true + } else { return false + } + default: + return true + } + }) + return filteredByUsage + } + + /** + * Removes ecogesture from the list that depends on equipment the user hasn't + * @param {Ecogesture[]} ecogestureList + * @param {ProfileEcogesture} profileEcogesture + * @returns {Ecogesture[]} + */ + public filterByEquipment( + ecogestureList: Ecogesture[], + profileEcogesture: ProfileEcogesture + ): Ecogesture[] { + for (const ecogesture of ecogestureList) { + if (ecogesture.equipment === true) { + for (const equipmentType of ecogesture.equipmentType) { + if (!profileEcogesture.equipments.includes(equipmentType)) { + const index = ecogestureList.indexOf(ecogesture) + ecogestureList.splice(index, 1) + } } } + } + return ecogestureList + } + + /** + * Return a filtered list according to ecogesture profile, the list is sorted by low difficulty and high efficiency + * @param {ProfileEcogesture} profileEcogesture + * @returns {Ecogesture[]} + */ + public async getEcogestureListByProfile( + profileEcogesture: ProfileEcogesture + ): Promise<Ecogesture[]> { + const ecogestureList: Ecogesture[] = await this.getAllEcogestures() + const filteredByUsage: Ecogesture[] = this.filterByUsage( + ecogestureList, + profileEcogesture + ) + const filteredByEquipment: Ecogesture[] = this.filterByEquipment( + filteredByUsage, + profileEcogesture ) - return filteredEcogestureList + const sortedByDifficultyAndEfficiency: Ecogesture[] = orderBy( + filteredByEquipment, + [ + ecogesture => { + return ecogesture.difficulty + }, + ecogesture => { + return ecogesture.efficiency + }, + ], + ['asc', 'desc'] + ) + return sortedByDifficultyAndEfficiency } + /** * Update one ecogesture * @param {Ecogesture} ecogesture - Ecogesture to save diff --git a/src/services/initialization.service.ts b/src/services/initialization.service.ts index bab9fda86..42d9da6db 100644 --- a/src/services/initialization.service.ts +++ b/src/services/initialization.service.ts @@ -56,6 +56,8 @@ import { DateTime } from 'luxon' import ProfileTypeEntityService from './profileTypeEntity.service' import TermsService from './terms.service' import log from 'utils/logger' +import { ProfileEcogesture } from 'models/profileEcogesture.model' +import ProfileEcogestureService from './profileEcogesture.service' export default class InitializationService { private readonly _client: Client @@ -195,6 +197,17 @@ export default class InitializationService { throw error } } + public async initProfileEcogesture(): Promise<ProfileEcogesture | null> { + const profileEcogestureService = new ProfileEcogestureService(this._client) + try { + const loadedProfileEcogesture = await profileEcogestureService.getProfileEcogesture() + log.info('[Initialization] ProfileEcogesture loaded') + return loadedProfileEcogesture + } catch (error) { + log.error('Initialization error - initProfileEcogesture: ', error) + throw error + } + } public async initEcogesture(hash: string): Promise<string> { const hashEcogestureType = hashFile(ecogestureData) diff --git a/src/services/profileEcogesture.service.spec.ts b/src/services/profileEcogesture.service.spec.ts new file mode 100644 index 000000000..1c516dfb9 --- /dev/null +++ b/src/services/profileEcogesture.service.spec.ts @@ -0,0 +1,50 @@ +import { QueryResult } from 'cozy-client' +import { EquipmentType } from 'enum/ecogesture.enum' +import { ProfileEcogesture } from 'models/profileEcogesture.model' +import mockClient from '../../tests/__mocks__/client' +import { mockProfileEcogestureUpdated } from '../../tests/__mocks__/profileEcogesture.mock' +import ProfileEcogestureService from './profileEcogesture.service' + +const profileEcogestureService = new ProfileEcogestureService(mockClient) + +describe('ProfileEcogesture service', () => { + it('should get the Profile Ecogesture', async () => { + const mockQueryResult: QueryResult<ProfileEcogesture> = { + data: mockProfileEcogestureUpdated, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result = await profileEcogestureService.getProfileEcogesture() + expect(result).toEqual(mockProfileEcogestureUpdated) + }) + it('should update a profile ecogesture', async () => { + const ecogestureProfile = { + ...mockProfileEcogestureUpdated, + equipments: [ + EquipmentType.BOILER, + EquipmentType.INTERNET_BOX, + EquipmentType.FREEZER, + ], + } + const mockQueryResult: QueryResult<ProfileEcogesture> = { + data: [mockProfileEcogestureUpdated], + bookmark: '', + next: false, + skip: 0, + } + const mockQueryResultUpdate: QueryResult<ProfileEcogesture> = { + data: ecogestureProfile, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValue(mockQueryResult) + mockClient.save.mockResolvedValue(mockQueryResultUpdate) + const result = await profileEcogestureService.updateProfileEcogesture({ + equipments: [EquipmentType.FREEZER], + }) + expect(result).toEqual(ecogestureProfile) + }) +}) diff --git a/src/services/profileEcogesture.service.ts b/src/services/profileEcogesture.service.ts new file mode 100644 index 000000000..006809ad3 --- /dev/null +++ b/src/services/profileEcogesture.service.ts @@ -0,0 +1,50 @@ +import { Client, QueryDefinition, QueryResult, Q } from 'cozy-client' +import { PROFILEECOGESTURE_DOCTYPE } from 'doctypes' +import { ProfileEcogesture } from 'models/profileEcogesture.model' + +export default class ProfileEcogestureService { + private readonly _client: Client + + constructor(_client: Client) { + this._client = _client + } + /** + * Retrieve the ProfileEcogesture from db + * @returns {ProfileEcogesture} + */ + public async getProfileEcogesture(): Promise<ProfileEcogesture | null> { + const query: QueryDefinition = Q(PROFILEECOGESTURE_DOCTYPE) + const { + data: profileEcogesture, + }: QueryResult<ProfileEcogesture> = await this._client.query( + query.limitBy(1) + ) + if (profileEcogesture) return profileEcogesture + else return null + } + + /** + * Saves ProfileEcogesture in database + * @returns {ProfileEcogesture} + */ + public async updateProfileEcogesture( + attributes: Partial<ProfileEcogesture> + ): Promise<ProfileEcogesture | null> { + const query: QueryDefinition = Q(PROFILEECOGESTURE_DOCTYPE) + const { + data: [doc], + }: QueryResult<ProfileEcogesture[]> = await this._client.query( + query.limitBy(1) + ) + if (doc) { + const { + data: profileEcogesture, + }: QueryResult<ProfileEcogesture | null> = await this._client.save({ + ...doc, + ...attributes, + }) + if (profileEcogesture) return profileEcogesture + } + return null + } +} diff --git a/src/services/profileEcogestureForm.service.ts b/src/services/profileEcogestureForm.service.ts new file mode 100644 index 000000000..6717b8771 --- /dev/null +++ b/src/services/profileEcogestureForm.service.ts @@ -0,0 +1,105 @@ +import { EquipmentType } from 'enum/ecogesture.enum' +import { + EcogestureStepForm, + ProfileEcogestureAnswerType, +} from 'enum/ecogestureForm.enum' +import { IndividualOrCollective, WarmingType } from 'enum/profileType.enum' +import { + ProfileEcogesture, + ProfileEcogestureAnswer, +} from 'models/profileEcogesture.model' + +export default class ProfileEcogestureFormService { + private readonly profileEcogesture: ProfileEcogesture + + constructor(profileEcogesture: ProfileEcogesture) { + this.profileEcogesture = profileEcogesture + } + + /** + * getNextFormStep + * @param {EcogestureStepForm} step + * @returns {EcogestureStepForm} next step + */ + public getNextFormStep(step: EcogestureStepForm): EcogestureStepForm { + switch (step) { + case EcogestureStepForm.HEATING_TYPE: + return this.profileEcogesture.heating === + IndividualOrCollective.INDIVIDUAL + ? EcogestureStepForm.WARMING_FLUID + : EcogestureStepForm.HOT_WATER_TYPE + case EcogestureStepForm.WARMING_FLUID: + return EcogestureStepForm.HOT_WATER_TYPE + case EcogestureStepForm.HOT_WATER_TYPE: + return EcogestureStepForm.EQUIPMENTS + default: + return EcogestureStepForm.HEATING_TYPE + } + } + + /** + * getPreviousFormStep + * @param {EcogestureStepForm} step + * @returns {EcogestureStepForm} previous step + */ + public getPreviousFormStep(step: EcogestureStepForm): EcogestureStepForm { + switch (step) { + case EcogestureStepForm.EQUIPMENTS: + return EcogestureStepForm.HOT_WATER_TYPE + case EcogestureStepForm.HOT_WATER_TYPE: + return this.profileEcogesture.heating === + IndividualOrCollective.INDIVIDUAL + ? EcogestureStepForm.WARMING_FLUID + : EcogestureStepForm.HEATING_TYPE + case EcogestureStepForm.WARMING_FLUID: + return EcogestureStepForm.HEATING_TYPE + default: + return EcogestureStepForm.HEATING_TYPE + } + } + + /** + * getAnswerForStep + * @param {EcogestureStepForm} step + * @returns {EcogestureFormAnswer} + */ + static getAnswerForStep(step: EcogestureStepForm): ProfileEcogestureAnswer { + switch (step) { + case EcogestureStepForm.HEATING_TYPE: + return { + type: ProfileEcogestureAnswerType.SINGLE_CHOICE, + attribute: 'heating', + choices: Object.values(IndividualOrCollective), + } + case EcogestureStepForm.WARMING_FLUID: + return { + type: ProfileEcogestureAnswerType.SINGLE_CHOICE, + attribute: 'warmingFluid', + choices: [ + WarmingType.ELECTRICITY, + WarmingType.GAS, + WarmingType.WOOD, + WarmingType.FUEL, + ], + } + case EcogestureStepForm.HOT_WATER_TYPE: + return { + type: ProfileEcogestureAnswerType.SINGLE_CHOICE, + attribute: 'hotWater', + choices: Object.values(IndividualOrCollective), + } + case EcogestureStepForm.EQUIPMENTS: + return { + type: ProfileEcogestureAnswerType.MULTI_CHOICE, + attribute: 'equipments', + choices: Object.keys(EquipmentType), + } + default: + return { + type: ProfileEcogestureAnswerType.SINGLE_CHOICE, + attribute: 'heating', + choices: Object.values(IndividualOrCollective), + } + } + } +} diff --git a/src/store/index.ts b/src/store/index.ts index 45137173e..670d74d46 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -23,11 +23,14 @@ import { } from 'models' import { ChartState } from 'models/chart.model' import { Client } from 'cozy-client' +import { ProfileEcogesture } from 'models/profileEcogesture.model' +import { profileEcogestureReducer } from './profileEcogesture/profileEcogesture.reducer' export interface EcolyoState { global: GlobalState profile: Profile profileType: ProfileType + profileEcogesture: ProfileEcogesture chart: ChartState modal: ModalState challenge: ChallengeState @@ -37,6 +40,7 @@ export const ecolyoReducer = combineReducers({ global: globalReducer, profile: profileReducer, profileType: profileTypeReducer, + profileEcogesture: profileEcogestureReducer, chart: chartReducer, modal: modalReducer, challenge: challengeReducer, diff --git a/src/store/profile/profile.reducer.ts b/src/store/profile/profile.reducer.ts index 65ac46a8a..8334f1a68 100644 --- a/src/store/profile/profile.reducer.ts +++ b/src/store/profile/profile.reducer.ts @@ -23,6 +23,7 @@ const initialState: Profile = { mailToken: '', monthlyAnalysisDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), isProfileTypeCompleted: false, + isProfileEcogestureCompleted: false, onboarding: { isWelcomeSeen: false, }, diff --git a/src/store/profileEcogesture/profileEcogesture.action.spec.ts b/src/store/profileEcogesture/profileEcogesture.action.spec.ts new file mode 100644 index 000000000..ce271348d --- /dev/null +++ b/src/store/profileEcogesture/profileEcogesture.action.spec.ts @@ -0,0 +1,45 @@ +import { + createMockStore, + mockInitialEcolyoState, +} from '../../../tests/__mocks__/store' +import { mockProfileEcogesture } from '../../../tests/__mocks__/profileEcogesture.mock' +import { + updateProfileEcogesture, + UPDATE_PROFILEECOGESTURE, +} from './profileEcogesture.actions' + +const mockUpdateProfileEcogesture = jest.fn() +const mockNewProfileEcogestureEntry = jest.fn() +jest.mock('services/profileEcogesture.service', () => { + return jest.fn(() => { + return { + updateProfileEcogesture: mockUpdateProfileEcogesture, + newProfileEcogestureEntry: mockNewProfileEcogestureEntry, + } + }) +}) + +describe('profileEcogesture actions', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let store: any + beforeEach(() => { + store = createMockStore(mockInitialEcolyoState) + }) + it('should create an UPDATE_PROFILEECOGESTURE action when ecogestureProfile is updated', async () => { + mockUpdateProfileEcogesture.mockResolvedValueOnce(mockProfileEcogesture) + const expectedActions = [ + { + type: UPDATE_PROFILEECOGESTURE, + payload: mockProfileEcogesture, + }, + ] + await store.dispatch(updateProfileEcogesture(mockProfileEcogesture)) + expect(store.getActions()).toEqual(expectedActions) + }) + + it('should not create action when ProfileEcogesture is not updated', async () => { + mockUpdateProfileEcogesture.mockResolvedValueOnce(null) + await store.dispatch(updateProfileEcogesture(mockProfileEcogesture)) + expect(store.getActions()).toEqual([]) + }) +}) diff --git a/src/store/profileEcogesture/profileEcogesture.actions.ts b/src/store/profileEcogesture/profileEcogesture.actions.ts new file mode 100644 index 000000000..bf38ae729 --- /dev/null +++ b/src/store/profileEcogesture/profileEcogesture.actions.ts @@ -0,0 +1,69 @@ +import { Client } from 'cozy-client' +import { Dispatch } from 'react' +import { AppStore } from 'store' +import { ProfileEcogesture } from 'models/profileEcogesture.model' +import { PROFILEECOGESTURE_DOCTYPE } from 'doctypes/com-grandlyon-ecolyo-profileecogesture' +import ProfileEcogestureService from 'services/profileEcogesture.service' + +export const UPDATE_PROFILEECOGESTURE = 'UPDATE_PROFILEECOGESTURE' +export const CREATE_NEW_PROFILEECOGESTURE = 'CREATE_NEW_PROFILEECOGESTURE' + +export interface UpdateProfileEcogesture { + type: typeof UPDATE_PROFILEECOGESTURE + payload?: ProfileEcogesture +} + +export interface CreateNewProfileEcogesture { + type: typeof CREATE_NEW_PROFILEECOGESTURE + payload?: ProfileEcogesture +} + +export type ProfileEcogestureActionTypes = + | UpdateProfileEcogesture + | CreateNewProfileEcogesture + +export function updateProfileEcogestureSuccess( + updatedProfileEcogesture: ProfileEcogesture +): UpdateProfileEcogesture { + return { + type: UPDATE_PROFILEECOGESTURE, + payload: updatedProfileEcogesture, + } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function updateProfileEcogesture(upd: Partial<ProfileEcogesture>): any { + return async ( + dispatch: Dispatch<UpdateProfileEcogesture>, + getState: () => AppStore, + { client }: { client: Client } + ) => { + const profileEcogestureService = new ProfileEcogestureService(client) + const updatedProfileEcogesture = await profileEcogestureService.updateProfileEcogesture( + upd + ) + if (updatedProfileEcogesture) { + dispatch(updateProfileEcogestureSuccess(updatedProfileEcogesture)) + } + } +} + +export function newProfileEcogestureEntry( + upd: Partial<ProfileEcogesture> + // eslint-disable-next-line @typescript-eslint/no-explicit-any +): any { + return async ( + dispatch: Dispatch<UpdateProfileEcogesture>, + getState: () => AppStore, + { client }: { client: Client } + ) => { + console.log('client', client) + const { data: newProfileEcogesture } = await client.create( + PROFILEECOGESTURE_DOCTYPE, + upd + ) + if (newProfileEcogesture) { + dispatch(updateProfileEcogestureSuccess(newProfileEcogesture)) + } + } +} diff --git a/src/store/profileEcogesture/profileEcogesture.reducer.spec.ts b/src/store/profileEcogesture/profileEcogesture.reducer.spec.ts new file mode 100644 index 000000000..71662a591 --- /dev/null +++ b/src/store/profileEcogesture/profileEcogesture.reducer.spec.ts @@ -0,0 +1,31 @@ +import { profileEcogestureReducer } from './profileEcogesture.reducer' +import { UPDATE_PROFILEECOGESTURE } from './profileEcogesture.actions' +import { + mockProfileEcogesture, + mockProfileEcogestureUpdated, +} from '../../../tests/__mocks__/profileEcogesture.mock' + +describe('profileEcogesture reducer', () => { + it('should return the initial state', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const result = profileEcogestureReducer(undefined as any, { + type: 'default', + }) + expect(result).toEqual(mockProfileEcogesture) + }) + + it('should handle UPDATE_PROFILEECOGESTURE with payload', () => { + const result = profileEcogestureReducer(mockProfileEcogesture, { + type: UPDATE_PROFILEECOGESTURE, + payload: mockProfileEcogestureUpdated, + }) + expect(result).toEqual(mockProfileEcogestureUpdated) + }) + + it('should handle UPDATE_PROFILEECOGESTURE without payload', () => { + const result = profileEcogestureReducer(mockProfileEcogesture, { + type: UPDATE_PROFILEECOGESTURE, + }) + expect(result).toEqual(mockProfileEcogesture) + }) +}) diff --git a/src/store/profileEcogesture/profileEcogesture.reducer.ts b/src/store/profileEcogesture/profileEcogesture.reducer.ts new file mode 100644 index 000000000..40646dc63 --- /dev/null +++ b/src/store/profileEcogesture/profileEcogesture.reducer.ts @@ -0,0 +1,31 @@ +import { Reducer } from 'redux' +import { IndividualOrCollective, WarmingType } from 'enum/profileType.enum' +import { ProfileEcogesture } from 'models/profileEcogesture.model' +import { + CREATE_NEW_PROFILEECOGESTURE, + ProfileEcogestureActionTypes, + UPDATE_PROFILEECOGESTURE, +} from './profileEcogesture.actions' + +const initialState: ProfileEcogesture = { + heating: IndividualOrCollective.INDIVIDUAL, + warmingFluid: WarmingType.ELECTRICITY, + hotWater: IndividualOrCollective.INDIVIDUAL, + equipments: [], +} + +export const profileEcogestureReducer: Reducer<ProfileEcogesture> = ( + state = initialState, + action: ProfileEcogestureActionTypes +): ProfileEcogesture => { + switch (action.type) { + case UPDATE_PROFILEECOGESTURE: + case CREATE_NEW_PROFILEECOGESTURE: + return { + ...state, + ...action.payload, + } + default: + return state + } +} diff --git a/src/utils/hash.spec.ts b/src/utils/hash.spec.ts index 123acfaa7..e9ec0c11d 100644 --- a/src/utils/hash.spec.ts +++ b/src/utils/hash.spec.ts @@ -5,7 +5,7 @@ describe('hash utilis test', () => { describe('hashFile test', () => { it('should return the correct hash of the file', () => { const result = hashFile(ecogesturesData) - expect(result).toBe('18e0ab48244aa3aad6ff70ffb972ac76fda315f4') + expect(result).toBe('7d8b9916cb68f61dd4cd283585e790cf756e1b6d') }) }) }) diff --git a/tests/__mocks__/ecogesturesData.mock.ts b/tests/__mocks__/ecogesturesData.mock.ts index dd9605dd5..97f36951d 100644 --- a/tests/__mocks__/ecogesturesData.mock.ts +++ b/tests/__mocks__/ecogesturesData.mock.ts @@ -591,3 +591,60 @@ export const ecogesturesColdWaterData: Ecogesture[] = [ _type: 'com.grandlyon.ecolyo.ecogesture', }, ] + +export const BoilerEcogesture: Ecogesture[] = [ + { + fluidTypes: [FluidType.ELECTRICITY, FluidType.WATER], + id: '0046', + longDescription: + "Pourquoi continuer à chauffer de l’eau lorsqu’on n’est pas là pour l’utiliser ? Si vous possédez un chauffe-eau à accumulation et que vous partez plusieurs jours, il peut être utile de le couper car il continuera de consommer pour maintenir l’eau à température. Attention cependant à la douche froide du retour, n'oubliez de le remettre en marche en rentrant !", + longName: 'Je coupe mon chauffe-eau dès que je pars plus de 4 jours.', + shortName: 'Déesse du feu', + usage: Usage.ALL, + impactLevel: 6, + efficiency: 3, + difficulty: 2, + room: [Room.ALL], + season: Season.WINTER, + equipment: true, + equipmentType: [EquipmentType.BOILER], + equipmentInstallation: true, + investment: null, + action: false, + actionName: null, + actionDuration: 3, + doing: false, + objective: false, + _id: '001', + _rev: '1-67f1ea36efdd892c96bf64a8943154cd', + _type: 'com.grandlyon.ecolyo.ecogesture', + }, +] +export const BoilerEcogestureFalse: Ecogesture[] = [ + { + fluidTypes: [FluidType.ELECTRICITY, FluidType.WATER], + id: '0046', + longDescription: + "Pourquoi continuer à chauffer de l’eau lorsqu’on n’est pas là pour l’utiliser ? Si vous possédez un chauffe-eau à accumulation et que vous partez plusieurs jours, il peut être utile de le couper car il continuera de consommer pour maintenir l’eau à température. Attention cependant à la douche froide du retour, n'oubliez de le remettre en marche en rentrant !", + longName: 'Je coupe mon chauffe-eau dès que je pars plus de 4 jours.', + shortName: 'Déesse du feu', + usage: Usage.ALL, + impactLevel: 6, + efficiency: 3, + difficulty: 2, + room: [Room.ALL], + season: Season.WINTER, + equipment: false, + equipmentType: [EquipmentType.BOILER], + equipmentInstallation: true, + investment: null, + action: false, + actionName: null, + actionDuration: 3, + doing: false, + objective: false, + _id: '001', + _rev: '1-67f1ea36efdd892c96bf64a8943154cd', + _type: 'com.grandlyon.ecolyo.ecogesture', + }, +] diff --git a/tests/__mocks__/profile.mock.ts b/tests/__mocks__/profile.mock.ts index 1b8a7b902..aaee9099c 100644 --- a/tests/__mocks__/profile.mock.ts +++ b/tests/__mocks__/profile.mock.ts @@ -30,4 +30,5 @@ export const profileData: Profile = { isWelcomeSeen: false, }, haveSeenEcogestureModal: false, + isProfileEcogestureCompleted: false, } diff --git a/tests/__mocks__/profileEcogesture.mock.ts b/tests/__mocks__/profileEcogesture.mock.ts new file mode 100644 index 000000000..5489fead6 --- /dev/null +++ b/tests/__mocks__/profileEcogesture.mock.ts @@ -0,0 +1,29 @@ +import { EquipmentType } from 'enum/ecogesture.enum' +import { ProfileEcogestureAnswerType } from 'enum/ecogestureForm.enum' +import { IndividualOrCollective, WarmingType } from 'enum/profileType.enum' +import { + ProfileEcogesture, + ProfileEcogestureAnswer, +} from 'models/profileEcogesture.model' + +export const mockProfileEcogesture: ProfileEcogesture = { + heating: IndividualOrCollective.INDIVIDUAL, + warmingFluid: WarmingType.ELECTRICITY, + hotWater: IndividualOrCollective.INDIVIDUAL, + equipments: [], +} +export const mockProfileEcogestureUpdated: ProfileEcogesture = { + heating: IndividualOrCollective.INDIVIDUAL, + warmingFluid: WarmingType.ELECTRICITY, + hotWater: IndividualOrCollective.INDIVIDUAL, + equipments: [EquipmentType.BOILER, EquipmentType.INTERNET_BOX], +} + +export const mockEcogestureAnswer: ProfileEcogestureAnswer = { + type: ProfileEcogestureAnswerType.SINGLE_CHOICE, + attribute: 'heating', + choices: [ + IndividualOrCollective.INDIVIDUAL, + IndividualOrCollective.COLLECTIVE, + ], +} diff --git a/tests/__mocks__/store.ts b/tests/__mocks__/store.ts index 7e59847f8..385277205 100644 --- a/tests/__mocks__/store.ts +++ b/tests/__mocks__/store.ts @@ -25,7 +25,7 @@ import configureStore from 'redux-mock-store' import thunkMiddleware from 'redux-thunk' import { EcolyoState } from 'store' import mockClient from './client' - +import { mockProfileEcogesture } from './profileEcogesture.mock' export const mockInitialGlobalState: GlobalState = { screenType: ScreenType.MOBILE, challengeExplorationNotification: false, @@ -117,6 +117,7 @@ export const mockInitialProfileState: Profile = { sendConsumptionAlert: false, waterDailyConsumptionLimit: 0, sendAnalysisNotification: true, + isProfileEcogestureCompleted: false, mailToken: '', monthlyAnalysisDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), isProfileTypeCompleted: false, @@ -176,6 +177,7 @@ export const mockInitialEcolyoState = { global: mockInitialGlobalState, profile: mockInitialProfileState, profileType: mockInitialProfileTypeState, + profileEcogesture: mockProfileEcogesture, chart: mockInitialChartState, modal: mockInitialModalState, challenge: mockInitialChallengeState, -- GitLab