Skip to content

feat#22-realtor-certification-ui#24

Merged
Dobbymin merged 11 commits intomainfrom
feat#22-realtor-certification-ui
Aug 19, 2025
Merged

feat#22-realtor-certification-ui#24
Dobbymin merged 11 commits intomainfrom
feat#22-realtor-certification-ui

Conversation

@Dobbymin
Copy link
Copy Markdown
Contributor

@Dobbymin Dobbymin commented Aug 19, 2025

📝 요약 (Summary)

공인중개사 인증을 위한 파일 업로드 기능을 구현했습니다. 드래그 앤 드롭을 지원하는 사용자 친화적인 인터페이스와 실시간 유효성 검사를 통해 안전하고 편리한 인증서 제출 경험을 제공합니다.

✅ 주요 변경 사항 (Key Changes)

  • 파일 업로드 컴포넌트 구현: CustomFileUpload 컴포넌트로 드래그 앤 드롭 및 파일 선택 기능 제공
  • 유효성 검사 시스템: Zod 스키마를 활용한 파일 크기, 형식, 이름 검증
  • 폼 상태 관리: React Hook Form을 통한 완전한 폼 상태 관리 및 에러 처리
  • 성공 화면 구현: 제출 완료 후 성공 메시지와 네비게이션 기능
  • 조건부 렌더링: 제출 상태에 따른 UI 전환 (제목 숨김, 성공 화면 표시)

💻 상세 구현 내용 (Implementation Details)

파일 구조

src/features/realtor-certification/
├── components/common/
│   ├── CustomFileUpload.tsx    # 재사용 가능한 파일 업로드 컴포넌트
│   └── SubmitSuccessBox.tsx    # 성공 상태 표시 컴포넌트
├── model/schema/
│   └── realtor-certification.schema.ts  # Zod 유효성 검사 스키마
└── ui/
    ├── CertificationForm.tsx       # 메인 폼 컴포넌트
    ├── SubmitSuccessSection.tsx    # 성공 섹션
    └── TitleSection.tsx            # 제목 섹션

핵심 기능

  • 파일 업로드: 드래그 앤 드롭, 클릭 선택, 실시간 미리보기
  • 유효성 검사: 최대 10MB, PDF/JPG/PNG/WEBP 형식 지원
  • 상태 관리: 제출 전/후 상태에 따른 UI 전환
  • 에러 처리: 사용자 친화적인 에러 메시지 표시

🚀 트러블 슈팅 (Trouble Shooting)

React Hook Form과 파일 업로드 통합

  • 문제input type="file"의 value 속성이 File 타입과 호환되지 않는 이슈
  • 해결field props를 분해하여 value 제외하고 필요한 속성만 전달

조건부 렌더링 구조

  • 문제: 제출 성공 시 TitleSection 숨김과 SubmitSuccessSection 표시 로직
  • 해결: 페이지 레벨에서 상태 관리하여 컴포넌트 간 의존성 최소화

⚠️ 알려진 이슈 및 참고 사항 (Known Issues & Notes)

  • 현재 API 호출은 시뮬레이션으로 구현되어 있음 (1초 지연)
  • 실제 API 연동 시 FormData 구조로 전송 예정
  • 파일 압축 및 최적화 기능은 향후 구현 예정
  • 다중 파일 업로드는 현재 지원하지 않음

📸 스크린샷 (Screenshots)

#️⃣ 관련 이슈 (Related Issues)

@Dobbymin Dobbymin self-assigned this Aug 19, 2025
@Dobbymin Dobbymin linked an issue Aug 19, 2025 that may be closed by this pull request
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @Dobbymin, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 풀 리퀘스트는 공인중개사 인증 기능의 초기 프론트엔드 구현을 위한 UI 컴포넌트, 상태 관리 로직, 파일 업로드 필드 및 관련 유효성 검사 모듈을 추가합니다. 이 변경사항은 사용자가 공인중개사 인증서를 제출할 수 있는 인터페이스를 제공하고, 제출 상태를 관리하며, 파일 유효성 검사를 수행합니다.

Highlights

  • 핵심 UI 컴포넌트 추가: 공인중개사 인증 페이지의 핵심 UI 컴포넌트(제출 폼, 성공 섹션, 파일 업로드 필드)가 추가되었습니다.
  • 상태 관리 로직 구현: 공인중개사 인증 제출을 위한 상태 관리 로직이 구현되었습니다.
  • 재사용 가능한 파일 업로드 컴포넌트 도입: 파일 업로드 기능(드래그 앤 드롭, 미리보기, 오류 표시 포함)을 위한 재사용 가능한 CustomFileUpload 컴포넌트가 도입되었습니다.
  • 강력한 폼 유효성 검사 스키마 정의: react-hook-form과 zod를 활용하여 파일 크기, 형식, 파일명 유효성 검사를 포함한 데이터 스키마가 정의되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이 PR은 공인중개사 인증 기능의 UI 및 관련 로직을 추가하는 것을 목표로 하고 있습니다. 전반적으로 기능 구현이 잘 이루어졌지만, 몇 가지 개선점을 제안합니다.
