Skip to content

Conversation

@TAEINJEONG
Copy link
Collaborator

@TAEINJEONG TAEINJEONG commented Mar 14, 2025

요구사항

기본

로그인

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

회원가입

  • 이메일 input에서 focus out 할 떄, 값이 없을 경우 input에 빨강색 테두리와 아래에 “이메일을 입력해주세요.” 빨강색 에러 메세지를 보입니다.
  • 이메일 input에서 focus out 할 때, 이메일 형식에 맞지 않은 경우 input에 빨강색 테두리와 아래에 “잘못된 이메일 형식입니다.” 빨강색 에러 메세지를 보입니다.
  • 닉네임 input에서 focus out할 때, 값이 없을 경우 input에 빨강색 테두리와 아래에 “닉네임을 입력해주세요.” 빨강색 에러 메세지를 보입니다.
  • 비밀번호 input에서 focus out 할 때, 값이 8자 미만일 경우 아래에 “비밀번호 8자 이상 입력해주세요.” 에러 메세지를 보입니다.
  • 비밀번호 input에서 focus out할 때, 값이 8자 미만일 경우 아래에 "비밀번호 8자 이상 입력해주세요.” 에러 메세지를 보입니다.
  • 비밀번호 input과 비밀번호 확인 input의 값이 다른 경우, 비밀번호 확인 input 아래에 “비밀번호가 일치하지 않습니다..” 에러 메세지를 보입니다.
  • input 에 빈 값이 있거나 에러 메세지가 있으면 ‘회원가입’ 버튼을 비활성화 됩니다.
  • input 에 유효한 값을 입력하면 ‘회원가입’ 버튼이 활성화 됩니다.
  • 활성화된 ‘회원가입’ 버튼을 누르면 “/signup”로 이동합니다.

심화

  • 눈 모양 아이콘 클릭시 비밀번호의 문자열이 보이기도 하고, 가려지기도 합니다.
  • 비밀번호의 문자열이 가려질 때는 눈 모양 아이콘에는 사선이 그어져있고, 비밀번호 문자열이 보일 때는 사선이 없는 눈 모양 아이콘이 보이도록 합니다.

주요 변경사항

  • 로그인 및 회원가입 페이지, 입력값에 대한 유효성 검사기능 추가
  • 비밀번호 toggle 버튼에 따른 비밀번호 타입 toggle기능 추가

스크린샷

이메일 입력값이 없을 경우

스크린샷 2025-03-14 오후 5 11 55

이메일 형식이 틀렸을 경우

스크린샷 2025-03-14 오후 5 12 22

비밀번호 입력값이 없을 경우

스크린샷 2025-03-14 오후 5 12 45

비밀번호 입력값이 8자 이하일 경우

스크린샷 2025-03-14 오후 5 13 09

이메일 및 비밀번호의 입력값의 유효성이 올바른 경우

스크린샷 2025-03-14 오후 5 13 29

닉네임 입력값이 없는 경우

스크린샷 2025-03-14 오후 5 14 26

비밀번호 입력값이 보여지는 경우

스크린샷 2025-03-14 오후 5 15 00

시연 영상

2025-03-14.5.15.50.mov
  • 위의 영상에서 error input의 border가 제대로 적용안된것 처럼 녹화되었습니다! 하단에 배포 사이트에서 확인해보시면 border가 정상적으로 적용되어있습니다!

배포 URL

https://visionary-biscotti-3b5524.netlify.app/login

멘토에게

  • DOM에 접근해서 직접적으로 인터렉티브한 자바스크립트 코드는 처음 작성해봅니다! 구현은 제대로 동작하는것 같지만, 더 효율적이거나 개선할 수 있는 부분이 있을지 궁금합니다. 코드 최적화나 더 나은 접근 방법에 대한 조언을 주시면 감사하겠습니다!
  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@kiJu2 kiJu2 changed the base branch from main to Basic-정태인 March 17, 2025 02:56
@kiJu2
Copy link
Collaborator

kiJu2 commented Mar 17, 2025

스프리트 미션 하시느라 수고 많으셨어요.
학습에 도움 되실 수 있게 꼼꼼히 리뷰 하도록 해보겠습니다. 😊

@kiJu2
Copy link
Collaborator

kiJu2 commented Mar 17, 2025

DOM에 접근해서 직접적으로 인터렉티브한 자바스크립트 코드는 처음 작성해봅니다! 구현은 제대로 동작하는것 같지만, 더 효율적이거나 개선할 수 있는 부분이 있을지 궁금합니다. 코드 최적화나 더 나은 접근 방법에 대한 조언을 주시면 감사하겠습니다!

넵넵 ! 물론입니다 ! 꼼꼼히 살펴보고 코멘트 남기겠습니다 ㅎㅎㅎ

Comment on lines +83 to +89
.on {
background-image: url("./assets/images/btn_visibility_on_24px.svg");
}

