Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[서지훈]sprint4 #130

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions images/icons/visible.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 6 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<header>
<a href="/"
><img
src="images/logo/panda-market-logo.svg"
src="images/logo/panda-market-logo.png"
alt="판다마켓 홈"
width="153"
/></a>
Expand Down Expand Up @@ -83,12 +83,14 @@ <h1>
</main>

<footer>
<div>©codeit - 2024</div>
<div id="footerMenu">
<div class="copyright">
<p >©codeit - 2024</p>
</div>
<div class="footerMenu">
<a href="privacy.html">Privacy Policy</a>
<a href="faq.html">FAQ</a>
</div>
<div id="socialMedia">
<div class="socialMedia">
<a
href="https://www.facebook.com/"
target="_blank"
Expand Down
23 changes: 14 additions & 9 deletions login.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,28 @@
<main class = "login-container">
<div class="logo-home">
<a href="/">
<img src="images/logo/panda-market-logo.svg" alt="판다마켓 홈" width="153"/>
<img src="images/logo/panda-market-logo.png" alt="판다마켓 홈"/>
</a>
</div>
<form method="post">

<form method="post" id="loginForm">
<div class="input-item">
<label for="email">이메일</label>
<input id="email" name="email" type="email" placeholder="이메일을 입력해주세요">
<input id="email" name="email" type="email" placeholder="이메일을 입력해주세요" required>
</div>
<div class="input-item">
<label for="password">비밀번호</label>
<div class="input-wrapper">
<input id="password" name="password" type="password" placeholder="비밀번호를 입력해주세요">
<button type="button" class="password-toggle-btn">
<img src="/images/icons/invisible.svg" alt="비밀번호 숨김 아이콘"/>
</button>
<div class = "input-container">
<input id="password" name="password" type="password" placeholder="비밀번호를 입력해주세요" required>
<button type="button" class="password-toggle-btn" id = "toggle-password">
<img src="/images/icons/invisible.svg" alt="비밀번호 숨김 아이콘"/>
</button>
</div>
<span class="error-message" id="password-error"></span>
</div>
</div>
<button class="button pill-button" type="submit">로그인</button>
<button class="button pill-button" type="submit" id="submit-button" disabled>로그인</button>
</form>

<div class="social-login">
Expand All @@ -57,5 +60,7 @@ <h3>간편 로그인하기</h3>
<a href="signup.html">회원가입</a>
</div>
</main>
<script src="scripts/loginValidation.js"></script>
<script src="scripts/login.js"></script>
</body>
</html>
25 changes: 25 additions & 0 deletions scripts/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
document.addEventListener("DOMContentLoaded",function(){
const loginForm = document.getElementById("loginForm");
const emailInput = document.getElementById("email");
const passwordInput = document.getElementById("password");
const togglePassword = document.getElementById("toggle-password");

emailInput.addEventListener("focusout", function(){
loginValidationResults.email = checkEmailValidation();
toggleSubmitButton();
});

passwordInput.addEventListener("focusout", function() {
loginValidationResults.password = checkPasswordInputValidation();
toggleSubmitButton();
});

togglePassword.addEventListener("click", function(){
togglePasswordVisibility("password", "toggle-password");
});

loginForm.addEventListener("submit", function(event) {
event.preventDefault();
window.location.href = '/items.html';
});
});
181 changes: 181 additions & 0 deletions scripts/loginValidation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
const emailInput = document.getElementById("email");
const nicknameInput = document.getElementById("nickname");
const passwordInput = document.getElementById("password");
const checkPasswordInput = document.getElementById("password-check");

const loginValidationResults = {
email: false,
password: false
};
const signupValidationResults = {
email: false,
nickname : false,
password: false,
passwordCheck : false
};

// 에러 메시지 요소 생성 함수
function createErrorMessageElement(id, message){
const errorElement = document.createElement('span');
errorElement.id = id;
errorElement.className = 'error-message';
errorElement.textContent = message;
return errorElement;
}

