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 #106

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
33 changes: 23 additions & 10 deletions login/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,43 @@
</head>
<body>
<header>
<a class="home-logo" href="/"><img class="header-img" src=../imgs/signup_logo.png></a>
<a class="home-logo" href="/"><img class="header-img" src=../imgs/signup_logo.png alt="홈으로"></a>
</header>
<main>
<div class="container">
<form>
<label for="email">이메일</label>
<div class="pseudo-form">
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기는 가짜 폼태그보다 진짜 폼태그를 써주는게 어떨까요?

Suggested change
<div class="pseudo-form">
<form class="signup-form">


<label for="email">
이메일
<span class="email-empty error-message hidden">이메일을 입력해주세요.</span>
<span class="email-wrong-format error-message hidden">잘못된 이메일 형식입니다.</span>
</label>
<input id="email" name="email" class="text-input" placeholder="이메일을 입력해주세요">
<label for="password">비밀번호</label>

Comment on lines +17 to +23
Copy link
Collaborator

Choose a reason for hiding this comment

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

제 생각에는 에러메세지는 의미적으로 라벨과 상관이 없다고 생각합니다.

재헌님께서 에러메세지를 position: absolute로 선언하고 라벨을 position: relative를 선언 해 줌으로서 에러메세지 위치를 잡으려고 라벨안에 두신것 같은데 이러한 의도가 맞을까요?

그렇다면 라벨과 인풋을 div로 감싸는 마크업을 더 낫다고 생각이 듭니다.

<div>
            <label for="email"> 이메일 </label>
            <input
              id="email"
              name="email"
              class="text-input"
              placeholder="이메일을 입력해주세요"
            />
            <span class="email-empty error-message hidden"
              >이메일을 입력해주세요.</span
            >
            <span class="email-wrong-format error-message hidden"
              >잘못된 이메일 형식입니다.</span
            >
</div>

<label for="password">
비밀번호
<span class="password-empty error-message hidden">비밀번호를 입력해주세요.</span>
<span class="password-wrong-format error-message hidden">비밀번호를 8자 이상 입력해주세요.</span>
</label>
<div class="password-field">
<input id="password" name="password" class="text-input" type="password" placeholder="비밀번호를 입력해주세요">
<img src="../imgs/EyeIconSlashed.png" class="password-visibility-icon">
<img src="../imgs/EyeIconSlashed.png" class="password-visibility-icon" alt="패스워드 보이기">

</div>
<button class="doit">로그인</button>
<button class="login action-button">로그인</button>

<div class="easy-login">
<span>간편 로그인하기</span>
<div class="media-icons">
<a href="https://www.google.com/"><img src="../imgs/Component2.png"></a>
<a href="https://www.kakaocorp.com/page/"><img src="../imgs/Component3.png"></a>
<a href="https://www.google.com/"><img src="../imgs/Component2.png" alt="Google"></a>
<a href="https://www.kakaocorp.com/page/"><img src="../imgs/Component3.png" alt="Kakao"></a>
</div>
</div>
</form>

</div>
<span class=signup-link>판다마켓이 처음이신가요? <a href="/signup">회원가입</a></span>
</div>
</main>
<script type="module" src="../scripts/signupIndex.js"></script>
<script type="module" src="../scripts/signupEventHandler.js"></script>
</body>
</html>
24 changes: 14 additions & 10 deletions scripts/buttonValidationCheck.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
// 조건이 충족되면 회색 버튼을 파란색으로 보이게 합니다.
// 조건은 validChecklist에 배열로 각 함수값들을 저장해 확인합니다.
// validChecklist의 원소들이 모두 true라면 버튼을 파란색으로 만듭니다.
// 버튼 작동 조건을 최종적으로 확인하는 스크립트이기 때문에 버튼이 동작하는데 필요한 요건들을 확인하는 함수들은 모두 여기에서 실행합니다.

const btn = document.querySelector('.doit');
// 모든 input에 값이 있고, 모든 input에 errored 클래스가 없을때 작동합니다.
// 조건을 만족하면 버튼에 valid 클래스가 추가돼 파란색이 되고 disabled가 해제됩니다.

import { inputs, btn } from "./constLib.js";
import filledInputCheck from "./filledInputsCheck.js";
import passwordVerifiedCheck from "./passwordVerifiedCheck.js";

export default function btnValidCheck() {
const validChecklist = [filledInputCheck(), passwordVerifiedCheck()]; // 함수가 호출될때마다 배열 안의 함수들을 실행합니다.

validChecklist.every((e) => e === true)
? btn.classList.add('valid')
: btn.classList.remove('valid');
const isValid = [...inputs].every(e => !e.classList.contains('errored')) && filledInputCheck(); // 모든 input에 errored 클래스가 없다 && 모든 input에 값이 있다
Copy link
Collaborator

Choose a reason for hiding this comment

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

every 메서드를 사용하신 점 잘하셨습니다 !


if (isValid) {
btn.classList.add('valid');
btn.disabled = false;
return;
}

btn.classList.remove('valid');
btn.disabled = true;

}
16 changes: 16 additions & 0 deletions scripts/constLib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const form = document.querySelector('.pseudo-form');
const inputs = document.querySelectorAll('input');
const btn = document.querySelector('.action-button');

