Skip to content

Conversation

@suuuuya
Copy link
Collaborator

@suuuuya suuuuya commented Jul 16, 2025

Sprint Mission 4 요구사항

기본

로그인

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

회원가입

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

심화

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

작업 URL

판다마켓 | 메인
판다마켓 | 로그인
판다마켓 | 회원가입

주요 변경사항

  • 스프린트 미션 3 코드 리뷰 개선 사항 반영
  • 스프린트 미션 4 구현 완료

스크린샷

로그인

유형 1 (빈 값) 유형 2 (값이 맞지 않을 경우) 유형 3 (submit/toggle 버튼 활성화)
image image image

회원가입

유형 1 (빈 값) 유형 2 (값이 맞지 않을 경우) 유형 3 (submit/toggle 버튼 활성화)
image image image

멘토에게

  • 배웠던 import export 문법을 처음 응용해보면서 코드를 모듈화 해서 관리해보려고 시도했는데요. 😀
    작은 프로젝트에서는 파일 나누는 기준을 정하는게 어려운 것 같아요. . . 이렇게 파일을 분리할 때 제일 우선적으로 고려하는 기준이 있을까요?

  • 비슷한 패턴의 로직을 반복할때 고민해서 네이밍 하는데도 변수나 함수 파라미터 이름이 겹치게 되는 경우가 생깁니다.
    (새 기능을 추가해서 만들 때 기존에 짰던 코드를 자꾸 건드리게 돼요 . . . 🤕)
    의미만 명확하게 전달되면 비슷하거나 겹쳐도 괜찮은지 궁금합니다.

suuuuya added 3 commits July 16, 2025 15:50
- auth(회원인증) 디렉토리 생성 및 스타일 분리
- 경로 관리 개선
- (공통) 폼 공통 컴포넌트 스타일 수정
- (로그인/회원가입) 입력 검증 함수 구현, 이벤트 동작 추가
- (로그인/회원가입) 비밀번호 표시/숨기기 동작 이벤트 구현
@suuuuya suuuuya added the 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. label Jul 16, 2025
@kiJu2
Copy link
Collaborator

kiJu2 commented Jul 17, 2025

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

@kiJu2
Copy link
Collaborator

kiJu2 commented Jul 17, 2025

커밋 메시지 좀 더 자세히 써도 될 것 같아요 !

"스프린트 미션 4 기본 요구사항 작업 완료" 라고 한다면 해당 커밋이 어떤 작업을 수행했는지 알기가 어렵습니다 !
대신, "sign-in 페이지 form 스타일링"과 같이 해당 커밋이 어떤 작업을 수행했는지 분할해서 커밋해보는건 어떨까요? 😉

@kiJu2
Copy link
Collaborator

kiJu2 commented Jul 17, 2025

배웠던 import export 문법을 처음 응용해보면서 코드를 모듈화 해서 관리해보려고 시도했는데요. 😀

👍👍👍

작은 프로젝트에서는 파일 나누는 기준을 정하는게 어려운 것 같아요. . . 이렇게 파일을 분리할 때 제일 우선적으로 고려하는 기준이 있을까요?

사실 이건 “경험”으로 익혀가는 부분이지만, 아래와 같은 신호가 있다면 분리를 고려해볼 수 있어요:

  • "어? 이 함수 다른 데서도 쓸 것 같은데?"
  • "이거 수정하려면 다른 JS 파일에도 가서 고쳐야 하네?"
  • "이 기능이 특정 페이지에만 종속되지 않아!"
    어떻게 하면 더 나은 설계를 할 수 있을까?”를 고민하는 건 아주 중요한 개발자의 태도예요.
    정답은 없지만, 재사용성과 유지보수성이라는 기준을 계속 떠올리면서 코드를 분리하는 연습을 하다 보면,
    더욱 확장성 있는 구조를 만들 수 있으실거예요. 😉😉

@kiJu2
Copy link
Collaborator

kiJu2 commented Jul 17, 2025

비슷한 패턴의 로직을 반복할때 고민해서 네이밍 하는데도 변수나 함수 파라미터 이름이 겹치게 되는 경우가 생깁니다.
(새 기능을 추가해서 만들 때 기존에 짰던 코드를 자꾸 건드리게 돼요 . . . 🤕)
의미만 명확하게 전달되면 비슷하거나 겹쳐도 괜찮은지 궁금합니다.


