Skip to content

Conversation

@Insung-Jo
Copy link

@Insung-Jo Insung-Jo commented Jun 16, 2025

📌 변경 사항 개요

  • 회원 가입 폼 구현 했습니다.

✨ 요약

  • 회원 가입 관련 스키마 작성
  • 회원 가입 API 호출 훅으로 분리
  • 회원 가입 폼 구현

📝 상세 내용

  • 이전 로그인 폼이랑 유사하기 때문에 추가된 부분에서 설명 드리겠습니다.

스키마 관련

패턴 의미 설명
/ 정규식 시작, 끝 리터럴 표기법에서 패턴의 시작과 끝을 감싸준다.
^ 시작 anchor 문자열의 시작부터 검사
[a-zA-Z가-힣] 문자 클래스 허용 문자:
- a-z (소문자)
- A-Z (대문자)
- 가-힣 (한글 전체)
{1,10} 수량자 1글자 이상 10글자 이하 반복
$ 종료 anchor 패턴이 문자열 끝까지 도달해야 합니다. (이후에 추가 문자가 있으면 매칭 실패)
  nickname: {
    required: '닉네임을 입력해 주세요.',
    pattern: {
      value: /^[a-zA-Z-]{1,10}$/,
      message: '한글 또는 영어만 입력할 수 있으며, 최대 10자까지 가능합니다.',
    },
  },
  • 닉네임은 요청대로 한글 또는 영어로만 입력이 가능하게 정규식을 작성했습니다.
부분 역할 설명
validate 커스텀 유효성 검사 함수 입력값(value)이 유효한지 검증하는 로직 정의
import { SignupFormData } from '../types/auth.type'

export function useConfirmPasswordValidation(getValues: () => SignupFormData) {
  return {
    required: '비밀번호를 한번 더 입력해 주세요.',
    validate: (value: string) => {
      const password = getValues().password
      return value === password || '비밀번호가 일치하지 않습니다'
    },
  }
}
  • 기존에는 useWatch를 사용하여 값을 추적하였으나 값이 변경될 때마다 리렌더링이 발생하는 문제가 있어 getValues를 사용하여 필요한 시점에만 값을 가져와 비교하도록 구현했습니다.

폼 관련(코드래빗 리뷰 반영 전)

함수 역할 설명
trigger 유효성 검증 실행 특정 필드 또는 전체 폼의 유효성 검증을 수동으로 실행할 때 사용
getValues 현재 폼 값 조회 현재까지 입력된 폼 데이터를 즉시 가져올 때 사용 (렌더링 없이 동기적으로 값 조회 가능)
const {
    register,
    handleSubmit,
    trigger,
    getValues,
    formState: { errors, isSubmitting, isValid },
  } = useForm<SignupFormData>({
    mode: 'onChange',
    defaultValues: {
      email: '',
      nickname: '',
      password: '',
      confirmPassword: '',
    },
  })

  const [checked, setChecked] = useState(false)
  const password = getValues('password')
  const { submit } = useSignupSubmit()
  const validation = useConfirmPasswordValidation(getValues)

  useEffect(() => { // password 값이 변경될 때마다 confirmPassword 필드 유효성 검사 재실행
    trigger('confirmPassword')
  }, [password, trigger])

  function handleAgree() {
    setChecked((prev) => !prev)
  }

//...
<input
          type="checkbox"
          id="terms"
          onChange={handleAgree}
          checked={isChecked}
        />
  • 기존 validate만으로는 값이 변경될 때마다 동적으로 UI가 반영 되지 않는 상황 때문에 trigger를 사용하였습니다.
  • getValues로 현재 입력된 폼 데이터를 통하여 값 비교를 했습니다.
  • 이용약관 동의는 간단하게 useState를 통하여 구현했습니다.

🔗 관련 이슈

#54

🖼️ 스크린샷

기본

image

에러 발생

image

성공

image

응답

  • 계정이 많아질 거 같아서 우선 중복으로 했을 때 처리가 잘 되는지 확인.
    image

