diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..912999a5 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,23 @@ +{ + "arrowParens": "always", + "bracketSameLine": false, + "objectWrap": "preserve", + "bracketSpacing": true, + "semi": true, + "experimentalOperatorPosition": "end", + "experimentalTernaries": false, + "singleQuote": true, + "jsxSingleQuote": false, + "quoteProps": "as-needed", + "trailingComma": "all", + "singleAttributePerLine": false, + "htmlWhitespaceSensitivity": "css", + "vueIndentScriptAndStyle": false, + "proseWrap": "preserve", + "insertPragma": false, + "printWidth": 80, + "requirePragma": false, + "tabWidth": 2, + "useTabs": false, + "embeddedLanguageFormatting": "auto" +} diff --git a/css/login.css b/css/login.css index e97b3357..2139ab44 100644 --- a/css/login.css +++ b/css/login.css @@ -1,6 +1,6 @@ body { margin: 0; - font-family: 'Pretendard' ; + font-family: 'Pretendard'; } .login-wrapper { @@ -11,7 +11,7 @@ body { .login-box { width: 640px; - padding: 48px; + padding: 56px; box-sizing: border-box; } @@ -20,12 +20,13 @@ body { display: flex; justify-content: center; align-items: center; + margin-bottom: 40px; } .logo-img { width: 396px; height: 132px; - display: block; + display: block; } /*입력창*/ @@ -38,18 +39,18 @@ label { font-size: 18px; font-weight: 700; margin-bottom: 16px; - color: #1F2937; + color: #1f2937; } -input[type="email"], -input[type="password"] { +input[type='email'], +input[type='password'] { width: 100%; - height: 48px; + height: 56px; font-size: 15px; - padding: 16px; + padding: 16px; border-radius: 12px; border: none; - background-color: #F3F4F6; + background-color: #f3f4f6; box-sizing: border-box; } @@ -65,9 +66,10 @@ input[type="password"] { margin: 16 48 48 48px; border-radius: 12px; box-sizing: border-box; - background-color: #F3F4F6; + background-color: #f3f4f6; border: none; font-size: 16px; + margin: 0; } .password-input .btn { @@ -88,12 +90,11 @@ input[type="password"] { height: 100%; } - /*로그인 버튼*/ .login-btn { width: 100%; height: 56px; - background-color: #9CA3AF; + background-color: #9ca3af; color: #ffffff; font-weight: 600; font-size: 20px; @@ -103,7 +104,7 @@ input[type="password"] { /*간편 로그인*/ .social-login { - background-color: #E6F2FF; + background-color: #e6f2ff; height: 74px; display: flex; justify-content: space-between; @@ -134,11 +135,11 @@ input[type="password"] { font-size: 14px; font-weight: 500; text-align: center; - color: #1F2937; + color: #1f2937; } .signup-callout a { - color: #3182F6; + color: #3182f6; font-size: 14px; font-weight: 500; } @@ -151,4 +152,26 @@ input[type="password"] { width: 100%; height: auto; } -} \ No newline at end of file +} + +/*에러 메세지*/ +.error-input { + border: 1px solid #f74747 !important; +} + +.error-message { + color: #f74747; + font-size: 14px; + font-weight: 600; + margin-top: 10px; + display: block; +} + +/*로그인 버튼 활성화*/ +.login-btn.enabled { + background-color: #3692ff; +} + +.login-btn:disabled { + cursor: not-allowed; +} diff --git a/css/signup.css b/css/signup.css index 068ca997..792043a3 100644 --- a/css/signup.css +++ b/css/signup.css @@ -1,6 +1,6 @@ body { margin: 0; - font-family: 'Pretendard' ; + font-family: 'Pretendard'; } .login-wrapper { @@ -20,12 +20,13 @@ body { display: flex; justify-content: center; align-items: center; + margin-bottom: 40px; } .logo-img { width: 396px; height: 132px; - display: block; + display: block; } /*입력창*/ @@ -38,19 +39,19 @@ label { font-size: 18px; font-weight: 700; margin-bottom: 16px; - color: #1F2937; + color: #1f2937; } -input[type="email"], -input[type="password"], -input[type="text"]{ +input[type='email'], +input[type='password'], +input[type='text'] { width: 100%; - height: 48px; + height: 56px; font-size: 15px; - padding: 16px; + padding: 16px; border-radius: 12px; border: none; - background-color: #F3F4F6; + background-color: #f3f4f6; box-sizing: border-box; } @@ -67,7 +68,7 @@ input[type="text"]{ margin: 16 48 48 48px; border-radius: 12px; box-sizing: border-box; - background-color: #F3F4F6; + background-color: #f3f4f6; border: none; font-size: 16px; } @@ -90,12 +91,11 @@ input[type="text"]{ height: 100%; } - /*로그인 버튼*/ .login-btn { width: 100%; height: 56px; - background-color: #9CA3AF; + background-color: #9ca3af; color: #ffffff; font-weight: 600; font-size: 20px; @@ -105,7 +105,7 @@ input[type="text"]{ /*간편 로그인*/ .social-login { - background-color: #E6F2FF; + background-color: #e6f2ff; height: 74px; display: flex; justify-content: space-between; @@ -136,11 +136,11 @@ input[type="text"]{ font-size: 14px; font-weight: 500; text-align: center; - color: #1F2937; + color: #1f2937; } .signup-callout a { - color: #3182F6; + color: #3182f6; font-size: 14px; font-weight: 500; } @@ -155,4 +155,28 @@ input[type="text"]{ } } +/*에러 메세지*/ +.error-input { + border: 1px solid #f74747 !important; +} + +.correct-input { + border: 1px solid #3692ff !important; +} +.error-message { + color: #f74747; + font-size: 14px; + font-weight: 600; + margin-top: 10px; + display: block; +} + +/*로그인 버튼 활성화*/ +.login-btn.enabled { + background-color: #3692ff; +} + +.login-btn:disabled { + cursor: not-allowed; +} diff --git a/images/eye-off.png b/images/eye-off.png deleted file mode 100644 index fb4eeaf4..00000000 Binary files a/images/eye-off.png and /dev/null differ diff --git a/images/eye-off.svg b/images/eye-off.svg new file mode 100644 index 00000000..45ad6232 --- /dev/null +++ b/images/eye-off.svg @@ -0,0 +1,3 @@ + + + diff --git a/images/eye-on.png b/images/eye-on.png deleted file mode 100644 index 467cf49a..00000000 Binary files a/images/eye-on.png and /dev/null differ diff --git a/images/eye-on.svg b/images/eye-on.svg new file mode 100644 index 00000000..43a5af17 --- /dev/null +++ b/images/eye-on.svg @@ -0,0 +1,3 @@ + + + diff --git a/index.html b/index.html index b6e516d3..77b3e14e 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ 판다마켓 - + diff --git a/js/login.js b/js/login.js index ca340fdf..313fae5e 100644 --- a/js/login.js +++ b/js/login.js @@ -1,12 +1,83 @@ function inputPassword(inputId, eyeId) { - const passwordInput = document.getElementById(inputId); - const eyeIcon = document.getElementById(eyeId); - - if (passwordInput.type === "password") { - passwordInput.type = "text"; - eyeIcon.src = "images/eye-on.png"; - } else { - passwordInput.type = "password"; - eyeIcon.src = "images/eye-off.png"; - } - } \ No newline at end of file + const passwordInput = document.getElementById(inputId); + const eyeIcon = document.getElementById(eyeId); + + if (passwordInput.type === 'password') { + passwordInput.type = 'text'; + eyeIcon.src = 'images/eye-on.svg'; + } else { + passwordInput.type = 'password'; + eyeIcon.src = 'images/eye-off.svg'; + } +} + +document.addEventListener('DOMContentLoaded', function () { + const emailInput = document.getElementById('email'); + const emailError = document.getElementById('email-error'); + const passwordInput = document.getElementById('password'); + const passwordError = document.getElementById('password-error'); + const loginButton = document.getElementById('login-button'); + + function validateEmail(email) { + const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; + return emailRegex.test(email); + } + + function updateButtonState() { + const emailValue = emailInput.value.trim(); + const passwordValue = passwordInput.value.trim(); + const emailValid = emailValue !== '' && validateEmail(emailValue); + const passwordValid = passwordValue !== '' && passwordValue.length >= 8; + if (emailValid && passwordValid) { + loginButton.disabled = false; + loginButton.classList.add('enabled'); + } else { + loginButton.disabled = true; + loginButton.classList.remove('enabled'); + } + } + + emailInput.addEventListener('input', function () { + const value = emailInput.value.trim(); + if (value === '') { + emailInput.classList.add('error-input'); + emailError.textContent = '이메일을 입력해주세요.'; + emailError.style.display = 'block'; + } else if (!validateEmail(value)) { + emailInput.classList.add('error-input'); + emailError.textContent = '잘못된 이메일 형식입니다.'; + emailError.style.display = 'block'; + } else { + emailInput.classList.remove('error-input'); + emailError.textContent = ''; + emailError.style.display = 'none'; + } + updateButtonState(); + }); + + passwordInput.addEventListener('input', function () { + const value = passwordInput.value.trim(); + if (value === '') { + passwordInput.classList.add('error-input'); + passwordError.textContent = '비밀번호를 입력해주세요.'; + passwordError.style.display = 'block'; + } else if (value.length < 8) { + passwordInput.classList.add('error-input'); + passwordError.textContent = '비밀번호를 8자 이상 입력해주세요.'; + passwordError.style.display = 'block'; + } else { + passwordInput.classList.remove('error-input'); + passwordError.textContent = ''; + passwordError.style.display = 'none'; + } + updateButtonState(); + }); + + loginButton.addEventListener('click', function () { + if (!this.disabled) { + window.location.href = '/items'; + } + }); + + updateButtonState(); +}); diff --git a/js/signup.js b/js/signup.js index 1fe0fda6..64375f0d 100644 --- a/js/signup.js +++ b/js/signup.js @@ -1,13 +1,14 @@ +/*눈 아이콘*/ function inputPassword(inputId, eyeId) { const passwordInput = document.getElementById(inputId); const eyeIcon = document.getElementById(eyeId); - if (passwordInput.type === "password") { - passwordInput.type = "text"; - eyeIcon.src = "images/eye-on.png"; + if (passwordInput.type === 'password') { + passwordInput.type = 'text'; + eyeIcon.src = 'images/eye-on.svg'; } else { - passwordInput.type === "password"; - eyeIcon.src = "images/eye-off.png"; + passwordInput.type = 'password'; + eyeIcon.src = 'images/eye-off.svg'; } } @@ -15,12 +16,131 @@ function confirmPassword(inputId, eyeId) { const passwordInput = document.getElementById(inputId); const eyeIcon = document.getElementById(eyeId); - if (passwordInput.type === "password") { - passwordInput.type = "text"; - eyeIcon.src = "images/eye-on.png"; + if (passwordInput.type === 'password') { + passwordInput.type = 'text'; + eyeIcon.src = 'images/eye-on.svg'; } else { - passwordInput.type === "password"; - eyeIcon.src = "images/eye-off.png"; + passwordInput.type = 'password'; + eyeIcon.src = 'images/eye-off.svg'; } } +document.addEventListener('DOMContentLoaded', function () { + const emailInput = document.getElementById('email'); + const nicknameInput = document.getElementById('nickname'); + const passwordInput = document.getElementById('password'); + const confirmInput = document.getElementById('password-confirm'); + const emailError = document.getElementById('email-error'); + const nicknameError = document.getElementById('nickname-error'); + const passwordError = document.getElementById('password-error'); + const confirmError = document.getElementById('confirm-error'); + const signupButton = document.getElementById('signup-button'); + + function validateEmail(email) { + const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; + return emailRegex.test(email); + } + + function updateButtonState() { + const emailValue = emailInput.value.trim(); + const nickValue = nicknameInput.value.trim(); + const pwValue = passwordInput.value.trim(); + const confirmValue = confirmInput.value.trim(); + const emailValid = emailValue !== '' && validateEmail(emailValue); + const nickValid = nickValue !== ''; + const pwValid = pwValue !== '' && pwValue.length >= 8; + const confirmValid = + confirmValue !== '' && + confirmValue.length >= 8 && + pwValue === confirmValue; + if (emailValid && nickValid && pwValid && confirmValid) { + signupButton.disabled = false; + signupButton.classList.add('enabled'); + } else { + signupButton.disabled = true; + signupButton.classList.remove('enabled'); + } + } + + emailInput.addEventListener('blur', function () { + const value = emailInput.value.trim(); + if (value === '') { + emailInput.classList.add('error-input'); + emailError.textContent = '이메일을 입력해주세요.'; + emailError.style.display = 'block'; + } else if (!validateEmail(value)) { + emailInput.classList.add('error-input'); + emailError.textContent = '잘못된 이메일 형식입니다.'; + emailError.style.display = 'block'; + } else { + emailInput.classList.remove('error-input'); + emailError.textContent = ''; + emailError.style.display = 'none'; + } + updateButtonState(); + }); + + nicknameInput.addEventListener('blur', function () { + const value = nicknameInput.value.trim(); + if (value !== '') { + nicknameInput.classList.add('correct-input'); + } else { + nicknameInput.classList.remove('correct-input'); + } + updateButtonState(); + }); + + passwordInput.addEventListener('blur', function () { + const value = passwordInput.value.trim(); + if (value === '') { + passwordInput.classList.add('error-input'); + passwordError.textContent = '비밀번호를 입력해주세요.'; + passwordError.style.display = 'block'; + } else if (value.length < 8) { + passwordInput.classList.add('error-input'); + passwordError.textContent = '비밀번호를 8자 이상 입력해주세요.'; + passwordError.style.display = 'block'; + } else { + passwordInput.classList.remove('error-input'); + passwordError.textContent = ''; + passwordError.style.display = 'none'; + } + updateButtonState(); + }); + + confirmInput.addEventListener('blur', function () { + const pwValue = passwordInput.value.trim(); + const value = confirmInput.value.trim(); + if (value === '') { + confirmInput.classList.add('error-input'); + confirmError.textContent = '비밀번호 확인을 입력해주세요.'; + confirmError.style.display = 'block'; + } else if (value.length < 8) { + confirmInput.classList.add('error-input'); + confirmError.textContent = '비밀번호 확인을 8자 이상 입력해주세요.'; + confirmError.style.display = 'block'; + } else if (pwValue !== value) { + confirmInput.classList.add('error-input'); + confirmError.textContent = '비밀번호가 일치하지 않습니다.'; + confirmError.style.display = 'block'; + } else { + confirmInput.classList.remove('error-input'); + confirmError.textContent = ''; + confirmError.style.display = 'none'; + } + updateButtonState(); + }); + + emailInput.addEventListener('input', updateButtonState); + nicknameInput.addEventListener('input', updateButtonState); + passwordInput.addEventListener('input', updateButtonState); + confirmInput.addEventListener('input', updateButtonState); + + signupButton.addEventListener('click', function () { + if (!this.disabled) { + window.location.href = 'login.html'; + } + }); + + updateButtonState(); +}); diff --git a/login.html b/login.html index 6e1b435b..33e5a7b7 100644 --- a/login.html +++ b/login.html @@ -1,52 +1,83 @@ - - - - 판다마켓 로그인 - - - - + + + + 판다마켓 로그인 + + + + + + + + + + + + - - -
-
-
- - 판다로고 - -
-
- - -
-
- -
- - + +
+ +
+ + 판다로고 + +
+
+ + +
-
- -
- - \ No newline at end of file + +

+ 판다마켓이 처음이신가요? 회원가입 +

+ + + + diff --git a/signup.html b/signup.html index e1ce2b13..e3a1ea20 100644 --- a/signup.html +++ b/signup.html @@ -1,63 +1,130 @@ - - - - 판다마켓 로그인 - - - - + + + + 판다마켓 회원가입 + + + + + + + + + + + + - - -
-
-
- - 판다로고 - -
-
- - -
-
- - -
-
- -
- - -
-
- -
- - +
+ +
+
+
+ +
+ + + +
+
-
- -
- - \ No newline at end of file + +

+ 이미 회원이신가요? 로그인 +

+ + + +