diff --git a/css/login.css b/css/login.css index 4700b03dc..8495f83ce 100644 --- a/css/login.css +++ b/css/login.css @@ -40,13 +40,26 @@ input { } input:focus { - outline: 2px solid var(--brand-blue); + outline: 1px solid var(--brand-blue); +} + +.error-input, +.error-input:focus { + outline: 1px solid var(--error-red); } .password-input { position: relative; } +.error-message { + margin-top: 8px; + margin-left: 16px; + font-size: 15px; + font-weight: 600; + color: var(--error-red); +} + .visibility-button { width: 24px; height: 24px; diff --git a/js/button.js b/js/button.js new file mode 100644 index 000000000..4e1d213ec --- /dev/null +++ b/js/button.js @@ -0,0 +1,25 @@ +// validitiy checker (boolean) +import { emailIsValid, nicknameIsValid, pwIsValid, pwRetypeIsValid } from './input.js'; + +const loginButton = document.querySelector('#login-button'); +const signupButton = document.querySelector('#signup-button'); + +// every input is valid -> button disable=false +export function buttonDisableChecker(event) { + + if(loginButton !== null) { + if(emailIsValid && pwIsValid) { + loginButton.disabled = false; + } else { + loginButton.disabled = true; + } + } + + if(signupButton !== null) { + if(emailIsValid && pwIsValid && nicknameIsValid && pwRetypeIsValid) { + signupButton.disabled = false; + } else { + signupButton.disabled = true; + } + } +} \ No newline at end of file diff --git a/js/input.js b/js/input.js new file mode 100644 index 000000000..60fdf4b7b --- /dev/null +++ b/js/input.js @@ -0,0 +1,86 @@ +// password valid condition +const PW_MIN_LENGTH = 8; + +// for button disable toggle +export let emailIsValid = false; +export let nicknameIsValid = false; +export let pwIsValid = false; +export let pwRetypeIsValid = false; + +// email validitiychecker +export function emailInputCheck(event) { + const target = event.target; + const errorMessage = document.querySelector('#email-error-message'); + + if (target.value === "") { + target.classList.add('error-input'); + errorMessage.textContent = '이메일을 입력해주세요.'; + emailIsValid = false; + } + // checkValidity() : true ("" or type match), false (different type) + if (!target.checkValidity()) { + target.classList.add('error-input'); + errorMessage.textContent = '잘못된 이메일 형식입니다.'; + emailIsValid = false; + } + if (target.checkValidity() && target.value !== "") { + target.classList.remove('error-input'); + errorMessage.textContent = ''; + emailIsValid = true; + } +} + +// nickname validitiychecker +export function nicknameInputCheck(event) { + const target = event.target; + const errorMessage = document.querySelector('#nickname-error-message'); + + if (target.value === "") { + target.classList.add('error-input'); + errorMessage.textContent = '닉네임을 입력해주세요.'; + nicknameIsValid = false; + } else { + target.classList.remove('error-input'); + errorMessage.textContent = ''; + nicknameIsValid = true; + } +} + +// password validitiychecker +export function pwInputCheck(event) { + const target = event.target; + const errorMessage = document.querySelector('#password-error-message'); + + if (target.value.length === 0) { + target.classList.add('error-input'); + errorMessage.textContent = '비밀번호를 입력해주세요.'; + pwIsValid = false; + } + if (target.value.length < PW_MIN_LENGTH && target.value.length > 0) { + target.classList.add('error-input'); + errorMessage.textContent = '비밀번호를 8자 이상 입력해주세요.'; + pwIsValid = false; + } + if (target.value.length >= PW_MIN_LENGTH) { + target.classList.remove('error-input'); + errorMessage.textContent = ''; + pwIsValid = true; + } +} + +// retype password validitiychecker +export function pwRetypeInputCheck(event) { + const target = event.target; + const pwInput = document.querySelector('#password-input'); + const errorMessage = document.querySelector('#password-retype-error-message'); + + if (target.value !== pwInput.value) { + target.classList.add('error-input'); + errorMessage.textContent = '비밀번호가 일치하지 않습니다.'; + pwRetypeIsValid = false; + } else { + target.classList.remove('error-input'); + errorMessage.textContent = ''; + pwRetypeIsValid = true; + } +} \ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 000000000..4112869af --- /dev/null +++ b/js/main.js @@ -0,0 +1,32 @@ +import { emailInputCheck,nicknameInputCheck, pwInputCheck, pwRetypeInputCheck } from './input.js'; +import { buttonDisableChecker } from './button.js'; +import { pwVisibleToggle } from './pw_visibility.js'; + +const emailInput = document.querySelector('#email-input'); +const pwInput = document.querySelector('#password-input'); +const pwRetypeInput = document.querySelector('#password-retype-input'); +const nicknameInput = document.querySelector('#nickname-input'); + +const pwVisibleBtn = document.querySelector('#password-visibility-button'); +const pwRetypeVisibleBtn = document.querySelector('#password-retype-visibility-button'); + +// login page event +emailInput.addEventListener('focusout', emailInputCheck); +pwInput.addEventListener('focusout', pwInputCheck); + +emailInput.addEventListener('focusout', buttonDisableChecker); +pwInput.addEventListener('focusout', buttonDisableChecker); + +pwVisibleBtn.addEventListener('click', pwVisibleToggle); + + +// additional event for signup page +if (pwRetypeInput && nicknameInput) { + nicknameInput.addEventListener('focusout', nicknameInputCheck); + pwRetypeInput.addEventListener('focusout', pwRetypeInputCheck); + + nicknameInput.addEventListener('focusout', buttonDisableChecker); + pwRetypeInput.addEventListener('focusout', buttonDisableChecker); + + pwRetypeVisibleBtn.addEventListener('click', pwVisibleToggle); +} \ No newline at end of file diff --git a/js/pw_visibility.js b/js/pw_visibility.js new file mode 100644 index 000000000..aecd694a6 --- /dev/null +++ b/js/pw_visibility.js @@ -0,0 +1,17 @@ +let visibleMode = false; + +export function pwVisibleToggle(event) { + const img = event.target; + const input = img.parentElement.parentElement.firstElementChild; + + if (visibleMode) { + img.src = "/images/btn_visibility_off.png"; + input.type = "password"; + visibleMode = false; + } else { + img.src = "/images/btn_visibility_on.png"; + input.type = "text"; + visibleMode = true; + } +} + diff --git a/pages/login/index.html b/pages/login/index.html index 71f3a2084..fabee9f84 100644 --- a/pages/login/index.html +++ b/pages/login/index.html @@ -14,6 +14,7 @@ +
@@ -26,30 +27,33 @@

이메일

- +

비밀번호

- + /> 비밀번호 표시 옵션 +

- + + + + + \ No newline at end of file diff --git a/pages/login/signup.html b/pages/login/signup.html index 2e9b973e2..55525026d 100644 --- a/pages/login/signup.html +++ b/pages/login/signup.html @@ -14,6 +14,7 @@ +
@@ -26,55 +27,61 @@

이메일

- +

닉네임

- +

비밀번호

- 비밀번호 표시 옵션 +

비밀번호 확인

- 비밀번호 표시 옵션 +

- + + + + + \ No newline at end of file