diff options
Diffstat (limited to 'frontend')
| -rw-r--r-- | frontend/components/AddToCart.js | 56 | ||||
| -rw-r--r-- | frontend/components/Cart.js | 42 | ||||
| -rw-r--r-- | frontend/components/CartList.js | 2 | ||||
| -rw-r--r-- | frontend/components/Header.js | 2 | ||||
| -rw-r--r-- | frontend/components/Item.js | 2 | ||||
| -rw-r--r-- | frontend/components/RemoveFromCart.js | 25 | ||||
| -rw-r--r-- | frontend/components/Reset.js | 87 | ||||
| -rw-r--r-- | frontend/components/Signin.js | 2 | ||||
| -rw-r--r-- | frontend/components/Signup.js | 2 | ||||
| -rw-r--r-- | frontend/enhancers.js | 18 | ||||
| -rw-r--r-- | frontend/enhancers/enhancers.js | 32 | ||||
| -rw-r--r-- | frontend/lib/initApollo.js | 1 | ||||
| -rw-r--r-- | frontend/package.json | 3 | ||||
| -rw-r--r-- | frontend/pages/reset.js | 12 | ||||
| -rw-r--r-- | frontend/pages/signup.js | 2 | ||||
| -rw-r--r-- | frontend/queries/index.js | 41 |
16 files changed, 230 insertions, 99 deletions
diff --git a/frontend/components/AddToCart.js b/frontend/components/AddToCart.js index e46a1f5..4522137 100644 --- a/frontend/components/AddToCart.js +++ b/frontend/components/AddToCart.js @@ -1,11 +1,13 @@ import { Component } from 'react'; -import { ADD_TO_CART_MUTATION, CURRENT_USER_QUERY, SINGLE_ITEM_QUERY } from '../queries'; -import { removeFromCartEnhancer, userEnhancer } from '../enhancers'; import { graphql, compose } from 'react-apollo'; import Transition from 'react-transition-group/Transition'; -import makeImage from '../lib/image'; import styled from 'styled-components'; import PropTypes from 'prop-types'; +import { CURRENT_USER_QUERY, SINGLE_ITEM_QUERY } from '../queries'; +import { removeFromCartEnhancer, userEnhancer, addtoCartEnhancer } from '../enhancers/enhancers'; + +console.log(addtoCartEnhancer); +import makeImage from '../lib/image'; const JumpImg = styled.img` border: 0 solid black; @@ -36,59 +38,29 @@ const JumpImg = styled.img` class AddToCart extends Component { static propTypes = { - currentUserQuery: PropTypes.object, + currentUser: PropTypes.object, }; componentDidMount() { - this.props.currentUserQuery.refetch(); + this.props.currentUser.refetch(); } - addToCart = async () => { + handleAddToCart = async () => { + console.log(`Gonna add this item to the cart! ${this.props.id}`); const res = await this.props.addToCart({ variables: { - userId: this.props.currentUserQuery.user.id, - itemId: this.props.id, - }, - }); - this.props.currentUserQuery.refetch(); - console.log(res); - }; - - removeFromCart = async () => { - const res = await this.props.removeFromCart({ - variables: { - userId: this.props.currentUserQuery.user.id, - itemId: this.props.id, + id: this.props.id, }, }); - this.props.currentUserQuery.refetch(); - console.log(res); + console.log({ realResponse: res }); + this.props.currentUser.refetch(); }; render() { - const user = this.props.currentUserQuery.user; - // TODO WTF - if (!user || this.props.singleItemQuery.loading || !this.props.singleItemQuery.Item) return <p>Loading...</p>; - const cartIds = user.cart.map(item => item.id); - const image = this.props.singleItemQuery.Item.image || {}; - const isInCart = cartIds.includes(this.props.id); - const { x, y } = document.querySelector('.cart').getBoundingClientRect(); - return ( - <div> - {isInCart ? ( - <button onClick={this.removeFromCart}>❌ Remove From Cart</button> - ) : ( - <button onClick={this.addToCart}>Add To Cart 👜</button> - )} - <Transition in={isInCart} timeout={1000}> - {status => <JumpImg x={x} y={y} src={makeImage(image)} className={`jump-${status}`} />} - </Transition> - </div> - ); + return <button onClick={this.handleAddToCart}>🛒 Add To Cart</button>; } } -const createOrderEnhancer = graphql(ADD_TO_CART_MUTATION, { name: 'addToCart' }); const singleItemEnhancer = graphql(SINGLE_ITEM_QUERY, { name: 'singleItemQuery', options: ({ id }) => ({ @@ -97,4 +69,4 @@ const singleItemEnhancer = graphql(SINGLE_ITEM_QUERY, { }, }), }); -export default compose(userEnhancer, createOrderEnhancer, removeFromCartEnhancer, singleItemEnhancer)(AddToCart); +export default compose(userEnhancer, addtoCartEnhancer, removeFromCartEnhancer, singleItemEnhancer)(AddToCart); diff --git a/frontend/components/Cart.js b/frontend/components/Cart.js index 88b072c..4153600 100644 --- a/frontend/components/Cart.js +++ b/frontend/components/Cart.js @@ -2,8 +2,7 @@ import { Component } from 'react'; import { graphql, compose } from 'react-apollo'; import styled from 'styled-components'; import { CURRENT_USER_QUERY } from '../queries'; -import formatMoney from '../lib/formatMoney.js'; -import ChaChing from './ChaChing'; +import RemoveFromCart from './RemoveFromCart'; const CartStyles = styled.div` background: white; @@ -16,31 +15,44 @@ const CartStyles = styled.div` class Cart extends Component { componentDidMount() { - // This fetches the new data, but doesn't populate the user via props - // this.props.currentUserQuery.refetch(); - // This fetches the new data, and populates the user via props - setTimeout(this.props.currentUserQuery.refetch, 1); + console.log('refetching..'); + setTimeout(this.props.currentUser.refetch, 10); } - render() { + if (!this.props.currentUser.me) { + return null; + } // Check for loading state.. - const { loading, error } = this.props.currentUserQuery; - const { user } = this.props.currentUserQuery; - if (loading || error || !user) return <p>Cart Loading...</p>; - const total = user.cart.reduce((a, b) => a + b.price, 0); + // const { loading, error } = this.props.currentUserQuery; + // const { user } = this.props.currentUserQuery; + // if (loading || error || !user) return <p>Cart Loading...</p>; + // const total = user.cart.reduce((a, b) => a + b.price, 0); + const { me } = this.props.currentUser; + console.log(me); return ( <CartStyles className="cart"> - There + <p>🛒: {me.cart.length} Items</p> + <ul> + {me.cart.map(cartItem => ( + <li key={cartItem.id}> + <strong> + {cartItem.quantity} of {cartItem.item.title} + </strong> + <RemoveFromCart id={cartItem.id} /> + </li> + ))} + </ul> + {/* There {user.cart.length === 1 ? ' is ' : 'are '} <ChaChing amount={user.cart.length} /> {user.cart.length === 1 ? ' item ' : ' items '} - in your cart totaling - <ChaChing amount={formatMoney(total)} /> + in your cart totaling */} + {/* <ChaChing amount={formatMoney(total)} /> */} </CartStyles> ); } } -const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUserQuery' }); +const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUser' }); export default compose(userEnhancer)(Cart); diff --git a/frontend/components/CartList.js b/frontend/components/CartList.js index b54aa39..661d5ad 100644 --- a/frontend/components/CartList.js +++ b/frontend/components/CartList.js @@ -12,7 +12,7 @@ import styled from 'styled-components'; import formatMoney from '../lib/formatMoney'; import makeImage from '../lib/image'; import TakeMyMoney from './TakeMyMoney'; -import { removeFromCartEnhancer } from '../enhancers'; +import { removeFromCartEnhancer } from '../enhancers/enhancers'; import { CURRENT_USER_QUERY } from '../queries'; import PropTypes from 'prop-types'; diff --git a/frontend/components/Header.js b/frontend/components/Header.js index 5e1a620..774bd0b 100644 --- a/frontend/components/Header.js +++ b/frontend/components/Header.js @@ -28,7 +28,7 @@ class Header extends Component { <div> {this.props.currentUser.me ? this.props.currentUser.me.email : 'Not Signed in'} <Signout /> - {/* <Cart /> */} + <Cart /> {/* <Search /> */} </div> ); diff --git a/frontend/components/Item.js b/frontend/components/Item.js index d19af0e..2a0fc69 100644 --- a/frontend/components/Item.js +++ b/frontend/components/Item.js @@ -59,7 +59,7 @@ class ItemComponent extends React.Component { <button>Buy for {formatMoney(item.price)}</button> </TakeMyMoney> - {/* <AddToCart id={item.id} /> */} + <AddToCart id={item.id} /> <button onClick={this.removeItem}>× Delete item</button> </Item> ); diff --git a/frontend/components/RemoveFromCart.js b/frontend/components/RemoveFromCart.js new file mode 100644 index 0000000..e3eb919 --- /dev/null +++ b/frontend/components/RemoveFromCart.js @@ -0,0 +1,25 @@ +import { Component } from 'react'; +import { graphql, compose } from 'react-apollo'; +import Transition from 'react-transition-group/Transition'; +import styled from 'styled-components'; +import PropTypes from 'prop-types'; +import { removeFromCartEnhancer } from '../enhancers/enhancers'; + +class RemoveFromCart extends Component { + handleRemoveFromCart = async () => { + console.log(`gonna remove item from cart`); + const res = await this.props.removeFromCart({ + variables: { + id: this.props.id, + }, + }); + console.log('This came back from removeFromCart:', res); + // this.props.currentUserQuery.refetch(); + }; + + render() { + return <button onClick={this.handleRemoveFromCart}>× Remove</button>; + } +} + +export default compose(removeFromCartEnhancer)(RemoveFromCart); diff --git a/frontend/components/Reset.js b/frontend/components/Reset.js new file mode 100644 index 0000000..7d36de7 --- /dev/null +++ b/frontend/components/Reset.js @@ -0,0 +1,87 @@ +import React, { Component } from 'react'; +import { graphql, compose } from 'react-apollo'; +import { RESET_MUTATION, CURRENT_USER_QUERY } from '../queries'; + +class Reset extends Component { + state = { + confirmPassword: '', + password: '', + errors: [], + }; + + saveToState = e => { + const { name, value } = e.target; + this.setState({ [name]: value }); + }; + + resetPassword = async e => { + console.log(e); + e.preventDefault(); + + if (this.state.password !== this.state.confirmPassword) { + this.setState({ errors: [{ message: 'Passwords Must Match!' }] }); + } + + const res = await this.props.resetPassword({ + variables: { + resetToken: this.props.resetToken, + password: this.state.password, + confirmPassword: this.state.confirmPassword, + }, + }); + + if (res.errors) { + this.setState({ errors: res.errors }); + return; + } + console.log('Back!'); + console.log(res); + // sign them in! + localStorage.setItem('token', res.data.resetPassword.token); + // refresh the current user query + this.props.currentUser.refetch(); + }; + + render() { + return ( + <div> + {this.state.loading ? 'LOADING...' : 'Ready!'} + + {this.state.errors ? this.state.errors.map((err, i) => <p key={i}>{err.message}</p>) : null} + + <form onSubmit={this.resetPassword}> + <label htmlFor="password"> + password + <input + value={this.state.password} + onChange={this.saveToState} + name="password" + type="password" + id="password" + /> + </label> + <label htmlFor="confirm"> + Confirm: + <input + value={this.state.confirmPassword} + onChange={this.saveToState} + name="confirmPassword" + type="password" + id="confirmPassword" + /> + </label> + + <button type="submit">Request Reset!</button> + </form> + </div> + ); + } +} + +// 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. + +const restEnahncer = graphql(RESET_MUTATION, { name: 'resetPassword' }); +const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUser' }); + +export default compose(restEnahncer, userEnhancer)(Reset); diff --git a/frontend/components/Signin.js b/frontend/components/Signin.js index aac1222..752199b 100644 --- a/frontend/components/Signin.js +++ b/frontend/components/Signin.js @@ -37,7 +37,7 @@ class Signin extends Component { render() { return ( <div> - {this.state.loading ? 'LOADING...' : 'Ready!'} + {this.state.loading ? 'LOADING...' : null} {this.state.errors ? this.state.errors.map(err => <p>{err.message}</p>) : null} diff --git a/frontend/components/Signup.js b/frontend/components/Signup.js index 746f1e4..e9d6737 100644 --- a/frontend/components/Signup.js +++ b/frontend/components/Signup.js @@ -42,7 +42,7 @@ class Signup extends Component { render() { return ( <div> - {this.state.loading ? 'LOADING...' : 'Ready!'} + {this.state.loading ? 'LOADING...' : null} {this.state.error ? <p>{this.state.error.message}</p> : null} diff --git a/frontend/enhancers.js b/frontend/enhancers.js deleted file mode 100644 index d86ca6d..0000000 --- a/frontend/enhancers.js +++ /dev/null @@ -1,18 +0,0 @@ -import { REMOVE_FROM_CART_MUTATION, CURRENT_USER_QUERY } from './queries'; - -import { graphql } from 'react-apollo'; - -export const removeFromCartEnhancer = graphql(REMOVE_FROM_CART_MUTATION, { - name: 'removeFromCart', - options: { - update: (proxy, payload) => { - const data = proxy.readQuery({ query: CURRENT_USER_QUERY }); - const cartItemId = payload.data.removeFromCartItems.cartItem.id; - data.user.cart = data.user.cart.filter(item => item.id !== cartItemId); - proxy.writeQuery({ query: CURRENT_USER_QUERY, data }); - }, - }, -}); - -// Current User Query -export const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUserQuery' }); diff --git a/frontend/enhancers/enhancers.js b/frontend/enhancers/enhancers.js index ff1712f..f7021c3 100644 --- a/frontend/enhancers/enhancers.js +++ b/frontend/enhancers/enhancers.js @@ -1,5 +1,12 @@ -import { ALL_ITEMS_QUERY, REMOVE_ITEM_MUTATION, SINGLE_ITEM_QUERY } from '../queries/index'; import { graphql } from 'react-apollo'; +import { + REMOVE_FROM_CART_MUTATION, + ALL_ITEMS_QUERY, + REMOVE_ITEM_MUTATION, + SINGLE_ITEM_QUERY, + CURRENT_USER_QUERY, + ADD_TO_CART_MUTATION, +} from '../queries/index'; export const itemEnhancer = graphql(ALL_ITEMS_QUERY, { name: 'itemsQuery', @@ -35,3 +42,26 @@ export const singleItemEnhancer = graphql(SINGLE_ITEM_QUERY, { variables: { id }, }), }); + +export const removeFromCartEnhancer = graphql(REMOVE_FROM_CART_MUTATION, { + name: 'removeFromCart', + options: { + update: (proxy, payload) => { + const data = proxy.readQuery({ query: CURRENT_USER_QUERY }); + const cartItemId = payload.data.removeFromCart.id; + data.me.cart = data.me.cart.filter(item => item.id !== cartItemId); + proxy.writeQuery({ query: CURRENT_USER_QUERY, data }); + }, + }, +}); + +export const addtoCartEnhancer = graphql(ADD_TO_CART_MUTATION, { + name: 'addToCart', + options: { + update: (proxy, payload) => { + console.log('=----asdf-asd-fas-df-asdf-sa-df'); + }, + }, +}); + +export const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUser' }); diff --git a/frontend/lib/initApollo.js b/frontend/lib/initApollo.js index 7252a00..d0f1351 100644 --- a/frontend/lib/initApollo.js +++ b/frontend/lib/initApollo.js @@ -33,7 +33,6 @@ function create(initialState) { if (typeof localStorage !== 'undefined' && localStorage.getItem('token')) { headers.authorization = `Bearer ${localStorage.getItem('token')}`; } - console.log({ headers }); operation.setContext({ headers }); return forward(operation); diff --git a/frontend/package.json b/frontend/package.json index 53e5f51..547a576 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -32,7 +32,6 @@ "micro-dev": "^2.2.0", "next": "^4.2.3", "next-routes": "^1.2.0", - "nodemailer": "^4.4.2", "nprogress": "^0.2.0", "prop-types": "^15.6.0", "react": "^16.2.0", @@ -48,4 +47,4 @@ "devDependencies": { "jest": "^22.1.4" } -} +}
\ No newline at end of file diff --git a/frontend/pages/reset.js b/frontend/pages/reset.js new file mode 100644 index 0000000..899ebbc --- /dev/null +++ b/frontend/pages/reset.js @@ -0,0 +1,12 @@ +import withData from '../lib/withData'; +import Page from '../components/Page'; +import Reset from '../components/Reset'; + +const ResetPage = props => ( + <Page> + <h2>So you wanna reset your password?</h2> + <Reset resetToken={props.url.query.resetToken} /> + </Page> +); + +export default withData(ResetPage); diff --git a/frontend/pages/signup.js b/frontend/pages/signup.js index 1ea3794..d3b98d7 100644 --- a/frontend/pages/signup.js +++ b/frontend/pages/signup.js @@ -9,7 +9,7 @@ const SignUpPage = () => ( <Page> <p>I'm the Sign Up url!</p> <Signup /> - {/* <Signin /> */} + <Signin /> <RequestReset /> </Page> ); diff --git a/frontend/queries/index.js b/frontend/queries/index.js index ea02c8b..e61a9d5 100644 --- a/frontend/queries/index.js +++ b/frontend/queries/index.js @@ -44,6 +44,19 @@ export const REQUEST_RESET_MUTATION = gql` } `; +export const RESET_MUTATION = gql` + mutation resetPassword($resetToken: String!, $password: String!, $confirmPassword: String!) { + resetPassword(resetToken: $resetToken, password: $password, confirmPassword: $confirmPassword) { + token + user { + id + email + name + } + } + } +`; + export const CREATE_ORDER_MUTATION = gql` mutation CreateOrderMutation($token: String!, $userId: ID!, $itemId: ID!) { createOrder(token: $token, userId: $userId, itemId: $itemId) { @@ -142,11 +155,19 @@ export const UPDATE_LINK_MUTATION = gql` `; export const CURRENT_USER_QUERY = gql` + ${itemDetails} query userQuery { me { id email name + cart { + id + quantity + item { + ...itemDetails + } + } } } `; @@ -176,25 +197,17 @@ export const USER_ORDERS_QUERY = gql` `; export const ADD_TO_CART_MUTATION = gql` - mutation AddToCart($userId: ID!, $itemId: ID!) { - addToCartItems(userUserId: $userId, cartItemId: $itemId) { - cartItem { - id - title - price - } + mutation addToCart($id: ID!) { + addToCart(id: $id) { + id } } `; export const REMOVE_FROM_CART_MUTATION = gql` - mutation xxx($userId: ID!, $itemId: ID!) { - removeFromCartItems(userUserId: $userId, cartItemId: $itemId) { - cartItem { - id - title - price - } + mutation removeFromCart($id: ID!) { + removeFromCart(id: $id) { + id } } `; |
