import { ArrowPathIcon } from "@heroicons/react/24/solid"; import clsx from "clsx"; import * as React from "react"; import { useEffect, useState } from "react"; import { Pagination as ShadCnPagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from "../ui/pagination"; import { ChevronDoubleLeftIcon, ChevronDoubleRightIcon } from "@heroicons/react/16/solid"; type PaginationItemWrapperProps = { isLoadingPage: boolean; children: React.ReactNode; }; function PaginationItemWrapper({ isLoadingPage, children }: PaginationItemWrapperProps) { return ( {children} ); } type Props = { mobilePagination: boolean; page: number; totalPages: number; loadingPage: number | undefined; onPageChange: (page: number) => void; generatePageUrl?: (page: number) => string; }; export default function Pagination({ mobilePagination, page, totalPages, loadingPage, onPageChange, generatePageUrl, }: Props) { totalPages = Math.round(totalPages); const isLoading = loadingPage !== undefined; const [currentPage, setCurrentPage] = useState(page); useEffect(() => { setCurrentPage(page); }, [page]); const handlePageChange = (newPage: number) => { if (newPage < 1 || newPage > totalPages || newPage === currentPage || isLoading) { return; } setCurrentPage(newPage); onPageChange(newPage); }; const handleLinkClick = (newPage: number, event: React.MouseEvent) => { event.preventDefault(); if (newPage < 1 || newPage > totalPages || newPage === currentPage || isLoading) { return; } handlePageChange(newPage); }; const renderPageNumbers = () => { const pageNumbers = []; const maxPagesToShow = mobilePagination ? 3 : 4; let startPage = Math.max(1, currentPage - Math.floor(maxPagesToShow / 2)); const endPage = Math.min(totalPages, startPage + maxPagesToShow - 1); if (endPage - startPage < maxPagesToShow - 1) { startPage = Math.max(1, endPage - maxPagesToShow + 1); } if (startPage > 1) { pageNumbers.push( {!mobilePagination && ( handleLinkClick(1, e)}> 1 )} ); if (startPage > 2 && !mobilePagination) { pageNumbers.push( ); } } for (let i = startPage; i <= endPage; i++) { pageNumbers.push( handleLinkClick(i, e)} > {loadingPage === i ? : i} ); } return pageNumbers; }; return ( {mobilePagination && ( handleLinkClick(1, e)}> )} 1 && generatePageUrl ? generatePageUrl(currentPage - 1) : ""} onClick={e => handleLinkClick(currentPage - 1, e)} aria-disabled={currentPage === 1} className={clsx(currentPage === 1 && "cursor-not-allowed")} /> {renderPageNumbers()} {!mobilePagination && currentPage < totalPages && totalPages - currentPage > 2 && ( <> handleLinkClick(totalPages, e)} > {totalPages} )} handleLinkClick(currentPage + 1, e)} aria-disabled={currentPage === totalPages} className={clsx(currentPage === totalPages && "cursor-not-allowed")} /> {mobilePagination && ( handleLinkClick(totalPages, e)} > )} ); }