-
Notifications
You must be signed in to change notification settings - Fork 1
Fix/128 QA(1차, 2차) 피드백 및 이슈 해결 #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Warning Rate limit exceeded@LeeCh0129 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 36 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
Walkthrough이 변경 사항은 마이페이지(내 정보, 내 예약, 내 체험 관리, 예약 현황) 관련 UI/UX와 로직을 전반적으로 개선합니다. 주요 내용은 토스트 메시지 도입, 스켈레톤 UI 개선, 카드 클릭 시 상세 페이지 이동, 텍스트 오버플로우 처리, 쿼리 무효화 로직 강화, 입력값 유효성 검사 추가 등입니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ActivityCard
participant Router
User->>ActivityCard: 카드 클릭
ActivityCard->>Router: 상세 페이지로 이동 (/activities/${id})
Note over ActivityCard: 메뉴/버튼 클릭 시<br>stopPropagation으로 카드 클릭 차단
sequenceDiagram
participant User
participant ProfilePage
participant Toast
User->>ProfilePage: 닉네임/비밀번호 입력
ProfilePage->>ProfilePage: 유효성 검사
alt 오류 발생
ProfilePage->>Toast: toast.error("오류 메시지")
end
User->>ProfilePage: 저장 클릭
ProfilePage->>ProfilePage: 저장 성공/실패 후 인풋 초기화
ProfilePage->>Toast: toast.success/error("결과 메시지")
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes(해당 변경 사항에서 요구사항 외의 기능적 코드 변경은 발견되지 않았습니다.) Possibly related PRs
Suggested labels
Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (20)
src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts(3 hunks)src/app/(with-header)/mypage/activities/components/ActivityCard.tsx(4 hunks)src/app/(with-header)/mypage/activities/page.tsx(2 hunks)src/app/(with-header)/mypage/dashboard/components/ReservationInfoModal.tsx(4 hunks)src/app/(with-header)/mypage/dashboard/page.tsx(4 hunks)src/app/(with-header)/mypage/layout.tsx(3 hunks)src/app/(with-header)/mypage/profile/page.tsx(7 hunks)src/app/(with-header)/mypage/reservations/components/ReservationCard.tsx(5 hunks)src/app/(with-header)/mypage/reservations/components/ReviewModal.tsx(4 hunks)src/app/(with-header)/mypage/reservations/page.tsx(3 hunks)src/components/Dropdown.tsx(3 hunks)src/components/FloatingBox/hooks/useBookingMutation.ts(3 hunks)src/hooks/useActivityOptions.ts(1 hunks)src/hooks/useDashboardQueries.ts(3 hunks)src/hooks/useMyActivitiesQueries.ts(2 hunks)src/hooks/useMyPageQueries.ts(3 hunks)src/hooks/useProfileImageUpload.ts(2 hunks)src/hooks/useReservationQueries.ts(3 hunks)src/types/dropdownTypes.ts(1 hunks)src/utils/timeSlotUtils.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
src/components/Dropdown.tsx (1)
src/lib/utils.ts (1)
cn(4-6)
src/hooks/useReservationQueries.ts (2)
src/types/reservationTypes.ts (1)
CreateReviewRequest(51-54)src/apis/reservations.ts (1)
createReview(55-64)
src/app/(with-header)/mypage/dashboard/components/ReservationInfoModal.tsx (1)
src/utils/timeSlotUtils.ts (2)
createFilteredTimeSlotOptions(13-25)getSelectedTimeSlotValue(38-48)
src/app/(with-header)/mypage/layout.tsx (2)
src/app/(with-header)/mypage/page.tsx (1)
MyPageMainPage(19-120)src/app/(with-header)/mypage/components/ProfileNavigation.tsx (1)
ProfileNavigation(19-91)
src/hooks/useActivityOptions.ts (1)
src/types/dashboardTypes.ts (1)
MyActivitiesResponse(19-23)
🪛 Biome (2.1.2)
src/app/(with-header)/mypage/activities/components/ActivityCard.tsx
[error] 38-41: Static Elements should not be interactive.
To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.
(lint/a11y/noStaticElementInteractions)
[error] 38-41: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.
Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.
(lint/a11y/useKeyWithClickEvents)
[error] 100-107: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
🔇 Additional comments (47)
src/types/dropdownTypes.ts (1)
25-25: 텍스트 오버플로우 처리를 위한 속성 추가 승인드롭다운 컴포넌트에서 긴 텍스트 처리를 위한
truncateText옵션 속성이 적절하게 추가되었습니다. 옵셔널 속성으로 구현되어 기존 코드와의 호환성을 유지합니다.src/hooks/useProfileImageUpload.ts (2)
3-3: Toast 알림 라이브러리 import 승인사용자 피드백 개선을 위해
sonner라이브러리의 toast 기능을 import했습니다.
29-29: 사용자 친화적인 오류 알림으로 개선파일 타입 및 크기 검증 실패 시 blocking alert 대신 toast.error를 사용하여 사용자 경험을 개선했습니다. 기존 검증 로직은 그대로 유지되어 기능적 변화는 없습니다.
Also applies to: 35-35
src/hooks/useReservationQueries.ts (4)
8-17: Import 구문 정리 및 toast 추가필요한 타입들과 toast 알림 기능을 체계적으로 import하여 코드 가독성을 개선했습니다.
56-56: 예약 취소 피드백 개선alert 대신 toast 알림을 사용하여 예약 취소 성공/실패 메시지를 non-blocking 방식으로 표시합니다.
Also applies to: 59-59
69-75: mutation 함수 시그니처 가독성 개선후기 작성 mutation의 매개변수를 명시적으로 구조화하여 코드 가독성을 향상시켰습니다.
81-81: 후기 작성 피드백 개선후기 작성 성공/실패 시 toast 알림을 사용하여 사용자 경험을 개선했습니다.
Also applies to: 84-84
src/utils/timeSlotUtils.ts (2)
1-4: 필터링 기능을 위한 타입 import 추가대시보드 필터 옵션 타입을 추가로 import하여 새로운 필터링 함수를 지원합니다.
12-25: 탭별 시간대 필터링 함수 추가활성 탭에 따라 예약이 있는 시간대만 필터링하는 새로운 유틸리티 함수가 적절하게 구현되었습니다. 기존 함수와 일관된 패턴을 따르며, 대시보드 UI 개선 요구사항을 충족합니다.
src/hooks/useDashboardQueries.ts (3)
9-9: Toast 알림 시스템 도입대시보드 관련 작업에서 사용자 피드백 개선을 위해 toast 알림 라이브러리를 import했습니다.
131-137: 예약 상태 업데이트 피드백 개선예약 승인/거절 처리 시 동적 상태 텍스트와 함께 toast 알림을 표시하여 사용자 경험을 개선했습니다. 성공/실패 상황에 따라 적절한 toast 타입을 사용합니다.
Also applies to: 141-141
186-186: 다중 예약 거절 피드백 개선여러 예약을 일괄 거절할 때의 성공/실패 피드백을 toast 알림으로 개선하여 일관된 사용자 경험을 제공합니다.
Also applies to: 190-190
src/app/(with-header)/mypage/dashboard/components/ReservationInfoModal.tsx (4)
3-4: 코드 변경사항 승인
useEffect와useQueryClient추가가 적절합니다. 탭 변경에 따른 상태 관리와 향후 쿼리 무효화를 위한 준비가 잘 되어 있습니다.
57-57: 필터링 로직 개선 승인
createFilteredTimeSlotOptions를 사용하여 활성 탭에 따른 시간대 필터링이 적절히 구현되었습니다. 사용자 경험이 향상될 것입니다.
64-75: 탭 변경 시 유효성 검사 로직 승인탭 변경 시 현재 선택된 스케줄이 유효한지 확인하고 무효한 경우 초기화하는 로직이 잘 구현되었습니다. 사용자 혼란을 방지할 수 있습니다.
89-89: 사용자 피드백 개선 승인
alert를toast.error로 교체하여 더 나은 사용자 경험을 제공합니다. 비차단적인 알림으로 UI 흐름이 개선됩니다.src/hooks/useMyPageQueries.ts (1)
13-13: 사용자 알림 시스템 개선 승인
alert호출을toast알림으로 일관되게 교체하여 사용자 경험이 크게 개선됩니다. 비차단적인 알림으로 더 부드러운 인터랙션을 제공합니다.Also applies to: 69-69, 75-75, 136-136, 142-142
src/components/FloatingBox/hooks/useBookingMutation.ts (1)
1-1: 쿼리 무효화 로직 개선 승인예약 성공 후 예약 관련 쿼리를 무효화하여 UI 데이터 일관성을 보장하는 좋은 개선입니다.
exact: false옵션으로 관련된 모든 예약 쿼리가 적절히 갱신됩니다.Also applies to: 10-10, 28-32
src/components/Dropdown.tsx (1)
37-37: 텍스트 오버플로우 처리 기능 추가 승인
truncateTextprop 추가로 긴 텍스트 처리가 개선됩니다. 기본값false로 하위 호환성을 유지하면서, 필요시 텍스트 잘림과 왼쪽 정렬을 제공하는 좋은 설계입니다.Also applies to: 133-133, 142-146
src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts (1)
5-5: 에러 처리 및 쿼리 무효화 개선 승인
alert를toast.error로 교체하고 쿼리 무효화 로직을 명확하게 정리한 개선사항이 훌륭합니다. 활동 삭제 후 관련 데이터가 적절히 갱신되어 UI 일관성이 보장됩니다.Also applies to: 19-24, 34-39
src/hooks/useMyActivitiesQueries.ts (3)
12-12: 토스트 라이브러리 도입 승인사용자 피드백을 위한
sonner라이브러리 도입이 적절합니다. 다른 파일들과의 일관성을 유지하고 있습니다.
44-52: 쿼리 무효화 로직 강화 승인체험 삭제 시 홈페이지 관련 쿼리들도 무효화하는 로직이 추가되어 데이터 일관성이 개선되었습니다.
exact: false옵션을 사용하여 부분 매칭으로 관련 쿼리들을 효과적으로 무효화합니다.
54-54: 토스트 메시지로 개선된 사용자 피드백기존
alert를toast메시지로 변경하여 사용자 경험이 개선되었습니다. 성공과 오류 메시지 모두 적절한 토스트 타입을 사용하고 있습니다.Also applies to: 57-57
src/app/(with-header)/mypage/reservations/components/ReviewModal.tsx (2)
9-9: 토스트 알림으로 개선된 사용자 피드백
alert대신toast.error를 사용하여 비차단적인 사용자 피드백을 제공합니다. 다른 컴포넌트들과 일관성을 유지하고 있습니다.Also applies to: 41-41, 45-45
97-97: 반응형 텍스트 스타일링 적용모바일 환경에서의 텍스트 크기 조정이 적절히 적용되어 사용자 경험이 개선되었습니다.
Also applies to: 100-100, 103-103
src/app/(with-header)/mypage/dashboard/page.tsx (3)
12-12: 스켈레톤 UI 개선
CalendarSkeleton컴포넌트 도입으로 로딩 상태의 사용자 경험이 개선되었습니다. 기존의 단순한 div 대신 구조화된 스켈레톤을 사용합니다.Also applies to: 72-72
23-27: 훅 사용법 개선
useActivityOptions훅에서 반환되는handleActivityChange함수를 사용하여 로직이 단순화되었습니다. 콜백 함수를 통해 상태 업데이트를 처리하는 방식이 깔끔합니다.
125-126: 드롭다운 텍스트 오버플로우 처리
min-w-0클래스와truncateText={true}속성 추가로 긴 텍스트의 오버플로우 문제가 해결되었습니다. 이는 PR 목표 중 하나인 텍스트 오버플로우 이슈 해결과 일치합니다.src/app/(with-header)/mypage/layout.tsx (2)
13-14: 레이아웃 로직 단순화
useMyProfile훅과 관련 로직을 제거하여 레이아웃의 책임을 단순화했습니다. 프로필 데이터 관리는 개별 페이지에서 처리하도록 책임이 분리되었습니다.Also applies to: 45-45
38-38: Flex 레이아웃 개선
min-w-0클래스 추가로 flex 컨테이너에서의 콘텐츠 크기 조정 문제가 해결되었습니다. 이는 텍스트 오버플로우 방지에 도움이 됩니다.Also applies to: 54-54
src/app/(with-header)/mypage/reservations/page.tsx (1)
167-192: 스켈레톤 UI 상세화 개선기존의 단순한 스켈레톤에서 실제 예약 카드 구조를 반영한 상세한 스켈레톤으로 개선되었습니다. 이미지, 콘텐츠, 버튼 영역을 구분하여 더 나은 로딩 경험을 제공합니다.
Also applies to: 250-274
src/app/(with-header)/mypage/activities/components/ActivityCard.tsx (2)
24-26: 카드 클릭 네비게이션 구현이 적절합니다활동 상세 페이지로의 네비게이션 로직이 명확하고 직관적으로 구현되었습니다.
78-81: 이벤트 전파 차단이 올바르게 구현되었습니다메뉴 버튼 클릭 시 카드 클릭 이벤트가 발생하지 않도록
stopPropagation()을 적절히 사용했습니다.src/app/(with-header)/mypage/activities/page.tsx (2)
89-121: 스켈레톤 UI 개선이 매우 우수합니다실제 카드 레이아웃과 일치하는 상세한 스켈레톤 UI를 구현하여 사용자 경험이 크게 향상되었습니다. 이미지, 별점, 제목, 가격, 버튼 영역까지 세밀하게 구현된 점이 인상적입니다.
187-214: 무한 스크롤 로딩 스켈레톤이 일관성 있게 구현되었습니다초기 로딩과 무한 스크롤 로딩에서 동일한 스켈레톤 UI를 사용하여 일관된 사용자 경험을 제공합니다. 반응형 디자인도 적절히 적용되었습니다.
src/hooks/useActivityOptions.ts (3)
12-16: 훅 인터페이스 개선이 적절합니다
onActivityChange콜백과useQueryClient통합으로 더 유연하고 재사용 가능한 훅이 되었습니다.
38-64: 쿼리 무효화 로직이 포괄적으로 구현되었습니다활동 변경 시 관련된 모든 쿼리(
reservedSchedules,activityReservations,monthlyReservationDashboard)를 무효화하여 데이터 일관성을 보장합니다. 콜백 패턴을 통한 확장성도 우수합니다.
26-31: 옵션 생성 로직이 간소화되었습니다중복 제목 처리 로직이 제거되고 더 직관적인 구조로 개선되었습니다.
value에 ID를 문자열로,label에 제목을 사용하는 방식이 명확합니다.src/app/(with-header)/mypage/reservations/components/ReservationCard.tsx (4)
48-50: 카드 네비게이션이 ActivityCard와 일관성 있게 구현되었습니다활동 상세 페이지로의 네비게이션 로직이 ActivityCard와 동일한 패턴으로 구현되어 사용자 경험의 일관성을 제공합니다.
43-46: 예약 상태 표시 로직이 개선되었습니다체험 완료 여부를 고려한 버튼 및 상태 표시 로직이 더욱 정교해졌습니다. 특히
showExpiredStatus를 통한 만료된 예약 처리가 사용자에게 명확한 정보를 제공합니다.
133-137: 예약 만료 상태 표시가 유용합니다
pending상태이지만 체험이 완료된 경우 "예약 만료" 라벨을 표시하는 것은 사용자에게 현재 예약 상태를 명확히 전달하는 좋은 UX 개선입니다.
108-111: 이벤트 전파 차단이 적절히 구현되었습니다버튼 클릭 시 카드 클릭 이벤트가 발생하지 않도록
stopPropagation()을 사용한 것이 올바른 구현입니다.Also applies to: 120-123
src/app/(with-header)/mypage/profile/page.tsx (5)
8-8: 닉네임 유효성 검사가 추가되어 폼 검증이 강화되었습니다
validateNickname함수를 통한 닉네임 검증으로 사용자 입력의 품질이 향상되었습니다. 블러 이벤트에서의 실시간 검증도 좋은 UX를 제공합니다.Also applies to: 74-79
37-50: API 완료 후 비밀번호 필드 초기화가 보안을 강화합니다성공/실패와 관계없이 API 요청 완료 후 비밀번호 필드와 에러를 초기화하는 것은 보안과 사용자 경험 모두에 도움이 됩니다.
107-121: 저장 버튼 비활성화 로직이 포괄적으로 구현되었습니다API 요청 상태, 유효성 검사 에러 등을 종합적으로 고려한 버튼 비활성화 로직으로 사용자가 잘못된 데이터를 제출하는 것을 효과적으로 방지합니다.
159-196: 로딩 상태 스켈레톤 UI가 상세하게 구현되었습니다제목, 버튼, 각 입력 필드별로 개별적인 스켈레톤을 구현하여 실제 폼 레이아웃과 유사한 로딩 경험을 제공합니다. 다른 MyPage 컴포넌트들과 일관성 있는 패턴입니다.
84-89: 조건부 유효성 검사가 사용자 친화적입니다비밀번호 필드에 값이 있을 때만 유효성 검사를 수행하여 불필요한 에러 메시지를 방지하는 것은 좋은 UX 개선입니다.
Also applies to: 95-104
| <div | ||
| className='flex h-128 w-full max-w-792 cursor-pointer flex-row rounded-3xl border border-gray-300 bg-white transition-shadow hover:shadow-md sm:h-156 lg:h-204' | ||
| onClick={handleCardClick} | ||
| > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
접근성 개선이 필요합니다
정적 분석 도구에서 지적한 대로 접근성 문제가 있습니다. 키보드 네비게이션과 적절한 역할(role) 속성이 필요합니다.
다음과 같이 수정하여 접근성을 개선하세요:
- <div
- className='flex h-128 w-full max-w-792 cursor-pointer flex-row rounded-3xl border border-gray-300 bg-white transition-shadow hover:shadow-md sm:h-156 lg:h-204'
- onClick={handleCardClick}
- >
+ <div
+ className='flex h-128 w-full max-w-792 cursor-pointer flex-row rounded-3xl border border-gray-300 bg-white transition-shadow hover:shadow-md sm:h-156 lg:h-204'
+ onClick={handleCardClick}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ handleCardClick();
+ }
+ }}
+ role="button"
+ tabIndex={0}
+ aria-label={`${title} 활동 상세보기`}
+ >📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div | |
| className='flex h-128 w-full max-w-792 cursor-pointer flex-row rounded-3xl border border-gray-300 bg-white transition-shadow hover:shadow-md sm:h-156 lg:h-204' | |
| onClick={handleCardClick} | |
| > | |
| <div | |
| className='flex h-128 w-full max-w-792 cursor-pointer flex-row rounded-3xl border border-gray-300 bg-white transition-shadow hover:shadow-md sm:h-156 lg:h-204' | |
| onClick={handleCardClick} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| e.preventDefault(); | |
| handleCardClick(); | |
| } | |
| }} | |
| role="button" | |
| tabIndex={0} | |
| aria-label={`${title} 활동 상세보기`} | |
| > |
🧰 Tools
🪛 Biome (2.1.2)
[error] 38-41: Static Elements should not be interactive.
To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.
(lint/a11y/noStaticElementInteractions)
[error] 38-41: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.
Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.
(lint/a11y/useKeyWithClickEvents)
🤖 Prompt for AI Agents
In src/app/(with-header)/mypage/activities/components/ActivityCard.tsx around
lines 38 to 41, the div acting as a clickable card lacks accessibility features.
To fix this, replace the div with a semantic interactive element like a button
or add role="button" to the div, ensure it is focusable by adding tabIndex={0},
and handle keyboard events such as onKeyDown to trigger handleCardClick on Enter
or Space key presses. This will improve keyboard navigation and accessibility
compliance.
| <button | ||
| onClick={handleEdit} | ||
| onClick={(e) => { | ||
| e.stopPropagation(); | ||
| handleEdit(); | ||
| }} | ||
| className='flex h-50 w-full items-center justify-center border-b border-gray-300 px-4 py-3 text-center text-base font-medium text-gray-900 hover:bg-gray-50 sm:h-62 sm:px-46 sm:py-18 sm:text-lg' | ||
| > | ||
| 수정하기 | ||
| </button> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
버튼 타입 명시가 필요합니다
정적 분석에서 지적한 대로 버튼 요소에 명시적인 type 속성이 필요합니다.
<button
+ type="button"
onClick={(e) => {
e.stopPropagation();
handleEdit();
}}동일하게 삭제 버튼에도 적용하세요:
<button
+ type="button"
onClick={(e) => {
e.stopPropagation();
handleDelete();
}}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <button | |
| onClick={handleEdit} | |
| onClick={(e) => { | |
| e.stopPropagation(); | |
| handleEdit(); | |
| }} | |
| className='flex h-50 w-full items-center justify-center border-b border-gray-300 px-4 py-3 text-center text-base font-medium text-gray-900 hover:bg-gray-50 sm:h-62 sm:px-46 sm:py-18 sm:text-lg' | |
| > | |
| 수정하기 | |
| </button> | |
| <button | |
| type="button" | |
| onClick={(e) => { | |
| e.stopPropagation(); | |
| handleEdit(); | |
| }} | |
| className='flex h-50 w-full items-center justify-center border-b border-gray-300 px-4 py-3 text-center text-base font-medium text-gray-900 hover:bg-gray-50 sm:h-62 sm:px-46 sm:py-18 sm:text-lg' | |
| > | |
| 수정하기 | |
| </button> |
🤖 Prompt for AI Agents
In src/app/(with-header)/mypage/activities/components/ActivityCard.tsx around
lines 98 to 106, the button element lacks an explicit type attribute, which can
cause unintended form submissions. Add type="button" to this button and also to
the delete button elsewhere in the file to explicitly specify their behavior and
avoid default submit actions.
src/app/(with-header)/mypage/dashboard/components/ReservationInfoModal.tsx
Outdated
Show resolved
Hide resolved
| <Modal.Content | ||
| zIndex={9999} | ||
| backdropClassName='bg-black/50 max-sm:!items-start max-sm:!justify-start' | ||
| className='!m-0 !h-750 !w-480 !max-w-none !min-w-0 !rounded-xl !p-0 max-sm:!h-full max-sm:!max-h-full max-sm:!w-full max-sm:!rounded-none max-sm:!border-none' | ||
| > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
모달 스타일링 및 레이어링 개선
zIndex={9999}와 backdropClassName을 통해 모달의 레이어링과 반응형 디자인이 개선되었습니다. 특히 모바일에서의 전체 화면 표시를 위한 스타일링이 적절합니다.
하지만 복잡한 Tailwind 클래스 문자열을 개선할 수 있습니다:
- className='!m-0 !h-750 !w-480 !max-w-none !min-w-0 !rounded-xl !p-0 max-sm:!h-full max-sm:!max-h-full max-sm:!w-full max-sm:!rounded-none max-sm:!border-none'
+ className={cn(
+ '!m-0 !h-750 !w-480 !max-w-none !min-w-0 !rounded-xl !p-0',
+ 'max-sm:!h-full max-sm:!max-h-full max-sm:!w-full max-sm:!rounded-none max-sm:!border-none'
+ )}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Modal.Content | |
| zIndex={9999} | |
| backdropClassName='bg-black/50 max-sm:!items-start max-sm:!justify-start' | |
| className='!m-0 !h-750 !w-480 !max-w-none !min-w-0 !rounded-xl !p-0 max-sm:!h-full max-sm:!max-h-full max-sm:!w-full max-sm:!rounded-none max-sm:!border-none' | |
| > | |
| <Modal.Content | |
| zIndex={9999} | |
| backdropClassName='bg-black/50 max-sm:!items-start max-sm:!justify-start' | |
| className={cn( | |
| '!m-0 !h-750 !w-480 !max-w-none !min-w-0 !rounded-xl !p-0', | |
| 'max-sm:!h-full max-sm:!max-h-full max-sm:!w-full max-sm:!rounded-none max-sm:!border-none' | |
| )} | |
| > |
🤖 Prompt for AI Agents
In src/app/(with-header)/mypage/reservations/components/ReviewModal.tsx around
lines 59 to 63, the modal uses a long, complex Tailwind CSS class string for
styling and responsiveness. To improve readability and maintainability, refactor
these class names by extracting them into descriptive variables or using a
utility function to compose the class string. This will simplify the JSX and
make future style adjustments easier.
| onError: (error) => { | ||
| alert(`후기 작성 실패: ${error.message}`); | ||
| }, | ||
| onError: (error) => {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
에러 처리 개선 필요
후기 작성 실패 시 사용자에게 피드백을 제공하지 않는 사일런트 에러 처리가 적용되어 있습니다. 다른 컴포넌트들처럼 토스트 메시지를 사용하는 것이 좋겠습니다.
다음과 같이 토스트 에러 메시지를 추가하는 것을 권장합니다:
+import { toast } from 'sonner';
// 파일 상단에 import 추가 후
- onError: (error) => {},
+ onError: (error) => {
+ toast.error(`후기 작성 실패: ${error.message}`);
+ },📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| onError: (error) => {}, | |
| // At the top of src/app/(with-header)/mypage/reservations/page.tsx | |
| import { toast } from 'sonner'; | |
| // … other imports and code … | |
| // Replace the existing onError handler at line 129: | |
| onError: (error) => { | |
| toast.error(`후기 작성 실패: ${error.message}`); | |
| }, |
🤖 Prompt for AI Agents
In src/app/(with-header)/mypage/reservations/page.tsx at line 129, the onError
handler for the review submission is currently empty, resulting in silent
failure without user feedback. Update the onError function to display a toast
error message to inform the user of the failure, consistent with other
components' error handling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (3)
src/hooks/useMyPageQueries.ts (2)
3-14: import 정렬 실패로 CI가 깨지고 있습니다CI 로그에
simple-import-sort/imports경고가 발생했습니다.sonner추가 이후 전체 import 블록이 규칙(외부 → 내부 → 상대 경로 등)을 만족하지 않아 자동 정렬이 필요합니다.
아래 diff 예시는 한 가지 가능한 정렬 순서이니, 실제로는pnpm lint --fix혹은eslint --fix로 자동 정렬해 주세요.'use client'; -import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { useEffect } from 'react'; -import { toast } from 'sonner'; -import { - getMyProfile, - updateMyProfile, - uploadProfileImage, -} from '@/apis/mypage'; -import { UpdateProfileRequest } from '@/types/mypageTypes'; -import useMyPageStore from '@/stores/MyPage/useMyPageStore'; -import useUserStore from '@/stores/authStore'; +import { useEffect } from 'react'; +import { toast } from 'sonner'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; + +import { + getMyProfile, + updateMyProfile, + uploadProfileImage, +} from '@/apis/mypage'; +import useUserStore from '@/stores/authStore'; +import useMyPageStore from '@/stores/MyPage/useMyPageStore'; +import { UpdateProfileRequest } from '@/types/mypageTypes';정렬 오류가 해결되지 않으면 파이프라인이 계속 실패하므로 꼭 수정 바랍니다.
124-137: 중복 호출·중복 상태 업데이트 제거 필요
mutation.isSuccess처리 구간에서 동일한 코드가 두 번 실행되고 있습니다.
setLoading(false)두 번 호출queryClient.setQueryData(QUERY_KEYS.PROFILE, updatedUser)두 번 호출이는 불필요한 렌더링을 유발하고 가독성을 해칩니다. 한 번만 호출하도록 정리해 주세요.
setUser(updatedUser); - queryClient.setQueryData(QUERY_KEYS.PROFILE, updatedUser); - - setLoading(false); - setGlobalUser(updatedUser); // [추가] 헤더 상태(authStore)도 동기화 - - queryClient.setQueryData(QUERY_KEYS.PROFILE, updatedUser); - - setLoading(false); + queryClient.setQueryData(QUERY_KEYS.PROFILE, updatedUser); + setGlobalUser(updatedUser); // [추가] 헤더 상태(authStore)도 동기화 + setLoading(false);리팩터 후에도 의도한 동작(캐시 갱신·로딩 해제)이 유지되는지 확인 바랍니다.
src/components/Dropdown.tsx (1)
3-192: ESLint 플러그인 누락 해결 및 자동 수정 설정CI에서
eslint-plugin-react-hooks플러그인을 찾지 못해npx eslint --fix가 실패했습니다. 다음을 조치해주세요:
- package.json devDependencies에
eslint-plugin-react-hooks추가// package.json { "devDependencies": { + "eslint-plugin-react-hooks": "^최신버전", // … } }- CI 설정 파일(예: .github/workflows/ci.yml)에서 devDependencies가 설치되도록
npm ci(또는pnpm install --dev) 스텝을 확인- 플러그인 설치 후 import 정렬 및 JSX props 정렬을 자동으로 수정하려면:
npx eslint src/components/Dropdown.tsx --fix
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
src/components/Dropdown.tsx(4 hunks)src/hooks/useMyPageQueries.ts(3 hunks)src/types/dropdownTypes.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/components/Dropdown.tsx (1)
src/lib/utils.ts (1)
cn(4-6)
🪛 GitHub Actions: CI
src/components/Dropdown.tsx
[warning] 3-192: simple-import-sort/imports: Run autofix to sort these imports!; react/jsx-sort-props: Callbacks must be listed after all other props and props should be sorted alphabetically.
src/hooks/useMyPageQueries.ts
[warning] 3-3: simple-import-sort/imports: Run autofix to sort these imports!
🔇 Additional comments (4)
src/hooks/useMyPageQueries.ts (1)
70-77: alert → toast 전환 👍동기화/에러 상황에서
toast.success·toast.error로 교체하여 UX를 비차단형으로 개선한 점이 적절합니다. 동일 패턴이 전체 훅에서 일관되게 적용된 것도 좋습니다.Also applies to: 137-144
src/components/Dropdown.tsx (3)
40-40: 새로운 truncateText prop 추가 확인됨텍스트 오버플로우 처리를 위한
truncateTextprop이 적절히 추가되었습니다. 기본값을false로 설정하여 기존 동작을 유지하는 것도 좋은 접근입니다.
136-136: overflow-hidden 클래스 추가 승인드롭다운 버튼에
overflow-hidden클래스를 항상 적용하는 것은 텍스트 오버플로우 문제 해결을 위한 적절한 접근입니다.
146-150: 조건부 텍스트 잘림 스타일 구현 승인
truncateTextprop에 따라 조건부로flex-1 truncate text-left클래스를 적용하는 로직이 올바르게 구현되었습니다.cn함수를 사용한 클래스 병합도 적절합니다.
| optionClassName?: string; | ||
| truncateText?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
JSDoc 문서에 새로운 속성 설명 추가 필요
truncateText 속성이 추가되었지만 JSDoc 문서에 해당 속성에 대한 설명이 누락되었습니다. 다른 속성들과 일관성을 위해 설명을 추가해주세요.
다음과 같이 JSDoc 문서를 업데이트해주세요:
* @property disableScroll - 스크롤 비활성화 여부
+ * @property truncateText - 텍스트 잘림 처리 활성화 여부
*/🤖 Prompt for AI Agents
In src/types/dropdownTypes.ts around lines 27 to 28, the new property
truncateText lacks a JSDoc description. Add a clear explanation for truncateText
in the existing JSDoc comment block above the interface or type definition,
ensuring it matches the style and detail level of other property descriptions
for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/app/(with-header)/mypage/reservations/page.tsx (1)
123-123: 후기 작성 실패 시 에러 처리 필요현재 빈 onError 핸들러로 인해 사일런트 에러가 발생하고 있으며, TypeScript 린터 오류도 발생합니다.
- onError: (error) => {}, + onError: (error) => { + toast.error('후기 작성에 실패했습니다. 다시 시도해주세요.'); + },파일 상단에
import { toast } from 'sonner';추가가 필요합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/app/(with-header)/mypage/dashboard/components/ReservationInfoModal.tsx(4 hunks)src/app/(with-header)/mypage/reservations/page.tsx(4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/app/(with-header)/mypage/reservations/page.tsx (2)
src/hooks/useReservationQueries.ts (1)
useMyReservations(24-42)src/app/(with-header)/mypage/reservations/components/ReservationCard.tsx (1)
ReservationCard(21-111)
src/app/(with-header)/mypage/dashboard/components/ReservationInfoModal.tsx (1)
src/utils/timeSlotUtils.ts (2)
createFilteredTimeSlotOptions(13-25)getSelectedTimeSlotValue(38-48)
🪛 GitHub Actions: CI
src/app/(with-header)/mypage/reservations/page.tsx
[error] 123-123: @typescript-eslint/no-unused-vars: 'error' is defined but never used. Allowed unused args must match /^_/u.
src/app/(with-header)/mypage/dashboard/components/ReservationInfoModal.tsx
[warning] 3-173: simple-import-sort/imports and react/jsx-sort-props: Run autofix to sort imports. Callbacks must be listed after all other props.
🔇 Additional comments (5)
src/app/(with-header)/mypage/reservations/page.tsx (1)
159-187: 스켈레톤 UI 개선이 잘 구현되었습니다실제 예약 카드 레이아웃과 일치하는 상세한 스켈레톤 UI가 구현되었으며, 반응형 디자인도 적절히 적용되었습니다.
Also applies to: 226-250
src/app/(with-header)/mypage/dashboard/components/ReservationInfoModal.tsx (4)
55-55: 리팩토링 잘 적용됨시간대 옵션 생성 로직을 유틸리티 함수로 분리한 것이 좋습니다. 코드 재사용성과 유지보수성이 향상되었습니다.
61-73: 탭 변경 시 스케줄 유효성 검증 로직 우수함탭 변경 시 현재 선택된 시간대의 유효성을 검사하여 초기화하는 로직이 잘 구현되었습니다. 사용자 경험 개선에 도움이 됩니다.
87-87: 토스트 메시지로 UX 개선 완료브라우저 alert에서 toast 메시지로 변경하여 사용자 경험이 개선되었습니다. PR 목표에 부합하는 좋은 변경사항입니다.
3-3: 파이프라인 오류:eslint-plugin-react-hooks플러그인 누락ESLint 자동 수정(
--fix)을 실행하는 과정에서 다음 오류가 발생했습니다.
“ESLint couldn’t find the plugin "eslint-plugin-react-hooks"”플러그인이 설치되지 않아 임포트 정렬이 자동으로 적용되지 않습니다. 아래 중 하나를 수행해주세요:
npm install eslint-plugin-react-hooks@latest --save-dev명령으로 플러그인 설치 후를 재실행npx eslint src/app/(with-header)/mypage/dashboard/components/ReservationInfoModal.tsx --fix- 플러그인 설치가 어려울 경우, 임포트를 수동으로
simple-import-sort/imports규칙에 맞춰 정렬
| const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = | ||
| useMyReservations(filter || undefined); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
에러 처리가 제거되어 사용자 피드백이 없습니다
useMyReservations 훅에서 error 변수를 제거하여 API 오류 시 사용자에게 알릴 수 없습니다. PR 목표에 따라 토스트 메시지로 에러를 표시해야 합니다.
- const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } =
- useMyReservations(filter || undefined);
+ const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, error } =
+ useMyReservations(filter || undefined);추가로 파일 상단에 토스트 import와 에러 처리 로직이 필요합니다:
import { toast } from 'sonner';
import { useEffect } from 'react';
// 컴포넌트 내부
useEffect(() => {
if (error) {
toast.error('예약 내역을 불러오는데 실패했습니다.');
}
}, [error]);🤖 Prompt for AI Agents
In src/app/(with-header)/mypage/reservations/page.tsx around lines 48 to 49, the
error variable from useMyReservations is not being handled, so API errors do not
provide user feedback. Fix this by destructuring the error variable from
useMyReservations, importing toast from 'sonner' and useEffect from 'react' at
the top of the file, and adding a useEffect hook inside the component that shows
a toast error message when error is truthy.
evaain706
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QA수정 수고많으셨습니다!
minimo-9
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
마지막까지 수정하시느라 고생많으셨습니다!!
BokyungCodes
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QA 많으셨을텐데 다 수정해주셨네요! 너무너무 고생하셨습니다ㅠㅠ
📌 변경 사항 개요
QA 1차, 2차 통합 피드백 및 이슈 해결
마이페이지(정보, 내역, 관리, 현황) 전반적인 UI/UX 개선 및 이슈 해결
📝 상세 내용
🔗 관련 이슈
🖼️ 스크린샷(선택사항)
💡 참고 사항
Summary by CodeRabbit
신규 기능 및 개선
버그 수정 및 사용자 경험 개선
기타