"use client"; import { useState, useMemo } from "react"; import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { PaginationProps, PaginationConfig } from "@/lib/types"; const DEFAULT_CONFIG: PaginationConfig = { itemsPerPage: 20, maxVisiblePages: 5, showFirstLast: true, showPrevNext: true, }; export function Pagination({ currentPage, totalPages, totalItems, itemsPerPage, onPageChange, onItemsPerPageChange, config = {}, className = "", }: PaginationProps) { const [localItemsPerPage, setLocalItemsPerPage] = useState(itemsPerPage); const finalConfig = useMemo( () => ({ ...DEFAULT_CONFIG, ...config }), [config] ); // Calcular índices dos itens const startIndex = (currentPage - 1) * itemsPerPage + 1; const endIndex = Math.min(currentPage * itemsPerPage, totalItems); // Gerar array de páginas visíveis const visiblePages = useMemo(() => { const pages: (number | string)[] = []; const { maxVisiblePages } = finalConfig; if (totalPages <= maxVisiblePages) { // Se total de páginas é menor que o máximo, mostrar todas for (let i = 1; i <= totalPages; i++) { pages.push(i); } } else { // Lógica para mostrar páginas com ellipsis const halfVisible = Math.floor(maxVisiblePages / 2); let startPage = Math.max(1, currentPage - halfVisible); const endPage = Math.min(totalPages, startPage + maxVisiblePages - 1); // Ajustar se estivermos no final if (endPage - startPage + 1 < maxVisiblePages) { startPage = Math.max(1, endPage - maxVisiblePages + 1); } // Primeira página if (startPage > 1) { pages.push(1); if (startPage > 2) { pages.push("..."); } } // Páginas do meio for (let i = startPage; i <= endPage; i++) { pages.push(i); } // Última página if (endPage < totalPages) { if (endPage < totalPages - 1) { pages.push("..."); } pages.push(totalPages); } } return pages; }, [currentPage, totalPages, finalConfig]); const handleItemsPerPageChange = (newItemsPerPage: string) => { const newValue = parseInt(newItemsPerPage); setLocalItemsPerPage(newValue); if (onItemsPerPageChange) { onItemsPerPageChange(newValue); } }; const canGoPrevious = currentPage > 1; const canGoNext = currentPage < totalPages; if (totalPages <= 1) { return null; } return (
{/* Informações dos itens */}
Mostrando {startIndex} a {endIndex} de {totalItems} resultado {totalItems !== 1 ? "s" : ""}
{/* Controles de paginação */}
{/* Seletor de itens por página */} {onItemsPerPageChange && (
Por página:
)} {/* Botões de navegação */}
{/* Primeira página */} {finalConfig.showFirstLast && ( )} {/* Página anterior */} {finalConfig.showPrevNext && ( )} {/* Números das páginas */} {visiblePages.map((page, index) => (
{page === "..." ? ( ... ) : ( )}
))} {/* Próxima página */} {finalConfig.showPrevNext && ( )} {/* Última página */} {finalConfig.showFirstLast && ( )}
); }