Skip to content
Snippets Groups Projects
infinity-scroll.tsx 3.17 KiB
"use client"

import Game from "@/components/game-item";
import { Card } from "@/components/ui/card";
import { IGame } from "@/types/igdb-types";
import { useInfiniteQuery } from "@tanstack/react-query";
import { useSearchParams } from "next/navigation";
import { Fragment } from "react";
import InfiniteScroll from "react-infinite-scroll-component";

export function InfiniteScrollGames() {
    const searchParams = useSearchParams()

    const searchQuery = searchParams.get('search');
    const categoryQuery = searchParams.get('category');
    const genreQuery = searchParams.get('genre');
    const platformQuery = searchParams.get('platform');
    const sortbyQuery = searchParams.get('sortby');
    const orderQuery = searchParams.get('order');

    const searchURL = searchQuery ? `&search=${searchQuery}` : "";
    const categoryURL = categoryQuery ? `&category=${categoryQuery}` : "";
    const genreURL = genreQuery ? `&genre=${genreQuery}` : "";
    const platformURL = platformQuery ? `&platform=${platformQuery}` : "";
    const sortbyURL = sortbyQuery ? `&sortby=${sortbyQuery}` : "";
    const orderURL = orderQuery ? `&order=${orderQuery}` : "";

    const params = searchURL + categoryURL + genreURL + platformURL + sortbyURL + orderURL;

    const {
        status,
        data,
        error,
        fetchNextPage,
        hasNextPage,
    } = useInfiniteQuery(
        ['infiniteGames', params],
        async ({ pageParam = 1 }) =>
            await fetch(`/api/games/?page=${pageParam}${params}`,
            ).then((result) => result.json() as Promise<IGame[]>),
        {
            getNextPageParam: (lastPage, pages) => {
                return lastPage.length > 0 ? pages.length + 1 : undefined;
            },
        },
    )

    return (
        <Card className="p-6">
            {status === 'error'
                ?
                (<span>Error: {(error as Error).message}</span>)
                :
                (status === 'success' && (
                    <InfiniteScroll
                        dataLength={data?.pages.length * 20}
                        next={fetchNextPage}
                        hasMore={hasNextPage ? true : false}
                        loader={<h4>Loading more...</h4>}
                        endMessage={
                            <p style={{ textAlign: 'center' }}>
                                <b>Yay! You have seen it all</b>
                            </p>
                        }
                    >
                        <div className="">
                            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8">
                                {data.pages.map((page, i) => (
                                    <Fragment key={i}>
                                        {page.map((game: IGame) => (
                                            <Game id={game.id} name={game.name} cover={game.cover} key={game.id} />
                                        ))}
                                    </Fragment>
                                ))}
                            </div>
                        </div>
                    </InfiniteScroll>
                ))}
        </Card>
    )
}