1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
import { Component } from 'react'
import { withApollo, graphql, compose } from 'react-apollo'
import UpdateItem from './UpdateItem';
import Link from 'next/link';
import styled from 'styled-components';
import TakeMyMoney from './TakeMyMoney';
import AddToCart from './AddToCart';
import Pagination from './Pagination';
import formatMoney from '../lib/formatMoney';
import makeImage from '../lib/image';
import slugify from 'slugify';
import { ALL_ITEMS_QUERY, DELETE_ITEM_MUTATION } from '../queries';
const Title = styled.h1`
font-size: 10px;
`;
const Items = styled.div`
display: grid;
grid-template-columns: repeat(4, calc(33% - 20px));
grid-gap: 20px;
`;
const Item = styled.div`
background: #f3f3f3;
padding: 5px;
img {
width: 100%;
}
`;
class ItemList extends Component {
componentDidMount() {
this.prefetchNextItems(this.props.page);
}
componentWillReceiveProps(nextProps) {
// update the next items if the page prop changed
if(this.props.page !== nextProps.page) {
this.prefetchNextItems(nextProps.page);
}
}
prefetchNextItems = (currentPage) => {
const page = currentPage + 1;
console.log(`Prefetching Next items! Page ${page}`);
this.props.client.query({
query: ALL_ITEMS_QUERY,
variables: {
skip: (page * 3) - 3
}
})
}
render() {
console.log("CLIENTTT!!", this.props.client);
// 1
if (this.props.allItemsQuery && this.props.allItemsQuery.loading) {
return <div>Loading</div>
}
// 2
if (this.props.allItemsQuery && this.props.allItemsQuery.error) {
console.log(this.props.allItemsQuery.error)
return <div>Error</div>
}
// 3
const itemsToRender = this.props.allItemsQuery.allItems;
return (
<div>
<Pagination page={this.props.page}></Pagination>
<Title>Items For Sale</Title>
<Items>
{itemsToRender.map((item,i) => (
<Item className="item" key={i}>
{ item.image ? <img key={item.image.secret} src={makeImage(item.image)} /> : null }
<h3>
<Link href={{
pathname: 'item',
query: {
slug: slugify(item.title),
itemId: item.id
},
}}>
<a>{item.title}</a>
</Link>
</h3>
<p>{item.description}</p>
<Link href={{
pathname: '/admin/update',
query: { id: item.id }
}}>
<a>Edit ✏️</a>
</Link>
<TakeMyMoney
id={item.id}
amount={item.price}
name={item.title} // the pop-in header title
description={item.description} // the pop-in header subtitle
image={makeImage(item.image)}
>
<button>Buy for {formatMoney(item.price)}</button>
</TakeMyMoney>
<AddToCart id={item.id}></AddToCart>
<button onClick={() => this.props.removeItemMutation({ variables: { id: item.id }})}>× Delete item</button>
</Item>
))}
</Items>
</div>
)
}
}
// 1
// We export the graphQL HOC - this will fetch the data and inject it into the ItemList compeont via props
// Create some Enhancers
const itemsEnahncer = graphql(ALL_ITEMS_QUERY, { name: 'allItemsQuery', options({ page }) {
return {
variables: {
skip: (page * 3) - 3
},
}
}});
const deleteItemEnhancer = graphql(DELETE_ITEM_MUTATION, {
name: 'removeItemMutation',
options: {
update: (proxy, { data: { deleteItem } }) => {
// grab the data from our cache
const data = proxy.readQuery({ query: ALL_ITEMS_QUERY });
// filter out the delted item
data.allItems = data.allItems.filter(item => item.id !== deleteItem.id);
// and then "set state" (update cache), so it will update whereever we have used this data on the page
proxy.writeQuery({ query: ALL_ITEMS_QUERY, data });
},
}
});
export default withApollo(compose(itemsEnahncer, deleteItemEnhancer)(ItemList));
|