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

[이현우] sprint3 #40

Open
wants to merge 5 commits into
base: basic-이현우
Choose a base branch
from

Conversation

gealot
Copy link
Collaborator

@gealot gealot commented Oct 6, 2024

주요 변경사항

배포 결과

이전 코드리뷰 반영

  • 미션 1~2에서 학습하지 않았던 자바스크립트를 미리 사용해도 되는지, 그 부분이 궁금하여 코드리뷰 에서 문의드렸습니다. 코드리뷰에서 설명해주신 바와 같이 RFC 5322 표준으로 정의된 이메일 정규표현식을 사용하여 validation을 반영하였습니다. ✅ 2024-10-05
  • 코드리뷰 사항을 반영하여 GTM(Google Tag Manager) 코드를 common.js 파일로 분리, 모든 페이지에서 GTM을 참조하도록 구조를 변경하였습니다. ✅ 2024-10-05
  • 코드리뷰사항을 반영하여 절대 경로로 리소스를 불러오도록 코드를 수정하였습니다. ✅ 2024-10-05
  • 코드리뷰 에서 설명해주신 바와 같이 POSIX 표준을 준수하지 않은 파일을 POSIX 표준에 맞추어 VSCode 설정을 변경(files.insertFinalNewline: true)하여 파일 저장 시 항상 마지막 줄(End of Line)이 개행되도록 설정하였습니다. ✅ 2024-10-05
  • 코드리뷰 에서 설명해주신 바와 같이 .gitignore 파일에서 필요한 부분(macOS, Windows, VSCode)만 포함하여 다시 .gitignore 파일을 구성하였습니다. ✅ 2024-10-05
  • 보다 명확하게 form의 의미를 구분하기 위해 id로 분리했었는데, 스타일시트에서는 굳이 id selector을 구분하여 작성할 필요는 없겠다는 생각이 들어 코드리뷰 사항을 반영하여 공통된 클래스(auth-form)로 구분하였습니다. ✅ 2024-10-05
  • 코드리뷰 사항을 반영하여 추후 추가될 수도 있는 컨텐츠를 고려하여 전체 선택자 대신 직접 자식 요소들(#login, auth-form, social-login, auth-prompt)을 추가하였습니다. ✅ 2024-10-05
  • 위 form 사례와 같이 코드리뷰를 반영하여 스타일은 동일하고 컨텐츠만 다른 클래스(go-signup, go-login)를 공통된 의미를 가지는 클래스(auth-prompt)로 묶었습니다. ✅ 2024-10-05
  • CSS 변수는 코드리뷰 에서처럼 별도의 스타일시트(variables.css)로 분리하였습니다. ✅ 2024-10-05
  • 코드리뷰 에서 설명해주신 바와 같이 login.js 대신 검증을 의미하는 validation.js로 변경하였습니다. ✅ 2024-10-05
  • 코드리뷰 사항을 반영하여 validation 메시지를 과도하기 일반화하지 않고 input 요소의 이벤트리스너에 맞게 메시지를 재구성(invalidNickname 등)하였습니다. ✅ 2024-10-05
  • 코드리뷰에서 각각 언급하신 showValidityMessage, getMessage 함수는 이벤트리스너 동작요건 변경으로 더 이상 사용되지 않습니다. ✅ 2024-10-05

기본 요구사항

로그인, 회원가입 페이지 공통

  • 로그인 및 회원가입 페이지의 이메일, 비밀번호, 비밀번호 확인 input에 필요한 유효성 검증 함수를 만들고 적용해 주세요. ✅ 2024-10-01
  • 이메일 input에서 focus out 할 때, 값이 없을 경우 input에 빨강색 테두리와 아래에 “이메일을 입력해주세요.” 빨강색 에러 메세지를 보입니다. ✅ 2024-10-01
  • 이메일 input에서 focus out 할 때, 이메일 형식에 맞지 않는 경우 input에 빨강색 테두리와 아래에 “잘못된 이메일 형식입니다” 빨강색 에러 메세지를 보입니다. ✅ 2024-10-01
  • 비밀번호 input에서 focus out 할 때, 값이 없을 경우 아래에 “비밀번호를 입력해주세요.” 에러 메세지를 보입니다. ✅ 2024-10-05
  • 비밀번호 input에서 focus out 할 때, 값이 8자 미만일 경우 아래에 “비밀번호를 8자 이상 입력해주세요.” 에러 메세지를 보입니다. ✅ 2024-10-05
  • input 에 빈 값이 있거나 에러 메세지가 있으면 ‘로그인’ 버튼은 비활성화 됩니다. ✅ 2024-10-05
  • input 에 유효한 값을 입력하면 ‘로그인' 버튼이 활성화 됩니다. ✅ 2024-10-05
  • 활성화된 ‘로그인’ 버튼을 누르면 “/items” 로 이동합니다 ✅ 2024-10-05

로그인 - 팝업

  • 이메일과 비밀번호를 입력하고 로그인 버튼을 누른 후, 다음 조건을 참조하여 로그인 성공 여부를 alert 메시지로 출력합니다. ✅ 2024-10-05
    • 만약 입력한 이메일이 데이터베이스(USER_DATA)에 없거나, 이메일은 일치하지만 비밀번호가 틀린 경우, '비밀번호가 일치하지 않습니다.'라는 메시지를 alert로 표시합니다. ✅ 2024-10-05
    • 만약 입력한 이메일이 데이터베이스에 존재하고, 비밀번호도 일치할 경우, “/items”로 이동합니다. ✅ 2024-10-05

회원가입 - 팝업

  • 회원가입을 위해 이메일, 닉네임, 비밀번호, 비밀번호 확인을 입력한 뒤, 회원가입 버튼을 클릭하세요. 그 후에는 다음 조건에 따라 회원가입 가능 여부를 alert로 알려주세요. ✅ 2024-10-05
    • 입력한 이메일이 이미 데이터베이스(USER_DATA)에 존재하는 경우, '사용 중인 이메일입니다'라는 메시지를 alert로 표시합니다. ✅ 2024-10-05
    • 입력한 이메일이 데이터베이스(USER_DATA)에 없는 경우, 회원가입이 성공적으로 처리되었으므로 로그인 페이지(”/login”)로 이동합니다. ✅ 2024-10-05

심화 요구사항

전체(로그인, 회원가입, 랜딩 페이지) 공통

  • 브라우저에 현재 보이는 화면의 영역(viewport) 너비를 기준으로 분기되는 반응형 디자인을 적용합니다. (참고) ✅ 2024-10-06
    • PC: 1200px 이상 ✅ 2024-10-06
    • Tablet: 744px 이상 ~ 1199px 이하 🚧 스타일 작업 완료 시 체크하겠습니다.
    • Mobile: 375px 이상 ~ 743px 이하 ✅ 2024-10-06
    • 375px 미만 사이즈의 디자인은 고려하지 않습니다. ✅ 2024-10-06

로그인, 회원가입 페이지 공통

  • Tablet 사이즈에서 내부 디자인은 PC 사이즈와 동일합니다. ✅ 2024-10-05
  • Mobile 사이즈에서 좌우 여백 16px 제외하고 내부 요소들이 너비를 모두 차지합니다. ✅ 2024-10-05
  • Mobile 사이즈에서 내부 요소들의 너비는 기기의 너비가 커지는 만큼 커지지만 400px을 넘지 않습니다. ✅ 2024-10-05
  • 비밀번호 및 비밀번호 확인 입력란에 눈 모양 아이콘 클릭 시 비밀번호 표시/숨기기 토글이 가능합니다. 기본 상태는 비밀번호 숨김으로 설정합니다. ✅ 2024-10-05

로그인 - 팝업

  • 오류 메시지 모달을 구현합니다. 모달 내 내용은 alert 메시지와 동일합니다. ✅ 2024-10-05

회원가입 - 팝업

  • 오류 메시지 모달을 구현합니다. 모달 내 내용은 alert 메시지와 동일합니다. ✅ 2024-10-05

랜딩 페이지

  • PC, Tablet 사이즈의 이미지 크기는 고정값을 사용합니다. ✅ 2024-10-06
  • Mobile 사이즈의 이미지는 좌우 여백 32px을 제외하고 이미지 영역이 꽉 차게 구현합니다. (이때 가로가 커지는 비율에 맞춰 세로도 커져야 합니다.) ✅ 2024-10-05
  • 페이스북, 카카오톡, 디스코드, 트위터 등 SNS에서 판다마켓 랜딩 페이지('/') 공유 시 미리보기를 볼 수 있도록 랜딩 페이지 메타 태그를 설정합니다. ✅ 2024-10-05
  • 미리보기에서 제목은 "판다마켓", 설명은 "일상에서 모든 물건을 거래해보세요"로 설정합니다. ✅ 2024-10-05
  • 주소와 이미지는 자유롭게 설정하세요. ✅ 2024-10-05
  • 로그인, 회원가입 페이지에 공통으로 사용하는 로직이 있다면, 반복하지 않고 공통된 로직을 모듈로 분리해 사용해 주세요. ✅ 2024-10-05
  • Mobile 사이즈 너비가 커지면, "Privacy Policy", "FAQ", "codeit-2024"이 있는 영역과 SNS 아이콘들이 있는 영역의 사이 간격이 커집니다. ✅ 2024-10-05
  • Tablet 사이즈로 작아질 때 최소 좌우 여백이 "판다마켓" 로고의 왼쪽에 여백 24px, "로그인" 버튼 오른쪽 여백 24px을 유지할 수 있도록 "판다마켓" 로고와 "로그인" 버튼의 간격이 가까워집니다. ✅ 2024-10-05
  • Mobile 사이즈로 작아질 때 최소 좌우 여백이 "판다마켓" 로고의 왼쪽에 여백 16px, "로그인" 버튼 오른쪽 여백 16px을 유지할 수 있도록 "판다마켓" 로고와 "로그인" 버튼의 간격이 가까워집니다. ✅ 2024-10-05

로그인,회원가입 validation 추가 및 반응형 디자인 추가
validation.js에서 불필요한 코드를 제거하고 스타일 일부를 정리하였습니다.
@gealot gealot requested a review from pers0n4 October 6, 2024 11:35
@gealot gealot added 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 진행 중 🏃 스프린트 미션 진행중입니다. labels Oct 6, 2024
Comment on lines +30 to +46
function createOrUpdateMetaTag(name, content, isProperty = false) {
// 표준 메타태그인지 Open Graph 메타태그인지 구별하기 위해 Property 여부를 확인
let metadata = document.querySelector(`meta[${isProperty ? 'property' : 'name'}="${name}"]`);
if (!metadata) {
metadata = document.createElement('meta');
if (isProperty) {
// Open Graph 메타태그는 property 속성을 사용
metadata.setAttribute('property', name);
} else {
// 표준 메타태그는 name 속성을 사용
metadata.name = name;
}
document.head.appendChild(metadata);
}
// 메타태그의 content 속성을 설정
metadata.content = content;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

true로 동작을 제어하는 플래그 방식의 함수가 정의되었다면, 이 경우는 아예 함수를 분리하는 게 좋을 거라는 신호일 수 있습니다.
만약 현재 상황에서 SEO를 위해 twitter cards나 schema.org 요소를 추가해야 하는 상황이 된다면 어떨까요?

Comment on lines +56 to 61
main > #logo,
main > .auth-form,
main > .social-login,
main > .auth-prompt {
flex: 0 1 40rem;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

우선 id selector로 접근하는 #logo의 경우는 굳이 main > 같은 표현을 사용할 필요는 없을 것 같네요. 나머지 클래스에 리스트 형태로 스타일을 지정하는 방식도 나쁘진 않지만, auth-form, social-login, auth-prompt가 동일한 기능을 하고 있는 부분이 있다면 해당 영역만 content-wrapper 같은 식의 재사용할 수 있는 클래스로 정의하는 것도 괜찮은 접근일 것 같습니다.

Comment on lines 235 to 245
signupForm?.addEventListener('submit', handleSignupSubmit);
loginForm?.addEventListener('submit', handleLoginSubmit);
emailInput.addEventListener('focusout', validateEmail);
// 로그인 페이지에는 닉네임 입력이 없으므로 Optional Chaining 사용
nicknameInput?.addEventListener('focusout', validateNickname);
passwordInput.addEventListener('focusout', validatePasswords);
// 비밀번호 확인 입력 시 비밀번호 validation
confirmInput?.addEventListener('input', validatePasswords);
pwToggleButtons.forEach(button => {
button.addEventListener('click', () => togglePassword(containers));
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

element에 이벤트를 할당할 때 optional chaining으로 처리하고 있는 이유가 element는 그 자체로써 HTML에 종속적인 구조를 가지고 있기 때문이죠.
그렇다면 이런 케이스는 모든 로직을 js 파일 내에서 처리하려고 하기보다는 element를 쿼리하는 부분은 제어할 수 없음을 인정하고 js 영역에서는 이벤트를 할당할 수 있는 addFormEvent 등의 함수를 정의해두고 HTML 파일 내 script 영역에서 쿼리한 element에 이벤트를 할당하는 것도 고려해볼 수 있을 것 같습니다.
사실 더 나아가면 이벤트 위임 패턴이나 작성하신 것과 비슷한 패턴으로 스크립트 내에서 이벤트를 핸들링하는 식으로 처리할 수도 있습니다. 물론 이것은 충분히 일반화가 진행되어야 한다는 전제가 따라붙지만요. 지금으로썬 단계별로 잘 개선되고 있는 것 같네요.

Comment on lines 61 to 68
setTimeout(() => {
toast.classList.remove('hide');
toast.classList.add('show');
}, 10);
setTimeout(() => {
fadeOut(toast);
isToastShow = false;
}, 1000);
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. 입력한 값이 검증 규칙에 어긋났을 때 실패 메시지를 보여주고 fadeOut시키는 게 좋은 패턴일까요? 🤔
  2. 그리고 간단한 애니메이션의 경우는 CSS의 animation을 사용하는 게 JS로 직접 처리하는 것보다는 여러모로 이롭습니다. (CSS와 JS의 분리라거나, 성능면에서라거나)

Comment on lines 136 to 192
function isPasswordValid(password) {
return password && password.length >= 8;
}

function validatePasswords(event) {
event.preventDefault();
// 비밀번호 확인 input이 존재하는지 확인
const isConfirmInputExist = !!confirmInput;

// 비밀번호와 비밀번호 확인 input이 모두 존재하고 두 값이 일치하지 않는 경우, 둘 다 data-invalid 속성 추가
const isValid = !isConfirmInputExist || passwordInput.value === confirmInput.value;
const hasValue = passwordInput.value && (!isConfirmInputExist || confirmInput.value);

passwordInput.setAttribute('data-invalid', hasValue && !isValid);
confirmInput?.setAttribute('data-invalid', hasValue && !isValid);

if (!hasValue) {
passwordInput.removeAttribute('data-invalid');
confirmInput?.removeAttribute('data-invalid');
}

// 비밀번호 확인 input이 존재하지 않는 경우, 비밀번호만 검증
const validations = [
{
condition: !passwordInput.value,
input: passwordInput,
message: validityMessage.passwordIsEmpty,
},
{
condition: !isPasswordValid(passwordInput.value),
input: passwordInput,
message: validityMessage.passwordIsTooShort,
},
{
condition: isConfirmInputExist && !confirmInput.value,
input: confirmInput,
message: validityMessage.passwordIsEmpty,
},
{
condition: isConfirmInputExist && !isPasswordValid(confirmInput.value),
input: confirmInput,
message: validityMessage.passwordIsTooShort,
},
{
condition: isConfirmInputExist && passwordInput.value !== confirmInput.value,
input: confirmInput,
message: validityMessage.passwordIsNotMatch,
},
];

// 조건, 입력값, 메세지 순서대로 순회하며 조건이 참일 경우 메세지를 띄우기
for (const { condition, input, message } of validations) {
if (condition) {
showToast(input, message);
break;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

패스워드를 검증하기 위해 많이 고민한 흔적이 드러나는 것처럼 보이네요. 하지만 몇 가지 개선할 수 있을만한 지점들이 보이는 것 같네요.
이 부분은 같이 한번 뜯어보면 좋을 것 같아서 다음 멘토링 시간에 한번 봅시다.

Copy link
Collaborator

@pers0n4 pers0n4 left a comment

Choose a reason for hiding this comment

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

안녕하세요, 현우님.
이전 미션에서 리뷰를 남겼던 부분을 반영해주셨군요! 수고하셨습니다.
노파심(?)에 한 말씀 드리자면, 제가 남기는 리뷰도 어디까지나 개인의 의견이기 때문에 제가 남긴 작성한 리뷰를 모두 반영한다는 느낌보다는 제가 미처 제대로 파악하지 못한 부분이 있을 수도 있으니 비판적으로 검토한 후에 아니라고 생각되는 부분이 있다면 추가로 논의를 진행한 후에 결정하는 것도 충분히 가능한 사안입니다.
그리고 다음부터는 커밋 단위도 신경 쓰면서 잘 나눠보시면 더 좋을 것 같습니다.

데이터와 액션과 연산을 용도에 맞게 모듈화하였습니다.
@gealot
Copy link
Collaborator Author

gealot commented Oct 9, 2024

안녕하세요, 현우님. 이전 미션에서 리뷰를 남겼던 부분을 반영해주셨군요! 수고하셨습니다. 노파심(?)에 한 말씀 드리자면, 제가 남기는 리뷰도 어디까지나 개인의 의견이기 때문에 제가 남긴 작성한 리뷰를 모두 반영한다는 느낌보다는 제가 미처 제대로 파악하지 못한 부분이 있을 수도 있으니 비판적으로 검토한 후에 아니라고 생각되는 부분이 있다면 추가로 논의를 진행한 후에 결정하는 것도 충분히 가능한 사안입니다. 그리고 다음부터는 커밋 단위도 신경 쓰면서 잘 나눠보시면 더 좋을 것 같습니다.

리뷰 감사합니다. 안그래도 다른 분들 제출한것을 보고 커밋을 좀 더 잘게 쪼개서 해야 하는데 git의 장점을 제대로 활용하지 못하고 있다는 생각이 들었습니다. 다음 미션부터는 이를 명심해서 커밋해 보겠습니다. 조언 감사합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 진행 중 🏃 스프린트 미션 진행중입니다.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants