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
|
import React, { Component } from 'react';
import { graphql, gql } from 'react-apollo';
import { ALL_ITEMS_QUERY, CREATE_ITEM_MUTATION } from '../queries';
import ErrorMessage from './ErrorMessage';
import { fileEndpoint } from '../config';
class CreateLink extends Component {
state = {
description: 'test',
title: 'testing title',
image: '',
price: 500,
fullPrice: 0,
loading: false,
error: {
message: '',
},
};
componentWillReceiveProps(nextProps) {
console.log(nextProps);
}
uploadFile = async e => {
this.setState({ loading: true });
const files = e.currentTarget.files;
const data = new FormData();
data.append('file', files[0]);
data.append('upload_preset', 'sickfits');
// use the file endpoint
const res = await fetch('https://api.cloudinary.com/v1_1/wesbos/image/upload', {
method: 'POST',
body: data,
});
const file = await res.json();
console.log(file);
this.setState({ image: file.secure_url, loading: false });
};
_createLink = async e => {
e.preventDefault();
// pull the values from state
const { description, title, price, image } = this.state;
// create a mutation
// TODO: handle any errors
// turn loading on
this.setState({ loading: true });
try {
console.log('About to call create item mutation');
const res = await this.props.createItemMutation({
// pass in those variables from state
variables: {
description,
title,
image,
price: parseInt(price),
},
});
} catch (error) {
this.setState({ error });
console.log(error);
}
this.setState({ loading: false });
};
render() {
return (
<div>
{this.state.loading ? 'LOADING...' : 'Ready!'}
<ErrorMessage error={this.state.error} onButtonClick={() => this.setState({ error: {} })} />
<form onSubmit={this._createLink}>
<p>
Image
<input onChange={this.uploadFile} type="file" accept=".png, .jpg, .jpeg" />
{this.state.image ? <img src={this.state.image} width="100" alt={this.state.title} /> : null}
</p>
<p>
Title
<input
value={this.state.title}
onChange={e => this.setState({ title: e.target.value })}
type="text"
placeholder="Title"
/>
</p>
<label>
Price<input
type="number"
min="0"
value={this.state.price}
onChange={e => this.setState({ price: e.target.value })}
/>
</label>
<textarea
value={this.state.description}
onChange={e => this.setState({ description: e.target.value })}
type="text"
placeholder="The desc for this item"
/>
<button disabled={!this.state.loading} type="submit">
Submit
</button>
</form>
</div>
);
}
}
// TODO: The create item should only be allowed
// When we submit this mutation, we need to update our store - we have a few ways to do that:
// One - we can go nucular and run refetchQueries() which will just go get everything - this is easy, but at the cost of efficiency.
export default graphql(CREATE_ITEM_MUTATION, {
name: 'createItemMutation',
options: {
// Easy, but slow
// refetchQueries: ['AllLinksQuery']
// This is much Better / efficient
// Notice how the variable is called createItem - that is because createItem is the name of the query!
update: (proxy, { data: { createItem } }) => {
console.log('UPDATING');
const data = proxy.readQuery({ query: ALL_ITEMS_QUERY });
// data is our store, allItems is our sub-"state", it's just an array. We can just add it to
console.log({ createItem });
data.allItems = [createItem, ...data.allItems.slice(1, 3)];
// and then "set state", so it will update on the page. This will update the cache for us!
proxy.writeQuery({ query: ALL_ITEMS_QUERY, data });
},
},
})(CreateLink);
|