Skip to content

[Feat] #58 마이페이지 관련 api 연동 - #75

Merged
hdg0116 merged 33 commits into
developfrom
feat/#58-마이페이지-관련-api-연동
May 29, 2026

Hidden character warning

The head ref may contain hidden characters: "feat/#58-\ub9c8\uc774\ud398\uc774\uc9c0-\uad00\ub828-api-\uc5f0\ub3d9"
Merged

hdg0116 merged 33 commits into
developfrom
feat/#58-마이페이지-관련-api-연동

Conversation

@hdg0116

@hdg0116 hdg0116 commented May 28, 2026

Copy link
Copy Markdown
Collaborator

🗒️ PR 타입

  • 기능 추가
  • 기능 삭제
  • 버그 수정
  • 코드 리팩토링
  • 문서 수정
  • 의존성, 환경 변수, 빌드 관련 코드 업데이트

🔗 관련 이슈


📌 작업사항

마이페이지 프로필

  • 내 프로필 조회 API 연동
  • 프로필 사진 렌더링 로직 추가
  • 학과 조회 API 연동 및 학과명 말줄임 처리
  • 학교 이름 파싱 함수 적용
  • 로그아웃 기능 추가

체크리스트 / 선호도

  • 체크리스트 유무 조건별 조회 및 수정 API 연동
  • 룸메이트 선호도 수정 기능 추가

나의 활동 — 내가 쓴 모집글

  • GET /api/v1/posts/me API 연동 (getMyPosts, useMyRecruitPosts)
  • 모집 상태(isClosed)에 따른 뱃지·현재 인원·버튼 톤 분기 처리
  • 상세보기 버튼 클릭 시 모집글 상세 페이지 이동
  • 삭제하기 버튼 클릭 시 AlertDialog 확인 후 삭제 (useDeleteMyPost)

나의 활동 — 소속된 방

  • 내가 속한 룸메이트 그룹 목록 조회 API 연동
  • 방장/멤버 variant 구분 및 내 프로필 훅 분리
  • 방 나가기 기능 및 모달 추가
  • 현재 인원 유틸 함수 구현 및 적용
  • 소속된 방 없을 때 빈 상태 문구 및 카드 UI 수정

정리

  • 1:1 매칭 탭 제거
  • 불필요한 UI 및 사용하지 않는 목데이터 제거
  • 아이콘 및 로고 이미지 추가

📸 스크린샷

구현 완료하자마자 서버가 꺼져서ㅠㅠㅠ 추후에 촬영하겠습니다ㅠㅠㅠ


📣 기타사항 및 코멘트

파일 변경이 너무너무 많아서... 마이페이지쪽 훅이랑 새로생긴 UI, API쪽 파일만 확인해주시면 될 것 같아요ㅠㅠ


✅ 체크리스트

  • 로컬에서 빌드 및 테스트 완료
  • Label 지정 완료
  • 리뷰어 지정 완료
  • 코드 리뷰 반영 완료

Summary by CodeRabbit

  • New Features

    • 내 룸메이트 그룹 조회 및 탈퇴 기능 추가
    • 내 모집글 관리 및 삭제 기능 추가
    • 프로필 편집 및 조회 기능 강화
    • 활동 탭 재설계 (슬라이드 네비게이션 적용)
  • Improvements

    • 선택 필드의 텍스트 오버플로우 및 잘림 처리 개선
    • 프로필 아바타 표시 방식 개선
    • 룸메이트 요청 UI 텍스트 명확화
    • 마이페이지 프로필 정보 표시 업데이트

Review Change Stack

hdg0116 added 30 commits May 28, 2026 05:48
@hdg0116
hdg0116 requested a review from nabbang6 May 28, 2026 20:07
@hdg0116 hdg0116 self-assigned this May 28, 2026
@hdg0116 hdg0116 added 🐞 Fix 버그 해결 ✨ Feature 기능 개발 🔗 API API 관련 작업 🔧 Chore minor work 🔨 Refactor 코드 리팩토링 labels May 28, 2026
@vercel

vercel Bot commented May 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
bangjjack-frontend-dev Ready Ready Preview, Comment May 29, 2026 4:12am

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@hdg0116, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 37 minutes and 45 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 58e81f3b-9b13-449f-83a5-b01f79cbcb59

📥 Commits

Reviewing files that changed from the base of the PR and between 72d7de9 and 4b05272.

📒 Files selected for processing (11)
  • src/constants/labels.ts
  • src/features/mypage/components/MyPageContent.tsx
  • src/features/mypage/components/MyPageEmptyState.tsx
  • src/features/mypage/components/activity/MyActivityRoomList.tsx
  • src/features/mypage/components/activity/MyRecruitPostList.tsx
  • src/features/mypage/components/profile-edit/ProfileEditFields.tsx
  • src/features/mypage/constants/index.ts
  • src/features/mypage/constants/myActivityRoom.constants.ts
  • src/features/mypage/schemas/myProfileEditSchema.ts
  • src/features/mypage/utils/myProfileEditUtils.ts
  • src/features/roommate-group/types/index.ts

