Skip to content

Conversation

@youdaeng2
Copy link
Member

@youdaeng2 youdaeng2 commented Jul 25, 2025

📦 Pull Request

📝 요약(Summary)

myprofile 페이지 구현

  • 리스트 컴포넌트에서 데이터를 패칭하고, 리스트를 만든
  • 페이지에서 리스트 컴포넌트를 렌더링합니다.

드롭다운 컴포넌트 scroll 막히는 거 수정하였습니다
myCard 컴포넌트 스타일 수정하였습니다

1. index.tsx (MyProfile)

  • 전체 페이지의 레이아웃을 구성하는 엔트리 컴포넌트입니다.
  • Profile, TabNav, ReviewList, WineList 컴포넌트를 조합해 유저의 정보와 활동 내역을 보여줍니다.
  • 탭 전환을 위한 useState 로컬 상태 관리 포함.

2. Profile.tsx

  • 유저의 닉네임과 프로필 이미지를 보여주고, 닉네임 변경 기능을 제공합니다.
  • react-hook-form 기반의 입력 및 유효성 검증 적용.
  • (✔ 예정) 프로필 이미지 업로드 기능 추가 필요.

3. Tab.tsx

  • "내가 쓴 후기", "내가 등록한 와인" 두 개의 탭을 제공하며, 클릭 시 상태를 변경하여 내용을 전환합니다.
  • 각 탭별 총 개수도 함께 표시.

4. ReviewList.tsx

  • 내가 쓴 리뷰 리스트를 보여주는 컴포넌트입니다.
  • react-query를 사용하여 mock 데이터를 요청하고, MyCard UI 컴포넌트를 통해 출력합니다.
  • (✔ 예정) 무한 스크롤 및 API 연동 예정.

5. WineList.tsx

  • 내가 등록한 와인 목록을 보여줍니다.
  • 와인 이미지, 이름, 생산지, 가격 등을 ImageCard로 표현.
  • (✔ 예정) 무한 스크롤 및 API 연동 예정.

💬 공유사항 to 리뷰어

qna

  • 에러메세지 출력하는 게 나을까요?
  • 리액트 훅 폼을 처음 사용해보는 거라 현재 잘 되고있는 건지 헷갈려서요! 확인 한번 부탁드립니다
  • 전송 버튼이 이상해서 api 연결하고 수정해보겠습니다.

todo

  • 모달 연결 (예: 리뷰 수정/삭제 등)
  • API 연동 (닉네임 수정, 내 리뷰 / 내 와인 리스트 불러오기 등)
  • 무한 스크롤 기능 적용 (리뷰 / 와인 리스트) - hook으로 분리 예정
  • 이미지 업로드 기능 (프로필 사진 변경 등)
  • 심심한 부분 애니메이션 넣기
    -->

🗂️ 관련 이슈

📸 스크린샷

converted

image image image image image

✅ 체크리스트

  • [ x ] 빌드 및 테스트 통과
  • [ x ] ESLint/Prettier 검사 통과

youdaeng2 added 16 commits July 23, 2025 15:56
- `defaultValues`를 빈 문자열 → `{ nickname }`으로 초기화해, `placeholder` 대신 `defaultValue`로 기존 닉네임 표시
- 수동 `isDirty` 대신 `watch('nickname') !== nickname` 로 변경 여부 판단
- `required`/`minLength`/`maxLength` 유효성 검사 추가, 실패 시 `onInvalid`으로 콘솔에만 로깅
- `isSubmitting` 상태로 버튼 비활성화 및 텍스트를 “변경 중…” ↔ “변경하기”로 토글 -> 수정 필요
- 제출 성공 후 `reset` 호출로 폼을 새 기본값(new nickname)으로 초기화해 버튼 다시 비활성화 -> 수정 필요
@youdaeng2 youdaeng2 requested review from 626-ju and llmojoll July 25, 2025 09:33
@vercel
Copy link

vercel bot commented Jul 25, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
whyne-fe ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 26, 2025 7:29am

Comment on lines 85 to 92
onInvalid={(e: React.FormEvent<HTMLInputElement>) =>
// 브라우저 유효성 오류를 콘솔에만 출력
console.error(
'닉네임 유효성 오류:',
(e.currentTarget as HTMLInputElement).validationMessage,
)
}
/>
Copy link
Collaborator

Choose a reason for hiding this comment

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

회원가입 시 API에서 500에러 발생 시에는 에러 메시지를 보여주고, 그외의 에러가 발생했을 때는 에러 모달에 메시지를 띄워주는 방식으로 사용중입니다. 참고부탁드립니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

확인해보겠습니다 감사합니다!

Copy link
Collaborator

@626-ju 626-ju left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!

csr로 그리겠다고 염두에 두고 작성하신 것 같은데
pages폴더 안에 두면 빌드 시 프리렌더 과정에서 오류나지 않나요?
리액트 쿼리는 괜찮은가요...?
저두 잘 모르겠네요 ㅎㅎㅎ
멘토님 피드백 같이 기다리도록 하겠습니다!

