summaryrefslogtreecommitdiffstats
path: root/finished-application/frontend/components/CreateItem.js
diff options
context:
space:
mode:
Diffstat (limited to 'finished-application/frontend/components/CreateItem.js')
-rw-r--r--finished-application/frontend/components/CreateItem.js148
1 files changed, 148 insertions, 0 deletions
diff --git a/finished-application/frontend/components/CreateItem.js b/finished-application/frontend/components/CreateItem.js
new file mode 100644
index 0000000..503b3cb
--- /dev/null
+++ b/finished-application/frontend/components/CreateItem.js
@@ -0,0 +1,148 @@
+import React, { Component } from 'react';
+import { Mutation } from 'react-apollo';
+import Router from 'next/router';
+import wait from 'waait';
+import gql from 'graphql-tag';
+import Error from './ErrorMessage';
+import Form from './styles/Form';
+import formatMoney from '../lib/formatMoney';
+import { ALL_ITEMS_QUERY } from './Items';
+import { PAGINATION_QUERY } from './Pagination';
+
+const CREATE_ITEM_MUTATION = gql`
+ mutation CREATE_ITEM_MUTATION(
+ $description: String!
+ $title: String!
+ $price: Int!
+ $image: String
+ $largeImage: String
+ ) {
+ createItem(
+ description: $description
+ title: $title
+ price: $price
+ image: $image
+ largeImage: $largeImage
+ ) {
+ id
+ }
+ }
+`;
+
+class CreateItem extends Component {
+ state = {
+ title: '',
+ description: '',
+ image: '',
+ largeImage: '',
+ price: 0,
+ };
+
+ handleChange = e => {
+ const { name, value, type } = e.target;
+ const val = type === 'number' ? parseFloat(value) : value;
+ this.setState({ [name]: val });
+ };
+
+ 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();
+ this.setState({
+ image: file.secure_url,
+ largeImage: file.eager[0].secure_url,
+ loading: false,
+ });
+ };
+
+ render() {
+ return (
+ <Mutation
+ mutation={CREATE_ITEM_MUTATION}
+ variables={this.state}
+ refetchQueries={[{ query: ALL_ITEMS_QUERY }, { query: PAGINATION_QUERY }]}
+ >
+ {(createItem, { loading, error }) => (
+ <Form
+ data-test
+ onSubmit={async e => {
+ e.preventDefault();
+ const { data: { createItem: item } } = await createItem();
+ // we wait 0 ms so it puts the router push at the end of the call stack. This ensures that refetchQueries runs before we unmount the component :)
+ await wait();
+ Router.push({
+ pathname: `/item`,
+ query: { id: item.id },
+ });
+ }}
+ >
+ <h2>Sell an Item.</h2>
+ <Error error={error} />
+ <fieldset disabled={loading} aria-busy={loading}>
+ <label htmlFor="file">
+ Image
+ <input
+ required
+ id="file"
+ onChange={this.uploadFile}
+ type="file"
+ accept=".png, .jpg, .jpeg"
+ />
+ {this.state.image ? (
+ <img src={this.state.image} width="100" alt={this.state.title} />
+ ) : null}
+ </label>
+ <label htmlFor="title">
+ Title
+ <input
+ required
+ value={this.state.title}
+ onChange={this.handleChange}
+ type="text"
+ name="title"
+ id="title"
+ placeholder="Title"
+ />
+ </label>
+ <label htmlFor="price">
+ Price {this.state.price && formatMoney(this.state.price)}
+ <input
+ required
+ type="number"
+ id="price"
+ name="price"
+ min="0"
+ value={this.state.price}
+ onChange={this.handleChange}
+ />
+ </label>
+ <textarea
+ id="description"
+ required
+ name="description"
+ value={this.state.description}
+ onChange={this.handleChange}
+ placeholder="The desc for this item"
+ />
+ <button disabled={this.state.loading} type="submit">
+ Submit
+ </button>
+ </fieldset>
+ </Form>
+ )}
+ </Mutation>
+ );
+ }
+}
+
+export default CreateItem;
+export { CREATE_ITEM_MUTATION };