From d22616d5a675f5a381c741784333151255713b45 Mon Sep 17 00:00:00 2001 From: Wes Bos Date: Fri, 6 Apr 2018 16:44:50 -0400 Subject: local data with apollo --- backend/src/resolvers/Query.js | 6 ++-- frontend/components/Cart.js | 65 ++++++++++++++++++++------------------ frontend/components/Nav.js | 24 +++++++++++--- frontend/components/Order.js | 1 - frontend/components/Page.js | 33 +++++++++++-------- frontend/components/TakeMyMoney.js | 5 ++- frontend/components/UIContext.js | 25 --------------- frontend/lib/withData.js | 17 +++++++++- frontend/pages/orders.js | 5 ++- frontend/queries/index.js | 11 +++++++ 10 files changed, 113 insertions(+), 79 deletions(-) delete mode 100644 frontend/components/UIContext.js diff --git a/backend/src/resolvers/Query.js b/backend/src/resolvers/Query.js index a34b484..22dcd2a 100644 --- a/backend/src/resolvers/Query.js +++ b/backend/src/resolvers/Query.js @@ -24,8 +24,10 @@ const Query = { }, async orders(parent, args, ctx, info) { - const userId = getUserId(ctx); - console.log(info); + const { userId } = ctx.request; + if (!userId) { + throw new Error('You must be signed in to see your orders'); + } return ctx.db.query.orders( { where: { diff --git a/frontend/components/Cart.js b/frontend/components/Cart.js index 0a77754..7dbea8f 100644 --- a/frontend/components/Cart.js +++ b/frontend/components/Cart.js @@ -1,11 +1,10 @@ import React from 'react'; -import { Query } from 'react-apollo'; +import { Mutation, Query } from 'react-apollo'; import styled from 'styled-components'; import TakeMyMoney from './TakeMyMoney'; import formatMoney from '../lib/formatMoney'; -import { UIContext } from './UIContext'; import CartItem from './CartItem'; -import { CURRENT_USER_QUERY } from '../queries/index'; +import { CURRENT_USER_QUERY, LOCAL_STATE_QUERY, TOGGLE_CART_MUTATION } from '../queries/index'; import calcTotalPrice from '../lib/calcTotalPrice'; const CartStyles = styled.div` @@ -74,37 +73,43 @@ const CloseButton = styled.button` `; const Cart = props => ( - - {context => ( - - {({ data: { me }, error, loading }) => { - if (loading || error || !me) return null; - return ( - -
- - × - + + {toggle => ( + + {({ data }) => ( + + {({ data: { me }, error, loading }) => { + if (loading || error || !me) return null; + return ( + +
+ + × + - {me.name}'s Cart. -

- You have {me.cart.length} item{me.cart.length === 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(calcTotalPrice(me.cart))}

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

{formatMoney(calcTotalPrice(me.cart))}

+ + + +
+ + ); + }} +
+ )} )} -
+ ); export default Cart; diff --git a/frontend/components/Nav.js b/frontend/components/Nav.js index 80f91c6..eea29cb 100644 --- a/frontend/components/Nav.js +++ b/frontend/components/Nav.js @@ -2,10 +2,10 @@ import React, { Fragment } from 'react'; import Link from 'next/link'; import styled from 'styled-components'; import { Query } from 'react-apollo'; -import { CURRENT_USER_QUERY } from '../queries/index'; +import { CURRENT_USER_QUERY, LOCAL_STATE_QUERY } from '../queries/index'; import CartCount from './CartCount'; import Signout from './Signout'; -import { UIContext } from './UIContext'; +import { ApolloConsumer } from 'react-apollo'; const StyledUl = styled.ul` margin: 0; @@ -69,10 +69,13 @@ const StyledUl = styled.ul` `; class Nav extends React.Component { + componentDidMount() { + console.log('NAV MOUNTED'); + } render() { return ( - {({ data: { me } }) => ( + {({ data: { me }, refetch }) => ( Shop @@ -96,7 +99,7 @@ class Nav extends React.Component { My Account - + {/* {context => ( )} - + */} + + {cache => ( + + )} + )} diff --git a/frontend/components/Order.js b/frontend/components/Order.js index 603aae5..b38254f 100644 --- a/frontend/components/Order.js +++ b/frontend/components/Order.js @@ -60,7 +60,6 @@ class Order extends Component { Sick Fits - Order {order.id} -

Order Id: {order.id} diff --git a/frontend/components/Page.js b/frontend/components/Page.js index 031536b..3c6e3b1 100644 --- a/frontend/components/Page.js +++ b/frontend/components/Page.js @@ -3,8 +3,8 @@ import styled, { ThemeProvider, injectGlobal } from 'styled-components'; import PropTypes from 'prop-types'; import Header from './Header'; import Meta from './Meta'; -import { UIProvider } from './UIContext'; -// Global Style +import { client } from '../lib/withData'; +import { CURRENT_USER_QUERY } from '../queries'; const theme = { red: '#FF0000', @@ -50,17 +50,24 @@ const StyledPage = styled.div` background: white; `; -const Page = ({ children }) => ( - - - - -

- {children} - - - -); +class Page extends React.Component { + componentDidMount() { + // console.log('ComponentDidMount'); + // When the page loads, re-refetch the current user query + // client.query({ query: CURRENT_USER_QUERY, fetchPolicy: 'network-only' }); + } + render() { + return ( + + + +
+ {this.props.children} + + + ); + } +} Page.propTypes = { children: PropTypes.node.isRequired, }; diff --git a/frontend/components/TakeMyMoney.js b/frontend/components/TakeMyMoney.js index 6adf866..593c610 100644 --- a/frontend/components/TakeMyMoney.js +++ b/frontend/components/TakeMyMoney.js @@ -32,7 +32,10 @@ class TakeMyMoney extends Component { {({ data: { me } }) => { if (!me || !me.cart.length) return null; return ( - + {createOrder => ( this.setState({ isCartOpen: !this.state.isCartOpen }), - }} - > - {this.props.children} - - ); - } -} - -export { UIContext, UIProvider }; diff --git a/frontend/lib/withData.js b/frontend/lib/withData.js index c823e62..93a0db1 100644 --- a/frontend/lib/withData.js +++ b/frontend/lib/withData.js @@ -1,6 +1,6 @@ import withApollo from 'next-with-apollo'; import ApolloClient from 'apollo-boost'; - +import { LOCAL_STATE_QUERY } from '../queries/index'; // can also be a function that accepts a `headers` object (SSR only) and returns a config const client = new ApolloClient({ @@ -16,6 +16,21 @@ const client = new ApolloClient({ }); } }, + clientState: { + resolvers: { + Mutation: { + toggleCart(_, variables, { cache }) { + const { cartOpen } = cache.read({ query: LOCAL_STATE_QUERY }); + const data = { data: { cartOpen: !cartOpen } }; + cache.writeData(data); + return data; + }, + }, + }, + defaults: { + cartOpen: false, + }, + }, }); export { client }; diff --git a/frontend/pages/orders.js b/frontend/pages/orders.js index cc5ff36..772bb74 100644 --- a/frontend/pages/orders.js +++ b/frontend/pages/orders.js @@ -2,12 +2,15 @@ import { Component } from 'react'; import withData from '../lib/withData'; import Page from '../components/Page'; import OrderList from '../components/OrderList'; +import PleaseSignIn from '../components/PleaseSignIn'; class Orders extends Component { render() { return ( - + + + ); } diff --git a/frontend/queries/index.js b/frontend/queries/index.js index 15eaf49..5e9e28b 100644 --- a/frontend/queries/index.js +++ b/frontend/queries/index.js @@ -259,3 +259,14 @@ export const UPDATE_PERMISSIONS_MUTATION = gql` } } `; + +export const LOCAL_STATE_QUERY = gql` + { + cartOpen @client + } +`; +export const TOGGLE_CART_MUTATION = gql` + mutation toggleCart { + toggleCart @client + } +`; -- cgit v1.3