diff options
| author | Wes Bos <wesbos@gmail.com> | 2018-04-12 16:31:01 -0400 |
|---|---|---|
| committer | Wes Bos <wesbos@gmail.com> | 2018-04-12 16:31:01 -0400 |
| commit | 97b6de6aa437f7a913a33b9e6aa18a919faf2caf (patch) | |
| tree | 431e12a535baf1d2ad59601ee7c5e8084ae7a263 /frontend/components | |
| parent | d22616d5a675f5a381c741784333151255713b45 (diff) | |
a whole bunch of things that should be in their own commits
Diffstat (limited to 'frontend/components')
| -rw-r--r-- | frontend/components/AddToCart.js | 6 | ||||
| -rw-r--r-- | frontend/components/ErrorMessage.js | 7 | ||||
| -rw-r--r-- | frontend/components/Item.js | 2 | ||||
| -rw-r--r-- | frontend/components/Items.js | 10 | ||||
| -rw-r--r-- | frontend/components/Order.js | 12 | ||||
| -rw-r--r-- | frontend/components/Page.js | 14 | ||||
| -rw-r--r-- | frontend/components/Permissions.js | 113 | ||||
| -rw-r--r-- | frontend/components/PleaseSignIn.js | 11 | ||||
| -rw-r--r-- | frontend/components/Reset.js | 2 | ||||
| -rw-r--r-- | frontend/components/ResetRequest.js | 4 | ||||
| -rw-r--r-- | frontend/components/Search.js | 13 | ||||
| -rw-r--r-- | frontend/components/styles/SickButton.js | 5 | ||||
| -rw-r--r-- | frontend/components/styles/Table.js | 31 |
13 files changed, 133 insertions, 97 deletions
diff --git a/frontend/components/AddToCart.js b/frontend/components/AddToCart.js index 3566c0c..18186d8 100644 --- a/frontend/components/AddToCart.js +++ b/frontend/components/AddToCart.js @@ -18,7 +18,11 @@ class AddToCart extends Component { const existingIndex = data.me.cart.findIndex(cartItem => cartItem.id === newCartItem.id); if (existingIndex >= 0) { // already in cache, just replace it - data.me.cart = [...data.me.cart.slice(0, existingIndex), newCartItem, ...data.me.cart.slice(existingIndex + 1)]; + data.me.cart = [ + ...data.me.cart.slice(0, existingIndex), + newCartItem, + ...data.me.cart.slice(existingIndex + 1), + ]; } else { data.me.cart = [...data.me.cart, newCartItem]; } diff --git a/frontend/components/ErrorMessage.js b/frontend/components/ErrorMessage.js index 3731554..c73a2b7 100644 --- a/frontend/components/ErrorMessage.js +++ b/frontend/components/ErrorMessage.js @@ -18,14 +18,14 @@ const StyledError = styled.div` } `; -const DisplayError = ({ error }) => { +const DisplayError = ({ error, refetch }) => { 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) => ( <StyledError key={i}> <p> <strong>Shoot!</strong> - {error.message} + {error.message.replace('GraphQL error: ', '')} </p> </StyledError> )); @@ -34,7 +34,8 @@ const DisplayError = ({ error }) => { <StyledError> <p> <strong>Shoot!</strong> - {error.message} + {error.message.replace('GraphQL error: ', '')} + <button onClick={refetch}>Try Again</button> </p> </StyledError> ); diff --git a/frontend/components/Item.js b/frontend/components/Item.js index 2ed5742..99d8d93 100644 --- a/frontend/components/Item.js +++ b/frontend/components/Item.js @@ -83,7 +83,7 @@ class ItemComponent extends React.Component { <div className="buttonList"> <Link href={{ - pathname: '/admin/update', + pathname: '/update', query: { id: item.id }, }} > diff --git a/frontend/components/Items.js b/frontend/components/Items.js index 3c28de2..22e2d75 100644 --- a/frontend/components/Items.js +++ b/frontend/components/Items.js @@ -32,8 +32,6 @@ class ItemList extends React.Component { }; render() { const fetchPolicy = this.state.refetch ? 'network-only' : 'cache-first'; - console.log(this.state.refetch, this.props.page); - console.log(fetchPolicy); return ( <Center key={this.props.page}> <Pagination page={this.props.page} /> @@ -46,13 +44,9 @@ class ItemList extends React.Component { fetchPolicy={fetchPolicy} > {({ data, error, loading }) => { - if (loading) return <div>Loading</div>; + if (loading) return null; if (error) return <div>Error</div>; - return ( - <Items key={this.props.page}> - {data.items.map(item => <Item key={item.id} item={item} />)} - </Items> - ); + return <Items>{data.items.map(item => <Item key={item.id} item={item} />)}</Items>; }} </Query> <Pagination page={this.props.page} /> diff --git a/frontend/components/Order.js b/frontend/components/Order.js index b38254f..f6743fa 100644 --- a/frontend/components/Order.js +++ b/frontend/components/Order.js @@ -7,6 +7,7 @@ import styled from 'styled-components'; import { SINGLE_ORDER_QUERY } from '../queries'; import formatMoney from '../lib/formatMoney'; import Dump from './Dump'; +import Error from './ErrorMessage'; const OrderStyles = styled.div` max-width: 1000px; @@ -51,10 +52,15 @@ class Order extends Component { render() { return ( - <Query query={SINGLE_ORDER_QUERY} variables={{ id: this.props.id }}> - {({ data: { order }, error, loading }) => { + <Query + query={SINGLE_ORDER_QUERY} + variables={{ id: this.props.id }} + fetchPolicy="network-only" + > + {({ data, error, loading, refetch }) => { if (loading) return <p>Loading...</p>; - if (!order || error) return <p>No Order Found!</p>; + if (error) return <Error error={error} refetch={refetch} />; + const order = data.order; return ( <OrderStyles> <Head> diff --git a/frontend/components/Page.js b/frontend/components/Page.js index 3c6e3b1..ab14b10 100644 --- a/frontend/components/Page.js +++ b/frontend/components/Page.js @@ -51,10 +51,15 @@ const StyledPage = styled.div` `; class Page extends React.Component { + static propTypes = { + children: PropTypes.node.isRequired, + }; componentDidMount() { - // console.log('ComponentDidMount'); - // When the page loads, re-refetch the current user query - // client.query({ query: CURRENT_USER_QUERY, fetchPolicy: 'network-only' }); + // The first time we load in the client, we need to refetch the current user data + if (typeof window !== 'undefined' && !window.__CLIENTLOADED__) { + client.query({ query: CURRENT_USER_QUERY, fetchPolicy: 'network-only' }); + window.__CLIENTLOADED__ = true; + } } render() { return ( @@ -68,8 +73,5 @@ class Page extends React.Component { ); } } -Page.propTypes = { - children: PropTypes.node.isRequired, -}; export default Page; diff --git a/frontend/components/Permissions.js b/frontend/components/Permissions.js index 0b3976c..69a621b 100644 --- a/frontend/components/Permissions.js +++ b/frontend/components/Permissions.js @@ -1,44 +1,18 @@ import React from 'react'; import { Query, Mutation } from 'react-apollo'; -import styled from 'styled-components'; -import { BarLoader } from 'react-spinners'; -import { perPage } from '../config'; import { ALL_USERS_QUERY, UPDATE_PERMISSIONS_MUTATION } from '../queries/index'; import Error from './ErrorMessage'; -import Form from './styles/Form'; import SickButton from './styles/SickButton'; +import Table from './styles/Table'; -const PermissionsBox = styled.div` - border: 1px solid ${props => props.theme.offWhite}; - box-shadow: ${props => props.theme.bs}; - margin-bottom: 5rem; - padding: 2rem; - label { - cursor: pointer; - span { - transition: all 0.1s; - padding: 0 1rem; - display: block; - border: 1px solid ${props => props.theme.offWhite}; - border-left-width: 20px; - } - input { - display: none; - } - input:checked + span { - border-color: red; - } - margin-right: 1rem; - margin-bottom: 1rem; - } - .labels { - display: flex; - flex-wrap: wrap; - & > * { - flex: 0 1 auto; - } - } -`; +const possiblePermissions = [ + 'ADMIN', + 'USER', + 'ITEMCREATE', + 'ITEMUPDATE', + 'ITEMDELETE', + 'PERMISSIONUPDATE', +]; class User extends React.Component { state = { @@ -60,22 +34,12 @@ class User extends React.Component { return ( <Mutation mutation={UPDATE_PERMISSIONS_MUTATION}> {(updatePermissions, { loading, error }) => ( - <PermissionsBox key={user.id} className="user"> - <BarLoader className="barLoader" width="100%" height={5} color="red" loading={loading} /> + <tr key={user.id} className="user"> <Error error={error} /> - <h2> - {user.name} -- {user.email} - </h2> - <div className="labels"> - {[ - 'ADMIN', - 'USER', - 'ITEMCREATE', - 'ITEMUPDATE', - 'ITEMDELETE', - 'PERMISSIONUPDATE', - 'NUKE', - ].map(permission => ( + <td>{user.name}</td> + <td>{user.email}</td> + {possiblePermissions.map(permission => ( + <td> <label key={permission} htmlFor={`${user.id}-permission-${permission}`}> <input type="checkbox" @@ -85,25 +49,26 @@ class User extends React.Component { onChange={this.handlePermissionsChange} value={permission} /> - <span>{permission}</span> </label> - ))} - </div> - <SickButton - type="button" - onClick={async () => { - const res = await updatePermissions({ - variables: { - permissions: this.state.permissions, - userId: this.props.user.id, - }, - }); - console.log(res); - }} - > - Update Permissions - </SickButton> - </PermissionsBox> + </td> + ))} + <td> + <SickButton + type="button" + disabled={loading} + onClick={async () => { + const res = await updatePermissions({ + variables: { + permissions: this.state.permissions, + userId: this.props.user.id, + }, + }); + }} + > + Updat{loading ? 'ing' : 'e'} + </SickButton> + </td> + </tr> )} </Mutation> ); @@ -118,7 +83,17 @@ const Permissions = () => ( return ( <div> <h1>Manage User Permissions</h1> - {data.users.map(user => <User key={user.id} user={user} />)} + <Table> + <thead> + <tr> + <th>Name</th> + <th>Email</th> + {possiblePermissions.map(p => <th>{p}</th>)} + <th>👇🏻</th> + </tr> + </thead> + <tbody>{data.users.map(user => <User key={user.id} user={user} />)}</tbody> + </Table> </div> ); }} diff --git a/frontend/components/PleaseSignIn.js b/frontend/components/PleaseSignIn.js index 1533dbd..ff3b956 100644 --- a/frontend/components/PleaseSignIn.js +++ b/frontend/components/PleaseSignIn.js @@ -20,9 +20,16 @@ const PleaseSignIn = props => ( // check if they NO permissions, or they don't meet the requmrenets if ( !data.me.permissions || - !props.allowedPermissions.some(permission => data.me.permissions.contains(permission)) + !props.allowedPermissions.some(permission => data.me.permissions.includes(permission)) ) { - return <p>Insufficient Permissions to Manage Permissions</p>; + return ( + <p> + Insufficient Permissions to Manage Permissions. You have: + <strong>{data.me.permissions}</strong> + and you need + <strong>{props.allowedPermissions.join(' OR ')}</strong> + </p> + ); } } return props.children; diff --git a/frontend/components/Reset.js b/frontend/components/Reset.js index 5bc7f98..bbfc436 100644 --- a/frontend/components/Reset.js +++ b/frontend/components/Reset.js @@ -40,7 +40,7 @@ class Reset extends React.Component { }} refetchQueries={[{ query: CURRENT_USER_QUERY }]} > - {(resetMutation, { error, loading }) => ( + {(resetMutation, { error, loading, called }) => ( <Form onSubmit={e => this.resetPassword(e, resetMutation)}> <Error error={error} /> <fieldset disabled={loading} aria-busy={loading}> diff --git a/frontend/components/ResetRequest.js b/frontend/components/ResetRequest.js index fb6f660..4ed902e 100644 --- a/frontend/components/ResetRequest.js +++ b/frontend/components/ResetRequest.js @@ -3,6 +3,7 @@ import { Mutation } from 'react-apollo'; import { REQUEST_RESET_MUTATION } from '../queries'; import Form from './styles/Form'; import Error from './ErrorMessage'; +import Dump from './Dump'; class ResetRequest extends React.Component { state = { @@ -12,7 +13,7 @@ class ResetRequest extends React.Component { render() { return ( <Mutation mutation={REQUEST_RESET_MUTATION} variables={this.state}> - {(resetMutation, { loading, error }) => ( + {(resetMutation, { loading, error, called, data }) => ( <Form onSubmit={async e => { e.preventDefault(); @@ -21,6 +22,7 @@ class ResetRequest extends React.Component { }} > <Error error={error} /> + {!error && called && !loading && <p>Success! Check Your Email!</p>} <fieldset disabled={loading} aria-busy={loading}> <label htmlFor="email"> Email diff --git a/frontend/components/Search.js b/frontend/components/Search.js index 49c5023..a1b69cb 100644 --- a/frontend/components/Search.js +++ b/frontend/components/Search.js @@ -1,6 +1,6 @@ import Downshift from 'downshift'; import Router from 'next/router'; -import styled from 'styled-components'; +import styled, { keyframes } from 'styled-components'; import debounce from 'lodash.debounce'; import { client } from '../lib/withData'; import { SEARCH_ITEMS_QUERY } from '../queries'; @@ -35,6 +35,15 @@ const DropDownItem = styled.div` } `; +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 { @@ -43,7 +52,7 @@ const SearchStyles = styled.div` border: 0; font-size: 2rem; &.loading { - background: red; + animation: ${glow} 0.5s ease-in-out infinite alternate; } } `; diff --git a/frontend/components/styles/SickButton.js b/frontend/components/styles/SickButton.js index 3bd5001..5b5352e 100644 --- a/frontend/components/styles/SickButton.js +++ b/frontend/components/styles/SickButton.js @@ -10,6 +10,11 @@ const SickButton = styled.button` 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/frontend/components/styles/Table.js b/frontend/components/styles/Table.js new file mode 100644 index 0000000..e9d0673 --- /dev/null +++ b/frontend/components/styles/Table.js @@ -0,0 +1,31 @@ +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: 10px 5px; + position: relative; + &:last-child { + border-right: none; + width: 150px; + button { + width: 100%; + } + } + } + tr { + &:hover { + background: ${props => props.theme.offWhite}; + } + } +`; + +export default Table; |
