+
+ Crie sua petconta
+
+
+
+
+
+
+
+
+
+
+`;
+
+export default function SignUp() {
+ Component.call(this, { html, events });
+
+ const $nameInputContainer = this.selected.get('name-input');
+ const $lastNameInputContainer = this.selected.get('last-name-input');
+ const $birthDateInputContainer = this.selected.get('birth-date-input');
+ const $localInputContainer = this.selected.get('local-input');
+ const $emailInputContainer = this.selected.get('email-input');
+ const $phoneInputContainer = this.selected.get('phone-input');
+ const $passwordInputContainer = this.selected.get('password-input');
+ const $confirmPasswordInputContainer = this.selected.get(
+ 'confirm-password-input',
+ );
+ const $submitButton = this.selected.get('submit-button');
+ const $emailErrorMessage = this.selected.get('email-input-error');
+ const $passwordErrorMessage = this.selected.get('password-input-error');
+ const $confirmPasswordErrorMessage = this.selected.get(
+ 'confirm-password-input-error',
+ );
+
+ const nameInput = new TextInput({
+ placeholder: 'Devhat',
+ });
+ const lastNameInput = new TextInput({
+ placeholder: 'Devhat',
+ });
+ const birthDateInput = new TextInput({
+ placeholder: '13/12/1995',
+ type: 'date',
+ });
+ const localInput = new TextInput({
+ placeholder: 'São Paulo, SP',
+ });
+ const emailInput = new TextInput({
+ placeholder: 'dev@devhat.com.br',
+ type: 'email',
+ });
+ const phoneInput = new TextInput({
+ placeholder: '(11) 92875-3356',
+ });
+ const passwordInput = new TextInput({
+ placeholder: 'Senha',
+ assetPosition: 'suffix',
+ type: 'password',
+ });
+ const confirmPasswordInput = new TextInput({
+ placeholder: 'Confirmar senha',
+ assetPosition: 'suffix',
+ type: 'password',
+ });
+ const submitButton = new Button({
+ text: 'Cadastrar',
+ isFullWidth: true,
+ isDisabled: true,
+ });
+
+ nameInput.mount($nameInputContainer);
+ lastNameInput.mount($lastNameInputContainer);
+ birthDateInput.mount($birthDateInputContainer);
+ localInput.mount($localInputContainer);
+ emailInput.mount($emailInputContainer);
+ phoneInput.mount($phoneInputContainer);
+ passwordInput.mount($passwordInputContainer);
+ confirmPasswordInput.mount($confirmPasswordInputContainer);
+ submitButton.mount($submitButton);
+
+ const validateFields = () => {
+ const name = nameInput.getValue().trim();
+ const lastName = lastNameInput.getValue().trim();
+ const birthDate = birthDateInput.getValue().trim();
+ const local = localInput.getValue().trim();
+ const email = emailInput.getValue().trim();
+ const phone = phoneInput.getValue().trim();
+ const password = passwordInput.getValue().trim();
+ const confirmPassword = confirmPasswordInput.getValue().trim();
+
+ const allFieldsFilled =
+ name &&
+ lastName &&
+ birthDate &&
+ local &&
+ email &&
+ phone &&
+ password &&
+ confirmPassword;
+
+ if (allFieldsFilled) {
+ submitButton.enable();
+ } else {
+ submitButton.disable();
+ }
+ };
+
+ nameInput.selected
+ .get('input-text')
+ .addEventListener('input', validateFields);
+ lastNameInput.selected
+ .get('input-text')
+ .addEventListener('input', validateFields);
+ birthDateInput.selected
+ .get('input-text')
+ .addEventListener('input', validateFields);
+ localInput.selected
+ .get('input-text')
+ .addEventListener('input', validateFields);
+ emailInput.selected
+ .get('input-text')
+ .addEventListener('input', validateFields);
+ phoneInput.selected
+ .get('input-text')
+ .addEventListener('input', validateFields);
+ passwordInput.selected
+ .get('input-text')
+ .addEventListener('input', validateFields);
+ confirmPasswordInput.selected
+ .get('input-text')
+ .addEventListener('input', validateFields);
+
+ submitButton.listen('click', () => {
+ const email = emailInput.getValue();
+ const password = passwordInput.getValue();
+ const confirmPassword = confirmPasswordInput.getValue();
+ let validEmail = true;
+ let validPassword = true;
+ let validConfirmPassword = true;
+
+ if (!this.validateEmail(email)) {
+ validEmail = false;
+ $emailErrorMessage.classList.add('signUp-page__form-input--show-error');
+ $emailErrorMessage.innerText = 'E-mail inválido';
+ emailInput.inputError();
+ }
+
+ if (!this.validatePassword(password)) {
+ validPassword = false;
+ $passwordErrorMessage.classList.add(
+ 'signUp-page__form-input--show-error',
+ );
+ $passwordErrorMessage.innerText =
+ 'Senha inválida. Sua senha deve conter no mínimo 10 caracteres, incluindo pelo menos um caractere especial e uma letra maiúscula.';
+ passwordInput.inputError();
+ }
+
+ if (!this.validateConfirmPassword(password, confirmPassword)) {
+ validConfirmPassword = false;
+ $confirmPasswordErrorMessage.classList.add(
+ 'signUp-page__form-input--show-error',
+ );
+ $confirmPasswordErrorMessage.innerText = 'As senhas não coincidem.';
+ confirmPasswordInput.inputError();
+ }
+
+ if (validEmail)
+ $emailErrorMessage.classList.remove(
+ 'signUp-page__form-input--show-error',
+ );
+ if (validPassword)
+ $passwordErrorMessage.classList.remove(
+ 'signUp-page__form-input--show-error',
+ );
+
+ if (validConfirmPassword)
+ $confirmPasswordErrorMessage.classList.remove(
+ 'signUp-page__form-input--show-error',
+ );
+
+ if (validEmail && validPassword && validConfirmPassword) {
+ this.signUp();
+ }
+ });
+}
+
+SignUp.prototype = Object.assign(SignUp.prototype, Component.prototype, {
+ signUp() {
+ this.emit('signUp');
+ },
+ validateEmail(email) {
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
+
+ return emailRegex.test(email);
+ },
+ 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;
+ },
+
+ validateConfirmPassword(password, confirmpassword) {
+ return password === confirmpassword;
+ },
+});
diff --git a/src/layouts/app/pages/SignUp/index.scss b/src/layouts/app/pages/SignUp/index.scss
new file mode 100644
index 00000000..b732956c
--- /dev/null
+++ b/src/layouts/app/pages/SignUp/index.scss
@@ -0,0 +1,151 @@
+@use '~styles/colors.scss' as colors;
+@use '~styles/fonts.scss' as fonts;
+@use '~styles/breakpoints.scss' as breakpoints;
+
+.signup-page {
+ &__title {
+ font-family: fonts.$primaryFont;
+ color: colors.$gray800;
+ font-size: fonts.$xl2;
+ font-weight: 700;
+ line-height: 1.6;
+
+ margin-bottom: 3.2rem;
+ }
+
+ &__provider {
+ max-width: 45rem;
+
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 1.6rem;
+
+ margin-bottom: 3.2rem;
+ }
+
+ &__provider-button {
+ width: 100%;
+
+ display: flex;
+ gap: 1.6rem;
+
+ align-items: center;
+ justify-content: center;
+
+ font-family: fonts.$fifthFont;
+
+ font-size: 1.6rem;
+ font-weight: fonts.$medium;
+
+ padding: 1.6rem;
+
+ border: unset;
+
+ background-color: colors.$secondary100;
+ box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.084);
+ border-radius: 1.4rem;
+
+ transition: 0.3s ease-in-out;
+
+ cursor: pointer;
+
+ &:hover:not(:disabled) {
+ background-color: colors.$gray200;
+ }
+ }
+
+ &__provider-icon {
+ max-width: 2.4rem;
+ }
+
+ &__separator {
+ max-width: 45rem;
+
+ display: flex;
+
+ margin-bottom: 2.4rem;
+ }
+
+ &__divisor {
+ width: 100%;
+
+ border: unset;
+ border-top: 0.1rem solid colors.$gray200;
+ }
+
+ &__separator-text {
+ font-family: fonts.$fifthFont;
+
+ margin: 0 2.8rem;
+ }
+
+ &__form {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 2.8rem;
+ }
+
+ &__form-input {
+ position: relative;
+
+ &--error {
+ display: none;
+
+ font-family: fonts.$fifthFont;
+ color: colors.$error100;
+ font-size: 1.4rem;
+
+ margin-top: 0.8rem;
+ }
+
+ &--show-error {
+ display: block;
+ }
+
+ :has(&--error) .input-text-container,
+ :has(&--error) .input-text-container__input.standard.input-error {
+ background-color: transparent !important;
+ }
+
+ .input-text-container__input {
+ font-family: fonts.$fifthFont;
+ }
+ }
+
+ &__form-label {
+ width: max-content;
+
+ font-family: fonts.$primaryFont;
+ font-size: 1.4rem;
+
+ padding: 0 0.8rem;
+
+ position: absolute;
+ bottom: 4.8rem;
+ left: 3rem;
+ z-index: 1;
+
+ background-color: colors.$shade50;
+ }
+
+ &__submit-button {
+ max-width: 45rem;
+ }
+}
+
+@include breakpoints.from667 {
+ .signup-page {
+ &__provider {
+ grid-template-columns: 1fr 1fr;
+ }
+
+ &__form {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ }
+
+ &__submit-button {
+ grid-column: span 2;
+ }
+ }
+}
diff --git a/src/stories/SignUpPage.stories.js b/src/stories/SignUpPage.stories.js
new file mode 100644
index 00000000..0e3d5547
--- /dev/null
+++ b/src/stories/SignUpPage.stories.js
@@ -0,0 +1,15 @@
+import SignUp from '../layouts/app/pages/SignUp';
+
+export default {
+ title: 'Pages/SignUp',
+ render: () => {
+ const signUp = new SignUp();
+ const $container = document.createElement('div');
+
+ signUp.mount($container);
+
+ return $container;
+ },
+};
+
+export const SignUpPageStory = {};