Conversation
Walkthrough이번 변경 사항은 대시보드 라우팅, API, 커스텀 훅, 데이터 모델, UI 컴포넌트 및 타입 정의에 걸쳐 업데이트가 이루어졌습니다. 대시보드 경로가 정적 경로에서 동적 파라미터(:id)를 포함하도록 변경되었으며, 이벤트 정보와 참가자 데이터를 조회 및 승인하기 위한 새로운 API 함수와 커스텀 훅들이 추가되었습니다. 또한, 참가자 관리 관련 식별자가 문자열에서 숫자로 업데이트되었고, 이에 따라 관련 타입과 컴포넌트들도 수정되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant 사용자 as User
participant 대시보드 as DashboardPage
participant 훅 as useGetEventHook
participant API as getEventInfo
participant axios as axiosClient
사용자->>대시보드: /dashboard/:id 요청
대시보드->>훅: useGetEventHook 호출
훅->>API: getEventInfo(id) 호출
API->>axios: GET /host-channels/dashboard?eventId=id
axios-->>API: 응답 반환
API-->>훅: 결과 반환
훅-->>대시보드: eventInfo 전달
대시보드->>사용자: 동적 이벤트 정보 렌더링
sequenceDiagram
participant 카드 as ParticipantCard
participant 승인훅 as useApproveParticipants
participant API as approveParticipants
participant 스토어 as useParticipantStore
카드->>승인훅: approveParticipant 호출 (orderNumber 전달)
승인훅->>API: POST /host-channels/dashboard/participant-management/approve
API-->>승인훅: 응답 반환
승인훅->>스토어: 참가자 승인 상태 업데이트
스토어-->>카드: UI 업데이트 반영
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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: 4
🔭 Outside diff range comments (1)
src/app/routes/routes.ts (1)
32-44: 💡 Verification agent🧩 Analysis chain
라우트 일관성 검토 필요
DASHBOARD_ROUTES의 모든 하위 라우트는 이제 동적 매개변수
:id를 포함해야 합니다. 하위 라우트에 누락된 부분이 없는지 확인이 필요합니다.
🏁 Script executed:
#!/bin/bash # DASHBOARD_ROUTES를 사용하는 모든 곳에서 id 파라미터가 올바르게 전달되는지 확인 rg "DASHBOARD_ROUTES\.[a-zA-Z]+" --no-ignore -A 2Length of output: 1611
동적 매개변수
:id추가 필요현재
DASHBOARD_ROUTES의 모든 하위 라우트에 동적 매개변수:id를 포함해야 하는 요구사항이 반영되어 있지 않습니다. 검증 스크립트 결과, 라우트를 사용하는 곳(src/app/routes/Router.tsx,src/pages/dashboard/ui/ticket/TicketListPage.tsx등)에서 그대로 정적 경로를 참조하고 있음을 확인했습니다.
- 수정 대상:
src/app/routes/routes.ts(라인 32-44)
- 모든 하위 라우트 값에 동적 매개변수
:id를 추가하도록 수정해야 합니다.- 확인 필요: 라우트를 사용하는 다른 파일들(예:
src/app/routes/Router.tsx및 페이지 네비게이션 관련 코드)에서도 변경된 동적 경로가 올바르게 처리되는지 점검해야 합니다.예시 변경:
- ticket: `${MAIN_ROUTES.dashboard}/ticket`, + ticket: `${MAIN_ROUTES.dashboard}/:id/ticket`,개별 라우트에 적절한
:id파라미터가 포함되도록 전체 코드의 일관성을 반드시 확인해 주세요.
🧹 Nitpick comments (12)
src/features/dashboard/api/event.ts (1)
3-10: API 함수 구현이 효과적입니다.이벤트 정보를 가져오는 API 함수가 적절하게 구현되었습니다. 하지만 오류 처리나 반환 타입 명시가 없습니다.
다음과 같이 오류 처리 및 반환 타입을 개선할 수 있습니다:
-export const getEventInfo = async (eventId: string) => { +export const getEventInfo = async (eventId: string): Promise<dashboardData> => { try { const response = await axiosClient.get('/host-channels/dashboard', { params: { eventId: eventId, }, }); return response.data.result; + } catch (error) { + console.error('이벤트 정보를 가져오는데 실패했습니다:', error); + throw error; + } };src/features/dashboard/hook/useGetEventHook.ts (1)
6-15: 커스텀 훅 구현이 적절합니다.이벤트 정보를 가져오는 커스텀 훅이 잘 구현되었습니다. React Query를 사용하여 데이터 페칭을 처리하고 있습니다.
다음과 같이 로딩 상태와 오류 처리를 개선할 수 있습니다:
export const useGetEventHook = () => { const { id } = useParams(); - const { data: eventInfo } = useQuery<dashboardData>({ + const { data: eventInfo, isLoading, error } = useQuery<dashboardData>({ queryKey: ['eventInfo', id], queryFn: () => getEventInfo(id as string), }); - return { eventInfo }; + return { eventInfo, isLoading, error }; };src/shared/types/dashboardType.ts (1)
25-35: 새로운 인터페이스가 추가되었습니다.이벤트 정보를 위한 새로운 인터페이스
dashboardData가 추가되었습니다.TypeScript 인터페이스 명명 규칙에 따라 파스칼케이스(PascalCase)를 사용하는 것이 좋습니다:
-export interface dashboardData { +export interface DashboardData { eventName: string; eventStartDate: string; eventStartTime: string; eventEndDate: string; eventEndTime: string; totalTicketCnt: number; totalPrice: number; ticket: boolean; ticketOption: boolean; }src/pages/dashboard/ui/mail/EmailEditPage.tsx (2)
13-14: 참가자 데이터를 가져오는 훅이 사용되었습니다.useParticipants 훅을 사용하여 참가자 데이터를 가져오고 있습니다. 로딩 상태와 오류 처리가 없습니다.
다음과 같이 로딩 상태와 오류 처리를 추가할 수 있습니다:
- const { participants } = useParticipants(); + const { participants, isLoading, error } = useParticipants(); + + if (isLoading) { + return <div>로딩 중...</div>; + } + + if (error) { + return <div>참가자 데이터를 불러오는 중 오류가 발생했습니다.</div>; + }
21-21: 동적 참가자 이메일 목록을 전달합니다.참가자 이메일 목록을 동적으로 가져와
EmailInput컴포넌트에 전달합니다.participants가 undefined일 경우를 대비하여 기본값을 제공하는 것이 좋습니다:
- allParticipantEmails={participants.map(p => p.email)} + allParticipantEmails={(participants || []).map(p => p.email)}src/pages/dashboard/ui/mail/EmailPage.tsx (2)
8-14: 정적 데이터에서 동적 데이터로의 전환 개선정적으로 가져온
participantsInfo에서 동적으로 데이터를 가져오는useParticipants훅으로 변경한 것은 좋은 개선입니다. 하지만 로딩 상태나 에러 처리가 없습니다.import { useParticipants } from '../../../../features/dashboard/hook/useParticipants'; const EmailPage = () => { const navigate = useNavigate(); const [ticketModalOpen, setTicketModalOpen] = useState(false); - const { participants } = useParticipants(); + const { participants, isLoading, error } = useParticipants(); + + // 로딩 상태와 에러 처리 + if (isLoading) return <div>로딩 중...</div>; + if (error) return <div>참가자 정보를 불러오는 중 오류가 발생했습니다.</div>;
18-21: 동적 데이터에 대한 방어적 코딩 필요참가자 데이터가 없는 경우에 대한 처리가 누락되었습니다. 빈 배열이나 undefined 상태를 처리하는 방어적 코딩이 필요합니다.
<EmailInput openSelectTicket={() => setTicketModalOpen(true)} - allParticipantEmails={participants.map(p => p.email)} + allParticipantEmails={participants?.length ? participants.map(p => p.email) : []} />src/widgets/dashboard/ui/EventOverview.tsx (1)
1-3: 인터페이스 구조 개선 및 prop 명명 규칙 검토인터페이스 이름은 파스칼 케이스(PascalCase)를 사용하는 것이 일반적인 TypeScript 관행입니다. 또한 prop 타입을 인라인으로 정의하기보다는 별도로 정의하는 것이 코드 가독성을 높입니다.
-import { dashboardData } from '../../../shared/types/dashboardType'; +import { dashboardData as DashboardData } from '../../../shared/types/dashboardType'; -const EventOverview = ({ eventInfo }: { eventInfo?: dashboardData }) => { +type EventOverviewProps = { + eventInfo?: DashboardData; +}; + +const EventOverview = ({ eventInfo }: EventOverviewProps) => {src/pages/dashboard/ui/ParticipantsMangementPage.tsx (1)
18-18: 로딩 및 에러 상태 처리가 필요할 수 있습니다.
현재useParticipants훅에서isLoading,error를 반환하지만, 해당 상태에 대한 처리가 보이지 않습니다. 사용자에게 로딩 중임을 알리거나 에러 발생 시 대체 UI를 제공하는 방안을 고려해 보세요.src/shared/types/participantInfoType.ts (1)
2-6: 새로운 필드 추가 및 필드명 변경이 잘 정리되었습니다.
participant필드명은 다소 추상적이므로, 실제로 이름을 나타낸다면participantName과 같은 보다 직관적인 이름을 고려하시기 바랍니다.src/features/dashboard/hook/useParticipants.ts (1)
29-38: 상태 동기화 전략을 확인해 보세요.
toggleApproveParticipant만 수행하고participants쿼리를 재검증하지 않으므로, 다른 곳에서 동일 데이터를 사용할 경우 상태가 완전히 동기화되지 않을 수 있습니다. 필요하다면invalidateQueries(['participants'])등을 사용해 API 데이터를 다시 가져오거나, store만으로 전체 상태를 일관성 있게 관리하는 방안을 고려해 보세요.src/features/dashboard/ui/PariticipantsList.tsx (1)
37-39: 중복된 초기화 로직 검토 필요
initializeParticipants함수가 두 개의useEffect에서 호출되고 있습니다. 첫 번째는 컴포넌트 마운트 시, 두 번째는participants변경 시 호출됩니다. 컴포넌트 마운트 시에도participants는 이미 정의되어 있으므로, 첫 번째useEffect는 불필요할 수 있습니다.중복된 초기화 로직을 제거하고 두 번째
useEffect만 유지하는 것이 좋을 것 같습니다:-useEffect(() => { - initializeParticipants(participants); -}, [initializeParticipants]); useEffect(() => { initializeParticipants(participants); }, [participants, initializeParticipants]);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (15)
src/app/routes/routes.ts(2 hunks)src/features/dashboard/api/event.ts(1 hunks)src/features/dashboard/api/participants.ts(1 hunks)src/features/dashboard/hook/useGetEventHook.ts(1 hunks)src/features/dashboard/hook/useParticipants.ts(1 hunks)src/features/dashboard/model/ParticipantStore.tsx(4 hunks)src/features/dashboard/ui/ParicipantCard.tsx(2 hunks)src/features/dashboard/ui/PariticipantsList.tsx(2 hunks)src/pages/dashboard/ui/DashbaordPage.tsx(1 hunks)src/pages/dashboard/ui/ParticipantsMangementPage.tsx(4 hunks)src/pages/dashboard/ui/mail/EmailEditPage.tsx(1 hunks)src/pages/dashboard/ui/mail/EmailPage.tsx(1 hunks)src/shared/types/dashboardType.ts(1 hunks)src/shared/types/participantInfoType.ts(1 hunks)src/widgets/dashboard/ui/EventOverview.tsx(2 hunks)
🧰 Additional context used
🧬 Code Definitions (7)
src/pages/dashboard/ui/mail/EmailPage.tsx (1)
src/features/dashboard/hook/useParticipants.ts (1)
useParticipants(9-27)
src/pages/dashboard/ui/mail/EmailEditPage.tsx (1)
src/features/dashboard/hook/useParticipants.ts (1)
useParticipants(9-27)
src/pages/dashboard/ui/ParticipantsMangementPage.tsx (1)
src/features/dashboard/hook/useParticipants.ts (1)
useParticipants(9-27)
src/widgets/dashboard/ui/EventOverview.tsx (1)
src/shared/types/dashboardType.ts (1)
dashboardData(25-35)
src/features/dashboard/ui/PariticipantsList.tsx (2)
src/shared/types/participantInfoType.ts (1)
participantsData(1-11)src/features/dashboard/model/ParticipantStore.tsx (1)
useParticipantStore(14-73)
src/features/dashboard/ui/ParicipantCard.tsx (2)
src/features/dashboard/model/ParticipantStore.tsx (1)
useParticipantStore(14-73)src/features/dashboard/hook/useParticipants.ts (1)
useApproveParticipants(29-38)
src/pages/dashboard/ui/DashbaordPage.tsx (1)
src/features/dashboard/hook/useGetEventHook.ts (1)
useGetEventHook(6-15)
🔇 Additional comments (25)
src/shared/types/dashboardType.ts (1)
38-38: 경로 업데이트가 적절합니다.대시보드 메뉴 경로가 '/dashboard/'로 업데이트되었습니다.
src/pages/dashboard/ui/mail/EmailEditPage.tsx (1)
8-8: useParticipants 훅을 사용하여 동적 데이터 처리로 변경했습니다.정적 데이터 대신
useParticipants훅을 사용하여 참가자 데이터를 동적으로 가져오도록 변경했습니다.src/features/dashboard/api/participants.ts (1)
3-4:Details
❓ Verification inconclusive
하드코딩된 기본값 사용에 주의
eventId의 기본값이 1로 하드코딩되어 있습니다. 이는 다양한 이벤트를 처리할 때 문제가 될 수 있습니다. 호출하는 컴포넌트에서 항상eventId를 명시적으로 전달하는 것이 좋습니다.
🏁 Script executed:
#!/bin/bash # 이 함수가 어떻게 사용되는지 확인 rg -A 2 "getParticipants\(" --no-ignoreLength of output: 256
핵심: 현재 호출부에서는
eventId가 명시적으로 전달되고 있으나, 기본값(1) 유지로 인한 향후 리스크에 주의가 필요합니다.
src/features/dashboard/api/participants.ts에서getParticipants함수의 파라미터 기본값으로eventId가 1로 설정되어 있습니다.src/features/dashboard/hook/useParticipants.ts에서는 함수 호출 시{ eventId, tags, page, size }와 같이 인자를 명시적으로 전달하고 있어, 현재 사용 사례에서는 문제 없이 동작합니다.- 다만, 만약 다른 곳에서 인자를 누락하고 호출할 경우, 의도치 않은 기본값이 사용될 수 있으므로, 향후 다양한 이벤트를 처리할 때 혼란을 방지하기 위해 기본값 제거 또는 반드시 인자를 전달하도록 로직을 보완하는 것을 고려해 주세요.
src/app/routes/routes.ts (1)
8-8:Details
❓ Verification inconclusive
동적 라우트로의 변경에 따른 영향 검토 필요
대시보드 라우트를 정적 경로에서 동적 매개변수를 포함하는 경로로 변경했습니다. 이는 대시보드 관련 모든 컴포넌트에 영향을 줄 수 있습니다.
🏁 Script executed:
#!/bin/bash # 대시보드 관련 컴포넌트들이 이 라우트 변경에 맞게 업데이트되었는지 확인 rg "useNavigate.*dashboard" --no-ignoreLength of output: 41
동적 대시보드 라우트 검증 필요
현재
useNavigate를 통한 대시보드 경로 참조 검색 결과가 나타나지 않아, 새로운 동적 라우트(/dashboard/:id)가 대시보드 관련 컴포넌트에 제대로 반영되었는지 확신하기 어렵습니다.
- 대시보드 관련 컴포넌트들이
/dashboard/:id경로 사용에 맞춰 업데이트되었는지 수동 검토가 필요합니다.- 추가 검증을 위해 전체 코드베이스에서
/dashboard/:id패턴 혹은 다른 관련 참조(예:<Link>사용 등)를 확인해주시기 바랍니다.src/pages/dashboard/ui/ParticipantsMangementPage.tsx (3)
9-9: 커스텀 훅 도입을 통한 데이터 소스 전환이 적절합니다.
useParticipants훅을 통해 동적으로 데이터를 받아오도록 설정한 점이 좋습니다.
38-38: 동적 데이터 전달 로직이 잘 반영되었습니다.
ParticipantsList에 동적으로 가져온participants배열을 넘기는 접근이 적절합니다.
56-56: 이메일 배열 매핑 로직이 효과적입니다.
participants.map(p => p.email)을 통해 이메일 목록만 추출하는 구현이 명확합니다.src/features/dashboard/hook/useParticipants.ts (1)
1-7: React Query 및 API 함수 임포트가 적절합니다.
외부 라이브러리와 필요한 함수들을 간결히 불러오고 있어, 가독성과 유지보수에 유리합니다.src/pages/dashboard/ui/DashbaordPage.tsx (4)
7-9: 훅을 사용한 이벤트 데이터 가져오기 구현 잘되었습니다.이벤트 정보를 가져오기 위한
useGetEventHook의 통합이 잘 이루어졌습니다. 라우터의 URL 파라미터에서 id를 가져와 이벤트 정보를 조회하는 패턴이 적절합니다.
14-14: 이벤트 이름에 대한 Fallback 처리가 좋습니다.이벤트 이름이 없을 경우 '이벤트 이름 없음'으로 표시하는 fallback 처리가 잘 되어 있습니다. 사용자 경험 측면에서 좋은 접근입니다.
16-16: 이벤트 정보 Props 전달 확인EventOverview 컴포넌트에 eventInfo를 props로 전달하는 방식이 명확합니다.
21-27: 티켓 판매 및 금액 표시 로직 개선티켓 판매 수와 판매 금액에 대한 동적 표시가 잘 구현되었습니다. 값이 없는 경우 '-'로 처리하는 fallback 패턴도 좋습니다.
src/features/dashboard/model/ParticipantStore.tsx (5)
10-11: 타입 변경이 일관되게 적용되었습니다.
ticketNum: string에서orderNumber: number로의 타입 변경이 인터페이스에 잘 반영되었습니다. 이 변경은 데이터 모델의 일관성을 향상시키며, 숫자형 식별자를 사용하는 것이 적절합니다.
22-24: 초기화 로직 업데이트 확인참가자 초기화 로직이
orderNumber를 사용하도록 업데이트되었습니다. 타입 시스템에서는number로 선언되었지만, 객체 키로 사용될 때 자동으로 문자열로 변환되므로Record<string, boolean>타입은 유효합니다.Also applies to: 26-29
40-43: toggleAll 메서드 업데이트 확인
toggleAll메서드에서orderNumber를 사용하도록 코드가 일관되게 업데이트되었습니다.
48-63: toggleParticipant 메서드 파라미터 타입 변경
toggleParticipant메서드의 파라미터가orderNumber: number로 변경되었고, 내부 로직도 이에 맞게 잘 수정되었습니다.
65-72: toggleApproveParticipant 메서드 파라미터 타입 변경
toggleApproveParticipant메서드의 파라미터가orderNumber: number로 변경되었고, 승인 상태를true로 설정하는 로직도 올바르게 구현되었습니다.src/features/dashboard/ui/ParicipantCard.tsx (4)
7-7: 승인 로직 개선 - useMutation 패턴 적용
toggleApproveParticipant대신useApproveParticipants훅을 사용하여 API 호출 후 상태 업데이트를 처리하는 패턴으로 변경한 것은 좋은 접근입니다. 이는 서버 상태와 클라이언트 상태의 동기화를 보장하는 데 도움이 됩니다.Also applies to: 16-19
26-33: 참가자 정보 표시 업데이트참가자 정보 표시가 새로운 데이터 구조에 맞게 업데이트되었습니다.
orderNumber,participant,phoneNumber등의 프로퍼티 이름이 일관되게 변경되었습니다.
37-51: 확인하기 버튼 네비게이션 로직 개선확인하기 버튼 클릭 시 네비게이션 로직이 개선되었습니다. 상태 전달 시
participant속성을 사용하는 것이 데이터 구조와 일관성을 유지합니다.
54-64: 승인 상태 확인 및 버튼 로직 수정승인 상태 확인 로직이
participant.orderNumber를 사용하도록 변경되었습니다. 승인 버튼 클릭 시approveParticipant함수에orderId객체를 전달하는 방식으로 구현된 것이 적절합니다.src/features/dashboard/ui/PariticipantsList.tsx (4)
10-13: 참가자 목록 Props 업데이트
ParticipantsList컴포넌트가 외부에서participants배열을 받도록 업데이트된 것은 좋은 변경입니다. 이를 통해 컴포넌트가 더 유연하게 사용될 수 있습니다.
14-24: 상태 관리 및 초기화 로직참가자 상태 관리를 위한 훅 사용이 잘 구현되었습니다. 컴포넌트 마운트 시
initializeParticipants함수로 초기화하는 방식이 적절합니다.
26-35: 필터링 로직 업데이트참가자 목록 필터링 로직이 새로운 데이터 구조에 맞게 업데이트되었습니다. 승인 상태 및 체크인 상태에 따른 필터링이 잘 구현되었습니다.
60-67: 참가자 카드 컴포넌트 매핑 업데이트참가자 카드 컴포넌트 매핑이 새로운 데이터 구조에 맞게 업데이트되었습니다.
key로participant.id를 사용하고, 체크 상태 및 토글 함수에participant.orderNumber를 사용하는 방식이 일관성 있게 적용되었습니다.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (5)
src/features/dashboard/ui/Checklist.tsx (1)
11-15: fallback 처리 고려 필요id가 없을 경우 빈 배열로 처리하는 것은 좋은 방어 코딩입니다. 그러나 id가 없거나 잘못된 형식일 때 사용자에게 보여줄 대체 UI나 오류 메시지를 추가하는 것을 고려해보세요.
const { id } = useParams(); const navigate = useNavigate(); const menuLists = id ? getMenuLists(id) : []; // id가 있을 때만 리스트 생성 + // 체크리스트가 비어있을 때 보여줄 메시지나 대체 UI를 추가할 수 있습니다 const checkLists = menuLists .filter(item => ['이벤트 기본 정보', '이벤트 상세와 사진', '티켓 생성하기'].includes(item.text)) .map(items => ({ text: items.text, path: items.path }));src/widgets/dashboard/ui/SideBar.tsx (2)
14-15: 빈 menuLists에 대한 처리 개선 필요id가 없을 경우 빈 배열을 사용하는 것은 좋은 방어 코딩이지만, 빈 메뉴 리스트가 표시될 때 사용자 경험을 고려해야 합니다. 빈 메뉴 리스트가 표시되는 상황에 대한 UI 처리를 추가하는 것이 좋겠습니다.
const { id } = useParams(); const [selectedIcon, setSelectedIcon] = useState<string>(''); const menuLists = id ? getMenuLists(id) : []; + // 메뉴 리스트가 비어있을 때 UI 처리메뉴 리스트가 비어있을 때 사용자에게 적절한 안내 메시지를 표시하거나, 이전 페이지로 돌아갈 수 있는 버튼을 제공하는 것을 고려해보세요.
32-57: 메뉴 목록이 비어있는 경우 대비 필요menuLists가 빈 배열일 경우(id가 없는 경우) 화면에 아무것도 표시되지 않을 수 있습니다. 이 경우에 대한 처리를 추가하는 것이 좋겠습니다.
<div className="flex flex-col gap-7 md:gap-8 mt-4"> + {menuLists.length === 0 ? ( + <div className="flex flex-col items-center justify-center p-4"> + <p className="text-gray-500">메뉴를 불러올 수 없습니다.</p> + <button + className="mt-2 px-4 py-2 bg-main text-white rounded-md" + onClick={() => navigate('/')} + > + 홈으로 돌아가기 + </button> + </div> + ) : ( {menuLists.map((menu, index) => ( <div key={index} className="flex items-center space-x-6 cursor-pointer group" onClick={() => handleMenuClick(menu.text, menu.path)} > <div className={`w-1 h-8 rounded-[5px] transition-all${ selectedIcon === menu.text ? 'bg-main' : 'bg-transparent group-hover:bg-main' }`} /> <HorizontalCardButton iconPath={ <img src={selectedIcon === menu.text ? menu.clickedIcon : menu.icon} alt={menu.text} className="w-8 h-8 md:w-9 md:h-9 mr-3" /> } hoverIconPath={<img src={menu.clickedIcon} alt={menu.text} className="w-8 h-8 md:w-9 md:h-9 mr-3" />} label={menu.text} onClick={() => handleMenuClick(menu.text, menu.path)} className="group" /> </div> ))} + )} </div>src/shared/types/dashboardType.ts (2)
25-35: 새로운 인터페이스 추가 적절함대시보드 데이터를 위한 인터페이스를 추가한 것은 타입 안전성을 높이는 좋은 접근입니다. 다만 각 속성에 대한 JSDoc 주석을 추가하면 더 명확한 문서화가 될 것입니다.
export interface dashboardData { + /** 이벤트 이름 */ eventName: string; + /** 이벤트 시작 날짜 (YYYY-MM-DD 형식) */ eventStartDate: string; + /** 이벤트 시작 시간 (HH:MM 형식) */ eventStartTime: string; + /** 이벤트 종료 날짜 (YYYY-MM-DD 형식) */ eventEndDate: string; + /** 이벤트 종료 시간 (HH:MM 형식) */ eventEndTime: string; + /** 총 티켓 수량 */ totalTicketCnt: number; + /** 총 금액 */ totalPrice: number; + /** 티켓 생성 여부 */ ticket: boolean; + /** 티켓 옵션 설정 여부 */ ticketOption: boolean; }
37-56: 동적 경로 구현 적절함메뉴 리스트를 정적 배열에서 함수로 변경하여 id 매개변수를 통해 동적 경로를 생성하는 방식은 좋은 리팩토링입니다. 다만 id에 대한 타입 유효성 검사를 추가하는 것을 고려해볼 수 있습니다.
-export const getMenuLists = (id: string | number) => [ +export const getMenuLists = (id: string | number) => { + // id 값이 유효한지 확인 + if (!id) { + console.warn('getMenuLists: 유효하지 않은 id 값이 전달되었습니다.'); + } + + return [ { text: '대시보드', icon: dashboard, clickedIcon: clickedDashboard, path: `/dashboard/${id}` }, { text: '이벤트 기본 정보', icon: eventInfo, clickedIcon: clickedEventInfo, path: `/dashboard/${id}/eventInfo` }, { text: '이벤트 상세와 사진', icon: eventDetail, clickedIcon: clickedEventDetail, path: `/dashboard/${id}/eventDetail`, }, { text: '이벤트 태그 정보', icon: tag, clickedIcon: clickedTag, path: `/dashboard/${id}/eventTag` }, { text: '티켓 생성하기', icon: ticket, clickedIcon: clickedTicket, path: `/dashboard/${id}/ticket` }, { text: '이메일 예약 발송', icon: email, clickedIcon: clickedEmail, path: `/dashboard/${id}/email` }, { text: '보낸 이메일', icon: sentEmail, clickedIcon: clickedSentEmail, path: `/dashboard/${id}/mailBox` }, { text: '구매/참가자 관리', icon: participants, clickedIcon: clickedParticipants, path: `/dashboard/${id}/participants-management`, }, + ]; +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/app/routes/routes.ts(2 hunks)src/features/dashboard/api/participants.ts(1 hunks)src/features/dashboard/ui/Checklist.tsx(1 hunks)src/shared/types/dashboardType.ts(1 hunks)src/widgets/dashboard/ui/SideBar.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/features/dashboard/api/participants.ts
- src/app/routes/routes.ts
🧰 Additional context used
🧬 Code Definitions (2)
src/features/dashboard/ui/Checklist.tsx (1)
src/shared/types/dashboardType.ts (1)
getMenuLists(37-56)
src/widgets/dashboard/ui/SideBar.tsx (1)
src/shared/types/dashboardType.ts (1)
getMenuLists(37-56)
🔇 Additional comments (4)
src/features/dashboard/ui/Checklist.tsx (2)
3-4: 새로운 의존성 추가 확인기존의 menuLists 직접 임포트 대신 getMenuLists 함수와 useParams 훅을 사용하여 라우트 매개변수를 통해 동적으로 메뉴 리스트를 가져오는 방식으로 변경되었습니다. 이는 라우팅 구조 변경에 잘 대응하는 개선입니다.
8-9: 라우트 매개변수 활용 방식 적절함useParams 훅을 통해 URL에서 id 매개변수를 추출하는 방식이 적절하게 구현되었습니다. 이를 통해 동적 라우팅을 지원하고 컴포넌트를 재사용할 수 있게 되었습니다.
src/widgets/dashboard/ui/SideBar.tsx (2)
4-6: 의존성 업데이트 적절함useParams를 추가하고 menuLists 대신 getMenuLists 함수를 임포트하도록 변경한 것은 동적 라우팅 구조에 맞게 잘 수정되었습니다.
11-11: 라우트 매개변수 활용 방식 적절함useParams 훅을 통해 URL에서 id 매개변수를 추출하는 방식이 적절하게 구현되었습니다.
ee79855 to
bf2d831
Compare
bf2d831 to
c68c445
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (6)
src/features/dashboard/api/event.ts (1)
3-10: API 구현이 됐네요, 몇 가지 개선점이 있습니다.이벤트 정보를 가져오는 함수가 잘 구현되었습니다만, 다음과 같은 개선 사항을 고려해보세요:
- 오류 처리 로직이 없습니다. API 호출 실패 시 어떻게 처리할지 고려해보세요.
- 타입 안전성을 위해 반환 타입을 명시하는 것이 좋습니다.
- 객체 속성 단축 구문을 사용하여 코드를 간결하게 만들 수 있습니다.
-export const getEventInfo = async (eventId: string) => { +export const getEventInfo = async (eventId: string): Promise<dashboardData> => { const response = await axiosClient.get('/host-channels/dashboard', { params: { - eventId: eventId, + eventId, }, }); return response.data.result; };src/pages/dashboard/ui/DashbaordPage.tsx (4)
7-9: 훅 사용이 잘 구현되었습니다.useGetEventHook을 사용하여 이벤트 정보를 가져오는 구현이 잘 되었습니다. 다만, 로딩 상태와 오류 상태를 처리하는 부분이 없습니다. 사용자 경험 향상을 위해 이러한 상태를 처리하는 것이 좋습니다.
-import { useGetEventHook } from '../../../features/dashboard/hook/useGetEventHook'; +import { useGetEventHook } from '../../../features/dashboard/hook/useGetEventHook'; +import { Spinner } from '../../../shared/ui/loading/Spinner'; // 예시, 실제 경로는 다를 수 있음 const DashboardPage = () => { - const { eventInfo } = useGetEventHook(); + const { eventInfo, isLoading, isError } = useGetEventHook(); + + if (isLoading) return <Spinner />; + if (isError) return <div>이벤트 정보를 불러오는 중 오류가 발생했습니다.</div>;
18-22: 티켓 판매 수 표시가 잘 구현되었습니다.다만, 값이 없을 때 '-'로 표시하는 것보다 '0장'과 같이 일관된 형식으로 표시하는 것이 더 나을 수 있습니다. 사용자 경험 측면에서 고려해보세요.
icon={<img src={ticket} alt="티켓" className="w-8 md:w-9" />} title="티켓 판매 수" - value={`${eventInfo?.totalTicketCnt || '-'}장`} + value={`${eventInfo?.totalTicketCnt || 0}장`}
23-27: 판매 금액 컴포넌트가 잘 추가되었습니다.티켓 판매 수와 마찬가지로, 값이 없을 때도 일관된 형식으로 표시하는 것이 좋을 것 같습니다.
icon={<img src={cash} alt="돈" className="w-8 md:w-9" />} title="판매 금액" - value={`${eventInfo?.totalPrice || '-'}원`} + value={`${eventInfo?.totalPrice || 0}원`}
1-33: 파일 이름에 오타가 있습니다.파일 이름이 'DashbaordPage.tsx'로 되어 있는데, 'DashboardPage.tsx'로 수정하는 것이 좋겠습니다.
src/shared/types/dashboardType.ts (1)
25-35: 새로운 dashboardData 인터페이스가 이벤트 정보를 잘 표현합니다.dashboardData 인터페이스는 이벤트의 주요 정보(이름, 날짜, 시간, 티켓 등)를 포함하고 있어 대시보드에 필요한 데이터 구조를 잘 정의하고 있습니다. 다만, 모든 필드가 필수로 설정되어 있는데, 일부 필드는 선택적(optional)일 수 있는지 검토해 보세요.
export interface dashboardData { eventName: string; eventStartDate: string; eventStartTime: string; eventEndDate: string; eventEndTime: string; - totalTicketCnt: number; - totalPrice: number; - ticket: boolean; - ticketOption: boolean; + totalTicketCnt?: number; // 티켓이 없는 경우를 고려 + totalPrice?: number; // 무료 이벤트인 경우를 고려 + ticket?: boolean; + ticketOption?: boolean; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (17)
src/app/routes/routes.ts(2 hunks)src/features/dashboard/api/event.ts(1 hunks)src/features/dashboard/api/participants.ts(1 hunks)src/features/dashboard/hook/useGetEventHook.ts(1 hunks)src/features/dashboard/hook/useParticipants.ts(1 hunks)src/features/dashboard/model/ParticipantStore.tsx(4 hunks)src/features/dashboard/ui/Checklist.tsx(1 hunks)src/features/dashboard/ui/ParicipantCard.tsx(2 hunks)src/features/dashboard/ui/PariticipantsList.tsx(2 hunks)src/pages/dashboard/ui/DashbaordPage.tsx(1 hunks)src/pages/dashboard/ui/ParticipantsMangementPage.tsx(4 hunks)src/pages/dashboard/ui/mail/EmailEditPage.tsx(1 hunks)src/pages/dashboard/ui/mail/EmailPage.tsx(1 hunks)src/shared/types/dashboardType.ts(1 hunks)src/shared/types/participantInfoType.ts(1 hunks)src/widgets/dashboard/ui/EventOverview.tsx(2 hunks)src/widgets/dashboard/ui/SideBar.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
- src/features/dashboard/hook/useGetEventHook.ts
- src/pages/dashboard/ui/mail/EmailEditPage.tsx
- src/features/dashboard/api/participants.ts
- src/widgets/dashboard/ui/SideBar.tsx
- src/pages/dashboard/ui/ParticipantsMangementPage.tsx
- src/widgets/dashboard/ui/EventOverview.tsx
- src/pages/dashboard/ui/mail/EmailPage.tsx
- src/features/dashboard/hook/useParticipants.ts
- src/app/routes/routes.ts
- src/features/dashboard/model/ParticipantStore.tsx
- src/features/dashboard/ui/ParicipantCard.tsx
- src/features/dashboard/ui/PariticipantsList.tsx
🧰 Additional context used
🧬 Code Definitions (2)
src/features/dashboard/ui/Checklist.tsx (1)
src/shared/types/dashboardType.ts (1)
getMenuLists(37-56)
src/pages/dashboard/ui/DashbaordPage.tsx (1)
src/features/dashboard/hook/useGetEventHook.ts (1)
useGetEventHook(6-15)
🔇 Additional comments (9)
src/shared/types/participantInfoType.ts (3)
2-4: 참가자 식별자 개선이 이루어졌습니다.정수형 식별자(
id,orderNumber)와 참가자 이름 필드(participant)가 추가되어 백엔드 API와의 통합이 더 원활해졌습니다. 이는 정적 데이터에서 동적 API 기반 데이터로의 전환을 잘 지원합니다.
6-6: 일관된 명명 규칙으로 변경되었습니다.
phone에서phoneNumber로의 이름 변경은 필드 명명 규칙을 더 명확하고 일관되게 만들어 코드 가독성을 향상시킵니다.
1-11: 타입 정의가 API 응답 구조와 잘 맞춰졌습니다.참가자 데이터 구조가 백엔드 API 응답 형식과 일치하도록 적절히 수정되었습니다. 이전의 문자열 기반 식별자(
ticketNum)를 숫자 기반 식별자(id,orderNumber)로 변경한 것은 타입 안정성을 높이는 좋은 변화입니다.이 변경으로 PR 목표인 '구매/참가자 관리 API 구현'이 잘 지원되고 있습니다.
src/pages/dashboard/ui/DashbaordPage.tsx (2)
14-14: 이벤트 이름 표시가 잘 구현되었습니다.이벤트 이름이 없을 경우 대체 텍스트를 표시하는 것은 좋은 방식입니다.
16-16: EventOverview 컴포넌트에 eventInfo 전달이 잘 구현되었습니다.EventOverview 컴포넌트에 eventInfo를 props로 전달하여 동적 데이터를 표시할 수 있게 한 점이 좋습니다.
src/features/dashboard/ui/Checklist.tsx (3)
3-4: 추가된 임포트가 기능 개선에 적절합니다.새로운 임포트인
getMenuLists와useParams는 동적 라우팅 구현에 필요한 적절한 추가입니다. 이를 통해 URL 파라미터에서 이벤트 ID를 추출하고 해당 ID에 맞는 메뉴 리스트를 동적으로 생성할 수 있게 되었습니다.
8-8: 라우트 파라미터 추출이 적절하게 구현되었습니다.useParams 훅을 사용하여 URL에서 id 파라미터를 추출하는 방식이 React Router의 권장 패턴에 따라 잘 구현되었습니다.
11-15:Details
❓ Verification inconclusive
동적 메뉴 리스트 생성 로직이 잘 구현되었으나, 오류 처리가 필요합니다.
id가 존재할 때만 getMenuLists를 호출하여 메뉴 리스트를 생성하는 방식은 적절합니다. 그러나 id가 존재하지만 유효하지 않은 경우에 대한 오류 처리가 없습니다. 또한, id가 없을 때 빈 배열을 반환하면 체크리스트가 비어 있게 되는데, 이것이 의도한 동작인지 검토해 보세요.
🏁 Script executed:
#!/bin/bash # id가 없거나 유효하지 않을 때 어떻게 처리되는지 확인 rg -A 3 -B 3 "useParams|getMenuLists" --type ts --type tsxLength of output: 88
아래와 같이 파일 확장자 패턴을 수정한 재검증 스크립트를 실행해 주세요. 이전 명령은 TSX 파일을 인식하지 못해 결과를 얻지 못했습니다.
검증 요청: getMenuLists 호출부의 예외 처리 보완
- 파일: src/features/dashboard/ui/Checklist.tsx (11~15행)
- id가 존재할 경우에만 getMenuLists를 호출하는 점은 적절하나, id가 존재하지만 유효하지 않은 경우에 대한 예외 처리가 누락되어 있습니다.
- id가 없을 경우 빈 배열을 반환하여 체크리스트가 비어있게 되는 동작이 의도한 것인지 재검토해 주세요.
검증 스크립트의 실행 결과와 함께, 위 사항들을 반영하여 추가적인 예외 처리를 적용할지 결정해 주시기 바랍니다.
🏁 Script executed:
#!/bin/bash # TS 및 TSX 파일 모두에서 getMenuLists 호출 구문을 검색하여 관련 사용 사례와 오류 처리 로직 존재 여부를 확인합니다. rg -g "*.tsx" -g "*.ts" -A 5 -B 5 "getMenuLists\("Length of output: 1702
검증: 오류 처리 및 빈 배열 반환 동작 확인 필요
- 파일:
src/features/dashboard/ui/Checklist.tsx(라인 11-15)- 검증 내용:
id가 존재할 경우에만getMenuLists(id)가 호출되는 점은 적절하지만, 유효하지 않은 id의 경우에 대한 오류 처리 로직이 구현되어 있지 않습니다.id가 없을 때 빈 배열을 반환하는데, 이 동작이 의도된 것인지 재검토가 필요합니다.위 사항들을 고려하여, 유효하지 않은 id가 제공되었을 때 적절한 오류 처리(예: 에러 메시지 출력, fallback 처리 등)를 추가하거나, 빈 배열 반환이 의도된 동작이라면 해당 동작에 대한 명확한 주석을 보완해 주시기 바랍니다.
src/shared/types/dashboardType.ts (1)
37-56:Details
❓ Verification inconclusive
ID 기반 동적 메뉴 생성 함수가 잘 구현되었습니다.
getMenuLists 함수는 id 매개변수를 받아 동적으로 경로를 생성하는 방식으로 잘 구현되었습니다. 문자열과 숫자 모두 허용하는 것은 유연성 측면에서 좋은 접근입니다. 다만, 이 함수가 사용되는 모든 곳에서 id가 존재하는지 확인하는 로직이 필요합니다.
🏁 Script executed:
#!/bin/bash # getMenuLists 함수가 사용되는 모든 곳 확인 rg -A 2 -B 2 "getMenuLists" --type ts --type tsxLength of output: 76
확인 요청: getMenuLists 함수 사용 위치 검증 필요
getMenuLists 함수는 id를 받아 동적으로 메뉴 경로를 생성하는 방식으로 잘 구현되어 있습니다. 문자열과 숫자 모두 허용하는 점은 유연성이 뛰어나지만, 호출하는 모든 위치에서 유효한 id가 전달되고 있는지 확인하는 로직이 추가로 있으면 좋겠습니다.
단, 기존 검증 스크립트 실행 시 "unrecognized file type: tsx" 오류가 발생하여 TSX 파일까지 포함한 전체 검색이 제대로 이루어지지 않았습니다. 재검증을 위해 아래와 같이 TS와 TSX 파일 모두를 검색하는 스크립트를 다시 실행해 주시기 바랍니다.
#!/bin/bash rg -g "*.{ts,tsx}" -A 2 -B 2 "getMenuLists"
진행사항
추후 적용
Summary by CodeRabbit