diff options
Diffstat (limited to 'components')
| -rw-r--r-- | components/AddToCart.js | 100 | ||||
| -rw-r--r-- | components/Cart.js | 46 | ||||
| -rw-r--r-- | components/CartList.js | 114 | ||||
| -rw-r--r-- | components/ChaChing.js | 56 | ||||
| -rw-r--r-- | components/Count.js | 37 | ||||
| -rw-r--r-- | components/CreateItem.js | 128 | ||||
| -rw-r--r-- | components/ErrorMessage.js | 32 | ||||
| -rw-r--r-- | components/Header.js | 42 | ||||
| -rw-r--r-- | components/Item.js | 61 | ||||
| -rw-r--r-- | components/Items.js | 97 | ||||
| -rw-r--r-- | components/LoginAuth0.js | 76 | ||||
| -rw-r--r-- | components/Meta.js | 24 | ||||
| -rw-r--r-- | components/Nav.js | 46 | ||||
| -rw-r--r-- | components/OrderList.js | 52 | ||||
| -rw-r--r-- | components/Page.js | 24 | ||||
| -rw-r--r-- | components/Pagination.js | 43 | ||||
| -rw-r--r-- | components/Search.js | 68 | ||||
| -rw-r--r-- | components/Signup.js | 94 | ||||
| -rw-r--r-- | components/SingleItem.js | 36 | ||||
| -rw-r--r-- | components/TakeMyMoney.js | 43 | ||||
| -rw-r--r-- | components/UpdateItem.js | 75 |
21 files changed, 0 insertions, 1294 deletions
diff --git a/components/AddToCart.js b/components/AddToCart.js deleted file mode 100644 index e46a1f5..0000000 --- a/components/AddToCart.js +++ /dev/null @@ -1,100 +0,0 @@ -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'; - -const JumpImg = styled.img` - border: 0 solid black; - max-width: 100px; - transition: all 0.5s; - position: fixed; - left: ${props => props.x}px; - top: -100%; - &.jump-entered { - border-color: green; - transform-origin: 0 0; - transform: scale(0); - top: ${props => props.y}px; - left: ${props => props.x}px; - } - &.jump-entering { - border-color: yellow; - top: ${props => props.y}px; - left: ${props => props.x}px; - } - &.jump-exited { - border-color: red; - } - &.jump-exiting { - border-color: yellow; - } -`; - -class AddToCart extends Component { - static propTypes = { - currentUserQuery: PropTypes.object, - }; - - componentDidMount() { - this.props.currentUserQuery.refetch(); - } - - addToCart = async () => { - 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, - }, - }); - this.props.currentUserQuery.refetch(); - console.log(res); - }; - - 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> - ); - } -} - -const createOrderEnhancer = graphql(ADD_TO_CART_MUTATION, { name: 'addToCart' }); -const singleItemEnhancer = graphql(SINGLE_ITEM_QUERY, { - name: 'singleItemQuery', - options: ({ id }) => ({ - variables: { - id, - }, - }), -}); -export default compose(userEnhancer, createOrderEnhancer, removeFromCartEnhancer, singleItemEnhancer)(AddToCart); diff --git a/components/Cart.js b/components/Cart.js deleted file mode 100644 index 88b072c..0000000 --- a/components/Cart.js +++ /dev/null @@ -1,46 +0,0 @@ -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'; - -const CartStyles = styled.div` - background: white; - border-radius: 10px; - padding: 20px; - overflow: hidden; - display: flex; - align-items: center; -`; - -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); - } - - render() { - // 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); - - return ( - <CartStyles className="cart"> - 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)} /> - </CartStyles> - ); - } -} - -const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUserQuery' }); -export default compose(userEnhancer)(Cart); diff --git a/components/CartList.js b/components/CartList.js deleted file mode 100644 index b54aa39..0000000 --- a/components/CartList.js +++ /dev/null @@ -1,114 +0,0 @@ -import { Component } from 'react'; -import withData from '../lib/withData'; -import Items from '../components/Items'; -import Signup from '../components/Signup'; -import LoginAuth0 from '../components/LoginAuth0'; -import Page from '../components/Page'; -import { USER_ORDERS_QUERY, GET_CART_STATE } from '../queries'; -import { graphql, compose } from 'react-apollo'; -import has from 'lodash.has'; -import get from 'lodash.get'; -import styled from 'styled-components'; -import formatMoney from '../lib/formatMoney'; -import makeImage from '../lib/image'; -import TakeMyMoney from './TakeMyMoney'; -import { removeFromCartEnhancer } from '../enhancers'; -import { CURRENT_USER_QUERY } from '../queries'; -import PropTypes from 'prop-types'; - -const CartStyles = styled.div` - padding: 20px; - position: relative; - background: white; - position: fixed; - height: 100%; - top: 0; - right: 0; - bottom: 0; - transform: translateX(100%); - transition: all 0.3s; - box-shadow: 0 0 10px 3px rgba(0, 0, 0, 0.2); - z-index: 5; - ${props => props.open && `transform: translateX(0);`}; - .toggleOpen { - position: absolute; - top: 0; - left: 0; - transform: translateX(-100%); - } -`; - -class CartList extends Component { - static contextTypes = { - client: PropTypes.object, - }; - - componentDidMount() { - setTimeout(this.props.currentUserQuery.refetch, 1); - // Set the cart state to be closed - this.context.client.writeQuery({ - query: GET_CART_STATE, - data: { ui: { isCartOpen: true, __typename: 'Network' } }, - }); - } - - toggleOpen = () => { - this.props.uiQuery.updateQuery(() => ({ ui: { isCartOpen: false, __typename: 'Network' } })); - }; - - render() { - if (this.props.loading) { - return <p>Loading....</p>; - } - - if (this.props.error) { - return <p>Error....</p>; - } - - // if (!has(this.props, 'currentUserQuery.user.cart')) { - // return <p>Don't have it yet!</p>; - // } - // OMG Clean this up - let { user = {} } = this.props.currentUserQuery || {}; - if (!user) user = {}; - const cart = user.cart || []; - const userId = user.id; - // const userId = this.props.currentUserQuery.user.id; - - const total = cart.reduce((a, b) => a + b.price, 0); - return ( - <CartStyles open> - <button className="toggleOpen" onClick={this.toggleOpen}> - Open Cart - </button> - <h1>{cart.length} Items</h1> - - <ul> - {cart.map(item => ( - <li key={item.id}> - {item.title} - <button - onClick={() => - this.props.removeFromCart({ - variables: { - userId, - itemId: item.id, - }, - })} - > - × Delete - </button> - </li> - ))} - </ul> - <TakeMyMoney amount={total} name="Testing 123" description="Test test 123"> - <button>Buy for {formatMoney(total)}</button> - </TakeMyMoney> - </CartStyles> - ); - } -} - -const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUserQuery' }); -const uiEnhancer = graphql(GET_CART_STATE, { name: 'uiQuery' }); -export default compose(userEnhancer, removeFromCartEnhancer, uiEnhancer)(CartList); diff --git a/components/ChaChing.js b/components/ChaChing.js deleted file mode 100644 index 5874c27..0000000 --- a/components/ChaChing.js +++ /dev/null @@ -1,56 +0,0 @@ -import TransitionGroup from 'react-transition-group/TransitionGroup'; -import Transition from 'react-transition-group/Transition'; -import styled from 'styled-components'; - -const CartCount = styled.div` - padding: 10px; - transition: all 0.5s; - display: inline-block; - background: white; - background: linear-gradient(to bottom, #eeeeee 0%, #eeeeee 100%); - transform: translateY(100%); - z-index: 1; - position: relative; - &.cart-entering { - background: green; - transform: translateY(100%); - } - &.cart-entered { - transform: translateY(0); - } - &.cart-exiting { - position: absolute; - z-index: 0; - left: 0; - transform: translateY(-100%); - } -`; - -const ChaChingStyles = styled.div` - position: relative; - display: inline-block; - overflow: hidden; -`; - -const ChaChing = ({ amount }) => ( - <ChaChingStyles> - <TransitionGroup> - <Transition - in - timeout={{ - enter: 0, - exit: 500, - }} - key={amount} - > - {status => ( - <CartCount className={`cart-${status}`} key={`count-${amount}`}> - {amount} - </CartCount> - )} - </Transition> - </TransitionGroup> - </ChaChingStyles> -); - -export default ChaChing; diff --git a/components/Count.js b/components/Count.js deleted file mode 100644 index 800a902..0000000 --- a/components/Count.js +++ /dev/null @@ -1,37 +0,0 @@ -import React, { Component } from 'react' -import { graphql, gql } from 'react-apollo' - -import { ALL_ITEMS_QUERY } from '../queries'; - -class Count extends Component { - - render() { - - // 1 - if (this.props.allLinksQuery && this.props.allLinksQuery.loading) { - return <div>Loading</div> - } - - // 2 - if (this.props.allLinksQuery && this.props.allLinksQuery.error) { - return <div>Error</div> - } - - // 3 - const itemsToRender = this.props.allLinksQuery.allItems - - return ( - <div> - <h1>There are {itemsToRender.length} items for sale</h1> - </div> - ) - } - -} - -// 1 - -// We export the graphQL HOC - this will fetch the data and inject it into the Count compeont via props - -export { ALL_ITEMS_QUERY } -export default graphql(ALL_ITEMS_QUERY, { name: 'allLinksQuery' }) (Count) diff --git a/components/CreateItem.js b/components/CreateItem.js deleted file mode 100644 index 27b62e5..0000000 --- a/components/CreateItem.js +++ /dev/null @@ -1,128 +0,0 @@ -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 makeImage from '../lib/image'; -import { fileEndpoint } from '../config'; - -class CreateLink extends Component { - state = { - description: '', - title: '', - image: '', - price: 0, - 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('data', files[0]); - - // use the file endpoint - const res = await fetch(fileEndpoint, { - method: 'POST', - body: data, - }); - const file = await res.json(); - this.setState({ image: file.id, loading: false }); - }; - - _createLink = async e => { - e.preventDefault(); - // pull the values from state - const { description, title, image, price, fullPrice } = this.state; - // create a mutation - // 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: { - description, - title, - price: parseInt(price), - fullPrice, - imageId: image, - }, - }); - } 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" /> - </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> - ); - } -} -// 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 } }) => { - 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); diff --git a/components/ErrorMessage.js b/components/ErrorMessage.js deleted file mode 100644 index 12de51d..0000000 --- a/components/ErrorMessage.js +++ /dev/null @@ -1,32 +0,0 @@ -import styled from 'styled-components'; -import React from 'react'; - -import PropTypes from 'prop-types'; - -const StyledError = styled.div` - background: pink; - border: 2px solid red; - padding: 20px; - display: flex; - p { - margin: 0; - flex: 1 0 auto; - } -`; - -const DisplayError = props => { - if (!props.error || !props.error.message) return null; - return ( - <StyledError> - <p>{props.error.message}</p> - <button onClick={props.onButtonClick}>×</button> - </StyledError> - ); -}; - -DisplayError.propTypes = { - error: PropTypes.object.isRequired, - onButtonClick: PropTypes.func.isRequired, -}; - -export default DisplayError; diff --git a/components/Header.js b/components/Header.js deleted file mode 100644 index cc4cca7..0000000 --- a/components/Header.js +++ /dev/null @@ -1,42 +0,0 @@ -import { Component } from 'react'; -import { graphql, compose } from 'react-apollo'; -import { CURRENT_USER_QUERY } from '../queries'; -import Cart from './Cart'; -import Login from './LoginAuth0'; -import Search from './Search'; -import NProgress from 'nprogress'; -import Router from 'next/router'; - -Router.onRouteChangeStart = url => { - console.log(`Loading: ${url}`); - NProgress.start(); -}; -Router.onRouteChangeComplete = () => NProgress.done(); -Router.onRouteChangeError = () => NProgress.done(); - -class Header 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); - } - - render() { - const user = this.props.currentUserQuery.user || {}; - const { email = '' } = user; - return ( - <div> - <p> - Signed in as <strong>{email}</strong> - </p> - <Login /> - <Cart /> - <Search /> - </div> - ); - } -} - -const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUserQuery' }); -export default compose(userEnhancer)(Header); diff --git a/components/Item.js b/components/Item.js deleted file mode 100644 index 1b47fcf..0000000 --- a/components/Item.js +++ /dev/null @@ -1,61 +0,0 @@ -import styled from 'styled-components'; -import slugify from 'slugify'; -import { Link } from '../routes'; -import AddToCart from './AddToCart'; -import makeImage from '../lib/image'; -import TakeMyMoney from './TakeMyMoney'; -import formatMoney from '../lib/formatMoney'; - -const Item = styled.div` - background: #f3f3f3; - padding: 5px; - img { - width: 100%; - } -`; - -const ItemComponent = ({ item }) => ( - <Item key={item.id}> - {item.image ? <img key={item.image.secret} src={makeImage(item.image)} alt={item.title} /> : null} - <h3> - <Link - route="item" - params={{ - slug: slugify(item.title), - itemId: item.id, - }} - > - <a>{item.title}</a> - </Link> - </h3> - - <p>{item.description}</p> - {/* { - - <Link - href={{ - pathname: '/admin/update', - query: { id: item.id }, - }} - > - <a>Edit βοΈ</a> - </Link> - - } */} - - <TakeMyMoney - id={item.id} - amount={item.price} - name={item.title} // the pop-in header title - description={item.description} // the pop-in header subtitle - image={makeImage(item.image)} - > - <button>Buy for {formatMoney(item.price)}</button> - </TakeMyMoney> - - <AddToCart id={item.id} /> - <button onClick={() => this.props.removeItemMutation({ variables: { id: item.id } })}>× Delete item</button> - </Item> -); - -export default ItemComponent; diff --git a/components/Items.js b/components/Items.js deleted file mode 100644 index 053c9af..0000000 --- a/components/Items.js +++ /dev/null @@ -1,97 +0,0 @@ -import { Component } from 'react'; -import { withApollo, graphql, compose } from 'react-apollo'; -import styled from 'styled-components'; -import Pagination from './Pagination'; -import Item from './Item'; - -import { ALL_ITEMS_QUERY, DELETE_ITEM_MUTATION } from '../queries'; - -const Title = styled.h1`font-size: 10px;`; - -const Items = styled.div` - display: grid; - grid-template-columns: repeat(4, calc(33% - 20px)); - grid-gap: 20px; -`; - -class ItemList extends Component { - componentDidMount() { - this.prefetchNextItems(this.props.page); - } - - componentWillReceiveProps(nextProps) { - // update the next items if the page prop changed - if (this.props.page !== nextProps.page) { - this.prefetchNextItems(nextProps.page); - } - } - - prefetchNextItems = currentPage => { - const page = currentPage + 1; - console.log(`Prefetching Next items! Page ${page}`); - this.props.client.query({ - query: ALL_ITEMS_QUERY, - variables: { - skip: page * 3 - 3, - }, - }); - }; - - render() { - // 1 - if (this.props.allItemsQuery && this.props.allItemsQuery.loading) { - return <div>Loading</div>; - } - - // 2 - if (this.props.allItemsQuery && this.props.allItemsQuery.error) { - console.log(this.props.allItemsQuery.error); - return <div>Error</div>; - } - - // 3 - const itemsToRender = this.props.allItemsQuery.allItems; - - return ( - <div> - <Pagination page={this.props.page} /> - <Title>Items For Sale</Title> - <Items key={this.props.page}>{itemsToRender.map((item, i) => <Item key={item.id} item={item} />)}</Items> - </div> - ); - } -} - -// 1 - -// We export the graphQL HOC - this will fetch the data and inject it into the ItemList compeont via props - -// Create some Enhancers -const itemEnhancer = graphql(ALL_ITEMS_QUERY, { - name: 'allItemsQuery', - options({ page }) { - return { - variables: { - skip: page * 3 - 3, - }, - }; - }, -}); - -const deleteItemEnhancer = graphql(DELETE_ITEM_MUTATION, { - name: 'removeItemMutation', - options: { - update: (proxy, { data: { deleteItem } }) => { - // grab the data from our cache - const data = proxy.readQuery({ query: ALL_ITEMS_QUERY }); - - // filter out the deleted item - data.allItems = data.allItems.filter(item => item.id !== deleteItem.id); - - // and then "set state" (update cache), so it will update wherever we have used this data on the page - proxy.writeQuery({ query: ALL_ITEMS_QUERY, data }); - }, - }, -}); - -export default withApollo(compose(itemEnhancer, deleteItemEnhancer)(ItemList)); diff --git a/components/LoginAuth0.js b/components/LoginAuth0.js deleted file mode 100644 index b55ae4a..0000000 --- a/components/LoginAuth0.js +++ /dev/null @@ -1,76 +0,0 @@ -import { Component, PropTypes } from 'react'; -import Auth0Lock from 'auth0-lock'; -import { graphql, compose } from 'react-apollo'; -import { CURRENT_USER_QUERY } from '../queries/index'; - -class LoginAuth0 extends Component { - constructor(props) { - super(props); - if (typeof window === 'undefined') return; - const redirectUrl = `http://localhost:3000/signup`; - this._lock = new Auth0Lock('r6D64Waoq7roAnv8GT04dnn1tpq9PAqu', 'wesbos.auth0.com', { - auth: { - redirect: false, - }, - }); - } - - componentDidMount() { - this._lock.on('authenticated', authResult => { - console.log(authResult); - window.localStorage.setItem('auth0IdToken', authResult.idToken); - console.log('Im baaaack!'); - this.props.currentUserQuery.refetch(); - }); - - this._lock.on('authorization_error', err => { - console.error(err); - }); - - // refech on page load because of the server render - this.props.currentUserQuery.refetch(); - } - - logout = () => { - window.localStorage.removeItem('auth0IdToken'); - this.props.currentUserQuery.refetch(); - }; - - createUser = async () => { - const variables = { - idToken: window.localStorage.getItem('auth0IdToken'), - emailAddress: 'wesbos@gmail.com', - name: 'Hardcoded Wes', - }; - // TODO - make a createUser function - this.props - .createUser({ variables }) - .then(response => { - // this.props.currentUserQuery.refetch(); - this.props.history.replace('/'); - }) - .catch(e => { - console.error(e); - this.props.history.replace('/'); - }); - }; - - _showLogin = () => { - this._lock.show(); - }; - - render() { - const { user } = this.props.currentUserQuery; - if (user) { - return <button onClick={this.logout}>Log out π</button>; - } - return ( - <div> - <button onClick={this._showLogin}>Log in with Auth0 </button> - </div> - ); - } -} - -const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUserQuery' }); -export default compose(userEnhancer)(LoginAuth0); diff --git a/components/Meta.js b/components/Meta.js deleted file mode 100644 index d7a2e17..0000000 --- a/components/Meta.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import Head from 'next/head'; -import { injectGlobal } from 'styled-components'; - -const Meta = () => ( - <div> - <Head> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - {injectGlobal` - html { - background: white; - } - `} - <meta charSet="utf-8" /> - <link rel="shortcut icon" href="https://wesbos.com/wp-content/themes/wb2014/i/crown-yellow-small.png" /> - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" /> - <link rel="stylesheet" type="text/css" href="/static/nprogress.css" /> - - <title>Sick Fits</title> - </Head> - </div> -); - -export default Meta; diff --git a/components/Nav.js b/components/Nav.js deleted file mode 100644 index d1f341d..0000000 --- a/components/Nav.js +++ /dev/null @@ -1,46 +0,0 @@ -import Link from 'next/link'; -import styled from 'styled-components'; - -const StyledUl = styled.ul` - margin: 0; - padding: 0; - display: flex; - li { - display: flex; - flex: 1; - } - a { - padding: 10px; - flex: 1; - text-decoration: none; - text-align: center; - background: rgba(0, 0, 0, 0.2); - color: white; - margin-right: 20px; - &:hover { - background: rgba(0, 0, 0, 0.3); - } - } -`; - -const Nav = () => ( - <StyledUl> - <Link prefetch href="/"> - <a>Home</a> - </Link> - <Link prefetch href="/signup"> - <a>Sign Up</a> - </Link> - <Link prefetch href="/add"> - <a>Add an Item</a> - </Link> - <Link prefetch href="/orders"> - <a>Orders</a> - </Link> - <Link prefetch href="/cart"> - <a>My Cart</a> - </Link> - </StyledUl> -); - -export default Nav; diff --git a/components/OrderList.js b/components/OrderList.js deleted file mode 100644 index c33f0b9..0000000 --- a/components/OrderList.js +++ /dev/null @@ -1,52 +0,0 @@ -import { Component } from 'react'; -import withData from '../lib/withData'; -import Items from '../components/Items'; -import CreateItem from '../components/CreateItem'; -import Signup from '../components/Signup'; -import LoginAuth0 from '../components/LoginAuth0'; -import Page from '../components/Page'; -import { USER_ORDERS_QUERY } from '../queries'; -import { graphql, compose } from 'react-apollo' -import has from 'lodash.has'; -import get from 'lodash.get'; -import formatMoney from '../lib/formatMoney'; -import makeImage from '../lib/image'; - -class OrderList extends Component { - componentDidMount() { - console.log('Mounting!'); - } - render() { - - if(this.props.loading) { - return <p>Loading...</p> - } - - if(this.props.error) { - return <p>Error...</p> - } - - if(!has(this.props, 'userOrdersQuery.user.orders')) { - return <p>Don't have it yet!</p> - } - - const orders = this.props.userOrdersQuery.user.orders; - - console.log(orders); - return ( - <div> - <h2>You have {orders.length} Orders</h2> - <ul> - {orders.map(order => <li key={order.id}> - <img src={makeImage(order.item.image)} alt=""/> - <h3>{order.item.title} ({formatMoney(order.amount)}) </h3> - <p>{order.item.description}</p> - </li>)} - </ul> - </div> - ) - } -} - -const ordersEnhancer = graphql(USER_ORDERS_QUERY, { name: 'userOrdersQuery' }); -export default compose(ordersEnhancer)(OrderList) diff --git a/components/Page.js b/components/Page.js deleted file mode 100644 index f45d421..0000000 --- a/components/Page.js +++ /dev/null @@ -1,24 +0,0 @@ -import styled from 'styled-components'; -import Header from './Header'; -import Meta from './Meta'; -import Nav from './Nav'; -import CartList from './CartList'; - -const StyledPage = styled.div` - font-family: sans-serif; - color: #303030; - background: #efc600; - padding: 100px; -`; - -const Page = ({ children }) => ( - <StyledPage className="main"> - <Meta /> - <Nav /> - <Header /> - <CartList /> - {children} - </StyledPage> -); - -export default Page; diff --git a/components/Pagination.js b/components/Pagination.js deleted file mode 100644 index dedd231..0000000 --- a/components/Pagination.js +++ /dev/null @@ -1,43 +0,0 @@ -import React, { Component } from 'react'; -import { graphql, gql, compose } from 'react-apollo'; -import { ALL_ITEMS_QUERY } from '../queries'; -import withData from '../lib/withData'; -import { Link } from '../routes'; - -const Pagination = props => { - const { loading, error } = props.allItemsQuery; - - if (loading) return <p>Loading Item...</p>; - - const meta = props.allItemsQuery._allItemsMeta; - const { page } = props; - const pages = Math.floor(meta.count / 3); - return ( - <div> - <p> - Page <strong>{page} </strong> - of - <strong>{pages} </strong> - - - <strong>{meta.count} </strong> - total - </p> - - {page > 1 ? ( - <Link prefetch route="items" params={{ page: page - 1 }}> - <a>βPrev</a> - </Link> - ) : null} - - {page < pages ? ( - <Link prefetch route="items" params={{ page: page + 1 }}> - <a>Next β</a> - </Link> - ) : null} - </div> - ); -}; - -const ComponentWithMutations = compose(graphql(ALL_ITEMS_QUERY, { name: 'allItemsQuery' }))(Pagination); - -export default ComponentWithMutations; diff --git a/components/Search.js b/components/Search.js deleted file mode 100644 index 0ce136e..0000000 --- a/components/Search.js +++ /dev/null @@ -1,68 +0,0 @@ -import Downshift from 'downshift'; -import { SEARCH_ITEMS_QUERY } from '../queries'; -import { graphql, compose } from 'react-apollo'; -import makeImage from '../lib/image'; -import { Router } from '../routes'; -import slugify from 'slugify'; - -function routeToItem(item) { - Router.pushRoute('item', { - slug: slugify(item.title), - itemId: item.id, - }); -} - -function BasicAutocomplete(props) { - const { items, onChange } = props; - return ( - <Downshift onChange={routeToItem} itemToString={item => item.title}> - {({ getInputProps, getItemProps, isOpen, inputValue, selectedItem, highlightedIndex }) => ( - <div> - <input - {...getInputProps({ - placeholder: 'Search For Item', - onChange: e => props.refetch({ searchTerm: e.target.value }), - style: { fontSize: '20px', padding: '20px', display: 'block', width: '100%' }, - })} - /> - {isOpen ? ( - <div> - {items.map((item, index) => ( - <div - {...getItemProps({ item })} - key={item.id} - style={{ - backgroundColor: highlightedIndex === index ? '#e8e8e8' : 'white', - borderLeft: highlightedIndex === index ? '10px solid #ffc600' : '10px solid white', - padding: '10px', - display: 'flex', - alignItems: 'center', - }} - > - <img width="50" style={{ 'margin-right': '10px' }} src={makeImage(item.image)} alt={item.title} /> - {item.title} - </div> - ))} - </div> - ) : null} - </div> - )} - </Downshift> - ); -} - -const Search = props => ( - <BasicAutocomplete - items={props.searchItems.allItems} - onChange={selectedItem => console.log(selectedItem)} - refetch={props.searchItems.refetch} - /> -); - -const searchEnhancer = graphql(SEARCH_ITEMS_QUERY, { - name: 'searchItems', - options: { - variables: { searchTerm: 'camo' }, - }, -}); -export default compose(searchEnhancer)(Search); diff --git a/components/Signup.js b/components/Signup.js deleted file mode 100644 index 57e2569..0000000 --- a/components/Signup.js +++ /dev/null @@ -1,94 +0,0 @@ -import React, { Component } from 'react'; -import { graphql, gql } from 'react-apollo'; -import { CREATE_USER_MUTATION } from '../queries'; - -class Signup extends Component { - constructor() { - super(); - const idToken = typeof window !== 'undefined' ? localStorage.getItem('auth0IdToken') || '' : ''; - this.state = { - email: '', - name: '', - idToken, - error: undefined, - }; - } - - render() { - return ( - <div> - {this.state.loading ? 'LOADING...' : 'Ready!'} - - {this.state.error ? <p>{this.state.error.message}</p> : ''} - - <form onSubmit={this._createUser}> - <p> - Email - <input - value={this.state.email} - onChange={e => this.setState({ email: e.target.value })} - type="text" - placeholder="email" - /> - </p> - - <p> - Name - <input - value={this.state.name} - onChange={e => this.setState({ name: e.target.value })} - type="text" - placeholder="name" - /> - </p> - - <p> - idToken - <input - disabled - value={this.state.idToken} - onChange={e => this.setState({ idToken: e.target.value })} - type="text" - placeholder="name" - /> - </p> - - <button type="submit">Submit</button> - </form> - </div> - ); - } - - _createUser = async e => { - e.preventDefault(); - // pull the values from state - const { email, name, idToken } = this.state; - // create a mutation - // TODO: handle any errors - // turn loading on - this.setState({ loading: true }); - console.log(name, email, idToken); - try { - const res = await this.props.createUserMutation({ - // pass in those variables from state - variables: { name, email, idToken }, - }); - } catch (error) { - this.setState({ error }); - console.dir(error); - } - this.setState({ loading: false }); - }; -} -// 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_USER_MUTATION, { - name: 'createUserMutation', - 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! - }, -})(Signup); diff --git a/components/SingleItem.js b/components/SingleItem.js deleted file mode 100644 index 297c33d..0000000 --- a/components/SingleItem.js +++ /dev/null @@ -1,36 +0,0 @@ -import { graphql, compose } from 'react-apollo'; -import { Motion, spring } from 'react-motion'; -import { SINGLE_ITEM_QUERY } from '../queries'; -import makeImage from '../lib/image'; - -const SingleItem = props => { - if (!props.findItem.Item) return <p>Not ready</p>; - console.log(props.findItem.Item); - - if (props.loading) return <p>Loading...</p>; - if (props.error) return <p>Error...</p>; - - const item = props.findItem.Item; - return ( - <div> - <img src={makeImage(item.image)} alt={item.title} /> - <h2>Viewing {item.title}</h2> - - <Motion defaultStyle={{ x: 0 }} style={{ x: spring(100) }}> - {value => <div>{value.x}</div>} - </Motion> - </div> - ); -}; - -const ComponentWithMutations = compose( - graphql(SINGLE_ITEM_QUERY, { - name: 'findItem', - // This comes from Props - options: ({ id }) => ({ - variables: { id }, - }), - }) -)(SingleItem); - -export default ComponentWithMutations; diff --git a/components/TakeMyMoney.js b/components/TakeMyMoney.js deleted file mode 100644 index d68cca1..0000000 --- a/components/TakeMyMoney.js +++ /dev/null @@ -1,43 +0,0 @@ -import { Component } from 'react'; -import StripeCheckout from 'react-stripe-checkout'; -import { CREATE_ORDER_MUTATION, CURRENT_USER_QUERY } from '../queries'; -import { graphql, compose } from 'react-apollo'; - - -class TakeMyMoney extends Component { - onToken = async (res) => { - const token = res.id; - const userId = this.props.currentUserQuery.user.id; - const itemId = this.props.id; - console.log(`Going to make a purchase with ${token}`); - console.log(`THe person that bought this was ${userId}`) - console.log(`The item id is ${itemId}`) - const charge = await this.props.createOrder({ variables: { token, userId, itemId }}); - alert(`Back from the charge! ${charge.id}`); - console.log(charge); - - } - render() { - const user = this.props.currentUserQuery.user || {}; - const email = user.email || ''; - return ( - <div> - <StripeCheckout - amount={this.props.amount} - name={this.props.name} - description={this.props.description} - token={this.onToken} - stripeKey="pk_lclTtThFp8CnO3QtEZSd8HA9mFUps" - currency="USD" - email={email} - > - {this.props.children} - </StripeCheckout> - </div> - ) - } -} - -const userEnhancer = graphql(CURRENT_USER_QUERY, { name: 'currentUserQuery' }); -const createOrderEnhancer = graphql(CREATE_ORDER_MUTATION, { name: 'createOrder' }); -export default compose(userEnhancer, createOrderEnhancer)(TakeMyMoney); diff --git a/components/UpdateItem.js b/components/UpdateItem.js deleted file mode 100644 index 27be90f..0000000 --- a/components/UpdateItem.js +++ /dev/null @@ -1,75 +0,0 @@ -import React, { Component } from 'react'; -import { graphql, gql, compose } from 'react-apollo'; -import { SINGLE_ITEM_QUERY, UPDATE_LINK_MUTATION } from '../queries'; - -class UpdateLink extends Component { - state = { - ...this.props.findItem.Item, - }; - - saveToState = e => { - let { name, value, type } = e.target; - if (type === 'number') { - value = parseInt(value); - } - - this.setState({ [name]: value }); - }; - - _createLink = async e => { - e.preventDefault(); - // pull the values from state - const { description, title } = this.state; - const { id } = this.props; - // create a mutation - // TODO: handle any errors - // turn loading on - this.setState({ loading: true }); - console.log(this.state); - const res = await this.props.updateItem({ - // pass in those variables from state - variables: { - ...this.state, - }, - }); - this.setState({ loading: false }); - }; - - render() { - return ( - <div> - <h2>Edit {this.props.id}</h2> - {this.state.loading ? 'LOADING...' : 'Ready!'} - <form onSubmit={this._createLink}> - <label htmlFor="title">Title</label> - <input value={this.state.title} name="title" onChange={this.saveToState} type="text" /> - - <label htmlFor="description">Description</label> - <textarea value={this.state.description} name="description" onChange={this.saveToState} /> - - <label htmlFor="price">Price</label> - <input type="number" name="price" onChange={this.saveToState} value={this.state.price} /> - - <label htmlFor="fullPrice">Full Price</label> - <input type="number" name="fullPrice" onChange={this.saveToState} value={this.state.fullPrice} /> - - <button type="submit">Save...</button> - </form> - </div> - ); - } -} - -const ComponentWithMutations = compose( - // First, query for getting the link - graphql(SINGLE_ITEM_QUERY, { - name: 'findItem', - options: ({ id }) => ({ - variables: { id }, - }), - }), - // Second, the mutation for updating the link - graphql(UPDATE_LINK_MUTATION, { name: 'updateItem' }) -)(UpdateLink); - -export default ComponentWithMutations; |
