From 39069a4b9dbf8eb03c82af63e8da602de632a9e6 Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Thu, 1 Feb 2024 23:58:30 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20#289=20-=20SearchSpaceReqBody=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/types/index.ts b/src/types/index.ts index 4bbac1b6..a39932bc 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -112,7 +112,9 @@ export interface UserDetailInfo { // 검색 req body export interface SearchSpaceReqBody { memberId?: number - pageNumber: number + pageNumber?: number + lastSpaceId?: number + lastFavoriteCount?: number pageSize: number sort?: string keyWord?: string From 663688d7abdb34dd01b07157a8cb8a6ececc854c Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Fri, 2 Feb 2024 00:01:44 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20#289=20-=20=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=9D=98=20=EC=8A=A4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A5=BC=20Cur?= =?UTF-8?q?sor-based=20pagination=20=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 11 +-- .../SpaceList/hooks/useMainSpacesQuery.ts | 77 ++++++++++++++++ .../common/MainSpaceList/MainSpaceList.tsx | 87 +++++++++++++++++++ src/services/space/spaces.ts | 12 ++- 4 files changed, 175 insertions(+), 12 deletions(-) create mode 100644 src/components/SpaceList/hooks/useMainSpacesQuery.ts create mode 100644 src/components/common/MainSpaceList/MainSpaceList.tsx diff --git a/src/app/page.tsx b/src/app/page.tsx index d8da13cc..003f3b2b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,14 +1,9 @@ 'use client' -import { - CategoryList, - Dropdown, - LinkItem, - SpaceList, - Spinner, -} from '@/components' +import { CategoryList, Dropdown, LinkItem, Spinner } from '@/components' import FloatingButton from '@/components/FloatingButton/FloatingButton' import { ChipColors } from '@/components/common/Chip/Chip' +import MainSpaceList from '@/components/common/MainSpaceList/MainSpaceList' import { useCategoryParam, useSortParam } from '@/hooks' import useGetPopularLinks from '@/hooks/useGetPopularLinks' import { fetchGetSpaces } from '@/services/space/spaces' @@ -77,7 +72,7 @@ export default function Home() { onChange={handleCategoryChange} /> - { + const sortValue = + queryKey === 'main' || queryKey === 'search' + ? sort === 'favorite' + ? 'favorite_count' + : 'created_at' + : undefined + const categoryValue = category === 'all' ? '' : category.toUpperCase() + const { data, fetchNextPage, hasNextPage, isLoading } = useInfiniteQuery({ + queryKey: [ + 'spaces', + queryKey, + { + ...(memberId && { memberId: memberId }), + ...(sortValue && { sort: sortValue }), + category: categoryValue, + keyword, + }, + ], + queryFn: ({ pageParam }) => + fetchFn({ + memberId, + lastFavoriteCount: pageParam.lastFavoriteCount, + lastSpaceId: pageParam.lastSpaceId, + pageSize: PAGE_SIZE, + sort: sortValue, + filter: categoryValue, + keyWord: keyword, + }), + initialPageParam: { lastSpaceId: undefined, lastFavoriteCount: undefined }, + getNextPageParam: ( + lastPage: MainSpacePageType, + ): + | { + lastSpaceId: number | undefined + lastFavoriteCount: number | undefined + } + | undefined => { + return lastPage.metaData?.hasNext + ? { + lastSpaceId: lastPage.metaData.lastId, + lastFavoriteCount: lastPage.metaData.lastFavoriteCount, + } + : undefined + }, + }) + + return { + spaces: data, + fetchNextPage, + hasNextPage, + isSpacesLoading: isLoading, + } +} + +export default useMainSpacesQuery diff --git a/src/components/common/MainSpaceList/MainSpaceList.tsx b/src/components/common/MainSpaceList/MainSpaceList.tsx new file mode 100644 index 00000000..4db44fde --- /dev/null +++ b/src/components/common/MainSpaceList/MainSpaceList.tsx @@ -0,0 +1,87 @@ +'use client' + +import { Fragment } from 'react' +import { NONE_SEARCH_RESULT } from '@/components/SpaceList/constants' +import useMainSpacesQuery from '@/components/SpaceList/hooks/useMainSpacesQuery' +import { CATEGORIES_RENDER } from '@/constants' +import useInfiniteScroll from '@/hooks/useInfiniteScroll' +import { SearchSpaceReqBody, SpaceResBody } from '@/types' +import { Spinner } from '../..' +import Space from '../Space/Space' + +export interface SpaceListProps { + memberId?: number + queryKey: string + sort?: string + category: string + keyword?: string + fetchFn: ({ + memberId, + pageNumber, + lastFavoriteCount, + lastSpaceId, + pageSize, + sort, + filter, + keyWord, + }: SearchSpaceReqBody) => Promise +} + +const MainSpaceList = ({ + queryKey, + memberId, + sort, + category, + keyword, + fetchFn, +}: SpaceListProps) => { + const { spaces, fetchNextPage, hasNextPage, isSpacesLoading } = + useMainSpacesQuery({ + queryKey, + memberId, + sort, + category, + keyword, + fetchFn, + }) + + const { target } = useInfiniteScroll({ hasNextPage, fetchNextPage }) + console.log(spaces) + return isSpacesLoading ? ( + + ) : ( + <> +
    + {spaces?.pages[0].responses.length + ? spaces?.pages.map((group, i) => ( + + {group.responses?.map((space: SpaceResBody) => ( +
  • + +
  • + ))} +
    + )) + : !isSpacesLoading && ( +
    + {NONE_SEARCH_RESULT} +
    + )} + +
    +