// 유효성 검사 실패시, 빨간색 박스 표시 함수
function errorDisplay(input, message) {
input.style.border = "1px solid #F74747";
let errorElement = document.getElementById(input.id + '-error');
if (!errorElement) {
errorElement = createErrorMessageElement(input.id + '-error', message);
input.insertAdjacentElement('afterend', errorElement);
} else {
errorElement.textContent = message;
}
errorElement.style.display = "block";
}

// 상태 초기화 함수
function errorReset(input) {
input.style.border = "none";
const errorElement = document.getElementById(input.id + '-error');
if (errorElement) {
errorElement.style.display = "none";
}
}
Comment on lines +27 to +46
Copy link
Collaborator

Choose a reason for hiding this comment

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

공통된 로직을 잘 뽑아서 중복 코드를 없애주셨네요 ~ ! 잘 하셨습니다 !


// 이메일 형식을 검사하는 함수 (간단한 예시)
function emailValidationText(email) {
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailPattern.test(email);
}

// 이메일 검사 함수
function checkEmailValidation(){
const isEmail = emailInput.value.trim();

if (!isEmail) {
errorDisplay(emailInput, '이메일을 입력해주세요.');
return false;
} else if (!emailValidationText(isEmail)) {
errorDisplay(emailInput, '잘못된 이메일 형식입니다.');
return false;
} else {
errorReset(emailInput);
return true;
}
}

//비밀번호 확인 함수
function checkPasswordValidation(checkPasswordInput){

const passwordInput = document.getElementById("password");
const isPassword = passwordInput.value.trim();
Copy link
Collaborator

Choose a reason for hiding this comment

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

유저의 입력값을 trim 하는것은 좋은 방법입니다 ! 센스있네요 !

const minLength = 8;

if (!isPassword) {
errorDisplay(passwordInput, '비밀번호를 입력해주세요.');
checkPasswordInput.disabled = true;
return false;
} else if (isPassword.length < minLength) {
errorDisplay(passwordInput, '비밀번호를 8자 이상 입력해주세요.');
checkPasswordInput.disabled = true;
return false;
} else {
errorReset(passwordInput);
checkPasswordInput.disabled = false;
return true;
}
}

function checkPasswordInputValidation(){

const passwordInput = document.getElementById("password");
const isPassword = passwordInput.value.trim();
const minLength = 8;

if (!isPassword) {
errorDisplay(passwordInput, '비밀번호를 입력해주세요.');
return false;
}
else if (isPassword.length < minLength) {
errorDisplay(passwordInput, '비밀번호를 8자 이상 입력해주세요.');
return false;
}
else {
errorReset(passwordInput);
return true;
}
}


// 비밀번호 일치 검사 함수
function checkPasswordMatch(){
const isPassword = passwordInput.value.trim();
const isCheckPassword = checkPasswordInput.value.trim();

if (!isPassword || !isCheckPassword) {
errorDisplay(passwordInput, "비밀번호를 입력해주세요.");
errorDisplay(checkPasswordInput, "비밀번호 확인을 입력해주세요.");
return false;
}
else if (isPassword !== isCheckPassword) {
errorDisplay(checkPasswordInput, "비밀번호가 일치하지 않습니다.");
return false;
}
else {
errorReset(passwordInput);
errorReset(checkPasswordInput);
return true;
}
}

// 닉네임 검사 함수
function checkNicknameValidation(){
const isNickname = nicknameInput.value.trim();
if (!isNickname) {
errorDisplay(nicknameInput, '닉네임을 입력해주세요.');
return false;
}
else {
errorReset(nicknameInput);
return true;
}
}

