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

[ Feat ] signup page #109

Merged
merged 19 commits into from
Oct 21, 2024
Merged

[ Feat ] signup page #109

merged 19 commits into from
Oct 21, 2024

Conversation

ptyoiy
Copy link
Contributor

@ptyoiy ptyoiy commented Oct 14, 2024

#️⃣ Related Issue

Closes #58

✅ Done Task

  • 회원가입 페이지 구현
  • 유효성 검사 적용
  • 누락된 변경 사항 적용 (로그인 페이지)

☀️ New-insight

  • zod
    refine을 적용한 부분과 아닌 부분으로 나눌 수 있네요.
export const baseSignupSchema = z.object({
 ...
  password: z
    .string()
    .min(8)
    .max(15)
    .regex(/^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*])[a-zA-Z\d~!@#$%^&*]+$/),

  confirmPassword: z.string(),
 ...
});

export const signupSchema = baseSignupSchema.refine(
  (data) => data.password === data.confirmPassword,
  {
    message: "비밀번호와 비밀번호 확인이 일치하지 않습니다.",
    path: ["confirmPassword"],
  },
);

z.object 메서드의 리턴값 중에는 partial메서드가 있어 스키마에 존재하는 필드를 선택적으로 검사할 수 있습니다.
반면 refine 메서드를 사용하면 partial메서드를 사용할 수 없어 항상 모든 필드를 검사해야 하죠.
여담으로 refine의 호출은 모든 필드가 채워져 있을 때 작동한다고 합니다. 그래서 defaultValues에 누락된 필드가 있으면 refine 함수가 호출되지 않으니 주의하는 게 좋겠습니다.

const parseResult = baseSignupSchema.partial().safeParse({
  [fieldName]: value,
});
if (!parseResult.success) {
  form.setError(fieldName, parseResult.error);
  return;
}

partial 기능은 닉네임이나 백준 아이디의 중복 검사를 위해 서버와 통신할 때 사용하려고 합니다. 닉네임의 스키마를 만족하지 않으면 스키마 에러를 표시하고, 만족하면 서버와 통신하여 결과를 표시하는 방식이죠.

💎 PR Point

  • 파일 변경 사항
    main과 잘못 병합해서 그런지 몇 가지 레거시 변경 사항들이 잡히네요. view/signup, page 위주로 보시면 됩니다.
    AuthHeader의 경우 좌측 로고를 없애야 해서 recipe으로 /signup인지 확인하여 닫기 버튼의 위치를 처리했습니다.

  • 유효성 검사 모드
    회원 가입 폼에서 사용되는 필드는 프로필사진, 아이디, 비밀번호, 비번 확인, 닉네임, 백준 아이디로 총 6개입니다.

    • 기본적으로 아이디비밀번호는 onTouched 모드로 동작합니다.
    • 비밀번호 확인getMultipleRevalidationHandlers("password")를 사용하여 이 필드를 onTouched 모드로 검사할 때 비밀번호 필드도 같이 검사하도록 합니다. 이를 통해 두 필드가 다 비어있을 때 비밀번호 확인 필드를 먼저 포커스 아웃하면 비밀번호부터 작성하라고 안내 하는 에러 효과를 발생시킵니다.
    • 닉네임백준 아이디 필드는 handleOnChangeMode를 사용하여 onChange 모드로 동작합니다. onChange 모드, watch 및 서버 검사 로직을 조합하여 실시간 서버 검증 기능을 구현했습니다. 중복 확인 버튼이 있는 보통의 디자인은 이런 게 필요 없겠지만 우리 디자인은 버튼이 없는 것 같아 실시간으로 검사하는 방향인 것으로 생각하여 이렇게 구현했습니다. 현재는 실시간 검사 기능을 임시로 모방한 것이라서 나중에 api연결 시 디바운싱 적용과 함께 useCheckOnServer 훅을 고치면 되겠습니다.
  • 에러 메세지

    • 아이디는 기본적으로 에러 효과 없이 메세지가 떠야 하므로 descriptionProps에 message를 명시적으로 넣어줬습니다.
    • 비밀번호비번 확인아이디와 같이 메세지가 떠야 하므로 동일한 작업을 해줬습니다. 다만 두 필드가 한 description을 공유하기에 비번 확인만 description을 출력하게 했으며 aria-describedby는 같은 값을 넣어줬습니다.. 에러 효과의 조건은 두 필드 중 하나라도 error가 있으면 표시해 줘야 하기에 descriptionProps에 명시적으로 isError를 넣어줬습니다.
    • 닉네임백준 아이디로딩중, 에러메세지, 사용 가능 안내 메세지 셋 중 하나를 보여주어야 합니다. 에러 효과는 기본 적용되기 때문에 message 내용만 신경 쓰면 됩니다. 우선 로딩중이 1순위로 나와야 하기에 삼항 연산자의 첫번째로 위치하고, 그 다음 사용 가능 안내를 표시할 지 에러를 표시할 지 정하는 삼항 연산자를 두번째에 위치시켜 구현했습니다.
        const nicknameMsg = isNicknameLoading
          ? "로딩중"
          : showNicknameMsg
            ? "사용가능한 닉네임이에요."
            : errors.nickname?.message;
  • isActive
    버튼에 적용할 isActive 값은 보통 form.formState.isValid를 사용하면 되지만 서버 검증 로딩 중에는 검사를 통과하여 valid한 것으로 나타나고 검사 결과를 받은 뒤에 다시 에러가 표시되기 때문에 잠깐 isActivetrue가 되어 깜빡이게 됩니다. 이를 방지하기 위해 isValid && !isNicknameLoading && !isBaekjoonIdLoading을 사용하여 검사합니다.

📸 Screenshot

  • 임시 검증 로직은 마지막 글자가 t면 통과
    signuppage

@ptyoiy ptyoiy added ✨ Feat 새로운 기능 구현 GYU 곽규한 labels Oct 14, 2024
@github-actions github-actions bot added size/l and removed size/m labels Oct 14, 2024
@github-actions github-actions bot added size/m and removed size/l labels Oct 14, 2024
@github-actions github-actions bot added size/l and removed size/m labels Oct 15, 2024
Copy link
Member

@j-nary j-nary left a comment

Choose a reason for hiding this comment

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

PR 내용보고 많이 배워갑니다! 상세하게 적어주셔서 정말 감사합니다
수고하셨어요 !! 코리 몇개만 확인 부탁드립니다 :)

src/asset/img/img_userprofile.png Outdated Show resolved Hide resolved
src/app/signup/page.tsx Outdated Show resolved Hide resolved
src/app/signup/page.tsx Outdated Show resolved Hide resolved
src/app/signup/page.tsx Outdated Show resolved Hide resolved
src/view/index/AuthHeader/index.css.ts Outdated Show resolved Hide resolved
src/view/index/AuthHeader/index.css.ts Outdated Show resolved Hide resolved
Copy link
Member

@j-nary j-nary left a comment

Choose a reason for hiding this comment

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

LGTM !!

Copy link
Member

@wuzoo wuzoo left a comment

Choose a reason for hiding this comment

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

고생하셨습니다 ~ !! 🚀

@ptyoiy ptyoiy merged commit 7142bb0 into main Oct 21, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ Feat 새로운 기능 구현 GYU 곽규한 size/l
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Join 페이지 구현
3 participants