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

[스프린트 미션3] 이현서 #25

Conversation

dlgustj321
Copy link

@dlgustj321 dlgustj321 commented Nov 8, 2024

요구사항

기본

공통

  • Github에 스프린트 미션 PR을 만들어 주세요.

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

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

심화

  • 페이스북, 카카오톡, 디스코드, 트위터 등 SNS에서 판다마켓 랜딩 페이지(“/”) 공유 시 미리보기를 볼 수 있도록 랜딩 페이지 메타 태그를 설정합니다.
  • 미리보기에서 제목은 “판다마켓”, 설명은 “일상에서 모든 물건을 거래해보세요”로 설정합니다.
  • 주소와 이미지는 자유롭게 설정하세요.
  • 로그인, 회원가입 페이지에 공통으로 사용하는 로직이 있다면, 반복하지 않고 공통된 로직을 모듈로 분리해 사용해 주세요.

주요 변경사항

스크린샷

image
image
image
image
image
image
image
image
image

Netlify 링크

https://famous-belekoy-4bf136.netlify.app/

멘토에게

  • 멘토링 시간 때 물어보겠습니다!
  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@dlgustj321 dlgustj321 requested a review from jhaemin November 8, 2024 07:37
@dlgustj321 dlgustj321 self-assigned this Nov 8, 2024
@dlgustj321 dlgustj321 added 미완성🫠 완성은 아니지만 제출합니다... 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. labels Nov 8, 2024
@dlgustj321 dlgustj321 closed this Nov 8, 2024
@dlgustj321 dlgustj321 reopened this Nov 8, 2024
height: 80px;
background-color: rgba(54, 146, 255, 1);
color:#FFFFFF;
font-family:"Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;
Copy link

Choose a reason for hiding this comment

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

font-family는 body에 한 번만 정의해줘도 됩니다.

Copy link
Author

Choose a reason for hiding this comment

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

아!! 계속 작업하다 보니까 중복해서 작성한 것 같습니다! 죄송합니다!

Comment on lines +54 to +165
const emailError = document.getElementById('email-error');
const passwordError = document.getElementById('password-error');

emailInput.addEventListener('focusout', validateEmail);
passwordInput.addEventListener('focusout', validatePassword);
emailInput.addEventListener('input', validateForm);
passwordInput.addEventListener('input', validateForm);

function validateEmail() {
const email = emailInput.value;
if (!email) {
emailError.innerText = '이메일을 입력해주세요.';
emailInput.classList.add('error');
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
emailError.innerText = '잘못된 이메일 형식입니다.';
emailInput.classList.add('error');
} else {
emailError.innerText = '';
emailInput.classList.remove('error');
}
}

function validatePassword() {
const password = passwordInput.value;
if (!password) {
passwordError.innerText = '비밀번호를 입력해주세요.';
passwordInput.classList.add('error');
} else if (password.length < 8) {
passwordError.innerText = '비밀번호를 8자 이상 입력해주세요.';
passwordInput.classList.add('error');
} else {
passwordError.innerText = '';
passwordInput.classList.remove('error');
}
}

function validateForm() {
validateEmail();
validatePassword();
checkFormValidity();
}

function checkFormValidity() {
if (emailInput.value && passwordInput.value &&
!emailInput.classList.contains('error') &&
!passwordInput.classList.contains('error')) {
loginButton.disabled = false;
} else {
loginButton.disabled = true;
}
}

function togglePasswordVisibility() {
const type = passwordInput.getAttribute("type") === "password" ? "text" : "password";
passwordInput.setAttribute("type", type);
}

document.getElementById('login-form').addEventListener('submit', function(event) {
event.preventDefault();
const email = emailInput.value;
const password = passwordInput.value;

if (!email) {
emailError.innerText = '이메일을 입력해주세요.';
emailInput.classList.add('error');
}
if (!password) {
passwordError.innerText = '비밀번호를 입력해주세요.';
passwordInput.classList.add('error');
}

loginButton.addEventListener('click', () => {
loginButton.classList.add('clicked');
setTimeout(() => {
loginButton.classList.remove('clicked');
}, 100);
});

document.getElementById('login-form').addEventListener('submit', function(event) {
event.preventDefault();
const email = emailInput.value;
const password = passwordInput.value;

if (!email || !password) {
return;
}

const user = USER_DATA.find(user => user.email === email);

if (!user) {
emailError.innerText = '이메일이 일치하지 않습니다.';
emailInput.classList.add('error');
} else if (user.password !== password) {
passwordError.innerText = '비밀번호가 일치하지 않습니다.';
passwordInput.classList.add('error');
} else {
window.location.href = "/items";
}
})});
</script>
Copy link

Choose a reason for hiding this comment

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

signup.js 처럼 별도의 파일로 분리하면 어떨까요?

Comment on lines +69 to +72
emailInput.addEventListener('focusout', validateEmail);
passwordInput.addEventListener('focusout', validatePassword);
emailInput.addEventListener('input', validateForm);
passwordInput.addEventListener('input', validateForm);
Copy link

Choose a reason for hiding this comment

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

각각의 항목을 검증하는 함수를 분리한 점 좋습니다! 그런데 input마다 폼 전체를 검증하고 있어서 입력마다 불필요한 동작이 많이 일어나고 있어요. 어떻게 하면 사용자가 더 매끄럽게 사용할 수 있을지 고민해 보면 좋겠습니다.

Comment on lines +74 to +75
transform: scale(0.95);
transition: transform 0.1s ease;
Copy link

Choose a reason for hiding this comment

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

클릭할 때 느낌 좋아요 ㅎㅎ

Copy link

Choose a reason for hiding this comment

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

transition:active에 정의하면 active 상태에서 기존 상태로 돌아갈 땐 transition 속성이 없기 때문에 애니메이션되지 않습니다. 의도하신 게 아니라면 transition 속성을 .btn에 정의하는 게 더 좋을 것 같아요

Comment on lines +76 to +81
passwordConfirmInput.style.borderColor = 'red';
return false;
} else if (!passwordConfirmInput.value.trim()) {
passwordConfirmInput.style.borderColor = ''
} else {
passwordConfirmInput.style.borderColor = 'blue';
Copy link

Choose a reason for hiding this comment

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

인라인 스타일을 사용하면 스타일 코드의 응집도가 떨어지고 추적과 변경 대응에 불리해요.
상태별로 클래스를 지정하고 스타일을 정의한 다음 클래스를 토글링하는 방식을 제안해 볼게요!

@jhaemin jhaemin merged commit cbe9133 into codeit-sprint-fullstack:basic-이현서 Nov 13, 2024
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