// 비밀번호 보이기 활성화 함수( 눈모양 이미지를 클릭 시, 비밀번호가 보이고, 다시 누르면 비밀번호가 보이지 않도록 )
function togglePasswordVisibility(idInput, togglebtn){
const passwordField = document.getElementById(idInput);
const toggleButton = document.getElementById(togglebtn);
const toggleIcon = toggleButton.querySelector("img");

if(passwordField.type === "password"){
passwordField.type = "text";
toggleIcon.src = "/images/icons/visible.svg";
toggleButton.alt = "비밀번호 보이기";
}
else{
passwordField.type = "password";
toggleIcon.src = "/images/icons/invisible.svg";
toggleButton.alt = "비밀번호 숨기기";
}
}

// 버튼 활성화 함수( 모든 값이 들어있을 경우에 버튼 활성화, 아닐땐 비활성화 )
function toggleSubmitButton() {
const submitButton = document.getElementById("submit-button");
const loginAllValid = Object.values(loginValidationResults).every(value => value === true);
const signUpAllValid = Object.values(signupValidationResults).every(value => value === true);

if (loginAllValid) {
submitButton.removeAttribute("disabled");
}
else if(signUpAllValid){
submitButton.removeAttribute("disabled");
}
else {
submitButton.setAttribute("disabled", "disabled");
}
}
Comment on lines +166 to +180
Copy link
Collaborator

Choose a reason for hiding this comment

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

toggleSubmitButton이 로그인 버튼과 회원가입 버튼에 각각 사용되네요. 그것을 if문으로 구분짓고 있습니다. 제 생각에는 로그인 페이지를 위한 버튼, 회원가입 페이지를 위한 버튼 각각 함수를 따로 만드는게 낫다고 생각합니다.

함수는 하나의 책임만을 가지는게 낫습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

그럼 따로 분리해서 동작하도록 설계해보겠습니다!


37 changes: 37 additions & 0 deletions scripts/signup.js
Copy link
Collaborator

Choose a reason for hiding this comment

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

input 이벤트일때 에러메세지를 지워주면 좀 더 나은 UX가 될 것 같습니다 !

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
document.addEventListener("DOMContentLoaded",function(){
Copy link
Collaborator

Choose a reason for hiding this comment

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

스크립트 태그가 제일 아래에 있어서 DOM이 모두 로드된 후에 자바스크립트가 실행되긴 하지만 그래도 이렇게 작성해주시면 센스있는 코드가 되는것 같습니다 !

const signupForm = document.getElementById("signupForm");
const emailInput = document.getElementById("email");
const nicknameInput = document.getElementById("nickname");
const passwordInput = document.getElementById("password");
const checkPasswordInput = document.getElementById("password-check");
const togglePassword = document.getElementById("toggle-password");
const checkTogglePassword = document.getElementById("check-toggle-password");

emailInput.addEventListener("focusout", function(){
loginValidationResults.email = checkEmailValidation();
toggleSubmitButton();
Copy link
Collaborator

Choose a reason for hiding this comment

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

toggleSubmitButton이 중복되어 등장을 하네요. form 태그에 input 이벤트 핸들러를 초기화시켜놓으면 어떨까요? 그러면 자식 태그에서 발생하는 input 이벤트를 버블링 페이즈에서 잡아서 button을 활성화 시킬지 검사 할 수 있을 것 같아요.

테스트해봤는데 자식 태그에서 input 이벤트 발생시 로그 확인 할 수 있어요.

  signupForm.addEventListener("input", (event) => {
      console.log("captured");
    });

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

최대한 함수 여러개 쓰는 중복을 배재 시킬려고 했는데, 초기화를 생각 못했네요ㅠㅠ 한번 수정해보도록 하겠습니다!

});
nicknameInput.addEventListener("focusout", function(){
loginValidationResults.nickname = checkNicknameValidation();
Copy link
Collaborator

Choose a reason for hiding this comment

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

const signupValidationResults = {
  email: false,
  nickname: false,
  password: false,
  passwordCheck: false,
};

해당 객체를 sign up 페이지에서 사용하시려고 정의하신것 같은데 loginValidation 객체를 사용하셨네요.
혹시 어떤 이유에서일까요?

제 생각에는 이렇게 전역변수를 사용하는것은 좋지 않은 것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

기본 flag를 초기화 해서 저장 해놓은 다음, 에러 메시지가 발생하지 않을때, true 변경해 그 값을 signupValidationResults에 하나하나 저장해서, 최종적으로 모든 값이 true일때, 버튼이 활성화 되는 형태로 구성했습니다!

toggleSubmitButton();
});
passwordInput.addEventListener("focusout", function() {
loginValidationResults.password = checkPasswordValidation(checkPasswordInput);
toggleSubmitButton();
});
checkPasswordInput.addEventListener("focusout", function() {
loginValidationResults.passwordCheck = checkPasswordMatch();
toggleSubmitButton();
});
togglePassword.addEventListener("click", function(){
togglePasswordVisibility("password", "toggle-password");
});
checkTogglePassword.addEventListener("click", function(){
togglePasswordVisibility("password-check", "check-toggle-password");
});

signupForm.addEventListener("submit", function(event) {
event.preventDefault();
window.location.href = '/login.html';
});
});
29 changes: 19 additions & 10 deletions signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<img src="images/logo/panda-market-logo.svg" alt="판다마켓 홈"/>
</a>
</div>
<form method="post">
<form method="post" id="signupForm">
<div class="input-item">
<label for="email">이메일</label>
<input id="email" name="email" type="email" placeholder="이메일을 입력해주세요">
Expand All @@ -36,23 +36,30 @@
<div class="input-item">
<label for="password">비밀번호</label>
<div class="input-wrapper">
Copy link
Collaborator

