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