import React, { useEffect, useMemo, useRef, useState } from 'react'; import { PaginationListItemButtonProps } from '@digigov/ui/navigation/Pagination/Pagination'; export interface usePaginationProps { total: number; resultsPerPageOptions: number[]; previousLabel?: string; nextLabel?: string; } export interface usePaginationReturn { registerPaginationLabel: () => { start: number; end: number; total: number; ref: React.RefObject | undefined; }; registerPaginationResultsPerPageSelect: () => { resultsPerPageOptions: number[]; currentResultsPerPage: number; handleOnChange: React.Dispatch>; ref: React.RefObject | undefined; }; setTotal: (total: number) => void; setCurrentPage: (page: number) => void; items: PaginationListItemButtonProps[]; currentPage: number; offset: number; limit: number; } export const usePagination = ({ total: totalLength, resultsPerPageOptions, previousLabel, nextLabel, }: usePaginationProps): usePaginationReturn => { const [total, setTotal] = useState(totalLength); useEffect(() => { setTotal(totalLength); }, [totalLength]); const [currentPage, setCurrentPage] = useState(1); const [currentResultsPerPage, setCurrentResultsPerPage] = useState( resultsPerPageOptions[0] ); const totalPages = Math.ceil(total / currentResultsPerPage) - 1; const currentPageResultsStart = (currentPage - 1) * currentResultsPerPage + 1; const currentPageResultsEnd = currentPage * currentResultsPerPage < total ? currentPage * currentResultsPerPage : total; const labelRef = useRef>(undefined); const selectLabelRef = useRef>(undefined); useEffect(() => { setCurrentPage(totalPages < currentPage ? totalPages : currentPage); }, [currentPage, totalPages]); const registerPaginationLabel = () => { return { start: currentPageResultsStart, end: currentPageResultsEnd, total: total, ref: labelRef.current, }; }; const registerPaginationResultsPerPageSelect = () => { return { resultsPerPageOptions: resultsPerPageOptions, currentResultsPerPage: currentResultsPerPage, handleOnChange: setCurrentResultsPerPage, ref: selectLabelRef.current, }; }; const items = useMemo(() => { const content: PaginationListItemButtonProps[] = []; let countingDots = false; content.push({ children: previousLabel, arrow: 'left', onClick: () => currentPage !== 1 && setCurrentPage(currentPage - 1), active: currentPage !== 1, }); for (let page = 1; page <= totalPages; page++) { if ( page <= 1 || page >= totalPages || (page <= currentPage + 1 && page >= currentPage - 1) ) { if (countingDots) { countingDots = false; } console.log(page, currentPage); content.push({ children: page, variant: 'number', onClick: () => setCurrentPage(page), isCurrentPage: currentPage === page, }); } else { if (!countingDots) { countingDots = true; content.push({ variant: 'dots', }); } } } content.push({ children: nextLabel, arrow: 'right', onClick: () => currentPage !== totalPages && setCurrentPage(currentPage + 1), active: currentPage !== totalPages, }); return content; }, [currentPage, totalPages]); return { registerPaginationLabel, registerPaginationResultsPerPageSelect, items, currentPage, setCurrentPage, offset: (currentPage - 1) * currentResultsPerPage, limit: currentResultsPerPage + 1, setTotal, }; }; export default usePagination;