Conversation
Walkthrough이 변경 사항은 이벤트 삭제 기능을 추가하고, 관련 API 및 훅을 정비하며, UI 컴포넌트에 삭제 모드와 검증 콜백을 도입합니다. 이벤트 카드에서 삭제 버튼과 확인 모달이 제공되고, 삭제 성공 시 카드가 즉시 사라집니다. 여러 컴포넌트와 훅의 import 경로와 타입도 일관성 있게 수정되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant MyHostPage
participant EventCard
participant DeleteConfirmModal
participant useEventDeletion(API)
User->>MyHostPage: "삭제" 버튼 클릭(삭제 모드 진입)
MyHostPage->>EventCard: isDelete=true로 렌더링
User->>EventCard: 삭제 아이콘 클릭
EventCard->>DeleteConfirmModal: 모달 오픈
User->>DeleteConfirmModal: "삭제" 버튼 클릭
DeleteConfirmModal->>EventCard: onConfirm 호출
EventCard->>useEventDeletion: mutate(eventId)
useEventDeletion-->>EventCard: 삭제 성공 콜백
EventCard->>MyHostPage: onDeleteSuccess(eventId)
MyHostPage->>MyHostPage: deletedEventIds에 추가, UI에서 카드 제거
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used🧬 Code Graph Analysis (1)src/shared/ui/EventCard.tsx (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
🔇 Additional comments (3)
✨ Finishing Touches
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. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
src/features/event/ui/FileUpload.tsx (1)
24-28: useEffect를 통한 validation 콜백 구현이 올바릅니다.
previewUrl변경 시 부모 컴포넌트에 validation 상태를 알리는 로직이 적절하게 구현되었습니다.성능 최적화를 위해 dependency array에서
onValidationChange를 제거하는 것을 고려해보세요:useEffect(() => { if (onValidationChange) { onValidationChange(!!previewUrl); } - }, [previewUrl, onValidationChange]); + }, [previewUrl]);
onValidationChange는 보통 부모 컴포넌트에서 안정적인 함수 참조로 제공되지만, dependency에서 제거하면 불필요한 재실행을 방지할 수 있습니다.src/entities/event/hook/useEventHook.ts (1)
22-28: 이벤트 삭제 훅이 잘 구현되었습니다!React Query의
useMutation패턴을 올바르게 따르고 있으며, 타입 정의도 적절합니다.추가 제안: 에러 처리나 성공 후 캐시 무효화를 위해
onSuccess와onError옵션을 고려해보세요.예시:
export const useEventDeletion = () => { - return useMutation<ApiResponse<null>, Error, number>({ + const queryClient = useQueryClient(); + return useMutation<ApiResponse<null>, Error, number>({ mutationFn: async (eventId: number) => { return await eventDeletion(eventId); }, + onSuccess: (_, eventId) => { + // 이벤트 목록과 상세 정보 캐시 무효화 + queryClient.invalidateQueries({ queryKey: ['eventList'] }); + queryClient.invalidateQueries({ queryKey: ['eventDetail', eventId] }); + }, }); };src/widgets/host/DeleteConfirmModal.tsx (1)
9-27: 모달 UX 및 접근성 개선을 고려해보세요.현재 구현은 기본적인 기능을 제공하지만, 다음과 같은 개선사항을 추가하면 더 나은 사용자 경험을 제공할 수 있습니다:
- ESC 키로 모달 닫기
- 모달 외부 클릭 시 닫기
- 접근성 속성 추가 (role, aria-label 등)
- 모달이 열릴 때 body 스크롤 방지
다음과 같이 개선할 수 있습니다:
+import { useEffect } from 'react'; import TertiaryButton from '../../../design-system/ui/buttons/TertiaryButton'; const DeleteConfirmModal = ({ isOpen, onClose, onConfirm }: DeleteConfirmModalProps) => { + useEffect(() => { + if (isOpen) { + const handleEsc = (e: KeyboardEvent) => { + if (e.key === 'Escape') onClose(); + }; + document.addEventListener('keydown', handleEsc); + document.body.style.overflow = 'hidden'; + + return () => { + document.removeEventListener('keydown', handleEsc); + document.body.style.overflow = ''; + }; + } + }, [isOpen, onClose]); if (!isOpen) return null; return ( - <div className="fixed inset-0 w-full max-w-lg z-50 flex items-center justify-center mx-auto bg-black bg-opacity-60"> - <div className="bg-white rounded-lg p-6 w-[90%] max-w-md shadow-lg"> + <div + className="fixed inset-0 w-full max-w-lg z-50 flex items-center justify-center mx-auto bg-black bg-opacity-60" + onClick={onClose} + role="dialog" + aria-modal="true" + aria-labelledby="delete-modal-title" + > + <div + className="bg-white rounded-lg p-6 w-[90%] max-w-md shadow-lg" + onClick={(e) => e.stopPropagation()} + > - <h2 className="text-base md:text-lg font-semibold text-black mb-3">이벤트를 삭제하시겠습니까?</h2> + <h2 id="delete-modal-title" className="text-base md:text-lg font-semibold text-black mb-3">이벤트를 삭제하시겠습니까?</h2>src/shared/ui/EventCard.tsx (1)
119-134: 모달 렌더링 최적화를 고려하세요.각 EventCard 내부에 DeleteConfirmModal을 렌더링하는 것은 카드가 많을 때 비효율적일 수 있습니다.
모달을 상위 컴포넌트로 이동하고 필요한 정보만 전달하는 방식을 고려해보세요. 또한 에러 처리에
alert대신 토스트 알림을 사용하면 더 나은 UX를 제공할 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
public/assets/menu/Delete.svgis excluded by!**/*.svgpublic/assets/menu/HomeButton.svgis excluded by!**/*.svg
📒 Files selected for processing (18)
design-system/ui/Header.tsx(2 hunks)design-system/ui/buttons/TertiaryButton.tsx(1 hunks)src/entities/event/api/event.ts(1 hunks)src/entities/event/hook/useEventHook.ts(2 hunks)src/entities/event/hook/useEventListHook.ts(1 hunks)src/features/event/ui/EventFunnel.tsx(1 hunks)src/features/event/ui/EventList.tsx(1 hunks)src/features/event/ui/FileUpload.tsx(2 hunks)src/features/home/hooks/useEventHook.ts(1 hunks)src/pages/dashboard/ui/EventDetailPage.tsx(1 hunks)src/pages/dashboard/ui/EventInfoPage.tsx(1 hunks)src/pages/event/ui/EventDetailsPage.tsx(1 hunks)src/pages/event/ui/create-event/EventInfoPage.tsx(1 hunks)src/pages/menu/ui/myHost/MyHostPage.tsx(2 hunks)src/shared/ui/EventCard.tsx(4 hunks)src/shared/ui/backgrounds/DashboardLayout.tsx(3 hunks)src/shared/ui/backgrounds/TicketHostLayout.tsx(3 hunks)src/widgets/host/DeleteConfirmModal.tsx(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: storybook
🔇 Additional comments (24)
design-system/ui/buttons/TertiaryButton.tsx (1)
14-14: 폰트 크기 변경의 의도를 확인해주세요.small 사이즈에서
text-11을text-10으로 변경하셨는데, 이벤트 삭제 기능과 관련해서 폰트 크기를 줄일 특별한 이유가 있는지 확인이 필요합니다. 디자인 시스템의 일관성을 위해 다른 버튼 컴포넌트들과 동일한 기준을 적용하고 있는지 검토해주세요.src/entities/event/hook/useEventListHook.ts (1)
3-3:Details
✅ Verification successful
import 경로 변경이 올바른지 확인해주세요.
getAllEventsInfinite함수의 import 경로가'../api/eventDetail'에서'../api/event'로 변경되었습니다. 이 변경이 API 모듈 재구성의 일부인지 확인하고, 새 경로에서 함수가 정상적으로 export되고 있는지 검증이 필요합니다.다음 스크립트로 함수의 존재 여부를 확인해보겠습니다:
🏁 Script executed:
#!/bin/bash # getAllEventsInfinite 함수가 새 경로에 올바르게 존재하는지 확인 echo "=== event.ts 파일에서 getAllEventsInfinite 함수 확인 ===" rg -A 5 "export.*getAllEventsInfinite" src/entities/event/api/event.ts echo "=== useEventListHook에서 사용되는 함수 확인 ===" rg -A 2 -B 2 "getAllEventsInfinite" src/entities/event/hook/useEventListHook.tsLength of output: 988
import 경로 및 함수 존재 확인 완료
src/entities/event/api/event.ts에서getAllEventsInfinite가 정상적으로 export되고 있습니다.useEventListHook.ts에서 올바른 경로(../api/event)로 import되고 있습니다.해당 변경사항은 정확하므로 추가 검증이나 수정이 필요 없습니다.
design-system/ui/Header.tsx (1)
1-1:Details
✅ Verification successful
타입 변경으로 인한 호환성을 검증해주세요.
leftButtonLabel의 타입을string에서ReactNode로 변경하여 더 유연한 콘텐츠를 지원할 수 있게 되었습니다. 하지만 이 변경이 기존 사용처들과 호환되는지, 그리고TextButton컴포넌트가ReactNode타입의label을 올바르게 처리할 수 있는지 확인이 필요합니다.다음 스크립트로 호환성을 확인해보겠습니다:
Also applies to: 10-10
🏁 Script executed:
#!/bin/bash # TextButton 컴포넌트의 label prop 타입 확인 echo "=== TextButton 컴포넌트의 label prop 타입 확인 ===" rg -A 10 "interface.*Props" design-system/ui/buttons/TextButton.tsx echo "=== Header 컴포넌트 사용처에서 leftButtonLabel 사용 현황 ===" rg -B 3 -A 3 "leftButtonLabel" --type tsx --type tsLength of output: 655
🏁 Script executed:
#!/bin/bash # TextButton 컴포넌트의 label Prop 타입 재확인 echo "=== TextButton 컴포넌트의 label Prop 타입 확인 ===" rg -A 10 "interface TextButtonProps" design-system/ui/buttons/TextButton.tsx # leftButtonLabel 사용처 탐색 echo "=== 전체 코드베이스에서 leftButtonLabel 사용처 검색 ===" rg -n "leftButtonLabel" .Length of output: 2748
leftButtonLabel 타입 변경 호환성 확인 완료
TextButton 컴포넌트의
labelProp이ReactNode로 정의되어 있어, 문자열뿐 아니라 JSX 요소(예:<img />)도 모두 올바르게 처리합니다. 전체 코드베이스에서leftButtonLabel에 문자열과 ReactNode가 혼용된 사용 사례를 검토한 결과, 호환성 문제가 없음을 확인했습니다.
- TextButtonProps.label: ReactNode로 선언 (
string, JSX 등 모두 허용)- 기존 사용처: 문자열(
"<"등) 및 JSX(<img src=… />) 모두 정상 렌더링 확인해당 타입 변경에 따른 추가 조치는 필요하지 않습니다.
src/features/event/ui/EventList.tsx (1)
3-3:Details
✅ Verification successful
API 함수들의 import 경로 변경이 적절합니다.
getAllEventsInfinite와getCategoryEventsInfinite함수들을eventDetail모듈에서event모듈로 이동한 것은 API 함수들을 통합하는 리팩토링으로 보입니다.다른 파일들에서도 동일한 함수들의 import 경로가 일관성 있게 업데이트되었는지 확인해보겠습니다:
🏁 Script executed:
#!/bin/bash # Description: 코드베이스에서 getAllEventsInfinite와 getCategoryEventsInfinite 함수의 import 경로 확인 echo "=== getAllEventsInfinite 함수 import 확인 ===" rg -A 2 -B 2 "getAllEventsInfinite" echo "=== getCategoryEventsInfinite 함수 import 확인 ===" rg -A 2 -B 2 "getCategoryEventsInfinite" echo "=== 기존 eventDetail 모듈에서의 import 잔재 확인 ===" rg "from.*eventDetail.*event"Length of output: 3563
✔️ API 함수 import 경로 통합 확인 완료
getAllEventsInfinite및getCategoryEventsInfinite가src/entities/event/api/event.ts에서 정상적으로 export됨EventList.tsx와useEventListHook.ts에서 모두 일관되게 새 경로(../api/event)를 사용eventDetail모듈 관련 잔여 import 없음해당 리팩토링을 승인합니다.
src/pages/event/ui/EventDetailsPage.tsx (1)
20-20: useEventDetail 훅의 import 경로 정리가 적절합니다.다른 파일들과 일관성 있게 훅의 import 경로가 정리되어 모듈 구조가 개선되었습니다.
src/pages/dashboard/ui/EventInfoPage.tsx (1)
13-13: import 경로 정리가 일관성 있게 적용되었습니다.다른 파일들과 동일한 패턴으로
useEventDetail훅의 import 경로가 정리되어 코드베이스의 일관성이 향상되었습니다.src/features/event/ui/FileUpload.tsx (2)
4-4: useEffect import 추가가 적절합니다.새로운 validation 콜백 기능을 위해 필요한 import입니다.
11-11: validation 콜백 prop 추가가 잘 설계되었습니다.
onValidationChangeprop을 선택적으로 추가하여 기존 컴포넌트와의 호환성을 유지하면서도 새로운 기능을 제공합니다.src/pages/event/ui/create-event/EventInfoPage.tsx (3)
6-8: 검증 콜백 인터페이스 추가 승인검증 상태 변경을 외부로 알릴 수 있는 선택적 콜백 prop이 적절히 추가되었습니다. TypeScript 타입 정의도 명확합니다.
10-10: 함수 시그니처 업데이트 승인새로운 prop을 구조분해할당으로 받도록 함수 시그니처가 올바르게 업데이트되었습니다.
14-14:Details
✅ Verification successful
검증 콜백 전파 확인
FileUpload 컴포넌트에
onValidationChange콜백이 올바르게 전달되었습니다. 이를 통해 검증 상태를 상위 컴포넌트로 전파할 수 있습니다.FileUpload 컴포넌트가 이 콜백을 올바르게 처리하는지 확인해주세요:
🏁 Script executed:
#!/bin/bash # FileUpload 컴포넌트에서 onValidationChange prop 사용 확인 ast-grep --pattern $'interface $_Props { $$$ onValidationChange?: (isValid: boolean) => void; $$$ }' # FileUpload 컴포넌트에서 콜백 호출 확인 rg -A 5 "onValidationChange" --type tsxLength of output: 175
추가 검증을 위해
FileUpload컴포넌트 파일 위치를 찾고,onValidationChangeprop 정의 및 호출 여부를 확인하는 스크립트를 실행해주세요.
🏁 Script executed:
#!/bin/bash # 1. FileUpload 컴포넌트가 정의된 .tsx 파일 찾기 rg -l "FileUpload" -g '*.tsx' # 2. 찾은 파일들에서 Props 인터페이스에 onValidationChange 정의 확인 rg -C3 "interface .*Props" -g '*.tsx' | sed -n '1,20p' rg -C3 "onValidationChange" -g '*.tsx' # 3. FileUpload 내부에서 콜백이 실제로 호출되는지 확인 rg -C5 "onValidationChange" -g '*.tsx'Length of output: 24592
검증 콜백 전파 확인 완료
src/features/event/ui/FileUpload.tsx에서
FileUploadProps에onValidationChange?: (isValid: boolean) => void가 정의되어 있으며useEffect훅에서previewUrl변경 시onValidationChange(!!previewUrl)를 호출하도록 구현되어 있습니다.따라서 상위 컴포넌트로 검증 상태가 정상 전파됩니다.
src/features/home/hooks/useEventHook.ts (1)
2-2:Details
✅ Verification successful
Import 경로 리팩토링 승인 및 검증 요청
getEventByTag함수의 import 경로가eventDetail에서event모듈로 변경되었습니다. 이는 API 모듈 구조 개선의 일환으로 보입니다.다른 파일들과의 일관성과 새 경로의 유효성을 확인해주세요:
🏁 Script executed:
#!/bin/bash # getEventByTag 함수가 새 경로에 존재하는지 확인 ast-grep --pattern $'export $_ getEventByTag' # 다른 파일들에서 eventDetail에서 event로의 import 경로 변경 확인 rg "from.*event/api/event" --type ts --type tsx rg "from.*event/api/eventDetail" --type ts --type tsxLength of output: 208
아래 스크립트를 실행해
getEventByTag의 새 경로 존재 여부와 전체 import 일관성을 다시 확인해주세요:
🏁 Script executed:
#!/bin/bash # 1) getEventByTag 함수가 새 모듈에서 올바르게 export 되었는지 확인 grep -R "export .*getEventByTag" -n src/entities/event/api/event* # 2) 코드베이스 전반에서 event 모듈 import 현황 확인 grep -R "entities/event/api/event" -n src grep -R "entities/event/api/eventDetail" -n srcLength of output: 521
Import 경로 리팩토링 승인 및 일관성 확인 완료
src/entities/event/api/event.ts에서getEventByTag가 정상적으로 export됨(59번째 줄).useEventHook.ts와EventList.tsx에서../../../entities/event/api/event로 import가 적용되었으며, 더 이상eventDetail경로를 참조하는 import가 없습니다.이상 없습니다.
src/shared/ui/backgrounds/DashboardLayout.tsx (5)
1-2: Import 구문 정리 승인중복된
useStateimport가 제거되고useLocation훅이 추가되었습니다. Import 구문이 깔끔하게 정리되었습니다.
6-6: 홈 버튼 이미지 Import 추가조건부 버튼 표시를 위한 홈 버튼 이미지가 적절히 import되었습니다.
21-27: 조건부 네비게이션 로직 승인홈 페이지에서는 루트('/')로, 다른 페이지에서는 이전 페이지(-1)로 이동하는 로직이 명확하고 직관적입니다.
42-42: 조건부 버튼 표시 구현라우트에 따라 홈 버튼 이미지 또는 '<' 텍스트를 표시하는 로직이 적절히 구현되었습니다.
16-19:Details
✅ Verification successful
라우트 기반 조건부 로직 구현
현재 경로를 확인하여 대시보드 홈 여부를 판단하는 로직이 잘 구현되었습니다.
정규식 패턴이 의도한 라우트를 정확히 매칭하는지 확인해주세요:
🏁 Script executed:
#!/bin/bash # 대시보드 관련 라우트 패턴 확인 rg "/dashboard/" --type ts --type tsx -A 2 -B 2 # 라우팅 설정에서 대시보드 경로 확인 fd "route" --type f | xargs rg "dashboard" -A 3 -B 3Length of output: 5344
정규식 패턴 검증 완료: 대시보드 홈(/dashboard/:id)만 정확히 매칭합니다
라우팅 설정(src/app/routes/routes.ts, Router.tsx)상/dashboard/:id외에는 동일한 수준의 경로가 없으므로,const home = /^\/dashboard\/[^/]+$/.test(location.pathname);은 의도한 대로 첫 번째 레벨 대시보드 홈 경로만 일치시킵니다. 추가 검증 및 수정이 필요하지 않습니다.
src/features/event/ui/EventFunnel.tsx (1)
101-101: EventInfo 단계 검증 요구사항 추가 승인EventInfo 단계에
requireValidation={true}가 추가되어 다른 정보 입력 단계들과 일관성이 맞춰졌습니다. 이벤트 정보 입력은 필수 검증이 필요한 단계이므로 적절한 변경입니다.src/entities/event/hook/useEventHook.ts (2)
1-5: Import 변경사항이 적절합니다!새로운 이벤트 삭제 기능을 위한
useMutation과ApiResponse타입이 올바르게 추가되었고, API 모듈 리팩토링에 따른 import 경로 변경도 일관성 있게 적용되었습니다.
7-7:Details
✅ Verification successful
Export 방식 변경에 대한 확인이 필요합니다.
useEventDetail이 default export에서 named export로 변경되었습니다. 이는 breaking change이므로 모든 사용처가 업데이트되었는지 확인이 필요합니다.다음 스크립트를 실행하여 모든 사용처가 업데이트되었는지 확인하세요:
🏁 Script executed:
#!/bin/bash # Description: useEventDetail의 모든 import가 named import로 변경되었는지 확인 # Test: default import 사용 검색. 기대값: 결과 없음 rg -A 2 "import\s+useEventDetail\s+from.*useEventHook" # Test: named import 사용 검색. 기대값: 모든 사용처가 표시됨 rg -A 2 "import\s+\{.*useEventDetail.*\}\s+from.*useEventHook"Length of output: 825
useEventDetail 명명형(named) export 적용 완료 확인
–
default import구문이 더 이상 존재하지 않음
– 모든 사용처가 아래와 같이import { useEventDetail } from '…/useEventHook'로 업데이트됨
• src/pages/dashboard/ui/EventInfoPage.tsx
• src/pages/dashboard/ui/EventDetailPage.tsx
• src/pages/event/ui/EventDetailsPage.tsxsrc/shared/ui/backgrounds/TicketHostLayout.tsx (1)
3-4: UI 개선사항이 잘 적용되었습니다!홈 버튼 추가로 사용자 네비게이션이 개선되었고, 반응형 텍스트 크기 조정으로 모바일 사용성이 향상되었습니다.
w-full클래스 추가도 적절합니다.Also applies to: 20-20, 27-33, 54-54
src/pages/dashboard/ui/EventDetailPage.tsx (1)
11-11: Import 구문이 올바르게 수정되었습니다!
useEventDetail의 export 방식 변경에 맞춰 import 구문이 적절히 업데이트되었습니다.src/pages/menu/ui/myHost/MyHostPage.tsx (2)
42-52: 삭제 버튼의 조건부 렌더링이 적절합니다.이벤트가 있을 때만 삭제 버튼을 표시하는 것은 좋은 UX 결정입니다.
57-58: 삭제된 이벤트의 로컬 필터링 동작을 확인하세요.현재 구현은 삭제된 이벤트를 로컬 상태로만 관리하여 UI에서 숨깁니다. 페이지 새로고침 시 삭제된 이벤트가 다시 나타날 수 있습니다.
이것이 의도된 동작인지 확인하고, 필요하다면 삭제 성공 후 서버에서 데이터를 다시 가져오는 것을 고려해보세요.
| export const eventDeletion = async (eventId: number) => { | ||
| const response = await axiosClient.delete(`/events/${eventId}`); | ||
| return response.data; | ||
| }; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
함수 리팩토링의 일관성과 타입 안전성을 검토해주세요.
이벤트 삭제 함수가 deleteEvent에서 eventDeletion으로 이름이 변경되고, 타입 어노테이션이 제거되었습니다. 몇 가지 확인이 필요합니다:
- 명명 일관성: 다른 API 함수들과 네이밍 컨벤션이 일치하는지 확인
- 타입 안전성: 명시적인 반환 타입 제거로 인한 타입 추론 문제 가능성
- 사용처 업데이트: 이 함수를 사용하는 모든 곳에서 새 함수명으로 업데이트되었는지 확인
다음 스크립트로 함수 사용처와 일관성을 확인해보겠습니다:
타입 안전성을 위해 명시적인 반환 타입을 유지하는 것을 권장합니다:
-export const eventDeletion = async (eventId: number) => {
- const response = await axiosClient.delete(`/events/${eventId}`);
+export const eventDeletion = async (eventId: number): Promise<ApiResponse<string>> => {
+ const response = await axiosClient.delete<ApiResponse<string>>(`/events/${eventId}`);
return response.data;
};🏁 Script executed:
#!/bin/bash
# 기존 deleteEvent 함수 사용처가 남아있는지 확인
echo "=== 기존 deleteEvent 함수 사용처 확인 ==="
rg -i "deleteEvent" --type ts --type tsx
echo "=== 새로운 eventDeletion 함수 사용처 확인 ==="
rg -i "eventDeletion" --type ts --type tsx
echo "=== API 함수들의 네이밍 패턴 확인 ==="
rg -A 1 "export const.*=" src/entities/event/api/event.tsLength of output: 1097
API 함수 eventDeletion에 명시적 반환 타입 및 제네릭 타입 추가 필요
src/entities/event/api/event.ts 내 다른 API 함수들과 비교했을 때, 반환 타입 어노테이션과 axiosClient.delete 제네릭 타입이 빠져 있어 타입 안전성이 떨어집니다.
확인 및 조치 사항:
- 반환 타입을 명시적으로 선언 (
Promise<ApiResponse<…>>) axiosClient.delete<…>제네릭 타입을 추가- 이 함수를 호출하는 모든 곳이
eventDeletion으로 변경되었는지 재검토
예시 변경안:
-export const eventDeletion = async (eventId: number) => {
- const response = await axiosClient.delete(`/events/${eventId}`);
+export const eventDeletion = async (eventId: number): Promise<ApiResponse<void>> => {
+ const response = await axiosClient.delete<ApiResponse<void>>(`/events/${eventId}`);
return response.data;
};추가로, API 함수 네이밍 컨벤션을 일관되게 유지하고 싶다면
- 동사+주체(예:
deleteEvent,getEventDetail) - 또는 모두 noun+action(예:
eventDeletion,eventDetail)
중 하나로 통일하는 방안을 검토해주세요.
📝 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.
| export const eventDeletion = async (eventId: number) => { | |
| const response = await axiosClient.delete(`/events/${eventId}`); | |
| return response.data; | |
| }; | |
| export const eventDeletion = async (eventId: number): Promise<ApiResponse<void>> => { | |
| const response = await axiosClient.delete<ApiResponse<void>>(`/events/${eventId}`); | |
| return response.data; | |
| }; |
🤖 Prompt for AI Agents
In src/entities/event/api/event.ts around lines 76 to 79, the function
eventDeletion lacks explicit return type annotation and does not specify a
generic type for axiosClient.delete, which reduces type safety. Add a specific
return type, such as Promise<ApiResponse<YourType>>, and include the appropriate
generic type parameter in the delete call. Also, verify that all usage sites
have been updated to use eventDeletion instead of previous function names, and
consider standardizing the naming convention across API functions for
consistency.
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 3
🧹 Nitpick comments (4)
src/features/event/ui/FileUpload.tsx (1)
24-28: useEffect를 통한 validation 콜백 구현이 올바릅니다.
previewUrl변경 시 부모 컴포넌트에 validation 상태를 알리는 로직이 적절하게 구현되었습니다.성능 최적화를 위해 dependency array에서
onValidationChange를 제거하는 것을 고려해보세요:useEffect(() => { if (onValidationChange) { onValidationChange(!!previewUrl); } - }, [previewUrl, onValidationChange]); + }, [previewUrl]);
onValidationChange는 보통 부모 컴포넌트에서 안정적인 함수 참조로 제공되지만, dependency에서 제거하면 불필요한 재실행을 방지할 수 있습니다.src/entities/event/hook/useEventHook.ts (1)
22-28: 이벤트 삭제 훅이 잘 구현되었습니다!React Query의
useMutation패턴을 올바르게 따르고 있으며, 타입 정의도 적절합니다.추가 제안: 에러 처리나 성공 후 캐시 무효화를 위해
onSuccess와onError옵션을 고려해보세요.예시:
export const useEventDeletion = () => { - return useMutation<ApiResponse<null>, Error, number>({ + const queryClient = useQueryClient(); + return useMutation<ApiResponse<null>, Error, number>({ mutationFn: async (eventId: number) => { return await eventDeletion(eventId); }, + onSuccess: (_, eventId) => { + // 이벤트 목록과 상세 정보 캐시 무효화 + queryClient.invalidateQueries({ queryKey: ['eventList'] }); + queryClient.invalidateQueries({ queryKey: ['eventDetail', eventId] }); + }, }); };src/widgets/host/DeleteConfirmModal.tsx (1)
9-27: 모달 UX 및 접근성 개선을 고려해보세요.현재 구현은 기본적인 기능을 제공하지만, 다음과 같은 개선사항을 추가하면 더 나은 사용자 경험을 제공할 수 있습니다:
- ESC 키로 모달 닫기
- 모달 외부 클릭 시 닫기
- 접근성 속성 추가 (role, aria-label 등)
- 모달이 열릴 때 body 스크롤 방지
다음과 같이 개선할 수 있습니다:
+import { useEffect } from 'react'; import TertiaryButton from '../../../design-system/ui/buttons/TertiaryButton'; const DeleteConfirmModal = ({ isOpen, onClose, onConfirm }: DeleteConfirmModalProps) => { + useEffect(() => { + if (isOpen) { + const handleEsc = (e: KeyboardEvent) => { + if (e.key === 'Escape') onClose(); + }; + document.addEventListener('keydown', handleEsc); + document.body.style.overflow = 'hidden'; + + return () => { + document.removeEventListener('keydown', handleEsc); + document.body.style.overflow = ''; + }; + } + }, [isOpen, onClose]); if (!isOpen) return null; return ( - <div className="fixed inset-0 w-full max-w-lg z-50 flex items-center justify-center mx-auto bg-black bg-opacity-60"> - <div className="bg-white rounded-lg p-6 w-[90%] max-w-md shadow-lg"> + <div + className="fixed inset-0 w-full max-w-lg z-50 flex items-center justify-center mx-auto bg-black bg-opacity-60" + onClick={onClose} + role="dialog" + aria-modal="true" + aria-labelledby="delete-modal-title" + > + <div + className="bg-white rounded-lg p-6 w-[90%] max-w-md shadow-lg" + onClick={(e) => e.stopPropagation()} + > - <h2 className="text-base md:text-lg font-semibold text-black mb-3">이벤트를 삭제하시겠습니까?</h2> + <h2 id="delete-modal-title" className="text-base md:text-lg font-semibold text-black mb-3">이벤트를 삭제하시겠습니까?</h2>src/shared/ui/EventCard.tsx (1)
119-134: 모달 렌더링 최적화를 고려하세요.각 EventCard 내부에 DeleteConfirmModal을 렌더링하는 것은 카드가 많을 때 비효율적일 수 있습니다.
모달을 상위 컴포넌트로 이동하고 필요한 정보만 전달하는 방식을 고려해보세요. 또한 에러 처리에
alert대신 토스트 알림을 사용하면 더 나은 UX를 제공할 수 있습니다.
🛑 Comments failed to post (3)
src/entities/event/api/event.ts (1)
76-79: 💡 Verification agent
🧩 Analysis chain
함수 리팩토링의 일관성과 타입 안전성을 검토해주세요.
이벤트 삭제 함수가
deleteEvent에서eventDeletion으로 이름이 변경되고, 타입 어노테이션이 제거되었습니다. 몇 가지 확인이 필요합니다:
- 명명 일관성: 다른 API 함수들과 네이밍 컨벤션이 일치하는지 확인
- 타입 안전성: 명시적인 반환 타입 제거로 인한 타입 추론 문제 가능성
- 사용처 업데이트: 이 함수를 사용하는 모든 곳에서 새 함수명으로 업데이트되었는지 확인
다음 스크립트로 함수 사용처와 일관성을 확인해보겠습니다:
타입 안전성을 위해 명시적인 반환 타입을 유지하는 것을 권장합니다:
-export const eventDeletion = async (eventId: number) => { - const response = await axiosClient.delete(`/events/${eventId}`); +export const eventDeletion = async (eventId: number): Promise<ApiResponse<string>> => { + const response = await axiosClient.delete<ApiResponse<string>>(`/events/${eventId}`); return response.data; };
🏁 Script executed:
#!/bin/bash # 기존 deleteEvent 함수 사용처가 남아있는지 확인 echo "=== 기존 deleteEvent 함수 사용처 확인 ===" rg -i "deleteEvent" --type ts --type tsx echo "=== 새로운 eventDeletion 함수 사용처 확인 ===" rg -i "eventDeletion" --type ts --type tsx echo "=== API 함수들의 네이밍 패턴 확인 ===" rg -A 1 "export const.*=" src/entities/event/api/event.tsLength of output: 1097
API 함수
eventDeletion에 명시적 반환 타입 및 제네릭 타입 추가 필요
src/entities/event/api/event.ts내 다른 API 함수들과 비교했을 때, 반환 타입 어노테이션과axiosClient.delete제네릭 타입이 빠져 있어 타입 안전성이 떨어집니다.확인 및 조치 사항:
- 반환 타입을 명시적으로 선언 (
Promise<ApiResponse<…>>)axiosClient.delete<…>제네릭 타입을 추가- 이 함수를 호출하는 모든 곳이
eventDeletion으로 변경되었는지 재검토예시 변경안:
-export const eventDeletion = async (eventId: number) => { - const response = await axiosClient.delete(`/events/${eventId}`); +export const eventDeletion = async (eventId: number): Promise<ApiResponse<void>> => { + const response = await axiosClient.delete<ApiResponse<void>>(`/events/${eventId}`); return response.data; };추가로, API 함수 네이밍 컨벤션을 일관되게 유지하고 싶다면
- 동사+주체(예:
deleteEvent,getEventDetail)- 또는 모두 noun+action(예:
eventDeletion,eventDetail)
중 하나로 통일하는 방안을 검토해주세요.📝 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.export const eventDeletion = async (eventId: number): Promise<ApiResponse<void>> => { const response = await axiosClient.delete<ApiResponse<void>>(`/events/${eventId}`); return response.data; };🤖 Prompt for AI Agents
In src/entities/event/api/event.ts around lines 76 to 79, the function eventDeletion lacks explicit return type annotation and does not specify a generic type for axiosClient.delete, which reduces type safety. Add a specific return type, such as Promise<ApiResponse<YourType>>, and include the appropriate generic type parameter in the delete call. Also, verify that all usage sites have been updated to use eventDeletion instead of previous function names, and consider standardizing the naming convention across API functions for consistency.src/pages/menu/ui/myHost/MyHostPage.tsx (1)
70-72:
⚠️ Potential issue매개변수 이름을 단수형으로 수정하세요.
onDeleteSuccess콜백의 매개변수 이름이 혼란을 야기할 수 있습니다. 실제로는 단일 ID를 받으므로 복수형 대신 단수형을 사용해야 합니다.-onDeleteSuccess={(deletedEventIds: number) => { - setDeletedEventIds(prev => [...prev, deletedEventIds]); +onDeleteSuccess={(deletedEventId: number) => { + setDeletedEventIds(prev => [...prev, deletedEventId]); }}📝 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.onDeleteSuccess={(deletedEventId: number) => { setDeletedEventIds(prev => [...prev, deletedEventId]); }}🤖 Prompt for AI Agents
In src/pages/menu/ui/myHost/MyHostPage.tsx around lines 70 to 72, the parameter name 'deletedEventIds' suggests it is an array, but the comment indicates it should be a single ID. Rename the parameter to a singular form, such as 'deletedEventId', to accurately reflect that it is a single value, and update its usage accordingly.src/shared/ui/EventCard.tsx (1)
114-114:
⚠️ Potential issue삭제 버튼 클릭 시 이벤트 전파를 중지하세요.
삭제 버튼을 클릭할 때 카드의 onClick 이벤트가 실행되지 않도록 이벤트 전파를 중지해야 합니다.
onClick={() => setIsModalOpen(true)} +onClick={(e) => { + e.stopPropagation(); + setIsModalOpen(true); +}}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/shared/ui/EventCard.tsx at line 114, the onClick handler opens a modal but does not prevent event propagation when clicking the delete button. To fix this, add an event parameter to the delete button's onClick handler and call event.stopPropagation() within it to prevent the click from bubbling up and triggering the card's onClick event.
이벤트 삭제 퍼블리싱
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Style