diff options
| -rw-r--r-- | backend/src/resolvers/Mutation.js | 32 | ||||
| -rw-r--r-- | backend/src/resolvers/Query.js | 3 | ||||
| -rw-r--r-- | backend/src/schema.graphql | 13 | ||||
| -rw-r--r-- | frontend/components/Pagination.js | 1 | ||||
| -rw-r--r-- | frontend/components/Reset.js | 5 | ||||
| -rw-r--r-- | frontend/components/Search.js | 15 | ||||
| -rw-r--r-- | frontend/components/Signin.js | 83 | ||||
| -rw-r--r-- | frontend/components/Signup.js | 108 | ||||
| -rw-r--r-- | frontend/queries/queries.graphql | 13 |
9 files changed, 127 insertions, 146 deletions
diff --git a/backend/src/resolvers/Mutation.js b/backend/src/resolvers/Mutation.js index 153833d..9510cd6 100644 --- a/backend/src/resolvers/Mutation.js +++ b/backend/src/resolvers/Mutation.js @@ -21,19 +21,17 @@ const mutations = { }, info ); - const token = jwt.sign({ userId: user.id }, process.env.APP_SECRET); ctx.response.cookie('token', token, { maxAge: 1000 * 60 * 60 * 24 * 365, httpOnly: true, }); - return { user }; + return user; }, async signout(parent, args, ctx, info) { ctx.response.clearCookie('token'); - // TODO: What do we return here? - return { id: 'abc123' }; + return { message: 'goodbye!' }; }, async signin(parent, { email, password }, ctx, info) { @@ -52,10 +50,7 @@ const mutations = { maxAge: 1000 * 60 * 60 * 24 * 365, httpOnly: true, }); - return { - token, - user, - }; + return user; }, // Create An Item @@ -139,11 +134,9 @@ const mutations = { from: 'wesbos@gmail.com', to: user.email, subject: 'Your password reset token', - // TODO: don't hardcore localhost here html: mail.makeANiceEmail( - `Your password reset link is here! \n\n<a href="${ctx.request.protocol}://${ctx.request.get( - 'host' - )}/reset?resetToken=${resetToken}">Click Here to reset</a>s` + `Your password reset link is here! \n\n<a href="${process.env + .FRONTEND_URL}/reset?resetToken=${resetToken}">Click Here to reset</a>` ), }); return res.updateUser; @@ -182,13 +175,14 @@ const mutations = { resetTokenExpiry: null, }, }); + const token = jwt.sign({ userId: updatedUser.id }, process.env.APP_SECRET); + ctx.response.cookie('token', token, { + maxAge: 1000 * 60 * 60 * 24 * 365, + httpOnly: true, + }); - // 6. send back the Auth Payload for the GraphQL request on the client - return { - // TODO: This should use sub instead of userId - token: jwt.sign({ userId: updatedUser.id }, process.env.APP_SECRET), - user: updatedUser, - }; + // 6. send back the User for the GraphQL request on the client + return updatedUser; }, /* Add to cart @@ -265,7 +259,6 @@ const mutations = { const userId = ctx.request.userId; const user = await ctx.db.query.user( { where: { id: userId } }, - // TODO - can we just pass info here? '{ id, name, email, cart { id, quantity, item { title, price, id, description, image } }}' ); // 1. Recalculate the total for the price @@ -303,7 +296,6 @@ const mutations = { total: charge.amount, charge: charge.id, items: { - // TODO this is going to be create instead create: orderItems, }, user: { diff --git a/backend/src/resolvers/Query.js b/backend/src/resolvers/Query.js index b1e0c5b..7e61c07 100644 --- a/backend/src/resolvers/Query.js +++ b/backend/src/resolvers/Query.js @@ -4,13 +4,12 @@ const { forwardTo } = require('prisma-binding'); const Query = { items(parent, args, ctx, info) { + console.log(args); return ctx.db.query.items({ ...args }, info); }, itemsConnection: forwardTo('db'), - // TODO: Make sure they own this order before looking it up - // order: forwardTo('db'), async order(parent, args, ctx, info) { // 1. make sure they are signed in if (!ctx.request.userId) { diff --git a/backend/src/schema.graphql b/backend/src/schema.graphql index 14d4797..bd60b61 100644 --- a/backend/src/schema.graphql +++ b/backend/src/schema.graphql @@ -7,10 +7,10 @@ type Query { } type Mutation { - signup(email: String!, password: String!, name: String!): AuthPayload! - signin(email: String!, password: String!): AuthPayload! + signup(email: String!, password: String!, name: String!): User! + signin(email: String!, password: String!): User! requestReset(email: String!): User - resetPassword(resetToken: String!, password: String!, confirmPassword: String!): AuthPayload! + resetPassword(resetToken: String!, password: String!, confirmPassword: String!): User! createItem(title: String, description: String, price: Int, image: String, largeImage: String): Item! deleteItem(id: ID!): Item! updateItem(id: ID!, title: String, description: String, price: Int): Item! @@ -18,13 +18,12 @@ type Mutation { removeFromCart(id: ID!): CartItem createOrder(token: String!): Order! updateUser(name: String): User - signout: User + signout: SuccessMessage updatePermissions(permissions: [Permission], userId: ID!): User } -type AuthPayload { - token: String! - user: User! +type SuccessMessage { + message: String } type User { diff --git a/frontend/components/Pagination.js b/frontend/components/Pagination.js index d56b100..380026d 100644 --- a/frontend/components/Pagination.js +++ b/frontend/components/Pagination.js @@ -37,7 +37,6 @@ const Pagination = props => ( const { aggregate } = data.itemsConnection; const { page } = props; const pages = Math.ceil(aggregate.count / perPage); - // TODO prefetch this return ( <PaginationStyles data-test="pagination"> <Link diff --git a/frontend/components/Reset.js b/frontend/components/Reset.js index 0815262..c4d791c 100644 --- a/frontend/components/Reset.js +++ b/frontend/components/Reset.js @@ -22,10 +22,7 @@ class Reset extends React.Component { resetPassword = async (e, resetMutation) => { e.preventDefault(); - const res = await resetMutation(); - // sign them in! - localStorage.setItem('token', res.data.resetPassword.token); - // TODO: Manually call refresh on a Query + await resetMutation(); }; render() { diff --git a/frontend/components/Search.js b/frontend/components/Search.js index eb00d93..9f43d36 100644 --- a/frontend/components/Search.js +++ b/frontend/components/Search.js @@ -64,14 +64,18 @@ class AutoComplete extends React.Component { items: [], loading: false, }; - onChange = debounce(async (e, client) => { + onChange = async (e, client) => { if (!e.target.value) { return this.setState({ items: [] }); } this.setState({ loading: true }); + this.search(client, e.target.value); + }; + + search = debounce(async (client, searchTerm) => { const res = await client.query({ query: SEARCH_ITEMS_QUERY, - variables: { searchTerm: e.target.value }, + variables: { searchTerm }, }); this.setState({ items: res.data.items, loading: false }); }, 350); @@ -112,9 +116,10 @@ class AutoComplete extends React.Component { </DropDownItem> ))} {/* Found Nothing State */} - {!this.state.items.length && ( - <DropDownItem>Nothing Found for {inputValue}...</DropDownItem> - )} + {!this.state.items.length && + !this.state.loading && ( + <DropDownItem>Nothing Found for {inputValue}...</DropDownItem> + )} </DropDown> )} </div> diff --git a/frontend/components/Signin.js b/frontend/components/Signin.js index 7a4db8c..23a5835 100644 --- a/frontend/components/Signin.js +++ b/frontend/components/Signin.js @@ -9,14 +9,6 @@ class Signin extends Component { email: `wesbos@gmail.com`, password: 'abc123', }; - - loginUser = async (e, signin, client) => { - e.preventDefault(); - const res = await signin(); - // TODO instead of refetching, can we just use the data returned? - client.query({ query: CURRENT_USER_QUERY, fetchPolicy: 'network-only' }); - }; - saveToState = e => { const { name, value } = e.target; this.setState({ [name]: value }); @@ -24,44 +16,49 @@ class Signin extends Component { render() { return ( - <ApolloConsumer> - {client => ( - <Mutation mutation={SIGNIN_MUTATION} variables={this.state}> - {(signin, { loading, error }) => ( - <Form onSubmit={e => this.loginUser(e, signin, client)}> - <Error error={error} /> - <fieldset disabled={loading} aria-busy={loading}> - <label htmlFor="email"> - Email - <input - value={this.state.email} - onChange={this.saveToState} - name="email" - type="text" - placeholder="email" - /> - </label> + <Mutation + mutation={SIGNIN_MUTATION} + variables={this.state} + refetchQueries={[{ query: CURRENT_USER_QUERY }]} + > + {(signin, { loading, error }) => ( + <Form + onSubmit={e => { + e.preventDefault(); + signin(); + }} + > + <Error error={error} /> + <fieldset disabled={loading} aria-busy={loading}> + <label htmlFor="email"> + Email + <input + value={this.state.email} + onChange={this.saveToState} + name="email" + type="text" + placeholder="email" + /> + </label> - <label htmlFor="password"> - Password - <input - type="password" - name="password" - id="password" - className="password" - placeholder="password" - value={this.state.password} - onChange={this.saveToState} - /> - </label> + <label htmlFor="password"> + Password + <input + type="password" + name="password" + id="password" + className="password" + placeholder="password" + value={this.state.password} + onChange={this.saveToState} + /> + </label> - <button type="submit">Sign In!</button> - </fieldset> - </Form> - )} - </Mutation> + <button type="submit">Sign In!</button> + </fieldset> + </Form> )} - </ApolloConsumer> + </Mutation> ); } } diff --git a/frontend/components/Signup.js b/frontend/components/Signup.js index ef622ed..624bc10 100644 --- a/frontend/components/Signup.js +++ b/frontend/components/Signup.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { Mutation, ApolloConsumer } from 'react-apollo'; +import { Mutation } from 'react-apollo'; import { SIGNUP_MUTATION, CURRENT_USER_QUERY } from '../queries/queries.graphql'; import Form from './styles/Form'; import Error from './ErrorMessage'; @@ -18,64 +18,62 @@ class Signup extends Component { render() { return ( - <ApolloConsumer> - {client => ( - <Mutation mutation={SIGNUP_MUTATION} variables={this.state}> - {(signup, { loading, error }) => ( - <Form - method="post" - onSubmit={async e => { - e.preventDefault(); - const res = await signup(); - // TODO can we return theuser from signup? - client.query({ query: CURRENT_USER_QUERY, fetchPolicy: 'network-only' }); - }} - > - <fieldset disabled={loading} aria-busy={loading}> - <Error error={error} /> - <h2>Sign Up for an Account</h2> - <label htmlFor="email"> - Email - <input - value={this.state.email} - onChange={this.saveToState} - name="email" - type="text" - placeholder="email" - /> - </label> + <Mutation + mutation={SIGNUP_MUTATION} + variables={this.state} + refetchQueries={[{ query: CURRENT_USER_QUERY }]} + > + {(signup, { loading, error }) => ( + <Form + method="post" + onSubmit={async e => { + e.preventDefault(); + const res = await signup(); + }} + > + <fieldset disabled={loading} aria-busy={loading}> + <Error error={error} /> + <h2>Sign Up for an Account</h2> + <label htmlFor="email"> + Email + <input + value={this.state.email} + onChange={this.saveToState} + name="email" + type="text" + placeholder="email" + /> + </label> - <label htmlFor="name"> - Name - <input - type="text" - name="name" - placeholder="name" - value={this.state.name} - 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="signupPassword"> - Password - <input - type="password" - name="password" - id="signupPassword" - className="password" - placeholder="password" - value={this.state.password} - onChange={this.saveToState} - /> - </label> + <label htmlFor="signupPassword"> + Password + <input + type="password" + name="password" + id="signupPassword" + className="password" + placeholder="password" + value={this.state.password} + onChange={this.saveToState} + /> + </label> - <button type="submit">Submit</button> - </fieldset> - </Form> - )} - </Mutation> + <button type="submit">Submit</button> + </fieldset> + </Form> )} - </ApolloConsumer> + </Mutation> ); } } diff --git a/frontend/queries/queries.graphql b/frontend/queries/queries.graphql index 22e5f29..2ee2c8b 100644 --- a/frontend/queries/queries.graphql +++ b/frontend/queries/queries.graphql @@ -16,18 +16,14 @@ mutation CREATE_ITEM_MUTATION($description: String!, $title: String!, $price: In mutation SIGNUP_MUTATION($email: String!, $name: String!, $password: String!) { signup(email: $email, name: $name, password: $password) { - token - user { - id - email - name - } + id + email + name } } mutation SIGNIN_MUTATION($email: String!, $password: String!) { signin(email: $email, password: $password) { - token user { id email @@ -38,7 +34,7 @@ mutation SIGNIN_MUTATION($email: String!, $password: String!) { mutation SIGN_OUT_MUTATION { signout { - id + message } } @@ -50,7 +46,6 @@ mutation REQUEST_RESET_MUTATION($email: String!) { mutation RESET_MUTATION($resetToken: String!, $password: String!, $confirmPassword: String!) { resetPassword(resetToken: $resetToken, password: $password, confirmPassword: $confirmPassword) { - token user { id email |
