/** @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}
)
}
export function PaginationLabel ({
currentPage,
pageSize,
plural,
singular,
total,
}: PaginationProps) {
const { stats } = getPaginationStats({
plural,
singular,
currentPage,
total,
pageSize,
})
if (!total) {
return No {plural}
}
return (
Showing {stats}
)
}