| 'use client'; |
|
|
| import { useEffect, useMemo, useState } from 'react'; |
|
|
| export interface UsePaginationOptions { |
| perPage: number; |
| |
| resetOn?: unknown[]; |
| } |
|
|
| export interface UsePaginationResult<T> { |
| page: number; |
| setPage: (page: number) => void; |
| totalPages: number; |
| total: number; |
| pageItems: T[]; |
| rangeStart: number; |
| rangeEnd: number; |
| } |
|
|
| export function usePagination<T>( |
| items: T[], |
| { perPage, resetOn = [] }: UsePaginationOptions |
| ): UsePaginationResult<T> { |
| const [page, setPage] = useState(1); |
|
|
| const total = items.length; |
| const totalPages = Math.max(1, Math.ceil(total / perPage)); |
|
|
| |
| useEffect(() => { |
| if (page > totalPages) setPage(totalPages); |
| }, [page, totalPages]); |
|
|
| |
| |
| useEffect(() => { setPage(1); }, resetOn); |
|
|
| const pageItems = useMemo(() => { |
| const start = (page - 1) * perPage; |
| return items.slice(start, start + perPage); |
| }, [items, page, perPage]); |
|
|
| const rangeStart = total === 0 ? 0 : (page - 1) * perPage + 1; |
| const rangeEnd = Math.min(total, page * perPage); |
|
|
| return { page, setPage, totalPages, total, pageItems, rangeStart, rangeEnd }; |
| } |
|
|