만약 같은 네이밍이 필요한 일이 발생한다면 "진짜 필요한 변수인가?"를 먼저 고민해보셔야 해요.
그게 아니라 정말 필요한데 의미가 비슷한 다음과 같은 상황이라면:

function isRightCalc(num1, num2, result) {
  const rusult2 = num1 + num2;

  return result2 === result;
}

이 때 result2라는 작명은 좋지 못합니다. 어떤 구분이 있는지 명확하지 않으니까요.
저였다면 위와 같은 상황이라면 두 "결과"라는 의미는 같으나 차이점인 expectedResultcalculatedResult로 작명할 것 같아요.

혹은 작명이 잘 안떠올라서 귀찮은 상황이거나 몰입중이라면 내부 변수를 _result(private, 로컬, 임시 등에 쓰이는 간단한 꼼수?)로 작명할 것 같기도 해요 😅

서로 다른 두 함수에 작성된 로직이 다르면 두 함수의 목적이 다르다고 볼 수 있습니다.
만약 이름이 겹칠 것 같다면 서로 다른 차이를 함수명에 명시해주는게 좋을 것 같아요. 😉

@kiJu2
Copy link
Collaborator

kiJu2 commented Jul 17, 2025

(이어서) 작명 꿀팁..?

그리고 개발자에게 작명은 숙명입니다... 아마 철학관 같이 작명 사업 하시는 분들보다 개발자가 이름을 더 많이 지을거예요... 😅
경험이 많아질수록 '작명'에 소모되는 시간이 현저히 줄어들게 되지만, 개발한지 얼마 되지 않았다면 오래 고민하기도 해요.

1. 이럴 때 좋은 방법은 다음과 같이 아주 대충 지어놓고:

function _(num1, num2, result) {
  const rusult2 = num1 + num2;

  return result2 === result;
}

2. GPT한테 추천 받아보면 됩니다 😉:

GPT. 다음 함수를 봐줘:

function _(num1, num2, result) {
  const rusult2 = num1 + num2;

  return result2 === result;
}

함수 이름이 안떠오르는데 3가지만 추천해줄래 ?


물론이죠! 이 함수는 두 숫자의 합이 기대값(result)과 같은지를 비교하는 함수이므로, 아래와 같은 이름을 추천드립니다:
1. isSumEqual
→ 의미: num1 + num2 === result인지 확인하는 함수.
→ 읽기 쉽고 조건 검사 함수처럼 is로 시작해 직관적입니다.
2. checkSumMatch
→ 의미: 합산된 값이 주어진 결과와 일치하는지 확인.
→ check와 match를 써서 비교하는 느낌을 강조했습니다.
3. validateAdditionResult
→ 의미: 두 수의 덧셈 결과가 기대한 결과와 맞는지 검증.
→ 약간 길지만, 검증 로직이라는 점을 명확하게 표현합니다.

짧고 직관적인 이름을 원한다면 isSumEqual이 가장 깔끔합니다.
필요하면 상황에 맞춰 더 다양한 뉘앙스로 제안드릴 수도 있어요!


실제로 저도 안떠오를 때 하는 방법이고, GPT 이름 짓는 인사이트 넓히기도 좋아서 함수명 안떠오르면 물어보고 사용합니다. 😉

Copy link
Collaborator

Choose a reason for hiding this comment

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

오호 경로만 봐도 어떤 목적의 스타일인지 알겠네요 👍👍

Comment on lines +5 to +24
export const validateEmail = (email) => {
const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

if (!email) {
return { message: "이메일을 입력해주세요.", status: "error" };
}
if (!pattern.test(email)) {
return { message: "잘못된 이메일 형식입니다.", status: "error" };
}

return SUCCESS;
};

// 닉네임 입력 검증
export const validateNickName = (nickname) => {
if (!nickname) {
return { message: "닉네임을 입력해주세요.", status: "error" };
}
return SUCCESS;
};
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

Choose a reason for hiding this comment

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

(선택) 또한, throw를 사용하는 방법도 있을 것 같아요. 😉