Walkthrough

마이페이지 기능을 목 데이터에서 실제 API 연동으로 전환합니다. 프로필 조회/수정, 게시물 조회/삭제, 룸메이트 그룹 조회/탈퇴 API를 추가하고, 프로필 편집과 체크리스트 관리를 서버 연동 훅으로 재구성합니다.

Changes

마이페이지 API 연동 및 프로필 편집 리팩토링

Layer / File(s) Summary
API 계층, 타입, 쿼리 키 정의
src/api/users.ts, src/api/posts.ts, src/api/roommateGroups.ts, src/api/index.ts, src/features/user/types/index.ts, src/features/user/queries/userQueryKeys.ts, src/features/roommate-group/types/index.ts, src/features/roommate-group/queries/roommateGroupQueryKeys.ts, src/features/user/hooks/index.ts
사용자 프로필/게시물/룸메이트 그룹 API 클라이언트 함수 및 관련 타입(UserProfileData, UpdateUserProfileRequest, MyPost, MyRoommateGroup) 정의. React Query 쿼리 키(userQueryKeys.myProfile(), mypageQueryKeys.myPosts(), roommateGroupQueryKeys.me()) 추가.
프로필 편집 타입, 스키마, 상수
src/features/mypage/types/myProfileEditContent.types.ts, src/features/mypage/types/myProfileEditData.types.ts, src/features/mypage/schemas/myProfileEditSchema.ts, src/features/mypage/constants/myProfileEditContent.constants.ts, src/features/mypage/constants/myProfileEditLabels.constants.ts, src/features/mypage/constants/index.ts
프로필 폼 검증 스키마에 departmentId 필드 추가. ProfileEditFieldsPropssetValue 타입 추가. 캠퍼스/성별/기숙사/학기 표시 라벨과 체크리스트 필드 메타 상수 정의. 기본값 객체 확장.
프로필 폼 변환 유틸리티
src/features/mypage/utils/myProfileEditUtils.ts, src/features/mypage/utils/formatPeopleCount.ts, src/features/mypage/utils/index.ts
mapUserProfileToFormValues, mapFormToProfileRequest, createMyChecklistSections, mapMyChecklistSectionsToRequest 등 프로필/체크리스트 데이터 변환 함수. 라벨 역조회, 검증 로직 포함. formatPeopleCount 유틸 추가.
프로필 편집 데이터/저장 훅 및 체크리스트 에디터
src/features/mypage/hooks/useMyProfileEditData.ts, src/features/mypage/hooks/useMyChecklistEditor.ts, src/features/user/hooks/useMyProfile.ts, src/features/user/hooks/useUpdateUserProfile.ts, src/features/onboarding/hooks/useSaveOnboardingChecklist.ts, src/features/mypage/hooks/index.ts
useMyProfileEditData: API 프로필을 폼 값으로 변환 반환. useMyChecklistEditor: 프로필 체크리스트를 섹션으로 변환, 저장 상태 관리. useUpdateUserProfile: 프로필 업데이트 뮤테이션. useSaveOnboardingChecklist: 성공 시 myProfile() 쿼리 무효화.
프로필 편집 UI 컴포넌트
src/features/mypage/components/profile-edit/ProfileEditFields.tsx, src/features/mypage/components/profile-edit/ProfileViewContent.tsx, src/features/mypage/components/profile-edit/ProfileAvatarSection.tsx, src/features/mypage/components/MyProfileEditContent.tsx
ProfileEditFields에서 캠퍼스별 동적 학과 조회. ProfileViewContent, MyProfileEditContent에서 useMyProfileEditData 훅 기반 폼 관리. 저장/수정 버튼 로딩 상태 추가. 이미지 미리보기 URL 정리 로직 개선.
체크리스트 UI 컴포넌트 업데이트
src/features/mypage/components/checklist/MyChecklistContent.tsx
useMyChecklistEditor 반환값 변경(lastUpdated 제거, isSaveDisabled/isSaving 추가). 저장 버튼 disabled 조건 및 라벨 렌더링 업데이트. "마지막 수정" 텍스트 제거.
마이페이지 메인 콘텐츠 및 메뉴
src/features/mypage/components/MyPageContent.tsx, src/features/mypage/components/MyPageProfileCard.tsx, src/features/mypage/components/MyPageMenuSection.tsx
useMyProfileEditData에서 가져온 defaultProfileFormprofileImageUrl 기반으로 프로필 카드 정보 동적 구성. birthYear에서 나이 계산. imageUrl prop 추가. 로그아웃 시 clearAuth() + /login 이동.
활동 탭 슬라이드 레이아웃 리팩토링
src/features/mypage/components/MyActivityContent.tsx, src/features/mypage/components/activity/ActivityTabs.tsx, src/pages/MyActivityPage.tsx
조건부 렌더링에서 translateX 슬라이드 기반 레이아웃으로 변경. "matches" 탭 제거. ActivityTabs에서 하단 언더라인 동적 이동. h-full 클래스 추가.
모집 게시물 목록 API 연동
src/features/mypage/components/activity/MyRecruitPostList.tsx, src/features/mypage/hooks/useMyRecruitPosts.ts, src/features/mypage/hooks/useDeleteMyPost.ts
useMyRecruitPosts 훅으로 API 게시물 조회. useDeleteMyPost로 삭제 뮤테이션. 카드에서 게시물 필드 기반 상태/멤버 수 표시. 상세/삭제 버튼 추가. 알림창 확인 삭제 플로우.
소속 방 목록 API 연동
src/features/mypage/components/activity/MyActivityRoomList.tsx, src/features/mypage/components/activity/RoomCardLayout.tsx, src/features/mypage/components/activity/RoommateMemberList.tsx
useMyRoommateGroups 훅으로 API 그룹 조회. 그룹을 MyActivityRoomMock 형태로 매핑(리더/멤버 구분, variant 설정). 멤버 이름에 프로필 이미지 추가. 탈퇴/철회 확인 다이얼로그 후 leaveRoommateGroup 호출.
룸메이트 그룹 조회/탈퇴 훅 및 쿼리
src/features/roommate-group/hooks/useMyRoommateGroups.ts, src/features/roommate-group/hooks/useLeaveRoommateGroup.ts, src/features/roommate-group/hooks/index.ts, src/features/roommate-group/queries/roommateGroupQueryKeys.ts, src/features/roommate-group/index.ts
룸메이트 그룹 조회 및 탈퇴 React Query 훅. 쿼리 키 정의. 타입 정의(RoommateGroupMember, MyRoommateGroup). 성공 시 쿼리 무효화 처리.
아이콘, 선택 필드, 채팅, 통계 UI 업데이트
src/assets/icons/index.ts, src/components/ui/select-field.tsx, src/features/chat/constants.ts, src/features/chat/components/chat-detail/ChatRoommateInviteSheet.tsx, src/features/mypage/components/activity/ActivityStat.tsx
크라운 아이콘 추가. 드롭다운 트리거에 min-w-0/overflow-hidden/truncate 추가. 채팅 메뉴 "초대" → "요청" 문구 변경. 통계 값을 formatPeopleCount()로 포맷.
목 데이터 정리 및 모듈 내보내기
src/features/mypage/mocks.ts, src/features/mypage/index.ts, src/features/mypage/constants/myActivityRoom.constants.ts
모집글/체크리스트/프로필 관련 목 상수 제거(MY_RECRUIT_POSTS, MY_PROFILE_IMPORTANCE_ITEMS, MY_CHECKLIST_SECTIONS 등). "matches" 탭 제거. 내보내기 정리. 새 훅/타입/상수 모듈 인덱스 추가.
파비콘 업데이트
index.html
파비콘 경로를 /favicon.svg/logo.svg로 변경.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Bangjjack/Bangjjack-Frontend#30: 프로필 편집 UI 구현 및 관련 컴포넌트 시그니처 변경에서 같은 파일 경로(ProfileAvatarSection.tsx, ProfileEditFields.tsx) 수정으로 직접 코드 경로 확장.
  • Bangjjack/Bangjjack-Frontend#67: MyPageContent.tsx의 프로필 카드 표시 이름 로직에서 같은 필드(defaultProfileForm/parseDisplayName(username)) 변경으로 겹침.
  • Bangjjack/Bangjjack-Frontend#54: chat/constants.tsCHAT_INPUT_MENU_ITEMS 수정에서 같은 상수 영역 충돌 가능.

