"use client"; import { useRouter, useSearchParams } from "next/navigation"; import { Button } from "./Button"; import { IconButton } from "./Button"; interface CursorPaginationProps { hasNextPage: boolean; hasPrevPage: boolean; pageSize: number; currentCount: number; pageSizeOptions?: number[]; nextCursor?: string | null; } export function CursorPagination({ hasNextPage, hasPrevPage, pageSize, currentCount, pageSizeOptions = [20, 50, 100], nextCursor, }: CursorPaginationProps) { const router = useRouter(); const searchParams = useSearchParams(); const goToNext = () => { if (!nextCursor) return; const params = new URLSearchParams(searchParams); params.set("cursor", nextCursor); router.push(`?${params.toString()}`); }; const goToFirst = () => { const params = new URLSearchParams(searchParams); params.delete("cursor"); router.push(`?${params.toString()}`); }; const changePageSize = (size: number) => { const params = new URLSearchParams(searchParams); params.set("limit", size.toString()); params.delete("cursor"); router.push(`?${params.toString()}`); }; return (
{/* Page size selector */}
Show per page
{/* Count info */}
Showing {currentCount} items
{/* Navigation */}
); } interface OffsetPaginationProps { currentPage: number; totalPages: number; pageSize: number; totalItems: number; pageSizeOptions?: number[]; } export function OffsetPagination({ currentPage, totalPages, pageSize, totalItems, pageSizeOptions = [20, 50, 100], }: OffsetPaginationProps) { const router = useRouter(); const searchParams = useSearchParams(); const goToPage = (page: number) => { const params = new URLSearchParams(searchParams); params.set("page", page.toString()); router.push(`?${params.toString()}`); }; const changePageSize = (size: number) => { const params = new URLSearchParams(searchParams); params.set("limit", size.toString()); params.set("page", "1"); router.push(`?${params.toString()}`); }; const startItem = (currentPage - 1) * pageSize + 1; const endItem = Math.min(currentPage * pageSize, totalItems); const getPageNumbers = () => { const pages: (number | string)[] = []; const maxVisiblePages = 5; if (totalPages <= maxVisiblePages) { for (let i = 1; i <= totalPages; i++) { pages.push(i); } } else { if (currentPage <= 3) { for (let i = 1; i <= 4; i++) { pages.push(i); } pages.push("..."); pages.push(totalPages); } else if (currentPage >= totalPages - 2) { pages.push(1); pages.push("..."); for (let i = totalPages - 3; i <= totalPages; i++) { pages.push(i); } } else { pages.push(1); pages.push("..."); for (let i = currentPage - 1; i <= currentPage + 1; i++) { pages.push(i); } pages.push("..."); pages.push(totalPages); } } return pages; }; return (
{/* Page size selector */}
Show per page
{/* Page info */}
{startItem}-{endItem} of {totalItems}
{/* Page navigation */}
goToPage(currentPage - 1)} disabled={currentPage <= 1} title="Previous page" > {getPageNumbers().map((page, index) => ( {page === "..." ? ( ... ) : ( )} ))} goToPage(currentPage + 1)} disabled={currentPage >= totalPages} title="Next page" >
); }