Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7bdaf43
refactor: 폴더 구조 변경 및 모듈화 적용
0Hyunn Mar 15, 2025
bf151e2
feat: 이메일, 패스워드 에러 메세지 p태그 추가 및 로그인 버튼 ID 추가
0Hyunn Mar 16, 2025
c4c4758
fix: 로그인 버튼 hover 기능, pointer 기능 삭제
0Hyunn Mar 16, 2025
7068044
feat: 로그인 유효성 검사 추가
0Hyunn Mar 16, 2025
f61e76f
fix: 로그인/회원 가입 버튼 스타일 해제
0Hyunn Mar 16, 2025
f38233c
refactor: 코드 정리 및 리팩토링
0Hyunn Mar 16, 2025
04cd035
feat: 이메일/비밀번호 에러 메세지 p태그 추가
0Hyunn Mar 16, 2025
69896ca
chore: pages 폴더 내 불필요한 파일 삭제(css)
0Hyunn Mar 16, 2025
aad8299
refactor: 케밥케이스로 파일명 수정
0Hyunn Mar 16, 2025
e371fa5
refactor: 파일 이름 변경으로 인한 기존 파일 삭제
0Hyunn Mar 16, 2025
3af9d05
feat: 로그인/회원 가입 유효성 검사 기능 추가 및 공통 js 추가
0Hyunn Mar 16, 2025
4bf098e
refactor: 유효성 검사 실패 시 error color 추가
0Hyunn Mar 16, 2025
e6508d5
fix: js명 수정함에 따른 파일명 수정
0Hyunn Mar 16, 2025
8b61b84
feat: 에러 p태그 추가
0Hyunn Mar 16, 2025
8d71afc
fix: 간편 로그인 섹션을 form 외부로 이동하여 구조 개선
0Hyunn Mar 17, 2025
a0c7796
fix: 로그인/회원가입 버튼이 입력 없이 활성화되는 문제 해결
0Hyunn Mar 17, 2025
9854b69
chore: 오픈 그래프 썸네일 이미지 파일명 변경
0Hyunn Mar 17, 2025
028512e
feat: signup, login 페이지에 오픈 그래프 태그 추가
0Hyunn Mar 17, 2025
2a2a0eb
fix: 불필요한 공백 제거
0Hyunn Mar 17, 2025
c49f3c2
fix: 불필요한 min-width 삭제
0Hyunn Mar 17, 2025
6bd545e
chore: 오픈 그래프 메타 태그의 배포 링크 업데이트
0Hyunn Mar 17, 2025
963dc4f
refactor: 주석 삭제
0Hyunn Mar 17, 2025
31aec70
refactor: 불필요한 주석 삭제
0Hyunn Mar 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions css/account.css → auth/account.css
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ body {
color: #3692ff;
}

