-
Notifications
You must be signed in to change notification settings - Fork 3
Feat/105/my crew api 연결 #109
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
Changes from 8 commits
2c8278b
aea88e1
91b6927
013b2de
58be236
5faea7f
26d1701
f5472c7
ff655e2
a5fbad9
e466861
9ad835f
ad03a87
4d4dcd9
e946b5e
fd76ffb
bdb86e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { fetchApi } from '@/src/utils/api'; | ||
| import { MyCrewListResponse, PageableTypes } from '@/src/types/crew-card'; | ||
|
|
||
| export async function getMyCrewHostedList(pageable: PageableTypes) { | ||
| const { page, size, sort = ['string'] } = pageable; | ||
|
|
||
| const response: { data: MyCrewListResponse } = await fetchApi( | ||
| `/api/crews/hosted?page=${page}&size=${size}&sort=${sort}`, | ||
| { | ||
| method: 'GET', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| credentials: 'include', // 인증 정보를 요청에 포함 | ||
| }, | ||
| ); | ||
| return response.data; | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,18 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { fetchApi } from '@/src/utils/api'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { MyCrewListResponse, PageableTypes } from '@/src/types/crew-card'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export async function getMyCrewJoinedList(pageable: PageableTypes) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { page, size, sort = ['string'] } = pageable; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const response: { data: MyCrewListResponse } = await fetchApi( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `/api/crews/joined?page=${page}&size=${size}&sort=${sort}`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| method: 'GET', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| headers: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'Content-Type': 'application/json', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| credentials: 'include', // 인증 정보를 요청에 포함 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return response.data; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 에러 처리와 코드 일관성 개선이 필요합니다. 다음과 같은 개선사항들을 제안드립니다:
다음과 같이 수정해보시는 건 어떨까요?: export async function getMyCrewJoinedList(pageable: PageableTypes) {
const { page, size, sort = ['string'] } = pageable;
+
+ if (page < 0 || size <= 0) {
+ throw new Error('Invalid pagination parameters');
+ }
- const response: { data: MyCrewListResponse } = await fetchApi(
- `/api/crews/joined?page=${page}&size=${size}&sort=${sort}`,
- {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- },
- credentials: 'include', // 인증 정보를 요청에 포함
- },
- );
- return response.data;
+ try {
+ const response: { data: MyCrewListResponse } = await fetchApi(
+ `/api/crews/joined?page=${page}&size=${size}&sort=${sort}`,
+ {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ credentials: 'include', // Include authentication information
+ },
+ );
+ return response.data;
+ } catch (error) {
+ throw new Error(`Failed to fetch joined crew list: ${error.message}`);
+ }
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import { getMyCrewHostedList } from '@/src/_apis/crew/my-crew-hosted-list'; | ||
| import { MyCrewListResponse } from '@/src/types/crew-card'; | ||
|
|
||
| export function useGetMyCrewHostedQuery() { | ||
| return { | ||
| queryKey: ['my-crew-creation'], | ||
| queryFn: ({ pageParam = 0 }) => | ||
| getMyCrewHostedList({ page: pageParam, size: 6, sort: ['string'] }).then((response) => { | ||
|
||
| if (response === undefined) { | ||
| throw new Error('Response is undefined'); | ||
| } | ||
| return response; | ||
| }), | ||
| getNextPageParam: (lastPage: MyCrewListResponse, allPages: MyCrewListResponse[]) => | ||
| lastPage.hasNext ? allPages.length : undefined, | ||
| }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getMyCrewJoinedList } from '@/src/_apis/crew/my-crew-joined-list'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { MyCrewListResponse } from '@/src/types/crew-card'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function useGetMyCrewJoinedQuery() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| queryKey: ['my-crew-participation'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| queryFn: ({ pageParam = 0 }) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getMyCrewJoinedList({ page: pageParam, size: 6, sort: ['string'] }).then((response) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (response === undefined) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error('Response is undefined'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return response; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getNextPageParam: (lastPage: MyCrewListResponse, allPages: MyCrewListResponse[]) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lastPage.hasNext ? allPages.length : undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function useGetMyCrewJoinedQuery() { | |
| return { | |
| queryKey: ['my-crew-participation'], | |
| queryFn: ({ pageParam = 0 }) => | |
| getMyCrewJoinedList({ page: pageParam, size: 6, sort: ['string'] }).then((response) => { | |
| if (response === undefined) { | |
| throw new Error('Response is undefined'); | |
| } | |
| return response; | |
| }), | |
| getNextPageParam: (lastPage: MyCrewListResponse, allPages: MyCrewListResponse[]) => | |
| lastPage.hasNext ? allPages.length : undefined, | |
| }; | |
| } | |
| export function useGetMyCrewJoinedQuery({ | |
| pageSize = 6, | |
| sortOption = ['createdAt,desc'] | |
| }: { | |
| pageSize?: number; | |
| sortOption?: string[]; | |
| } = {}) { | |
| return { | |
| queryKey: ['my-crew-participation', pageSize, sortOption], | |
| queryFn: ({ pageParam = 0 }) => | |
| getMyCrewJoinedList({ page: pageParam, size: pageSize, sort: sortOption }).then((response) => { | |
| if (response === undefined) { | |
| throw new Error('크루 목록을 가져오는데 실패했습니다.'); | |
| } | |
| return response; | |
| }), | |
| getNextPageParam: (lastPage: MyCrewListResponse, allPages: MyCrewListResponse[]) => | |
| lastPage.hasNext ? allPages.length : undefined, | |
| }; | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,19 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'use client'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useGetMyCrewHostedQuery } from '@/src/_queries/crew/my-crew-hosted-list-query'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useInfiniteScroll } from '@/src/hooks/use-infinite-scroll'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import CrewCardList from '@/src/components/common/crew-list/crew-card-list'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default function MyCrewParticipationPage() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { data, ref, isFetchingNextPage } = useInfiniteScroll(useGetMyCrewHostedQuery()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <CrewCardList | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inWhere="my-crew" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data={data ?? { pages: [], pageParams: [] }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref={ref} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isFetchingNextPage={isFetchingNextPage} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default function MyCrewParticipationPage() { | |
| const { data, ref, isFetchingNextPage } = useInfiniteScroll(useGetMyCrewHostedQuery()); | |
| return ( | |
| <div> | |
| <CrewCardList | |
| inWhere="my-crew" | |
| data={data ?? { pages: [], pageParams: [] }} | |
| ref={ref} | |
| isFetchingNextPage={isFetchingNextPage} | |
| /> | |
| </div> | |
| ); | |
| } | |
| export default function MyCrewParticipationPage() { | |
| const { | |
| data, | |
| ref, | |
| isFetchingNextPage, | |
| isError, | |
| error, | |
| isLoading | |
| } = useInfiniteScroll(useGetMyCrewHostedQuery()); | |
| if (isLoading) { | |
| return <div>로딩 중...</div>; | |
| } | |
| if (isError) { | |
| return <div>에러가 발생했습니다: {error?.message}</div>; | |
| } | |
| return ( | |
| <div> | |
| <CrewCardList | |
| inWhere="my-crew" | |
| data={data ?? { pages: [], pageParams: [] }} | |
| ref={ref} | |
| isFetchingNextPage={isFetchingNextPage} | |
| /> | |
| </div> | |
| ); | |
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| 'use client'; | ||
|
|
||
| import { useGetMyCrewJoinedQuery } from '@/src/_queries/crew/my-crew-joined-list-query'; | ||
| import { useInfiniteScroll } from '@/src/hooks/use-infinite-scroll'; | ||
| import CrewCardList from '@/src/components/common/crew-list/crew-card-list'; | ||
|
|
||
| export default function MyCrewParticipationPage() { | ||
| const { data, ref, isFetchingNextPage } = useInfiniteScroll(useGetMyCrewJoinedQuery()); | ||
| return ( | ||
| <div> | ||
| <CrewCardList | ||
| inWhere="my-crew" | ||
| data={data ?? { pages: [], pageParams: [] }} | ||
| ref={ref} | ||
| isFetchingNextPage={isFetchingNextPage} | ||
| /> | ||
| </div> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| 'use client'; | ||
|
|
||
| import { ReactNode, useEffect, useState } from 'react'; | ||
| import { usePathname, useRouter } from 'next/navigation'; | ||
| import Tabs from '@/src/components/common/tab'; | ||
|
|
||
| export default function MyCrewLayout({ children }: { children: ReactNode }) { | ||
| const router = useRouter(); | ||
| const currentPath = usePathname(); | ||
| const myCrewTabs = [ | ||
| { label: '내가 참여한 크루', id: 'joined-crew', route: '/my-crew/joined' }, | ||
| { label: '내가 만든 크루', id: 'hosted-crew', route: '/my-crew/hosted' }, | ||
| ]; | ||
| const [currentTab, setCurrentTab] = useState(myCrewTabs[0].id); | ||
|
|
||
| const handleTabClick = (id: string) => { | ||
| const targetRoute = myCrewTabs.find((tab) => tab.id === id)?.route; | ||
| if (targetRoute) router.push(targetRoute); | ||
| }; | ||
|
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 에러 처리 개선이 필요합니다
다음과 같이 수정해보세요: const handleTabClick = (id: string) => {
const targetRoute = myCrewTabs.find((tab) => tab.id === id)?.route;
- if (targetRoute) router.push(targetRoute);
+ if (targetRoute) {
+ router.push(targetRoute);
+ } else {
+ console.error(`탭 ID ${id}에 해당하는 경로를 찾을 수 없습니다.`);
+ // TODO: 사용자에게 에러 메시지 표시
+ }
};
|
||
|
|
||
| useEffect(() => { | ||
| const activeTabId = myCrewTabs.find((tab) => tab.route === currentPath)?.id; | ||
| if (activeTabId) setCurrentTab(activeTabId); | ||
| }, [currentPath]); | ||
|
|
||
| return ( | ||
| <div className="py-8 md:py-12.5"> | ||
| <div className="px-3 md:px-8 lg:px-11.5"> | ||
| <Tabs | ||
| variant="default" | ||
| tabs={myCrewTabs} | ||
| activeTab={currentTab} | ||
| onTabClick={(id) => { | ||
| handleTabClick(id); | ||
| }} | ||
| /> | ||
| </div> | ||
| <div className="mt-8 px-3 md:px-8 lg:px-11.5">{children}</div> | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,40 +1,7 @@ | ||
| 'use client'; | ||
|
|
||
| import { useState } from 'react'; | ||
| import Tabs from '@/src/components/common/tab'; | ||
| import { redirect } from 'next/navigation'; | ||
|
|
||
| export default function MyCrewPage() { | ||
| const myPageTabs = [ | ||
| { label: '내가 참여한 크루', id: 'joined-crew' }, | ||
| { label: '내가 만든 크루', id: 'made-crew' }, | ||
| ]; | ||
| const [currentTab, setCurrentTab] = useState(myPageTabs[0].id); | ||
|
|
||
| // TODO: fetchCrewData 함수를 사용하여 데이터를 불러오기 : 파라미터 수정 필요 | ||
| // TODO: 리스트와는 다른 데이터를 사용해야해서 우선 주석처리 했습니다. | ||
| // const { data, ref, isFetchingNextPage } = | ||
| // useInfiniteScroll<MyCrewListResponse>(useGetCrewListQuery()); | ||
|
|
||
| return ( | ||
| <div className="py-8 md:py-12.5"> | ||
| <div className="px-3 md:px-8 lg:px-11.5"> | ||
| <Tabs | ||
| variant="default" | ||
| tabs={myPageTabs} | ||
| activeTab={currentTab} | ||
| onTabClick={(id) => { | ||
| setCurrentTab(id); | ||
| }} | ||
| /> | ||
| </div> | ||
| <div className="mt-8 px-3 md:px-8 lg:px-11.5"> | ||
| {/* <CrewCardList | ||
| inWhere="my-crew" | ||
| data={data} | ||
| ref={ref} | ||
| isFetchingNextPage={isFetchingNextPage} | ||
| /> */} | ||
| </div> | ||
| </div> | ||
| ); | ||
| redirect('/my-crew/joined'); | ||
| } |
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 호출 실패 시 적절한 에러 처리가 없습니다. 네트워크 오류나 서버 오류에 대한 처리를 추가하는 것이 좋겠습니다.
다음과 같이 에러 처리를 추가하는 것을 제안드립니다:
export async function getMyCrewHostedList(pageable: PageableTypes) { const { page, size, sort = ['string'] } = pageable; - const response: { data: MyCrewListResponse } = await fetchApi( - `/api/crews/hosted?page=${page}&size=${size}&sort=${sort}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - credentials: 'include', // 인증 정보를 요청에 포함 - }, - ); - return response.data; + try { + const response: { data: MyCrewListResponse } = await fetchApi( + `/api/crews/hosted?page=${page}&size=${size}&sort=${sort}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + credentials: 'include', + }, + ); + return response.data; + } catch (error) { + if (error instanceof Error) { + throw new Error(`내가 주최한 크루 목록을 가져오는데 실패했습니다: ${error.message}`); + } + throw error; + } }📝 Committable suggestion