import { hasNextPage, hasPreviousPage, LengthAwarePaginationResponse, PaginationResponse, SimplePaginationResponse, } from '@common/http/backend-response/pagination-response'; import {Button} from '@common/ui/buttons/button'; import memoize from 'nano-memoize'; import {Link} from 'react-router-dom'; import clsx from 'clsx'; import {Trans} from '@common/i18n/trans'; import {KeyboardArrowRightIcon} from '@common/icons/material/KeyboardArrowRight'; import {KeyboardArrowLeftIcon} from '@common/icons/material/KeyboardArrowLeft'; import {scrollToTop} from '@common/ui/navigation/use-scroll-to-top'; import {useRef} from 'react'; import {FirstPageIcon} from '@common/icons/material/FirstPage'; export type PaginationControlsType = 'simple' | 'lengthAware'; interface Props { pagination: PaginationResponse | undefined; className?: string; type?: PaginationControlsType; scrollToTop?: boolean; } export function PaginationControls({ pagination, className, type, scrollToTop, }: Props) { if ( !pagination?.data?.length || (!hasNextPage(pagination) && !hasPreviousPage(pagination)) ) { return null; } const isLengthAware = (!type || type === 'lengthAware') && 'total' in pagination && pagination.total != null; if (isLengthAware) { return ( ); } return ( ); } interface LengthAwarePaginationProps { data: LengthAwarePaginationResponse; className?: string; scrollToTop?: boolean; } function LengthAwarePagination({ data, className, scrollToTop: shouldScrollToTop, }: LengthAwarePaginationProps) { const ref = useRef(null); const currentPage = data.current_page; const total = data.total; const perPage = data.per_page; const range = generatePaginationRangeWithDots(currentPage, total, perPage); return ( ); } interface SimplePaginationProps { data: SimplePaginationResponse; className?: string; scrollToTop?: boolean; } function SimplePagination({ data, className, scrollToTop: shouldScrollToTop, }: SimplePaginationProps) { const ref = useRef(null); const currentPage = data.current_page; const isLastPage = !hasNextPage(data); return (
{currentPage > 1 && ( )}
); } const generatePaginationRangeWithDots = memoize( (currentPage: number, total: number, perPage: number) => { const totalPages = Math.ceil(total / perPage); const delta = 3; const range = []; for ( let i = Math.max(2, currentPage - delta); i <= Math.min(totalPages - 1, currentPage + delta); i++ ) { range.push(i); } if (currentPage - delta > 2) { range.unshift('...'); } if (currentPage + delta < totalPages - 1) { range.push('...'); } range.unshift(1); range.push(totalPages); return range; }, );