/* 로그인/회원가입 버튼 */
.form button {
/* 로그인/회원가입 버튼 auth-button */
.auth-button {
width: 100%;
height: 56px;
background-color: #9ca3af;
Expand All @@ -101,14 +101,10 @@ body {
font-weight: 600;
border: none;
border-radius: 25px;
cursor: pointer;
/* cursor: pointer; */
margin-top: 10px;
}

.form button:hover {
background-color: #3578e5;
}

/* 간편 로그인 배치 */
.easy-login {
display: flex;
Expand Down Expand Up @@ -166,9 +162,13 @@ body {
font-size: 1.4rem;
}

.input-error {
border: 1.5px solid #f74747 !important;
}

/* 태블릿과 PC에서는 동일한 스타일을 유지하므로 별도 스타일 변경 없음 */
/* 아이패드 에어를 기준으로 구현하였습니다. (820 x 1180) */
@media (min-width: 768px) and (max-width: 1199px) {
@media (max-width: 1199px) {
}

/* 모바일 반응형 구현 */
Expand Down Expand Up @@ -198,7 +198,7 @@ body {
width: 100%;
}

.form button {
.auth-button {
width: 100%;
}

Expand Down
68 changes: 68 additions & 0 deletions auth/login-validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { emailInput, passwordInput, emailPattern, emailError, passwordError, loginBtn, isEmailValid, isPasswordValid } from "./validation-common.js";

// 이메일 유효성 검사 함수
const emailCheck = () => {
// 이메일 값 공백 제거 후 가져오기.
const emailValue = emailInput.value.trim();
Comment on lines +5 to +6
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 제안
주석을 다는 것은 좋은 습관입니다. 다만 주석 또한 읽어야 하는 정보라 중복되지 않는 내용을 입력해주시는 것이 가독성면에서 더 좋아요.
지금 주석은 아래 trim 메소드를 통해 파악할 수 있는 내용이라 없어도 될 것 같습니다~

isEmailValid.value = false;

if (emailValue === "") {
emailError.textContent = "이메일을 입력해주세요.";
emailError.style.display = "block";
emailInput.classList.add("input-error");
} else if (!emailPattern.test(emailValue)) {
emailError.textContent = "잘못된 이메일 형식입니다.";
emailError.style.display = "block";
emailInput.classList.add("input-error");
} else {
emailError.style.display = "none";
emailInput.classList.remove("input-error");
isEmailValid.value = true;
}

loginBtnToggle();
};

// 패스워드 유효성 검사 함수
const passwordCheck = () => {
const passwordValue = passwordInput.value.trim();
isPasswordValid.value = false;

if (passwordValue === "") {
passwordError.textContent = "비밀번호를 입력해주세요.";
passwordError.style.display = "block";
passwordInput.classList.add("input-error");
} else if (passwordValue.length < 8) {
passwordError.textContent = "비밀번호를 8자 이상 입력해주세요.";
passwordError.style.display = "block";
passwordInput.classList.add("input-error");
} else {
passwordError.style.display = "none";
passwordInput.classList.remove("input-error");
isPasswordValid.value = true;
}

loginBtnToggle();
};

// 이메일, 패스워드 유효성 검사에 따른 로그인 버튼 활성화 함수
const loginBtnToggle = () => {
if (isEmailValid.value && isPasswordValid.value) {
loginBtn.style.backgroundColor = "#3578e5";
loginBtn.style.cursor = "pointer";
loginBtn.disabled = false;
} else {
loginBtn.style.backgroundColor = "#9ca3af";
loginBtn.style.color = "#f3f4f6";
loginBtn.style.cursor = "not-allowed";
loginBtn.disabled = true;
}
Comment on lines +49 to +59
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 제안
해당 함수의 조건부분만 제외하면 signup-validation.js 파일의 signupBtnToggle과 동일한 함수네요~
해당 함수를 한번만 정의해서 두 파일에서 같이 사용할 수 있게 하시면 더 좋을 것 같아요~

이는 다른 로직들도 동일합니다~ 같은 로직의 경우 하나를 재사용하는 것이 유지보수 측면에서도 좋으니 account.css를 만드셨던 것처럼 두 파일의 중복을 줄이는 법도 고민해보세요~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 피드백 감사합니다. 저도 구현하면서 두 파일의 동일한 함수가 사용 되고 있어 이를 한번만 정의 해서 import하는 방식을 고민했는데 알려주셔서 감사합니다!!! 🔥🔥

};

// focusout 이벤트
emailInput.addEventListener("focusout", emailCheck);
passwordInput.addEventListener("focusout", passwordCheck);

// 초기 로그인 버튼 비활성화
loginBtn.disabled = true;
loginBtn.style.cursor = "not-allowed";
100 changes: 100 additions & 0 deletions auth/signup-validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {
emailInput,
nameInput,
passwordInput,
passwordCheckInput,
emailPattern,
emailError,
passwordError,
passwordCheckError,
signupBtn,
isEmailValid,
isPasswordValid,
isPasswordCheckValid,
} from "./validation-common.js";

// 이메일 유효성 검사 함수
const emailCheck = () => {
// 이메일 값 공백 제거 후 가져오기.
const emailValue = emailInput.value.trim();
isEmailValid.value = false;

if (emailValue === "") {
emailError.textContent = "이메일을 입력해주세요.";
emailError.style.display = "block";
emailInput.classList.add("input-error");
} else if (!emailPattern.test(emailValue)) {
emailError.textContent = "잘못된 이메일 형식입니다.";
emailError.style.display = "block";
emailInput.classList.add("input-error");
} else {
emailError.style.display = "none";
emailInput.classList.remove("input-error");
isEmailValid.value = true;
}

signupBtnToggle();
};

// 패스워드 유효성 검사 함수
const passwordCheck = () => {
const passwordValue = passwordInput.value.trim();
isPasswordValid.value = false;

if (passwordValue === "") {
passwordError.textContent = "비밀번호를 입력해주세요.";
passwordError.style.display = "block";
passwordInput.classList.add("input-error");
} else if (passwordValue.length < 8) {
passwordError.textContent = "비밀번호를 8자 이상 입력해주세요.";
passwordError.style.display = "block";
passwordInput.classList.add("input-error");
} else {
passwordError.style.display = "none";
passwordInput.classList.remove("input-error");
isPasswordValid.value = true;
}

passwordDblCheck(); // 비밀번호 확인 후, 비밀번호 수정 시 이를 감지 하지 못해서 추가. (즉시 검사하는 함수)
signupBtnToggle();
};

const passwordDblCheck = () => {
const passwordCheckValue = passwordCheckInput.value.trim();
const passwordValue = passwordInput.value.trim();
isPasswordCheckValid.value = false;

if (passwordCheckValue !== passwordValue) {
passwordCheckError.textContent = "비밀번호가 일치하지 않습니다.";
passwordCheckInput.classList.add("input-error");
passwordCheckError.style.display = "block";
} else {
passwordCheckError.style.display = "none";
passwordCheckInput.classList.remove("input-error");
isPasswordCheckValid.value = true;
}

signupBtnToggle();
};

const signupBtnToggle = () => {
if (isEmailValid.value && isPasswordValid.value && isPasswordCheckValid.value) {
signupBtn.style.backgroundColor = "#3578e5";
signupBtn.style.cursor = "pointer";
signupBtn.disabled = false;
} else {
signupBtn.style.backgroundColor = "#9ca3af";
signupBtn.style.color = "#f3f4f6";
signupBtn.style.cursor = "not-allowed";
signupBtn.disabled = true;
}
};

// focusout 이벤트
emailInput.addEventListener("focusout", emailCheck);
passwordInput.addEventListener("focusout", passwordCheck);
passwordCheckInput.addEventListener("focusout", passwordDblCheck);

// 회원가입 버튼 요소 초기 상태 설정
signupBtn.style.cursor = "not-allowed";
signupBtn.disabled = true;
1 change: 1 addition & 0 deletions js/login_password_showing.js → auth/toggle-password.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @param {input태그 id} inputId
* @param {i 태그 자신} iconElement
*/

const togglePasswordVisibility = (inputId, iconElement) => {
const passwordInput = document.getElementById(inputId);
const isPassword = passwordInput.type === "password";
Expand Down
25 changes: 25 additions & 0 deletions auth/validation-common.js
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 칭찬
이름도 공통된 룰에 따라 명명되어 있고 정리도 아주 잘 되어 있네요 👍

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 공통 입력 요소 ( 이메일, 비밀번호)
export const emailInput = document.querySelector("#form-email");
export const passwordInput = document.querySelector("#form-password");

// 회원가입 전용 입력 요소 (닉네임, 비밀번호 확인)
export const nameInput = document.querySelector("#form-name");
export const passwordCheckInput = document.querySelector("#form-password-check");

// 에러 메시지 요소 (이메일, 패스워드, 패스워드 확인)
export const emailError = document.querySelector("#email-error");
export const passwordError = document.querySelector("#password-error");
export const passwordCheckError = document.querySelector("#password-check-error");

// 로그인 및 회원가입 버튼
export const loginBtn = document.querySelector("#btn-login");
export const signupBtn = document.querySelector("#btn-signup");

// 유효성 검사 패턴
export const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 제안
이러한 패턴을 정규식이라고 합니다. 정규식을 작성하시면 이를 테스트해서 필요한 값들을 다 판별할 수 있는지 확인해보시는 것이 좋습니다~ 작성하신 것처럼 이메일 패턴 체크나 비밀번호 조건 체크할 때 사용합니다~ 변수가 많아지면 해당 변수들만 따로 분리하셔도 좋습니다~

regexr


// 유효성 검사 상태 변수
// 원시타입으로 내보내면 에러가 났음.. 객체로 관리
export let isEmailValid = { value: false };
export let isPasswordValid = { value: false };
export let isPasswordCheckValid = { value: false };
Comment on lines +23 to +25
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗️ 수정요청
위와 달리 이러한 변수들은 let으로 선언된 변경 및 재할당이 가능한 변수입니다.
한 파일에서 관리하기보다 사용하는 곳에서 선언해 관리하는 것이 흐름 파악 및 유지보수 측면에서 더 좋을 것 같습니다~

1 change: 1 addition & 0 deletions css/common.css → common/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
--white: #ffffff;
--background: #cfe5ff;
--skyblue: #e6f2ff;
--error-red: #f74747;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 제안
에러는 일반적으로 빨간색이므로 해당 색상변수명을 --error로 해도 될 것 같습니다~

}

html {
Expand Down
78 changes: 0 additions & 78 deletions html/login.html

This file was deleted.

File renamed without changes
Loading
Loading