Suggested reviewers

  • nabbang6
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive PR이 이슈 #58의 요구 사항 중 '자신이 속한 룸메이트 그룹 목록 조회 API 연동'을 구현했으나, 북마크/기본 태그/체크리스트 등록 관련 요구사항 일부는 미구현 상태입니다. 이슈 #58의 북마크 API, 기본 태그 조회, 체크리스트 등록 API 연동 요구사항들의 구현 현황을 명확히 하고, 필요시 별도 이슈 분리를 검토하시기 바랍니다.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 마이페이지 API 연동이라는 주요 변경 사항을 명확하게 요약하고 있으며, 이슈 #58을 참고하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿 구조를 따르며, 기능 추가/삭제/버그 수정/리팩토링을 체계적으로 명시하고, 마이페이지 프로필/체크리스트/활동 영역의 작업 사항을 상세히 기술했습니다.
Out of Scope Changes check ✅ Passed 변경사항들이 주로 마이페이지 API 연동, UI 개선, 유틸리티 추가에 집중되어 있으며, 이슈 #58의 범위 내에서 대부분 타당한 범위 내 변경으로 판단됩니다.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#58-마이페이지-관련-api-연동

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

Copy link
Copy Markdown

✅ CI 검증 결과

TypeScript: 통과
ESLint: 통과
Prettier: 실패
Build: 통과

