48 lines
1.9 KiB
TypeScript
48 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
interface PaginationProps {
|
|
page: number;
|
|
totalPages: number;
|
|
onPageChange: (page: number) => void;
|
|
}
|
|
|
|
export default function Pagination({ page, totalPages, onPageChange }: PaginationProps) {
|
|
if (totalPages <= 1) return null;
|
|
|
|
const pages: number[] = [];
|
|
const maxShow = 7;
|
|
let start = Math.max(1, page - Math.floor(maxShow / 2));
|
|
const end = Math.min(totalPages, start + maxShow - 1);
|
|
start = Math.max(1, end - maxShow + 1);
|
|
for (let i = start; i <= end; i++) pages.push(i);
|
|
|
|
const btn = "px-2.5 py-1.5 text-[12px] rounded-md border border-line hover:bg-surface transition-colors";
|
|
|
|
return (
|
|
<div className="flex items-center justify-center gap-1 mt-8 flex-wrap">
|
|
<button type="button" onClick={() => onPageChange(page - 1)} disabled={page <= 1}
|
|
className={`${btn} ${page <= 1 ? "opacity-25 cursor-not-allowed" : ""}`}>上一页</button>
|
|
{start > 1 && (
|
|
<>
|
|
<button type="button" onClick={() => onPageChange(1)} className={btn}>1</button>
|
|
{start > 2 && <span className="px-1 text-[12px] text-muted">...</span>}
|
|
</>
|
|
)}
|
|
{pages.map((p) => (
|
|
<button type="button" key={p} onClick={() => onPageChange(p)}
|
|
className={`px-2.5 py-1.5 text-[12px] rounded-md border ${
|
|
p === page ? "bg-accent text-white border-accent font-medium" : `border-line hover:bg-surface`
|
|
}`}>{p}</button>
|
|
))}
|
|
{end < totalPages && (
|
|
<>
|
|
{end < totalPages - 1 && <span className="px-1 text-[12px] text-muted">...</span>}
|
|
<button type="button" onClick={() => onPageChange(totalPages)} className={btn}>{totalPages}</button>
|
|
</>
|
|
)}
|
|
<button type="button" onClick={() => onPageChange(page + 1)} disabled={page >= totalPages}
|
|
className={`${btn} ${page >= totalPages ? "opacity-25 cursor-not-allowed" : ""}`}>下一页</button>
|
|
</div>
|
|
);
|
|
}
|