summaryrefslogtreecommitdiffstats
path: root/frontend/components
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/components')
-rw-r--r--frontend/components/Cart.js142
-rw-r--r--frontend/components/CartCount.js8
-rw-r--r--frontend/components/Item.js63
-rw-r--r--frontend/components/Items.js1
-rw-r--r--frontend/components/Meta.js9
-rw-r--r--frontend/components/Nav.js65
-rw-r--r--frontend/components/Order.js39
-rw-r--r--frontend/components/styles/CartStyles.js47
-rw-r--r--frontend/components/styles/CloseButton.js13
-rw-r--r--frontend/components/styles/ItemStyles.js39
-rw-r--r--frontend/components/styles/NavStyles.js64
-rw-r--r--frontend/components/styles/OrderStyles.js38
-rw-r--r--frontend/components/styles/PriceTag.js17
-rw-r--r--frontend/components/styles/Supreme.js13
14 files changed, 288 insertions, 270 deletions
diff --git a/frontend/components/Cart.js b/frontend/components/Cart.js
index 8d57c33..2481e11 100644
--- a/frontend/components/Cart.js
+++ b/frontend/components/Cart.js
@@ -1,119 +1,53 @@
import React from 'react';
import { Mutation, Query } from 'react-apollo';
-import styled from 'styled-components';
+import { adopt } from 'react-adopt';
import TakeMyMoney from './TakeMyMoney';
import formatMoney from '../lib/formatMoney';
import CartItem from './CartItem';
import { CURRENT_USER_QUERY, LOCAL_STATE_QUERY, TOGGLE_CART_MUTATION } from '../queries/queries';
import calcTotalPrice from '../lib/calcTotalPrice';
import Error from './ErrorMessage';
+import CartStyles from './styles/CartStyles';
+import Supreme from './styles/Supreme';
+import CloseButton from './styles/CloseButton';
-const CartStyles = styled.div`
- padding: 20px;
- position: relative;
- background: white;
- position: fixed;
- height: 100%;
- top: 0;
- right: 0;
- width: 40%;
- min-width: 500px;
- bottom: 0;
- transform: translateX(100%);
- transition: all 0.3s;
- box-shadow: 0 0 10px 3px rgba(0, 0, 0, 0.2);
- z-index: 5;
- display: grid;
- grid-template-rows: auto 1fr auto;
- ${props => props.open && `transform: translateX(0);`};
- header {
- border-bottom: 5px solid ${props => props.theme.black};
- margin-bottom: 2rem;
- padding-bottom: 2rem;
- }
- footer {
- border-top: 10px double ${props => props.theme.black};
- margin-top: 2rem;
- padding-top: 2rem;
- display: grid;
- grid-template-columns: auto auto;
- align-items: center;
- font-size: 3rem;
- font-weight: 900;
- p {
- margin: 0;
- }
- }
-`;
+const Composed = adopt({
+ toggleCart: <Mutation mutation={TOGGLE_CART_MUTATION} />,
+ localState: <Query query={LOCAL_STATE_QUERY} />,
+ currentUser: <Query query={CURRENT_USER_QUERY} data-test="cart" />,
+});
-const CartUl = styled.ul`
- margin: 0;
- padding: 0;
- list-style: none;
- overflow: scroll;
-`;
+const Cart = () => (
+ <Composed>
+ {({ toggleCart, localState, currentUser }) => {
+ const { data: { me }, error, loading } = currentUser;
+ if (loading) return <p>Loading...</p>;
+ if (error) return <Error error={error} />;
+ if (!me) return <p>Please Sign In!</p>;
+ return (
+ <CartStyles open={localState.data.cartOpen}>
+ <header>
+ <CloseButton title="close" onClick={toggleCart}>
+ &times;
+ </CloseButton>
-const Supreme = styled.h3`
- background: ${props => props.theme.red};
- color: white;
- display: inline-block;
- padding: 4px 5px;
- transform: skew(-3deg);
- margin: 0;
- font-size: 4rem;
-`;
+ <Supreme>{me.name}'s Cart.</Supreme>
+ <p>
+ You have {me.cart.length} item{me.cart.length === 1 ? '' : 's'} in your cart.
+ </p>
+ </header>
-const CloseButton = styled.button`
- background: black;
- color: white;
- font-size: 3rem;
- border: 0;
- position: absolute;
- z-index: 2;
- right: 0;
-`;
-
-// TODO: use react-adopt to compose these
-const Cart = props => (
- <Mutation mutation={TOGGLE_CART_MUTATION}>
- {toggle => (
- <Query query={LOCAL_STATE_QUERY}>
- {({ data }) => (
- <Query query={CURRENT_USER_QUERY} data-test="cart">
- {({ data: { me }, error, loading }) => {
- if (loading) return <p>Loading...</p>;
- if (error) return <Error error={error} />;
- if (!me) return <p>Please Sign In!</p>;
- return (
- <CartStyles open={data.cartOpen}>
- <header>
- <CloseButton title="close" onClick={toggle}>
- &times;
- </CloseButton>
-
- <Supreme>{me.name}'s Cart.</Supreme>
- <p>
- You have {me.cart.length} item{me.cart.length === 1 ? '' : 's'} in your cart.
- </p>
- </header>
-
- <CartUl>
- {me.cart.map(cartItem => <CartItem key={cartItem.id} cartItem={cartItem} />)}
- </CartUl>
- <footer>
- <p>{formatMoney(calcTotalPrice(me.cart))}</p>
- <TakeMyMoney>
- <button>Checkout</button>
- </TakeMyMoney>
- </footer>
- </CartStyles>
- );
- }}
- </Query>
- )}
- </Query>
- )}
- </Mutation>
+ <ul>{me.cart.map(cartItem => <CartItem key={cartItem.id} cartItem={cartItem} />)}</ul>
+ <footer>
+ <p>{formatMoney(calcTotalPrice(me.cart))}</p>
+ <TakeMyMoney>
+ <button>Checkout</button>
+ </TakeMyMoney>
+ </footer>
+ </CartStyles>
+ );
+ }}
+ </Composed>
);
export default Cart;
diff --git a/frontend/components/CartCount.js b/frontend/components/CartCount.js
index 1cc4e47..525ed22 100644
--- a/frontend/components/CartCount.js
+++ b/frontend/components/CartCount.js
@@ -44,7 +44,13 @@ const AnimationStyles = styled.span`
const CartCount = ({ count }) => (
<AnimationStyles>
<TransitionGroup>
- <CSSTransition unmountOnExit className="count" classNames="count" key={count} timeout={{ enter: 400, exit: 400 }}>
+ <CSSTransition
+ unmountOnExit
+ className="count"
+ classNames="count"
+ key={count}
+ timeout={{ enter: 400, exit: 400 }}
+ >
<Dot>{count}</Dot>
</CSSTransition>
</TransitionGroup>
diff --git a/frontend/components/Item.js b/frontend/components/Item.js
index 87d24c4..d6b339e 100644
--- a/frontend/components/Item.js
+++ b/frontend/components/Item.js
@@ -1,63 +1,14 @@
import React from 'react';
-import styled from 'styled-components';
+import PropTypes from 'prop-types';
import Link from 'next/link';
import Title from './styles/Title';
import AddToCart from './AddToCart';
import DeleteItem from './DeleteItem';
import formatMoney from '../lib/formatMoney';
-import PropTypes from 'prop-types';
-
-const Item = styled.div`
- background: white;
- border: 1px solid ${props => props.theme.offWhite};
- box-shadow: ${props => props.theme.bs};
- position: relative;
- display: grid;
- align-content: start;
- grid-auto-rows: fit-content;
- img {
- width: 100%;
- height: 400px;
- object-fit: cover;
- }
- p {
- font-size: 14px;
- line-height: 2;
- font-weight: 600;
- padding: 0 3rem;
- font-size: 1.5rem;
- }
- .buttonList {
- display: grid;
- border-top: 1px solid ${props => props.theme.lightgrey};
- grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
- grid-gap: 1px;
- background: ${props => props.theme.lightgrey};
- align-self: end;
- & > * {
- background: white;
- border: 0;
- font-size: 1rem;
- padding: 1rem;
- }
- }
-`;
-
-const PriceTag = styled.span`
- background: ${props => props.theme.red};
- transform: rotate(3deg);
- color: white;
- font-weight: 600;
- padding: 5px;
- line-height: 1;
- font-size: 3rem;
- display: inline-block;
- position: absolute;
- top: -3px;
- right: -3px;
-`;
+import ItemStyles from './styles/ItemStyles';
+import PriceTag from './styles/PriceTag';
-class ItemComponent extends React.Component {
+class Item extends React.Component {
static propTypes = {
item: PropTypes.object.isRequired,
};
@@ -65,7 +16,7 @@ class ItemComponent extends React.Component {
render() {
const item = this.props.item;
return (
- <Item key={item.id}>
+ <ItemStyles key={item.id}>
{item.image && <img src={item.image} alt={item.title} />}
<Title>
<Link
@@ -94,9 +45,9 @@ class ItemComponent extends React.Component {
<AddToCart id={item.id} />
<DeleteItem id={item.id} />
</div>
- </Item>
+ </ItemStyles>
);
}
}
-export default ItemComponent;
+export default Item;
diff --git a/frontend/components/Items.js b/frontend/components/Items.js
index 5768b6b..1289de1 100644
--- a/frontend/components/Items.js
+++ b/frontend/components/Items.js
@@ -24,7 +24,6 @@ class ItemList extends React.Component {
page: PropTypes.number.isRequired,
};
static getDerivedStateFromProps(nextProps, state) {
- console.log(nextProps);
return { refetch: state.page !== nextProps.page };
}
state = {
diff --git a/frontend/components/Meta.js b/frontend/components/Meta.js
index bee5a69..fe9c29f 100644
--- a/frontend/components/Meta.js
+++ b/frontend/components/Meta.js
@@ -1,21 +1,14 @@
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="/static/favicon.png" />
<link rel="stylesheet" type="text/css" href="/static/nprogress.css" />
-
- <title>Sick Fits</title>
+ <title>Sick Fits!</title>
</Head>
</div>
);
diff --git a/frontend/components/Nav.js b/frontend/components/Nav.js
index 1e39762..89a7c4c 100644
--- a/frontend/components/Nav.js
+++ b/frontend/components/Nav.js
@@ -7,73 +7,14 @@ import CartCount from './CartCount';
import Signout from './Signout';
import { ApolloConsumer } from 'react-apollo';
-const StyledNav = styled.ul`
- margin: 0;
- padding: 0;
- display: flex;
- justify-self: end;
- font-size: 2rem;
- a,
- button {
- padding: 1rem 3rem;
- display: flex;
- align-items: center;
- position: relative;
- text-transform: uppercase;
- font-weight: 900;
- font-size: 1em;
- background: none;
- border: 0;
- cursor: pointer;
- @media (max-width: 700px) {
- font-size: 10px;
- padding: 0 10px;
- }
- &:before {
- content: '';
- width: 2px;
- background: ${props => props.theme.lightgrey};
- height: 100%;
- left: 0;
- position: absolute;
- transform: skew(-20deg);
- top: 0;
- bottom: 0;
- }
- &:after {
- height: 2px;
- background: red;
- content: '';
- width: 0;
- position: absolute;
- transform: translateX(-50%);
- transition: width 0.4s;
- transition-timing-function: cubic-bezier(1, -0.65, 0, 2.31);
- left: 50%;
- margin-top: 2rem;
- }
- &:hover,
- &:focus {
- outline: none;
- &:after {
- width: calc(100% - 60px);
- }
- }
- }
- @media (max-width: 1300px) {
- border-top: 1px solid ${props => props.theme.lightgrey};
- width: 100%;
- justify-content: center;
- font-size: 1.5rem;
- }
-`;
+import NavStyles from './styles/NavStyles';
class Nav extends React.Component {
render() {
return (
<Query query={CURRENT_USER_QUERY}>
{({ data: { me } }) => (
- <StyledNav data-test="nav">
+ <NavStyles data-test="nav">
<Link href="/items">
<a>Shop</a>
</Link>
@@ -109,7 +50,7 @@ class Nav extends React.Component {
</ApolloConsumer>
</Fragment>
)}
- </StyledNav>
+ </NavStyles>
)}
</Query>
);
diff --git a/frontend/components/Order.js b/frontend/components/Order.js
index 0a71b18..0e0aa5f 100644
--- a/frontend/components/Order.js
+++ b/frontend/components/Order.js
@@ -3,47 +3,10 @@ import { Query } from 'react-apollo';
import { format } from 'date-fns';
import Head from 'next/head';
import PropTypes from 'prop-types';
-import styled from 'styled-components';
import { SINGLE_ORDER_QUERY } from '../queries/queries';
import formatMoney from '../lib/formatMoney';
-import Dump from './Dump';
import Error from './ErrorMessage';
-
-const OrderStyles = styled.div`
- max-width: 1000px;
- margin: 0 auto;
- border: 1px solid ${props => props.theme.offWhite};
- box-shadow: ${props => props.theme.bs};
- padding: 2rem;
- border-top: 10px solid red;
- & > p {
- display: grid;
- grid-template-columns: 1fr 5fr;
- margin: 0;
- border-bottom: 1px solid ${props => props.theme.offWhite};
- span {
- padding: 1rem;
- &:first-child {
- font-weight: 900;
- text-align: right;
- }
- }
- }
- .order-item {
- border-bottom: 1px solid ${props => props.theme.offWhite};
- display: grid;
- grid-template-columns: 300px 1fr;
- align-items: center;
- grid-gap: 2rem;
- margin: 2rem 0;
- padding-bottom: 2rem;
- img {
- width: 100%;
- height: 100%;
- object-fit: cover;
- }
- }
-`;
+import OrderStyles from './styles/OrderStyles';
class Order extends Component {
static propTypes = {
diff --git a/frontend/components/styles/CartStyles.js b/frontend/components/styles/CartStyles.js
new file mode 100644
index 0000000..d5ee93a
--- /dev/null
+++ b/frontend/components/styles/CartStyles.js
@@ -0,0 +1,47 @@
+import styled from 'styled-components';
+
+const CartStyles = styled.div`
+ padding: 20px;
+ position: relative;
+ background: white;
+ position: fixed;
+ height: 100%;
+ top: 0;
+ right: 0;
+ width: 40%;
+ min-width: 500px;
+ bottom: 0;
+ transform: translateX(100%);
+ transition: all 0.3s;
+ box-shadow: 0 0 10px 3px rgba(0, 0, 0, 0.2);
+ z-index: 5;
+ display: grid;
+ grid-template-rows: auto 1fr auto;
+ ${props => props.open && `transform: translateX(0);`};
+ header {
+ border-bottom: 5px solid ${props => props.theme.black};
+ margin-bottom: 2rem;
+ padding-bottom: 2rem;
+ }
+ footer {
+ border-top: 10px double ${props => props.theme.black};
+ margin-top: 2rem;
+ padding-top: 2rem;
+ display: grid;
+ grid-template-columns: auto auto;
+ align-items: center;
+ font-size: 3rem;
+ font-weight: 900;
+ p {
+ margin: 0;
+ }
+ }
+ ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ overflow: scroll;
+ }
+`;
+
+export default CartStyles;
diff --git a/frontend/components/styles/CloseButton.js b/frontend/components/styles/CloseButton.js
new file mode 100644
index 0000000..69fd55c
--- /dev/null
+++ b/frontend/components/styles/CloseButton.js
@@ -0,0 +1,13 @@
+import styled from 'styled-components';
+
+const CloseButton = styled.button`
+ background: black;
+ color: white;
+ font-size: 3rem;
+ border: 0;
+ position: absolute;
+ z-index: 2;
+ right: 0;
+`;
+
+export default CloseButton;
diff --git a/frontend/components/styles/ItemStyles.js b/frontend/components/styles/ItemStyles.js
new file mode 100644
index 0000000..8ae0836
--- /dev/null
+++ b/frontend/components/styles/ItemStyles.js
@@ -0,0 +1,39 @@
+import styled from 'styled-components';
+
+const Item = styled.div`
+ background: white;
+ border: 1px solid ${props => props.theme.offWhite};
+ box-shadow: ${props => props.theme.bs};
+ position: relative;
+ display: grid;
+ align-content: start;
+ grid-auto-rows: fit-content;
+ img {
+ width: 100%;
+ height: 400px;
+ object-fit: cover;
+ }
+ p {
+ font-size: 14px;
+ line-height: 2;
+ font-weight: 600;
+ padding: 0 3rem;
+ font-size: 1.5rem;
+ }
+ .buttonList {
+ display: grid;
+ border-top: 1px solid ${props => props.theme.lightgrey};
+ grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
+ grid-gap: 1px;
+ background: ${props => props.theme.lightgrey};
+ align-self: end;
+ & > * {
+ background: white;
+ border: 0;
+ font-size: 1rem;
+ padding: 1rem;
+ }
+ }
+`;
+
+export default Item;
diff --git a/frontend/components/styles/NavStyles.js b/frontend/components/styles/NavStyles.js
new file mode 100644
index 0000000..41523df
--- /dev/null
+++ b/frontend/components/styles/NavStyles.js
@@ -0,0 +1,64 @@
+import styled from 'styled-components';
+
+const NavStyles = styled.ul`
+ margin: 0;
+ padding: 0;
+ display: flex;
+ justify-self: end;
+ font-size: 2rem;
+ a,
+ button {
+ padding: 1rem 3rem;
+ display: flex;
+ align-items: center;
+ position: relative;
+ text-transform: uppercase;
+ font-weight: 900;
+ font-size: 1em;
+ background: none;
+ border: 0;
+ cursor: pointer;
+ @media (max-width: 700px) {
+ font-size: 10px;
+ padding: 0 10px;
+ }
+ &:before {
+ content: '';
+ width: 2px;
+ background: ${props => props.theme.lightgrey};
+ height: 100%;
+ left: 0;
+ position: absolute;
+ transform: skew(-20deg);
+ top: 0;
+ bottom: 0;
+ }
+ &:after {
+ height: 2px;
+ background: red;
+ content: '';
+ width: 0;
+ position: absolute;
+ transform: translateX(-50%);
+ transition: width 0.4s;
+ transition-timing-function: cubic-bezier(1, -0.65, 0, 2.31);
+ left: 50%;
+ margin-top: 2rem;
+ }
+ &:hover,
+ &:focus {
+ outline: none;
+ &:after {
+ width: calc(100% - 60px);
+ }
+ }
+ }
+ @media (max-width: 1300px) {
+ border-top: 1px solid ${props => props.theme.lightgrey};
+ width: 100%;
+ justify-content: center;
+ font-size: 1.5rem;
+ }
+`;
+
+export default NavStyles;
diff --git a/frontend/components/styles/OrderStyles.js b/frontend/components/styles/OrderStyles.js
new file mode 100644
index 0000000..4a2d804
--- /dev/null
+++ b/frontend/components/styles/OrderStyles.js
@@ -0,0 +1,38 @@
+import styled from 'styled-components';
+
+const OrderStyles = styled.div`
+ max-width: 1000px;
+ margin: 0 auto;
+ border: 1px solid ${props => props.theme.offWhite};
+ box-shadow: ${props => props.theme.bs};
+ padding: 2rem;
+ border-top: 10px solid red;
+ & > p {
+ display: grid;
+ grid-template-columns: 1fr 5fr;
+ margin: 0;
+ border-bottom: 1px solid ${props => props.theme.offWhite};
+ span {
+ padding: 1rem;
+ &:first-child {
+ font-weight: 900;
+ text-align: right;
+ }
+ }
+ }
+ .order-item {
+ border-bottom: 1px solid ${props => props.theme.offWhite};
+ display: grid;
+ grid-template-columns: 300px 1fr;
+ align-items: center;
+ grid-gap: 2rem;
+ margin: 2rem 0;
+ padding-bottom: 2rem;
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+ }
+`;
+export default OrderStyles;
diff --git a/frontend/components/styles/PriceTag.js b/frontend/components/styles/PriceTag.js
new file mode 100644
index 0000000..9116681
--- /dev/null
+++ b/frontend/components/styles/PriceTag.js
@@ -0,0 +1,17 @@
+import styled from 'styled-components';
+
+const PriceTag = styled.span`
+ background: ${props => props.theme.red};
+ transform: rotate(3deg);
+ color: white;
+ font-weight: 600;
+ padding: 5px;
+ line-height: 1;
+ font-size: 3rem;
+ display: inline-block;
+ position: absolute;
+ top: -3px;
+ right: -3px;
+`;
+
+export default PriceTag;
diff --git a/frontend/components/styles/Supreme.js b/frontend/components/styles/Supreme.js
new file mode 100644
index 0000000..d946ccd
--- /dev/null
+++ b/frontend/components/styles/Supreme.js
@@ -0,0 +1,13 @@
+import styled from 'styled-components';
+
+const Supreme = styled.h3`
+ background: ${props => props.theme.red};
+ color: white;
+ display: inline-block;
+ padding: 4px 5px;
+ transform: skew(-3deg);
+ margin: 0;
+ font-size: 4rem;
+`;
+
+export default Supreme;