🚨 일부 검증이 실패했습니다. 수정 후 다시 확인해주세요.

@github-actions

Copy link
Copy Markdown

✅ CI 검증 결과

TypeScript: 통과
ESLint: 통과
Prettier: 통과
Build: 통과

🎉 모든 검증을 통과했습니다.

@hdg0116

hdg0116 commented May 29, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
✅ 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.

@hdg0116

hdg0116 commented May 29, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/features/mypage/components/MyProfileEditContent.tsx (1)

84-107: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

프로필 이미지 변경이 서버 요청에 반영되지 않습니다.

  • mapFormToProfileRequest가 만드는 UpdateUserProfileRequestprofileImage/image 필드가 없고(요청 타입 자체에도 없음), submitProfileFormprofilePreviewUrl/File을 페이로드에 넣지 않습니다.
  • updateProfileImage(file)URL.createObjectURL(file)로 미리보기 URL만 바꾸며, 서버 업데이트와 연결되지 않습니다.
  • ProfileAvatarSectiononImageChange/isEditing를 받도록 되어 있으나 실제 구현에서 사용되지 않아(렌더에서는 imageUrl/name만 전달) 이미지 변경 이벤트 경로가 없습니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/mypage/components/MyProfileEditContent.tsx` around lines 84 -
107, The profile image change isn’t sent to the server because
mapFormToProfileRequest/UpdateUserProfileRequest lack any image field and
submitProfileForm only sends form values; updateProfileImage only sets a preview
URL and isn’t connected to the payload, and ProfileAvatarSection isn’t wired to
emit onImageChange. Fix by adding an image field to the UpdateUserProfileRequest
(or an imageId/thumbnail field as your API expects) and update
mapFormToProfileRequest to include that field; in submitProfileForm include the
currently selected File or uploaded image identifier from component state when
calling updateUserProfile; modify updateProfileImage to store the selected File
(e.g., profileImageFile state) in addition to the preview URL and ensure
URL.revokeObjectURL is used when replacing previews; finally pass onImageChange
and isEditing into ProfileAvatarSection so the UI emits the selected image into
updateProfileImage before submitProfileForm runs.
🧹 Nitpick comments (4)
src/features/user/types/index.ts (1)

22-36: ⚡ Quick win

semester/dormitory 등에 유니온 타입 적용을 검토해 주세요.

기존 UserProfilesemester: Semester, dormitory: Dormitory 유니온 타입을 사용하는데, 새로 추가된 UserProfileData(및 UpdateUserProfileRequest)는 동일 필드를 string으로 정의해 타입 안정성이 낮아지고 두 타입 간 표현이 불일치합니다. 이미 상단에서 Semester, Dormitory를 import 하고 있으므로 재사용을 권장합니다.

♻️ 제안 변경 (해당 필드 예시)
-  semester: string;
-  dormitory: string;
+  semester: Semester;
+  dormitory: Dormitory;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/user/types/index.ts` around lines 22 - 36, UserProfileData
currently types semester and dormitory as string which diverges from the
existing UserProfile and reduces type safety; change the types of semester and
dormitory in the UserProfileData type (and mirror the same change in
UpdateUserProfileRequest) from string to the imported union types Semester and
Dormitory respectively, ensure the top-of-file imports for Semester and
Dormitory are used, and run type checks to confirm no other mismatches remain
(refer to the UserProfileData type and UpdateUserProfileRequest symbol names to
locate the changes).
src/api/roommateGroups.ts (1)

5-17: 💤 Low value

경로 상수 사용을 일관성 있게 적용해 주세요.

ROOMMATE_GROUP_API_PATHS를 정의해 me만 상수로 관리하면서 leaveRoommateGroup에서는 경로를 인라인으로 작성해 일관성이 떨어집니다. 경로를 한곳에서 관리하면 오타나 변경 누락을 줄일 수 있습니다.

♻️ 제안 변경
 const ROOMMATE_GROUP_API_PATHS = {
   me: "/roommate-groups/me",
+  leaveMember: (groupId: number) => `/roommate-groups/${groupId}/members/me`,
 } as const;
