hellowin/kanca

View on GitHub
src/infra/component/Pagination.js

Summary

Maintainability
C
1 day
Test Coverage
// @flow
import React from 'react';

class Pagination extends React.Component {

  state: {
    page: number,
  }

  props: {
    list: Object[],
    ChildNode: any,
    perPage?: number,
    hideNavigationOnSinglePage?: boolean,
    Wrapper?: any,
  }

  goToPage: Function

  constructor(props: Object) {
    super(props);

    this.goToPage = this.goToPage.bind(this);

    this.state = {
      page: 1,
    };
  }

  goToPage(page: number) {
    return (e: Event) => {
      e.preventDefault();
      this.setState({ page });
    }
  }

  render() {
    const { list, ChildNode, hideNavigationOnSinglePage, perPage, Wrapper } = this.props;
    const { page } = this.state;

    // handle default props
    const fixPerPage = perPage || 10;

    // handle list
    const start = (page - 1) * fixPerPage;
    const end = start + fixPerPage;
    const currentList = list.slice(start, end);

    // handle pagination details
    const totalPage = Math.ceil(list.length / fixPerPage);
    const max = 3;
    const startPage: number = page - max <= 1 ? 1 : page - max;
    const endPage: number = page + max >= totalPage ? totalPage : page + max;
    const allPages = [];
    for (let x = startPage; x <= endPage; x++) {
      allPages.push(x);
    }

    // available pages
    const pages = [
      (<li key="first" className={page <= 1 ? 'disabled page-item' : 'page-item'}>
        <a className="page-link no-href-link" aria-label="First" onClick={this.goToPage(1)}>
          <span aria-hidden="true">««</span>
          <span className="sr-only">First</span>
        </a>
      </li>),
      (<li key="prev" className={page <= 1 ? 'disabled page-item' : 'page-item'}>
        <a className="page-link no-href-link" aria-label="Previous" onClick={this.goToPage(page - 1)}>
          <span aria-hidden="true">«</span>
          <span className="sr-only">Previous</span>
        </a>
      </li>),
      ...allPages.map((pg, key) => <li key={key} className={page === pg ? 'active page-item' : 'page-item'}><a className="page-link no-href-link" onClick={this.goToPage(pg)} >{pg}</a></li>),
      (<li key="next" className={page >= totalPage ? 'disabled page-item' : 'page-item'}>
        <a className="page-link no-href-link" aria-label="Next" onClick={this.goToPage(page + 1)}>
          <span aria-hidden="true">»</span>
          <span className="sr-only">Next</span>
        </a>
      </li>),
      (<li key="last" className={page >= totalPage ? 'disabled page-item' : 'page-item'}>
        <a className="page-link no-href-link" aria-label="Last" onClick={this.goToPage(totalPage)}>
          <span aria-hidden="true">»»</span>
          <span className="sr-only">Last</span>
        </a>
      </li>),
    ];

    const pagination = (
      <nav>
        <ul className="pagination" style={{ float: 'right' }}>
          {pages.map((page, key) => page)}
        </ul>
      </nav>
    );

    const navigation = hideNavigationOnSinglePage && totalPage === 1 ? '' : (
      <div className="row">
        <div className="col-md-6" style={{ lineHeight: 3 }}>
          Page {page} of {totalPage}. Item {start + 1} to {end}.
        </div>
        <div className="col-md-6">
          {pagination}
        </div>
      </div>
    );

    const content = Wrapper ? (
      <Wrapper>
        {currentList.map((props, key) => <ChildNode key={key} {...props} />)}
      </Wrapper>
    ) : currentList.map((props, key) => <ChildNode key={key} {...props} />);

    return (
      <div className="row">
        <div className="col-12">
          {content}
        </div>
        <div className="col-12">
          {navigation}
        </div>
      </div>
    );
  }

}

export default Pagination;