✅ 체크리스트

  • 브랜치 네이밍 컨벤션을 준수했습니다
  • 커밋 컨벤션을 준수했습니다
  • 코드가 프로젝트의 스타일 가이드라인을 준수합니다

💡 참고 사항

  • Input은 리펙토링 작업에서 잘게 쪼갤 거 같습니다 ㅎㅎ.. (변수가 너무 많긴 하네요)
  • 추후에 추가를 한다면 오류가 발생 했을 때 문제가 되는 부분에 foucs 가는 것을 해보고 싶습니당

Summary by CodeRabbit

  • 신규 기능

    • 회원가입 페이지와 회원가입 폼이 추가되었습니다.
    • 이메일, 닉네임, 비밀번호, 비밀번호 확인 입력란과 약관 동의 체크박스가 포함된 회원가입 폼이 제공됩니다.
    • 각 입력란에 대한 유효성 검사 및 에러 메시지 표시 기능이 도입되었습니다.
    • 비밀번호 확인 필드의 실시간 검증 기능이 추가되었습니다.
    • 회원가입 성공 및 실패 시 알림이 제공되며, 성공 시 로그인 페이지로 이동합니다.
  • 기타

    • 기존 로그인(사인인) 폼이 제거되었습니다.

@Insung-Jo Insung-Jo added this to the 2차 구현 기간 milestone Jun 16, 2025
@Insung-Jo Insung-Jo self-assigned this Jun 16, 2025
@Insung-Jo Insung-Jo added ✨Feat 기능 개발 🎨Style UI, 스타일 관련 수정 labels Jun 16, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 16, 2025

"""

Walkthrough

이 변경 사항은 기존의 로그인 폼을 제거하고, 회원가입 폼 및 관련 유효성 검사, 제출 로직, 타입, 커스텀 훅, 스키마 등을 새롭게 추가합니다. 회원가입 폼은 입력값 검증, 비밀번호 확인, 약관 동의 체크박스, 제출 처리 기능을 포함합니다.

Changes

파일/경로 변경 요약
src/app/(auth)/signin/page.tsx 기존 로그인 폼 컴포넌트(MyForm) 삭제
src/app/(auth)/signup/page.tsx 회원가입 페이지 컴포넌트(Signup) 추가, SignupForm 렌더링
src/app/features/auth/components/SignupForm.tsx 회원가입 폼(SignupForm) 컴포넌트 추가, 입력값 검증 및 제출 처리
src/app/features/auth/hooks/useConfirmPasswordValidation.ts 비밀번호 확인 유효성 검사 커스텀 훅 추가
src/app/features/auth/hooks/useSignupSubmit.ts 회원가입 제출 처리 커스텀 훅 추가, 성공/실패 토스트 및 이동 처리
src/app/features/auth/schemas/signupValidation.ts 회원가입 입력값 유효성 검사 스키마 추가(이메일, 비밀번호, 닉네임)
src/app/features/auth/types/auth.type.ts 회원가입 폼 데이터 타입(SignupFormData) 추가

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SignupForm
    participant useSignupSubmit
    participant AuthAPI
    participant Router
    participant Toast

    User->>SignupForm: 입력값 작성 및 제출
    SignupForm->>useSignupSubmit: submit(formData)
    useSignupSubmit->>AuthAPI: signup(formData)
    AuthAPI-->>useSignupSubmit: 응답(성공/실패)
    alt 성공
        useSignupSubmit->>Toast: 성공 토스트 표시
        useSignupSubmit->>Router: 로그인 페이지로 이동
    else 실패
        useSignupSubmit->>Toast: 에러 토스트 표시
    end
Loading

Possibly related PRs

  • CoPlay-FE/coplan#29: 인증 API, 상태 관리, 로그인/회원가입 훅 구현. 본 PR의 회원가입 폼과 제출 훅이 해당 PR의 인증 로직에 직접적으로 의존함.
  • CoPlay-FE/coplan#44: 재사용 가능한 Input 컴포넌트 추가 및 react-hook-form과의 통합. 본 PR에서 삭제된 로그인 폼이 해당 Input 컴포넌트를 사용했을 가능성이 높음.

Suggested reviewers

  • dkslel1225
  • LeeCh0129

Poem

🐇
새싹 폼이 쏙! 로그인은 굿바이,
회원가입 폼이 반짝, 유효성도 꽉!
체크박스, 비밀번호, 닉네임까지
토스트 알림에 웃음꽃 피네.
코드를 뛰노는 토끼의 봄날,
새로운 시작, 우리 함께 hop!

"""

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-06-16T17_03_22_317Z-debug-0.log


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d560b41 and f9c4ee6.

