forked from pterodactyl/panel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPagination.tsx
More file actions
77 lines (67 loc) · 2.59 KB
/
Pagination.tsx
File metadata and controls
77 lines (67 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import React from 'react';
import { PaginatedResult } from '@/api/http';
import tw from 'twin.macro';
import styled from 'styled-components/macro';
import Button from '@/components/elements/Button';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faAngleDoubleLeft, faAngleDoubleRight } from '@fortawesome/free-solid-svg-icons';
interface RenderFuncProps<T> {
items: T[];
isLastPage: boolean;
isFirstPage: boolean;
}
interface Props<T> {
data: PaginatedResult<T>;
showGoToLast?: boolean;
showGoToFirst?: boolean;
onPageSelect: (page: number) => void;
children: (props: RenderFuncProps<T>) => React.ReactNode;
}
const Block = styled(Button)`
${tw`p-0 w-10 h-10`}
&:not(:last-of-type) {
${tw`mr-2`};
}
`;
function Pagination<T>({ data: { items, pagination }, onPageSelect, children }: Props<T>) {
const isFirstPage = pagination.currentPage === 1;
const isLastPage = pagination.currentPage >= pagination.totalPages;
const pages = [];
// Start two spaces before the current page. If that puts us before the starting page default
// to the first page as the starting point.
const start = Math.max(pagination.currentPage - 2, 1);
const end = Math.min(pagination.totalPages, pagination.currentPage + 5);
for (let i = start; i <= end; i++) {
pages.push(i);
}
return (
<>
{children({ items, isFirstPage, isLastPage })}
{pages.length > 1 && (
<div css={tw`mt-4 flex justify-center`}>
{pages[0] > 1 && !isFirstPage && (
<Block isSecondary color={'primary'} onClick={() => onPageSelect(1)}>
<FontAwesomeIcon icon={faAngleDoubleLeft} />
</Block>
)}
{pages.map((i) => (
<Block
isSecondary={pagination.currentPage !== i}
color={'primary'}
key={`block_page_${i}`}
onClick={() => onPageSelect(i)}
>
{i}
</Block>
))}
{pages[4] < pagination.totalPages && !isLastPage && (
<Block isSecondary color={'primary'} onClick={() => onPageSelect(pagination.totalPages)}>
<FontAwesomeIcon icon={faAngleDoubleRight} />
</Block>
)}
</div>
)}
</>
);
}
export default Pagination;