diff --git a/css/common.css b/css/common.css index 24e665f0..74eb7e99 100644 --- a/css/common.css +++ b/css/common.css @@ -24,6 +24,7 @@ --color-input: #f3f4f6; --color-white: #ffffff; --color-text-login: #1f2937; + --color-error-red: #f74747; /* Typography */ --font-primary: "Pretendard-Regular", sans-serif; @@ -58,3 +59,7 @@ body { background-color: var(--color-disabled); } /* 비활성화시에 속성이랑 클래스 둘다 넣어야 함 */ + +.display-none { + display: none; +} diff --git a/css/login-signup-style.css b/css/login-signup-style.css index b73ef144..c84e4894 100644 --- a/css/login-signup-style.css +++ b/css/login-signup-style.css @@ -46,17 +46,31 @@ main { font-size: 16px; } +.form__input.invalid { + border: 1px solid var(--color-error-red); +} + +.form__error-msg { + position: relative; + top: -12px; + padding-left: 16px; + color: var(--color-error-red); + font-weight: 500; + font-size: 14px; +} + .input--password { position: relative; } -.btn--visibility-off { +.btn--visibility { border: none; background-color: var(--color-input); position: absolute; top: 16px; right: 24px; bottom: 16px; + padding: 0; } .btn--interactions { diff --git a/faq.html b/faq.html index e69de29b..93e4fdf5 100644 --- a/faq.html +++ b/faq.html @@ -0,0 +1 @@ + diff --git a/index.html b/index.html index b3ead464..5d17cbb3 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,7 @@ /> - + 판다마켓 diff --git a/js/btn-functions.js b/js/btn-functions.js new file mode 100644 index 00000000..4a031a67 --- /dev/null +++ b/js/btn-functions.js @@ -0,0 +1,24 @@ +//모든 input의 유효성 검사를 통과했을 때에만 누를 수 있어야하므로 validate와 작동방식이 달라야함 +export function toggleBtnStatus() { + const btn = document.querySelector(".btn--interactions"); + const errorMessages = document.querySelectorAll(".form__error-msg"); + const inputs = document.querySelectorAll(".form__input"); + + for (const message of errorMessages) { + if (message.textContent) { + btn.setAttribute("disabled", ""); + btn.classList.add("btn--disabled"); + return; + } + } + for (const input of inputs) { + if (!input.value) { + btn.setAttribute("disabled", ""); + btn.classList.add("btn--disabled"); + return; + } + } + + btn.removeAttribute("disabled"); + btn.classList.remove("btn--disabled"); +} diff --git a/js/login-signup.js b/js/login-signup.js new file mode 100644 index 00000000..42fc036c --- /dev/null +++ b/js/login-signup.js @@ -0,0 +1,60 @@ +import { + isEmpty, + validateEmail, + validatePassword, + validatePasswordConfirm, + validatePasswordConfirmReverse, + validateNickname, +} from "./validate.js"; +import { toggleBtnStatus } from "./btn-functions.js"; + +function toggleVisibility(event) { + const btn = event.target.parentElement; + const passwordInput = btn.previousElementSibling; + const iconOff = btn.children[0]; + const iconOn = btn.children[1]; + + if (passwordInput.getAttribute("type") === "password") { + passwordInput.setAttribute("type", "text"); + btn.setAttribute("aria-pressed", "true"); + } else { + passwordInput.setAttribute("type", "password"); + btn.setAttribute("aria-pressed", "false"); + } + iconOff.classList.toggle("display-none"); + iconOn.classList.toggle("display-none"); +} + +function isSignupPage() { + return window.location.pathname.search("signup") === -1 ? false : true; +} + +const form = document.querySelector(".container--form"); +const validateMap = { + email: validateEmail, + password: validatePassword, + "password-confirm": validatePasswordConfirm, + nickname: validateNickname, +}; + +form.addEventListener("focusout", (event) => { + const { id } = event.target; + + if (validateMap[id]) { + validateMap[id](event); + //비밀번호확인란부터 입력후 비밀번호를 변경할 시 비밀번호 확인 유효성 검사 + if (id === "password" && isSignupPage()) { + const passwordConfirmInput = document.getElementById("password-confirm"); + const passwordConfirm = passwordConfirmInput.value; + if (!isEmpty(passwordConfirm)) { + validatePasswordConfirmReverse(); + } + } + toggleBtnStatus(); + } +}); +form.addEventListener("click", (event) => { + if (event.target.classList.contains("form__icon")) { + toggleVisibility(event); + } +}); diff --git a/js/validate.js b/js/validate.js new file mode 100644 index 00000000..ce83eba6 --- /dev/null +++ b/js/validate.js @@ -0,0 +1,118 @@ +// common functions +export function isEmpty(value) { + return value ? false : true; +} + +function addInvalid(input) { + input.classList.add("invalid"); +} + +function removeInvalid(input) { + input.classList.remove("invalid"); +} + +// email functions +const emailPattern = /^[A-Za-z0-9_\.\-]+@[A-Za-z0-9\-]+\.[A-Za-z0-9\-]+/; + +function checkEmailFormat(email) { + if (emailPattern.test(email)) { + return true; + } else { + return false; + } +} + +export function validateEmail(event) { + const emailInput = event.target; + const email = emailInput.value; + let divErrorMessage = document.querySelector(".error-msg--email"); + + if (isEmpty(email)) { + divErrorMessage.textContent = "이메일을 입력해주세요"; + addInvalid(emailInput); + } else if (!checkEmailFormat(email)) { + divErrorMessage.textContent = "잘못된 이메일 형식입니다"; + addInvalid(emailInput); + } else { + divErrorMessage.textContent = ""; + removeInvalid(emailInput); + } +} + +// password functions +function checkPasswordFormat(password) { + if (password.length < 8) { + return false; + } else { + return true; + } +} + +function checkPassword(password, passwordConfirm) { + return password === passwordConfirm ? true : false; +} + +export function validatePassword(event) { + const passwordInput = event.target; + const password = passwordInput.value; + let divErrorMessage = document.querySelector(".error-msg--password"); + + if (isEmpty(password)) { + divErrorMessage.textContent = "비밀번호를 입력해주세요"; + addInvalid(passwordInput); + } else if (!checkPasswordFormat(password)) { + divErrorMessage.textContent = "비밀번호를 8자 이상 입력해주세요"; + addInvalid(passwordInput); + } else { + divErrorMessage.textContent = ""; + removeInvalid(passwordInput); + } +} + +export function validatePasswordConfirm(event) { + const passwordInput = document.getElementById("password"); + const password = passwordInput.value; + const passwordConfirmInput = event.target; + const passwordConfirm = passwordConfirmInput.value; + let divErrorMessage = document.querySelector(".error-msg--password-confirm"); + + if (!checkPassword(password, passwordConfirm)) { + divErrorMessage.textContent = "비밀번호가 일치하지 않습니다"; + addInvalid(passwordConfirmInput); + } else { + divErrorMessage.textContent = ""; + removeInvalid(passwordConfirmInput); + } +} + +//password유효성 검사를 하면서 password-confirm검사를 하기 위해 event가 아닌 고정으로 값을 가져오도록 함 +export function validatePasswordConfirmReverse() { + const passwordInput = document.getElementById("password"); + const password = passwordInput.value; + const passwordConfirmInput = document.getElementById("password-confirm"); + const passwordConfirm = passwordConfirmInput.value; + let divErrorMessage = document.querySelector(".error-msg--password-confirm"); + + if (!checkPassword(password, passwordConfirm)) { + divErrorMessage.textContent = "비밀번호가 일치하지 않습니다"; + addInvalid(passwordConfirmInput); + } else { + divErrorMessage.textContent = ""; + removeInvalid(passwordConfirmInput); + } +} + +//nickname functions +export function validateNickname(event) { + const nicknameInput = event.target; + const nickname = nicknameInput.value; + let divErrorMessage = document.querySelector(".error-msg--nickname"); + + if (isEmpty(nickname)) { + divErrorMessage.textContent = "닉네임을 입력해주세요"; + addInvalid(nicknameInput); + } else { + divErrorMessage.textContent = ""; + removeInvalid(nicknameInput); + } +} diff --git a/login.html b/login.html index 2557c53f..5ead6fd4 100644 --- a/login.html +++ b/login.html @@ -17,7 +17,12 @@ 판다마켓 -
+ +
@@ -36,25 +42,39 @@ name="password" type="password" required - autocomplete="password" + autocomplete="off" placeholder="비밀번호를 입력해주세요" class="form__input" />
+
- + +
@@ -84,5 +104,6 @@ 회원가입
+ diff --git a/signup.html b/signup.html index d9b1362c..edbf37bc 100644 --- a/signup.html +++ b/signup.html @@ -16,7 +16,12 @@ /> 판다마켓 -
+ +
+
@@ -45,50 +52,70 @@ name="password" type="password" required - autocomplete="password" + autocomplete="off" placeholder="비밀번호를 입력해주세요" class="form__input" />
+
- +
+
- + +
간편 로그인하기 @@ -116,5 +143,6 @@ 이미 회원이신가요? 로그인
+