diff options
Diffstat (limited to 'stepped-solutions/21')
| -rwxr-xr-x | stepped-solutions/21/backend/src/resolvers/Mutation.js | 45 | ||||
| -rwxr-xr-x | stepped-solutions/21/backend/src/schema.graphql | 12 | ||||
| -rwxr-xr-x | stepped-solutions/21/frontend/components/DeleteItem.js | 48 | ||||
| -rwxr-xr-x | stepped-solutions/21/frontend/components/Item.js | 49 |
4 files changed, 154 insertions, 0 deletions
diff --git a/stepped-solutions/21/backend/src/resolvers/Mutation.js b/stepped-solutions/21/backend/src/resolvers/Mutation.js new file mode 100755 index 0000000..c5ac963 --- /dev/null +++ b/stepped-solutions/21/backend/src/resolvers/Mutation.js @@ -0,0 +1,45 @@ +const Mutations = { + async createItem(parent, args, ctx, info) { + // TODO: Check if they are logged in + + const item = await ctx.db.mutation.createItem( + { + data: { + ...args, + }, + }, + info + ); + + console.log(item); + + return item; + }, + updateItem(parent, args, ctx, info) { + // first take a copy of the updates + const updates = { ...args }; + // remove the ID from the updates + delete updates.id; + // run the update method + return ctx.db.mutation.updateItem( + { + data: updates, + where: { + id: args.id, + }, + }, + info + ); + }, + async deleteItem(parent, args, ctx, info) { + const where = { id: args.id }; + // 1. find the item + const item = await ctx.db.query.item({ where }, `{ id title}`); + // 2. Check if they own that item, or have the permissions + // TODO + // 3. Delete it! + return ctx.db.mutation.deleteItem({ where }, info); + }, +}; + +module.exports = Mutations; diff --git a/stepped-solutions/21/backend/src/schema.graphql b/stepped-solutions/21/backend/src/schema.graphql new file mode 100755 index 0000000..82bb186 --- /dev/null +++ b/stepped-solutions/21/backend/src/schema.graphql @@ -0,0 +1,12 @@ +# import * from './generated/prisma.graphql' + +type Mutation { + createItem(title: String, description: String, price: Int, image: String, largeImage: String): Item! + updateItem(id: ID!, title: String, description: String, price: Int): Item! + deleteItem(id: ID!): Item +} + +type Query { + items: [Item]! + item(where: ItemWhereUniqueInput!): Item +} diff --git a/stepped-solutions/21/frontend/components/DeleteItem.js b/stepped-solutions/21/frontend/components/DeleteItem.js new file mode 100755 index 0000000..4d9bd2b --- /dev/null +++ b/stepped-solutions/21/frontend/components/DeleteItem.js @@ -0,0 +1,48 @@ +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(); + } + }} + > + {this.props.children} + </button> + )} + </Mutation> + ); + } +} + +export default DeleteItem; diff --git a/stepped-solutions/21/frontend/components/Item.js b/stepped-solutions/21/frontend/components/Item.js new file mode 100755 index 0000000..a40439b --- /dev/null +++ b/stepped-solutions/21/frontend/components/Item.js @@ -0,0 +1,49 @@ +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'; + +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> + <button>Add To Cart</button> + <DeleteItem id={item.id}>Delete This Item</DeleteItem> + </div> + </ItemStyles> + ); + } +} |
