feat: (QA/4) 프로필 삭제 구현 - #437
Conversation
Walkthrough프로필 이미지 편집 화면에 선택·삭제 액션을 제공하는 하단 시트를 추가하고, 업로드·패치·삭제 뮤테이션과 시트 상태 및 사용자 정보 쿼리 갱신을 연결합니다. Changes프로필 이미지 편집
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant EditProfile
participant ProfileImageBottomSheet
participant ProfileImageMutation
participant UserInfoQuery
EditProfile->>ProfileImageBottomSheet: 이미지 액션 시트 열기
ProfileImageBottomSheet->>EditProfile: 선택 또는 삭제 이벤트 전달
EditProfile->>ProfileImageMutation: 이미지 업로드·패치·삭제 실행
ProfileImageMutation-->>EditProfile: 작업 성공 결과 반환
EditProfile->>UserInfoQuery: 사용자 정보 쿼리 무효화
EditProfile->>ProfileImageBottomSheet: 시트 닫기
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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
ESLint install failed: private package registry requires authentication. Disable ESLint in CodeRabbit settings or use public packages. 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. Comment |
|
MATEBALL-STORYBOOK |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/pages/edit-profile/edit-profile.tsx (1)
51-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value불필요한 바텀시트 닫기 상태 업데이트를 제거하세요.
handleSelectProfileImage내부에서 이미setIsProfileImageSheetOpen(false)를 호출하여 바텀시트를 닫은 후 파일 선택 창을 띄우고 있습니다. 따라서 파일 업로드(POST) 및 수정(PATCH) 뮤테이션이 완료된 시점에는 바텀시트가 열려 있지 않으므로onSuccess콜백에서 상태를 다시 업데이트할 필요가 없습니다.♻️ 수정 제안
const postProfileImageMutation = useMutation({ ...imageMutations.POST_PROFILE_IMAGE(), onSuccess: ({ profileImageUrl }) => { setProfileImageUrl(profileImageUrl); - setIsProfileImageSheetOpen(false); queryClient.invalidateQueries({ queryKey: USER_KEY.INFO(), }); }, }); const patchProfileImageMutation = useMutation({ ...imageMutations.PATCH_PROFILE_IMAGE(), onSuccess: ({ profileImageUrl }) => { setProfileImageUrl(profileImageUrl); - setIsProfileImageSheetOpen(false); queryClient.invalidateQueries({ queryKey: USER_KEY.INFO(), }); }, });🤖 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/pages/edit-profile/edit-profile.tsx` around lines 51 - 73, Remove the redundant setIsProfileImageSheetOpen(false) calls from the onSuccess callbacks of postProfileImageMutation and patchProfileImageMutation, while preserving the profile image update and USER_KEY.INFO invalidation behavior.src/pages/edit-profile/components/profile-image-bottom-sheet.tsx (1)
25-42: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win버튼의 비활성화 상태 스타일링을 추가하고, 삭제 진행 중에는 앨범 선택을 제한하세요.
현재
disabled속성이 적용되더라도 시각적 변화가 없어 사용자가 비활성화 상태임을 인지하기 어려울 수 있습니다.disabled:opacity-50 disabled:cursor-not-allowed등의 유틸리티 클래스를 추가하여 비활성화 상태를 명확히 표시하는 것을 권장합니다.또한, 삭제(API 통신)가 진행 중일 때 다른 액션(앨범에서 선택)이 실행되지 않도록
isDeleting상태를 앨범 선택 버튼에도 연결해 주는 것이 안전합니다.♻️ 수정 제안
<button type="button" - className="body_16_m w-full cursor-pointer px-[2rem] py-[1.2rem] text-gray-900" + className="body_16_m w-full cursor-pointer px-[2rem] py-[1.2rem] text-gray-900 disabled:opacity-50 disabled:cursor-not-allowed" onClick={onSelectImage} + disabled={isDeleting} > 앨범에서 선택 </button> <div className="h-[0.1rem] bg-gray-300" /> <button type="button" - className="body_16_m w-full cursor-pointer px-[2rem] py-[1.2rem] text-state-error" + className="body_16_m w-full cursor-pointer px-[2rem] py-[1.2rem] text-state-error disabled:opacity-50 disabled:cursor-not-allowed" onClick={onDeleteImage} disabled={!canDelete || isDeleting} >🤖 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/pages/edit-profile/components/profile-image-bottom-sheet.tsx` around lines 25 - 42, Update the album-selection and delete buttons in the profile image bottom sheet to include disabled-state styling such as reduced opacity and a not-allowed cursor. Bind isDeleting to the album-selection button’s disabled state so onSelectImage cannot run while deletion is in progress, while preserving the existing canDelete condition for the delete button.
🤖 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.
Nitpick comments:
In `@src/pages/edit-profile/components/profile-image-bottom-sheet.tsx`:
- Around line 25-42: Update the album-selection and delete buttons in the
profile image bottom sheet to include disabled-state styling such as reduced
opacity and a not-allowed cursor. Bind isDeleting to the album-selection
button’s disabled state so onSelectImage cannot run while deletion is in
progress, while preserving the existing canDelete condition for the delete
button.
In `@src/pages/edit-profile/edit-profile.tsx`:
- Around line 51-73: Remove the redundant setIsProfileImageSheetOpen(false)
calls from the onSuccess callbacks of postProfileImageMutation and
patchProfileImageMutation, while preserving the profile image update and
USER_KEY.INFO invalidation behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 53a11c18-7edd-4bf5-a8c5-edff22bbbc6a
📒 Files selected for processing (2)
src/pages/edit-profile/components/profile-image-bottom-sheet.tsxsrc/pages/edit-profile/edit-profile.tsx
#️⃣ Related Issue
Closes #436
☀️ New-insight
💎 PR Point
프로필 이미지 바텀시트 추가
프로필 이미지를 클릭하면 바로 앨범이 열리지 않고 바텀시트 노출
앨범에서 선택을 누르면 바텀시트를 닫은 뒤 숨겨진 파일 input을 실행
이미지 상태에 따른 API 분기
기본 이미지 상태에서 이미지 등록:
POST /v3/users/profile-image등록된 이미지 변경:
PATCH /v3/users/profile-image등록된 이미지 삭제:
DELETE /v3/users/profile-image기본 이미지 삭제 예외 처리
기본 프로필 이미지 상태에서는 삭제할 사용자 이미지가 없기 때문에 삭제 API를 호출하지 않음
현재는 클릭 자체를 막아놓았고 추후 기획파트와 상의하여 ux 개선 예정
프로필 이미지 캐시 갱신
이미지 등록·수정·삭제 성공 후 프로필 이미지 상태를 업데이트하고, 사용자 정보 쿼리를 무효화하여 다른 화면에서도 변경된 이미지가 반영되도록 구현
📸 Screenshot
Summary by CodeRabbit