const emailInput = document.querySelector('#email');
const nicknameInput = document.querySelector('#nickname');
const passwordInput = document.querySelector('#password');
const verifyPasswordInput = document.querySelector('#verify-password');

const loginPage = '/login';
const itemsPage = '/items';

const loginButtonLink = '/items';
const signupButtonLink = '/signup';

export { form, inputs, btn, emailInput, nicknameInput, passwordInput, verifyPasswordInput, loginPage, itemsPage, loginButtonLink, signupButtonLink };
21 changes: 21 additions & 0 deletions scripts/emailValidationCheck.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { emailInput, btn } from "./constLib.js";

const emailEmptyMessage = document.querySelector('.email-empty');
const emailWrongFormatMessage = document.querySelector('.email-wrong-format');

function isCorrectEmailFormat(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
Comment on lines +6 to +9
Copy link
Collaborator

Choose a reason for hiding this comment

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

정규 표현식을 사용하신점도 좋았고 테스트하는 로직을 함수로 감싸주신점도 잘 하셨습니다 !


export default function emailValidationCheck(event) {

if( event.target !== emailInput ) return;

emailInput.classList.toggle('errored', !emailInput.value || !isCorrectEmailFormat(emailInput.value));
emailInput.classList.toggle('correct', emailInput.value && isCorrectEmailFormat(emailInput.value));

emailEmptyMessage.classList.toggle('hidden', emailInput.value);
emailWrongFormatMessage.classList.toggle('hidden', !emailInput.value || isCorrectEmailFormat(emailInput.value));

}
11 changes: 5 additions & 6 deletions scripts/filledInputsCheck.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// 모든 input에 내용이 있는지 체크합니다: 내용이 있다면 (모든 input에 placeholder가 없을 때) true를, 비어있다면 false를 반환합니다.
// 모든 input에 내용이 있는지 체크합니다: 내용이 있다면 true를, 비어있다면 false를 반환합니다.

const inputs = document.querySelectorAll('input');
import { inputs } from "./constLib.js";

export default function filledInputCheck() {
const hiddenPlaceholders = document.querySelectorAll('input:not(:placeholder-shown)');

return hiddenPlaceholders.length === inputs.length
? true
: false;
if (!inputs || !inputs.length) return true;

return [...inputs].every( (e) => e.value !== '' );
}
4 changes: 1 addition & 3 deletions scripts/mainPageEventHandler.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { btnLink } from "./stdLib.js";

const loginPage = '/login';
const itemsPage = '/items';
import { loginPage, itemsPage } from "./constLib.js";

const loginBtn = document.querySelector('.login-button');
const itemsBtn = document.querySelector('.items-button');
Expand Down
14 changes: 14 additions & 0 deletions scripts/nicknameEmptyCheck.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { nicknameInput, btn } from "./constLib.js";

const nicknameEmptyMessage = document.querySelector('.nickname-empty');

export default function nicknameEmptyCheck(event) {

if ( !nicknameInput || event.target !== nicknameInput ) return; // 닉네임 란이 없거나 || 닉네임 란에서 발생한 이벤트가 아니라면 return

nicknameInput.classList.toggle('errored', !nicknameInput.value);
nicknameInput.classList.toggle('correct', nicknameInput.value);

nicknameEmptyMessage.classList.toggle('hidden', nicknameInput.value);

}
18 changes: 18 additions & 0 deletions scripts/passwordFormatCheck.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { passwordInput, btn } from "./constLib.js";

const passwordEmptyMessage = document.querySelector('.password-empty');
const passwordWrongFormatMessage = document.querySelector('.password-wrong-format');

const isLongEnough = (str) => str.length >= 8;
Copy link
Collaborator

Choose a reason for hiding this comment

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

로직을 이해하기 쉽게 함수로 빼신 점 잘 하셨습니다 !


export default function passwordFormatCheck(event) {

if ( event.target !== passwordInput ) return;

passwordInput.classList.toggle('errored', !passwordInput.value || !isLongEnough(passwordInput.value));
passwordInput.classList.toggle('correct', passwordInput.value && isLongEnough(passwordInput.value));

passwordEmptyMessage.classList.toggle('hidden', passwordInput.value);
passwordWrongFormatMessage.classList.toggle('hidden', !passwordInput.value || isLongEnough(passwordInput.value));

}
26 changes: 12 additions & 14 deletions scripts/passwordVerifiedCheck.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
// 회원가입 페이지에서 패스워드와 패스워드 확인 란의 내용이 같은지 체크합니다.
// 같지 않다면 패스워드 확인에 빨간 아웃라인이 나타나고 메시지가 보여집니다.
// 같다면 true를, 같지 않다면 false를 반환합니다. 패스워드 확인 란이 없다면 항상 true를 반환합니다.
// 패스워드 확인 란이 없다면 바로 return 합니다.

const passwordInput = document.querySelector('#password');
const verifyPasswordInput = document.querySelector('#verify-password');
const passwordMismatchingMsg = document.querySelector('.password-mismatching-msg');
import { passwordInput, verifyPasswordInput } from "./constLib.js";

export default function passwordVerifiedCheck() {
if (!verifyPasswordInput) return true;
const passwordMismatchingMessage = document.querySelector('.password-mismatching');

if (verifyPasswordInput.value !== passwordInput.value) {
verifyPasswordInput.classList.add('mismatching');
passwordMismatchingMsg.classList.remove('hidden');
return false;
}
export default function passwordVerifiedCheck(event) {
if ( !verifyPasswordInput || (event.target !== (verifyPasswordInput || passwordInput)) ) return; // 패스워드 확인 란이 없거나 || 패스워드 또는 패스워드 확인 란에서 발생한 이벤트가 아니라면 return

verifyPasswordInput.classList.remove('mismatching');
passwordMismatchingMsg.classList.add('hidden');
return true;
const isPasswordMatching = passwordInput.value === verifyPasswordInput.value;
const isVerifyPasswordEmpty = verifyPasswordInput.value === '';

verifyPasswordInput.classList.toggle('errored', !isPasswordMatching && !isVerifyPasswordEmpty);
verifyPasswordInput.classList.toggle('correct', isPasswordMatching && !isVerifyPasswordEmpty);

passwordMismatchingMessage.classList.toggle('hidden', isPasswordMatching || isVerifyPasswordEmpty);
}
64 changes: 0 additions & 64 deletions scripts/signup.js

This file was deleted.

43 changes: 43 additions & 0 deletions scripts/signupEventHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// import된 각 함수들을 이벤트에 지정합니다.

import toggleVisibility from "./togglePasswordVisibility.js";
import btnValidCheck from "./buttonValidationCheck.js";
import { form, btn, loginButtonLink, signupButtonLink } from "./constLib.js";
import emailValidationCheck from "./emailValidationCheck.js";
import nicknameEmptyCheck from "./nicknameEmptyCheck.js";
import passwordVerifiedCheck from "./passwordVerifiedCheck.js";
import passwordFormatCheck from "./passwordFormatCheck.js";
import { btnLink } from "./stdLib.js";

const passwordVisibilityIcons = document.querySelectorAll('.password-visibility-icon');


// 버튼 disabled 설정 - 페이지 진입 후 아무 동작도 하지 않았을때 버튼이 동작하는걸 방지합니다.
btn.disabled = true;


// 버튼 링크 설정
if (btn.classList.contains('login')) btn.addEventListener('click', () => { btnLink(loginButtonLink) });
else if (btn.classList.contains('signup')) btn.addEventListener('click', () => { btnLink(signupButtonLink) });
Comment on lines +20 to +21
Copy link
Collaborator

Choose a reason for hiding this comment

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

버튼 관련 로직을 재사용 또는 통일 시키려고 하신 노력이 보이시는것 같네요.

제 생각에는 signupEventHandler 자바스크립트 파일에는 회원가입에 관한 로직만 있는게 더 좋다고 생각합니다. 그러나 20번줄을 보면 로그인 버튼 관련 로직이 있는 것 같네요. 로그인 버튼 로직은 로그인 자바스크립트 파일에 작성해주시는게 더 좋습니다.

로직이 다른 파일에 섞이게되면 이게 스노우볼이 되어서 나중에는 관리가 힘들어진다고 생각합니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

function btnLink(ref) {
    location.href = ref;
}

export { btnLink }

btnLink의 구현체인데, 이정도로 짧은 코드는 화살표함수를 써서 인라인으로 구현하는게 어떨까요?



// 눈 이미지에 패스워드 가시성 토글 스크립트 지정
for (let each of passwordVisibilityIcons) {
each.addEventListener('click', toggleVisibility);
}


// 폼에 각 이벤트 지정

function eventFunctionsPackage(e) {

emailValidationCheck(e);
nicknameEmptyCheck(e);
passwordFormatCheck(e);
passwordVerifiedCheck(e);
btnValidCheck();

}

form.addEventListener('focusout', eventFunctionsPackage);
form.addEventListener('input', eventFunctionsPackage);
Comment on lines +42 to +43
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 부분이 요구사항과 맞지 않는 부분이 있는 것 같습니다.
요구사항에서는 focus out일때 validation을 하도록 안내가 되어있습니다.
하지만 지금 코드에서는 focus out 및 유저가 타이핑을 하는 매순간 마다 validation이 진행되고 있습니다.

focus out일때 validation을 진행하고 input 입력중일때는 에러메세지를 없애는 로직으로
focus out의 로직과 input 이벤트의 로직을 분리하는게 어떨까요?

실무에서는 재헌님이 하신 방법도 UX를 고려해서 사용하는 방법이긴 합니다만 스프린트 미션에서는 요구사항이 명시되어있어서 우선 그것을 따르는게 맞는것 같아요 ㅎㅎ

15 changes: 0 additions & 15 deletions scripts/signupIndex.js

This file was deleted.

Loading
Loading