summaryrefslogtreecommitdiffstats
path: root/stepped-solutions/21
diff options
context:
space:
mode:
authorWes Bos <wesbos@gmail.com>2018-06-27 13:02:25 -0400
committerWes Bos <wesbos@gmail.com>2018-06-27 13:02:25 -0400
commitff7fc88e36bb66a47327fa2c7e8513b222e539ef (patch)
treeecfc2901b53d8e068252b058a07d1a4e63d42816 /stepped-solutions/21
parent4e52a98a0f78d2bedfdd31a1955639143cd26fc6 (diff)
Video 21
Diffstat (limited to 'stepped-solutions/21')
-rwxr-xr-xstepped-solutions/21/backend/src/resolvers/Mutation.js45
-rwxr-xr-xstepped-solutions/21/backend/src/schema.graphql12
-rwxr-xr-xstepped-solutions/21/frontend/components/DeleteItem.js48
-rwxr-xr-xstepped-solutions/21/frontend/components/Item.js49
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>
+ );
+ }
+}