summaryrefslogtreecommitdiffstats
path: root/frontend/components
diff options
context:
space:
mode:
authorWes Bos <wesbos@gmail.com>2018-03-12 14:06:25 -0400
committerWes Bos <wesbos@gmail.com>2018-03-12 14:06:25 -0400
commit46a0ba30ef54a7e36206481a4f5b2bf1f9702fca (patch)
treea95fd534fc27761d8b26d0dffcdb5f300f7a61c7 /frontend/components
parentf7bea2d1b7be2b70dceb25c9837f608b538e9cec (diff)
wip
Diffstat (limited to 'frontend/components')
-rw-r--r--frontend/components/AddToCart.js2
-rw-r--r--frontend/components/Cart.js46
-rw-r--r--frontend/components/CartCount.js52
-rw-r--r--frontend/components/CartList.js2
-rw-r--r--frontend/components/CreateItem.js38
-rw-r--r--frontend/components/EditUser.js51
-rw-r--r--frontend/components/Header.js2
-rw-r--r--frontend/components/Item.js10
-rw-r--r--frontend/components/Items.js51
-rw-r--r--frontend/components/Nav.js89
-rw-r--r--frontend/components/OrderList.js7
-rw-r--r--frontend/components/Page.js20
-rw-r--r--frontend/components/Pagination.js76
-rw-r--r--frontend/components/RequestReset.js19
-rw-r--r--frontend/components/Reset.js5
-rw-r--r--frontend/components/Signin.js6
-rw-r--r--frontend/components/Signout.js2
-rw-r--r--frontend/components/Signup.js5
-rw-r--r--frontend/components/SingleItem.js3
-rw-r--r--frontend/components/TakeMyMoney.js2
-rw-r--r--frontend/components/ToggleCart.js22
-rw-r--r--frontend/components/UIContext.js23
-rw-r--r--frontend/components/UpdateItem.js9
-rw-r--r--frontend/components/styles/Form.js40
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}>
&times;
</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;