From a6af043686e4375d7944e91cae3d5b63c59edab0 Mon Sep 17 00:00:00 2001 From: Wes Bos Date: Thu, 22 Mar 2018 16:29:31 -0400 Subject: Migrate to render props --- frontend/components/AddToCart.js | 44 +++++---- frontend/components/Cart.js | 76 ++++++++-------- frontend/components/CartCount.js | 1 - frontend/components/CreateItem.js | 164 +++++++++++++++------------------- frontend/components/DeleteItem.js | 39 ++++++++ frontend/components/EditUser.js | 69 +++++++------- frontend/components/ErrorMessage.js | 27 +++--- frontend/components/Header.js | 7 +- frontend/components/Item.js | 16 ++-- frontend/components/Items.js | 59 +++++++----- frontend/components/Nav.js | 87 +++++++++--------- frontend/components/Order.js | 95 ++++++++++---------- frontend/components/OrderList.js | 84 ++++++++--------- frontend/components/Page.js | 3 +- frontend/components/Pagination.js | 94 ++++++++++--------- frontend/components/RemoveFromCart.js | 29 +++--- frontend/components/Reset.js | 115 +++++++++++------------- frontend/components/ResetRequest.js | 71 +++++++-------- frontend/components/Search.js | 38 ++++---- frontend/components/Signin.js | 88 ++++++++---------- frontend/components/Signout.js | 17 ++-- frontend/components/Signup.js | 118 ++++++++++-------------- frontend/components/SingleItem.js | 4 + frontend/components/TakeMyMoney.js | 63 +++++++------ frontend/components/UpdateItem.js | 4 +- frontend/components/styles/Form.js | 35 +++++++- 26 files changed, 727 insertions(+), 720 deletions(-) create mode 100644 frontend/components/DeleteItem.js (limited to 'frontend/components') diff --git a/frontend/components/AddToCart.js b/frontend/components/AddToCart.js index 22cfe02..4757296 100644 --- a/frontend/components/AddToCart.js +++ b/frontend/components/AddToCart.js @@ -1,36 +1,34 @@ import { Component } from 'react'; -import { graphql, compose } from 'react-apollo'; -import styled from 'styled-components'; +import { Mutation } from 'react-apollo'; import PropTypes from 'prop-types'; -import { removeFromCartEnhancer, userEnhancer, addToCartEnhancer, singleItemEnhancer } from '../enhancers/enhancers'; +import { ADD_TO_CART_MUTATION, CURRENT_USER_QUERY } from '../queries/index'; class AddToCart extends Component { static propTypes = { - currentUser: PropTypes.object.isRequired, + id: PropTypes.string.isRequired, }; - componentDidMount() { - this.props.currentUser.refetch(); - } - - handleAddToCart = async () => { - const res = await this.props.addToCart({ - variables: { - id: this.props.id, - }, - }); + update = (proxy, payload) => { + const newCartItem = payload.data.addToCart; + const data = proxy.readQuery({ query: CURRENT_USER_QUERY }); + const existingIndex = data.me.cart.findIndex(cartItem => cartItem.id === newCartItem.id); + if (existingIndex >= 0) { + // already in cache, just replace it + data.me.cart = [...data.me.cart.slice(0, existingIndex), newCartItem, ...data.me.cart.slice(existingIndex + 1)]; + } else { + data.me.cart = [...data.me.cart, newCartItem]; + } + proxy.writeQuery({ query: CURRENT_USER_QUERY, data }); }; render() { - return ; + const { id } = this.props; + return ( + + {addToCart => } + + ); } } -AddToCart.propTypes = { - currentUser: PropTypes.object.isRequired, - addToCart: PropTypes.func.isRequired, - id: PropTypes.string.isRequired, -}; - -export default compose(userEnhancer, addToCartEnhancer)(AddToCart); -export { AddToCart }; +export default AddToCart; diff --git a/frontend/components/Cart.js b/frontend/components/Cart.js index 26a11d4..fee757e 100644 --- a/frontend/components/Cart.js +++ b/frontend/components/Cart.js @@ -1,12 +1,11 @@ import React from 'react'; -import { compose } from 'react-apollo'; +import { Query } from 'react-apollo'; import styled from 'styled-components'; -import PropTypes from 'prop-types'; -import { userEnhancer } from '../enhancers/enhancers'; import TakeMyMoney from './TakeMyMoney'; import formatMoney from '../lib/formatMoney'; import { UIContext } from './UIContext'; import CartItem from './CartItem'; +import { CURRENT_USER_QUERY } from '../queries/index'; const CartStyles = styled.div` padding: 20px; @@ -73,43 +72,42 @@ const CloseButton = styled.button` right: 0; `; -const Cart = props => { - const { me } = props.currentUser; - if (!me) return null; - const itemCount = me.cart.length; - const totalPrice = me.cart.reduce((tally, cartItem) => tally + cartItem.quantity * cartItem.item.price, 0); +function calcTotalPrice(cart) { + return cart.reduce((tally, cartItem) => tally + cartItem.quantity * cartItem.item.price, 0); +} - return ( - - {context => ( - -
- - × - +const Cart = props => ( + + {context => ( + + {({ data: { me }, error, loading }) => { + if (loading || error || !me) return null; + return ( + +
+ + × + - {me.name}'s Cart. -

- You have {itemCount} item{itemCount === 1 ? '' : 's'} in your cart. -

-
+ {me.name}'s Cart. +

+ You have {me.cart.length} item{me.cart.length === 1 ? '' : 's'} in your cart. +

+
- {me.cart.map(cartItem => )} -
-

{formatMoney(totalPrice)}

- - - -
-
- )} -
- ); -}; + {me.cart.map(cartItem => )} + + + ); + }} + + )} + +); -Cart.propTypes = { - currentUser: PropTypes.object.isRequired, -}; - -export default compose(userEnhancer)(Cart); -export { Cart }; +export default Cart; diff --git a/frontend/components/CartCount.js b/frontend/components/CartCount.js index 7949307..245b07b 100644 --- a/frontend/components/CartCount.js +++ b/frontend/components/CartCount.js @@ -50,4 +50,3 @@ const CartCount = ({ count }) => ( ); export default CartCount; -export { CartCount }; diff --git a/frontend/components/CreateItem.js b/frontend/components/CreateItem.js index 74a6cee..d166c81 100644 --- a/frontend/components/CreateItem.js +++ b/frontend/components/CreateItem.js @@ -1,36 +1,24 @@ import React, { Component } from 'react'; -import { graphql, gql } from 'react-apollo'; +import { Mutation } from 'react-apollo'; import { CREATE_ITEM_MUTATION } from '../queries'; -import ErrorMessage from './ErrorMessage'; +import Error from './ErrorMessage'; import Form from './styles/Form'; import PropTypes from 'prop-types'; +import Router from 'next/router'; class CreateItem extends Component { - static propTypes = { - createItemMutation: PropTypes.func.isRequired, - }; - state = { - item: { - title: '', - description: '', - image: '', - largeImage: '', - price: 0, - }, - loading: false, - error: { - message: null, - }, + title: '', + description: '', + image: '', + largeImage: '', + price: 0, }; handleChange = e => { const { name, value, type } = e.target; - const updatedItem = { - ...this.state.item, - [name]: type === 'number' ? parseFloat(value) : value, - }; - this.setState({ item: updatedItem }); + const val = type === 'number' ? parseFloat(value) : value; + this.setState({ [name]: val }); }; uploadFile = async e => { @@ -46,81 +34,73 @@ class CreateItem extends Component { body: data, }); const file = await res.json(); - this.setState({ image: file.secure_url, largeImage: file.eager[0].secure_url, loading: false }); - }; - - createItem = async e => { - e.preventDefault(); - // TODO: handle any errors - // turn loading on - this.setState({ loading: true }); - try { - const res = await this.props.createItemMutation({ - // pass in those variables from state - variables: { - ...this.state.item, - }, - }); - } catch (error) { - this.setState({ error }); - } - this.setState({ loading: false }); + this.setState({ + image: file.secure_url, + largeImage: file.eager[0].secure_url, + loading: false, + }); }; render() { return ( -
-
- {this.state.loading ? 'LOADING...' : null} - this.setState({ error: {} })} /> -

- Image - - {this.state.image ? {this.state.title} : null} -

-

- Title - -

- -