You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

106 lines
3.6 KiB

import { toFa } from '@/lib/utils'
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationPrevious,
PaginationNext,
PaginationEllipsis,
} from '@/components/ui/pagination'
/* ──────────────────────────────────────────────────────────────────────────
* صفحه‌بندی مشترک جدول‌های مدیریت (تگ‌ها/ژانرها/…).
*
* server-side: total = count کل از بک‌اند، page صفحهٔ فعلی. تعداد صفحات از
* count/pageSize محاسبه می‌شود. اگر فقط یک صفحه باشد چیزی رندر نمی‌شود.
* ────────────────────────────────────────────────────────────────────────── */
type TablePaginationProps = {
page?: number
currentPage?: number
pageSize?: number
total?: number
totalPages?: number
onPageChange: (page: number) => void
}
/** بازهٔ صفحاتِ قابل‌نمایش حول صفحهٔ فعلی (حداکثر ۵ عدد). */
function pageWindow(page: number, totalPages: number): number[] {
const span = 2
let start = Math.max(1, page - span)
let end = Math.min(totalPages, page + span)
// پنجره را تا ۵ عدد پر می‌کنیم وقتی نزدیک ابتدا/انتها هستیم.
if (end - start < 4) {
if (start === 1) end = Math.min(totalPages, start + 4)
else if (end === totalPages) start = Math.max(1, end - 4)
}
const pages: number[] = []
for (let p = start; p <= end; p++) pages.push(p)
return pages
}
export default function TablePagination({
page,
currentPage,
pageSize = 20,
total,
totalPages: propTotalPages,
onPageChange,
}: TablePaginationProps) {
const activePage = currentPage ?? page ?? 1
const totalPages = propTotalPages ?? (total !== undefined ? Math.max(1, Math.ceil(total / pageSize)) : 1)
if (totalPages <= 1) return null
const pages = pageWindow(activePage, totalPages)
const first = pages[0]
const last = pages[pages.length - 1]
return (
<Pagination className="mx-0 w-auto">
<PaginationContent>
<PaginationItem>
<PaginationPrevious disabled={activePage <= 1} onClick={() => onPageChange(activePage - 1)} />
</PaginationItem>
{first > 1 && (
<>
<PaginationItem>
<PaginationLink onClick={() => onPageChange(1)}>{toFa(1)}</PaginationLink>
</PaginationItem>
{first > 2 && (
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
)}
</>
)}
{pages.map((p) => (
<PaginationItem key={p}>
<PaginationLink isActive={p === activePage} onClick={() => onPageChange(p)}>
{toFa(p)}
</PaginationLink>
</PaginationItem>
))}
{last < totalPages && (
<>
{last < totalPages - 1 && (
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
)}
<PaginationItem>
<PaginationLink onClick={() => onPageChange(totalPages)}>{toFa(totalPages)}</PaginationLink>
</PaginationItem>
</>
)}
<PaginationItem>
<PaginationNext disabled={activePage >= totalPages} onClick={() => onPageChange(activePage + 1)} />
</PaginationItem>
</PaginationContent>
</Pagination>
)
}