queryFn: fetchReviews,
});

// 로딩 중 표시
Copy link
Collaborator

Choose a reason for hiding this comment

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

저번에 구현 상세 계획 때
저도 비슷하게 계획을 세웠었는데
image

멘토님께서 Suspense 사용 추천해 주셔서 고려해봐야 할 것 같습니다.
서스펜스 쓸거면 에러바운더리도 같이 쓰는 게 보편적이라고 들었던 것 같은데

이건 회의 때 좀 더 이야기 해봐야 할 것 같아요!

Copy link
Member Author

Choose a reason for hiding this comment

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

이 부분은 좀 더 찾아보고 회의에서 얘기해보면 좋을 것 같네요! 감사합니다.

placeholder='새 닉네임을 입력하세요'
defaultValue={nickname} // 초기값 설정
{...register('nickname', {
required: '닉네임을 입력해주세요.',
Copy link
Collaborator

@626-ju 626-ju Jul 25, 2025

Choose a reason for hiding this comment

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

👍👍 좋습니다
조드 스키마 사용한다면 인풋에 좀 더 간단하게 넘길 수도 있을 것 같은데
의도한 대로 동작만 하다면 굳이 안 고치셔도 될 것 같아요!
(검사필드가 하나라 쓰기도 애매한 것 같구요.
차라리 다음에 필드가 좀 많은 폼을 만들 때 사용해보시는 게 좋을 것 같네요!
개인적으론 필드가 많을 때 그때마다 유효성 규칙을 해당 필드에 분리해서 주입하는 것보다
한번에 관리하는 게 편한 것 같습니다.)

const ProfileSchema = z.object({
  nickname: z
    .string()
    .min(2, { message: '최소 2자 이상 입력하세요.' })
    .max(20, { message: '최대 20자까지 가능합니다.' }),
});

type ProfileFormValues = z.infer<typeof ProfileSchema >

//useForm 호출 시

const {  register, handleSubmit, watch, reset,formState: { isSubmitting } } = useForm<ProfileFormValues >({
    resolver: zodResolver(ProfileSchema ),//리졸버를 같이 해주면
    mode: 'onChange',
  })
  
  
  
  //인풋에 넘길 때
  
 <Input {...register('nickname'}   type='text' ...  /> 이런 식으로 넘길  있습니다 

Copy link
Member Author

Choose a reason for hiding this comment

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

조드 스키마를 써본 적이 없어서 생각을 못했네요!!! 좀 더 공부 후에 어떤 게 나을지 고민해보고 나은 방향으로 적용해보겠습니다. 조언 감사합니다!

/**
* Review 타입 정의 (mock 데이터에서 추론)
*/
type Review = (typeof mockMyReviewsPage1.list)[number];
Copy link

@dwkim101 dwkim101 Jul 25, 2025

Choose a reason for hiding this comment

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

도메인 타입 정의(+목데이터 생성)은 zod로부터 추론(생성)하길 추천드려요

예시

// user.ts
import { z } from "zod";
import { faker } from "@faker-js/faker";

// 1. Zod 스키마 정의
export const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string(),
  email: z.string().email(),
  age: z.number().int().min(18).max(99),
  createdAt: z.date(),
});

// User
type User = z.infer<typeof UserSchema> // {  id: string;  name: string;  email: string;  age: number;  createdAt: Date; }


// 2. Faker로 데이터 생성 함수
export function generateFakeUser(): User {
  const user = {
    id: faker.string.uuid(),
    name: faker.person.fullName(),
    email: faker.internet.email(),
    age: faker.number.int({ min: 18, max: 99 }),
    createdAt: faker.date.past(),
  };
  // Zod로 검증 (타입 안전)
  return UserSchema.parse(user);
}

// 3. 여러 개 생성
export function generateFakeUsers(count: number): User[] {
  return Array.from({ length: count }, generateFakeUser);
}

// 사용 예시
const users = generateFakeUsers(5);
console.log(users);

Copy link
Member Author

Choose a reason for hiding this comment

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

타입 정의에 적용해보겠습니다 감사합니다

const onSubmit: SubmitHandler<FormValues> = async (data) => {
try {
// 실제 API 연결 시 axios/fetch 호출로 교체
await new Promise((r) => setTimeout(r, 1000));
Copy link

@dwkim101 dwkim101 Jul 25, 2025

Choose a reason for hiding this comment

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

nextjs를 활용중이시니 api에 만들어두시고 실제 요청을 쏘시고, (필요하다면)api에서 목데이터를 반환하는건 어떨까요?

@youdaeng2 youdaeng2 merged commit 12b9a3e into dev Jul 26, 2025
3 checks passed
@youdaeng2 youdaeng2 deleted the feature/myprofile branch July 30, 2025 21:59
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.

5 participants