61 lines
1.4 KiB
TypeScript
61 lines
1.4 KiB
TypeScript
import { useState, useMemo } from 'react'
|
|
|
|
interface UsePaginationOptions<T> {
|
|
items: T[]
|
|
itemsPerPage: number
|
|
}
|
|
|
|
interface UsePaginationResult<T> {
|
|
currentPage: number
|
|
totalPages: number
|
|
paginatedItems: T[]
|
|
goToPage: (page: number) => void
|
|
nextPage: () => void
|
|
previousPage: () => void
|
|
hasNextPage: boolean
|
|
hasPreviousPage: boolean
|
|
}
|
|
|
|
export function usePagination<T>({ items, itemsPerPage }: UsePaginationOptions<T>): UsePaginationResult<T> {
|
|
const [currentPage, setCurrentPage] = useState(1)
|
|
|
|
const totalPages = Math.max(1, Math.ceil(items.length / itemsPerPage))
|
|
|
|
const paginatedItems = useMemo(() => {
|
|
const startIndex = (currentPage - 1) * itemsPerPage
|
|
const endIndex = startIndex + itemsPerPage
|
|
return items.slice(startIndex, endIndex)
|
|
}, [items, currentPage, itemsPerPage])
|
|
|
|
const goToPage = (page: number): void => {
|
|
const validPage = Math.max(1, Math.min(page, totalPages))
|
|
setCurrentPage(validPage)
|
|
}
|
|
|
|
const nextPage = (): void => {
|
|
if (currentPage < totalPages) {
|
|
setCurrentPage(currentPage + 1)
|
|
}
|
|
}
|
|
|
|
const previousPage = (): void => {
|
|
if (currentPage > 1) {
|
|
setCurrentPage(currentPage - 1)
|
|
}
|
|
}
|
|
|
|
const hasNextPage = currentPage < totalPages
|
|
const hasPreviousPage = currentPage > 1
|
|
|
|
return {
|
|
currentPage,
|
|
totalPages,
|
|
paginatedItems,
|
|
goToPage,
|
|
nextPage,
|
|
previousPage,
|
|
hasNextPage,
|
|
hasPreviousPage,
|
|
}
|
|
}
|