import { useCallback, useMemo } from "react"; import { Icon } from "@iconify/react"; import { Link, useLocation, useSearchParams } from "react-router"; interface Props { lastPage: number; } export default function Pagination({ lastPage }: Props) { const location = useLocation(); const [searchParams] = useSearchParams(); const page = Number(searchParams.get("page") ?? 1); const createPageUrl = useCallback( (pageNumber: number) => { const params = new URLSearchParams(searchParams); params.set("page", pageNumber.toString()); return `${location.pathname}?${params.toString()}`; }, [searchParams, location.pathname], ); const numbers = useMemo(() => { const result = []; // Always show 5 pages, centering around the current page when possible const start = Math.max(1, Math.min(page - 2, lastPage - 4)); const end = Math.min(lastPage, start + 4); for (let i = start; i <= end; i++) result.push(i); return result; }, [page, lastPage]); return (
{/* Go to first page */} {/* Previous page */} {/* Page numbers */}
{numbers.map((number) => ( {number} ))}
{/* Next page */} = lastPage ? "#" : createPageUrl(page + 1)} aria-label="Go to Next Page" aria-disabled={page >= lastPage} tabIndex={page >= lastPage ? -1 : undefined} className={`pill button bg-orange-100! p-0.5! aspect-square text-2xl ${page >= lastPage ? "pointer-events-none opacity-50" : "hover:bg-orange-400!"}`} > {/* Go to last page */} = lastPage ? "#" : createPageUrl(lastPage)} aria-label="Go to Last Page" aria-disabled={page >= lastPage} tabIndex={page >= lastPage ? -1 : undefined} className={`pill button bg-orange-100! p-0.5! aspect-square text-2xl ${page >= lastPage ? "pointer-events-none opacity-50" : "hover:bg-orange-400!"}`} >
); }