Files
Docker/Downloads/Voltaserve/ui/src/lib/hooks/page-pagination.ts
2024-04-21 14:42:52 +02:00

78 lines
1.8 KiB
TypeScript

import { useCallback, useEffect, useMemo, useState } from 'react'
export type NavigateArgs = {
search: string
}
export type NavigateFunction = (args: NavigateArgs) => void
export type LocationObject = {
search: string
}
export type StorageOptions = {
enabled?: boolean
prefix?: string
namespace?: string
}
export type UsePagePaginationOptions = {
navigate: NavigateFunction
location: LocationObject
storage?: StorageOptions
steps?: number[]
}
export const usePagePagination = ({
navigate,
location,
storage = {
enabled: false,
prefix: 'app',
namespace: 'main',
},
steps = [5, 10, 20, 40, 80, 100],
}: UsePagePaginationOptions) => {
const queryParams = useMemo(
() => new URLSearchParams(location.search),
[location.search],
)
const page = Number(queryParams.get('page')) || 1
const storageSizeKey = useMemo(
() => `${storage.prefix}_${storage.namespace}_pagination_size`,
[storage],
)
const [size, setSize] = useState(
localStorage.getItem(storageSizeKey) && storage.enabled
? parseInt(localStorage.getItem(storageSizeKey) as string)
: steps[0],
)
const _setSize = useCallback(
(size: number) => {
setSize(size)
if (size && storage.enabled) {
localStorage.setItem(storageSizeKey, JSON.stringify(size))
}
},
[storageSizeKey, storage],
)
useEffect(() => {
if (!queryParams.has('page')) {
queryParams.set('page', '1')
navigate({ search: `?${queryParams.toString()}` })
}
}, [queryParams, navigate])
const setPage = useCallback(
(page: number) => {
queryParams.set('page', String(page))
navigate({ search: `?${queryParams.toString()}` })
},
[queryParams, navigate],
)
return { page, size, steps, setPage, setSize: _setSize }
}