@@
 export const leaveRoommateGroup = async (groupId: number): Promise<void> => {
-  await apiClient.delete(`/roommate-groups/${groupId}/members/me`);
+  await apiClient.delete(ROOMMATE_GROUP_API_PATHS.leaveMember(groupId));
 };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/roommateGroups.ts` around lines 5 - 17, The file mixes a path
constant (ROOMMATE_GROUP_API_PATHS.me) with an inline route in
leaveRoommateGroup; update ROOMMATE_GROUP_API_PATHS to include the member leave
path (e.g., add a key like memberMe or membersMe with a template placeholder or
function-style pattern) and change leaveRoommateGroup to use that constant
(referencing ROOMMATE_GROUP_API_PATHS and injecting groupId) so all API routes
are managed from the same constant object.
src/features/mypage/types/index.ts (1)

54-62: 💤 Low value

MyActivityMatchMock 정리 대상 여부 재확인

  • MyActivityMatchMocksrc/features/mypage/components/activity/MatchCard.tsx에서 props 타입으로 사용되고, MY_ACTIVITY_MATCHESsrc/features/mypage/components/activity/MyActivityMatchList.tsx에서 사용되고 있습니다.
  • 다만 MyActivityContentMyRecruitPostList/MyActivityRoomList만 렌더하며(src/features/mypage/components/MyActivityContent.tsx), MyActivityTabId"posts" | "rooms"로 제한되어 "matches" 탭은 제거된 상태입니다. "matches" UI가 더 이상 필요 없다면 MyActivityMatchMock만이 아니라 MyActivityMatchList/MatchCard/MY_ACTIVITY_MATCHES까지 함께 정리하는 방향이 맞습니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/mypage/types/index.ts` around lines 54 - 62, MyActivityMatchMock
and related match UI artifacts appear unused because MyActivityTabId only allows
"posts" | "rooms"; verify whether the "matches" tab/UI is intentionally removed
and if so delete the unused types and components: remove MyActivityMatchMock
from src/features/mypage/types/index.ts and then delete or refactor MatchCard
(src/features/mypage/components/activity/MatchCard.tsx), MyActivityMatchList
(src/features/mypage/components/activity/MyActivityMatchList.tsx) and the
MY_ACTIVITY_MATCHES mock; if you intend to keep "matches" functionality instead,
restore MyActivityTabId to include "matches" and ensure MyActivityContent
(src/features/mypage/components/MyActivityContent.tsx) renders
MyActivityMatchList and that props types (MyActivityMatchMock) match MatchCard
usage.
src/features/user/hooks/index.ts (1)

1-3: ⚡ Quick win

상대 경로 export를 @/ alias로 통일해주세요.

Line 1과 Line 3의 ./... export는 현재 규칙과 불일치합니다. alias로 맞추면 경로 일관성이 좋아집니다.

변경 예시
-export { useMyProfile } from "./useMyProfile";
+export { useMyProfile } from "`@/features/user/hooks/useMyProfile`";
 export { useUpdateUserChecklist } from "./useUpdateUserChecklist";
-export { useUpdateUserProfile } from "./useUpdateUserProfile";
+export { useUpdateUserProfile } from "`@/features/user/hooks/useUpdateUserProfile`";
 export { useUserChecklist } from "./useUserChecklist";
 export { useUserProfile } from "./useUserProfile";
 export { useUserTags } from "./useUserTags";

As per coding guidelines "Use @/ import alias to reference src/ directory (avoid relative paths)".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/user/hooks/index.ts` around lines 1 - 3, Update the two relative
exports to use the project alias so paths are consistent with the guideline;
replace the "./useMyProfile" and "./useUpdateUserProfile" exports in this barrel
file with alias imports (e.g. export { useMyProfile } from
"`@/features/user/hooks/useMyProfile`" and export { useUpdateUserProfile } from
"`@/features/user/hooks/useUpdateUserProfile`") while keeping the existing
exported symbols useMyProfile, useUpdateUserChecklist, and useUpdateUserProfile
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/features/mypage/components/activity/MyActivityRoomList.tsx`:
- Around line 111-117: The loading state currently renders a hardcoded English
string "Loading..." inside the isLoading branch (in MyActivityRoomList.tsx)
which breaks localization consistency; add a loading constant (e.g.
MY_JOINED_ROOM_LOADING_MESSAGE) alongside the existing
MY_JOINED_ROOM_ERROR_MESSAGE and MY_JOINED_ROOM_EMPTY_MESSAGE in the same
constants module, import it into MyActivityRoomList, and replace the hardcoded
"Loading..." passed to MyPageEmptyState with that constant (written in Korean)
so all empty/error/loading messages come from the same constants set.
- Around line 157-166: The leaveRoommateGroup call in MyActivityRoomList.tsx
does not provide user feedback or error handling; update the flow to pass
onSuccess and onError handlers (or enhance useLeaveRoommateGroup's default
callbacks) so a toast is shown on success and an error toast/handling runs on
failure. Specifically, when calling leaveRoommateGroup(confirmTarget.roomId)
from the AlertDialogAction, call the mutate API with onSuccess to show a success
toast and invalidate queries (consistent with MyRecruitPostList) and onError to
show an error toast and handle the error; alternatively, add these callbacks
into useLeaveRoommateGroup so leaveRoommateGroup automatically triggers toast
and error handling.

