1
|
|
|
import { FC } from 'react'
|
2
|
|
|
import { useStore } from 'effector-react'
|
3
|
|
|
import { useQueryClient } from 'react-query'
|
4
|
|
|
import { prevPage, nextPage, setPage, $page, $isAscending } from './model'
|
5
|
|
|
import { usePagination, DOTS } from './usePagination'
|
6
|
|
|
import { useCustomEventDetail } from 'shared/hooks/useCustomEventDetail'
|
7
|
|
|
import { fetchMoviesList } from 'entities/MoviesCardsGrid/model'
|
8
|
|
|
import { Text } from 'shared/ui'
|
9
|
|
|
|
10
|
|
|
import { IPagination } from './types'
|
11
|
|
|
|
12
|
|
|
import clsx from 'clsx'
|
13
|
|
|
import styles from './Pagination.module.scss'
|
14
|
|
|
|
15
|
|
|
const Pagination: FC<IPagination> = ({ siblingCount = 1 }) => {
|
|
|
|
|
16
|
|
|
const isAscending = useStore($isAscending)
|
17
|
|
|
const currentPage = useStore($page)
|
18
|
|
|
|
19
|
|
|
const totalPages = useCustomEventDetail('gotTotalPages')
|
20
|
|
|
|
21
|
|
|
const queryClient = useQueryClient()
|
22
|
|
|
|
23
|
|
|
const prefetchPage = async (pageParam: number) => {
|
24
|
|
|
await queryClient.prefetchQuery(['moviesList', pageParam], () =>
|
25
|
|
|
fetchMoviesList(pageParam),
|
26
|
|
|
)
|
27
|
|
|
}
|
28
|
|
|
|
29
|
|
|
const paginationRange = usePagination({
|
30
|
|
|
currentPage,
|
31
|
|
|
totalPages,
|
32
|
|
|
siblingCount,
|
33
|
|
|
}) as number[]
|
34
|
|
|
|
35
|
|
|
if (currentPage === 0 || paginationRange?.length < 2) {
|
36
|
|
|
return null
|
37
|
|
|
}
|
38
|
|
|
|
39
|
|
|
return (
|
40
|
|
|
<div className={styles.paginationWrapper}>
|
|
|
|
|
41
|
|
|
<ul className={styles.pagination}>
|
|
|
|
|
42
|
|
|
<li
|
|
|
|
|
43
|
|
|
className={clsx(styles.paginationItem, {
|
|
|
|
|
44
|
|
|
[styles['disabled']]: currentPage === 1,
|
45
|
|
|
})}
|
46
|
|
|
onClick={() => prevPage()}
|
|
|
|
|
47
|
|
|
onMouseEnter={() => prefetchPage(currentPage - 1)}
|
|
|
|
|
48
|
|
|
onMouseDownCapture={() => prefetchPage(currentPage - 1)}
|
|
|
|
|
49
|
|
|
>
|
50
|
|
|
<span className={styles.arrow}>❮</span>
|
|
|
|
|
51
|
|
|
</li>
|
52
|
|
|
{paginationRange?.map((pageNumber: number, idx) => {
|
|
|
|
|
53
|
|
|
if (pageNumber === DOTS) {
|
54
|
|
|
return (
|
55
|
|
|
<li
|
|
|
|
|
56
|
|
|
key={`pagination-${idx}`}
|
|
|
|
|
57
|
|
|
className={clsx(styles.paginationItem, styles.dots)}
|
|
|
|
|
58
|
|
|
>
|
|
|
|
|
59
|
|
|
...
|
60
|
|
|
</li>
|
61
|
|
|
)
|
62
|
|
|
}
|
63
|
|
|
|
64
|
|
|
return (
|
65
|
|
|
<li
|
|
|
|
|
66
|
|
|
key={`pagination-${idx}`}
|
|
|
|
|
67
|
|
|
className={clsx(styles.paginationItem, {
|
|
|
|
|
68
|
|
|
[styles['paginationForward']]:
|
69
|
|
|
pageNumber > 1 && pageNumber < totalPages && isAscending,
|
70
|
|
|
[styles['paginationBackward']]:
|
71
|
|
|
pageNumber > 1 && pageNumber < totalPages && !isAscending,
|
72
|
|
|
[styles['selected']]: pageNumber === currentPage,
|
73
|
|
|
})}
|
74
|
|
|
onClick={() => setPage(pageNumber)}
|
|
|
|
|
75
|
|
|
onMouseEnter={() => prefetchPage(pageNumber)}
|
|
|
|
|
76
|
|
|
>
|
77
|
|
|
<Text tag="span">{pageNumber}</Text>
|
|
|
|
|
78
|
|
|
</li>
|
79
|
|
|
)
|
80
|
|
|
})}
|
81
|
|
|
<li
|
|
|
|
|
82
|
|
|
className={clsx(styles.paginationItem, {
|
|
|
|
|
83
|
|
|
[styles['disabled']]: currentPage === totalPages,
|
84
|
|
|
})}
|
85
|
|
|
onClick={() => nextPage()}
|
|
|
|
|
86
|
|
|
onMouseEnter={() => prefetchPage(currentPage + 1)}
|
|
|
|
|
87
|
|
|
onMouseDownCapture={() => prefetchPage(currentPage + 1)}
|
|
|
|
|
88
|
|
|
>
|
89
|
|
|
<span className={styles.arrow}>❯</span>
|
|
|
|
|
90
|
|
|
</li>
|
91
|
|
|
</ul>
|
92
|
|
|
</div>
|
93
|
|
|
)
|
94
|
|
|
}
|
95
|
|
|
|
96
|
|
|
export { Pagination }
|
97
|
|
|
|