summaryrefslogtreecommitdiffstats
path: root/frontend/components
diff options
context:
space:
mode:
authorWes Bos <wesbos@gmail.com>2018-04-12 16:31:01 -0400
committerWes Bos <wesbos@gmail.com>2018-04-12 16:31:01 -0400
commit97b6de6aa437f7a913a33b9e6aa18a919faf2caf (patch)
tree431e12a535baf1d2ad59601ee7c5e8084ae7a263 /frontend/components
parentd22616d5a675f5a381c741784333151255713b45 (diff)
a whole bunch of things that should be in their own commits
Diffstat (limited to 'frontend/components')
-rw-r--r--frontend/components/AddToCart.js6
-rw-r--r--frontend/components/ErrorMessage.js7
-rw-r--r--frontend/components/Item.js2
-rw-r--r--frontend/components/Items.js10
-rw-r--r--frontend/components/Order.js12
-rw-r--r--frontend/components/Page.js14
-rw-r--r--frontend/components/Permissions.js113
-rw-r--r--frontend/components/PleaseSignIn.js11
-rw-r--r--frontend/components/Reset.js2
-rw-r--r--frontend/components/ResetRequest.js4
-rw-r--r--frontend/components/Search.js13
-rw-r--r--frontend/components/styles/SickButton.js5
-rw-r--r--frontend/components/styles/Table.js31
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;