주요 피드백은 다음과 같습니다:

  • 폼 제출 방식이 웹 접근성 표준에 맞게 개선되어야 합니다.
  • 컴포넌트 간 상태 관리 로직이 중복되어 있어 단순화가 필요합니다.
  • 하드코딩된 값들을 상수로 대체하여 유지보수성을 높이는 것이 좋습니다.
  • Zod 스키마에서 사용자 친화적인 오류 메시지를 제공하도록 개선할 수 있습니다.

자세한 내용은 각 파일의 주석을 참고해주세요.

Comment on lines +50 to +62
<form onSubmit={(e) => e.preventDefault()}>
<div className='space-y-6'>
<FileUploadField />
<Button
onClick={form.handleSubmit(onSubmit)}
type='submit'
className='h-12 w-full rounded-md text-lg'
disabled={!form.formState.isValid}
>
제출하기
</Button>
</div>
</form>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

현재 폼 제출 로직이 <Button>onClick 이벤트에 연결되어 있고, <form>onSubmitpreventDefault로 막혀있습니다. 이는 키보드(예: Enter 키)를 사용한 폼 제출과 같은 웹 접근성 표준을 저해할 수 있습니다. react-hook-formhandleSubmit 함수를 <form>onSubmit 이벤트에 직접 전달하고, 버튼에서는 type="submit"만 사용하도록 수정하는 것이 좋습니다.

      <form onSubmit={form.handleSubmit(onSubmit)}>
        <div className='space-y-6'>
          <FileUploadField />
          <Button
            type='submit'
            className='h-12 w-full rounded-md text-lg'
            disabled={!form.formState.isValid}
          >
            제출하기
          </Button>
        </div>
      </form>

<input
ref={fileInputRef}
type='file'
accept='.pdf,.jpg,.jpeg,.png,.webp'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

accept 속성에 파일 형식이 하드코딩되어 있습니다. src/features/realtor-certification/constants/certification-file.ts에 정의된 ACCEPTED_FILE_TYPES 상수를 사용하는 것이 좋습니다. 이렇게 하면 상수와 실제 허용 파일 형식이 항상 동기화되어 유지보수성이 향상됩니다.

먼저 상수를 import 하세요:

import { ACCEPTED_FILE_TYPES } from '../../constants';

그런 다음 accept 속성을 수정하세요.

Suggested change
accept='.pdf,.jpg,.jpeg,.png,.webp'
accept={ACCEPTED_FILE_TYPES.join(',')}

</p>
<p className='text-sm text-gray-500'>{placeholder}</p>
</div>
<div className='text-sm text-gray-400'>지원 형식: PDF, JPG, PNG, WEBP (최대 10MB)</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

지원 형식과 최대 파일 크기에 대한 안내 문구가 하드코딩되어 있습니다. 파일 형식은 ACCEPTED_FILE_TYPES에서, 최대 파일 크기는 MAX_FILE_SIZE_10MB에서 가져와 동적으로 표시하는 것이 좋습니다. 이렇게 하면 Zod 스키마의 유효성 검사 규칙과 UI에 표시되는 정보가 항상 일치하게 되어 유지보수성이 향상됩니다.


export const realtorCertificationSchema = z.object({
certificateFile: z
.instanceof(File)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

z.instanceof(File)을 사용하면 파일이 선택되지 않았을 때 (값이 undefined일 때) Zod의 기본 오류 메시지("Expected File, received undefined")가 표시될 수 있습니다. 사용자에게 더 친숙한 오류 메시지(예: "인증서 파일을 업로드해주세요.")를 제공하려면 z.instanceof(File, { message: '...' })와 같이 메시지를 직접 지정하는 것이 좋습니다. 이렇게 하면 필수 필드에 대한 유효성 검사 메시지를 직접 제어할 수 있습니다.

Suggested change
.instanceof(File)
.instanceof(File, { message: '인증서 파일을 업로드해주세요.' })

};

export const CertificationForm = ({ onSuccess }: props) => {
const [isSubmitted, setIsSubmitted] = useState(false);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

isSubmitted 상태는 부모 컴포넌트인 RealtorCertificationPage에서도 관리되고 있습니다. 상태 관리 로직이 중복되므로 이 컴포넌트 내의 isSubmitted 상태와 관련 로직(36번째 줄의 setIsSubmitted(true), 44-46번째 줄의 조건부 렌더링)을 제거하는 것이 좋습니다. CertificationForm은 폼의 역할만 수행하고, 제출 성공 시 onSuccess 콜백을 호출하여 부모에게 알리는 역할에 집중해야 합니다.

@Dobbymin Dobbymin added the 🎨 Design UI / UX 디자인 관련 작업을 진행하는 경우 label Aug 19, 2025
@Dobbymin Dobbymin merged commit 679afca into main Aug 19, 2025
2 checks passed
@Dobbymin Dobbymin deleted the feat#22-realtor-certification-ui branch August 19, 2025 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🎨 Design UI / UX 디자인 관련 작업을 진행하는 경우

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[UI 구현] 공인중개사 인증 폼

1 participant