+ + ) +} + +export default MainSpaceList diff --git a/src/services/space/spaces.ts b/src/services/space/spaces.ts index 9057bdfa..32b4ed16 100644 --- a/src/services/space/spaces.ts +++ b/src/services/space/spaces.ts @@ -2,15 +2,19 @@ import { SearchSpaceReqBody, SpaceInviteResBody } from '@/types' import { apiClient } from '../apiServices' const fetchGetSpaces = async ({ - pageNumber, + lastSpaceId, + lastFavoriteCount, pageSize, sort, filter, }: SearchSpaceReqBody) => { const path = '/api/spaces' const params = { - pageNumber: pageNumber.toString(), pageSize: pageSize.toString(), + ...(lastSpaceId !== undefined && { lastSpaceId: lastSpaceId.toString() }), + ...(lastFavoriteCount !== undefined && { + lastFavoriteCount: lastFavoriteCount.toString(), + }), ...(sort && { sort: sort }), filter: filter, } @@ -25,7 +29,7 @@ const fetchGetSpaces = async ({ } const fetchSearchSpaces = async ({ - pageNumber, + pageNumber = 0, pageSize, sort, filter, @@ -51,7 +55,7 @@ const fetchSearchSpaces = async ({ const fetchSearchMySpaces = async ({ memberId, - pageNumber, + pageNumber = 0, pageSize, filter, keyWord, From 467800d5a4bd50c33120a33ea58a133a32b22288 Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Fri, 2 Feb 2024 00:02:30 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20#289=20-=20pageNumber=EC=97=90=20de?= =?UTF-8?q?fault=20=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/user/profile/favorites.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/user/profile/favorites.ts b/src/services/user/profile/favorites.ts index 852d1e27..444f5d20 100644 --- a/src/services/user/profile/favorites.ts +++ b/src/services/user/profile/favorites.ts @@ -2,7 +2,7 @@ import { apiClient } from '@/services/apiServices' import { SearchSpaceReqBody } from '@/types' const fetchGetMyFavoriteSpaces = async ({ - pageNumber, + pageNumber = 0, pageSize, keyWord, filter, From 04ab8073bd841ef403c534171e70f73fa3162393 Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Fri, 2 Feb 2024 15:42:02 +0900 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20#289=20-=20=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/MainSpaceList/MainSpaceList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/MainSpaceList/MainSpaceList.tsx b/src/components/common/MainSpaceList/MainSpaceList.tsx index 4db44fde..34a8b4dc 100644 --- a/src/components/common/MainSpaceList/MainSpaceList.tsx +++ b/src/components/common/MainSpaceList/MainSpaceList.tsx @@ -46,7 +46,7 @@ const MainSpaceList = ({ }) const { target } = useInfiniteScroll({ hasNextPage, fetchNextPage }) - console.log(spaces) + return isSpacesLoading ? ( ) : (