11"use client" ;
2-
2+ import { capsuleQueryOptions } from "@/shared/api/queries/capsule" ;
33import {
44 CAPSULE_SORT ,
55 type CapsuleSortType ,
66 MY_CAPSULE_FILTER ,
77 type MyCapsuleFilterType ,
88} from "@/shared/types/api/capsule" ;
9+ import LoadingSpinner from "@/shared/ui/loading-spinner" ;
910import RevealMotion from "@/shared/ui/motion/reveal-motion" ;
10- import { useState } from "react" ;
11+ import { useInfiniteQuery } from "@tanstack/react-query" ;
12+ import { useCallback , useState } from "react" ;
13+ import { useIntersectionObserver } from "react-simplikit" ;
1114import CardContainer from "./_components/card-container" ;
1215import SelectTabSection from "./_components/select-tab-section" ;
1316import TitleSection from "./_components/title-section" ;
1417
18+ import * as styles from "./page.css" ;
19+
1520const MyCapsule = ( ) => {
1621 const [ selectedTab , setSelectedTab ] = useState < MyCapsuleFilterType > (
1722 MY_CAPSULE_FILTER . ALL ,
@@ -20,6 +25,26 @@ const MyCapsule = () => {
2025 CAPSULE_SORT . DEFAULT ,
2126 ) ;
2227
28+ const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isPending } =
29+ useInfiniteQuery (
30+ capsuleQueryOptions . infiniteMyCapsuleList ( selectedSort , selectedTab ) ,
31+ ) ;
32+
33+ const onIntersect = useCallback (
34+ ( entry : IntersectionObserverEntry ) => {
35+ if ( ! entry . isIntersecting ) return ;
36+ if ( hasNextPage && ! isFetchingNextPage ) {
37+ fetchNextPage ( ) ;
38+ }
39+ } ,
40+ [ hasNextPage , isFetchingNextPage , fetchNextPage ] ,
41+ ) ;
42+
43+ const footerRef = useIntersectionObserver < HTMLDivElement > ( onIntersect , {
44+ threshold : 0.1 ,
45+ rootMargin : "100px 0px" ,
46+ } ) ;
47+
2348 const handleSelect = ( value : MyCapsuleFilterType ) => {
2449 setSelectedTab ( value ) ;
2550 } ;
@@ -28,6 +53,9 @@ const MyCapsule = () => {
2853 setSelectedSort ( value ) ;
2954 } ;
3055
56+ const allCapsules =
57+ data ?. pages . flatMap ( ( page ) => page . result . timeCapsules ) || [ ] ;
58+
3159 return (
3260 < >
3361 < RevealMotion >
@@ -38,7 +66,11 @@ const MyCapsule = () => {
3866 selectedTab = { selectedTab }
3967 handleSort = { handleSort }
4068 />
41- < CardContainer selectedTab = { selectedTab } selectedSort = { selectedSort } />
69+ < CardContainer capsules = { allCapsules } isLoading = { isPending } />
70+
71+ < div ref = { footerRef } className = { styles . footer } >
72+ { isFetchingNextPage && < LoadingSpinner loading = { true } size = { 20 } /> }
73+ </ div >
4274 </ >
4375 ) ;
4476} ;
0 commit comments