Skip to content

Conversation

@yoouyeon
Copy link
Contributor

@yoouyeon yoouyeon commented Jan 13, 2026

💻 작업 내용

  • 프로필 이미지 컴포넌트 추가
  • 게스트 토큰 발급과 그룹 헤더 조회 api의 useMock 옵션 제거
  • 프로필 이미지 관련 컴포넌트들을 공용 컴포넌트로 교체
  • Member 타입 수정 (좀 더 느슨하게... falsy 값 처리가 가능한 프로퍼티들을 optional로 변경했습니다)
    (멤버 프로필 컴포넌트 분리 및 API 개선 #16 (comment))

빠른 배포를 위해 coderabbit 리뷰만 받고 머지합니다!

Summary by CodeRabbit

릴리스 노트

  • 리팩터링

    • 멤버 프로필 UI 컴포넌트를 개선하고 재구성했습니다.
    • 프로필 이미지 표시 기능을 최적화하여 여러 크기(소, 중, 대)를 지원하도록 업데이트했습니다.
  • Chores

    • 내부 데이터 모델 및 API 요청 로직을 최적화했습니다.

✏️ Tip: You can customize this high-level summary in your review settings.

- 크기별 프로필 이미지 컴포넌트 추가
- 스토리 추가
- profile, isPaid, paidAt 타입을 옵셔널로 변경 (falsy값 처리가 되어 있음)
- 관련 파일 수정
@yoouyeon yoouyeon self-assigned this Jan 13, 2026
@yoouyeon yoouyeon added 🔨 Refactor 코드 구조 개선 🎨 Design 디자인 관련 작업 labels Jan 13, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 13, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

요약

이 PR은 API 요청에서 모킹 옵션을 제거하고, Member 타입 필드를 선택적으로 변경하며, 새로운 MemberProfileImage 컴포넌트를 도입하고 기존 프로필 렌더링 로직을 리팩토링합니다.

변경 사항

코호트 / 파일 변경 요약
API 호출 정리
src/entities/auth/api/auth.ts, src/entities/group/api/group.ts
axios 호출에서 useMock: true 옵션 제거; 실제 엔드포인트로 직접 요청 전환
Member 타입 업데이트
src/entities/member/model/member.type.ts
profile (string → optional string), isPaid (boolean → optional boolean), paidAt (Date | null → optional Date)로 변경
MemberProfileImage 신규 컴포넌트
src/shared/ui/MemberProfileImage/index.tsx, index.styles.ts, index.stories.ts
크기별 프로필 이미지 렌더링을 위한 새 컴포넌트 추가 (sm/md/lg 사이즈 지원)
UI 리팩토링: 프로필 렌더링
src/features/expense-management/ui/MemberExpenses/index.tsx, index.styles.ts
MemberProfile 컴포넌트로 대체; 스타일 컴포넌트 4개 제거 (ProfileImg, ProfileWrapper, DeleteButtonWrapper, NameText)
프로필 이미지 컴포넌트 통합
src/pages/billDetail/ui/ExpenseMemberItem/index.tsx, index.style.ts
MemberProfileImage 컴포넌트 사용으로 전환; ProfileImg export 제거
스토리 데이터 업데이트
src/pages/memberSetup/ui/AddMember/index.stories.tsx, src/shared/ui/MemberProfile/index.stories.ts
paidAt 값을 null에서 undefined로 변경

관련된 가능성 있는 PR

제안 레이블

✨ Feature

🐰 프로필이 새옷을 입었네
Mock을 벗고 실제로 달려가고
선택적 필드로 유연해지니
컴포넌트 재사용으로 깔끔해졌고
호테기의 정원도 더 아름다워졌네!

🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot requested a review from ongheong January 13, 2026 15:40
@yoouyeon yoouyeon removed the request for review from ongheong January 13, 2026 15:40
@yoouyeon
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jan 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai bot changed the title @coderabbitai 제목 멤버 프로필 컴포넌트 분리 및 API 개선 Jan 13, 2026
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: 2

🤖 Fix all issues with AI agents
In @src/entities/member/model/member.type.ts:
- Around line 9-11: The isPaid field was made optional causing type mismatches;
revert it to a required boolean to restore compatibility: change isPaid?:
boolean to isPaid: boolean in member.type (Member type), and ensure related
types MemberSettlement.isPaid and UpdatePaymentStatusData.isPaid also use
boolean, and confirm consumers (e.g., ExpenseMemberItem using
useState<boolean>(member.isPaid) and the styled component expecting { isPaid:
boolean }) receive a boolean so no undefined is passed.

In @src/shared/ui/MemberProfileImage/index.tsx:
- Around line 4-7: Change the MemberProfileImageProps so src is optional (src?:
string) and update the component usage to accept possibly undefined src and rely
on the existing runtime fallback (src || defaultProfileImg); specifically modify
the MemberProfileImageProps interface and any places that pass member.profile to
the component (e.g., where MemberProfileImage is used) so TypeScript accepts
optional profile values without error, keeping the existing defaultProfileImg
fallback logic unchanged.
🧹 Nitpick comments (4)
src/entities/auth/api/auth.ts (1)

3-8: expiredAt 타입이 실제 응답과 불일치할 수 있습니다.

expiredAtDate로 정의되어 있지만, JSON 응답에서는 날짜가 문자열로 반환됩니다. axios는 자동으로 Date 객체로 변환하지 않으므로, 실제로는 string 타입이 반환될 가능성이 높습니다.

이 PR 범위를 벗어나지만, 향후 string으로 타입을 변경하거나 응답 처리 시 new Date()로 변환하는 것을 고려해 주세요.

src/shared/ui/MemberProfileImage/index.tsx (1)

9-11: alt 속성 누락으로 접근성 저하.

<img> 요소에 alt 속성이 없으면 스크린 리더 사용자에게 이미지 정보가 전달되지 않습니다. 프로필 이미지임을 나타내는 기본 alt 텍스트를 추가하거나, prop으로 받을 수 있도록 하는 것을 권장합니다.

♻️ Proposed fix
-function MemberProfileImage({ src, size }: MemberProfileImageProps) {
-  return <S.Image src={src || defaultProfileImg} $size={size || 'md'} />;
+interface MemberProfileImageProps {
+  src?: string;
+  size?: 'sm' | 'md' | 'lg';
+  alt?: string;
+}
+
+function MemberProfileImage({ src, size = 'md', alt = '프로필 이미지' }: MemberProfileImageProps) {
+  return <S.Image src={src || defaultProfileImg} $size={size} alt={alt} />;
 }
src/shared/ui/MemberProfileImage/index.styles.ts (1)

13-18: object-fit: contain 대신 cover 사용을 권장합니다.

프로필 이미지(아바타)에서 object-fit: contain을 사용하면 이미지 비율에 따라 원형 영역 내에 빈 공간이 생길 수 있습니다. 원형 아바타를 완전히 채우면서 중앙을 기준으로 자연스럽게 크롭하려면 cover가 더 적합합니다.

♻️ 권장 수정
 export const Image = styled.img<ProfileImgProps>`
   width: ${(props) => sizeMap[props.$size]};
   height: ${(props) => sizeMap[props.$size]};
-  object-fit: contain;
+  object-fit: cover;
   border-radius: 50%;
 `;
src/shared/ui/MemberProfileImage/index.stories.ts (1)

16-35: 실제 이미지가 포함된 스토리 추가를 고려해 주세요.

현재 모든 스토리가 빈 src를 사용하여 fallback 상태만 테스트합니다. 실제 이미지 URL을 사용하는 스토리를 추가하면 이미지 로딩 상태와 렌더링을 시각적으로 검증할 수 있습니다.

💡 예시: 실제 이미지가 포함된 스토리
export const WithImage: Story = {
  args: {
    src: 'https://picsum.photos/100',
    size: 'md',
  },
};
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 39f8568 and 5690daa.

📒 Files selected for processing (12)
  • src/entities/auth/api/auth.ts
  • src/entities/group/api/group.ts
  • src/entities/member/model/member.type.ts
  • src/features/expense-management/ui/MemberExpenses/index.styles.ts
  • src/features/expense-management/ui/MemberExpenses/index.tsx
  • src/pages/billDetail/ui/ExpenseMemberItem/index.style.ts
  • src/pages/billDetail/ui/ExpenseMemberItem/index.tsx
  • src/pages/memberSetup/ui/AddMember/index.stories.tsx
  • src/shared/ui/MemberProfile/index.stories.ts
  • src/shared/ui/MemberProfileImage/index.stories.ts
  • src/shared/ui/MemberProfileImage/index.styles.ts
  • src/shared/ui/MemberProfileImage/index.tsx
💤 Files with no reviewable changes (2)
  • src/features/expense-management/ui/MemberExpenses/index.styles.ts
  • src/pages/billDetail/ui/ExpenseMemberItem/index.style.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-12-28T04:24:56.857Z
Learnt from: yoouyeon
Repo: moddo-kr/moddo-frontend PR: 12
File: src/pages/login/LoginEntranceView.tsx:13-20
Timestamp: 2025-12-28T04:24:56.857Z
Learning: Guideline: Do not pass raw numbers for spacing props (e.g., gap, padding, margin) to the Flex component. If the design system uses tokenized spacing (theme.unit[...] ), derive spacing from design tokens instead of hard-coded numbers only if the component expects a direct number. In this case, the correct usage is to pass plain numbers (e.g., 16) directly for spacing props used by Flex, rather than theme.unit[16]. Apply this consistently across TSX files where Flex spacing props are used. This improves readability and ensures consistent spacing values align with design tokens.

Applied to files:

  • src/entities/group/api/group.ts
  • src/shared/ui/MemberProfileImage/index.styles.ts
  • src/shared/ui/MemberProfile/index.stories.ts
  • src/pages/memberSetup/ui/AddMember/index.stories.tsx
  • src/entities/auth/api/auth.ts
  • src/shared/ui/MemberProfileImage/index.tsx
  • src/shared/ui/MemberProfileImage/index.stories.ts
  • src/pages/billDetail/ui/ExpenseMemberItem/index.tsx
  • src/features/expense-management/ui/MemberExpenses/index.tsx
  • src/entities/member/model/member.type.ts
📚 Learning: 2025-12-28T04:21:15.172Z
Learnt from: yoouyeon
Repo: moddo-kr/moddo-frontend PR: 12
File: src/pages/login/LoginEntranceView.styles.tsx:21-26
Timestamp: 2025-12-28T04:21:15.172Z
Learning: LoginEntranceView.styles.tsx와 LoginPage.styles.ts의 LogoImg styled-component는 상태에 따라 분기되는 독립적인 UI에서 사용되며, 미래에 각각 다르게 변경될 가능성을 고려하여 의도적으로 중복 선언되었다. 이러한 경우 공통 모듈 추출보다 중복 유지가 더 적절한 설계이다.

Applied to files:

  • src/shared/ui/MemberProfileImage/index.styles.ts
🧬 Code graph analysis (1)
src/entities/auth/api/auth.ts (1)
public/mockServiceWorker.js (1)
  • response (125-125)
🔇 Additional comments (6)
src/entities/group/api/group.ts (1)

38-44: LGTM!

useMock 옵션 제거가 PR 목적에 맞게 올바르게 적용되었습니다. 함수 시그니처와 반환 값 처리가 유지되어 기존 호출 코드에 영향이 없습니다.

src/entities/auth/api/auth.ts (1)

10-12: LGTM!

useMock 옵션 제거가 PR 목적에 맞게 올바르게 적용되었습니다. group.ts의 변경과 일관성 있게 처리되었습니다.

src/shared/ui/MemberProfile/index.stories.ts (1)

22-22: LGTM!

Member 타입 변경에 맞춰 스토리 데이터가 올바르게 업데이트되었습니다.

Also applies to: 35-35

src/pages/billDetail/ui/ExpenseMemberItem/index.tsx (1)

68-68: LGTM!

MemberProfileImage 컴포넌트로의 교체가 깔끔하게 이루어졌습니다. 컴포넌트 내부에서 falsy한 src에 대한 폴백 처리가 되어 있어 member.profile이 undefined나 빈 문자열이어도 안전하게 동작합니다.

src/pages/memberSetup/ui/AddMember/index.stories.tsx (1)

23-23: LGTM!

Member 타입 변경에 맞춰 스토리 데이터가 올바르게 업데이트되었습니다.

src/features/expense-management/ui/MemberExpenses/index.tsx (1)

17-20: LGTM!

MemberProfile 컴포넌트로의 리팩토링이 깔끔합니다. 프로필 렌더링 로직이 공유 컴포넌트로 위임되어 코드 가독성과 재사용성이 향상되었습니다.

yoouyeon added a commit that referenced this pull request Jan 13, 2026
리뷰: #16 (comment)
- MemberProfile 컴포넌트에서 필요한 props만 받도록 수정
- 타입 변경사항 반영
yoouyeon added a commit that referenced this pull request Jan 13, 2026
다른 타입과의 일관성을 유지하기 위함
리뷰: #16 (comment)
리뷰: #16 (comment)
- MemberProfile 컴포넌트에서 필요한 props만 받도록 수정
- 타입 변경사항 반영

...
다른 타입과의 일관성을 유지하기 위함
리뷰: #16 (comment)
@yoouyeon yoouyeon force-pushed the feat/profile-fallback branch from 4361e33 to 4231dd0 Compare January 13, 2026 16:22
@yoouyeon yoouyeon merged commit 544e48f into hotfix/supabase-mock-api Jan 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🎨 Design 디자인 관련 작업 🔨 Refactor 코드 구조 개선

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants