diff --git a/api/src/graphql/parts.sdl.js b/api/src/graphql/parts.sdl.js
index 1acf7eb..ec9c3c3 100644
--- a/api/src/graphql/parts.sdl.js
+++ b/api/src/graphql/parts.sdl.js
@@ -7,6 +7,7 @@ export const schema = gql`
mainImage: String
createdAt: DateTime!
updatedAt: DateTime!
+ deleted: Boolean!
user: User!
userId: String!
Comment: [Comment]!
diff --git a/web/src/Routes.js b/web/src/Routes.js
index cfc8ce2..1a9920b 100644
--- a/web/src/Routes.js
+++ b/web/src/Routes.js
@@ -50,7 +50,8 @@ const Routes = () => {
-
+
+
)
diff --git a/web/src/components/AdminParts/AdminParts.js b/web/src/components/AdminParts/AdminParts.js
new file mode 100644
index 0000000..1f4e67b
--- /dev/null
+++ b/web/src/components/AdminParts/AdminParts.js
@@ -0,0 +1,128 @@
+import { useMutation, useFlash } from '@redwoodjs/web'
+import { Link, routes } from '@redwoodjs/router'
+
+import { QUERY } from 'src/components/AdminPartsCell'
+
+const DELETE_PART_MUTATION = gql`
+ mutation DeletePartMutation($id: String!) {
+ deletePart(id: $id) {
+ id
+ }
+ }
+`
+
+const MAX_STRING_LENGTH = 150
+
+const truncate = (text) => {
+ let output = text
+ if (text && text.length > MAX_STRING_LENGTH) {
+ output = output.substring(0, MAX_STRING_LENGTH) + '...'
+ }
+ return output
+}
+
+const jsonTruncate = (obj) => {
+ return truncate(JSON.stringify(obj, null, 2))
+}
+
+const timeTag = (datetime) => {
+ return (
+
+ )
+}
+
+const checkboxInputTag = (checked) => {
+ return
+}
+
+const AdminParts = ({ parts }) => {
+ const { addMessage } = useFlash()
+ const [deletePart] = useMutation(DELETE_PART_MUTATION, {
+ onCompleted: () => {
+ addMessage('Part deleted.', { classes: 'rw-flash-success' })
+ },
+ // This refetches the query on the list page. Read more about other ways to
+ // update the cache over here:
+ // https://www.apollographql.com/docs/react/data/mutations/#making-all-other-cache-updates
+ refetchQueries: [{ query: QUERY }],
+ awaitRefetchQueries: true,
+ })
+
+ const onDeleteClick = (id) => {
+ if (confirm('Are you sure you want to delete part ' + id + '?')) {
+ deletePart({ variables: { id } })
+ }
+ }
+
+ return (
+
+
+
+
+ | Id |
+ Title |
+ Description |
+ Code |
+ Main image |
+ Created at |
+ Updated at |
+ User id |
+ Deleted |
+ |
+
+
+
+ {parts.map((part) => (
+
+ | {truncate(part.id)} |
+ {truncate(part.title)} |
+ {truncate(part.description)} |
+ {truncate(part.code)} |
+ {truncate(part.mainImage)} |
+ {timeTag(part.createdAt)} |
+ {timeTag(part.updatedAt)} |
+ {truncate(part.userId)} |
+ {checkboxInputTag(part.deleted)} |
+
+
+ |
+
+ ))}
+
+
+
+ )
+}
+
+export default AdminParts
diff --git a/web/src/components/AdminPartsCell/AdminPartsCell.js b/web/src/components/AdminPartsCell/AdminPartsCell.js
new file mode 100644
index 0000000..a401087
--- /dev/null
+++ b/web/src/components/AdminPartsCell/AdminPartsCell.js
@@ -0,0 +1,39 @@
+import { Link, routes } from '@redwoodjs/router'
+
+import AdminParts from 'src/components/AdminParts'
+
+export const QUERY = gql`
+ query PARTS {
+ parts {
+ id
+ title
+ description
+ code
+ mainImage
+ createdAt
+ updatedAt
+ userId
+ deleted
+ user {
+ userName
+ }
+ }
+ }
+`
+
+export const Loading = () => Loading...
+
+export const Empty = () => {
+ return (
+
+ {'No parts yet. '}
+
+ {'Create one?'}
+
+
+ )
+}
+
+export const Success = ({ parts }) => {
+ return
+}
diff --git a/web/src/pages/AdminPartsPage/AdminPartsPage.js b/web/src/pages/AdminPartsPage/AdminPartsPage.js
new file mode 100644
index 0000000..b69f8c3
--- /dev/null
+++ b/web/src/pages/AdminPartsPage/AdminPartsPage.js
@@ -0,0 +1,12 @@
+import MainLayout from 'src/layouts/MainLayout'
+import AdminPartsCell from 'src/components/AdminPartsCell'
+
+const PartsPage = () => {
+ return (
+
+
+
+ )
+}
+
+export default PartsPage