/** @jsxRuntime classic */ /** @jsx jsx */ import { useEffect } from 'react' import { jsx, Stack, useTheme } from '@keystone-ui/core' import { Select } from '@keystone-ui/fields' import { ChevronRightIcon, ChevronLeftIcon } from '@keystone-ui/icons' import { Link, useRouter } from '../router' type PaginationProps = { pageSize: number total: number currentPage: number singular: string plural: string } export function usePaginationParams ({ defaultPageSize }: { defaultPageSize: number }) { const { query } = useRouter() const currentPage = Math.max( typeof query.page === 'string' && !Number.isNaN(parseInt(query.page)) ? Number(query.page) : 1, 1 ) const pageSize = typeof query.pageSize === 'string' && !Number.isNaN(parseInt(query.pageSize)) ? parseInt(query.pageSize) : defaultPageSize return { currentPage, pageSize } } function getPaginationStats ({ singular, plural, pageSize, currentPage, total }: PaginationProps) { let stats = '' if (total > pageSize) { const start = pageSize * (currentPage - 1) + 1 const end = Math.min(start + pageSize - 1, total) stats = `${start} - ${end} of ${total} ${plural}` } else { if (total > 1 && plural) { stats = `${total} ${plural}` } else if (total === 1 && singular) { stats = `${total} ${singular}` } } return { stats } } export function Pagination ({ currentPage, total, pageSize, singular, plural }: PaginationProps) { const { query, pathname, push } = useRouter() const { stats } = getPaginationStats({ singular, plural, currentPage, total, pageSize }) const { opacity } = useTheme() const nextPage = currentPage + 1 const prevPage = currentPage - 1 const minPage = 1 const nxtQuery = { ...query, page: nextPage } const prevQuery = { ...query, page: prevPage } const limit = Math.ceil(total / pageSize) const pages = [] useEffect(() => { // Check if the current page is larger than // the maximal page given the total and associated page size value. // (This could happen due to a deletion event, in which case we want to reroute the user to a previous page). if (currentPage > Math.ceil(total / pageSize)) { push({ pathname, query: { ...query, page: Math.ceil(total / pageSize), }, }) } }, [total, pageSize, currentPage, pathname, query, push]) // Don't render the pagination component if the pageSize is greater than the total number of items in the list. if (total <= pageSize) return null const onChange = (selectedOption: { value: string, label: string }) => { push({ pathname, query: { ...query, page: selectedOption.value, }, }) } for (let page = minPage; page <= limit; page++) { pages.push({ label: String(page), value: String(page), }) } return ( {`${plural} per page: ${pageSize}`} {stats}