In `@src/features/mypage/components/activity/MyRecruitPostList.tsx`:
- Around line 25-35: Replace the local DORMITORY_LABEL and ROOM_SIZE_LABEL
definitions in MyRecruitPostList with the shared constants from your labels
module and ensure both the label strings and TypeScript types are unified:
update the central labels export to provide DORMITORY_LABEL and ROOM_SIZE_LABEL
typed as Record<Dormitory, string> and Record<RoomSize, string> (not
Record<string,string>), normalize the whitespace in the label strings (choose
the project-standard form—either "1기숙사" or "1 기숙사") and then import those typed
constants into MyRecruitPostList to remove the local duplicates.

In `@src/features/mypage/components/MyPageContent.tsx`:
- Around line 30-33: The current conversion of defaultProfileForm.birthYear to
Number yields 0 for empty string so the fallback MY_PROFILE.age never triggers;
update the logic around birthYear/profileAge to first treat empty or whitespace
birthYear as invalid (e.g., if (!defaultProfileForm.birthYear ||
defaultProfileForm.birthYear.toString().trim() === "") use MY_PROFILE.age),
otherwise parse/validate the year (use parseInt/default to NaN and check
Number.isFinite or a valid year range) before computing new Date().getFullYear()
- birthYear + 1; adjust the variables birthYear and profileAge accordingly so
empty or non-numeric inputs fall back to MY_PROFILE.age.

In `@src/features/mypage/components/MyPageMenuSection.tsx`:
- Around line 47-52: handleConfirm in MyPageMenuSection.tsx only handles
item.type === "logout" so the "withdraw" (회원 탈퇴) flow never triggers; add a
branch for item.type === "withdraw" inside handleConfirm that calls the user
withdrawal mutation/API (e.g. invoke the withdraw/leaveUser function or
withdrawMutation.mutate with necessary params), handle success/failure
(clearAuth() and navigate("/login") on success, show error on failure), and
ensure the dialog is closed after the operation; reference the handleConfirm
function and the item.type checks to add the withdraw logic and hook up the
existing auth cleanup (clearAuth) and navigation (navigate).

In `@src/features/mypage/components/profile-edit/ProfileEditFields.tsx`:
- Around line 112-115: When campus changes the handler currently clears only
"department", leaving a stale "departmentId" value; update the onChange block
(where field.onChange(value) is called) to also reset the departmentId using
setValue("departmentId", <empty_value>, { shouldDirty: true, shouldValidate:
true }) alongside setValue("department", "", ...) so both fields are cleared
(choose the empty value consistent with your form state, e.g., null or "" for
departmentId).

In `@src/features/mypage/utils/myProfileEditUtils.ts`:
- Around line 52-54: 조건문이 values.departmentId를 falsy로 검사해 0을 유효한 값으로 취급하지 못하므로,
myProfileEditUtils.ts 내 해당 if 검사에서 values.departmentId를 단순
논리부정(!values.departmentId)로 판정하지 말고 명시적으로 null/undefined만 검사하도록 변경하세요 (예:
values.departmentId == null 또는 values.departmentId === undefined). 검사 대상은
campus, gender, semester, dormitory, values.departmentId이며, 만약 도메인에서 학과 ID가 0을
허용하지 않는 것이 의도라면 스키마 z.number().int().nonnegative()를 z.number().int().positive()로
변경해 의도를 일치시키세요.

In `@src/features/roommate-group/types/index.ts`:
- Around line 4-9: RoommateGroupMember.profileImage is declared as non-null
string but other types (e.g., UserProfileData / mypage member mocks) allow
string | null, so update the RoommateGroupMember type to accept null (e.g.,
profileImage: string | null or profileImage?: string | null) to match API
contract; update any code using RoommateGroupMember (renderers or mapping
functions) to handle null/undefined profileImage accordingly so null-safe
rendering won't break.

---

Outside diff comments:
In `@src/features/mypage/components/MyProfileEditContent.tsx`:
- Around line 84-107: The profile image change isn’t sent to the server because
mapFormToProfileRequest/UpdateUserProfileRequest lack any image field and
submitProfileForm only sends form values; updateProfileImage only sets a preview
URL and isn’t connected to the payload, and ProfileAvatarSection isn’t wired to
emit onImageChange. Fix by adding an image field to the UpdateUserProfileRequest
(or an imageId/thumbnail field as your API expects) and update
mapFormToProfileRequest to include that field; in submitProfileForm include the
currently selected File or uploaded image identifier from component state when
calling updateUserProfile; modify updateProfileImage to store the selected File
(e.g., profileImageFile state) in addition to the preview URL and ensure
URL.revokeObjectURL is used when replacing previews; finally pass onImageChange
and isEditing into ProfileAvatarSection so the UI emits the selected image into
updateProfileImage before submitProfileForm runs.

---