📒 Files selected for processing (2)
  • src/app/features/auth/components/SignupForm.tsx (1 hunks)
  • src/app/features/auth/hooks/useConfirmPasswordValidation.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app/features/auth/hooks/useConfirmPasswordValidation.ts
  • src/app/features/auth/components/SignupForm.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Insung-Jo Insung-Jo linked an issue Jun 16, 2025 that may be closed by this pull request
1 task
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (3)
src/app/(auth)/signup/page.tsx (1)

5-9: 불필요한 Fragment 제거 제안

<SignupForm /> 하나만 반환하므로 빈 Fragment(<>...</>)는 의미 없습니다. JSX 노이즈를 줄이고 가독성을 높이려면 Fragment를 삭제하고 컴포넌트를 바로 반환하세요.

-  return (
-    <>
-      <SignupForm />
-    </>
-  )
+  return <SignupForm />
src/app/features/auth/hooks/useConfirmPasswordValidation.ts (1)

3-9: 성능 최적화를 위한 useMemo 고려

매 렌더마다 새로운 객체를 반환하면 react-hook-form의 내부 비교가 불필요하게 실패할 수 있습니다. 훅 내에서 useMemo로 래핑하면 불필요한 재생성을 방지할 수 있습니다.

-export function useConfirmPasswordValidation(getValues: () => SignupFormData) {
-  return {
-    validate: (value: string) => {
-      const password = getValues().password
-      return value === password || '비밀번호가 일치하지 않습니다'
-    },
-  }
+export function useConfirmPasswordValidation(getValues: () => SignupFormData) {
+  return useMemo(
+    () => ({
+      validate: (value: string) => {
+        const password = getValues().password
+        return value === password || '비밀번호가 일치하지 않습니다'
+      },
+    }),
+    [getValues],
+  )
 }
src/app/features/auth/hooks/useSignupSubmit.ts (1)

18-24: 에러 메시지 국제화 및 Fallback 개선 제안

현재 토스트 메시지가 한글 문자열로 하드코딩되어 있습니다. 향후 다국어 지원을 염두에 두고 i18n 모듈(예: next-intl, react-i18next)을 통해 메시지를 관리하면 유지보수성이 올라갑니다. 또한 axios.isAxiosError(e) 블록 외부의 예외 메시지도 로깅하여 디버깅에 도움이 되도록 고려해 주세요.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f210b1c and d560b41.

📒 Files selected for processing (7)
  • src/app/(auth)/signin/page.tsx (0 hunks)
  • src/app/(auth)/signup/page.tsx (1 hunks)
  • src/app/features/auth/components/SignupForm.tsx (1 hunks)
  • src/app/features/auth/hooks/useConfirmPasswordValidation.ts (1 hunks)
  • src/app/features/auth/hooks/useSignupSubmit.ts (1 hunks)
  • src/app/features/auth/schemas/signupValidation.ts (1 hunks)
  • src/app/features/auth/types/auth.type.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/app/(auth)/signin/page.tsx
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/app/(auth)/signup/page.tsx (1)
src/app/features/auth/components/SignupForm.tsx (1)
  • SignupForm (13-107)
src/app/features/auth/hooks/useConfirmPasswordValidation.ts (1)
src/app/features/auth/types/auth.type.ts (1)
  • SignupFormData (19-21)
src/app/features/auth/components/SignupForm.tsx (5)
src/app/features/auth/types/auth.type.ts (1)
  • SignupFormData (19-21)
src/app/features/auth/hooks/useSignupSubmit.ts (1)
  • useSignupSubmit (8-28)
src/app/features/auth/hooks/useConfirmPasswordValidation.ts (1)
  • useConfirmPasswordValidation (3-10)
src/app/features/auth/schemas/signupValidation.ts (1)
  • signupValidation (1-23)
src/app/shared/lib/cn.ts (1)
  • cn (4-6)
🔇 Additional comments (2)
src/app/features/auth/schemas/signupValidation.ts (1)

1-23: 검증 스키마 적절성 확인 완료

필수 메시지·패턴 모두 명확하며 요구사항(이메일 형식, 8자 이상 비밀번호, 한/영 10자 닉네임)을 충족합니다.

src/app/features/auth/components/SignupForm.tsx (1)

94-101: Tailwind 클래스 네이밍 일관성 확인 필요
BG-blue / BG-blue-disabled 는 일반적인 Tailwind 접두어(bg-)와 다릅니다. 프로젝트 전역 유틸 클래스라면 상관없지만, 아닌 경우 렌더링 시 의도한 색상이 적용되지 않을 수 있습니다. 클래스를 다시 확인해 주세요.

Copy link
Contributor

@dkslel1225 dkslel1225 left a comment

Choose a reason for hiding this comment

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

설명 감사합니다, 폼 구현 수고하셨습니다~~! 👍✨

Copy link
Contributor

@yuj2n yuj2n left a comment

Choose a reason for hiding this comment

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

인성님 회원가입 폼 구현 수고하셨습니다!!
질문사항은 남겨두었습니다 : )

