diff options
Diffstat (limited to 'stepped-solutions/FINISHED/frontend/components')
43 files changed, 0 insertions, 2460 deletions
diff --git a/stepped-solutions/FINISHED/frontend/components/AddToCart.js b/stepped-solutions/FINISHED/frontend/components/AddToCart.js deleted file mode 100644 index 8a71cc3..0000000 --- a/stepped-solutions/FINISHED/frontend/components/AddToCart.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import { Mutation } from 'react-apollo'; -import gql from 'graphql-tag'; -import { CURRENT_USER_QUERY } from './User'; - -const ADD_TO_CART_MUTATION = gql` - mutation addToCart($id: ID!) { - addToCart(id: $id) { - id - quantity - } - } -`; - -class AddToCart extends React.Component { - render() { - const { id } = this.props; - return ( - <Mutation - mutation={ADD_TO_CART_MUTATION} - variables={{ - id, - }} - refetchQueries={[{ query: CURRENT_USER_QUERY }]} - > - {(addToCart, { loading }) => ( - <button disabled={loading} onClick={addToCart}> - Add{loading && 'ing'} To Cart 🛒 - </button> - )} - </Mutation> - ); - } -} -export default AddToCart; -export { ADD_TO_CART_MUTATION }; diff --git a/stepped-solutions/FINISHED/frontend/components/Cart.js b/stepped-solutions/FINISHED/frontend/components/Cart.js deleted file mode 100644 index 2a72b38..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Cart.js +++ /dev/null @@ -1,66 +0,0 @@ -import React from 'react'; -import { Query, Mutation } from 'react-apollo'; -import gql from 'graphql-tag'; -import { adopt } from 'react-adopt'; -import User from './User'; -import CartStyles from './styles/CartStyles'; -import Supreme from './styles/Supreme'; -import CloseButton from './styles/CloseButton'; -import SickButton from './styles/SickButton'; -import CartItem from './CartItem'; -import calcTotalPrice from '../lib/calcTotalPrice'; -import formatMoney from '../lib/formatMoney'; -import TakeMyMoney from './TakeMyMoney'; - -const LOCAL_STATE_QUERY = gql` - query { - cartOpen @client - } -`; - -const TOGGLE_CART_MUTATION = gql` - mutation { - toggleCart @client - } -`; -/* eslint-disable */ -const Composed = adopt({ - user: ({ render }) => <User>{render}</User>, - toggleCart: ({ render }) => <Mutation mutation={TOGGLE_CART_MUTATION}>{render}</Mutation>, - localState: ({ render }) => <Query query={LOCAL_STATE_QUERY}>{render}</Query>, -}); -/* eslint-enable */ - -const Cart = () => ( - <Composed> - {({ user, toggleCart, localState }) => { - const me = user.data.me; - if (!me) return null; - return ( - <CartStyles open={localState.data.cartOpen}> - <header> - <CloseButton onClick={toggleCart} title="close"> - × - </CloseButton> - <Supreme>{me.name}'s Cart</Supreme> - <p> - You Have {me.cart.length} Item{me.cart.length === 1 ? '' : 's'} in your cart. - </p> - </header> - <ul>{me.cart.map(cartItem => <CartItem key={cartItem.id} cartItem={cartItem} />)}</ul> - <footer> - <p>{formatMoney(calcTotalPrice(me.cart))}</p> - {me.cart.length && ( - <TakeMyMoney> - <SickButton>Checkout</SickButton> - </TakeMyMoney> - )} - </footer> - </CartStyles> - ); - }} - </Composed> -); - -export default Cart; -export { LOCAL_STATE_QUERY, TOGGLE_CART_MUTATION }; diff --git a/stepped-solutions/FINISHED/frontend/components/CartCount.js b/stepped-solutions/FINISHED/frontend/components/CartCount.js deleted file mode 100644 index c202d74..0000000 --- a/stepped-solutions/FINISHED/frontend/components/CartCount.js +++ /dev/null @@ -1,60 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { TransitionGroup, CSSTransition } from 'react-transition-group'; -import styled from 'styled-components'; - -const AnimationStyles = styled.span` - position: relative; - .count { - display: block; - position: relative; - transition: all 0.4s; - backface-visibility: hidden; - } - /* Intial State of the entered Dot */ - .count-enter { - transform: scale(4) rotateX(0.5turn); - } - .count-enter-active { - transform: rotateX(0); - } - .count-exit { - top: 0; - position: absolute; - transform: rotateX(0); - } - .count-exit-active { - transform: scale(4) rotateX(0.5turn); - } -`; - -const Dot = styled.div` - background: ${props => props.theme.red}; - color: white; - border-radius: 50%; - padding: 0.5rem; - line-height: 2rem; - min-width: 3rem; - margin-left: 1rem; - font-weight: 100; - font-feature-settings: 'tnum'; - font-variant-numeric: tabular-nums; -`; - -const CartCount = ({ count }) => ( - <AnimationStyles> - <TransitionGroup> - <CSSTransition - unmountOnExit - className="count" - classNames="count" - key={count} - timeout={{ enter: 400, exit: 400 }} - > - <Dot>{count}</Dot> - </CSSTransition> - </TransitionGroup> - </AnimationStyles> -); - -export default CartCount; diff --git a/stepped-solutions/FINISHED/frontend/components/CartItem.js b/stepped-solutions/FINISHED/frontend/components/CartItem.js deleted file mode 100644 index b0ce62e..0000000 --- a/stepped-solutions/FINISHED/frontend/components/CartItem.js +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; -import PropTypes from 'prop-types'; -import formatMoney from '../lib/formatMoney'; -import RemoveFromCart from './RemoveFromCart'; - -const CartItemStyles = styled.li` - padding: 1rem 0; - border-bottom: 1px solid ${props => props.theme.lightgrey}; - display: grid; - align-items: center; - grid-template-columns: auto 1fr auto; - img { - margin-right: 10px; - } - h3, - p { - margin: 0; - } -`; - -const CartItem = ({ cartItem }) => { - // first check if that item exists - if (!cartItem.item) - return ( - <CartItemStyles> - <p>This Item has been removed</p> - <RemoveFromCart id={cartItem.id} /> - </CartItemStyles> - ); - return ( - <CartItemStyles> - <img width="100" src={cartItem.item.image} alt={cartItem.item.title} /> - <div className="cart-item-details"> - <h3>{cartItem.item.title}</h3> - <p> - {formatMoney(cartItem.item.price * cartItem.quantity)} - {' - '} - <em> - {cartItem.quantity} × {formatMoney(cartItem.item.price)} each - </em> - </p> - </div> - <RemoveFromCart id={cartItem.id} /> - </CartItemStyles> - ); -}; - -CartItem.propTypes = { - cartItem: PropTypes.object.isRequired, -}; - -export default CartItem; diff --git a/stepped-solutions/FINISHED/frontend/components/CreateItem.js b/stepped-solutions/FINISHED/frontend/components/CreateItem.js deleted file mode 100644 index c115eac..0000000 --- a/stepped-solutions/FINISHED/frontend/components/CreateItem.js +++ /dev/null @@ -1,142 +0,0 @@ -import React, { Component } from 'react'; -import { Mutation } from 'react-apollo'; -import gql from 'graphql-tag'; -import Router from 'next/router'; -import Form from './styles/Form'; -import formatMoney from '../lib/formatMoney'; -import Error from './ErrorMessage'; - -const CREATE_ITEM_MUTATION = gql` - mutation CREATE_ITEM_MUTATION( - $title: String! - $description: String! - $price: Int! - $image: String - $largeImage: String - ) { - createItem( - title: $title - description: $description - price: $price - image: $image - largeImage: $largeImage - ) { - id - } - } -`; - -class CreateItem extends Component { - state = { - title: '', - description: '', - image: '', - largeImage: '', - price: 0, - }; - handleChange = e => { - const { name, type, value } = e.target; - const val = type === 'number' ? parseFloat(value) : value; - this.setState({ [name]: val }); - }; - - uploadFile = async e => { - const files = e.target.files; - const data = new FormData(); - data.append('file', files[0]); - data.append('upload_preset', 'sickfits'); - - const res = await fetch('https://api.cloudinary.com/v1_1/wesbostutorial/image/upload', { - method: 'POST', - body: data, - }); - const file = await res.json(); - this.setState({ - image: file.secure_url, - largeImage: file.eager[0].secure_url, - }); - }; - render() { - return ( - <Mutation mutation={CREATE_ITEM_MUTATION} variables={this.state}> - {(createItem, { loading, error }) => ( - <Form - data-test="form" - onSubmit={async e => { - // Stop the form from submitting - e.preventDefault(); - // call the mutation - const res = await createItem(); - // change them to the single item page - console.log(res); - Router.push({ - pathname: '/item', - query: { id: res.data.createItem.id }, - }); - }} - > - <Error error={error} /> - <fieldset disabled={loading} aria-busy={loading}> - <label htmlFor="file"> - Image - <input - type="file" - id="file" - name="file" - placeholder="Upload an image" - required - onChange={this.uploadFile} - /> - {this.state.image && ( - <img width="200" src={this.state.image} alt="Upload Preview" /> - )} - </label> - - <label htmlFor="title"> - Title - <input - type="text" - id="title" - name="title" - placeholder="Title" - required - value={this.state.title} - onChange={this.handleChange} - /> - </label> - - <label htmlFor="price"> - Price - <input - type="number" - id="price" - name="price" - placeholder="Price" - required - value={this.state.price} - onChange={this.handleChange} - /> - </label> - - <label htmlFor="description"> - Description - <textarea - id="description" - name="description" - placeholder="Enter A Description" - required - value={this.state.description} - onChange={this.handleChange} - /> - </label> - <button type="submit">Submit</button> - </fieldset> - </Form> - )} - </Mutation> - ); - } -} - -export default CreateItem; -export { CREATE_ITEM_MUTATION }; diff --git a/stepped-solutions/FINISHED/frontend/components/DeleteItem.js b/stepped-solutions/FINISHED/frontend/components/DeleteItem.js deleted file mode 100644 index e5e4752..0000000 --- a/stepped-solutions/FINISHED/frontend/components/DeleteItem.js +++ /dev/null @@ -1,50 +0,0 @@ -import React, { Component } from 'react'; -import { Mutation } from 'react-apollo'; -import gql from 'graphql-tag'; -import { ALL_ITEMS_QUERY } from './Items'; - -const DELETE_ITEM_MUTATION = gql` - mutation DELETE_ITEM_MUTATION($id: ID!) { - deleteItem(id: $id) { - id - } - } -`; - -class DeleteItem extends Component { - update = (cache, payload) => { - // manually update the cache on the client, so it matches the server - // 1. Read the cache for the items we want - const data = cache.readQuery({ query: ALL_ITEMS_QUERY }); - console.log(data, payload); - // 2. Filter the deleted itemout of the page - data.items = data.items.filter(item => item.id !== payload.data.deleteItem.id); - // 3. Put the items back! - cache.writeQuery({ query: ALL_ITEMS_QUERY, data }); - }; - render() { - return ( - <Mutation - mutation={DELETE_ITEM_MUTATION} - variables={{ id: this.props.id }} - update={this.update} - > - {(deleteItem, { error }) => ( - <button - onClick={() => { - if (confirm('Are you sure you want to delete this item?')) { - deleteItem().catch(err => { - alert(err.message); - }); - } - }} - > - {this.props.children} - </button> - )} - </Mutation> - ); - } -} - -export default DeleteItem; diff --git a/stepped-solutions/FINISHED/frontend/components/ErrorMessage.js b/stepped-solutions/FINISHED/frontend/components/ErrorMessage.js deleted file mode 100644 index 52d59a8..0000000 --- a/stepped-solutions/FINISHED/frontend/components/ErrorMessage.js +++ /dev/null @@ -1,51 +0,0 @@ -import styled from 'styled-components'; -import React from 'react'; - -import PropTypes from 'prop-types'; - -const ErrorStyles = styled.div` - padding: 2rem; - background: white; - margin: 2rem 0; - border: 1px solid rgba(0, 0, 0, 0.05); - border-left: 5px solid red; - p { - margin: 0; - font-weight: 100; - } - strong { - margin-right: 1rem; - } -`; - -const DisplayError = ({ error }) => { - if (!error || !error.message) return null; - if (error.networkError && error.networkError.result && error.networkError.result.errors.length) { - return error.networkError.result.errors.map((error, i) => ( - <ErrorStyles key={i}> - <p data-test="graphql-error"> - <strong>Shoot!</strong> - {error.message.replace('GraphQL error: ', '')} - </p> - </ErrorStyles> - )); - } - return ( - <ErrorStyles> - <p data-test="graphql-error"> - <strong>Shoot!</strong> - {error.message.replace('GraphQL error: ', '')} - </p> - </ErrorStyles> - ); -}; - -DisplayError.defaultProps = { - error: {}, -}; - -DisplayError.propTypes = { - error: PropTypes.object, -}; - -export default DisplayError; diff --git a/stepped-solutions/FINISHED/frontend/components/Header.js b/stepped-solutions/FINISHED/frontend/components/Header.js deleted file mode 100644 index 797eb8e..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Header.js +++ /dev/null @@ -1,75 +0,0 @@ -import Link from 'next/link'; -import styled from 'styled-components'; -import NProgress from 'nprogress'; -import Router from 'next/router'; -import Nav from './Nav'; -import Cart from './Cart'; -import Search from './Search'; - -Router.onRouteChangeStart = () => { - NProgress.start(); -}; -Router.onRouteChangeComplete = () => { - NProgress.done(); -}; - -Router.onRouteChangeError = () => { - NProgress.done(); -}; - -const Logo = styled.h1` - font-size: 4rem; - margin-left: 2rem; - position: relative; - z-index: 2; - transform: skew(-7deg); - a { - padding: 0.5rem 1rem; - background: ${props => props.theme.red}; - color: white; - text-transform: uppercase; - text-decoration: none; - } - @media (max-width: 1300px) { - margin: 0; - text-align: center; - } -`; - -const StyledHeader = styled.header` - .bar { - border-bottom: 10px solid ${props => props.theme.black}; - display: grid; - grid-template-columns: auto 1fr; - justify-content: space-between; - align-items: stretch; - @media (max-width: 1300px) { - grid-template-columns: 1fr; - justify-content: center; - } - } - .sub-bar { - display: grid; - grid-template-columns: 1fr auto; - border-bottom: 1px solid ${props => props.theme.lightgrey}; - } -`; - -const Header = () => ( - <StyledHeader> - <div className="bar"> - <Logo> - <Link href="/"> - <a>Sick Fits</a> - </Link> - </Logo> - <Nav /> - </div> - <div className="sub-bar"> - <Search /> - </div> - <Cart /> - </StyledHeader> -); - -export default Header; diff --git a/stepped-solutions/FINISHED/frontend/components/Item.js b/stepped-solutions/FINISHED/frontend/components/Item.js deleted file mode 100644 index 2741dcf..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Item.js +++ /dev/null @@ -1,50 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import Link from 'next/link'; -import Title from './styles/Title'; -import ItemStyles from './styles/ItemStyles'; -import PriceTag from './styles/PriceTag'; -import formatMoney from '../lib/formatMoney'; -import DeleteItem from './DeleteItem'; -import AddToCart from './AddToCart'; - -export default class Item extends Component { - static propTypes = { - item: PropTypes.object.isRequired, - }; - - render() { - const { item } = this.props; - return ( - <ItemStyles> - {item.image && <img src={item.image} alt={item.title} />} - - <Title> - <Link - href={{ - pathname: '/item', - query: { id: item.id }, - }} - > - <a>{item.title}</a> - </Link> - </Title> - <PriceTag>{formatMoney(item.price)}</PriceTag> - <p>{item.description}</p> - - <div className="buttonList"> - <Link - href={{ - pathname: 'update', - query: { id: item.id }, - }} - > - <a>Edit ✏️</a> - </Link> - <AddToCart id={item.id} /> - <DeleteItem id={item.id}>Delete This Item</DeleteItem> - </div> - </ItemStyles> - ); - } -} diff --git a/stepped-solutions/FINISHED/frontend/components/Items.js b/stepped-solutions/FINISHED/frontend/components/Items.js deleted file mode 100644 index 9b5426c..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Items.js +++ /dev/null @@ -1,61 +0,0 @@ -import React, { Component } from 'react'; -import { Query } from 'react-apollo'; -import gql from 'graphql-tag'; -import styled from 'styled-components'; -import Item from './Item'; -import Pagination from './Pagination'; -import { perPage } from '../config'; - -const ALL_ITEMS_QUERY = gql` - query ALL_ITEMS_QUERY($skip: Int = 0, $first: Int = ${perPage}) { - items(first: $first, skip: $skip, orderBy: createdAt_DESC) { - id - title - price - description - image - largeImage - } - } -`; - -const Center = styled.div` - text-align: center; -`; - -const ItemsList = styled.div` - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: 60px; - max-width: ${props => props.theme.maxWidth}; - margin: 0 auto; -`; - -class Items extends Component { - render() { - return ( - <Center> - <Pagination page={this.props.page} /> - <Query - query={ALL_ITEMS_QUERY} - // fetchPolicy="network-only" - variables={{ - skip: this.props.page * perPage - perPage, - }} - > - {({ data, error, loading }) => { - if (loading) return <p>Loading...</p>; - if (error) return <p>Error: {error.message}</p>; - return ( - <ItemsList>{data.items.map(item => <Item item={item} key={item.id} />)}</ItemsList> - ); - }} - </Query> - <Pagination page={this.props.page} /> - </Center> - ); - } -} - -export default Items; -export { ALL_ITEMS_QUERY }; diff --git a/stepped-solutions/FINISHED/frontend/components/Meta.js b/stepped-solutions/FINISHED/frontend/components/Meta.js deleted file mode 100644 index 2b98f92..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Meta.js +++ /dev/null @@ -1,13 +0,0 @@ -import Head from 'next/head'; - -const Meta = () => ( - <Head> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <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> - </Head> -); - -export default Meta; diff --git a/stepped-solutions/FINISHED/frontend/components/Nav.js b/stepped-solutions/FINISHED/frontend/components/Nav.js deleted file mode 100644 index 118db5a..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Nav.js +++ /dev/null @@ -1,49 +0,0 @@ -import Link from 'next/link'; -import { Mutation } from 'react-apollo'; -import { TOGGLE_CART_MUTATION } from './Cart'; -import NavStyles from './styles/NavStyles'; -import User from './User'; -import CartCount from './CartCount'; -import Signout from './Signout'; - -const Nav = () => ( - <User> - {({ data: { me } }) => ( - <NavStyles data-test="nav"> - <Link href="/items"> - <a>Shop</a> - </Link> - {me && ( - <> - <Link href="/sell"> - <a>Sell</a> - </Link> - <Link href="/orders"> - <a>Orders</a> - </Link> - <Link href="/me"> - <a>Account</a> - </Link> - <Signout /> - <Mutation mutation={TOGGLE_CART_MUTATION}> - {(toggleCart) => ( - <button onClick={toggleCart}> - My Cart - <CartCount count={me.cart.reduce((tally, cartItem) => tally + cartItem.quantity, 0)}></CartCount> - </button> - )} - </Mutation> - </> - )} - {!me && ( - <Link href="/signup"> - <a>Sign In</a> - </Link> - - )} - </NavStyles> - )} - </User> -); - -export default Nav; diff --git a/stepped-solutions/FINISHED/frontend/components/Order.js b/stepped-solutions/FINISHED/frontend/components/Order.js deleted file mode 100644 index 5177c0a..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Order.js +++ /dev/null @@ -1,92 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Query } from 'react-apollo'; -import { format } from 'date-fns'; -import Head from 'next/head'; -import gql from 'graphql-tag'; -import formatMoney from '../lib/formatMoney'; -import Error from './ErrorMessage'; -import OrderStyles from './styles/OrderStyles'; - -const SINGLE_ORDER_QUERY = gql` - query SINGLE_ORDER_QUERY($id: ID!) { - order(id: $id) { - id - charge - total - createdAt - user { - id - } - items { - id - title - description - price - image - quantity - } - } - } -`; - -class Order extends React.Component { - static propTypes = { - id: PropTypes.string.isRequired, - }; - render() { - return ( - <Query query={SINGLE_ORDER_QUERY} variables={{ id: this.props.id }}> - {({ data, error, loading }) => { - if (error) return <Error error={error} />; - if (loading) return <p>Loading...</p>; - const order = data.order; - return ( - <OrderStyles data-test="order"> - <Head> - <title>Sick Fits - Order {order.id}</title> - </Head> - <p> - <span>Order ID:</span> - <span>{this.props.id}</span> - </p> - <p> - <span>Charge</span> - <span>{order.charge}</span> - </p> - <p> - <span>Date</span> - <span>{format(order.createdAt, 'MMMM d, YYYY h:mm a')}</span> - </p> - <p> - <span>Order Total</span> - <span>{formatMoney(order.total)}</span> - </p> - <p> - <span>Item Count</span> - <span>{order.items.length}</span> - </p> - <div className="items"> - {order.items.map(item => ( - <div className="order-item" key={item.id}> - <img src={item.image} alt={item.title} /> - <div className="item-details"> - <h2>{item.title}</h2> - <p>Qty: {item.quantity}</p> - <p>Each: {formatMoney(item.price)}</p> - <p>SubTotal: {formatMoney(item.price * item.quantity)}</p> - <p>{item.description}</p> - </div> - </div> - ))} - </div> - </OrderStyles> - ); - }} - </Query> - ); - } -} - -export default Order; -export { SINGLE_ORDER_QUERY }; diff --git a/stepped-solutions/FINISHED/frontend/components/OrderList.js b/stepped-solutions/FINISHED/frontend/components/OrderList.js deleted file mode 100644 index e2e22ff..0000000 --- a/stepped-solutions/FINISHED/frontend/components/OrderList.js +++ /dev/null @@ -1,80 +0,0 @@ -import React from 'react'; -import { Query } from 'react-apollo'; -import { formatDistance } from 'date-fns'; -import Link from 'next/link'; -import styled from 'styled-components'; -import gql from 'graphql-tag'; -import Error from './ErrorMessage'; -import formatMoney from '../lib/formatMoney'; -import OrderItemStyles from './styles/OrderItemStyles'; - -const USER_ORDERS_QUERY = gql` - query USER_ORDERS_QUERY { - orders(orderBy: createdAt_DESC) { - id - total - createdAt - items { - id - title - price - description - quantity - image - } - } - } -`; - -const orderUl = styled.ul` - display: grid; - grid-gap: 4rem; - grid-template-columns: repeat(auto-fit, minmax(40%, 1fr)); -`; - -class OrderList extends React.Component { - render() { - return ( - <Query query={USER_ORDERS_QUERY}> - {({ data: { orders }, loading, error }) => { - if (loading) return <p>loading...</p>; - if (error) return <Error erorr={error} />; - console.log(orders); - return ( - <div> - <h2>You have {orders.length} orders</h2> - <orderUl> - {orders.map(order => ( - <OrderItemStyles key={order.id}> - <Link - href={{ - pathname: '/order', - query: { id: order.id }, - }} - > - <a> - <div className="order-meta"> - <p>{order.items.reduce((a, b) => a + b.quantity, 0)} Items</p> - <p>{order.items.length} Products</p> - <p>{formatDistance(order.createdAt, new Date())}</p> - <p>{formatMoney(order.total)}</p> - </div> - <div className="images"> - {order.items.map(item => ( - <img key={item.id} src={item.image} alt={item.title} /> - ))} - </div> - </a> - </Link> - </OrderItemStyles> - ))} - </orderUl> - </div> - ); - }} - </Query> - ); - } -} - -export default OrderList; diff --git a/stepped-solutions/FINISHED/frontend/components/Page.js b/stepped-solutions/FINISHED/frontend/components/Page.js deleted file mode 100644 index 75ab84a..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Page.js +++ /dev/null @@ -1,68 +0,0 @@ -import React, { Component } from 'react'; -import styled, { ThemeProvider, injectGlobal } from 'styled-components'; -import Header from '../components/Header'; -import Meta from '../components/Meta'; - -const theme = { - red: '#FF0000', - black: '#393939', - grey: '#3A3A3A', - lightgrey: '#E1E1E1', - offWhite: '#EDEDED', - maxWidth: '1000px', - bs: '0 12px 24px 0 rgba(0, 0, 0, 0.09)', -}; - -const StyledPage = styled.div` - background: white; - color: ${props => props.theme.black}; -`; - -const Inner = styled.div` - max-width: ${props => props.theme.maxWidth}; - margin: 0 auto; - padding: 2rem; -`; - -injectGlobal` - @font-face { - font-family: 'radnika_next'; - src: url('/static/radnikanext-medium-webfont.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - } - html { - box-sizing: border-box; - font-size: 10px; - } - *, *:before, *:after { - box-sizing: inherit; - } - body { - padding: 0; - margin: 0; - font-size: 1.5rem; - line-height: 2; - font-family: 'radnika_next'; - } - a { - text-decoration: none; - color: ${theme.black}; - } -`; - -class Page extends Component { - render() { - return ( - <ThemeProvider theme={theme}> - <StyledPage> - <Meta /> - <Header /> - <Inner>{this.props.children}</Inner> - </StyledPage> - </ThemeProvider> - ); - } -} - -export default Page; diff --git a/stepped-solutions/FINISHED/frontend/components/Pagination.js b/stepped-solutions/FINISHED/frontend/components/Pagination.js deleted file mode 100644 index b84af76..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Pagination.js +++ /dev/null @@ -1,67 +0,0 @@ -import React from 'react'; -import gql from 'graphql-tag'; -import { Query } from 'react-apollo'; -import Head from 'next/head'; -import Link from 'next/link'; -import PaginationStyles from './styles/PaginationStyles'; -import { perPage } from '../config'; - -const PAGINATION_QUERY = gql` - query PAGINATION_QUERY { - itemsConnection { - aggregate { - count - } - } - } -`; - -const Pagination = props => ( - <Query query={PAGINATION_QUERY}> - {({ data, loading, error }) => { - if (loading) return <p>Loading...</p>; - const count = data.itemsConnection.aggregate.count; - const pages = Math.ceil(count / perPage); - const page = props.page; - return ( - <PaginationStyles data-test="pagination"> - <Head> - <title> - Sick Fits! — Page {page} of {pages} - </title> - </Head> - <Link - prefetch - href={{ - pathname: 'items', - query: { page: page - 1 }, - }} - > - <a className="prev" aria-disabled={page <= 1}> - ← Prev - </a> - </Link> - <p> - Page {props.page} of - <span className="totalPages">{pages}</span>! - </p> - <p>{count} Items Total</p> - <Link - prefetch - href={{ - pathname: 'items', - query: { page: page + 1 }, - }} - > - <a className="next" aria-disabled={page >= pages}> - Next → - </a> - </Link> - </PaginationStyles> - ); - }} - </Query> -); - -export default Pagination; -export { PAGINATION_QUERY }; diff --git a/stepped-solutions/FINISHED/frontend/components/Permissions.js b/stepped-solutions/FINISHED/frontend/components/Permissions.js deleted file mode 100644 index 4b08c39..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Permissions.js +++ /dev/null @@ -1,131 +0,0 @@ -import { Query, Mutation } from 'react-apollo'; -import Error from './ErrorMessage'; -import gql from 'graphql-tag'; -import Table from './styles/Table'; -import SickButton from './styles/SickButton'; -import PropTypes from 'prop-types'; - -const possiblePermissions = [ - 'ADMIN', - 'USER', - 'ITEMCREATE', - 'ITEMUPDATE', - 'ITEMDELETE', - 'PERMISSIONUPDATE', -]; - -const UPDATE_PERMISSIONS_MUTATION = gql` - mutation updatePermissions($permissions: [Permission], $userId: ID!) { - updatePermissions(permissions: $permissions, userId: $userId) { - id - permissions - name - email - } - } -`; - -const ALL_USERS_QUERY = gql` - query { - users { - id - name - email - permissions - } - } -`; - -const Permissions = props => ( - <Query query={ALL_USERS_QUERY}> - {({ data, loading, error }) => ( - <div> - <Error error={error} /> - <div> - <h2>Manage Permissions</h2> - <Table> - <thead> - <tr> - <th>Name</th> - <th>Email</th> - {possiblePermissions.map(permission => <th key={permission}>{permission}</th>)} - <th>👇🏻</th> - </tr> - </thead> - <tbody>{data.users.map(user => <UserPermissions user={user} key={user.id} />)}</tbody> - </Table> - </div> - </div> - )} - </Query> -); - -class UserPermissions extends React.Component { - static propTypes = { - user: PropTypes.shape({ - name: PropTypes.string, - email: PropTypes.string, - id: PropTypes.string, - permissions: PropTypes.array, - }).isRequired, - }; - state = { - permissions: this.props.user.permissions, - }; - handlePermissionChange = (e) => { - const checkbox = e.target; - // take a copy of the current permissions - let updatedPermissions = [...this.state.permissions]; - // figure out if we need to remove or add this permission - if (checkbox.checked) { - // add it in! - updatedPermissions.push(checkbox.value); - } else { - updatedPermissions = updatedPermissions.filter(permission => permission !== checkbox.value); - } - this.setState({ permissions: updatedPermissions }); - }; - render() { - const user = this.props.user; - return ( - <Mutation - mutation={UPDATE_PERMISSIONS_MUTATION} - variables={{ - permissions: this.state.permissions, - userId: this.props.user.id, - }} - > - {(updatePermissions, { loading, error }) => ( - <> - {error && <tr><td colspan="8"><Error error={error} /></td></tr>} - < tr > - <td>{user.name}</td> - <td>{user.email}</td> - {possiblePermissions.map(permission => ( - <td key={permission}> - <label htmlFor={`${user.id}-permission-${permission}`}> - <input - id={`${user.id}-permission-${permission}`} - type="checkbox" - checked={this.state.permissions.includes(permission)} - value={permission} - onChange={this.handlePermissionChange} - /> - </label> - </td> - ))} - <td> - <SickButton type="button" disabled={loading} onClick={updatePermissions}> - Updat{loading ? 'ing' : 'e'} - </SickButton> - </td> - </tr> - </> - ) - } - </Mutation> - ); - } -} - -export default Permissions; diff --git a/stepped-solutions/FINISHED/frontend/components/PleaseSignIn.js b/stepped-solutions/FINISHED/frontend/components/PleaseSignIn.js deleted file mode 100644 index 80cfdbf..0000000 --- a/stepped-solutions/FINISHED/frontend/components/PleaseSignIn.js +++ /dev/null @@ -1,22 +0,0 @@ -import { Query } from 'react-apollo'; -import { CURRENT_USER_QUERY } from './User'; -import Signin from './Signin'; - -const PleaseSignIn = props => ( - <Query query={CURRENT_USER_QUERY}> - {({ data, loading }) => { - if (loading) return <p>Loading...</p>; - if (!data.me) { - return ( - <div> - <p>Please Sign In before Continuing</p> - <Signin /> - </div> - ); - } - return props.children; - }} - </Query> -); - -export default PleaseSignIn; diff --git a/stepped-solutions/FINISHED/frontend/components/RemoveFromCart.js b/stepped-solutions/FINISHED/frontend/components/RemoveFromCart.js deleted file mode 100644 index 025dae5..0000000 --- a/stepped-solutions/FINISHED/frontend/components/RemoveFromCart.js +++ /dev/null @@ -1,71 +0,0 @@ -import React from 'react'; -import { Mutation } from 'react-apollo'; -import styled from 'styled-components'; -import PropTypes from 'prop-types'; -import gql from 'graphql-tag'; -import { CURRENT_USER_QUERY } from './User'; - -const REMOVE_FROM_CART_MUTATION = gql` - mutation removeFromCart($id: ID!) { - removeFromCart(id: $id) { - id - } - } -`; - -const BigButton = styled.button` - font-size: 3rem; - background: none; - border: 0; - &:hover { - color: ${props => props.theme.red}; - cursor: pointer; - } -`; - -class RemoveFromCart extends React.Component { - static propTypes = { - id: PropTypes.string.isRequired, - }; - // This gets called as soon as we get a response back from the server after a mutation has been performed - update = (cache, payload) => { - // 1. first read the cache - const data = cache.readQuery({ query: CURRENT_USER_QUERY }); - // 2. remove that item from the cart - const cartItemId = payload.data.removeFromCart.id; - data.me.cart = data.me.cart.filter(cartItem => cartItem.id !== cartItemId); - // 3. write it back to the cache - cache.writeQuery({ query: CURRENT_USER_QUERY, data }); - }; - render() { - return ( - <Mutation - mutation={REMOVE_FROM_CART_MUTATION} - variables={{ id: this.props.id }} - update={this.update} - optimisticResponse={{ - __typename: 'Mutation', - removeFromCart: { - __typename: 'CartItem', - id: this.props.id, - }, - }} - > - {(removeFromCart, { loading, error }) => ( - <BigButton - disabled={loading} - onClick={() => { - removeFromCart().catch(err => alert(err.message)); - }} - title="Delete Item" - > - × - </BigButton> - )} - </Mutation> - ); - } -} - -export default RemoveFromCart; -export { REMOVE_FROM_CART_MUTATION }; diff --git a/stepped-solutions/FINISHED/frontend/components/RequestReset.js b/stepped-solutions/FINISHED/frontend/components/RequestReset.js deleted file mode 100644 index be21639..0000000 --- a/stepped-solutions/FINISHED/frontend/components/RequestReset.js +++ /dev/null @@ -1,60 +0,0 @@ -import React, { Component } from 'react'; -import { Mutation } from 'react-apollo'; -import gql from 'graphql-tag'; -import Form from './styles/Form'; -import Error from './ErrorMessage'; - -const REQUEST_RESET_MUTATION = gql` - mutation REQUEST_RESET_MUTATION($email: String!) { - requestReset(email: $email) { - message - } - } -`; - -class RequestReset extends Component { - state = { - email: '', - }; - saveToState = e => { - this.setState({ [e.target.name]: e.target.value }); - }; - render() { - return ( - <Mutation mutation={REQUEST_RESET_MUTATION} variables={this.state}> - {(reset, { error, loading, called }) => ( - <Form - method="post" - data-test="form" - onSubmit={async e => { - e.preventDefault(); - await reset(); - this.setState({ email: '' }); - }} - > - <fieldset disabled={loading} aria-busy={loading}> - <h2>Request a password reset</h2> - <Error error={error} /> - {!error && !loading && called && <p>Success! Check your email for a reset link!</p>} - <label htmlFor="email"> - Email - <input - type="email" - name="email" - placeholder="email" - value={this.state.email} - onChange={this.saveToState} - /> - </label> - - <button type="submit">Request Reset!</button> - </fieldset> - </Form> - )} - </Mutation> - ); - } -} - -export default RequestReset; -export { REQUEST_RESET_MUTATION }; diff --git a/stepped-solutions/FINISHED/frontend/components/Reset.js b/stepped-solutions/FINISHED/frontend/components/Reset.js deleted file mode 100644 index a132f03..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Reset.js +++ /dev/null @@ -1,84 +0,0 @@ -import React, { Component } from 'react'; -import { Mutation } from 'react-apollo'; -import gql from 'graphql-tag'; -import PropTypes from 'prop-types'; -import Form from './styles/Form'; -import Error from './ErrorMessage'; -import { CURRENT_USER_QUERY } from './User'; - -const RESET_MUTATION = gql` - mutation RESET_MUTATION($resetToken: String!, $password: String!, $confirmPassword: String!) { - resetPassword(resetToken: $resetToken, password: $password, confirmPassword: $confirmPassword) { - id - email - name - } - } -`; - -class Reset extends Component { - static propTypes = { - resetToken: PropTypes.string.isRequired, - }; - state = { - password: '', - confirmPassword: '', - }; - saveToState = e => { - this.setState({ [e.target.name]: e.target.value }); - }; - render() { - return ( - <Mutation - mutation={RESET_MUTATION} - variables={{ - resetToken: this.props.resetToken, - password: this.state.password, - confirmPassword: this.state.confirmPassword, - }} - refetchQueries={[{ query: CURRENT_USER_QUERY }]} - > - {(reset, { error, loading, called }) => ( - <Form - method="post" - onSubmit={async e => { - e.preventDefault(); - await reset(); - this.setState({ password: '', confirmPassword: '' }); - }} - > - <fieldset disabled={loading} aria-busy={loading}> - <h2>Reset Your Password</h2> - <Error error={error} /> - <label htmlFor="password"> - Password - <input - type="password" - name="password" - placeholder="password" - value={this.state.password} - onChange={this.saveToState} - /> - </label> - - <label htmlFor="confirmPassword"> - Confirm Your Password - <input - type="password" - name="confirmPassword" - placeholder="confirmPassword" - value={this.state.confirmPassword} - onChange={this.saveToState} - /> - </label> - - <button type="submit">Reset Your Password!</button> - </fieldset> - </Form> - )} - </Mutation> - ); - } -} - -export default Reset; diff --git a/stepped-solutions/FINISHED/frontend/components/Search.js b/stepped-solutions/FINISHED/frontend/components/Search.js deleted file mode 100644 index c29f93e..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Search.js +++ /dev/null @@ -1,94 +0,0 @@ -import React from 'react'; -import Downshift, { resetIdCounter } from 'downshift'; -import Router from 'next/router'; -import { ApolloConsumer } from 'react-apollo'; -import gql from 'graphql-tag'; -import debounce from 'lodash.debounce'; -import { DropDown, DropDownItem, SearchStyles } from './styles/DropDown'; - -const SEARCH_ITEMS_QUERY = gql` - query SEARCH_ITEMS_QUERY($searchTerm: String!) { - items(where: { OR: [{ title_contains: $searchTerm }, { description_contains: $searchTerm }] }) { - id - image - title - } - } -`; - -function routeToItem(item) { - Router.push({ - pathname: '/item', - query: { - id: item.id, - }, - }); -} - -class AutoComplete extends React.Component { - state = { - items: [], - loading: false, - }; - onChange = debounce(async (e, client) => { - console.log('Searching...'); - // turn loading on - this.setState({ loading: true }); - // Manually query apollo client - const res = await client.query({ - query: SEARCH_ITEMS_QUERY, - variables: { searchTerm: e.target.value }, - }); - this.setState({ - items: res.data.items, - loading: false, - }); - }, 350); - render() { - resetIdCounter(); - return ( - <SearchStyles> - <Downshift onChange={routeToItem} itemToString={item => (item === null ? '' : item.title)}> - {({ getInputProps, getItemProps, isOpen, inputValue, highlightedIndex }) => ( - <div> - <ApolloConsumer> - {client => ( - <input - {...getInputProps({ - type: 'search', - placeholder: 'Search For An Item', - id: 'search', - className: this.state.loading ? 'loading' : '', - onChange: e => { - e.persist(); - this.onChange(e, client); - }, - })} - /> - )} - </ApolloConsumer> - {isOpen && ( - <DropDown> - {this.state.items.map((item, index) => ( - <DropDownItem - {...getItemProps({ item })} - key={item.id} - highlighted={index === highlightedIndex} - > - <img width="50" src={item.image} alt={item.title} /> - {item.title} - </DropDownItem> - ))} - {!this.state.items.length && - !this.state.loading && <DropDownItem> Nothing Found {inputValue}</DropDownItem>} - </DropDown> - )} - </div> - )} - </Downshift> - </SearchStyles> - ); - } -} - -export default AutoComplete; diff --git a/stepped-solutions/FINISHED/frontend/components/Signin.js b/stepped-solutions/FINISHED/frontend/components/Signin.js deleted file mode 100644 index 4fd3013..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Signin.js +++ /dev/null @@ -1,76 +0,0 @@ -import React, { Component } from 'react'; -import { Mutation } from 'react-apollo'; -import gql from 'graphql-tag'; -import Form from './styles/Form'; -import Error from './ErrorMessage'; -import { CURRENT_USER_QUERY } from './User'; - -const SIGNIN_MUTATION = gql` - mutation SIGNIN_MUTATION($email: String!, $password: String!) { - signin(email: $email, password: $password) { - id - email - name - } - } -`; - -class Signin extends Component { - state = { - name: '', - password: '', - email: '', - }; - saveToState = e => { - this.setState({ [e.target.name]: e.target.value }); - }; - render() { - return ( - <Mutation - mutation={SIGNIN_MUTATION} - variables={this.state} - refetchQueries={[{ query: CURRENT_USER_QUERY }]} - > - {(signup, { error, loading }) => ( - <Form - method="post" - onSubmit={async e => { - e.preventDefault(); - await signup(); - this.setState({ name: '', email: '', password: '' }); - }} - > - <fieldset disabled={loading} aria-busy={loading}> - <h2>Sign into your account</h2> - <Error error={error} /> - <label htmlFor="email"> - Email - <input - type="email" - name="email" - placeholder="email" - value={this.state.email} - onChange={this.saveToState} - /> - </label> - <label htmlFor="password"> - Password - <input - type="password" - name="password" - placeholder="password" - value={this.state.password} - onChange={this.saveToState} - /> - </label> - - <button type="submit">Sign In!</button> - </fieldset> - </Form> - )} - </Mutation> - ); - } -} - -export default Signin; diff --git a/stepped-solutions/FINISHED/frontend/components/Signout.js b/stepped-solutions/FINISHED/frontend/components/Signout.js deleted file mode 100644 index f852531..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Signout.js +++ /dev/null @@ -1,19 +0,0 @@ -import React, { Component } from 'react'; -import { Mutation } from 'react-apollo'; -import gql from 'graphql-tag'; -import { CURRENT_USER_QUERY } from './User'; - -const SIGN_OUT_MUTATION = gql` - mutation SIGN_OUT_MUTATION { - signout { - message - } - } -`; - -const Signout = props => ( - <Mutation mutation={SIGN_OUT_MUTATION} refetchQueries={[{ query: CURRENT_USER_QUERY }]}> - {signout => <button onClick={signout}>Sign Out</button>} - </Mutation> -); -export default Signout; diff --git a/stepped-solutions/FINISHED/frontend/components/Signup.js b/stepped-solutions/FINISHED/frontend/components/Signup.js deleted file mode 100644 index e2f1a3f..0000000 --- a/stepped-solutions/FINISHED/frontend/components/Signup.js +++ /dev/null @@ -1,87 +0,0 @@ -import React, { Component } from 'react'; -import { Mutation } from 'react-apollo'; -import gql from 'graphql-tag'; -import Form from './styles/Form'; -import Error from './ErrorMessage'; -import { CURRENT_USER_QUERY } from './User'; - -const SIGNUP_MUTATION = gql` - mutation SIGNUP_MUTATION($email: String!, $name: String!, $password: String!) { - signup(email: $email, name: $name, password: $password) { - id - email - name - } - } -`; - -class Signup extends Component { - state = { - name: '', - email: '', - password: '', - }; - saveToState = e => { - this.setState({ [e.target.name]: e.target.value }); - }; - render() { - return ( - <Mutation - mutation={SIGNUP_MUTATION} - variables={this.state} - refetchQueries={[{ query: CURRENT_USER_QUERY }]} - > - {(signup, { error, loading }) => ( - <Form - method="post" - onSubmit={async e => { - e.preventDefault(); - await signup(); - this.setState({ name: '', email: '', password: '' }); - }} - > - <fieldset disabled={loading} aria-busy={loading}> - <h2>Sign Up for An Account</h2> - <Error error={error} /> - <label htmlFor="email"> - Email - <input - type="email" - name="email" - placeholder="email" - value={this.state.email} - onChange={this.saveToState} - /> - </label> - <label htmlFor="name"> - Name - <input - type="text" - name="name" - placeholder="name" - value={this.state.name} - onChange={this.saveToState} - /> - </label> - <label htmlFor="password"> - Password - <input - type="password" - name="password" - placeholder="password" - value={this.state.password} - onChange={this.saveToState} - /> - </label> - - <button type="submit">Sign Up!</button> - </fieldset> - </Form> - )} - </Mutation> - ); - } -} - -export default Signup; -export { SIGNUP_MUTATION }; diff --git a/stepped-solutions/FINISHED/frontend/components/SingleItem.js b/stepped-solutions/FINISHED/frontend/components/SingleItem.js deleted file mode 100644 index 145b5ae..0000000 --- a/stepped-solutions/FINISHED/frontend/components/SingleItem.js +++ /dev/null @@ -1,70 +0,0 @@ -import React, { Component } from 'react'; -import gql from 'graphql-tag'; -import { Query } from 'react-apollo'; -import Error from './ErrorMessage'; -import styled from 'styled-components'; -import Head from 'next/head'; - -const SingleItemStyles = styled.div` - max-width: 1200px; - margin: 2rem auto; - box-shadow: ${props => props.theme.bs}; - display: grid; - grid-auto-columns: 1fr; - grid-auto-flow: column; - min-height: 800px; - img { - width: 100%; - height: 100%; - object-fit: contain; - } - .details { - margin: 3rem; - font-size: 2rem; - } -`; - -const SINGLE_ITEM_QUERY = gql` - query SINGLE_ITEM_QUERY($id: ID!) { - item(where: { id: $id }) { - id - title - description - largeImage - } - } -`; -class SingleItem extends Component { - render() { - return ( - <Query - query={SINGLE_ITEM_QUERY} - variables={{ - id: this.props.id, - }} - > - {({ error, loading, data }) => { - if (error) return <Error error={error} />; - if (loading) return <p>Loading...</p>; - if (!data.item) return <p>No Item Found for {this.props.id}</p>; - const item = data.item; - return ( - <SingleItemStyles> - <Head> - <title>Sick Fits | {item.title}</title> - </Head> - <img src={item.largeImage} alt={item.title} /> - <div className="details"> - <h2>Viewing {item.title}</h2> - <p>{item.description}</p> - </div> - </SingleItemStyles> - ); - }} - </Query> - ); - } -} - -export default SingleItem; -export { SINGLE_ITEM_QUERY }; diff --git a/stepped-solutions/FINISHED/frontend/components/TakeMyMoney.js b/stepped-solutions/FINISHED/frontend/components/TakeMyMoney.js deleted file mode 100644 index ca87832..0000000 --- a/stepped-solutions/FINISHED/frontend/components/TakeMyMoney.js +++ /dev/null @@ -1,79 +0,0 @@ -import React from 'react'; -import StripeCheckout from 'react-stripe-checkout'; -import { Mutation } from 'react-apollo'; -import Router from 'next/router'; -import NProgress from 'nprogress'; -import PropTypes from 'prop-types'; -import gql from 'graphql-tag'; -import calcTotalPrice from '../lib/calcTotalPrice'; -import Error from './ErrorMessage'; -import User, { CURRENT_USER_QUERY } from './User'; - -const CREATE_ORDER_MUTATION = gql` - mutation createOrder($token: String!) { - createOrder(token: $token) { - id - charge - total - items { - id - title - } - } - } -`; - -function totalItems(cart) { - return cart.reduce((tally, cartItem) => tally + cartItem.quantity, 0); -} - -class TakeMyMoney extends React.Component { - onToken = async (res, createOrder) => { - NProgress.start(); - // manually call the mutation once we have the stripe token - const order = await createOrder({ - variables: { - token: res.id, - }, - }).catch(err => { - alert(err.message); - }); - Router.push({ - pathname: '/order', - query: { id: order.data.createOrder.id }, - }); - }; - render() { - return ( - <User> - {({ data: { me }, loading }) => { - if (loading) return null; - return ( - <Mutation - mutation={CREATE_ORDER_MUTATION} - refetchQueries={[{ query: CURRENT_USER_QUERY }]} - > - {createOrder => ( - <StripeCheckout - amount={calcTotalPrice(me.cart)} - name="Sick Fits" - description={`Order of ${totalItems(me.cart)} items!`} - image={me.cart.length && me.cart[0].item && me.cart[0].item.image} - stripeKey="pk_test_Vtknn6vSdcZWSG2JWvEiWSqC" - currency="USD" - email={me.email} - token={res => this.onToken(res, createOrder)} - > - {this.props.children} - </StripeCheckout> - )} - </Mutation> - ); - }} - </User> - ); - } -} - -export default TakeMyMoney; -export { CREATE_ORDER_MUTATION }; diff --git a/stepped-solutions/FINISHED/frontend/components/UpdateItem.js b/stepped-solutions/FINISHED/frontend/components/UpdateItem.js deleted file mode 100644 index 11aef32..0000000 --- a/stepped-solutions/FINISHED/frontend/components/UpdateItem.js +++ /dev/null @@ -1,117 +0,0 @@ -import React, { Component } from 'react'; -import { Mutation, Query } from 'react-apollo'; -import gql from 'graphql-tag'; -import Router from 'next/router'; -import Form from './styles/Form'; -import formatMoney from '../lib/formatMoney'; -import Error from './ErrorMessage'; - -const SINGLE_ITEM_QUERY = gql` - query SINGLE_ITEM_QUERY($id: ID!) { - item(where: { id: $id }) { - id - title - description - price - } - } -`; -const UPDATE_ITEM_MUTATION = gql` - mutation UPDATE_ITEM_MUTATION($id: ID!, $title: String, $description: String, $price: Int) { - updateItem(id: $id, title: $title, description: $description, price: $price) { - id - title - description - price - } - } -`; - -class UpdateItem extends Component { - state = {}; - handleChange = e => { - const { name, type, value } = e.target; - const val = type === 'number' ? parseFloat(value) : value; - this.setState({ [name]: val }); - }; - updateItem = async (e, updateItemMutation) => { - e.preventDefault(); - console.log('Updating Item!!'); - console.log(this.state); - const res = await updateItemMutation({ - variables: { - id: this.props.id, - ...this.state, - }, - }); - console.log('Updated!!'); - }; - - render() { - return ( - <Query - query={SINGLE_ITEM_QUERY} - variables={{ - id: this.props.id, - }} - > - {({ data, loading }) => { - if (loading) return <p>Loading...</p>; - if (!data.item) return <p>No Item Found for ID {this.props.id}</p>; - return ( - <Mutation mutation={UPDATE_ITEM_MUTATION} variables={this.state}> - {(updateItem, { loading, error }) => ( - <Form onSubmit={e => this.updateItem(e, updateItem)}> - <Error error={error} /> - <fieldset disabled={loading} aria-busy={loading}> - <label htmlFor="title"> - Title - <input - type="text" - id="title" - name="title" - placeholder="Title" - required - defaultValue={data.item.title} - onChange={this.handleChange} - /> - </label> - - <label htmlFor="price"> - Price - <input - type="number" - id="price" - name="price" - placeholder="Price" - required - defaultValue={data.item.price} - onChange={this.handleChange} - /> - </label> - - <label htmlFor="description"> - Description - <textarea - id="description" - name="description" - placeholder="Enter A Description" - required - defaultValue={data.item.description} - onChange={this.handleChange} - /> - </label> - <button type="submit">Sav{loading ? 'ing' : 'e'} Changes</button> - </fieldset> - </Form> - )} - </Mutation> - ); - }} - </Query> - ); - } -} - -export default UpdateItem; -export { UPDATE_ITEM_MUTATION }; diff --git a/stepped-solutions/FINISHED/frontend/components/User.js b/stepped-solutions/FINISHED/frontend/components/User.js deleted file mode 100644 index 6f8a4fb..0000000 --- a/stepped-solutions/FINISHED/frontend/components/User.js +++ /dev/null @@ -1,41 +0,0 @@ -import { Query } from 'react-apollo'; -import gql from 'graphql-tag'; -import PropTypes from 'prop-types'; - -const CURRENT_USER_QUERY = gql` - query { - me { - id - email - name - permissions - orders { - id - } - cart { - id - quantity - item { - id - price - image - title - description - } - } - } - } -`; - -const User = props => ( - <Query {...props} query={CURRENT_USER_QUERY}> - {payload => props.children(payload)} - </Query> -); - -User.propTypes = { - children: PropTypes.func.isRequired, -}; - -export default User; -export { CURRENT_USER_QUERY }; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/CartStyles.js b/stepped-solutions/FINISHED/frontend/components/styles/CartStyles.js deleted file mode 100644 index d5ee93a..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/CartStyles.js +++ /dev/null @@ -1,47 +0,0 @@ -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/stepped-solutions/FINISHED/frontend/components/styles/CloseButton.js b/stepped-solutions/FINISHED/frontend/components/styles/CloseButton.js deleted file mode 100644 index 69fd55c..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/CloseButton.js +++ /dev/null @@ -1,13 +0,0 @@ -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/stepped-solutions/FINISHED/frontend/components/styles/DropDown.js b/stepped-solutions/FINISHED/frontend/components/styles/DropDown.js deleted file mode 100644 index df86aee..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/DropDown.js +++ /dev/null @@ -1,47 +0,0 @@ -import styled, { keyframes } from 'styled-components'; - -const DropDown = styled.div` - position: absolute; - width: 100%; - z-index: 2; - border: 1px solid ${props => props.theme.lightgrey}; -`; - -const DropDownItem = styled.div` - border-bottom: 1px solid ${props => props.theme.lightgrey}; - background: ${props => (props.highlighted ? '#f7f7f7' : 'white')}; - padding: 1rem; - transition: all 0.2s; - ${props => (props.highlighted ? 'padding-left: 2rem;' : null)}; - display: flex; - align-items: center; - border-left: 10px solid ${props => (props.highlighted ? props.theme.lightgrey : 'white')}; - img { - margin-right: 10px; - } -`; - -const glow = keyframes` - from { - box-shadow: 0 0 0px yellow; - } - - to { - box-shadow: 0 0 10px 1px yellow; - } -`; - -const SearchStyles = styled.div` - position: relative; - input { - width: 100%; - padding: 10px; - border: 0; - font-size: 2rem; - &.loading { - animation: ${glow} 0.5s ease-in-out infinite alternate; - } - } -`; - -export { DropDown, DropDownItem, SearchStyles }; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/Form.js b/stepped-solutions/FINISHED/frontend/components/styles/Form.js deleted file mode 100644 index 5717130..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/Form.js +++ /dev/null @@ -1,71 +0,0 @@ -import styled, { keyframes } from 'styled-components'; - -const loading = keyframes` - from { - background-position: 0 0; - /* rotate: 0; */ - } - - to { - background-position: 100% 100%; - /* rotate: 360deg; */ - } -`; - -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; - padding: 20px; - font-size: 1.5rem; - line-height: 1.5; - font-weight: 600; - label { - display: block; - margin-bottom: 1rem; - } - input, - textarea, - select { - width: 100%; - padding: 0.5rem; - font-size: 1rem; - 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: 0.5rem 1.2rem; - } - fieldset { - border: 0; - padding: 0; - - &[disabled] { - opacity: 0.5; - } - &::before { - height: 10px; - content: ''; - display: block; - background-image: linear-gradient(to right, #ff3019 0%, #e2b04a 50%, #ff3019 100%); - } - &[aria-busy='true']::before { - background-size: 50% auto; - animation: ${loading} 0.5s linear infinite; - } - } -`; - -Form.displayName = 'Form'; - -export default Form; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/ItemStyles.js b/stepped-solutions/FINISHED/frontend/components/styles/ItemStyles.js deleted file mode 100644 index b117d5f..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/ItemStyles.js +++ /dev/null @@ -1,39 +0,0 @@ -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: flex; - flex-direction: column; - img { - width: 100%; - height: 400px; - object-fit: cover; - } - p { - font-size: 12px; - line-height: 2; - font-weight: 300; - flex-grow: 1; - padding: 0 3rem; - font-size: 1.5rem; - } - .buttonList { - display: grid; - width: 100%; - 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}; - & > * { - background: white; - border: 0; - font-size: 1rem; - padding: 1rem; - } - } -`; - -export default Item; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/NavStyles.js b/stepped-solutions/FINISHED/frontend/components/styles/NavStyles.js deleted file mode 100644 index fe4abda..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/NavStyles.js +++ /dev/null @@ -1,66 +0,0 @@ -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; - color: ${props => props.theme.black}; - font-weight: 800; - @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/stepped-solutions/FINISHED/frontend/components/styles/OrderItemStyles.js b/stepped-solutions/FINISHED/frontend/components/styles/OrderItemStyles.js deleted file mode 100644 index 292c75d..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/OrderItemStyles.js +++ /dev/null @@ -1,44 +0,0 @@ -import styled from 'styled-components'; - -const OrderItemStyles = styled.li` - box-shadow: ${props => props.theme.bs}; - list-style: none; - padding: 2rem; - border: 1px solid ${props => props.theme.offWhite}; - h2 { - border-bottom: 2px solid red; - margin-top: 0; - margin-bottom: 2rem; - padding-bottom: 2rem; - } - - .images { - display: grid; - grid-gap: 10px; - grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); - margin-top: 1rem; - img { - height: 200px; - object-fit: cover; - width: 100%; - } - } - .order-meta { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(20px, 1fr)); - display: grid; - grid-gap: 1rem; - text-align: center; - & > * { - margin: 0; - background: rgba(0, 0, 0, 0.03); - padding: 1rem 0; - } - strong { - display: block; - margin-bottom: 1rem; - } - } -`; - -export default OrderItemStyles; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/OrderStyles.js b/stepped-solutions/FINISHED/frontend/components/styles/OrderStyles.js deleted file mode 100644 index f461b70..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/OrderStyles.js +++ /dev/null @@ -1,37 +0,0 @@ -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%; - object-fit: cover; - } - } -`; -export default OrderStyles; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/PaginationStyles.js b/stepped-solutions/FINISHED/frontend/components/styles/PaginationStyles.js deleted file mode 100644 index 30753af..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/PaginationStyles.js +++ /dev/null @@ -1,27 +0,0 @@ -import styled from 'styled-components'; - -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; - } -`; - -export default PaginationStyles; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/PriceTag.js b/stepped-solutions/FINISHED/frontend/components/styles/PriceTag.js deleted file mode 100644 index 9116681..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/PriceTag.js +++ /dev/null @@ -1,17 +0,0 @@ -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/stepped-solutions/FINISHED/frontend/components/styles/SickButton.js b/stepped-solutions/FINISHED/frontend/components/styles/SickButton.js deleted file mode 100644 index 5b5352e..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/SickButton.js +++ /dev/null @@ -1,20 +0,0 @@ -import styled from 'styled-components'; - -const SickButton = styled.button` - background: red; - color: white; - font-weight: 500; - border: 0; - border-radius: 0; - text-transform: uppercase; - font-size: 2rem; - padding: 0.8rem 1.5rem; - transform: skew(-2deg); - display: inline-block; - transition: all 0.5s; - &[disabled] { - opacity: 0.5; - } -`; - -export default SickButton; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/Supreme.js b/stepped-solutions/FINISHED/frontend/components/styles/Supreme.js deleted file mode 100644 index d946ccd..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/Supreme.js +++ /dev/null @@ -1,13 +0,0 @@ -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; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/Table.js b/stepped-solutions/FINISHED/frontend/components/styles/Table.js deleted file mode 100644 index b2cd6c4..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/Table.js +++ /dev/null @@ -1,35 +0,0 @@ -import styled from 'styled-components'; - -const Table = styled.table` - border-spacing: 0; - width: 100%; - border: 1px solid ${props => props.theme.offWhite}; - thead { - font-size: 10px; - } - td, - th { - border-bottom: 1px solid ${props => props.theme.offWhite}; - border-right: 1px solid ${props => props.theme.offWhite}; - padding: 5px; - position: relative; - &:last-child { - border-right: none; - width: 150px; - button { - width: 100%; - } - } - label { - padding: 10px 5px; - display: block; - } - } - tr { - &:hover { - background: ${props => props.theme.offWhite}; - } - } -`; - -export default Table; diff --git a/stepped-solutions/FINISHED/frontend/components/styles/Title.js b/stepped-solutions/FINISHED/frontend/components/styles/Title.js deleted file mode 100644 index e1901ec..0000000 --- a/stepped-solutions/FINISHED/frontend/components/styles/Title.js +++ /dev/null @@ -1,20 +0,0 @@ -import styled from 'styled-components'; - -const Title = styled.h3` - margin: 0 1rem; - text-align: center; - transform: skew(-5deg) rotate(-1deg); - margin-top: -3rem; - text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.1); - a { - background: ${props => props.theme.red}; - display: inline; - line-height: 1.3; - font-size: 4rem; - text-align: center; - color: white; - padding: 0 1rem; - } -`; - -export default Title; |