Suggested change
export const validateEmail = (email) => {
const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (!email) {
return { message: "이메일을 입력해주세요.", status: "error" };
}
if (!pattern.test(email)) {
return { message: "잘못된 이메일 형식입니다.", status: "error" };
}
return SUCCESS;
};
// 닉네임 입력 검증
export const validateNickName = (nickname) => {
if (!nickname) {
return { message: "닉네임을 입력해주세요.", status: "error" };
}
return SUCCESS;
};
export const validateEmail = (email) => {
const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (!email) {
throw new Error("잘못된 이메일 형식입니다.");
}
if (!pattern.test(email)) {
throw new Error("잘못된 이메일 형식입니다.");
}
return SUCCESS;
};
// 닉네임 입력 검증
export const validateNickName = (nickname) => {
if (!nickname) {
throw new Error("닉네임을 입력해주세요.");
}
return SUCCESS;
};

해당 코멘트 적용은 선택입니다 ! (그냥 넘겨도 됩니다 ~!)
throw로 해당 함수를 만들든, 연수님께서 작성하신 방법으로 하든 기능상 차이는 물론 없거니와 코드 스타일의 차이 정도로 볼 수 있을 것 같아요.

일부 유효성 검사 라이브러리에서는 연수님께서 작성주신 방법과 throw 두 유효성 검사 함수를 제공하기도 합니다. 즉. 상황에 따라 더 편한 방법을 사용하면 될 것 같아요 😉

class-validator

Comment on lines +71 to +75
const isPressed = toggleBtn.getAttribute("aria-pressed") === "true";
const inputType = toggleBtn.closest(".password-input").querySelector("input");

toggleBtn.setAttribute("aria-pressed", isPressed ? "false" : "true");
inputType.type = isPressed ? "password" : "text";
Copy link
Collaborator

Choose a reason for hiding this comment

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

크.. aria까지 신경쓰시는 모습 👍👍👍

정말 꼼꼼하네요 👍👍

Comment on lines +83 to +85
if (!targetFieldId) {
return;
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

굿굿 ! 조건에 맞지 않으면 함수를 조기에 return하시는 모습 !

if ... else 계속 사용하면 가독성이 떨어지고 자칫 블록 안에 블록, 블록 안에 블록.. 지옥에 빠질 수 있죠
이럴 때 연수님께서 하신 것처럼 조건에 부합하지 않으면 조기에 exit 시키는 패턴을 Guard Clause라고 합니다 !
훌륭합니다 ! 센스가 좋네요 👍👍

@kiJu2
Copy link
Collaborator

kiJu2 commented Jul 17, 2025

수고하셨습니다 연수님 !
이번 미션도 퍼펙트 하네요 ! 👍👍

리액트에서는 또 어떤 모습을 보여줄지 기대해봅니다 🥺🥺🥺

@kiJu2 kiJu2 merged commit 37d97d0 into codeit-bootcamp-frontend:Basic-이연수 Jul 17, 2025
@suuuuya
Copy link
Collaborator Author

suuuuya commented Jul 17, 2025

커밋메시지가 더 자세히 써질 것 같아요!

"스프린트 임무 4 기본적으로 요구되는 작업을 하고 싶습니다." 라고 생각하면 커밋이 어떤 작업을 수행할 수 있다는 것을 이해하고 있습니다! 대신, "로그인 페이지 양식 형성"과 같이 해당 커밋이 어떤 작업을 수행할 것인지 구분하여 커밋해는건데요? 😉

```commit

feat: 스프린트 미션 4 기본 요구사항 작업 완료

- (공통) 폼 공통 컴포넌트 스타일 수정
- (로그인/회원가입) 입력 검증 함수 구현, 이벤트 동작 추가

```

위처럼 스프린트 3부터 한 커밋에 여러 작업 내용을 묶어서 정리하기 시작했는데, (뭔가 깔끔해보여서요!ㅎㅎ) 수강생 분들 커밋 메시지를 보니 기능/작업 단위별로 세분화해서 올리신 경우가 많더라구요.
스프린트 미션같은 한 덩어리(?)에 여러 작업을 진행해야 하는 상황에서 실무에선 어떻게 관리하는지 기능/작업 단위로 올리는 것이 일반적인지 궁금합니다!

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