From e8a212fb3dd9db43ab331f1948a4307c4e9655eb Mon Sep 17 00:00:00 2001 From: BasicKTW Date: Fri, 16 May 2025 11:40:18 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20git=20hub=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- styles/homepage/home.css | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/styles/homepage/home.css b/styles/homepage/home.css index f149c65a..dc0175e0 100644 --- a/styles/homepage/home.css +++ b/styles/homepage/home.css @@ -190,7 +190,7 @@ footer { font-size: 18px; } - #features br { + .feature h1 br { display: none; } @@ -245,13 +245,13 @@ footer { } @media (max-width: 767px) { - #top-banner-text { + #top-banner-text h1 { font-size: 32px; line-height: 140%; } - br { - display: block; + .feature-description br { + display: inline; } #top-banner-text { @@ -326,10 +326,11 @@ footer { } #footer-Menu { + color: #cfcfcf; grid-column: 1 / 2; grid-row: 1 / 2; display: flex; - gap: 12px; + gap: 30px; justify-content: start; width: 100%; } @@ -347,4 +348,9 @@ footer { width: 375px; height: 198px; } + + .pill-button { + font-size: 18px; + padding: 12px 71px; + } } From 3c73b56cdfb83432f0ce5189ac0acbb435888816 Mon Sep 17 00:00:00 2001 From: BasicKTW Date: Fri, 16 May 2025 12:14:38 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EB=A9=94=EC=8B=9C=EC=A7=80=EC=99=80=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascript/login&signuppage/login.js | 72 ++++++++++++++++++++++++++++ login.html | 22 ++++++++- styles/signup&loginpage/login.css | 20 +++++++- 3 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 javascript/login&signuppage/login.js diff --git a/javascript/login&signuppage/login.js b/javascript/login&signuppage/login.js new file mode 100644 index 00000000..623c8da7 --- /dev/null +++ b/javascript/login&signuppage/login.js @@ -0,0 +1,72 @@ +const emailInput = document.getElementById("emailInput"); +const emailError = document.getElementById("emailError"); +const passwordInput = document.getElementById("passwardinput"); +const passwordError = document.getElementById("passwordError"); +const loginButton = document.getElementById("loginButton"); + +/* 이메일 정규표현식 */ +const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + +/* 유효성 검사 상태 변수 */ +let isEmailValid = false; +let isPasswordValid = false; + +/* 📌 유효성 검사 후 버튼 활성화 체크 */ +const updateButtonState = () => { + if (isEmailValid && isPasswordValid) { + loginButton.disabled = false; + } else { + loginButton.disabled = true; + } +}; + +/* 📌 이메일 Focus Out 체크 */ +emailInput.addEventListener("focusout", () => { + const value = emailInput.value.trim(); + + if (!value) { + emailInput.classList.add("error"); + emailError.textContent = "이메일을 입력해주세요."; + emailError.style.display = "block"; + isEmailValid = false; + } else if (!emailPattern.test(value)) { + emailInput.classList.add("error"); + emailError.textContent = "잘못된 이메일 형식입니다."; + emailError.style.display = "block"; + isEmailValid = false; + } else { + emailInput.classList.remove("error"); + emailError.style.display = "none"; + isEmailValid = true; + } + updateButtonState(); +}); + +/* 📌 비밀번호 Focus Out 체크 */ +passwordInput.addEventListener("focusout", () => { + const value = passwordInput.value.trim(); + + if (!value) { + passwordInput.classList.add("error"); + passwordError.textContent = "비밀번호를 입력해주세요."; + passwordError.style.display = "block"; + isPasswordValid = false; + } else if (value.length < 8) { + passwordInput.classList.add("error"); + passwordError.textContent = "비밀번호를 8자 이상 입력해주세요."; + passwordError.style.display = "block"; + isPasswordValid = false; + } else { + passwordInput.classList.remove("error"); + passwordError.style.display = "none"; + isPasswordValid = true; + } + updateButtonState(); +}); + +/* 📌 버튼 클릭 시 페이지 이동 */ +loginButton.addEventListener("click", () => { + if (isEmailValid && isPasswordValid) { + window.location.href = "/items"; + } +}); diff --git a/login.html b/login.html index 54a51f09..6cdbef47 100644 --- a/login.html +++ b/login.html @@ -27,7 +27,17 @@
- + +
@@ -44,8 +54,15 @@ id="togglePassword" />
+ - +
간편 로그인하기
@@ -63,5 +80,6 @@
+ diff --git a/styles/signup&loginpage/login.css b/styles/signup&loginpage/login.css index 17720cac..3f3ffcbe 100644 --- a/styles/signup&loginpage/login.css +++ b/styles/signup&loginpage/login.css @@ -50,6 +50,22 @@ body { padding-bottom: 16px; } +.logininput:focus { + border-color: #3692ff; + outline: none; + box-shadow: 0 0 5px rgba(74, 144, 226, 0.5); +} + +.error-message { + color: #f74747; + font-size: 14px; + margin-top: 8px; +} + +.logininput.error { + border: 1px solid #f74747 !important; +} + /* 이메일 박스 스타일 */ #emailbox { margin-bottom: 24px; @@ -82,7 +98,7 @@ body { /* 로그인 섹션 스타일 */ /* 로그인 버튼 */ -#loginbutton { +#loginButton { margin-top: 24px; margin-bottom: 24px; width: 640px; @@ -168,7 +184,7 @@ body { /* 입력 필드, 버튼 설정 */ .logininput, #passwardinput, - #loginbutton { + #loginButton { width: 100%; margin-bottom: 12px; } From 4c3bfc7d4776f0cfdf8871a80d683de90d6fe2ef Mon Sep 17 00:00:00 2001 From: BasicKTW Date: Fri, 16 May 2025 12:57:23 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=9D=B8=ED=92=8B=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascript/login&signuppage/signup.js | 123 ++++++++++++++++++++++++++ login.html | 1 + signup.html | 44 +++++++-- styles/signup&loginpage/login.css | 4 + styles/signup&loginpage/signup.css | 45 +++++++++- 5 files changed, 206 insertions(+), 11 deletions(-) create mode 100644 javascript/login&signuppage/signup.js diff --git a/javascript/login&signuppage/signup.js b/javascript/login&signuppage/signup.js new file mode 100644 index 00000000..2cbda72f --- /dev/null +++ b/javascript/login&signuppage/signup.js @@ -0,0 +1,123 @@ +const emailInput = document.getElementById("emailInput"); +const nicknameInput = document.getElementById("nicknameInput"); +const passwordInput = document.getElementById("passwordInput"); +const passwordConfirmInput = document.getElementById("passwordConfirmInput"); +const signupButton = document.getElementById("signup-button"); + +const emailError = document.getElementById("emailError"); +const nicknameError = document.getElementById("nicknameError"); +const passwordError = document.getElementById("passwordError"); +const passwordConfirmError = document.getElementById("passwordConfirmError"); + +/* 이메일 정규표현식 */ +const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + +/* 유효성 상태 */ +let isEmailValid = false; +let isNicknameValid = false; +let isPasswordValid = false; +let isPasswordMatch = false; + +/* 📌 유효성 검사 함수 */ +const validateEmail = () => { + const value = emailInput.value.trim(); + if (!value) { + emailInput.classList.add("error"); + emailError.textContent = "이메일을 입력해주세요."; + emailError.style.display = "block"; + isEmailValid = false; + } else if (!emailPattern.test(value)) { + emailInput.classList.add("error"); + emailError.textContent = "잘못된 이메일 형식입니다."; + emailError.style.display = "block"; + isEmailValid = false; + } else { + emailInput.classList.remove("error"); + emailError.style.display = "none"; + isEmailValid = true; + } +}; + +const validateNickname = () => { + const value = nicknameInput.value.trim(); + if (!value) { + nicknameInput.classList.add("error"); + nicknameError.textContent = "닉네임을 입력해주세요."; + nicknameError.style.display = "block"; + isNicknameValid = false; + } else { + nicknameInput.classList.remove("error"); + nicknameError.style.display = "none"; + isNicknameValid = true; + } +}; + +const validatePassword = () => { + const value = passwordInput.value.trim(); + if (!value) { + passwordInput.classList.add("error"); + passwordError.textContent = "비밀번호를 입력해주세요."; + passwordError.style.display = "block"; + isPasswordValid = false; + } else if (value.length < 8) { + passwordInput.classList.add("error"); + passwordError.textContent = "비밀번호를 8자 이상 입력해주세요."; + passwordError.style.display = "block"; + isPasswordValid = false; + } else { + passwordInput.classList.remove("error"); + passwordError.style.display = "none"; + isPasswordValid = true; + } +}; + +const validatePasswordConfirm = () => { + const value = passwordConfirmInput.value.trim(); + if (value !== passwordInput.value.trim()) { + passwordConfirmInput.classList.add("error"); + passwordConfirmError.textContent = "비밀번호가 일치하지 않습니다."; + passwordConfirmError.style.display = "block"; + isPasswordMatch = false; + } else { + passwordConfirmInput.classList.remove("error"); + passwordConfirmError.style.display = "none"; + isPasswordMatch = true; + } +}; + +/* 📌 입력 변경 시 실시간 검증 */ +emailInput.addEventListener("focusout", () => { + validateEmail(); + updateButtonState(); +}); + +nicknameInput.addEventListener("focusout", () => { + validateNickname(); + updateButtonState(); +}); + +passwordInput.addEventListener("focusout", () => { + validatePassword(); + updateButtonState(); +}); + +passwordConfirmInput.addEventListener("focusout", () => { + validatePasswordConfirm(); + updateButtonState(); +}); + +/* 📌 유효성 검사 후 버튼 활성화 체크 */ +const updateButtonState = () => { + if (isEmailValid && isNicknameValid && isPasswordValid && isPasswordMatch) { + signupButton.disabled = false; + } else { + signupButton.disabled = true; + } +}; + +/* 📌 회원가입 버튼 클릭 시 페이지 이동 */ +signupButton.addEventListener("click", () => { + if (isEmailValid && isNicknameValid && isPasswordValid && isPasswordMatch) { + window.location.href = "./login.html"; + } +}); diff --git a/login.html b/login.html index 6cdbef47..a8c4c62d 100644 --- a/login.html +++ b/login.html @@ -43,6 +43,7 @@
+
+ + - + + diff --git a/styles/signup&loginpage/login.css b/styles/signup&loginpage/login.css index 3f3ffcbe..d3e5e002 100644 --- a/styles/signup&loginpage/login.css +++ b/styles/signup&loginpage/login.css @@ -210,4 +210,8 @@ body { text-align: center; margin-top: 16px; } + + #togglePassword { + top: 41%; + } } diff --git a/styles/signup&loginpage/signup.css b/styles/signup&loginpage/signup.css index 1c1571fa..49d87b60 100644 --- a/styles/signup&loginpage/signup.css +++ b/styles/signup&loginpage/signup.css @@ -39,6 +39,25 @@ body { } /* 인풋 스타일 */ +.password-wrapper { + position: relative; + width: 640px; +} + +#togglePassword { + position: absolute; + right: 16px; + top: 50%; + transform: translateY(-50%); + width: 24px; + height: 24px; + cursor: pointer; + opacity: 0.6; +} +#togglePassword:hover { + opacity: 1; +} + .login-input { width: 640px; height: 56px; @@ -50,8 +69,26 @@ body { padding-bottom: 16px; } +.login-input:focus { + border-color: #3692ff; + outline: none; + box-shadow: 0 0 5px rgba(74, 144, 226, 0.5); +} + +/* 에러 메시지 스타일 */ +.error-message { + color: #f74747; + font-size: 14px; + margin-top: 8px; +} + +/* 에러 발생 시 input 스타일 */ +.login-input.error { + border: 1px solid #f74747 !important; +} + input::placeholder { - color: #9ca3af; /* 연한 회색 */ + color: #9ca3af; font-size: 16px; } @@ -176,9 +213,10 @@ input::placeholder { max-width: 400px; } - /* 비밀번호 wrapper 설정 */ + /* 비밀번호 input과 아이콘 정렬 */ .password-wrapper { display: flex; + justify-content: space-between; align-items: center; width: 100%; max-width: 400px; @@ -198,4 +236,7 @@ input::placeholder { width: 100%; max-width: 400px; } + #togglePassword { + top: 41%; + } } From 3c309985e6954c960088189ea8e23dd1f2b23b16 Mon Sep 17 00:00:00 2001 From: BasicKTW Date: Fri, 16 May 2025 13:07:25 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=EC=8A=A4=ED=94=84=EB=A6=B0?= =?UTF-8?q?=ED=8A=B8=20=EB=AF=B8=EC=85=98=204=20=EC=8B=AC=ED=99=94=20?= =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascript/login&signuppage/login.js | 20 +++++++++++++++ javascript/login&signuppage/signup.js | 35 +++++++++++++++++++++++++++ signup.html | 2 +- styles/signup&loginpage/login.css | 5 ++++ styles/signup&loginpage/signup.css | 5 ++-- 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/javascript/login&signuppage/login.js b/javascript/login&signuppage/login.js index 623c8da7..a9af9dda 100644 --- a/javascript/login&signuppage/login.js +++ b/javascript/login&signuppage/login.js @@ -3,6 +3,14 @@ const emailError = document.getElementById("emailError"); const passwordInput = document.getElementById("passwardinput"); const passwordError = document.getElementById("passwordError"); const loginButton = document.getElementById("loginButton"); +const togglePassword = document.getElementById("togglePassword"); + +/* 이미지 파일 경로 설정 */ +const eyeOpenSrc = "./images/anyicons/passwardeye.svg"; +const eyeSlashSrc = "./images/anyicons/passwardcancel.svg"; + +/* 초기 상태 설정 */ +let isPasswordVisible = false; /* 이메일 정규표현식 */ const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; @@ -70,3 +78,15 @@ loginButton.addEventListener("click", () => { window.location.href = "/items"; } }); + +/* 클릭 이벤트 */ +togglePassword.addEventListener("click", () => { + isPasswordVisible = !isPasswordVisible; + if (isPasswordVisible) { + passwordInput.type = "text"; + togglePassword.src = eyeOpenSrc; + } else { + passwordInput.type = "password"; + togglePassword.src = eyeSlashSrc; + } +}); diff --git a/javascript/login&signuppage/signup.js b/javascript/login&signuppage/signup.js index 2cbda72f..627fec0d 100644 --- a/javascript/login&signuppage/signup.js +++ b/javascript/login&signuppage/signup.js @@ -9,6 +9,17 @@ const nicknameError = document.getElementById("nicknameError"); const passwordError = document.getElementById("passwordError"); const passwordConfirmError = document.getElementById("passwordConfirmError"); +const togglePassword = document.getElementById("togglePassword"); +const togglePasswordConfirm = document.getElementById("togglePasswordConfirm"); + +/* 이미지 파일 경로 설정 */ +const eyeOpenSrc = "./images/anyicons/passwardeye.svg"; +const eyeSlashSrc = "./images/anyicons/passwardcancel.svg"; + +/* 초기 상태 */ +let isPasswordVisible = false; +let isPasswordConfirmVisible = false; + /* 이메일 정규표현식 */ const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; @@ -18,6 +29,30 @@ let isNicknameValid = false; let isPasswordValid = false; let isPasswordMatch = false; +/* 비밀번호 보이기/숨기기 토글 */ +togglePassword.addEventListener("click", () => { + isPasswordVisible = !isPasswordVisible; + if (isPasswordVisible) { + passwordInput.type = "text"; + togglePassword.src = eyeOpenSrc; + } else { + passwordInput.type = "password"; + togglePassword.src = eyeSlashSrc; + } +}); + +/* 비밀번호 확인 보이기/숨기기 토글 */ +togglePasswordConfirm.addEventListener("click", () => { + isPasswordConfirmVisible = !isPasswordConfirmVisible; + if (isPasswordConfirmVisible) { + passwordConfirmInput.type = "text"; + togglePasswordConfirm.src = eyeOpenSrc; + } else { + passwordConfirmInput.type = "password"; + togglePasswordConfirm.src = eyeSlashSrc; + } +}); + /* 📌 유효성 검사 함수 */ const validateEmail = () => { const value = emailInput.value.trim(); diff --git a/signup.html b/signup.html index 7f56085c..d7e5e54a 100644 --- a/signup.html +++ b/signup.html @@ -93,7 +93,7 @@ passwardtoggle