-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
57 changed files
with
979 additions
and
640 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
src/app/(root)/(routes)/cards/components/card-list-content/CardListContent.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
'use client' | ||
|
||
import { useEffect, useRef, useState } from 'react' | ||
import { useSearchParams } from 'next/navigation' | ||
import ExceptionBoundary from '@/components/domain/exception-boundary' | ||
import { useCardsQuery } from '@/hooks/api/queries/useCardsQuery' | ||
import { useIntersectionObserver } from '@/hooks/useIntersectionObserver' | ||
import { CategoryObjs, PriceRangeObjs } from '@/types/card' | ||
import CardList from '../card-list/CardList' | ||
import FilterFormDialog from '../filter-form-dialog' | ||
import SearchInput from '../search-input' | ||
|
||
const CardListContent = () => { | ||
const searchParams = useSearchParams() | ||
const [cardTitle, setCardTitle] = useState( | ||
searchParams.get('cardTitle' as string) || '', | ||
) | ||
const [category, setCatgegory] = useState<CategoryObjs['key']>( | ||
(searchParams.get('category') as CategoryObjs['key']) || undefined, | ||
) | ||
const [priceRange, setPriceRange] = useState<PriceRangeObjs['key']>( | ||
(searchParams.get('priceRange') as PriceRangeObjs['key']) || undefined, | ||
) | ||
|
||
// TODO: 현재 API 명세에 status에 어떤 값을 줘야하는지에 대한 정의가 되어 있지 않기 때문에 임시로 상수 값을 전달함 => 추후에 실제 동작 값으로 고치기 | ||
const { data, fetchNextPage, isError, isFetchingNextPage, isLoading } = | ||
useCardsQuery({ | ||
category: category, | ||
priceRange: priceRange, | ||
cardTitle: cardTitle, | ||
}) | ||
|
||
const lastElementRef = useRef<HTMLDivElement | null>(null) | ||
const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 }) | ||
|
||
useEffect(() => { | ||
if (isFetchingNextPage) { | ||
return | ||
} | ||
|
||
if (entry?.isIntersecting) { | ||
fetchNextPage() | ||
} | ||
}, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage]) | ||
|
||
// TODO: 아이템이 없을시 어떤 UI를 보여줄지 차후에 결정 | ||
|
||
const isEmpty = data?.pages[0].data.cardList.length === 0 | ||
console.log('content', data) | ||
|
||
return ( | ||
<> | ||
<div className="h-9 flex justify-between items-center mb-6"> | ||
<SearchInput setCardTitle={setCardTitle} /> | ||
<FilterFormDialog | ||
category={category} | ||
priceRange={priceRange} | ||
setPriceRange={setPriceRange} | ||
setCategory={setCatgegory} | ||
/> | ||
</div> | ||
<div> | ||
<ExceptionBoundary | ||
isLoading={isLoading} | ||
isError={isError} | ||
isEmpty={isEmpty} | ||
isFetchingNextPage={isFetchingNextPage} | ||
> | ||
<CardList data={data} /> | ||
</ExceptionBoundary> | ||
</div> | ||
<div ref={lastElementRef} /> | ||
</> | ||
) | ||
} | ||
export default CardListContent |
3 changes: 3 additions & 0 deletions
3
src/app/(root)/(routes)/cards/components/card-list-content/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import CardListContent from './CardListContent' | ||
|
||
export default CardListContent |
107 changes: 22 additions & 85 deletions
107
src/app/(root)/(routes)/cards/components/card-list/CardList.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,88 +1,25 @@ | ||
'use client' | ||
|
||
import { useEffect, useRef, Fragment, useState } from 'react' | ||
import { useSearchParams } from 'next/navigation' | ||
import { Fragment } from 'react' | ||
import { InfiniteData } from '@tanstack/react-query' | ||
import TradeStatusCard from '@/components/domain/card/trade-status-card' | ||
import ExceptionBoundary from '@/components/domain/exception-boundary' | ||
import MaxWidthWrapper from '@/components/domain/max-width-wrapper' | ||
import { useCardsQuery } from '@/hooks/api/queries/useCardsQuery' | ||
import { useIntersectionObserver } from '@/hooks/useIntersectionObserver' | ||
import { GetCardListRes } from '@/services/card/card' | ||
import { Card } from '@/types/card' | ||
import { Category, PriceRange } from '@/types/card' | ||
import FilterFormDialog from '../filter-form-dialog' | ||
import SearchInput from '../search-input' | ||
|
||
const CardListContent = () => { | ||
const searchParams = useSearchParams() | ||
const [cardTitle, setCardTitle] = useState( | ||
searchParams.get('cardTitle' as string) || '', | ||
) | ||
const [category, setCatgegory] = useState<Category>( | ||
(searchParams.get('category') as Category) || '전체보기', | ||
) | ||
const [priceRange, setPriceRange] = useState<PriceRange>( | ||
(searchParams.get('priceRange') as PriceRange) || '전체보기', | ||
) | ||
|
||
// TODO: 현재 API 명세에 status에 어떤 값을 줘야하는지에 대한 정의가 되어 있지 않기 때문에 임시로 상수 값을 전달함 => 추후에 실제 동작 값으로 고치기 | ||
const { data, fetchNextPage, isError, isFetchingNextPage, isLoading } = | ||
useCardsQuery({ | ||
category: category, | ||
priceRange: priceRange, | ||
cardTitle: cardTitle, | ||
}) | ||
|
||
const lastElementRef = useRef<HTMLDivElement | null>(null) | ||
const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 }) | ||
|
||
useEffect(() => { | ||
if (isFetchingNextPage) { | ||
return | ||
} | ||
|
||
if (entry?.isIntersecting) { | ||
fetchNextPage() | ||
} | ||
}, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage]) | ||
|
||
// TODO: 아이템이 없을시 어떤 UI를 보여줄지 차후에 결정 | ||
|
||
const isEmpty = data?.pages[0].length === 0 | ||
|
||
return ( | ||
<MaxWidthWrapper> | ||
<div className="h-9 flex justify-between items-center mb-6"> | ||
<SearchInput setCardTitle={setCardTitle} /> | ||
<FilterFormDialog | ||
category={category} | ||
priceRange={priceRange} | ||
setPriceRange={setPriceRange} | ||
setCategory={setCatgegory} | ||
/> | ||
</div> | ||
<div> | ||
<ExceptionBoundary | ||
isLoading={isLoading} | ||
isError={isError} | ||
isEmpty={isEmpty} | ||
isFetchingNextPage={isFetchingNextPage} | ||
> | ||
<> | ||
{data?.pages.map((currentPage: any, pageIndex) => ( | ||
<Fragment key={pageIndex}> | ||
{currentPage.map((card: Card) => ( | ||
<div key={card.cardId} className="mb-6"> | ||
<TradeStatusCard card={card} /> | ||
</div> | ||
))} | ||
</Fragment> | ||
))} | ||
</> | ||
</ExceptionBoundary> | ||
</div> | ||
|
||
<div ref={lastElementRef} /> | ||
</MaxWidthWrapper> | ||
) | ||
} | ||
export default CardListContent | ||
const CardList = ({ | ||
data, | ||
}: { | ||
data: InfiniteData<GetCardListRes, unknown> | undefined | ||
}) => ( | ||
<> | ||
{data?.pages.map(({ data: { cardList } }: GetCardListRes, pageIndex) => ( | ||
<Fragment key={pageIndex}> | ||
{cardList.map((card: Card) => ( | ||
<div key={card.cardId} className="mb-6"> | ||
<TradeStatusCard card={card} /> | ||
</div> | ||
))} | ||
</Fragment> | ||
))} | ||
</> | ||
) | ||
|
||
export default CardList |
Oops, something went wrong.