Skip to content

Commit 8fda88d

Browse files
author
Carlos Rufo Jimenez
committed
9.4-end-pagination-v2.1
1 parent 66f78ea commit 8fda88d

File tree

5 files changed

+89
-16
lines changed

5 files changed

+89
-16
lines changed

src/components/App.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import CreateLink from './CreateLink'
44
import Header from './Header'
55
import Login from './Login'
66
import Search from './Search'
7-
import { Switch, Route } from 'react-router-dom'
7+
import { Switch, Route, Redirect } from 'react-router-dom'
88

99
class App extends Component {
1010
render() {
@@ -13,10 +13,12 @@ class App extends Component {
1313
<Header />
1414
<div className="ph3 pv1 background-gray">
1515
<Switch>
16-
<Route exact path="/" component={LinkList} />
17-
<Route exact path="/create" component={CreateLink} />
16+
<Route exact path="/" render={() => <Redirect to="/new/1" />} />
1817
<Route exact path="/login" component={Login} />
18+
<Route exact path="/create" component={CreateLink} />
1919
<Route exact path="/search" component={Search} />
20+
<Route exact path="/top" component={LinkList} />
21+
<Route exact path="/new/:page" component={LinkList} />
2022
</Switch>
2123
</div>
2224
</div>

src/components/CreateLink.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { Component } from 'react'
22
import { Mutation } from 'react-apollo'
33
import gql from 'graphql-tag'
44
import { FEED_QUERY } from './LinkList'
5+
import { LINKS_PER_PAGE } from '../constants'
56

67
// 1
78
const POST_MUTATION = gql`
@@ -56,17 +57,27 @@ class CreateLink extends Component {
5657
mutation={POST_MUTATION}
5758
variables={{ description, url }}
5859
update={(cache, { data: { post } }) => {
59-
const data = cache.readQuery({ query: FEED_QUERY })
60+
const first = LINKS_PER_PAGE
61+
const skip = 0
62+
const orderBy = 'createdAt_DESC'
63+
const data = cache.readQuery({
64+
query: FEED_QUERY,
65+
variables: { first, skip, orderBy },
66+
})
6067
data.feed.links.splice(0, 0, post)
68+
data.feed.links.pop()
6169
cache.writeQuery({
6270
query: FEED_QUERY,
6371
data,
72+
variables: { first, skip, orderBy },
6473
})
6574
}}
6675
>
6776
{postMutation => (
6877
<button
69-
onClick={() => postMutation() && this.props.history.push('/')}
78+
onClick={() =>
79+
postMutation() && this.props.history.push(`/new/1`)
80+
}
7081
>
7182
Submit
7283
</button>

src/components/Header.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ class Header extends Component {
1414
new
1515
</Link>
1616
<div className="ml1">|</div>
17+
<Link to="/top" className="ml1 no-underline black">
18+
top
19+
</Link>
20+
<div className="ml1">|</div>
1721
<Link to="/search" className="ml1 no-underline black">
1822
search
1923
</Link>

src/components/LinkList.js

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import React, { Component } from 'react'
22
import Link from './Link'
33
import { Query } from 'react-apollo'
44
import gql from 'graphql-tag'
5+
import { LINKS_PER_PAGE } from '../constants'
56

6-
// 1
77
export const FEED_QUERY = gql`
8-
# 2
9-
query FeedQuery {
10-
feed {
8+
query FeedQuery($first: Int, $skip: Int, $orderBy: LinkOrderByInput) {
9+
feed(first: $first, skip: $skip, orderBy: $orderBy) {
10+
count
1111
links {
1212
id
1313
createdAt
@@ -24,6 +24,7 @@ export const FEED_QUERY = gql`
2424
}
2525
}
2626
}
27+
count
2728
}
2829
}
2930
`
@@ -109,15 +110,27 @@ class LinkList extends Component {
109110
)
110111
}
111112

113+
getQueryVariables = () => {
114+
const page = parseInt(this.props.match.params.page, 10)
115+
const isNewPage = this.props.location.pathname.includes('new')
116+
const skip = isNewPage ? (page - 1) * LINKS_PER_PAGE : 0
117+
const first = isNewPage ? LINKS_PER_PAGE : 100
118+
const orderBy = isNewPage ? 'createdAt_DESC' : null
119+
return { first, skip, orderBy }
120+
}
121+
112122
render() {
113123
return (
114-
<Query query={FEED_QUERY}>
124+
<Query query={FEED_QUERY} variables={this.getQueryVariables()}>
115125
{result => {
116126
if (result.loading) return <div>Loading</div>
117127
if (result.error) return <div>Error</div>
118128

119129
const { data, subscribeToMore } = result
120-
const linksToRender = data.feed.links
130+
131+
const isNewPage = this.props.location.pathname.includes('new')
132+
const linksToRender = this._getLinksToRender(isNewPage, data)
133+
const page = parseInt(this.props.match.params.page, 10)
121134

122135
return (
123136
<div>
@@ -139,6 +152,19 @@ class LinkList extends Component {
139152
link={link}
140153
/>
141154
))}
155+
{isNewPage && (
156+
<div className="flex ml4 mv3 gray">
157+
<div
158+
className="pointer mr2"
159+
onClick={() => this._previousPage()}
160+
>
161+
Previous
162+
</div>
163+
<div className="pointer" onClick={() => this._nextPage(data)}>
164+
Next
165+
</div>
166+
</div>
167+
)}
142168
</div>
143169
)
144170
}}
@@ -147,14 +173,18 @@ class LinkList extends Component {
147173
}
148174

149175
_updateCacheAfterVote = (store, createVote, linkId) => {
150-
// 1
151-
const data = store.readQuery({ query: FEED_QUERY })
176+
const isNewPage = this.props.location.pathname.includes('new')
177+
const page = parseInt(this.props.match.params.page, 10)
178+
const skip = isNewPage ? (page - 1) * LINKS_PER_PAGE : 0
179+
const first = isNewPage ? LINKS_PER_PAGE : 100
180+
const orderBy = isNewPage ? 'createdAt_DESC' : null
181+
const data = store.readQuery({
182+
query: FEED_QUERY,
183+
variables: { first, skip, orderBy },
184+
})
152185

153-
// 2
154186
const votedLink = data.feed.links.find(link => link.id === linkId)
155187
votedLink.votes = createVote.link.votes
156-
157-
// 3
158188
store.writeQuery({ query: FEED_QUERY, data })
159189
}
160190

@@ -186,6 +216,31 @@ class LinkList extends Component {
186216
document: NEW_VOTES_SUBSCRIPTION,
187217
})
188218
}
219+
220+
_getLinksToRender = (isNewPage, data) => {
221+
if (isNewPage) {
222+
return data.feed.links
223+
}
224+
const rankedLinks = data.feed.links.slice()
225+
rankedLinks.sort((l1, l2) => l2.votes.length - l1.votes.length)
226+
return rankedLinks
227+
}
228+
229+
_nextPage = data => {
230+
const page = parseInt(this.props.match.params.page, 10)
231+
if (page <= data.feed.count / LINKS_PER_PAGE) {
232+
const nextPage = page + 1
233+
this.props.history.push(`/new/${nextPage}`)
234+
}
235+
}
236+
237+
_previousPage = () => {
238+
const page = parseInt(this.props.match.params.page, 10)
239+
if (page > 1) {
240+
const previousPage = page - 1
241+
this.props.history.push(`/new/${previousPage}`)
242+
}
243+
}
189244
}
190245

191246
export default LinkList

src/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export const AUTH_TOKEN = 'auth-token'
2+
export const LINKS_PER_PAGE = 5

0 commit comments

Comments
 (0)