-
Notifications
You must be signed in to change notification settings - Fork 3
DetailPage api 연결 #114
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
DetailPage api 연결 #114
Conversation
Walkthrough이 풀 리퀘스트는 여러 파일에 대한 변경 사항을 포함하며, 주요 변경 사항은 Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant API
participant CrewDetailSection
participant GatheringListSection
User->>CrewDetailSection: 요청 (ID)
CrewDetailSection->>API: getCrewDetail(ID)
API-->>CrewDetailSection: CrewDetail 데이터
CrewDetailSection-->>User: CrewDetail 표시
User->>GatheringListSection: 요청 (ID)
GatheringListSection->>API: getGatheringList(ID)
API-->>GatheringListSection: GatheringList 데이터
GatheringListSection-->>User: GatheringList 표시
Possibly related PRs
Suggested labels
Suggested reviewers
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
src/_apis/detail/get-crew-detail.tsOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't determine the plugin "react-hooks" uniquely.
Please remove the "plugins" setting from either config or remove either plugin installation. If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team. Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Outside diff range and nitpick comments (22)
src/_queries/detail/crew-detail-queries.ts (1)
4-9: 에러 처리와 로딩 상태에 대한 타입 정의 추가를 고려해보세요.데이터 타입과 함께 에러 및 로딩 상태에 대한 타입을 명시적으로 정의하면 컴포넌트에서 더 안전하게 사용할 수 있습니다.
+type CrewDetailResponse = { + // API 응답 타입 정의 +}; -export function useGetCrewDetailQuery(id: number) { +export function useGetCrewDetailQuery(id: number) { + type QueryError = { + message: string; + status: number; + }; return useQuery<CrewDetailResponse, QueryError>({ queryKey: ['crewDetail', id], queryFn: () => getCrewDetail(id), }); }src/_queries/detail/gathering-detail-queries.ts (1)
4-9: 에러 처리와 로딩 상태 관리를 추가하는 것이 좋겠습니다.현재 구현은 기본적인 데이터 fetching은 잘 처리하고 있지만, 다음 사항들을 고려해보시면 좋겠습니다:
- 에러 발생 시의 재시도 로직
- 캐시 무효화 전략
- 로딩 상태에 대한 타임아웃 설정
다음과 같이 개선해보세요:
export function useGetGatheringDetailQuery(crewId: number, gatheringId: number) { return useQuery({ queryKey: ['gatheringDetail', crewId, gatheringId], queryFn: () => GetGatheringDetail(crewId, gatheringId), + retry: 1, + staleTime: 5 * 60 * 1000, // 5분 + gcTime: 10 * 60 * 1000, // 10분 + timeout: 5000, // 5초 }); }src/_queries/detail/gathering-list-queries.ts (1)
5-11: 캐싱 설정 추가를 고려해보세요.쿼리 구현이 전반적으로 잘 되어있습니다. 다만, 데이터 신선도 관리를 위해
staleTime설정을 추가하면 좋을 것 같습니다.export function useGetGatheringListQuery(id: number) { return useQuery<GatheringType[], Error>({ queryKey: ['gatheringList', id], queryFn: () => getGatheringList(id), enabled: !!id, + staleTime: 5 * 60 * 1000, // 5분 }); }.gitignore (1)
30-30: 환경 변수 파일이 적절히 무시되도록 설정되었습니다.
.env파일을.gitignore에 추가한 것은 보안상 매우 중요한 조치입니다. 이는 민감한 환경 변수가 실수로 저장소에 커밋되는 것을 방지합니다.환경 변수 관리를 위해 다음 사항들을 고려해보세요:
.env.example파일을 생성하여 필요한 환경 변수의 템플릿을 제공- 팀원들과 환경 변수 관리 방법에 대한 문서화 진행
src/app/(crew)/crew/detail/[id]/_components/gathering-list-section.tsx (1)
10-20: 상태 처리 개선이 필요합니다.현재 구현은 기본적인 기능을 잘 수행하고 있지만, 다음과 같은 개선사항을 제안드립니다:
- if (isLoading) return <p>로딩 중...</p>; + if (isLoading) return <LoadingSpinner />; - if (error) return <p>데이터를 불러오는 데 실패했습니다: {error.message}</p>; + if (error) return ( + <ErrorMessage + title="데이터를 불러오는 데 실패했습니다" + message={error instanceof Error ? error.message : '알 수 없는 오류가 발생했습니다'} + /> + ); - if (!gatheringList || gatheringList.length === 0) return <p>데이터가 없습니다.</p>; + if (!gatheringList || gatheringList.length === 0) return ( + <EmptyState + message="아직 등록된 모임이 없습니다" + description="새로운 모임을 등록해보세요!" + /> + );
- 로딩 상태에 스피너 컴포넌트를 사용하여 사용자 경험을 개선
- 에러 처리에 타입 안전성을 추가하고 더 친숙한 에러 메시지를 표시
- 빈 데이터 상태에 대해 더 자세한 설명과 가이드를 제공
src/app/(crew)/crew/detail/[id]/_components/detail-crew-section.tsx (4)
7-9: 인터페이스에 문서화 추가 필요인터페이스의 목적과
id프로퍼티의 용도를 명확히 하기 위해 JSDoc 문서화를 추가하는 것이 좋습니다.다음과 같이 수정하는 것을 제안합니다:
+/** + * 크루 상세 정보 섹션의 프로퍼티 + */ interface DetailCrewSectionProps { + /** 조회할 크루의 고유 식별자 */ id: number; }
11-13: 데이터 타입 안전성 개선 필요
useGetCrewDetailQuery의 반환 타입이 명시적으로 지정되어 있지 않아 타입 안전성이 보장되지 않습니다.다음과 같이 타입 지정을 추가하는 것을 제안합니다:
- const { data, isLoading, error } = useGetCrewDetailQuery(id); + const { data, isLoading, error }: { + data: CrewDetailType | undefined; + isLoading: boolean; + error: Error | null; + } = useGetCrewDetailQuery(id);
14-15: 로딩 상태 UI 개선 필요현재 단순한 텍스트로 표시되는 로딩 상태를 사용자 경험을 고려한 컴포넌트로 개선해야 합니다.
TODO 주석을 해결하기 위한 스켈레톤 로딩 컴포넌트를 구현하는데 도움이 필요하신가요?
32-33: 조건부 렌더링 명확성 개선현재 구현은 정확하지만, 널 체크의 의도를 더 명확하게 표현할 수 있습니다.
다음과 같이 수정하는 것을 제안합니다:
- // data가 있을 때만 DetailCrewCard를 렌더링 - return data ? <DetailCrewCard data={data} /> : null; + if (!data) { + return null; + } + + return <DetailCrewCard data={data} />;src/app/(crew)/crew/detail/[id]/page.tsx (1)
26-26: TODO 주석을 더 구체적으로 작성해 주세요.현재 TODO 주석과 주석 처리된 코드에 대해 몇 가지 제안사항이 있습니다:
- TODO 주석에 구체적인 완료 조건이나 관련 이슈 번호를 포함해 주세요
CreateGathering컴포넌트의 구현 계획을 주석으로 명시해 주세요다음과 같이 개선하는 것을 추천드립니다:
- {/* <CreateGathering /> */} + {/* TODO: #issue-number - CreateGathering 컴포넌트 구현 예정 (다음 스프린트) */} - {/* // TODO: 리뷰 완성되면 수정 */} + {/* TODO: #issue-number - 리뷰 기능 구현 후 활성화 예정 - 백엔드 API 연동 필요 - 디자인 시안 확인 필요 */}Also applies to: 33-39
src/components/gathering-list/gathering-carousel.stories.tsx (1)
51-57: QueryClientProvider 데코레이터 구현이 잘 되었습니다.스토리북 데코레이터를 통해 QueryClientProvider를 적절히 설정하여 컴포넌트가 React Query 기능을 사용할 수 있도록 했습니다.
하지만 한 가지 제안사항이 있습니다:
decorators: [ (Story) => ( - <QueryClientProvider client={queryClient}> + <QueryClientProvider client={queryClient} key="query-provider"> <Story /> </QueryClientProvider> ), ],key prop을 추가하면 리렌더링 시 QueryClientProvider의 식별이 더 명확해집니다.
src/components/common/crew-list/detail-crew-card.stories.tsx (3)
2-6: Meta 타입 정의를 개선하세요현재 Meta 타입이 제네릭 없이 정의되어 있습니다. 컴포넌트의 타입 안정성을 위해 제네릭을 추가하는 것이 좋습니다.
다음과 같이 수정하는 것을 제안합니다:
-const meta: Meta = { +const meta: Meta<typeof DetailCrewCard> = {
15-39: 데이터 구조에 대한 문서화가 필요합니다복잡한 중첩 데이터 구조에 대한 설명이 부족합니다. 각 필드의 의미와 제약 조건을 JSDoc으로 문서화하면 좋겠습니다.
예시:
/** 크루 카드 데이터 구조 * @property {number} id - 크루 고유 식별자 * @property {string} title - 크루 이름 * @property {number} participantCount - 현재 참여자 수 * ... */
58-58: 한글 주석을 영문으로 변경하고 스토리 설명을 추가하세요코드 내 한글 주석이 있으며, 각 스토리의 목적과 차이점에 대한 설명이 부족합니다.
다음과 같이 수정하는 것을 제안합니다:
- crewMembers: [], // 빈 배열이라도 기본값으로 설정 + crewMembers: [], // Set empty array as default value그리고 각 스토리에 대한 설명을 추가하세요:
export const Default: Story = { parameters: { docs: { description: { story: 'Displays a confirmed crew card with maximum participants' } } }, args: { // ... } };Also applies to: 75-75
src/components/common/gathering-card/gathering-card.stories.tsx (2)
2-2: React Query 통합이 적절히 구현되었습니다.QueryClient의 설정이 올바르게 이루어졌습니다. 단, 스토리북 환경에서는 QueryClient의 기본 설정을 조정하는 것이 좋을 수 있습니다.
다음과 같은 설정을 고려해보세요:
-const queryClient = new QueryClient(); +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + cacheTime: 0, + }, + }, +});Also applies to: 5-6
43-43: 날짜 업데이트가 적절히 이루어졌습니다.스토리의 dateTime 값들이 미래 날짜로 적절하게 업데이트되었습니다. 다만, 테스트 데이터의 일관성을 위해 상대적인 날짜 사용을 고려해볼 수 있습니다.
다음과 같은 방식을 고려해보세요:
// utils/test-helpers.ts 파일 생성 export const getFutureDate = (daysFromNow: number) => { const date = new Date(); date.setDate(date.getDate() + daysFromNow); return date.toISOString().slice(0, 16); }; // stories에서 사용 dateTime: getFutureDate(30), // 30일 후Also applies to: 57-57
src/components/gathering-list/gathering-list.tsx (1)
9-10: TODO 주석에 대한 추적성 확보 필요TODO 주석이 다른 브랜치에서 수정될 예정이라고 명시되어 있습니다. 하지만 이러한 TODO 주석은 쉽게 잊혀질 수 있으며, 코드베이스에 장기간 남아있을 수 있습니다.
이 TODO 항목을 GitHub 이슈로 생성하여 추적하시겠습니까? 이슈에는 다음 내용이 포함될 수 있습니다:
- 수정이 필요한 구체적인 내용
- 예상 완료 시점
- 관련 디자인 변경사항
src/components/gathering-list/gathering-card-carousel.tsx (1)
34-34: 계산식에 대한 설명을 더 자세히 추가하면 좋을 것 같습니다.현재 주석은 "두 개일 경우"라고만 되어있는데, 계산식의 의미를 더 명확하게 설명하면 좋을 것 같습니다.
다음과 같이 주석을 개선하는 것을 제안드립니다:
- newSlideSize = 'w-[calc(50%-8px)]'; // 두 개일 경우 + newSlideSize = 'w-[calc(50%-8px)]'; // 두 개의 카드일 경우 (전체 너비의 50%에서 간격 16px의 절반을 뺌)src/components/common/gathering-card/presenter.tsx (2)
Line range hint
11-11: 스켈레톤 UI 구현이 필요합니다.초기 로딩 시 카드가 늘어나는 UX 이슈를 해결하기 위해 스켈레톤 UI 구현이 필요합니다.
스켈레톤 UI 구현을 위한 코드를 생성해드릴까요? 또는 이를 추적하기 위한 GitHub 이슈를 생성해드릴까요?
Line range hint
44-136: 컴포넌트 구조 개선을 제안드립니다.현재 구현은 잘 작동하지만, 다음과 같은 개선사항을 고려해보시면 좋을 것 같습니다:
컴포넌트 분리
- GatheringCardImage
- GatheringCardDeadline
- GatheringCardContent
- GatheringCardOverlay
등으로 분리하여 관리가 용이하도록 할 수 있습니다.스타일 상수화
h-[310px],h-40등의 매직 넘버를 상수로 추출- 반복되는 스타일 패턴을 유틸리티 클래스로 추출
리팩토링이 필요하시다면 구체적인 코드를 제안드릴 수 있습니다.
src/components/common/crew-list/detail-crew-card.tsx (2)
Line range hint
65-108: 주석 처리된 코드 정리가 필요합니다.주석 처리된 captain/crew 관련 로직이 많은 공간을 차지하고 있습니다. 이는 코드 유지보수를 어렵게 만들 수 있습니다.
제안사항:
- 구현이 필요한 로직이라면 GitHub Issue로 관리하는 것이 좋습니다.
- 불필요한 코드라면 완전히 제거하는 것이 좋습니다.
GitHub Issue를 생성하여 해당 작업을 추적하도록 도와드릴까요?
Line range hint
47-57: 크루 삭제 및 탈퇴 로직 구현이 필요합니다.handleConfirmDelete와 handleConfirmLeaveCrew 함수에 실제 구현이 필요합니다. 이는 중요한 비즈니스 로직이므로 우선적으로 구현되어야 합니다.
해당 기능 구현을 위한 코드를 제안해드릴까요?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (20)
.gitignore(2 hunks)next.config.mjs(0 hunks)src/_apis/detail/get-crew-detail.ts(1 hunks)src/_apis/detail/get-gathering-detail.ts(1 hunks)src/_apis/detail/get-gathering-list.ts(1 hunks)src/_queries/detail/crew-detail-queries.ts(1 hunks)src/_queries/detail/gathering-detail-queries.ts(1 hunks)src/_queries/detail/gathering-list-queries.ts(1 hunks)src/app/(crew)/crew/detail/[id]/_components/detail-crew-section.tsx(1 hunks)src/app/(crew)/crew/detail/[id]/_components/gathering-list-section.tsx(1 hunks)src/app/(crew)/crew/detail/[id]/page.tsx(1 hunks)src/components/common/crew-list/detail-crew-card.stories.tsx(2 hunks)src/components/common/crew-list/detail-crew-card.tsx(2 hunks)src/components/common/gathering-card/container.tsx(3 hunks)src/components/common/gathering-card/gathering-card.stories.tsx(3 hunks)src/components/common/gathering-card/presenter.tsx(1 hunks)src/components/gathering-list/gathering-card-carousel.tsx(5 hunks)src/components/gathering-list/gathering-carousel.stories.tsx(3 hunks)src/components/gathering-list/gathering-list.tsx(2 hunks)src/utils/api.ts(2 hunks)
💤 Files with no reviewable changes (1)
- next.config.mjs
🔇 Additional comments (25)
src/_queries/detail/crew-detail-queries.ts (2)
1-9: 구현이 깔끔하고 React Query 모범 사례를 잘 따르고 있습니다! 👍
쿼리 키 구조와 타입 정의가 명확하게 되어있습니다.
6-6: 쿼리 키가 적절히 구성되어 있는지 확인해주세요.
다른 곳에서 동일한 쿼리 키를 사용하고 있지 않은지 확인이 필요합니다.
✅ Verification successful
Let me check the actual implementation of the query to verify if there are any potential conflicts or issues.
쿼리 키 구성이 적절합니다.
'crewDetail' 쿼리 키는 해당 파일에서만 사용되고 있으며, id 파라미터와 함께 적절히 구성되어 있습니다. 다른 파일에서 중복 사용되지 않아 충돌 위험이 없습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 쿼리 키 'crewDetail'의 사용을 확인합니다.
# 쿼리 키 사용 검색
rg -l "queryKey.*crewDetail"
Length of output: 73
Script:
#!/bin/bash
# Check the actual implementation and usage of crewDetail query
rg -A 5 "queryKey.*crewDetail"
Length of output: 284
src/_queries/detail/gathering-detail-queries.ts (1)
1-2: import 경로 별칭(@/src)의 설정을 확인해주세요.
import 문이 올바르게 작성되었지만, @/src 별칭이 프로젝트의 tsconfig.json 또는 next.config에 올바르게 설정되어 있는지 확인이 필요합니다.
✅ Verification successful
경로 별칭(@/src)이 올바르게 설정되어 있습니다.
tsconfig.json에서 @/* 및 @/src/_apis/* 경로 별칭이 정확하게 설정되어 있어, import 문의 경로가 유효합니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# tsconfig.json에서 경로 별칭 설정 확인
cat tsconfig.json | jq '.compilerOptions.paths'
# next.config 파일에서 경로 별칭 설정 확인
fd -e js -e mjs "next.config" -x cat {}
Length of output: 1598
src/_apis/detail/get-crew-detail.ts (2)
4-13: 구현이 깔끔하고 명확합니다!
함수 시그니처와 구현이 잘 정의되어 있습니다. API 엔드포인트도 RESTful 규칙을 잘 따르고 있습니다.
4-5: API 엔드포인트 사용 확인 필요
PR 설명에 따르면 base URL을 fetch API에 추가해야 한다고 언급되어 있습니다. 현재 구현된 엔드포인트가 올바른지 확인이 필요합니다.
✅ Verification successful
Let me check the API configuration in src/utils/api.ts to verify how the base URL is handled.
Let me check how the crew detail API is implemented.
API 엔드포인트가 올바르게 구현되어 있음을 확인했습니다
src/utils/api.ts의 fetchApi 함수에서 process.env.NEXT_PUBLIC_API_BASE_URL을 base URL로 사용하여 API 요청을 처리하고 있습니다. getCrewDetail 함수는 이 fetchApi를 올바르게 사용하고 있어 base URL이 자동으로 추가됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the API endpoint usage across the codebase
# Check for any environment configuration files
echo "Checking for API configuration files..."
fd -e env -e js -e ts -e json . -x grep -l "API_URL\|BASE_URL"
# Check for other API endpoint usages
echo "Checking for API endpoint patterns..."
rg "/api/crews/[^/]+" --type ts
Length of output: 773
Script:
#!/bin/bash
# Check the API configuration implementation
echo "Content of src/utils/api.ts:"
cat src/utils/api.ts
# Check if there are any fetch implementations
echo -e "\nChecking fetch implementations:"
rg "fetch\(" src/_apis/detail/get-crew-detail.ts -A 5
Length of output: 2024
Script:
#!/bin/bash
# Check the implementation of get-crew-detail.ts
echo "Content of src/_apis/detail/get-crew-detail.ts:"
cat src/_apis/detail/get-crew-detail.ts
# Check for any other files that might be using this API
echo -e "\nFiles importing get-crew-detail:"
rg "from.*get-crew-detail" --type ts
Length of output: 758
src/_queries/detail/gathering-list-queries.ts (1)
1-3: 깔끔한 import 구조입니다!
외부 라이브러리, 내부 API, 타입 순서로 잘 정리되어 있습니다.
src/_apis/detail/get-gathering-list.ts (2)
4-4: 함수 시그니처가 적절하게 수정되었습니다.
id 매개변수를 추가한 것은 특정 모임의 정보를 가져오기 위한 적절한 변경사항입니다.
5-5: URL 구성 검증이 필요합니다.
URL에 사용되는 id 값의 유효성을 검증하는 것이 좋습니다.
.gitignore (1)
41-42: Storybook 관련 파일들이 적절히 제외되었습니다.
빌드 출력물(/storybook-static)과 로그 파일(*storybook.log)을 무시하도록 설정한 것은 적절한 조치입니다. 이는 저장소를 깨끗하게 유지하고 불필요한 파일들이 커밋되는 것을 방지합니다.
src/_apis/detail/get-gathering-detail.ts (2)
1-2: 타입 임포트 위치 확인이 필요합니다
타입 정의가 올바른 위치에서 임포트되고 있는지 확인이 필요합니다.
다음 스크립트로 타입 정의 위치를 확인해보겠습니다:
#!/bin/bash
# 타입 정의 위치 확인
fd "gathering-data.ts" src/types8-8: URL 구성 검증이 필요합니다
URL에 사용되는 파라미터들의 유효성 검사가 필요합니다.
다음 스크립트로 API 엔드포인트 사용을 확인해보겠습니다:
src/app/(crew)/crew/detail/[id]/_components/gathering-list-section.tsx (2)
1-9: 코드 구조가 깔끔하고 명확합니다!
'use client' 지시문의 올바른 사용과 함께 깔끔한 import 구문, 그리고 명확한 인터페이스 정의가 잘 되어있습니다.
4-4: GatheringCardCarousel 컴포넌트의 props 검증이 필요합니다.
GatheringCardCarousel 컴포넌트가 예상된 props를 올바르게 받는지 확인이 필요합니다.
Also applies to: 19-19
✅ Verification successful
GatheringCardCarousel 컴포넌트의 props가 정상적으로 구현되어 있습니다.
코드베이스 검증 결과:
- GatheringCardCarousel 컴포넌트가
gatheringData: GatheringType[]와crewId: numberprops를 올바르게 정의하고 있습니다. - gathering-list-section에서 전달하는 props 타입이 컴포넌트의 인터페이스와 일치합니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# GatheringCardCarousel 컴포넌트의 props 타입 정의 확인
ast-grep --pattern 'interface GatheringCardCarouselProps {
$$$
gatheringData: $_
crewId: $_
$$$
}'
Length of output: 108
Script:
#!/bin/bash
# Check the implementation of GatheringCardCarousel component
fd "gathering-card-carousel" --type f --exec cat {}
# Search for usage patterns of GatheringCardCarousel
rg "GatheringCardCarousel" -A 5
Length of output: 7979
src/app/(crew)/crew/detail/[id]/page.tsx (1)
3-9: 타입 정의와 임포트 구조가 깔끔합니다!
컴포넌트 임포트와 타입 정의가 명확하게 구성되어 있습니다.
src/utils/api.ts (2)
38-39: 환경 변수 설정 확인 필요
NEXT_PUBLIC_API_BASE_URL 환경 변수가 올바르게 설정되어 있는지 확인이 필요합니다.
✅ Verification successful
환경 변수 설정이 적절히 구성되어 있습니다
NEXT_PUBLIC_API_BASE_URL 환경 변수는 next.config.mjs에서 기본값 'https://foggy-sideways-saltasaurus.glitch.me/'로 적절하게 설정되어 있어 문제가 없습니다. 환경 변수가 없는 경우에도 기본값이 제공되므로 애플리케이션이 정상적으로 동작할 것입니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for environment variable usage in the codebase
# Check for environment variable references
echo "Checking for NEXT_PUBLIC_API_BASE_URL usage:"
rg "NEXT_PUBLIC_API_BASE_URL"
# Check if .env or similar files exist
echo -e "\nChecking for environment configuration files:"
fd -g ".env*"
Length of output: 643
Script:
#!/bin/bash
# Check the next.config.mjs file content to understand the default value
echo "Checking next.config.mjs configuration:"
cat next.config.mjs
# Check for .env files including hidden ones
echo -e "\nChecking for environment files (including hidden):"
fd -H -g ".env*"
# Check if there are any example env files
echo -e "\nChecking for example env files:"
fd -g "*env.example*"
Length of output: 1316
54-54: 응답 구조 변경에 따른 영향도 확인 필요
응답 구조가 { data: ... } 형태로 변경되었습니다. 이는 기존 API를 사용하는 코드에 영향을 줄 수 있습니다.
✅ Verification successful
Let me gather more information about the response types and their handling to verify the impact.
API 응답 구조 변경은 안전합니다
기존 API 소비자들이 이미 { data: ... } 구조를 예상하고 있음을 확인했습니다:
WritableGatheringCardInformResponse,MyCrewListResponse,ReviewInformResponse등의 타입들이 이미data필드를 포함하고 있습니다- API 호출 부분에서도
fetchApi<{ data: GatheringType[] }>,fetchApi<{ data: CrewDetail }>등과 같이data필드를 포함한 타입을 명시적으로 사용하고 있습니다
따라서 이 변경사항은 기존 코드와 일관성이 있으며 호환됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find potential affected API consumers
# Search for fetchApi usage
echo "Checking for fetchApi usage:"
ast-grep --pattern 'fetchApi<$_>($_)'
# Search for direct response handling
echo -e "\nChecking for potential response handling:"
rg "await.*fetchApi.*" -A 2
Length of output: 1453
Script:
#!/bin/bash
# Check response type definitions and handling
echo "Checking response type definitions:"
rg "type.*Response" -A 3
echo -e "\nChecking interface definitions:"
rg "interface.*Response" -A 3
echo -e "\nChecking actual response handling in components:"
rg "const.*=.*response" -A 2
Length of output: 2680
src/components/gathering-list/gathering-carousel.stories.tsx (2)
2-2: React Query 설정이 적절히 구현되었습니다.
QueryClient의 설정이 올바르게 되어있으며, 필요한 import문도 정확하게 추가되었습니다.
Also applies to: 42-43
67-67: crewId prop 추가에 대한 검증이 필요합니다.
crewId가 추가되었지만, 이 값이 실제로 어떻게 사용되는지 확인이 필요합니다.
✅ Verification successful
Let me check how the crewId is used in the GatheringCard component.
Let me try to find the GatheringCard component in the codebase first.
Let me check how the crewId is used in the GatheringCard container component.
Let me check for any API calls or hooks that might be using the crewId.
crewId prop이 적절하게 사용되고 있음을 확인했습니다.
crewId는 다음과 같이 올바르게 사용되고 있습니다:
- GatheringCard 컴포넌트에서 모임 상세 정보를 조회하는 useGetGatheringDetailQuery에 필요한 파라미터로 사용
- API 엔드포인트
/api/crews/${crewId}/gatherings/${gatheringId}에서 특정 크루의 모임 정보를 조회하는데 사용
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: crewId 사용 방식 확인
# GatheringCardCarousel 컴포넌트에서 crewId prop 사용 확인
ast-grep --pattern 'interface GatheringCardCarouselProps {
$$$
crewId: $_
$$$
}'
# crewId 사용 패턴 검색
rg -A 3 'crewId' src/components/gathering-list/
Length of output: 1757
Script:
#!/bin/bash
# GatheringCard 컴포넌트에서 crewId prop 사용 확인
ast-grep --pattern 'interface GatheringCardProps {
$$$
crewId: $_
$$$
}'
# GatheringCard 컴포넌트 내에서 crewId 사용 패턴 검색
rg -A 3 'crewId' src/components/gathering-card/
Length of output: 199
Script:
#!/bin/bash
# Find GatheringCard component file
fd GatheringCard
# Search for GatheringCard interface and crewId usage
rg -A 3 "interface.*GatheringCard"
rg -A 3 "type.*GatheringCard"
Length of output: 6525
Script:
#!/bin/bash
# Check GatheringCard container implementation
rg -A 10 "GatheringCardContainer" src/components/common/gathering-card/container.tsx
# Check if crewId is used in any API calls or important logic
rg -A 5 "crewId.*=" src/components/common/gathering-card/
rg -A 5 "useQuery.*crewId" src/components/common/gathering-card/
Length of output: 719
Script:
#!/bin/bash
# Search for API calls or hooks using crewId
rg -A 5 "api.*crewId"
rg -A 5 "mutation.*crewId"
rg -A 5 "useGathering.*crewId"
# Check the GatheringCard implementation file content
cat src/components/common/gathering-card/container.tsx
Length of output: 3296
src/components/common/gathering-card/gathering-card.stories.tsx (1)
28-34: 데코레이터 구현이 잘 되었습니다.
QueryClientProvider를 데코레이터로 구현한 방식이 적절합니다. 모든 스토리에서 일관된 Query 컨텍스트를 사용할 수 있게 되었습니다.
src/components/gathering-list/gathering-card-carousel.tsx (3)
12-12: Props 인터페이스 변경이 적절히 구현되었습니다.
crewId prop이 인터페이스에 추가되고 컴포넌트에서 올바르게 구조분해되어 사용되고 있습니다.
Also applies to: 15-18
63-63: 반응형 레이아웃 동작을 확인해주세요.
레이아웃 관련 변경사항들이 있어 다음 사항들을 확인해주시면 좋겠습니다:
- 모바일에서 카드가 전체 너비를 차지하는지
- lg 브레이크포인트에서 최소 너비 제한이 잘 적용되는지
- 여백이 디자인과 일치하는지
추가로, 브레이크포인트별 레이아웃 값들을 상수로 분리하는 것을 고려해보세요. 예:
const LAYOUT_CONFIG = {
mobile: {
slidesToShow: 1,
slideSize: 'w-full'
},
tablet: {
slidesToShow: 2,
slideSize: 'w-[calc(50%-8px)]'
},
desktop: {
slidesToShow: 3,
slideSize: 'w-[calc(33.33%-12px)]'
}
} as const;Also applies to: 77-78
109-109: 인디케이터 여백이 디자인 명세와 일치하는지 확인해주세요.
인디케이터의 상단 여백이 mt-4에서 mt-2로 변경되었습니다. 이 변경이 디자인 명세와 일치하는지 확인이 필요합니다.
src/components/common/gathering-card/presenter.tsx (1)
4-4: import 경로 변경이 적절합니다.
유틸리티 함수를 utils 디렉토리로 이동한 것은 코드 구조화 측면에서 좋은 변경입니다.
src/components/common/crew-list/detail-crew-card.tsx (2)
14-25: 인터페이스 구조 개선이 잘 되었습니다!
데이터를 하나의 객체로 묶어서 관리하는 방식이 props 전달을 더 깔끔하게 만들었습니다.
28-40: 데이터 구조 분해가 깔끔하게 되었습니다!
객체 구조 분해를 통해 코드의 가독성이 향상되었습니다.
| const response = await fetchApi<{ data: CrewDetail }>(url, { | ||
| method: 'GET', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| }); | ||
|
|
||
| return { data: response[0] }; | ||
| return response.data; |
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
에러 처리 로직 추가 검토 필요
API 호출 실패 시의 에러 처리가 명시적으로 구현되어 있지 않습니다. 사용자 경험 향상을 위해 에러 처리 로직 추가를 고려해 주세요.
다음과 같은 구현을 제안드립니다:
export async function getCrewDetail(id: number): Promise<CrewDetail> {
const url = `/api/crews/${id}`;
- const response = await fetchApi<{ data: CrewDetail }>(url, {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- },
- });
- return response.data;
+ try {
+ const response = await fetchApi<{ data: CrewDetail }>(url, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+ return response.data;
+ } catch (error) {
+ console.error('크루 상세 정보를 가져오는데 실패했습니다:', error);
+ throw new Error('크루 상세 정보를 불러올 수 없습니다.');
+ }
}📝 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.
| const response = await fetchApi<{ data: CrewDetail }>(url, { | |
| method: 'GET', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }); | |
| return { data: response[0] }; | |
| return response.data; | |
| try { | |
| const response = await fetchApi<{ data: CrewDetail }>(url, { | |
| method: 'GET', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }); | |
| return response.data; | |
| } catch (error) { | |
| console.error('크루 상세 정보를 가져오는데 실패했습니다:', error); | |
| throw new Error('크루 상세 정보를 불러올 수 없습니다.'); | |
| } |
| const url = `/api/crews/${id}/gatherings`; | ||
|
|
||
| const response = await fetchApi<{ data: GatheringType[] }>(url, { | ||
| method: 'GET', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| }); | ||
| return response.data; |
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
API 응답 처리 개선이 필요합니다.
API 응답 처리에서 몇 가지 개선이 필요합니다:
- 오류 처리가 누락되어 있습니다.
- API 응답의 유효성 검사가 없습니다.
다음과 같이 개선하는 것을 제안드립니다:
export async function getGatheringList(id: number): Promise<GatheringType[]> {
const url = `/api/crews/${id}/gatherings`;
+ try {
const response = await fetchApi<{ data: GatheringType[] }>(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
+
+ if (!response.data) {
+ throw new Error('데이터가 존재하지 않습니다');
+ }
+
return response.data;
+ } catch (error) {
+ console.error('모임 목록을 가져오는데 실패했습니다:', error);
+ throw error;
+ }
}또한 API 응답의 타입 안전성을 위해 zod와 같은 런타임 타입 검증 라이브러리의 사용을 고려해보시는 것을 추천드립니다.
📝 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.
| const url = `/api/crews/${id}/gatherings`; | |
| const response = await fetchApi<{ data: GatheringType[] }>(url, { | |
| method: 'GET', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }); | |
| return response.data; | |
| export async function getGatheringList(id: number): Promise<GatheringType[]> { | |
| const url = `/api/crews/${id}/gatherings`; | |
| try { | |
| const response = await fetchApi<{ data: GatheringType[] }>(url, { | |
| method: 'GET', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }); | |
| if (!response.data) { | |
| throw new Error('데이터가 존재하지 않습니다'); | |
| } | |
| return response.data; | |
| } catch (error) { | |
| console.error('모임 목록을 가져오는데 실패했습니다:', error); | |
| throw error; | |
| } | |
| } |
| export async function GetGatheringDetail( | ||
| crewId: number, | ||
| gatheringId: number, | ||
| ): Promise<GatheringDetailType> { |
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
함수 이름이 컨벤션을 따르지 않습니다
함수 이름이 파스칼 케이스(PascalCase)로 작성되어 있습니다. JavaScript/TypeScript에서 함수는 일반적으로 카멜 케이스(camelCase)를 사용합니다.
다음과 같이 수정하는 것을 제안합니다:
-export async function GetGatheringDetail(
+export async function getGatheringDetail(
crewId: number,
gatheringId: number,
): Promise<GatheringDetailType>📝 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 async function GetGatheringDetail( | |
| crewId: number, | |
| gatheringId: number, | |
| ): Promise<GatheringDetailType> { | |
| export async function getGatheringDetail( | |
| crewId: number, | |
| gatheringId: number, | |
| ): Promise<GatheringDetailType> { |
| const response = await fetchApi<{ data: GatheringDetailType }>(url, { | ||
| method: 'GET', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| }); |
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.
에러 처리 로직이 필요합니다
API 호출 시 발생할 수 있는 다양한 에러 상황(네트워크 오류, 서버 오류 등)에 대한 처리가 없습니다.
다음과 같은 에러 처리를 추가하는 것을 제안합니다:
- const response = await fetchApi<{ data: GatheringDetailType }>(url, {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- },
- });
+ try {
+ const response = await fetchApi<{ data: GatheringDetailType }>(url, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+ return response.data;
+ } catch (error) {
+ if (error instanceof Error) {
+ throw new Error(`모임 상세 정보를 가져오는데 실패했습니다: ${error.message}`);
+ }
+ throw new Error('모임 상세 정보를 가져오는데 실패했습니다');
+ }📝 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.
| const response = await fetchApi<{ data: GatheringDetailType }>(url, { | |
| method: 'GET', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }); | |
| try { | |
| const response = await fetchApi<{ data: GatheringDetailType }>(url, { | |
| method: 'GET', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }); | |
| return response.data; | |
| } catch (error) { | |
| if (error instanceof Error) { | |
| throw new Error(`모임 상세 정보를 가져오는데 실패했습니다: ${error.message}`); | |
| } | |
| throw new Error('모임 상세 정보를 가져오는데 실패했습니다'); | |
| } |
| if (error) { | ||
| if (error instanceof ApiError) { | ||
| try { | ||
| const errorData = JSON.parse(error.message); | ||
|
|
||
| if (errorData.status === 'NOT_FOUND') { | ||
| return <p>크루 정보를 찾을 수 없습니다</p>; | ||
| } | ||
| } catch { | ||
| return <p>{`Error ${error.status}: ${error.message}`}</p>; | ||
| } | ||
| } | ||
| return <p>데이터 통신에 실패했습니다.</p>; | ||
| } |
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
에러 처리 로직 개선 필요
현재 에러 처리 로직이 복잡하고 중첩된 조건문을 사용하고 있어 유지보수가 어려울 수 있습니다.
다음과 같이 에러 처리를 단순화하는 것을 제안합니다:
- if (error) {
- if (error instanceof ApiError) {
- try {
- const errorData = JSON.parse(error.message);
-
- if (errorData.status === 'NOT_FOUND') {
- return <p>크루 정보를 찾을 수 없습니다</p>;
- }
- } catch {
- return <p>{`Error ${error.status}: ${error.message}`}</p>;
- }
- }
- return <p>데이터 통신에 실패했습니다.</p>;
- }
+ if (error) {
+ const getErrorMessage = () => {
+ if (!(error instanceof ApiError)) {
+ return '데이터 통신에 실패했습니다.';
+ }
+ try {
+ const errorData = JSON.parse(error.message);
+ return errorData.status === 'NOT_FOUND'
+ ? '크루 정보를 찾을 수 없습니다'
+ : `Error ${error.status}: ${error.message}`;
+ } catch {
+ return `Error ${error.status}: ${error.message}`;
+ }
+ };
+ return <p>{getErrorMessage()}</p>;
+ }📝 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.
| if (error) { | |
| if (error instanceof ApiError) { | |
| try { | |
| const errorData = JSON.parse(error.message); | |
| if (errorData.status === 'NOT_FOUND') { | |
| return <p>크루 정보를 찾을 수 없습니다</p>; | |
| } | |
| } catch { | |
| return <p>{`Error ${error.status}: ${error.message}`}</p>; | |
| } | |
| } | |
| return <p>데이터 통신에 실패했습니다.</p>; | |
| } | |
| if (error) { | |
| const getErrorMessage = () => { | |
| if (!(error instanceof ApiError)) { | |
| return '데이터 통신에 실패했습니다.'; | |
| } | |
| try { | |
| const errorData = JSON.parse(error.message); | |
| return errorData.status === 'NOT_FOUND' | |
| ? '크루 정보를 찾을 수 없습니다' | |
| : `Error ${error.status}: ${error.message}`; | |
| } catch { | |
| return `Error ${error.status}: ${error.message}`; | |
| } | |
| }; | |
| return <p>{getErrorMessage()}</p>; | |
| } |
| export default async function CrewDetailPage({ params }: CrewDetailPageProps) { | ||
| const id = Number(params.id); |
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.
params.id의 타입 변환 처리를 개선해 주세요.
Number() 함수를 직접 사용하면 잘못된 id 형식에 대한 처리가 누락될 수 있습니다.
다음과 같이 개선하는 것을 추천드립니다:
- const id = Number(params.id);
+ const id = parseInt(params.id, 10);
+ if (isNaN(id)) {
+ throw new Error('Invalid ID format');
+ }📝 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 default async function CrewDetailPage({ params }: CrewDetailPageProps) { | |
| const id = Number(params.id); | |
| export default async function CrewDetailPage({ params }: CrewDetailPageProps) { | |
| const id = parseInt(params.id, 10); | |
| if (isNaN(id)) { | |
| throw new Error('Invalid ID format'); | |
| } |
| participantCount: 10, | ||
| totalCount: 20, | ||
| confirmed: true, | ||
| imageUrl: 'https://i.pinimg.com/564x/f8/8d/c5/f88dc5b857caf6c303ae5ef9dd12e7fb.jpg', |
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
이미지 URL을 상수로 분리하세요
하드코딩된 이미지 URL들이 여러 곳에서 반복되고 있습니다. 이는 유지보수를 어렵게 만들 수 있습니다.
스토리북 설정 파일에 상수로 분리하는 것을 제안합니다:
const MOCK_IMAGES = {
CREW_DEFAULT: 'https://i.pinimg.com/564x/f8/8d/c5/f88dc5b857caf6c303ae5ef9dd12e7fb.jpg',
PROFILE_DEFAULT: 'https://i.pinimg.com/564x/e2/25/bb/e225bb492dc7a20a549f3c0abec28eb8.jpg'
} as const;Also applies to: 29-30, 35-36, 56-56, 73-73
| {/* {currentPageData.map((card, id) => ( | ||
| <GatheringCard key={id} {...card} className={cardClassName} /> | ||
| ))} | ||
| ))} */} |
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.
💡 Codebase verification
주석 처리된 코드로 인한 심각한 기능 문제 확인됨
코드베이스 분석 결과, 현재 gathering-list.tsx에서 핵심 기능인 GatheringCard 렌더링이 주석 처리되어 있으며, 이는 다음과 같은 실제 문제를 야기합니다:
- 모임 데이터가 전혀 표시되지 않음
- 페이지네이션은 존재하지만 실제 데이터를 보여주지 않음
- 빈 카드만 표시되어 사용자 경험이 심각하게 저하됨
다음과 같이 수정하시기를 강력히 권장드립니다:
{currentPageData.length > 0 ? (
currentPageData.map((card, id) => (
<GatheringCard key={id} {...card} className={cardClassName} />
))
) : (
<div className="col-span-full text-center py-8">
현재 표시할 모임이 없습니다.
</div>
)}🔗 Analysis chain
주석 처리된 코드로 인한 잠재적 문제
현재 주요 기능인 GatheringCard 렌더링이 주석 처리되어 있습니다. 이로 인해 다음과 같은 문제가 발생할 수 있습니다:
- 사용자에게 데이터가 표시되지 않음
- 페이지네이션은 작동하지만 실제 데이터를 볼 수 없음
- 빈 카드만 표시되어 사용자 경험 저하
다음 중 하나의 방안을 선택하시기를 권장드립니다:
- 주석을 제거하고 기능을 복원
- 임시 UI나 로딩 상태를 표시
- 기능이 준비되지 않았다면 사용자에게 알림 메시지 표시
- {/* {currentPageData.map((card, id) => (
- <GatheringCard key={id} {...card} className={cardClassName} />
- ))} */}
+ {currentPageData.length > 0 ? (
+ currentPageData.map((card, id) => (
+ <GatheringCard key={id} {...card} className={cardClassName} />
+ ))
+ ) : (
+ <div className="col-span-full text-center py-8">
+ 현재 표시할 모임이 없습니다.
+ </div>
+ )}페이지네이션 기능이 여전히 올바르게 작동하는지 확인이 필요합니다:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 페이지네이션 관련 로직이 다른 컴포넌트에서도 사용되는지 확인
rg -l "Pagination.*total={Math\.ceil\("
Length of output: 174
Script:
#!/bin/bash
# 페이지네이션 관련 코드 검색
rg -l "Pagination.*total"
# GatheringCard 컴포넌트 사용 현황 확인
rg -l "GatheringCard"
# gathering-list.tsx 전체 내용 확인
cat src/components/gathering-list/gathering-list.tsx
Length of output: 4481
| if (error) { | ||
| if (error instanceof ApiError) { | ||
| try { | ||
| const errorData = JSON.parse(error.message); | ||
|
|
||
| if (opened) { | ||
| fetchGatheringDetail(); | ||
| if (errorData.status === 'NOT_FOUND') { | ||
| Toast({ message: '모임 정보를 찾을 수 없습니다.', type: 'error' }); | ||
| } | ||
| } catch { | ||
| Toast({ message: `Error ${error.status}: ${error.message}`, type: 'error' }); | ||
| } | ||
| } else { | ||
| Toast({ message: '데이터 통신에 실패했습니다.', type: 'error' }); | ||
| } | ||
| } | ||
| }, [opened]); | ||
| }, [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
에러 처리 로직 개선 제안
error.message를 JSON으로 파싱하는 대신, error.response?.data 또는 error.data를 사용하여 에러 정보를 처리하는 것이 더 안전하고 정확합니다. 이는 서버에서 전달된 실제 에러 데이터를 직접 활용하여 파싱 에러를 방지할 수 있습니다.
다음과 같이 수정하는 것을 제안합니다:
useEffect(() => {
if (error) {
if (error instanceof ApiError) {
- try {
- const errorData = JSON.parse(error.message);
+ const errorData = error.response?.data;
if (errorData.status === 'NOT_FOUND') {
Toast({ message: '모임 정보를 찾을 수 없습니다.', type: 'error' });
}
- } catch {
- Toast({ message: `Error ${error.status}: ${error.message}`, type: 'error' });
- }
} else {
Toast({ message: '데이터 통신에 실패했습니다.', type: 'error' });
}
}
}, [error]);Committable suggestion skipped: line range outside the PR's diff.
minkyung5x5
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.
수고하셨습니다!!!
ChoYenii
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.
수고많으셨습니다!
yulrang
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.
수고하셨습니다~!~! 고생하셨어용
🔖 Issue Ticket
#103
✍️ Description
디테일 페이지 get으로 요청 되는 부분 추가했습니다!
파일이 너무 많아져서 다른 요청은 다른 브렌치에 추가하겠습니다!
디테일 페이지 수정사항은 어차피 디자인이 바뀌면 다시 작업해야하기때문에,,, 나중에 수정하겠습니다!
어제 줌으로 전달했지만 fetch api에 baseUrl을 추가하고, next config rewrite 부분을 삭제했습니다!
제 실수로 env파일이 잘못 올라가는 바람에... 강사님이 도와주셔서 이전엔 커밋은 사라지고, 하나의 커밋만이 남았습니다ㅠㅠ
✅ Checklist
PR
Test
Summary by CodeRabbit
신규 기능
DetailCrewSection및GatheringListSection컴포넌트 추가로 크루 상세 정보와 모임 목록 표시.버그 수정
문서화
DetailCrewCard의 데이터 구조 변경 및 업데이트.리팩토링