94 lines
2.5 KiB
TypeScript
94 lines
2.5 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,
|
|
searchQuery?: string,
|
|
) {
|
|
const params = new URLSearchParams();
|
|
if (channelId) params.set("channel", channelId);
|
|
if (searchQuery) params.set("q", searchQuery);
|
|
if (page > 1) params.set("page", String(page));
|
|
const query = params.toString();
|
|
return query ? `${path}?${query}` : path;
|
|
}
|
|
|
|
export function LeaderboardPagination({
|
|
path,
|
|
page,
|
|
totalPages,
|
|
channelId,
|
|
searchQuery,
|
|
}: {
|
|
path: string;
|
|
page: number;
|
|
totalPages: number;
|
|
channelId?: string;
|
|
searchQuery?: 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, searchQuery)}
|
|
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, searchQuery)}
|
|
isActive={value === page}
|
|
aria-label={`ไปหน้า ${value}`}
|
|
>
|
|
{value}
|
|
</PaginationLink>
|
|
</PaginationItem>
|
|
</Fragment>
|
|
))}
|
|
|
|
{page < totalPages && (
|
|
<PaginationItem>
|
|
<PaginationNext
|
|
href={pageHref(path, page + 1, channelId, searchQuery)}
|
|
text="ถัดไป"
|
|
aria-label="ไปหน้าถัดไป"
|
|
/>
|
|
</PaginationItem>
|
|
)}
|
|
</PaginationContent>
|
|
</Pagination>
|
|
);
|
|
}
|