diff --git a/index.html b/index.html index 8b2a3b00..da56da69 100644 --- a/index.html +++ b/index.html @@ -20,6 +20,7 @@ /> + diff --git a/item.html b/items.html similarity index 80% rename from item.html rename to items.html index 8170d49d..8d7115de 100644 --- a/item.html +++ b/items.html @@ -5,5 +5,7 @@ 판다마켓 - item - + + items 페이지 입니다! + diff --git a/login.html b/login.html index 3037de8e..e796577d 100644 --- a/login.html +++ b/login.html @@ -29,7 +29,7 @@ -
+
+ 이메일을 입력해주세요 + 잘못된 이메일 형식입니다
@@ -48,17 +54,31 @@ name="password" placeholder="비밀번호를 입력해주세요" /> -
+ 비밀번호를 입력해주세요 + 비밀번호를 8자 이상 입력해주세요 - -
@@ -90,5 +110,6 @@ 회원가입 + diff --git a/scripts/auth.js b/scripts/auth.js new file mode 100644 index 00000000..e34872a2 --- /dev/null +++ b/scripts/auth.js @@ -0,0 +1,173 @@ +const emailRegex = + /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/; +const loginForm = document.getElementById("loginForm"); +const signupForm = document.getElementById("signupForm"); +const emailInput = document.getElementById("email"); +const nicknameInput = document.getElementById("nickname"); +const passwordInput = document.getElementById("password"); +const confirmPasswordInput = document.getElementById("confirmPassword"); +const submitButton = document.getElementById("Submit-Button"); +let isEmailValid = false; +let isNicknameValid = false; +let isPasswordValid = false; +let isconfirmPasswordValid = false; + +function showError(inputElement, errorId) { + const errorElement = document.getElementById(errorId); + errorElement.style.display = "block"; + inputElement.style.outline = "1px solid var(--error)"; +} +function hideError(inputElement, errorId) { + const errorElement = document.getElementById(errorId); + errorElement.style.display = "none"; + inputElement.style.outline = "none"; +} + +function emailValidation() { + const emailValue = emailInput.value.trim(); + const emailValidation = emailRegex.test(emailValue); + + isEmailValid = false; + hideError(emailInput, "email-value-empty"); + hideError(emailInput, "email-value-invalid"); + + if (!emailValue) { + showError(emailInput, "email-value-empty"); + } else if (!emailValidation) { + showError(emailInput, "email-value-invalid"); + } else { + isEmailValid = true; + hideError(emailInput, "email-value-empty"); + hideError(emailInput, "email-value-invalid"); + } + + submitButtonActivation(); +} + +function nicknameValidation() { + const nicknameValue = nicknameInput.value.trim(); + + isNicknameValid = false; + hideError(nicknameInput, "nickname-value-empty"); + + if (!nicknameValue) { + showError(nicknameInput, "nickname-value-empty"); + } else { + isNicknameValid = true; + hideError(nicknameInput, "nickname-value-empty"); + } + + submitButtonActivation(); +} + +function passwordValidation() { + const passwordValue = passwordInput.value.trim(); + + isPasswordValid = false; + hideError(passwordInput, "password-value-empty"); + hideError(passwordInput, "password-value-invalid"); + + if (!passwordValue) { + showError(passwordInput, "password-value-empty"); + } else if (passwordValue.length < 8) { + showError(passwordInput, "password-value-invalid"); + } else { + isPasswordValid = true; + hideError(passwordInput, "password-value-empty"); + hideError(passwordInput, "password-value-invalid"); + } + + submitButtonActivation(); + if (signupForm) { + confirmPasswordValidation(); + } +} + +function confirmPasswordValidation() { + const confirmPasswordValue = confirmPasswordInput.value.trim(); + + isconfirmPasswordValid = false; + + hideError(confirmPasswordInput, "check-password-validation"); + hideError(confirmPasswordInput, "confirmPassword-value-invalid"); + if (!isPasswordValid) { + showError(confirmPasswordInput, "check-password-validation"); + } else if ( + !confirmPasswordValue || + confirmPasswordValue !== passwordInput.value.trim() + ) { + showError(confirmPasswordInput, "confirmPassword-value-invalid"); + } else { + isconfirmPasswordValid = true; + hideError(confirmPasswordInput, "check-password-validation"); + hideError(confirmPasswordInput, "confirmPassword-value-invalid"); + } + + submitButtonActivation(); +} + +function submitButtonActivation() { + let isAuthValid = isEmailValid && isPasswordValid; + if (signupForm) { + isAuthValid = isAuthValid && isNicknameValid && isconfirmPasswordValid; + } + + submitButton.disabled = !isAuthValid; +} + +if (emailInput) { + emailInput.addEventListener("focusout", emailValidation); +} +if (nicknameInput) { + nicknameInput.addEventListener("focusout", nicknameValidation); +} +if (passwordInput) { + passwordInput.addEventListener("input", passwordValidation); +} +if (confirmPasswordInput) { + confirmPasswordInput.addEventListener("input", confirmPasswordValidation); +} + +submitButtonActivation(); + +if (loginForm) { + loginForm.addEventListener("submit", function (event) { + event.preventDefault(); + window.location.href = "items.html"; + }); +} + +if (signupForm) { + signupForm.addEventListener("submit", function (event) { + event.preventDefault(); + window.location.href = "login.html"; + }); +} + +function PasswordToggleVisibility(event) { + const targetButton = event.currentTarget; + const targetInputField = targetButton.parentElement.querySelector("input"); + const targetToggleIcon = targetButton.querySelector(".password-toggle-icon"); + + const isPasswordVisible = targetInputField.type === "text"; + targetInputField.type = isPasswordVisible ? "password" : "text"; + targetToggleIcon.src = isPasswordVisible + ? "/images/icon/auth/eye-invisible.svg" + : "/images/icon/auth/eye-visible.svg"; + + targetToggleIcon.alt = isPasswordVisible + ? "비밀번호 숨김 아이콘" + : "비밀번호 표시 아이콘"; + + targetButton.setAttribute( + "aria-label", + isPasswordVisible ? "비밀번호 숨김" : "비밀번호 표시" + ); +} + +const passwordToggleButtons = document.querySelectorAll( + ".password-toggle-button" +); +passwordToggleButtons.forEach((passwordToggleButton) => + passwordToggleButton.addEventListener("click", PasswordToggleVisibility) +); diff --git a/signup.html b/signup.html index 262955c3..26dd4be8 100644 --- a/signup.html +++ b/signup.html @@ -28,7 +28,7 @@ -
+
+ 이메일을 입력해주세요 + 잘못된 이메일 형식입니다
+ 닉네임을 입력해주세요
@@ -56,35 +65,61 @@ name="password" placeholder="비밀번호를 입력해주세요" /> -
+ 비밀번호를 입력해주세요 + 비밀번호를 8자 이상 입력해주세요
- +
-
+ 먼저 비밀번호를 조건에 맞게 입력해주세요 + 비밀번호가 일치하지 않습니다
-
@@ -111,5 +146,6 @@ 로그인 + diff --git a/styles/auth.css b/styles/auth.css index bf558da3..aa248221 100644 --- a/styles/auth.css +++ b/styles/auth.css @@ -46,7 +46,7 @@ input::placeholder { } input:focus { - outline-color: var(--primary100); + outline: 1px solid var(--primary100); } .input-form-wrapper { @@ -55,7 +55,7 @@ input:focus { align-items: center; } -.password-show { +.password-toggle-button { position: absolute; right: 24px; cursor: pointer; @@ -65,6 +65,15 @@ input:focus { width: 100%; } +.error-message { + padding-left: 16px; + color: var(--error); + font-weight: 600; + font-size: var(--font-size-md); + line-height: var(--line-height-md); + display: none; +} + /* 간편 로그인하기 */ .login-simple { width: 100%; diff --git a/styles/global.css b/styles/global.css index f1cab570..c3bd95e2 100644 --- a/styles/global.css +++ b/styles/global.css @@ -77,39 +77,6 @@ body { font-family: "Pretendard", sans-serif; } -header { - width: 100%; - height: 70px; - padding: 0 16px; - display: flex; - align-items: center; - justify-content: space-between; - background-color: #fff; - border-bottom: 1px solid #dfdfdf; - position: fixed; - top: 0; - left: 0; - z-index: 1; -} - -footer { - padding: 32px 32px 30px; - color: var(--gray400); - background-color: var(--gray900); - display: flex; - align-items: center; - justify-content: space-between; - flex-wrap: wrap; - gap: 60px; -} - -.container { - max-width: 1120px; - margin: 0 auto; - width: 100%; - padding: 0 16px; -} - .button { background-color: var(--primary100); color: var(--gray100); @@ -141,18 +108,6 @@ footer { } @media (min-width: 768px) { - header { - padding: 0 24px; - } - - footer { - padding: 32px 104px 108px 104px; - } - - .container { - padding: 0 24px; - } - .btn-round { font-size: var(--font-size-xl); font-weight: 600; @@ -160,17 +115,3 @@ footer { border-radius: 9999px; } } - -@media (min-width: 1200px) { - header { - padding: 0 200px; - } - - footer { - padding: 32px 200px 108px 200px; - } - - .container { - padding: 0; - } -} diff --git a/styles/layout.css b/styles/layout.css new file mode 100644 index 00000000..941d6bac --- /dev/null +++ b/styles/layout.css @@ -0,0 +1,60 @@ +header { + width: 100%; + height: 70px; + padding: 0 16px; + display: flex; + align-items: center; + justify-content: space-between; + background-color: #fff; + border-bottom: 1px solid #dfdfdf; + position: fixed; + top: 0; + left: 0; + z-index: 1; +} + +footer { + padding: 32px 32px 30px; + color: var(--gray400); + background-color: var(--gray900); + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: 60px; +} + +.container { + max-width: 1120px; + margin: 0 auto; + width: 100%; + padding: 0 16px; +} + +@media (min-width: 768px) { + header { + padding: 0 24px; + } + + footer { + padding: 32px 104px 108px 104px; + } + + .container { + padding: 0 24px; + } +} + +@media (min-width: 1200px) { + header { + padding: 0 200px; + } + + footer { + padding: 32px 200px 108px 200px; + } + + .container { + padding: 0; + } +}