import { PER_PAGE } from 'lib/constants'; import usePagination from 'lib/hooks/usePagination'; import range from 'lodash/range'; import React from 'react'; import PageControl from 'components/common/Pagination/PageControl'; import useSearch from 'lib/hooks/useSearch'; import * as S from './Pagination.styled'; export interface PaginationProps { totalPages: number; } const NEIGHBOURS = 2; const Pagination: React.FC = ({ totalPages }) => { const { page, perPage, pathname } = usePagination(); const [searchText] = useSearch(); const currentPage = page || 1; const currentPerPage = perPage || PER_PAGE; const searchParam = searchText ? `&q=${searchText}` : ''; const getPath = (newPage: number) => `${pathname}?page=${Math.max( newPage, 1 )}&perPage=${currentPerPage}${searchParam}`; const pages = React.useMemo(() => { // Total visible numbers: neighbours, current, first & last const totalNumbers = NEIGHBOURS * 2 + 3; // totalNumbers + `...`*2 const totalBlocks = totalNumbers + 2; if (totalPages <= totalBlocks) { return range(1, totalPages + 1); } const startPage = Math.max( 2, Math.min(currentPage - NEIGHBOURS, totalPages) ); const endPage = Math.min( totalPages - 1, Math.min(currentPage + NEIGHBOURS, totalPages) ); let p = range(startPage, endPage + 1); const hasLeftSpill = startPage > 2; const hasRightSpill = totalPages - endPage > 1; const spillOffset = totalNumbers - (p.length + 1); switch (true) { case hasLeftSpill && !hasRightSpill: { p = [...range(startPage - spillOffset - 1, startPage - 1), ...p]; break; } case !hasLeftSpill && hasRightSpill: { p = [...p, ...range(endPage + 1, endPage + spillOffset + 1)]; break; } default: break; } return p; }, [currentPage, totalPages]); return ( {currentPage > 1 ? ( Previous ) : ( Previous )} {totalPages > 1 && ( )} {currentPage < totalPages ? ( Next ) : ( Next )} ); }; export default Pagination;