Nitpick comments:
In `@src/api/roommateGroups.ts`:
- Around line 5-17: The file mixes a path constant (ROOMMATE_GROUP_API_PATHS.me)
with an inline route in leaveRoommateGroup; update ROOMMATE_GROUP_API_PATHS to
include the member leave path (e.g., add a key like memberMe or membersMe with a
template placeholder or function-style pattern) and change leaveRoommateGroup to
use that constant (referencing ROOMMATE_GROUP_API_PATHS and injecting groupId)
so all API routes are managed from the same constant object.

In `@src/features/mypage/types/index.ts`:
- Around line 54-62: MyActivityMatchMock and related match UI artifacts appear
unused because MyActivityTabId only allows "posts" | "rooms"; verify whether the
"matches" tab/UI is intentionally removed and if so delete the unused types and
components: remove MyActivityMatchMock from src/features/mypage/types/index.ts
and then delete or refactor MatchCard
(src/features/mypage/components/activity/MatchCard.tsx), MyActivityMatchList
(src/features/mypage/components/activity/MyActivityMatchList.tsx) and the
MY_ACTIVITY_MATCHES mock; if you intend to keep "matches" functionality instead,
restore MyActivityTabId to include "matches" and ensure MyActivityContent
(src/features/mypage/components/MyActivityContent.tsx) renders
MyActivityMatchList and that props types (MyActivityMatchMock) match MatchCard
usage.

In `@src/features/user/hooks/index.ts`:
- Around line 1-3: Update the two relative exports to use the project alias so
paths are consistent with the guideline; replace the "./useMyProfile" and
"./useUpdateUserProfile" exports in this barrel file with alias imports (e.g.
export { useMyProfile } from "`@/features/user/hooks/useMyProfile`" and export {
useUpdateUserProfile } from "`@/features/user/hooks/useUpdateUserProfile`") while
keeping the existing exported symbols useMyProfile, useUpdateUserChecklist, and
useUpdateUserProfile unchanged.

In `@src/features/user/types/index.ts`:
- Around line 22-36: UserProfileData currently types semester and dormitory as
string which diverges from the existing UserProfile and reduces type safety;
change the types of semester and dormitory in the UserProfileData type (and
mirror the same change in UpdateUserProfileRequest) from string to the imported
union types Semester and Dormitory respectively, ensure the top-of-file imports
for Semester and Dormitory are used, and run type checks to confirm no other
mismatches remain (refer to the UserProfileData type and
UpdateUserProfileRequest symbol names to locate the changes).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1eef4c28-d098-448a-aaa8-ed1b55a8a1ee

📥 Commits

Reviewing files that changed from the base of the PR and between 1f940b4 and 72d7de9.