.off {
background-image: url("./assets/images/btn_visibility_off_24px.svg");
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

오호 background image로 on/off를 만드셨군요 ?

Comment on lines +12 to +24
if (type === "password") {
if (!passwordVisible) {
visiblePasswordIcon.classList.remove('on');
visiblePasswordIcon.classList.add('off');
passwordInput.setAttribute("type", "password");
} else {
visiblePasswordIcon.classList.remove('off');
visiblePasswordIcon.classList.add('on');
passwordInput.setAttribute("type", "text");
}

passwordVisible = !passwordVisible;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

다음과 같이 변경해볼 수 있어요 😊:

visiblePasswordIcon.addEventListener("click", () => {
  passwordVisible = !passwordVisible;
  passwordInput.type = passwordVisible ? "text" : "password";

  // ✅ 이미지 src 직접 변경
  visiblePasswordIcon.src = passwordVisible
    ? "./assets/images/btn_visibility_on_24px.svg"
    : "./assets/images/btn_visibility_off_24px.svg";
});

클래스 이름을 설정하고, 클래스에 css 코드를 넣을 필요 없이 src를 직접 변경해볼 수 있습니다. 😊

Comment on lines +31 to +48
if (inputType === "email") {
const emailValue = emailInput.value.trim();

if (!emailValue) {
emailError.textContent = "이메일을 입력해주세요.";
inputElement.classList.add("error");
isValid = false;
} else if (!isValidEmail(emailValue)) {
emailError.textContent = "잘못된 이메일 형식입니다.";
inputElement.classList.add("error");
isValid = false;
} else {
emailError.textContent = "";
inputElement.classList.remove("error");
}

state.email = isValid;
}
Copy link
Collaborator

@kiJu2 kiJu2 Mar 17, 2025

Choose a reason for hiding this comment

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

(심화/의견/선택) validation 때문에 조건 분기를 필연적으로 해야되는 상황이군요 !

이러할 경우 validation 함수 자체를 분리해볼 수 있습니다 !

매핑?: 객체 인덱스를 활용하여 분기하는 방법입니다 ! (이어서)

Copy link
Collaborator

Choose a reason for hiding this comment

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

validationRules과 element를 인덱싱하여 선언해볼 수 있어요:

  const formElements = {
    email: document.querySelector(".email-input"),
    nickname: document.querySelector(".nickname-input"),
    password: document.querySelector(".password-input"),
    passwordCheck: document.querySelector(".password-check-input"),
    signUpButton: document.querySelector(".signup-button"),
    loginButton: document.querySelector(".login-button"),
  };

  const errorMessages = {
    email: document.getElementById("emailError"),
    nickname: document.getElementById("nicknameError"),
    password: document.getElementById("passwordError"),
    passwordCheck: document.getElementById("passwordCheckError"),
  };

  const validationRules = {
    email: (value) => {
      if (!value) return "이메일을 입력해주세요.";
      if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) return "잘못된 이메일 형식입니다.";
      return "";
    },
    nickname: (value) => (!value ? "닉네임을 입력해주세요." : ""),
    password: (value) => {
      if (!value) return "비밀번호를 입력해주세요.";
      if (value.length < 8) return "비밀번호를 8자 이상 입력해주세요.";
      return "";
    },
    passwordCheck: (value) => {
      if (!value) return "비밀번호를 입력해주세요.";
      if (value !== formElements.password.value.trim()) return "비밀번호가 일치하지 않습니다.";
      return "";
    },
  };

Copy link
Collaborator

@kiJu2 kiJu2 Mar 17, 2025

Choose a reason for hiding this comment

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

그리고 다음과 같이 validate 함수를 만들어볼 수 있습니다 😊:

  function validateInput(type) {
    const inputElement = formElements[type];
    const errorElement = errorMessages[type];
    const value = inputElement.value.trim();
    const errorMessage = validationRules[type](value);

    if (errorMessage) {
      errorElement.textContent = errorMessage;
      inputElement.classList.add("error");
      state[type] = false;
    } else {
      errorElement.textContent = "";
      inputElement.classList.remove("error");
      state[type] = true;
    }

    updateButtonState();
  }

GPT랑 논의하고 제 의견이 잘 포함되었다고 사료되어 추가한 내용이며 실제로 동작되지 않을 수 있습니다 ! 만약 궁금하신 사항이 있다면 DM 주세요 ㅎㅎㅎ

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

Choose a reason for hiding this comment

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

굿굿 ! 순수함수를 작성하셨군요 !

순수함수는 안정성 있는 함수로 꼽힙니다. 😊

순수 함수는 외부의 상태를 변경하지 않으면서 동일한 인자에 대해 항상 똑같은 값을 리턴하는 함수다.

@kiJu2
Copy link
Collaborator

kiJu2 commented Mar 17, 2025

수고하셨습니다 태인님 !
항상 학습에 의욕이 넘치셔서 저도 욕심이 나 심화된 내용도 첨부하였습니다 ! 아마 태인님이라면 잘 따라올 수 있을거라고 생각했어요 !
그냥 이런 내용이 있구나 ~하고 읽어보시기만 해도 괜찮습니다 !
항상 열정적인 태인님. 이번 과제도 수고 많으셨습니다 😊😊

@kiJu2 kiJu2 merged commit d0aa69f into codeit-bootcamp-frontend:Basic-정태인 Mar 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants