diff --git a/package.json b/package.json index 3bba84c..b269ddf 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "react-dom": "^18.3.1", "react-horizontal-scrolling-menu": "^7.1.4", "react-icons": "^5.2.1", + "react-intersection-observer": "^9.13.1", "react-konva": "^18.2.10", "react-konva-utils": "^1.0.6", "react-lottie-player": "^2.1.0", diff --git a/src/app/(pages)/4q-gallery/_components/item-container.module.css b/src/app/(pages)/4q-gallery/_components/item-container.module.css index ad78530..1cccaa3 100644 --- a/src/app/(pages)/4q-gallery/_components/item-container.module.css +++ b/src/app/(pages)/4q-gallery/_components/item-container.module.css @@ -17,8 +17,13 @@ } .loadingContainer { - margin-top: 50px; + margin-top: 10px; + padding: 50px; width: 100%; display: flex; justify-content: center; } + +.emptyContainer { + width: 100%; +} \ No newline at end of file diff --git a/src/app/(pages)/4q-gallery/_components/item-container.tsx b/src/app/(pages)/4q-gallery/_components/item-container.tsx index 76e33ea..824f17b 100644 --- a/src/app/(pages)/4q-gallery/_components/item-container.tsx +++ b/src/app/(pages)/4q-gallery/_components/item-container.tsx @@ -2,30 +2,41 @@ import { useInfiniteQuery } from "@tanstack/react-query"; import styles from "./item-container.module.css"; import ItemCard from "./item-card"; import { getGalleryData } from "@/service/photo_api"; -import { Button } from "antd"; import { BounceDot } from "basic-loading"; import { Item } from "@/types/item"; +import { GalleryPage, ContainerProps } from "@/types/gallery"; +import { useInView } from "react-intersection-observer"; +import { message } from "antd"; -type GalleryPage = { - content: Item[]; - page: number; - number: number; - last: boolean; - totalPages: number; - totalElements: number; -}; +export default function Container({ category, tag, sort }: ContainerProps) { + const [messageApi, contextHolder] = message.useMessage(); -type ContainerProps = { - category: string; - tag: string; - sort: string; -}; + const warning = () => { + messageApi.open({ + type: "warning", + content: "더 이상 불러올 데이터가 없습니다.", + duration: 1.2, + style: { + marginTop: "40px", + }, + }); + }; + + const { ref, inView } = useInView({ + threshold: 0.2, + triggerOnce: false, + onChange: (inView) => { + if (inView && !hasNextPage) { + warning(); + } + }, + }); -export default function Container({ category, tag, sort }: ContainerProps) { const loadingOption = { - size: 12, + size: 10, color: "#FE5B10", }; + const { data, isLoading, @@ -48,6 +59,10 @@ export default function Container({ category, tag, sort }: ContainerProps) { gcTime: 300 * 1000, }); + if (inView && hasNextPage && !isFetchingNextPage) { + fetchNextPage(); + } + if (isLoading) { return (