⛔ Files ignored due to path filters (3)
  • public/logo.svg is excluded by !**/*.svg
  • src/assets/icons/ic-circle-alert.svg is excluded by !**/*.svg
  • src/assets/icons/ic-crown.svg is excluded by !**/*.svg
📒 Files selected for processing (58)
  • index.html
  • src/api/index.ts
  • src/api/posts.ts
  • src/api/roommateGroups.ts
  • src/api/users.ts
  • src/assets/icons/index.ts
  • src/components/ui/select-field.tsx
  • src/features/chat/components/chat-detail/ChatRoommateInviteSheet.tsx
  • src/features/chat/constants.ts
  • src/features/mypage/components/MyActivityContent.tsx
  • src/features/mypage/components/MyPageContent.tsx
  • src/features/mypage/components/MyPageMenuSection.tsx
  • src/features/mypage/components/MyPageProfileCard.tsx
  • src/features/mypage/components/MyProfileEditContent.tsx
  • src/features/mypage/components/activity/ActivityStat.tsx
  • src/features/mypage/components/activity/ActivityTabs.tsx
  • src/features/mypage/components/activity/MyActivityRoomList.tsx
  • src/features/mypage/components/activity/MyRecruitPostList.tsx
  • src/features/mypage/components/activity/RoomCardLayout.tsx
  • src/features/mypage/components/activity/RoommateMemberList.tsx
  • src/features/mypage/components/checklist/MyChecklistContent.tsx
  • src/features/mypage/components/profile-edit/ProfileAvatarSection.tsx
  • src/features/mypage/components/profile-edit/ProfileEditFields.tsx
  • src/features/mypage/components/profile-edit/ProfileViewContent.tsx
  • src/features/mypage/constants/index.ts
  • src/features/mypage/constants/myActivityRoom.constants.ts
  • src/features/mypage/constants/myProfileEditContent.constants.ts
  • src/features/mypage/constants/myProfileEditLabels.constants.ts
  • src/features/mypage/hooks/index.ts
  • src/features/mypage/hooks/useDeleteMyPost.ts
  • src/features/mypage/hooks/useMyChecklistEditor.ts
  • src/features/mypage/hooks/useMyProfileEditData.ts
  • src/features/mypage/hooks/useMyRecruitPosts.ts
  • src/features/mypage/index.ts
  • src/features/mypage/mocks.ts
  • src/features/mypage/queries/mypageQueryKeys.ts
  • src/features/mypage/schemas/myProfileEditSchema.ts
  • src/features/mypage/types/index.ts
  • src/features/mypage/types/myProfileEditContent.types.ts
  • src/features/mypage/types/myProfileEditData.types.ts
  • src/features/mypage/utils/formatPeopleCount.ts
  • src/features/mypage/utils/index.ts
  • src/features/mypage/utils/myProfileEditUtils.ts
  • src/features/onboarding/hooks/useSaveOnboardingChecklist.ts
  • src/features/roommate-group/hooks/index.ts
  • src/features/roommate-group/hooks/useLeaveRoommateGroup.ts
  • src/features/roommate-group/hooks/useMyRoommateGroups.ts
  • src/features/roommate-group/index.ts
  • src/features/roommate-group/queries/index.ts
  • src/features/roommate-group/queries/roommateGroupQueryKeys.ts
  • src/features/roommate-group/types/index.ts
  • src/features/user/hooks/index.ts
  • src/features/user/hooks/useMyProfile.ts
  • src/features/user/hooks/useUpdateUserChecklist.ts
  • src/features/user/hooks/useUpdateUserProfile.ts
  • src/features/user/queries/userQueryKeys.ts
  • src/features/user/types/index.ts
  • src/pages/MyActivityPage.tsx
💤 Files with no reviewable changes (2)
  • src/features/mypage/index.ts
  • src/features/mypage/mocks.ts

Comment thread src/features/mypage/components/activity/MyActivityRoomList.tsx
Comment thread src/features/mypage/components/activity/MyActivityRoomList.tsx
Comment thread src/features/mypage/components/activity/MyRecruitPostList.tsx Outdated
Comment thread src/features/mypage/components/MyPageContent.tsx Outdated
Comment on lines +47 to +52
const handleConfirm = () => {
if (item.type === "logout") {
clearAuth();
navigate("/login");
}
};

@coderabbitai coderabbitai Bot May 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# withdraw 처리 로직/API 존재 여부 확인
rg -nP '\bwithdraw\b' --type=ts --type=tsx -C2
rg -nP '(회원\s*탈퇴|탈퇴)' -C2

Repository: Bangjjack/Bangjjack-Frontend

Length of output: 1305


회원 탈퇴 다이얼로그 확인 시 실제 탈퇴 요청이 연결되지 않음

  • src/features/mypage/components/MyPageMenuSection.tsx에서 handleConfirmlogout만 처리하고, type: "withdraw"(“회원 탈퇴”)는 확인해도 동작 없이 다이얼로그가 닫힙니다.
  • 코드베이스에서 “회원 탈퇴/탈퇴” 관련 탈퇴 API/뮤테이션 호출 근거가 추가로 확인되지 않아, 탈퇴 플로우 구현(또는 비활성/안내 문구 보완) 필요합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/mypage/components/MyPageMenuSection.tsx` around lines 47 - 52,
handleConfirm in MyPageMenuSection.tsx only handles item.type === "logout" so
the "withdraw" (회원 탈퇴) flow never triggers; add a branch for item.type ===
"withdraw" inside handleConfirm that calls the user withdrawal mutation/API
(e.g. invoke the withdraw/leaveUser function or withdrawMutation.mutate with
necessary params), handle success/failure (clearAuth() and navigate("/login") on
success, show error on failure), and ensure the dialog is closed after the
operation; reference the handleConfirm function and the item.type checks to add
the withdraw logic and hook up the existing auth cleanup (clearAuth) and
navigation (navigate).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

회원 탈퇴 기능 유지 여부 아직 미결정 상태

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@hdg0116 이해했습니다! 회원 탈퇴 기능 포함 여부가 확정되면 그때 구현하셔도 됩니다. 해당 기능을 유지하기로 결정하셨을 때 추적이 필요하다면 별도 이슈로 등록해 드릴까요?

Comment thread src/features/mypage/components/profile-edit/ProfileEditFields.tsx
Comment thread src/features/mypage/utils/myProfileEditUtils.ts Outdated
Comment thread src/features/roommate-group/types/index.ts
@github-actions

Copy link
Copy Markdown

✅ CI 검증 결과

TypeScript: 통과
ESLint: 통과
Prettier: 통과
Build: 통과

🎉 모든 검증을 통과했습니다.

@nabbang6 nabbang6 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

확인햇습니당 👍
테스트해보셧을 때 문제없엇다면 바로 머지하셔도 될 것 같아요!! 고생하셧습니당

@hdg0116
hdg0116 merged commit f41c4f5 into develop May 29, 2026
4 checks passed
@hdg0116
hdg0116 deleted the feat/#58-마이페이지-관련-api-연동 branch May 29, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔗 API API 관련 작업 🔧 Chore minor work ✨ Feature 기능 개발 🐞 Fix 버그 해결 🔨 Refactor 코드 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] #58 마이페이지 관련 API 연동

2 participants