diff options
| author | Wes Bos <wesbos@gmail.com> | 2018-03-12 14:06:25 -0400 |
|---|---|---|
| committer | Wes Bos <wesbos@gmail.com> | 2018-03-12 14:06:25 -0400 |
| commit | 46a0ba30ef54a7e36206481a4f5b2bf1f9702fca (patch) | |
| tree | a95fd534fc27761d8b26d0dffcdb5f300f7a61c7 /frontend/components | |
| parent | f7bea2d1b7be2b70dceb25c9837f608b538e9cec (diff) | |
wip
Diffstat (limited to 'frontend/components')
24 files changed, 370 insertions, 212 deletions
diff --git a/frontend/components/AddToCart.js b/frontend/components/AddToCart.js index 6cab321..b87d4e9 100644 --- a/frontend/components/AddToCart.js +++ b/frontend/components/AddToCart.js @@ -6,8 +6,6 @@ import PropTypes from 'prop-types'; import { CURRENT_USER_QUERY, SINGLE_ITEM_QUERY } from '../queries'; import { removeFromCartEnhancer, userEnhancer, addtoCartEnhancer } from '../enhancers/enhancers'; -console.log(addtoCartEnhancer); - const JumpImg = styled.img` border: 0 solid black; max-width: 100px; diff --git a/frontend/components/Cart.js b/frontend/components/Cart.js index 78e0d88..f270b80 100644 --- a/frontend/components/Cart.js +++ b/frontend/components/Cart.js @@ -5,9 +5,8 @@ import Title from './styles/Title'; import { updateUIEnhancer, userEnhancer, uiEnhancer } from '../enhancers/enhancers'; import RemoveFromCart from './RemoveFromCart'; import TakeMyMoney from './TakeMyMoney'; -import ToggleCart from './ToggleCart'; import formatMoney from '../lib/formatMoney'; - +import { UIContext } from './UIContext'; import CartItem from './CartItem'; const CartStyles = styled.div` @@ -91,31 +90,32 @@ class Cart extends Component { const totalPrice = me.cart.reduce((tally, cartItem) => tally + cartItem.quantity * cartItem.item.price, 0); return ( - <CartStyles open={this.props.ui.uiData.isCartOpen}> - <header> - <ToggleCart - render={toggle => ( - <CloseButton title="close" onClick={toggle}> + <UIContext> + {context => ( + <CartStyles open={context.state.isCartOpen}> + <header> + <CloseButton title="close" onClick={context.toggle}> × </CloseButton> - )} - /> - <Supreme>Your Cart.</Supreme> - <p> - You have {itemCount} item{itemCount === 1 ? '' : 's'} in your cart. S{'I'.repeat(quantityCount)}CK - </p> - </header> - <CartUl>{me.cart.map(cartItem => <CartItem key={cartItem.id} cartItem={cartItem} />)}</CartUl> - <footer> - <p>{formatMoney(totalPrice)}</p> - <TakeMyMoney> - <button>Checkout</button> - </TakeMyMoney> - </footer> - </CartStyles> + <Supreme>{me.name}'s Cart.</Supreme> + <p> + You have {itemCount} item{itemCount === 1 ? '' : 's'} in your cart. + </p> + </header> + + <CartUl>{me.cart.map(cartItem => <CartItem key={cartItem.id} cartItem={cartItem} />)}</CartUl> + <footer> + <p>{formatMoney(totalPrice)}</p> + <TakeMyMoney> + <button>Checkout</button> + </TakeMyMoney> + </footer> + </CartStyles> + )} + </UIContext> ); } } -export default compose(userEnhancer, uiEnhancer)(Cart); +export default compose(userEnhancer)(Cart); diff --git a/frontend/components/CartCount.js b/frontend/components/CartCount.js new file mode 100644 index 0000000..245b07b --- /dev/null +++ b/frontend/components/CartCount.js @@ -0,0 +1,52 @@ +import styled from 'styled-components'; +import { TransitionGroup, CSSTransition } from 'react-transition-group'; + +const Dot = styled.div` + background: ${props => props.theme.red}; + color: white; + border-radius: 50%; + padding: 5px; + margin-left: 1rem; + font-weight: 100; + font-feature-settings: 'tnum'; + font-variant-numeric: tabular-nums; +`; + +const AnimationStyles = styled.span` + position: relative; + .count { + display: block; + position: relative; + transition: all 0.4s; + backface-visibility: hidden; + } + .count-enter { + transform: rotateX(0.5turn); + } + + .count-enter-active { + transform: rotateX(0); + } + + .count-exit { + top: 0; + position: absolute; + transform: rotateX(0); + } + + .count-exit-active { + transform: rotateX(0.5turn); + } +`; + +const CartCount = ({ count }) => ( + <AnimationStyles> + <TransitionGroup> + <CSSTransition className="count" classNames="count" key={count} timeout={{ enter: 2000, exit: 2000 }}> + <Dot>{count}</Dot> + </CSSTransition> + </TransitionGroup> + </AnimationStyles> +); + +export default CartCount; diff --git a/frontend/components/CartList.js b/frontend/components/CartList.js index 1a44012..8464398 100644 --- a/frontend/components/CartList.js +++ b/frontend/components/CartList.js @@ -88,4 +88,4 @@ class CartList extends Component { } } -export default compose(userEnhancer, removeFromCartEnhancer, uiEnhancer)(CartList); +export default compose(userEnhancer, removeFromCartEnhancer)(CartList); diff --git a/frontend/components/CreateItem.js b/frontend/components/CreateItem.js index 0d43c68..26b2c88 100644 --- a/frontend/components/CreateItem.js +++ b/frontend/components/CreateItem.js @@ -3,12 +3,14 @@ import { graphql, gql } from 'react-apollo'; import { ALL_ITEMS_QUERY, CREATE_ITEM_MUTATION } from '../queries'; import ErrorMessage from './ErrorMessage'; import { fileEndpoint } from '../config'; +import Form from './styles/Form'; class CreateLink extends Component { state = { description: 'test', title: 'testing title', image: '', + largeImage: '', price: 500, fullPrice: 0, loading: false, @@ -37,13 +39,13 @@ class CreateLink extends Component { }); const file = await res.json(); console.log(file); - this.setState({ image: file.secure_url, loading: false }); + this.setState({ image: file.secure_url, largeImage: file.eager[0].secure_url, loading: false }); }; - _createLink = async e => { + createItem = async e => { e.preventDefault(); // pull the values from state - const { description, title, price, image } = this.state; + const { description, title, price, image, largeImage } = this.state; // create a mutation // TODO: handle any errors // turn loading on @@ -56,6 +58,7 @@ class CreateLink extends Component { description, title, image, + largeImage, price: parseInt(price), }, }); @@ -69,10 +72,9 @@ class CreateLink extends Component { render() { return ( <div> - {this.state.loading ? 'LOADING...' : 'Ready!'} - - <ErrorMessage error={this.state.error} onButtonClick={() => this.setState({ error: {} })} /> - <form onSubmit={this._createLink}> + <Form onSubmit={this.createItem}> + {this.state.loading ? 'LOADING...' : null} + <ErrorMessage error={this.state.error} onButtonClick={() => this.setState({ error: {} })} /> <p> Image <input onChange={this.uploadFile} type="file" accept=".png, .jpg, .jpeg" /> @@ -101,34 +103,18 @@ class CreateLink extends Component { type="text" placeholder="The desc for this item" /> - <button disabled={!this.state.loading} type="submit"> + <button disabled={this.state.loading} type="submit"> Submit </button> - </form> + </Form> </div> ); } } -// TODO: The create item should only be allowed - -// 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 } }) => { - console.log('UPDATING'); - 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 }); - }, + refetchQueries: ['AllItemsQuery'], }, })(CreateLink); diff --git a/frontend/components/EditUser.js b/frontend/components/EditUser.js new file mode 100644 index 0000000..e763616 --- /dev/null +++ b/frontend/components/EditUser.js @@ -0,0 +1,51 @@ +import React from 'react'; +import Form from './styles/Form'; +import { userEnhancer, updateUserEnhancer } from '../enhancers/enhancers'; +import { compose } from 'react-apollo'; + +class EditUser extends React.Component { + state = { + changes: {}, + }; + handleChange = e => { + const { name, value } = e.target; + const { me } = this.props.currentUser; + const changes = { + ...this.state.changes, + [name]: value, + }; + if (value === me[e.target.name]) { + delete changes[name]; + } + this.setState({ changes }); + }; + + handleSubmit = async e => { + e.preventDefault(); + const user = await this.props.updateUser({ + variables: this.state.changes, + }); + this.props.currentUser.refetch(); + this.setState({ changes: {} }); + }; + + render() { + const { me } = this.props.currentUser; + if (!me) return <p>You must be logged in</p>; + return ( + <Form onSubmit={this.handleSubmit}> + <label htmlFor="name"> + Name: + <input type="text" name="name" defaultValue={me.name} onChange={this.handleChange} /> + </label> + <button type="submit">Update</button> + <strong>me:</strong> + <pre>{JSON.stringify(me.name)}</pre> + <strong>Change:</strong> + <pre>{JSON.stringify(this.state.changes)}</pre> + </Form> + ); + } +} + +export default compose(userEnhancer, updateUserEnhancer)(EditUser); diff --git a/frontend/components/Header.js b/frontend/components/Header.js index 0183e4a..0b815f9 100644 --- a/frontend/components/Header.js +++ b/frontend/components/Header.js @@ -5,7 +5,6 @@ import NProgress from 'nprogress'; import Router from 'next/router'; import styled from 'styled-components'; import Link from 'next/link'; -import Signout from './Signout'; import Cart from './Cart'; import Search from './Search'; import Nav from './Nav'; @@ -56,7 +55,6 @@ const Header = props => ( </div> <div className="sub-bar"> <Search /> - <Signout /> </div> <Cart /> </StyledHeader> diff --git a/frontend/components/Item.js b/frontend/components/Item.js index 87fb0b9..935930d 100644 --- a/frontend/components/Item.js +++ b/frontend/components/Item.js @@ -3,7 +3,8 @@ import Title from './styles/Title'; import styled from 'styled-components'; import slugify from 'slugify'; import { compose } from 'react-apollo'; -import { Link } from '../routes'; +// import { Link } from '../routes'; +import Link from 'next/link'; import AddToCart from './AddToCart'; import formatMoney from '../lib/formatMoney'; import { removeItemMutation } from '../enhancers/enhancers'; @@ -70,10 +71,9 @@ class ItemComponent extends React.Component { {item.image ? <img src={item.image} alt={item.title} /> : null} <Title> <Link - route="item" - params={{ - slug: slugify(item.title), - itemId: item.id, + href={{ + pathname: '/item', + query: { id: item.id }, }} > <a>{item.title}</a> diff --git a/frontend/components/Items.js b/frontend/components/Items.js index 6206592..01d9786 100644 --- a/frontend/components/Items.js +++ b/frontend/components/Items.js @@ -1,16 +1,10 @@ -import { Component } from 'react'; -import { withApollo, graphql, compose } from 'react-apollo'; +import React from 'react'; +import { compose } from 'react-apollo'; import styled from 'styled-components'; import Pagination from './Pagination'; import Item from './Item'; import { itemEnhancer } from '../enhancers/enhancers'; -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(auto-fit, minmax(300px, 1fr)); @@ -19,38 +13,21 @@ const Items = styled.div` margin: 0 auto; `; -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, - }, - }); - }; +const Center = styled.div` + text-align: center; +`; +class ItemList extends React.Component { + something() { } render() { - console.log(this.props); + const { loading, error } = this.props.itemsQuery; // 1 - if (this.props.itemsQuery && this.props.itemsQuery.loading) { + if (loading) { return <div>Loading</div>; } // 2 - if (this.props.itemsQuery && this.props.itemsQuery.error) { + if (error) { console.log(this.props.itemsQuery.error); return <div>Error</div>; } @@ -59,13 +36,13 @@ class ItemList extends Component { const itemsToRender = this.props.itemsQuery.items; return ( - <div> + <Center> <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> + <Pagination page={this.props.page} /> + </Center> ); } } -export default withApollo(compose(itemEnhancer)(ItemList)); +export default compose(itemEnhancer)(ItemList); diff --git a/frontend/components/Nav.js b/frontend/components/Nav.js index 9793087..aa0300b 100644 --- a/frontend/components/Nav.js +++ b/frontend/components/Nav.js @@ -1,8 +1,11 @@ import Link from 'next/link'; import styled from 'styled-components'; +import { Fragment } from 'react'; import { userEnhancer } from '../enhancers/enhancers'; import { compose } from 'react-apollo'; -import ToggleCart from './ToggleCart'; +import CartCount from './CartCount'; +import Signout from './Signout'; +import { UIContext } from './UIContext'; const StyledUl = styled.ul` margin: 0; @@ -20,6 +23,7 @@ const StyledUl = styled.ul` font-size: 2rem; background: none; border: 0; + cursor: pointer; &:before { content: ''; width: 1px; @@ -51,45 +55,54 @@ const StyledUl = styled.ul` } } } - .cart-count { - background: ${props => props.theme.red}; - color: white; - border-radius: 50%; - padding: 5px; - margin-left: 1rem; - font-weight: 100; - font-feature-settings: 'tnum'; - font-variant-numeric: tabular-nums; - } `; -const Nav = ({ currentUser }) => ( - <StyledUl> - <Link prefetch href="/items"> - <a>Shop</a> - </Link> - <Link prefetch href="/add"> - <a>Sell</a> - </Link> - <Link prefetch href="/signup"> - <a>Sign Up</a> - </Link> - <Link prefetch href="/orders"> - <a>Orders</a> - </Link> - {currentUser.me ? ( - <ToggleCart - render={toggle => ( - <button onClick={toggle}> - My Cart - <span className="cart-count"> - {currentUser.me.cart.reduce((tally, cartItem) => tally + cartItem.quantity, 0)} - </span> - </button> +class Nav extends React.Component { + componentDidMount() { + this.props.currentUser.refetch(); + } + render() { + const { currentUser } = this.props; + return ( + <StyledUl> + <Link prefetch href="/items"> + <a>Shop</a> + </Link> + <Link prefetch href="/add"> + <a>Sell</a> + </Link> + + {!currentUser.me && ( + <Link prefetch href="/signup"> + <a>Sign In</a> + </Link> )} - /> - ) : null} - </StyledUl> -); + + {currentUser.me && ( + <Fragment> + <Link href="/orders"> + <a>Orders</a> + </Link> + <Link href="/me"> + <a>My Account</a> + </Link> + <Signout /> + <UIContext> + {context => ( + <button onClick={context.toggle}> + My Cart + <CartCount + className="cart-count" + count={currentUser.me.cart.reduce((tally, cartItem) => tally + cartItem.quantity, 0)} + /> + </button> + )} + </UIContext> + </Fragment> + )} + </StyledUl> + ); + } +} export default compose(userEnhancer)(Nav); diff --git a/frontend/components/OrderList.js b/frontend/components/OrderList.js index cf12dc8..6a1ad67 100644 --- a/frontend/components/OrderList.js +++ b/frontend/components/OrderList.js @@ -31,7 +31,12 @@ class OrderList extends Component { <ul className="order-items"> <hr /> <h2> - <Link href={`/order/${order.id}`} prefetch> + <Link + href={{ + pathname: '/order', + query: { id: order.id }, + }} + > <a>{order.id}</a> </Link> <time dateTime={order.createdAt} title={format(order.createdAt, 'MMMM D, YYYY h:mm A')}> diff --git a/frontend/components/Page.js b/frontend/components/Page.js index 6256c3d..e07df88 100644 --- a/frontend/components/Page.js +++ b/frontend/components/Page.js @@ -4,7 +4,7 @@ import Meta from './Meta'; import Nav from './Nav'; import CartList from './CartList'; import { Component } from 'react'; - +import { UIProvider } from './UIContext'; // Global Style const theme = { @@ -16,7 +16,7 @@ const theme = { maxWidth: '1300px', }; -const globals = injectGlobal` +injectGlobal` html { box-sizing: border-box; font-size: 10px; @@ -44,13 +44,15 @@ const StyledPage = styled.div` `; const Page = ({ children }) => ( - <ThemeProvider theme={theme}> - <StyledPage className="main"> - <Meta /> - <Header /> - {children} - </StyledPage> - </ThemeProvider> + <UIProvider> + <ThemeProvider theme={theme}> + <StyledPage className="main"> + <Meta /> + <Header /> + {children} + </StyledPage> + </ThemeProvider> + </UIProvider> ); export default Page; diff --git a/frontend/components/Pagination.js b/frontend/components/Pagination.js index d00778b..dab7084 100644 --- a/frontend/components/Pagination.js +++ b/frontend/components/Pagination.js @@ -1,36 +1,68 @@ import React from 'react'; import { compose } from 'react-apollo'; -import { Link } from '../routes'; +import styled from 'styled-components'; +import Link from 'next/link'; import { itemEnhancer } from '../enhancers/enhancers'; +import { perPage } from '../config'; + +const PaginationStyles = styled.div` + text-align: center; + display: inline-grid; + grid-template-columns: repeat(4, auto); + align-items: stretch; + justify-content: center; + align-content: center; + margin: 2rem 0; + border: 1px solid ${props => props.theme.lightgrey}; + border-radius: 10px; + & > * { + margin: 0; + padding: 15px 30px; + border-right: 1px solid ${props => props.theme.lightgrey}; + &:last-child { + border-right: 0; + } + } + a[aria-disabled='true'] { + color: grey; + pointer-events: none; + } +`; const Pagination = props => { if (props.loading) return <p>Loading Item...</p>; const { aggregate, pageInfo } = props.itemsQuery.itemsConnection; - const { page } = props; - const pages = Math.floor(aggregate.count / 3); + + const pages = Math.ceil(aggregate.count / perPage); + console.log({ pageInfo }); return ( - <div> + <PaginationStyles> + <Link + prefetch + href={{ + pathname: 'items', + query: { page: page - 1 }, + }} + > + <a aria-disabled={page <= 1}>←Prev</a> + </Link> <p> - Page <strong>{page} </strong> - of - <strong>{pages} </strong> - - - <strong>{aggregate.count} </strong> - total + Page <strong>{page} </strong> of <strong>{pages} </strong> </p> - {pageInfo.hasPreviousPage ? ( - <Link prefetch route="items" params={{ page: page - 1 }}> - <a>←Prev</a> - </Link> - ) : null} - - {pageInfo.hasNextPage ? ( - <Link prefetch route="items" params={{ page: page + 1 }}> - <a>Next →</a> - </Link> - ) : null} - </div> + <p> + <strong>{aggregate.count}</strong> Items Total + </p> + <Link + prefetch + href={{ + pathname: 'items', + query: { page: page + 1 }, + }} + > + <a aria-disabled={page >= pages}>Next →</a> + </Link> + </PaginationStyles> ); }; diff --git a/frontend/components/RequestReset.js b/frontend/components/RequestReset.js index de16751..974924f 100644 --- a/frontend/components/RequestReset.js +++ b/frontend/components/RequestReset.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { graphql, compose } from 'react-apollo'; import { REQUEST_RESET_MUTATION } from '../queries'; +import Form from './styles/Form'; class ResetRequest extends Component { state = { @@ -45,20 +46,16 @@ class ResetRequest extends Component { render() { return ( - <div> - {this.state.loading ? 'LOADING...' : 'Ready!'} - + <Form onSubmit={this.requestReset}> + {this.state.loading ? 'LOADING...' : null} {this.state.errors ? this.state.errors.map(err => <p>{err.message}</p>) : null} - <h2>Request a Reset</h2> - <form onSubmit={this.requestReset}> - <label htmlFor="email"> - Email + <label htmlFor="email"> + Email <input value={this.state.email} onChange={this.saveToState} name="email" type="text" placeholder="email" /> - </label> + </label> - <button type="submit">Request Reset!</button> - </form> - </div> + <button type="submit">Request Reset!</button> + </Form> ); } } diff --git a/frontend/components/Reset.js b/frontend/components/Reset.js index 7d36de7..5593f75 100644 --- a/frontend/components/Reset.js +++ b/frontend/components/Reset.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { graphql, compose } from 'react-apollo'; import { RESET_MUTATION, CURRENT_USER_QUERY } from '../queries'; +import Form from './styles/Form'; class Reset extends Component { state = { @@ -49,7 +50,7 @@ class Reset extends Component { {this.state.errors ? this.state.errors.map((err, i) => <p key={i}>{err.message}</p>) : null} - <form onSubmit={this.resetPassword}> + <Form onSubmit={this.resetPassword}> <label htmlFor="password"> password <input @@ -72,7 +73,7 @@ class Reset extends Component { </label> <button type="submit">Request Reset!</button> - </form> + </Form> </div> ); } diff --git a/frontend/components/Signin.js b/frontend/components/Signin.js index 752199b..423e9e8 100644 --- a/frontend/components/Signin.js +++ b/frontend/components/Signin.js @@ -2,6 +2,8 @@ import React, { Component } from 'react'; import { graphql, compose } from 'react-apollo'; import { SIGNIN_MUTATION, CURRENT_USER_QUERY } from '../queries'; +import Form from './styles/Form'; + class Signin extends Component { state = { email: `wesbos@gmail.com`, @@ -41,7 +43,7 @@ class Signin extends Component { {this.state.errors ? this.state.errors.map(err => <p>{err.message}</p>) : null} - <form onSubmit={this.loginUser}> + <Form onSubmit={this.loginUser}> <label htmlFor="email"> Email <input value={this.state.email} onChange={this.saveToState} name="email" type="text" placeholder="email" /> @@ -61,7 +63,7 @@ class Signin extends Component { </label> <button type="submit">Sign In!</button> - </form> + </Form> </div> ); } diff --git a/frontend/components/Signout.js b/frontend/components/Signout.js index 97eef40..8581009 100644 --- a/frontend/components/Signout.js +++ b/frontend/components/Signout.js @@ -12,7 +12,7 @@ class Signout extends Component { render() { const { me, loading, error } = this.props.currentUser; if (!me || loading || error) return null; - return <button onClick={this.signout}>Sign Out of {me.id}👋 🏻</button>; + return <button onClick={this.signout}>Sign Out</button>; } } diff --git a/frontend/components/Signup.js b/frontend/components/Signup.js index e9d6737..3a4dd99 100644 --- a/frontend/components/Signup.js +++ b/frontend/components/Signup.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { graphql, compose } from 'react-apollo'; import { SIGNUP_MUTATION, CURRENT_USER_QUERY } from '../queries'; +import Form from './styles/Form'; class Signup extends Component { state = { @@ -46,7 +47,7 @@ class Signup extends Component { {this.state.error ? <p>{this.state.error.message}</p> : null} - <form onSubmit={this.createUser}> + <Form onSubmit={this.createUser}> <label htmlFor="email"> Email <input value={this.state.email} onChange={this.saveToState} name="email" type="text" placeholder="email" /> @@ -71,7 +72,7 @@ class Signup extends Component { </label> <button type="submit">Submit</button> - </form> + </Form> </div> ); } diff --git a/frontend/components/SingleItem.js b/frontend/components/SingleItem.js index 58da71c..add1707 100644 --- a/frontend/components/SingleItem.js +++ b/frontend/components/SingleItem.js @@ -7,9 +7,10 @@ const SingleItem = props => { if (props.loading) return <p>Loading...</p>; if (props.error) return <p>Error...</p>; const item = props.findItem.items[0]; + console.log(item); return ( <div> - <img src={item.image} alt={item.title} /> + <img src={item.largeImage || item.image} alt={item.title} /> <h2>Viewing {item.title}</h2> <p>{item.description}</p> </div> diff --git a/frontend/components/TakeMyMoney.js b/frontend/components/TakeMyMoney.js index 5ebfb95..333f31b 100644 --- a/frontend/components/TakeMyMoney.js +++ b/frontend/components/TakeMyMoney.js @@ -24,7 +24,7 @@ class TakeMyMoney extends Component { render() { const { me } = this.props.currentUserQuery; - if (!me.cart.length) return null; + if (!me || !me.cart.length) return null; const total = me.cart.reduce((tally, cartItem) => tally + cartItem.item.price * cartItem.quantity, 0); const totalItems = me.cart.reduce((tally, cartItem) => tally + cartItem.quantity, 0); return ( diff --git a/frontend/components/ToggleCart.js b/frontend/components/ToggleCart.js deleted file mode 100644 index c80baa6..0000000 --- a/frontend/components/ToggleCart.js +++ /dev/null @@ -1,22 +0,0 @@ -import { Component } from 'react'; -import { compose } from 'react-apollo'; -import { uiEnhancer, updateUIEnhancer } from '../enhancers/enhancers'; -import PropTypes from 'prop-types'; - -class ToggleCart extends Component { - static propTypes = { - render: PropTypes.func.isRequired, - toggleCart: PropTypes.func.isRequired, - ui: PropTypes.object.isRequired, - }; - toggle = e => { - // if this is a keyPress event, make sure it's the enter key - if (e.keyCode && e.keyCode !== 16) return; - this.props.toggleCart(!this.props.ui.uiData.isCartOpen); - }; - render() { - return this.props.render(this.toggle); - } -} - -export default compose(uiEnhancer, updateUIEnhancer)(ToggleCart); diff --git a/frontend/components/UIContext.js b/frontend/components/UIContext.js new file mode 100644 index 0000000..0e851c0 --- /dev/null +++ b/frontend/components/UIContext.js @@ -0,0 +1,23 @@ +import React from 'react'; + +const UIContext = React.createContext(); + +class UIProvider extends React.Component { + state = { + isCartOpen: false, + }; + render() { + return ( + <UIContext.Provider + value={{ + state: this.state, + toggle: () => this.setState({ isCartOpen: !this.state.isCartOpen }), + }} + > + {this.props.children} + </UIContext.Provider> + ); + } +} + +export { UIContext, UIProvider }; diff --git a/frontend/components/UpdateItem.js b/frontend/components/UpdateItem.js index febe2ad..e97b4aa 100644 --- a/frontend/components/UpdateItem.js +++ b/frontend/components/UpdateItem.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { graphql, gql, compose } from 'react-apollo'; import { SINGLE_ITEM_QUERY, UPDATE_LINK_MUTATION } from '../queries'; +import Form from './styles/Form'; import { singleItemEnhancer } from '../enhancers/enhancers'; @@ -51,9 +52,9 @@ class UpdateItem extends Component { const item = this.props.findItem.items[0]; return ( <div> - <h2>Edit {this.props.id}</h2> - {this.state.loading ? 'LOADING...' : 'Ready!'} - <form onSubmit={this.updateItem}> + <Form onSubmit={this.updateItem}> + <h2>Edit {item.title}</h2> + {this.state.loading ? 'LOADING...' : 'Ready!'} <fieldset disabled={this.state.loading}> <label htmlFor="title"> Title @@ -71,7 +72,7 @@ class UpdateItem extends Component { </label> <button type="submit">Save...</button> </fieldset> - </form> + </Form> </div> ); } diff --git a/frontend/components/styles/Form.js b/frontend/components/styles/Form.js new file mode 100644 index 0000000..db0eeb4 --- /dev/null +++ b/frontend/components/styles/Form.js @@ -0,0 +1,40 @@ +import styled from 'styled-components'; + +const Form = styled.form` + box-shadow: 0 0 5px 3px rgba(0, 0, 0, 0.05); + background: rgba(0, 0, 0, 0.02); + border: 5px solid white; + margin: 100px; + padding: 100px; + font-size: 2.5rem; + font-weight: 600; + label { + margin-bottom: 1rem; + display: block; + } + input, + textarea, + select { + margin-top: 2rem; + margin-bottom: 2rem; + width: 100%; + padding: 1rem; + font-size: 2rem; + border: 1px solid black; + &:focus { + outline: 0; + border-color: ${props => props.theme.red}; + } + } + button, + input[type='submit'] { + width: auto; + background: red; + color: white; + border: 0; + font-size: 2rem; + font-weight: 600; + padding: 1rem 2rem; + } +`; +export default Form; |