Choose a reason for hiding this comment

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

input-wrapper 태그의 CSS 스타일을 모두 없애도 아무런 변화가 일어나지 않는데 그렇다면 이 div를 없애도 되지 않을까요? 어떻게 생각하세요 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

flex-direction : column으로 배치 시키면 좋겠다 싶어서 넣었는데, 다시 확인해보니깐 없어도 동작이 그대로 되네요...ㅎ 특별하게 크게 동작하는거 같지 않아서 빼도 괜찮을거같습니다!!

<input id="password" name="password" type="password" placeholder="비밀번호를 입력해주세요">
<button type="button" class="password-toggle-btn">
<img src="/images/icons/invisible.svg" alt="비밀번호 숨김 아이콘">
</button>
<div class="input-container">
<input id="password" name="password" type="password" placeholder="비밀번호를 입력해주세요">
<button type="button" class="password-toggle-btn" id = "toggle-password">
<img src="/images/icons/invisible.svg" alt="비밀번호 숨김 아이콘"/>
</button>
</div>
</div>
<span class="error-message" id="password-error"></span>
</div>

<div class="input-item">
<label for="password-check">비밀번호 확인</label>
<div class="input-wrapper">
<input id="password-check" name="password-check" type="password" placeholder="비밀번호를 다시 한 번 입력해주세요">
<button type="button" class="password-toggle-btn">
<img src="/images/icons/invisible.svg" alt="비밀번호 숨김 아이콘">
</button>
<div class="input-container">
<input id="password-check" name="password-check" type="password" placeholder="비밀번호를 다시 한 번 입력해주세요" disabled>
<button type="button" class="password-toggle-btn" id = "check-toggle-password">
<img src="/images/icons/invisible.svg" alt="비밀번호 숨김 아이콘"/>
</button>
</div>
</div>
<span class="error-message" id="password-check-error"></span>
</div>
<button class="button pill-button" type="submit">회원가입</button>

<button class="button pill-button" type="submit" id="submit-button" disabled>회원가입</button>
</form>

<div class="social-login">
Expand All @@ -72,5 +79,7 @@ <h3>간편 로그인하기</h3>
<a href="login.html">로그인</a>
</div>
</main>
<script src="scripts/loginValidation.js"></script>
<script src="scripts/signup.js"></script>
</body>
</html>
Loading
Loading