122 lines
3.5 KiB
TypeScript
122 lines
3.5 KiB
TypeScript
import { ChangeEvent } from 'react';
|
||
|
||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||
|
||
import {
|
||
Pagination,
|
||
PaginationContent,
|
||
PaginationItem,
|
||
PaginationLink,
|
||
PaginationNext,
|
||
PaginationPrevious,
|
||
} from '../../pagination';
|
||
|
||
interface TablePaginationProps {
|
||
currentPage: number;
|
||
itemsPerPage: number;
|
||
totalPages: number;
|
||
totalOperations?: number;
|
||
transactionsQuantity: number;
|
||
itemsPerPageOptions: number[];
|
||
onPageChange: (page: number) => void;
|
||
onItemsPerPageChange: (e: ChangeEvent<HTMLSelectElement>) => void;
|
||
}
|
||
|
||
export const TransactionsTablePagination = ({
|
||
currentPage,
|
||
itemsPerPage,
|
||
totalPages,
|
||
totalOperations = 0,
|
||
itemsPerPageOptions,
|
||
transactionsQuantity,
|
||
onPageChange,
|
||
onItemsPerPageChange,
|
||
}: TablePaginationProps) => {
|
||
const { t } = useTextController();
|
||
|
||
const getPageNumbers = () => {
|
||
const pages = [];
|
||
const maxVisiblePages = 5; // Maximum number of visible pages
|
||
const halfVisible = Math.floor(maxVisiblePages / 2);
|
||
|
||
let startPage = Math.max(1, currentPage - halfVisible);
|
||
let endPage = Math.min(totalPages, currentPage + halfVisible);
|
||
|
||
if (currentPage <= halfVisible) {
|
||
endPage = Math.min(totalPages, maxVisiblePages);
|
||
} else if (currentPage + halfVisible >= totalPages) {
|
||
startPage = Math.max(1, totalPages - maxVisiblePages + 1);
|
||
}
|
||
|
||
for (let i = startPage; i <= endPage; i++) {
|
||
pages.push(i);
|
||
}
|
||
|
||
return pages;
|
||
};
|
||
|
||
return (
|
||
<>
|
||
{transactionsQuantity > 0 && (
|
||
<div className='flex flex-col items-center justify-between gap-4 sm:flex-row'>
|
||
<div className='text-sm text-gray-500'>
|
||
Показано {transactionsQuantity} из {totalOperations} операций
|
||
</div>
|
||
|
||
<Pagination>
|
||
<PaginationContent>
|
||
<PaginationItem>
|
||
<PaginationPrevious
|
||
onClick={() => onPageChange(currentPage - 1)}
|
||
className={
|
||
currentPage === 1 ? 'pointer-events-none opacity-50' : ''
|
||
}
|
||
/>
|
||
</PaginationItem>
|
||
|
||
{getPageNumbers().map((page, index) => (
|
||
<PaginationItem key={index}>
|
||
<PaginationLink
|
||
isActive={currentPage === page}
|
||
onClick={() => onPageChange(page as number)}
|
||
>
|
||
{page}
|
||
</PaginationLink>
|
||
</PaginationItem>
|
||
))}
|
||
|
||
<PaginationItem>
|
||
<PaginationNext
|
||
onClick={() => onPageChange(currentPage + 1)}
|
||
className={
|
||
currentPage === totalPages
|
||
? 'pointer-events-none opacity-50'
|
||
: ''
|
||
}
|
||
/>
|
||
</PaginationItem>
|
||
</PaginationContent>
|
||
</Pagination>
|
||
|
||
<div className='flex items-center gap-2'>
|
||
<span className='text-sm text-gray-500'>
|
||
{t('transactions.entries')}
|
||
</span>
|
||
<select
|
||
className='rounded border p-1 text-sm'
|
||
value={itemsPerPage}
|
||
onChange={onItemsPerPageChange}
|
||
>
|
||
{itemsPerPageOptions.map((option) => (
|
||
<option key={option} value={option}>
|
||
{option}
|
||
</option>
|
||
))}
|
||
</select>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</>
|
||
);
|
||
};
|