diff --git a/src/components/pagination.js b/src/components/pagination.js new file mode 100644 index 0000000..b44ca35 --- /dev/null +++ b/src/components/pagination.js @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016, Emiliano Eloi Silva Barbosa + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React, {Component} from "react"; + +class Pagination extends Component { + + paginate(page){ + this.props.onPageClick({ + ...this.props.pagination, + offset: page*this.props.pages + }); + } + + getItem(i){ + return ( +
  • { + this.paginate(i); + }}>{i+1}
  • + ); + } + + getTotals(){ + return( +
    +

    Total de Páginas: {this.requestedPages || "-"}

    +

    Total de Candidatos: {this.props.pagination.total_count || "-"}

    +
    + ); + } + + getPreviousLink(){ + return( +
  • + { + let previousPage = this.currentPage - 1; + previousPage = (previousPage < 0) ? 0 : previousPage; + this.paginate(previousPage); + }}> + + +
  • + ); + } + + getNextLink(){ + return( +
  • + { + let nextPage = this.currentPage + 1; + nextPage = (nextPage > this.requestedPages - 1) ? this.requestedPages - 1 : nextPage; + this.paginate(nextPage); + }}> + + +
  • + ); + } + + calculatePagination(pagination){ + this.showPaginaton = true; + if(!pagination.total_count){ + this.showPaginaton = false; + return; + } + this.requestedPages = Math.ceil(pagination.total_count / pagination.limit); + if(this.requestedPages < 2){ + this.showPaginaton = false; + return; + } + this.currentPage = pagination.offset / pagination.limit; + this.totalPages = (this.requestedPages < this.props.pages) ? this.requestedPages : this.props.pages; + this.startPage = (this.requestedPages <= this.props.pages) ? + 0 : (this.currentPage <= this.props.pages/2) ? + 0 : this.currentPage - this.props.pages/2; + } + + render(){ + + this.calculatePagination(this.props.pagination); + + if(!this.showPaginaton){ + return this.getTotals(); + } + + return ( + + ); + } +} + +export default Pagination; diff --git a/src/index.js b/src/index.js index 7a041c6..d3abf8e 100644 --- a/src/index.js +++ b/src/index.js @@ -21,11 +21,16 @@ import ReactDOM from "react-dom"; import PoliticianList from "./components/politician_list"; import Filters from "./components/filters"; +import Pagination from "./components/pagination"; class App extends Component { constructor(props) { super(props); + + this.pages = 10; + this.initialPage = 0; + this.initialPagination = {limit:this.pages,offset:this.initialPage}; this.state = { politicians: [], @@ -40,6 +45,7 @@ class App extends Component { selectedGender: [], selectedOccupations: [], selectedMaritalStatus: [], + pagination: this.initialPagination, query: "" }; @@ -47,13 +53,6 @@ class App extends Component { this.onChange = (state) => this.setState(state); - // FIXME: Iniial query - axios.get(this.URL + "/politicians/").then((result) => { - this.onChange({ - politicians: result.data.objects - }); - }); - } // FIXME @@ -101,20 +100,46 @@ class App extends Component { const marital_status = this.state.selectedMaritalStatus.map((item) => { return "marital_status__slug__in=" + item.value; }); + + let getPagination = () => { + let pag; + if(!this.isPageChanging){ + this.onChange({pagination:this.initialPagination}); + pag = this.initialPagination; + }else{ + pag = this.state.pagination; + } + let qsItems = []; + qsItems.push("offset=" + pag.offset); + qsItems.push("limit=" + pag.limit); + return qsItems; + }; let query = [].concat.call( politicians, elections, educations, political_parties, political_offices, - cities, states, elected, gender, occupations, marital_status + cities, states, elected, gender, occupations, marital_status, getPagination() ); this.onChange({query}); axios.get(this.URL + "/politicians/?" + query.join("&")).then((result) => { this.onChange({ - politicians: result.data.objects.map((item) => {return item;}) + politicians: result.data.objects.map((item) => {return item;}), + pagination: result.data.meta }); }); } + + componentDidMount(){ + this.onChangeQuery(); + } + + componentDidUpdate(prevProps, prevState){ + if (prevState.pagination.offset != this.state.pagination.offset && this.isPageChanging){ + this.onChangeQuery(); + this.isPageChanging = false; + } + } render() { @@ -137,6 +162,14 @@ class App extends Component { selectedOccupations={this.state.selectedOccupations} selectedMaritalStatus={this.state.selectedMaritalStatus} query={this.state.query} /> + + { + this.isPageChanging = true; + this.onChange({pagination}); + }}/>