From eff3c785f506555c0cd816162dc2e779db52ebfa Mon Sep 17 00:00:00 2001 From: nayoonju Date: Mon, 17 Jun 2024 02:56:42 +0900 Subject: [PATCH 1/8] =?UTF-8?q?fix:=20markup=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- login.html | 8 +------- signup.html | 10 ++-------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/login.html b/login.html index 7b54b6714..99c64e751 100644 --- a/login.html +++ b/login.html @@ -10,7 +10,6 @@ -

판다마켓

@@ -26,26 +25,21 @@

판다마켓

- - + -

간편 로그인하기

-
판다마켓이 처음이신가요? 회원가입
- diff --git a/signup.html b/signup.html index 572067101..656a6f7d3 100644 --- a/signup.html +++ b/signup.html @@ -34,31 +34,25 @@

판다마켓

-
- -

간편 로그인하기

-
이미 회원이신가요? 로그인
- - - \ No newline at end of file From 4bbdddfbf2378337caf8029bd66377956f9a895f Mon Sep 17 00:00:00 2001 From: nayoonju Date: Mon, 17 Jun 2024 02:57:20 +0900 Subject: [PATCH 2/8] =?UTF-8?q?fix:=20is-valid=20->=20is-error=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/css/style.css | 6 +++--- assets/scss/_form.scss | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/css/style.css b/assets/css/style.css index a9d18b733..6adc70c82 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -407,10 +407,10 @@ footer { padding: 1em 1.5em; height: 56px; } -.input-group.is-valid .error-border, .input-group.is-valid .error-border:focus { +.input-group.is-error .error-border, .input-group.is-error .error-border:focus { outline: 2px solid var(--error); } -.input-group.is-valid.valid .error-message { +.input-group.is-error.valid .error-message { display: none; } @media (max-width: 767px) { @@ -455,7 +455,7 @@ footer { color: var(--error); } -.is-valid .error-message { +.is-error .error-message { display: block; } diff --git a/assets/scss/_form.scss b/assets/scss/_form.scss index 6ef4076e7..cb1b861f9 100644 --- a/assets/scss/_form.scss +++ b/assets/scss/_form.scss @@ -59,12 +59,12 @@ } - &.is-valid .error-border, - &.is-valid .error-border:focus { + &.is-error .error-border, + &.is-error .error-border:focus { outline: 2px solid var(--error); } - &.is-valid.valid .error-message { + &.is-error.valid .error-message { display: none; } @@ -109,7 +109,7 @@ color: var(--error); } -.is-valid .error-message { +.is-error .error-message { display: block; } From cfd7b1f7b341001292393bcd9fadf43b3dc4c38f Mon Sep 17 00:00:00 2001 From: nayoonju Date: Mon, 17 Jun 2024 02:58:12 +0900 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EA=B4=80=EB=A0=A8=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85,=ED=95=A8=EC=88=98=EB=AA=85,=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=EA=B0=92=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/js/form-validation.js | 175 ++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 87 deletions(-) diff --git a/assets/js/form-validation.js b/assets/js/form-validation.js index 9536686cd..db1336bbb 100644 --- a/assets/js/form-validation.js +++ b/assets/js/form-validation.js @@ -1,137 +1,138 @@ -export let form = document.querySelector('.form'); -export let email = document.querySelector('#email'); -export let password = document.querySelector('#password'); -export let confirmPassword = document.querySelector('#confirmPassword'); -export let nickName = document.querySelector('#nickname'); -export let submitBtn = document.querySelector('#submitBtn'); - +export const form = document.querySelector('.form'); +export const inputList = form.querySelectorAll("input"); +export const submitBtn = document.querySelector('#submitBtn'); +export const VALIDATE_LIST = Object.freeze({ + EMAIL: 'val-email', + NICKNAME: 'val-nickname', + PASSWORD: 'val-password', + CONFIRM_PASSWORD: 'val-confirm-password', +}) +// 유효값에 대한 정의 export const validate = { errorPlacement: function (e, message) { - let errorDiv = e.nextElementSibling; - if (errorDiv && errorDiv.classList.contains('error-message')) { - errorDiv.innerHTML = message; - } else { + const inputFormDiv = e.parentNode; + let errorDiv = inputFormDiv.querySelector('.error-message'); + if (!errorDiv) { errorDiv = document.createElement('div'); errorDiv.classList.add('error-message'); - errorDiv.innerHTML = message; - e.parentNode.insertBefore(errorDiv, e.nextSibling); } + errorDiv.innerHTML = message; + inputFormDiv.appendChild(errorDiv); + }, showError: function (e, message) { - e.parentNode.classList.remove('valid') + const inputFormDiv = e.parentNode; + inputFormDiv.classList.remove('valid'); e.classList.add('error-border'); e.dataset.valid = 'false'; this.errorPlacement(e, message); }, success: function (e) { + const inputFormDiv = e.parentNode; + let errorDiv = inputFormDiv.querySelector('.error-message'); e.classList.remove('error-border'); - e.parentNode.classList.add('valid'); - e.dataset.valid = 'true'; - let errorDiv = e.nextElementSibling; - if (errorDiv && errorDiv.classList.contains('error-message')) { - errorDiv.innerHTML = ''; + if (errorDiv) { + errorDiv.remove(); } + inputFormDiv.classList.add('valid'); + e.dataset.valid = 'true'; }, messages: { - 'val-email': { + [VALIDATE_LIST.EMAIL]: { required: '이메일을 입력해주세요.', - minlength: '잘못된 이메일 형식입니다.', + pattern: '잘못된 이메일형식입니다.', }, - 'val-nickname': '닉네임을 입력해주세요.', - 'val-password': { + [VALIDATE_LIST.NICKNAME]: '닉네임을 입력해주세요.', + [VALIDATE_LIST.PASSWORD]: { required: '비밀번호를 입력해주세요.', minlength: '비밀번호를 8자 이상 입력해주세요.', }, - 'val-confirm-password': { + [VALIDATE_LIST.CONFIRM_PASSWORD]: { required: '비밀번호를 입력해주세요.', minlength: '비밀번호를 8자 이상 입력해주세요.', equalTo: '비밀번호가 일치하지 않습니다.', } }, rules: { - 'val-email': { + [VALIDATE_LIST.EMAIL]: { required: true, - email: /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/, + pattern: /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/, }, - 'val-nickname': { + [VALIDATE_LIST.NICKNAME]: { required: true, }, - 'val-password': { + [VALIDATE_LIST.PASSWORD]: { required: true, minlength: 8, }, - 'val-confirm-password': { + [VALIDATE_LIST.CONFIRM_PASSWORD]: { required: true, minlength: 8, equalTo: '#password', } - }, -} - -export function validateEmail() { - let value = email.value.trim(); - let rules = validate.rules['val-email']; - if (rules.required && !value) { - validate.showError(email, validate.messages['val-email'].required); - return false; - } - if (value && !rules.email.test(value)) { - validate.showError(email, validate.messages['val-email'].minlength); - return false; } - validate.success(email); - return true; } -export function validateNickname() { - let value = nickName.value.trim(); - let rules = validate.rules['val-nickname']; - if (rules && !value) { - validate.showError(nickName, validate.messages['val-nickname']); - return false; - } - validate.success(nickName); - return true; -} +// input 유효값 check +export function checkInputs(input) { + const inputType = input.name; + const inputValName = `val-${inputType}`; + const value = input.value.trim(); + const rules = validate.rules[inputValName]; + const message = validate.messages[inputValName]; -export function validatePassword() { - let value = password.value.trim(); - let rules = validate.rules['val-password']; - if (rules.required && !value) { - validate.showError(password, validate.messages['val-password'].required); - return false; - } - if (value && value.length < rules.minlength) { - validate.showError(password, validate.messages['val-password'].minlength); - return false; - } - validate.success(password); - return true; -} + // Specific validation checks + if (inputType === 'email') { + if (rules.required && !value) { + validate.showError(input, message.required); + return false; + } + if (value && !rules.pattern.test(value)) { + validate.showError(input, message.pattern); + return false; + } + validate.success(input); + return true; + } else if (inputType === 'nickname') { + if (rules && !value) { + validate.showError(input, message); + return false; + } + validate.success(input); + return true; + } else if (inputType === 'password') { + if (rules.required && !value) { + validate.showError(input, message.required); + return false; + } + if (value && value.length < rules.minlength) { + validate.showError(input, message.minlength); + return false; + } + validate.success(input); -export function validateConfirmPassword() { - let value = confirmPassword.value.trim(); - let passwordValue = password.value; - let rules = validate.rules['val-confirm-password']; - if (rules.required && !value) { - validate.showError(confirmPassword, validate.messages['val-confirm-password'].required); - return false; - } - if (value && value.length < rules.minlength) { - validate.showError(confirmPassword, validate.messages['val-confirm-password'].minlength); - return false; - } - if (value && value !== passwordValue) { - validate.showError(confirmPassword, validate.messages['val-confirm-password'].equalTo); - return false; + } else if (inputType === 'confirm-password') { + if (rules.required && !value) { + validate.showError(input, message.required); + return false; + } + if (value && value.length < rules.minlength) { + validate.showError(input, message.minlength); + return false; + } + if (value && value !== document.querySelector('#password').value) { + validate.showError(input, message.equalTo); + return false; + } + validate.success(input); + return true; } - validate.success(confirmPassword); - return true; } - -export function checkFormValidity() { +// form 전체에 대한 검증 +export function checkAllInput() { let formSubmitDone = [...form.querySelectorAll('input')].every(input => input.dataset.valid === 'true'); submitBtn.disabled = !formSubmitDone; + return formSubmitDone; } From 1c2981242d23013634a60d67dc582c7378c481df Mon Sep 17 00:00:00 2001 From: nayoonju Date: Mon, 17 Jun 2024 03:01:53 +0900 Subject: [PATCH 4/8] =?UTF-8?q?fix:=20=ED=86=A0=EA=B8=80=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/js/password-toggle.js | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/assets/js/password-toggle.js b/assets/js/password-toggle.js index 140eb27aa..e69de29bb 100644 --- a/assets/js/password-toggle.js +++ b/assets/js/password-toggle.js @@ -1,21 +0,0 @@ -export let passwordToggleBtns = document.querySelectorAll('.password-toggle-button'); - -export function passwordToggle(e) { - let button = e.currentTarget; - let passwordInput = button.parentElement.querySelector('input'); - let toggleIcon = document.createElement('i'); - toggleIcon.classList.add('icon'); - if (passwordInput.type == "password") { - passwordInput.type = "text"; - toggleIcon.classList.remove('ic_visible_on'); - toggleIcon.classList.add('ic_visible_off') - this.setAttribute("aria-label", "비밀번호 숨기기"); - } else { - passwordInput.type = "password"; - toggleIcon.classList.remove('ic_visible_off'); - toggleIcon.classList.add('ic_visible_on'); - this.setAttribute("aria-label", "비밀번호 보기"); - } - button.innerHTML = ''; - button.appendChild(toggleIcon); -} From 5136d8d2395daf7a943bd96c34e3d0df73ee7f43 Mon Sep 17 00:00:00 2001 From: nayoonju Date: Mon, 17 Jun 2024 03:03:01 +0900 Subject: [PATCH 5/8] =?UTF-8?q?fix:=20signup=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/js/signup.js | 92 +++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 57 deletions(-) diff --git a/assets/js/signup.js b/assets/js/signup.js index b0b23a9f2..9d2121f89 100644 --- a/assets/js/signup.js +++ b/assets/js/signup.js @@ -1,67 +1,25 @@ import { form, - email, - password, - confirmPassword, - nickName, - validateEmail, - validateNickname, - validatePassword, - validateConfirmPassword, - checkFormValidity, - submitBtn + inputList, + checkInputs, + checkAllInput, } from './form-validation.js'; -import { passwordToggleBtns, passwordToggle } from './password-toggle.js'; -submitBtn.disabled = true; - - -email.addEventListener('blur', function () { - this.parentNode.classList.add('is-valid'); - validateEmail(); -}); -nickName.addEventListener('blur', function () { - this.parentNode.classList.add('is-valid'); - validateNickname(); -}); -password.addEventListener('blur', function () { - this.parentNode.classList.add('is-valid'); - validatePassword(); -}); -confirmPassword.addEventListener('blur', function () { - this.parentNode.classList.add('is-valid'); - validateConfirmPassword(); -}); - -email.addEventListener('keyup', function () { - if (this.parentNode.classList.contains('is-valid')) { - } - validateEmail(); - checkFormValidity(); -}); -nickName.addEventListener('keyup', function () { - if (this.parentNode.classList.contains('is-valid')) { - } - validateNickname(); - checkFormValidity(); +inputList.forEach((input) => { + input.addEventListener('blur', function () { + this.parentNode.classList.add('is-error'); + checkInputs(input); + }); + input.addEventListener('keyup', () => { + checkInputs(input); + checkAllInput(); + }) }); -password.addEventListener('keyup', function () { - if (this.parentNode.classList.contains('is-valid')) { - } - validatePassword(); - checkFormValidity(); -}); -confirmPassword.addEventListener('keyup', function () { - if (this.parentNode.classList.contains('is-valid')) { - } - validateConfirmPassword(); - checkFormValidity(); -}); - +// form 제출 form.addEventListener('submit', function (event) { - if (validateEmail() && validatePassword() && validateConfirmPassword() && validateNickname()) { - event.preventDefault(); + event.preventDefault(); + if (checkAllInput) { alert('회원가입성공'); window.location.href = '/signup.html'; } @@ -69,6 +27,26 @@ form.addEventListener('submit', function (event) { // 패스워드 보기 +function passwordToggle(e) { + let button = e.currentTarget; + let passwordInput = button.parentElement.querySelector('input'); + let toggleIcon = document.createElement('i'); + toggleIcon.classList.add('icon'); + + const shouldShowPassword = passwordInput.type === 'password'; + passwordInput.type = shouldShowPassword ? 'text' : 'password'; + + toggleIcon.classList.toggle('ic_visible_on', !shouldShowPassword); + toggleIcon.classList.toggle('ic_visible_off', shouldShowPassword); + + const ariaLabel = shouldShowPassword ? '비밀번호 숨기기' : '비밀번호 보기'; + this.setAttribute("aria-label", ariaLabel); + + button.innerHTML = ''; + button.appendChild(toggleIcon); +} + +const passwordToggleBtns = document.querySelectorAll('.password-toggle-button'); passwordToggleBtns.forEach(btn => { btn.addEventListener('click', passwordToggle); }); \ No newline at end of file From 83d83d531c01a049b850a49b189f20e0797257ba Mon Sep 17 00:00:00 2001 From: nayoonju Date: Mon, 17 Jun 2024 03:03:09 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20login=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/js/login.js | 65 ++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/assets/js/login.js b/assets/js/login.js index 5bb59b3dd..73c6247a3 100644 --- a/assets/js/login.js +++ b/assets/js/login.js @@ -1,48 +1,51 @@ import { form, - email, - password, - validateEmail, - validatePassword, - checkFormValidity, - submitBtn + inputList, + checkInputs, + checkAllInput, } from './form-validation.js'; -import { passwordToggleBtns, passwordToggle } from './password-toggle.js'; -submitBtn.disabled = true; - -email.addEventListener('blur', function () { - this.parentNode.classList.add('is-valid'); - if (!validateEmail) { this.parentNode.classList.remove('is-valid'); } -}); -password.addEventListener('blur', function () { - this.parentNode.classList.add('is-valid'); - validatePassword(); -}); - -email.addEventListener('keyup', function () { - if (this.parentNode.classList.contains('is-valid')) { - } - validateEmail(); - checkFormValidity(); -}); -password.addEventListener('keyup', function () { - if (this.parentNode.classList.contains('is-valid')) { - } - validatePassword(); - checkFormValidity(); +inputList.forEach((input) => { + input.addEventListener('blur', function () { + this.parentNode.classList.add('is-error'); + checkInputs(input); + }); + input.addEventListener('keyup', () => { + checkInputs(input); + checkAllInput(); + }) }); +// form 제출 form.addEventListener('submit', function (event) { event.preventDefault(); - if (validateEmail() && validatePassword()) { + if (checkAllInput) { alert('로그인성공'); window.location.href = '/items.html'; } }); - // 패스워드 보기 +function passwordToggle(e) { + let button = e.currentTarget; + let passwordInput = button.parentElement.querySelector('input'); + let toggleIcon = document.createElement('i'); + toggleIcon.classList.add('icon'); + + const shouldShowPassword = passwordInput.type === 'password'; + passwordInput.type = shouldShowPassword ? 'text' : 'password'; + + toggleIcon.classList.toggle('ic_visible_on', !shouldShowPassword); + toggleIcon.classList.toggle('ic_visible_off', shouldShowPassword); + + const ariaLabel = shouldShowPassword ? '비밀번호 숨기기' : '비밀번호 보기'; + this.setAttribute("aria-label", ariaLabel); + + button.innerHTML = ''; + button.appendChild(toggleIcon); +} + +const passwordToggleBtns = document.querySelectorAll('.password-toggle-button'); passwordToggleBtns.forEach(btn => { btn.addEventListener('click', passwordToggle); }); \ No newline at end of file From 7efec9741d9d5596950ffea5b564ffc0f5b4b51a Mon Sep 17 00:00:00 2001 From: nayoonju Date: Mon, 17 Jun 2024 03:14:37 +0900 Subject: [PATCH 7/8] =?UTF-8?q?gitignore=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 496ee2ca6..5ee7cd0c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.DS_Store \ No newline at end of file +.DS_Store +assets/.DS_Store \ No newline at end of file From 758c1ad60bc50db5cc8a807e9e37e07166cf4dad Mon Sep 17 00:00:00 2001 From: nayoonju Date: Mon, 17 Jun 2024 03:18:06 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20js=20=ED=8F=B4=EB=8D=94=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/js/{ => auth}/form-validation.js | 0 assets/js/{ => auth}/login.js | 0 assets/js/{ => auth}/signup.js | 0 assets/js/{ => auth}/signup2.js | 27 +------------------------ assets/js/password-toggle.js | 0 5 files changed, 1 insertion(+), 26 deletions(-) rename assets/js/{ => auth}/form-validation.js (100%) rename assets/js/{ => auth}/login.js (100%) rename assets/js/{ => auth}/signup.js (100%) rename assets/js/{ => auth}/signup2.js (80%) delete mode 100644 assets/js/password-toggle.js diff --git a/assets/js/form-validation.js b/assets/js/auth/form-validation.js similarity index 100% rename from assets/js/form-validation.js rename to assets/js/auth/form-validation.js diff --git a/assets/js/login.js b/assets/js/auth/login.js similarity index 100% rename from assets/js/login.js rename to assets/js/auth/login.js diff --git a/assets/js/signup.js b/assets/js/auth/signup.js similarity index 100% rename from assets/js/signup.js rename to assets/js/auth/signup.js diff --git a/assets/js/signup2.js b/assets/js/auth/signup2.js similarity index 80% rename from assets/js/signup2.js rename to assets/js/auth/signup2.js index 7d0274b19..be14cf41e 100644 --- a/assets/js/signup2.js +++ b/assets/js/auth/signup2.js @@ -2,8 +2,6 @@ const form = document.querySelector("form"); const inputList = form.querySelectorAll("input"); const submitBtn = form.querySelector("#submitBtn"); -submitBtn.disabled = true; - inputList.forEach((input) => { input.addEventListener("keyup", function () { checkInputs(input); @@ -98,31 +96,8 @@ form.addEventListener("submit", (e) => { } }); - - // 패스워드 토글기능 -let passwordToggleBtns = document.querySelectorAll('.password-toggle-button'); - -function passwordToggle(e) { - let button = e.currentTarget; - let passwordInput = button.parentElement.querySelector('input'); - let toggleIcon = document.createElement('i'); - toggleIcon.classList.add('icon'); - if (passwordInput.type == "password") { - passwordInput.type = "text"; - toggleIcon.classList.remove('ic_visible_on'); - toggleIcon.classList.add('ic_visible_off') - this.setAttribute("aria-label", "비밀번호 숨기기"); - } else { - passwordInput.type = "password"; - toggleIcon.classList.remove('ic_visible_off'); - toggleIcon.classList.add('ic_visible_on'); - this.setAttribute("aria-label", "비밀번호 보기"); - } - button.innerHTML = ''; - button.appendChild(toggleIcon); -} - +const passwordToggleBtns = document.querySelectorAll('.password-toggle-button'); passwordToggleBtns.forEach(btn => { btn.addEventListener('click', passwordToggle); }); \ No newline at end of file diff --git a/assets/js/password-toggle.js b/assets/js/password-toggle.js deleted file mode 100644 index e69de29bb..000000000