Skip to content

Commit 47d9cad

Browse files
author
Carlos Rufo Jimenez
committed
9.4-end-pagination-v2.1
1 parent 86a048b commit 47d9cad

File tree

5 files changed

+89
-14
lines changed

5 files changed

+89
-14
lines changed

src/components/App.js

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

@@ -11,10 +11,12 @@ export default () => (
1111
<Header />
1212
<div className="ph3 pv1 background-gray">
1313
<Switch>
14-
<Route exact path="/" component={LinkList} />
14+
<Route exact path="/" render={() => <Redirect to="/new/1" />} />
1515
<Route exact path="/create" component={CreateLink} />
1616
<Route exact path="/login" component={Login} />
1717
<Route exact path="/search" component={Search} />
18+
<Route exact path="/top" component={LinkList} />
19+
<Route exact path="/new/:page" component={LinkList} />
1820
</Switch>
1921
</div>
2022
</div>

src/components/CreateLink.js

Lines changed: 12 additions & 3 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
const POST_MUTATION = gql`
78
mutation PostMutation($description: String!, $url: String!) {
@@ -53,13 +54,21 @@ class CreateLink extends Component {
5354
<Mutation
5455
mutation={POST_MUTATION}
5556
variables={{ description, url }}
56-
onCompleted={() => this.props.history.push('/')}
57+
onCompleted={() => this.props.history.push('/new/1')}
5758
update={(cache, { data: { post } }) => {
58-
const data = cache.readQuery({ query: FEED_QUERY })
59+
const first = LINKS_PER_PAGE
60+
const skip = 0
61+
const orderBy = 'createdAt_DESC'
62+
const data = cache.readQuery({
63+
query: FEED_QUERY,
64+
variables: { first, skip, orderBy }
65+
})
5966
data.feed.links.splice(0, 0, post)
67+
data.feed.links.pop()
6068
cache.writeQuery({
6169
query: FEED_QUERY,
62-
data
70+
data,
71+
variables: { first, skip, orderBy }
6372
})
6473
}}
6574
>

src/components/Header.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ const Header = props => {
1313
new
1414
</Link>
1515
<div className="ml1">|</div>
16+
<Link to="/top" className="ml1 no-underline black">
17+
top
18+
</Link>
19+
<div className="ml1">|</div>
1620
<Link to="/search" className="ml1 no-underline black">
1721
search
1822
</Link>

src/components/LinkList.js

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import Link from './Link'
33
import { Query } from 'react-apollo'
44
import gql from 'graphql-tag'
55
import LinkListSubscriptions from './LinkListSubscriptions'
6+
import { LINKS_PER_PAGE } from '../constants'
67

78
export const FEED_QUERY = gql`
8-
{
9-
feed {
9+
query FeedQuery($first: Int, $skip: Int, $orderBy: LinkOrderByInput) {
10+
feed(first: $first, skip: $skip, orderBy: $orderBy) {
1011
links {
1112
id
1213
createdAt
@@ -23,27 +24,65 @@ export const FEED_QUERY = gql`
2324
}
2425
}
2526
}
27+
count
2628
}
2729
}
2830
`
2931

30-
const updateCacheAfterVote = (store, createVote, linkId) => {
31-
const data = store.readQuery({ query: FEED_QUERY })
32+
const updateCacheAfterVote = (page, isNewPage, cache, createVote, linkId) => {
33+
const skip = isNewPage ? (page - 1) * LINKS_PER_PAGE : 0
34+
const first = isNewPage ? LINKS_PER_PAGE : 100
35+
const orderBy = isNewPage ? 'createdAt_DESC' : null
36+
const data = cache.readQuery({
37+
query: FEED_QUERY,
38+
variables: { first, skip, orderBy }
39+
})
3240

3341
const votedLink = data.feed.links.find(link => link.id === linkId)
3442
votedLink.votes = createVote.link.votes
43+
cache.writeQuery({ query: FEED_QUERY, data })
44+
}
45+
46+
const getQueryVariables = (page, isNewPage) => {
47+
const skip = isNewPage ? (page - 1) * LINKS_PER_PAGE : 0
48+
const first = isNewPage ? LINKS_PER_PAGE : 100
49+
const orderBy = isNewPage ? 'createdAt_DESC' : null
50+
return { first, skip, orderBy }
51+
}
52+
53+
const getLinksToRender = (isNewPage, data) => {
54+
if (isNewPage) {
55+
return data.feed.links
56+
}
57+
const rankedLinks = data.feed.links.slice()
58+
rankedLinks.sort((l1, l2) => l2.votes.length - l1.votes.length)
59+
return rankedLinks
60+
}
3561

36-
store.writeQuery({ query: FEED_QUERY, data })
62+
const nextPage = (page, data, history) => {
63+
if (page <= data.feed.count / LINKS_PER_PAGE) {
64+
const nextPage = page + 1
65+
history.push(`/new/${nextPage}`)
66+
}
67+
}
68+
69+
const previousPage = (page, history) => {
70+
if (page > 1) {
71+
const previousPage = page - 1
72+
history.push(`/new/${previousPage}`)
73+
}
3774
}
3875

39-
export default () => {
76+
export default ({ match, location, history }) => {
77+
const isNewPage = location.pathname.includes('new')
78+
const page = parseInt(match.params.page, 10)
4079
return (
41-
<Query query={FEED_QUERY}>
80+
<Query query={FEED_QUERY} variables={getQueryVariables(page, isNewPage)}>
4281
{({ loading, error, data, subscribeToMore }) => {
4382
if (loading) return <div>Fetching</div>
4483
if (error) return <div>Error</div>
4584

46-
const linksToRender = data.feed.links
85+
const linksToRender = getLinksToRender(isNewPage, data)
4786

4887
return (
4988
<LinkListSubscriptions subscribeToMore={subscribeToMore}>
@@ -52,9 +91,29 @@ export default () => {
5291
key={link.id}
5392
link={link}
5493
index={index}
55-
updateStoreAfterVote={updateCacheAfterVote}
94+
updateStoreAfterVote={updateCacheAfterVote.bind(
95+
this,
96+
page,
97+
isNewPage
98+
)}
5699
/>
57100
))}
101+
{isNewPage && (
102+
<div className="flex ml4 mv3 gray">
103+
<div
104+
className="pointer mr2"
105+
onClick={() => previousPage(page, history)}
106+
>
107+
Previous
108+
</div>
109+
<div
110+
className="pointer"
111+
onClick={() => nextPage(page, data, history)}
112+
>
113+
Next
114+
</div>
115+
</div>
116+
)}
58117
</LinkListSubscriptions>
59118
)
60119
}}

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)