import { Table } from "@tanstack/react-table"; import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from "lucide-react"; import { Pagination, PaginationContent, PaginationItem, PaginationLink, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@repo/shadcn-ui/components'; import { cn } from '@repo/shadcn-ui/lib/utils'; import { useTranslation } from '../../locales/i18n.ts'; import { DataTableMeta } from './data-table.tsx'; interface DataTablePaginationProps { table: Table; onPageChange?: (pageIndex: number) => void; onPageSizeChange?: (pageSize: number) => void; className?: string; } export function DataTablePagination({ table, onPageChange, onPageSizeChange, className }: DataTablePaginationProps) { const { t } = useTranslation(); const { pageIndex: rawIndex, pageSize: rawSize } = table.getState().pagination; const meta = table.options.meta as DataTableMeta; const totalRows = meta?.totalItems ?? table.getFilteredRowModel().rows.length; // Normalización segura const pageIndex = Number.isFinite(rawIndex) && rawIndex >= 0 ? rawIndex : 0; const pageSize = Number.isFinite(rawSize) && rawSize > 0 ? rawSize : 10; const pageCount = table.getPageCount() || Math.max(1, Math.ceil((totalRows || 0) / pageSize)); const hasSelected = table.getFilteredSelectedRowModel().rows.length > 0; // Rango visible (1-based en UI) const start = totalRows > 0 ? pageIndex * pageSize + 1 : 0; const end = totalRows > 0 ? Math.min(start + pageSize - 1, totalRows) : 0; // Handlers de navegación controlada const notify = (next: Partial<{ pageIndex: number; pageSize: number }>) => table.options.onPaginationChange?.({ pageIndex, pageSize, ...next }); const gotoPage = (index: number) => onPageChange ? onPageChange(index) : notify({ pageIndex: index }); const handlePageSizeChange = (size: string) => onPageSizeChange ? onPageSizeChange(Number(size)) : notify({ pageSize: Number(size) }); const gotoPreviousPage = () => gotoPage(pageIndex - 1); const gotoNextPage = () => gotoPage(pageIndex + 1); const gotoFirstPage = () => gotoPage(0); const gotoLastPage = () => gotoPage(pageCount - 1); return (
{/* Información izquierda */}
{t("components.datatable.pagination.showing_range", { start, end, total: totalRows })} {hasSelected && ( {t("components.datatable.pagination.rows_selected", { count: table.getFilteredSelectedRowModel().rows.length, total: table.getFilteredRowModel().rows.length, })} )}
{t("components.datatable.pagination.rows_per_page")} {pageIndex + 1} / {pageCount}
{/* Controles derecha */}
{ if (pageIndex > 0) gotoFirstPage(); }} isActive={pageIndex > 0} size="sm" className="px-2.5 cursor-pointer" > { if (pageIndex > 0) gotoPreviousPage(); }} isActive={pageIndex > 0} size="sm" className="px-2.5 cursor-pointer" > {t("components.datatable.pagination.page_of", { page: pageIndex + 1, of: pageCount })} { if (pageIndex < pageCount - 1) gotoNextPage(); }} isActive={pageIndex < pageCount - 1} size="sm" className="px-2.5 cursor-pointer" > { if (pageIndex < pageCount - 1) gotoLastPage(); }} isActive={pageIndex < pageCount - 1} size="sm" className="px-2.5 cursor-pointer" >
); }