117 lines
3.2 KiB
TypeScript
117 lines
3.2 KiB
TypeScript
"use client";
|
|
import React from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { PaginationBaseProps } from "./types";
|
|
|
|
/**
|
|
* Calculate the page numbers to display in pagination
|
|
* @param currentPage Current active page
|
|
* @param totalPages Total number of pages
|
|
* @param maxButtons Maximum number of page buttons to show (default: 5)
|
|
* @returns Array of page numbers to display
|
|
*/
|
|
const getPageNumbers = (currentPage: number, totalPages: number, maxButtons: number = 5): number[] => {
|
|
const pageNumbers: number[] = [];
|
|
|
|
// If we have fewer pages than the maximum buttons, show all pages
|
|
if (totalPages <= maxButtons) {
|
|
for (let i = 1; i <= totalPages; i++) {
|
|
pageNumbers.push(i);
|
|
}
|
|
}
|
|
// If we're near the beginning, show first maxButtons pages
|
|
else if (currentPage <= 3) {
|
|
for (let i = 1; i <= maxButtons; i++) {
|
|
pageNumbers.push(i);
|
|
}
|
|
}
|
|
// If we're near the end, show last maxButtons pages
|
|
else if (currentPage >= totalPages - 2) {
|
|
for (let i = totalPages - maxButtons + 1; i <= totalPages; i++) {
|
|
pageNumbers.push(i);
|
|
}
|
|
}
|
|
// Otherwise, show pages centered around current page
|
|
else {
|
|
for (let i = currentPage - 2; i <= currentPage + 2; i++) {
|
|
pageNumbers.push(i);
|
|
}
|
|
}
|
|
|
|
return pageNumbers;
|
|
};
|
|
|
|
export const PageNavigation: React.FC<PaginationBaseProps> = ({
|
|
pagination,
|
|
updatePagination,
|
|
loading = false,
|
|
lang,
|
|
translations,
|
|
}) => {
|
|
const t = translations[lang] || {};
|
|
|
|
const handlePageChange = (newPage: number) => {
|
|
if (newPage >= 1 && newPage <= pagination.totalPages) {
|
|
updatePagination({ page: newPage });
|
|
}
|
|
};
|
|
|
|
// Get the page numbers to display
|
|
const pageNumbers = getPageNumbers(pagination.page, pagination.totalPages);
|
|
|
|
return (
|
|
<div className="flex items-center space-x-2">
|
|
{pagination.back ? (
|
|
<Button
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={() => handlePageChange(pagination.page - 1)}
|
|
disabled={loading}
|
|
>
|
|
{t.previous || "Previous"}
|
|
</Button>
|
|
) : (
|
|
<Button variant="ghost" size="sm" disabled>
|
|
{t.previous || "Previous"}
|
|
</Button>
|
|
)}
|
|
|
|
{/* Page number buttons */}
|
|
<div className="flex items-center space-x-1">
|
|
{pageNumbers.map((pageNum) => (
|
|
<Button
|
|
key={pageNum}
|
|
variant={pagination.page === pageNum ? "default" : "outline"}
|
|
size="sm"
|
|
className="w-9 h-9 p-0"
|
|
onClick={() => handlePageChange(pageNum)}
|
|
disabled={loading}
|
|
>
|
|
{pageNum}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
|
|
{pagination.page < pagination.totalPages ? (
|
|
<Button
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={() => handlePageChange(pagination.page + 1)}
|
|
disabled={loading}
|
|
>
|
|
{t.next || "Next"}
|
|
</Button>
|
|
) : (
|
|
<Button variant="ghost" size="sm" disabled>
|
|
{t.next || "Next"}
|
|
</Button>
|
|
)}
|
|
|
|
{/* Page text display */}
|
|
<span className="px-4 py-1 text-sm text-muted-foreground">
|
|
{t.page || "Page"} {pagination.page} {t.of || "of"} {pagination.totalPages}
|
|
</span>
|
|
</div>
|
|
);
|
|
};
|