Path: blob/1.0-develop/resources/scripts/components/elements/Pagination.tsx
7461 views
import React from 'react';1import { PaginatedResult } from '@/api/http';2import tw from 'twin.macro';3import styled from 'styled-components/macro';4import Button from '@/components/elements/Button';5import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';6import { faAngleDoubleLeft, faAngleDoubleRight } from '@fortawesome/free-solid-svg-icons';78interface RenderFuncProps<T> {9items: T[];10isLastPage: boolean;11isFirstPage: boolean;12}1314interface Props<T> {15data: PaginatedResult<T>;16showGoToLast?: boolean;17showGoToFirst?: boolean;18onPageSelect: (page: number) => void;19children: (props: RenderFuncProps<T>) => React.ReactNode;20}2122const Block = styled(Button)`23${tw`p-0 w-10 h-10`}2425&:not(:last-of-type) {26${tw`mr-2`};27}28`;2930function Pagination<T>({ data: { items, pagination }, onPageSelect, children }: Props<T>) {31const isFirstPage = pagination.currentPage === 1;32const isLastPage = pagination.currentPage >= pagination.totalPages;3334const pages = [];3536// Start two spaces before the current page. If that puts us before the starting page default37// to the first page as the starting point.38const start = Math.max(pagination.currentPage - 2, 1);39const end = Math.min(pagination.totalPages, pagination.currentPage + 5);4041for (let i = start; i <= end; i++) {42pages.push(i);43}4445return (46<>47{children({ items, isFirstPage, isLastPage })}48{pages.length > 1 && (49<div css={tw`mt-4 flex justify-center`}>50{pages[0] > 1 && !isFirstPage && (51<Block isSecondary color={'primary'} onClick={() => onPageSelect(1)}>52<FontAwesomeIcon icon={faAngleDoubleLeft} />53</Block>54)}55{pages.map((i) => (56<Block57isSecondary={pagination.currentPage !== i}58color={'primary'}59key={`block_page_${i}`}60onClick={() => onPageSelect(i)}61>62{i}63</Block>64))}65{pages[4] < pagination.totalPages && !isLastPage && (66<Block isSecondary color={'primary'} onClick={() => onPageSelect(pagination.totalPages)}>67<FontAwesomeIcon icon={faAngleDoubleRight} />68</Block>69)}70</div>71)}72</>73);74}7576export default Pagination;777879