Files
erika/components/leaderboard/leaderboard-pagination.tsx
T

86 lines
2.3 KiB
TypeScript

import { Fragment } from "react";
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
function visiblePages(page: number, totalPages: number) {
const pages = new Set([1, totalPages, page - 1, page, page + 1]);
return [...pages]
.filter((value) => value >= 1 && value <= totalPages)
.sort((a, b) => a - b);
}
function pageHref(path: string, page: number, channelId?: string) {
const params = new URLSearchParams();
if (channelId) params.set("channel", channelId);
if (page > 1) params.set("page", String(page));
const query = params.toString();
return query ? `${path}?${query}` : path;
}
export function LeaderboardPagination({
path,
page,
totalPages,
channelId,
}: {
path: string;
page: number;
totalPages: number;
channelId?: string;
}) {
if (totalPages <= 1) return null;
const pages = visiblePages(page, totalPages);
return (
<Pagination aria-label="หน้าอันดับ">
<PaginationContent>
{page > 1 && (
<PaginationItem>
<PaginationPrevious
href={pageHref(path, page - 1, channelId)}
text="ก่อนหน้า"
aria-label="ไปหน้าก่อนหน้า"
/>
</PaginationItem>
)}
{pages.map((value, index) => (
<Fragment key={value}>
{index > 0 && value - pages[index - 1] > 1 && (
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
)}
<PaginationItem>
<PaginationLink
href={pageHref(path, value, channelId)}
isActive={value === page}
aria-label={`ไปหน้า ${value}`}
>
{value}
</PaginationLink>
</PaginationItem>
</Fragment>
))}
{page < totalPages && (
<PaginationItem>
<PaginationNext
href={pageHref(path, page + 1, channelId)}
text="ถัดไป"
aria-label="ไปหน้าถัดไป"
/>
</PaginationItem>
)}
</PaginationContent>
</Pagination>
);
}