diff --git a/src/components/ChangePassword/images/eye-slash.svg b/src/components/ChangePassword/images/eye-slash.svg new file mode 100644 index 00000000..59ae217f --- /dev/null +++ b/src/components/ChangePassword/images/eye-slash.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/components/ChangePassword/index.js b/src/components/ChangePassword/index.js new file mode 100644 index 00000000..782191a3 --- /dev/null +++ b/src/components/ChangePassword/index.js @@ -0,0 +1,160 @@ +import { Component } from 'pet-dex-utilities'; +import TextInput from '../TextInput'; +import Button from '../Button'; +import './index.scss'; + +const events = ['password:change']; + +const html = ` +
+

+ Senha antiga +

+
+ Senha inválida + +
+ +

Nova senha

+ +
+ Senha inválida + As senhas não coincidem + +
+ Senha inválida + As senhas não coincidem + + +
+`; + +export default function ChangePassword() { + Component.call(this, { html, events }); + const $changePasswordForm = this.selected.get('change-password'); + const $passwordInputContainer = this.selected.get('password'); + const $currentPasswordErrorMessage = this.selected.get('password-error'); + const $newPasswordInputContainer = this.selected.get('new-password'); + const $newPasswordErrorMessage = this.selected.get('new-password-error'); + const $newPasswordErrorMatch = this.selected.get('new-password-error-match'); + const $confirmPasswordInputContainer = this.selected.get('confirm-password'); + const $confirmPasswordErrorMessage = this.selected.get( + 'confirm-password-error', + ); + const $confirmPasswordErrorMatch = this.selected.get( + 'confirm-password-error-match', + ); + + const currentPasswordInput = new TextInput({ + placeholder: 'Senha', + assetPosition: 'suffix', + type: 'password', + }); + const newPasswordInput = new TextInput({ + placeholder: 'Nova senha', + assetPosition: 'suffix', + type: 'password', + }); + const confirmPasswordInput = new TextInput({ + placeholder: ' Confirmar senha', + assetPosition: 'suffix', + type: 'password', + }); + const submitButton = new Button({ + text: 'Salvar', + isFullWidth: true, + isDisabled: true, + }); + + currentPasswordInput.mount($passwordInputContainer); + newPasswordInput.mount($newPasswordInputContainer); + confirmPasswordInput.mount($confirmPasswordInputContainer); + submitButton.mount($changePasswordForm); + + const validatePassword = (password) => { + const hasMinLength = password.length >= 10; + const hasUppercase = /[A-Z]/g.test(password); + const hasNumber = /[0-9]/g.test(password); + const hasSpecialCharacter = /[!@#$%^&*(),.?":{}|<>]/g.test(password); + + return hasMinLength && hasUppercase && hasNumber && hasSpecialCharacter; + }; + + const validateSubmit = () => { + if ( + currentPasswordInput.getValue() && + newPasswordInput.getValue() && + confirmPasswordInput.getValue() + ) { + submitButton.enable(); + } else { + submitButton.disable(); + } + }; + + currentPasswordInput.selected + .get('input-text') + .addEventListener('input', () => { + $currentPasswordErrorMessage.classList.remove(); + validateSubmit(); + }); + newPasswordInput.selected + .get('input-text') + .addEventListener('input', validateSubmit); + confirmPasswordInput.selected + .get('input-text') + .addEventListener('input', validateSubmit); + + submitButton.listen('click', () => { + let validPasswords = true; + const newPassword = newPasswordInput.selected.get('input-text').value; + const confirmPassword = + confirmPasswordInput.selected.get('input-text').value; + + const showErrorMessage = (field, error) => { + const fieldValue = field.selected.get('input-text').value; + if (!validatePassword(fieldValue)) { + validPasswords = false; + error.classList.add('show-error'); + field.inputError(); + } + }; + + const removeErrors = (error) => { + error.classList.remove('show-error'); + }; + + showErrorMessage(currentPasswordInput, $currentPasswordErrorMessage); + showErrorMessage(newPasswordInput, $newPasswordErrorMessage); + showErrorMessage(confirmPasswordInput, $confirmPasswordErrorMessage); + + if (confirmPassword !== newPassword) { + validPasswords = false; + $newPasswordErrorMatch.classList.add('show-error'); + $confirmPasswordErrorMatch.classList.add('show-error'); + newPasswordInput.inputError(); + confirmPasswordInput.inputError(); + } + + if (validPasswords) { + removeErrors($currentPasswordErrorMessage); + removeErrors($newPasswordErrorMessage); + removeErrors($confirmPasswordErrorMessage); + removeErrors($newPasswordErrorMatch); + removeErrors($confirmPasswordErrorMatch); + this.emit('password:change'); + } + }); +} +ChangePassword.prototype = Object.assign( + ChangePassword.prototype, + Component.prototype, +); diff --git a/src/components/ChangePassword/index.scss b/src/components/ChangePassword/index.scss new file mode 100644 index 00000000..b4b2051d --- /dev/null +++ b/src/components/ChangePassword/index.scss @@ -0,0 +1,47 @@ +@use '~styles/colors.scss' as colors; +@use '~styles/fonts.scss' as fonts; +@use '~styles/breakpoints.scss' as breakpoints; + +.change-password { + display: flex; + flex-direction: column; + gap: 2rem; + + font-family: fonts.$primaryFont; + line-height: fonts.$headerLineHeight; + + background-color: colors.$secondary100; + + &__title { + color: colors.$gray600; + font-size: 1.8rem; + font-weight: fonts.$headerFontWeight; + } + + &__error { + display: none; + + color: colors.$error100; + + &.show-error { + display: block; + } + } + + &__password-tips { + color: colors.$gray500; + font-weight: fonts.$footerFontWeight; + + list-style-type: disc; + padding-inline-start: 2rem; + } + + &__separator { + width: 100%; + + display: flex; + + border: 0; + border-top: 0.1rem solid colors.$gray200; + } +} diff --git a/src/components/ChangePassword/index.spec.js b/src/components/ChangePassword/index.spec.js new file mode 100644 index 00000000..e69de29b diff --git a/src/stories/ChangePassword.stories.js b/src/stories/ChangePassword.stories.js new file mode 100644 index 00000000..97b4658c --- /dev/null +++ b/src/stories/ChangePassword.stories.js @@ -0,0 +1,41 @@ +import Drawer from '../components/Drawer'; +import ChangePassword from '../components/ChangePassword'; +import Button from '../components/Button'; +import { initializeSwiper } from '../utils/swiper'; + +export default { + title: 'Components/ChangePassword', + parameters: { + backgrounds: { + default: 'petdex', + values: [ + { + name: 'default', + value: '#F8F8F8', + }, + { + name: 'petdex', + value: '#003459', + }, + ], + }, + }, + render: () => { + initializeSwiper(); + const button = new Button({ + text: 'open', + }); + const changePassword = new ChangePassword(); + const $container = document.createElement('div'); + const drawer = new Drawer({ + title: 'Alterar senha', + content: changePassword, + }); + button.listen('click', () => drawer.open()); + button.mount($container); + + return $container; + }, +}; + +export const Default = {}; diff --git a/src/stories/PetRegister.stories.js b/src/stories/PetRegister.stories.js index 17073c6b..e8fc7f9a 100644 --- a/src/stories/PetRegister.stories.js +++ b/src/stories/PetRegister.stories.js @@ -1,4 +1,4 @@ -import PetRegister from '../home/components/PetRegister'; +import PetRegister from '../layouts/app/pages/PetRegister/index'; export default { title: 'Pages/PetProfile', diff --git a/src/stories/PetRegisterPage.stories.js b/src/stories/PetRegisterPage.stories.js index fe82bb33..5f9129dc 100644 --- a/src/stories/PetRegisterPage.stories.js +++ b/src/stories/PetRegisterPage.stories.js @@ -1,4 +1,4 @@ -import PetRegisterPage from '../pages/layouts/PetRegisterPage'; +import PetRegisterPage from '../layouts/app'; import afghanHound from './assets/petRegisterPage/afghanHound.svg'; import akita from './assets/petRegisterPage/akita.svg'; diff --git a/src/stories/PetVetPage.stories.js b/src/stories/PetVetPage.stories.js index b90912eb..0bbb3edb 100644 --- a/src/stories/PetVetPage.stories.js +++ b/src/stories/PetVetPage.stories.js @@ -1,4 +1,4 @@ -import PetVetPage from '../home/components/PetVetPage'; +import PetVetPage from '../components/Vaccine/index'; export default { title: 'Pages/PetVetPage', diff --git a/src/stories/PetWeightPage.stories.js b/src/stories/PetWeightPage.stories.js index 77c0487a..7f27364f 100644 --- a/src/stories/PetWeightPage.stories.js +++ b/src/stories/PetWeightPage.stories.js @@ -1,4 +1,4 @@ -import PetWeightPage from '../pages/layouts/PetWeightPage'; +import PetWeightPage from '../layouts/app/pages/PetWeight'; export default { title: 'Pages/PetWeightPage',