From 0985e8b4e6c071ab911976ea6ab713080db349ac Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Fri, 5 Apr 2019 12:19:17 +0200 Subject: [PATCH] add pagination component --- .../molecules/Pagination.module.scss | 43 ++++++++++++ .../src/components/molecules/Pagination.tsx | 66 +++++++++++++++++++ client/src/routes/Search.tsx | 32 +++++++-- 3 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 client/src/components/molecules/Pagination.module.scss create mode 100644 client/src/components/molecules/Pagination.tsx diff --git a/client/src/components/molecules/Pagination.module.scss b/client/src/components/molecules/Pagination.module.scss new file mode 100644 index 0000000..043df4d --- /dev/null +++ b/client/src/components/molecules/Pagination.module.scss @@ -0,0 +1,43 @@ +@import '../../styles/variables'; + +.pagination { + display: flex; + margin-top: $spacer * 2; + margin-bottom: $spacer; + justify-content: center; + + > div { + &:first-child { + margin-right: $spacer; + } + + &:last-child { + margin-left: $spacer; + text-align: right; + } + } +} + +.number { + text-align: center; + width: 2rem; + height: 2rem; + line-height: 1.7; + display: inline-block; + border-radius: 50%; + border: 1px solid transparent; + + &:hover, + &:focus { + background: rgba(255, 255, 255, .3); + border-color: $brand-grey; + } +} + +.current { + composes: number; + cursor: default; + pointer-events: none; + border: 1px solid $brand-grey; + color: $brand-grey-light; +} diff --git a/client/src/components/molecules/Pagination.tsx b/client/src/components/molecules/Pagination.tsx new file mode 100644 index 0000000..1a03bdc --- /dev/null +++ b/client/src/components/molecules/Pagination.tsx @@ -0,0 +1,66 @@ +import React, { PureComponent } from 'react' +import Button from '../atoms/Button' +import styles from './Pagination.module.scss' + +const PageNumber = ({ + i, + current +}: { + i: number + current: boolean + onClick: any +}) => ( + +) + +const PrevNext = ({ prevPage }: { prevPage?: number; onClick: any }) => ( + +) + +export default class Pagination extends PureComponent<{ + currentPage: number + totalPages: number + prevPage?: number + nextPage?: number + setPage(page: number): void +}> { + public render() { + const { + currentPage, + totalPages, + prevPage, + nextPage, + setPage + } = this.props + const isFirst = currentPage === 1 + const isLast = currentPage === totalPages + + return nextPage && nextPage > 1 ? ( +
+
+ {!isFirst && ( + + )} +
+
+ {Array.from({ length: totalPages }, (_, i) => ( + + ))} +
+
+ {!isLast && } +
+
+ ) : null + } +} diff --git a/client/src/routes/Search.tsx b/client/src/routes/Search.tsx index b49d90c..f9e21c7 100644 --- a/client/src/routes/Search.tsx +++ b/client/src/routes/Search.tsx @@ -5,6 +5,7 @@ import Spinner from '../components/atoms/Spinner' import Route from '../components/templates/Route' import { User } from '../context/User' import Asset from '../components/molecules/Asset' +import Pagination from '../components/molecules/Pagination' import styles from './Search.module.scss' interface SearchProps { @@ -14,15 +15,17 @@ interface SearchProps { interface SearchState { results: any[] + totalPages: number + currentPage: number isLoading: boolean - page: number } export default class Search extends PureComponent { public state = { results: [], - isLoading: true, - page: 0 + totalPages: 1, + currentPage: 1, + isLoading: true } private readonly searchTerm = queryString.parse(this.props.location.search) @@ -35,7 +38,7 @@ export default class Search extends PureComponent { private searchAssets = async () => { const searchQuery = { offset: 100, - page: this.state.page, + page: this.state.currentPage, query: { text: [this.searchTerm], price: [-1, 1] @@ -48,10 +51,19 @@ export default class Search extends PureComponent { const search = await this.context.ocean.aquarius.queryMetadata( searchQuery ) - this.setState({ results: search.results, isLoading: false }) + this.setState({ + results: search.results, + totalPages: search.totalPages, + currentPage: search.page + 1, // first page is always 0 in response + isLoading: false + }) Logger.log(`Loaded ${this.state.results.length} assets`) } + private setPage = (page: number) => { + this.setState({ currentPage: page }) + } + public renderResults = () => this.state.isLoading ? ( @@ -66,6 +78,8 @@ export default class Search extends PureComponent { ) public render() { + const { totalPages, currentPage } = this.state + return ( ${this.searchTerm}`} @@ -73,6 +87,14 @@ export default class Search extends PureComponent { wide > {this.renderResults()} + + ) }