diff --git a/src/components/Paginate.jsx b/src/components/Paginate.jsx index 34ecd8e..da8d3be 100644 --- a/src/components/Paginate.jsx +++ b/src/components/Paginate.jsx @@ -1,8 +1,9 @@ -import React, {Component, Fragment} from 'react'; +import React, {Fragment, useState} from 'react'; const LEFT_PAGE = 'LEFT'; const RIGHT_PAGE = 'RIGHT'; -const SPACE = 'SPACE'; +const SPACE_A = 'SPACE_A'; +const SPACE_B = 'SPACE_B'; /** * Helper method for creating a range of numbers @@ -20,60 +21,36 @@ const range = (from, to, step = 1) => { return range; } -export default class Paginate extends Component { - constructor(props) { - super(props); +export const Paginate = (props) => { + const pageLimit = typeof props.pageLimit === 'number' ? props.pageLimit : 30; + const totalRecords = typeof props.totalRecords === 'number' ? props.totalRecords : 0; + const pageNeighbours = typeof props.pageNeighbours === 'number' ? Math.max(0, Math.min(props.pageNeighbours, 2)) : 0; + const totalPages = Math.ceil(totalRecords / pageLimit); + const [currentPage, setCurrentPage] = useState(typeof props.currentPage === 'number' ? props.currentPage : 1); - this.loadProps = this.loadProps.bind(this); - this.gotoPage = this.gotoPage.bind(this); - this.handleClick = this.handleClick.bind(this); - this.handleMoveLeft = this.handleMoveLeft.bind(this); - this.handleMoveRight = this.handleMoveRight.bind(this); - this.makePageLink = this.makePageLink.bind(this); - this.fetchPageNumbers = this.fetchPageNumbers.bind(this); - - this.loadProps(); - this.state = {currentPage: this.currentPage}; + const gotoPage = (page) => { + const currentPage = Math.max(0, Math.min(page, totalPages)); + props.onPageChanged(page) + setCurrentPage(currentPage); } - loadProps() { - const {totalRecords = 0, pageLimit = 30, pageNeighbours = 0, currentPage = 1} = this.props; - - this.pageLimit = typeof pageLimit === 'number' ? pageLimit : 30; - this.totalRecords = typeof totalRecords === 'number' ? totalRecords : 0; - this.pageNeighbours = typeof pageNeighbours === 'number' ? Math.max(0, Math.min(pageNeighbours, 2)) : 0; - this.totalPages = Math.ceil(this.totalRecords / this.pageLimit); - this.currentPage = typeof currentPage === 'number' ? currentPage : 1 - } - - gotoPage(page) { - const {onPageChanged = f => f} = this.props; - const currentPage = Math.max(0, Math.min(page, this.totalPages)); - this.setState({currentPage: currentPage}, () => onPageChanged(page)); - } - - handleClick(page) { - return (evt) => { - evt.preventDefault(); - if (this.state.currentPage !== page) this.gotoPage(page); - } - } - - handleMoveLeft(evt) { + const handleClick = (page) => (evt) => { evt.preventDefault(); - this.gotoPage(this.state.currentPage - 1); + if (currentPage !== page) gotoPage(page); } - handleMoveRight(evt) { + const handleMoveLeft = (evt) => { evt.preventDefault(); - this.gotoPage(this.state.currentPage + 1); + gotoPage(currentPage - 1); } - makePageLink(page) { - const {makeLink = f => f} = this.props; - return makeLink(page); + const handleMoveRight = (evt) => { + evt.preventDefault(); + gotoPage(currentPage + 1); } + const makePageLink = (page) => props.makeLink(page); + /** * Let's say we have 10 pages and we set pageNeighbours to 2 * Given that the current page is 6 @@ -85,16 +62,12 @@ export default class Paginate extends Component { * [x] => represents current page * {...x} => represents page neighbours */ - fetchPageNumbers() { - const totalPages = this.totalPages; - const currentPage = this.state.currentPage; - const pageNeighbours = this.pageNeighbours; - + const fetchPageNumbers = () => { /** * totalNumbers: the total page numbers to show on the control * totalBlocks: totalNumbers + 2 to cover for the left(<) and right(>) controls */ - const totalNumbers = (this.pageNeighbours * 2) + 3; + const totalNumbers = (pageNeighbours * 2) + 3; const totalBlocks = totalNumbers + 2; if (totalPages > totalBlocks) { @@ -115,14 +88,14 @@ export default class Paginate extends Component { // handle: (1) < {5 6} [7] {8 9} (10) if (hasLeftSpill && !hasRightSpill) { const extraPages = range(startPage - spillOffset, startPage - 1); - pages = [LEFT_PAGE, 1, SPACE, ...extraPages, ...pages]; + pages = [LEFT_PAGE, 1, SPACE_A, ...extraPages, ...pages]; // handle: (1) {2 3} [4] {5 6} > (10) } else if (!hasLeftSpill && hasRightSpill) { const extraPages = range(endPage + 1, endPage + spillOffset); - pages = [1, ...pages, ...extraPages, SPACE, totalPages, RIGHT_PAGE]; + pages = [1, ...pages, ...extraPages, SPACE_B, totalPages, RIGHT_PAGE]; // handle: (1) < {4 5} [6] {7 8} > (10) } else if (hasLeftSpill && hasRightSpill) { - pages = [LEFT_PAGE, 1, SPACE, ...pages, SPACE, totalPages, RIGHT_PAGE]; + pages = [LEFT_PAGE, 1, SPACE_A, ...pages, SPACE_B, totalPages, RIGHT_PAGE]; } return pages; @@ -130,49 +103,45 @@ export default class Paginate extends Component { } return range(1, totalPages); - } - render() { - this.loadProps(); - if (!this.totalRecords || this.totalPages === 1) return null; + if (!totalRecords || totalPages === 1) return null; - const currentPage = this.state.currentPage; - const pages = this.fetchPageNumbers(); - const blocks = pages.map((page, index) => { - if (page === LEFT_PAGE) return ( -