@@ -0,0 +1,28 @@
import axios from 'axios'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
Copy link
Contributor

Choose a reason for hiding this comment

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

토스트 사용해주셨군용

labelName="비밀번호"
type="password"
placeholder="8자 이상 입력해 주세요"
autoComplete="new-password"
Copy link
Contributor

Choose a reason for hiding this comment

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

이렇게 적어주면 어떻게 자동완성이 이루어지는건가용?

Copy link
Author

@Insung-Jo Insung-Jo Jun 17, 2025

Choose a reason for hiding this comment

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

아니요 그 반대 입니다!

autoComplete라는 속성은 브라우저의 자동 완성 동작을 제어하는 속성입니다.
이 중에서 new-password는 해당 입력창이 새로운 비밀번호를 설정하는 필드임을 브라우저에게 알려주게 됩니다!

이 속성을 명시 하지 않았을 경우 브라우저에서는 과거에 입력한 데이터를 기준으로 자동 완성을 띄우게 됩니다. 이러면 UX 측면으로도 혼란을 야기할 수 있기 때문에 해당 속성을 사용하게 되었습니다.
공식 문서

type="email"
placeholder="이메일을 입력해 주세요"
autoComplete="email"
{...register('email', signupValidation.email)}
Copy link
Contributor

Choose a reason for hiding this comment

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

여기는 어떤 내용을 포함하고 있는걸까용?

Copy link
Author

@Insung-Jo Insung-Jo Jun 17, 2025

Choose a reason for hiding this comment

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

정확히 어느 부분을 말씀하신 건지는 파악할 수 없으나

만약 ...register를 말씀하신 거라면 기본적으로 register(name, options)를 호출해 반환된 값을 props로 전달하는 형태입니다.
이때 register의 반환 값은 { ref, name, onChange, onBlur } 형태의 객체이며 options에는 다양한 유효성 검증과 관련된 옵션이 있습니다!

만약 전체 옵션이 궁금하시다면 공식 문서를 참고하시면 됩니다!

Copy link

@LeeCh0129 LeeCh0129 left a comment

Choose a reason for hiding this comment

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

회원 가입 폼 구현 고생많으셨습니다~ 설명도 자세하게 작성해주셔서 이해가 잘되네요 👍

@Insung-Jo Insung-Jo merged commit f7e0d13 into develop Jun 17, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨Feat 기능 개발 🎨Style UI, 스타일 관련 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ Feat: 회원 가입 폼 구현

5 participants