diff --git a/.vscode/settings.json b/.vscode/settings.json
index 65a4f69..76d6767 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -17,6 +17,7 @@
"./web/src/Routes.js",
],
"cSpell.words": [
- "Uploader"
+ "Uploader",
+ "redwoodjs"
]
}
diff --git a/api/src/graphql/users.sdl.js b/api/src/graphql/users.sdl.js
index b714d64..1830193 100644
--- a/api/src/graphql/users.sdl.js
+++ b/api/src/graphql/users.sdl.js
@@ -9,7 +9,7 @@ export const schema = gql`
image: String
bio: String
Parts: [Part]!
- Part(partTitle: String!): Part
+ Part(partTitle: String): Part
Reaction: [PartReaction]!
Comment: [Comment]!
}
diff --git a/api/src/services/users/users.js b/api/src/services/users/users.js
index f0c8a01..cae1557 100644
--- a/api/src/services/users/users.js
+++ b/api/src/services/users/users.js
@@ -1,6 +1,7 @@
import { db } from 'src/lib/db'
import { requireAuth } from 'src/lib/auth'
import { requireOwnership } from 'src/lib/owner'
+import { UserInputError } from '@redwoodjs/api'
export const users = () => {
requireAuth({ role: 'admin' })
@@ -43,6 +44,9 @@ export const updateUserByUserName = async ({ userName, input }) => {
if(input.userName) {
input.userName = input.userName.replace(/([^a-zA-Z\d_:])/g, '-')
}
+ if(input.userName && ['new', 'edit', 'update'].includes(input.userName)) { //TODO complete this and use a regexp so that it's not case sensitive, don't want someone with the userName eDiT
+ throw new UserInputError(`You've tried to used a protected word as you userName, try something other than `)
+ }
return db.user.update({
data: input,
where: { userName },
@@ -58,7 +62,7 @@ export const deleteUser = ({ id }) => {
export const User = {
Parts: (_obj, { root }) => db.user.findOne({ where: { id: root.id } }).Part(),
- Part: (_obj, { root, ...rest }) => db.part.findOne({where: { title_userId: {
+ Part: (_obj, { root, ...rest }) => _obj.partTitle && db.part.findOne({where: { title_userId: {
title: _obj.partTitle,
userId: root.id,
}}}),
diff --git a/web/src/Routes.js b/web/src/Routes.js
index 437b3e4..547071b 100644
--- a/web/src/Routes.js
+++ b/web/src/Routes.js
@@ -17,6 +17,7 @@ const Routes = () => {
{/* Ownership enforced routes */}
+
{/* End ownership enforced routes */}
diff --git a/web/src/components/Part2Cell/Part2Cell.js b/web/src/components/Part2Cell/Part2Cell.js
index 6f1e886..a9016c4 100644
--- a/web/src/components/Part2Cell/Part2Cell.js
+++ b/web/src/components/Part2Cell/Part2Cell.js
@@ -5,7 +5,7 @@ import { useAuth } from '@redwoodjs/auth'
import PartProfile from 'src/components/PartProfile'
export const QUERY = gql`
- query FIND_PART_BY_USERNAME_TITLE($userName: String!, $partTitle: String!, $currentUserId: String) {
+ query FIND_PART_BY_USERNAME_TITLE($userName: String!, $partTitle: String, $currentUserId: String) {
userPart: userName(userName: $userName) {
id
name
@@ -52,6 +52,18 @@ const UPDATE_PART_MUTATION = gql`
}
}
`
+const CREATE_PART_MUTATION = gql`
+ mutation CreatePartMutation($input: CreatePartInput!) {
+ createPart(input: $input) {
+ id
+ title
+ user {
+ id
+ userName
+ }
+ }
+ }
+`
const TOGGLE_REACTION_MUTATION = gql`
mutation ToggleReactionMutation($input: TogglePartReactionInput!) {
togglePartReaction(input: $input){
@@ -84,7 +96,17 @@ export const Success = ({ userPart, variables: {isEditable}, refetch}) => {
addMessage('Part updated.', { classes: 'rw-flash-success' })
},
})
+ const [createUser] = useMutation(CREATE_PART_MUTATION, {
+ onCompleted: ({createPart}) => {
+ navigate(routes.part2({userName: createPart?.user?.userName, partTitle: createPart?.title}))
+ addMessage('Part Created.', { classes: 'rw-flash-success' })
+ },
+ })
const onSave = (id, input) => {
+ if(!id) {
+ createUser({ variables: { input } })
+ return
+ }
updateUser({ variables: { id, input } })
}
diff --git a/web/src/components/PartProfile/PartProfile.js b/web/src/components/PartProfile/PartProfile.js
index 874e0ad..9a7facc 100644
--- a/web/src/components/PartProfile/PartProfile.js
+++ b/web/src/components/PartProfile/PartProfile.js
@@ -33,6 +33,7 @@ const PartProfile = ({
title: part?.title,
mainImage: part?.mainImage,
description: part?.description,
+ userId: userPart?.id,
})
const setProperty = (property, value) => setInput({
...input,
@@ -43,7 +44,7 @@ const PartProfile = ({
const onImageUpload = ({cloudinaryPublicId}) => setProperty('mainImage', cloudinaryPublicId)
const onEditSaveClick = () => {
if (isEditable) {
- onSave(part.id, input)
+ input.title && onSave(part?.id, input)
return
}
navigate(routes.editPart2({userName: userPart.userName, partTitle: part.title}))
@@ -98,7 +99,7 @@ const PartProfile = ({
{/* main project center column */}
- { input?.mainImage && {
- -
- {/* */}
-
- {/* */}
+
-
+
{
isAuthenticated ?
diff --git a/web/src/pages/NewPart2Page/NewPart2Page.js b/web/src/pages/NewPart2Page/NewPart2Page.js
new file mode 100644
index 0000000..bd316a9
--- /dev/null
+++ b/web/src/pages/NewPart2Page/NewPart2Page.js
@@ -0,0 +1,20 @@
+import { useAuth } from '@redwoodjs/auth'
+
+import MainLayout from 'src/layouts/MainLayout'
+import Part2Cell from 'src/components/Part2Cell'
+
+
+const NewPart2Page = ({userName}) => {
+ const { currentUser } = useAuth()
+ return (
+
+
+
+ )
+}
+
+export default NewPart2Page
diff --git a/web/src/pages/NewPart2Page/NewPart2Page.stories.js b/web/src/pages/NewPart2Page/NewPart2Page.stories.js
new file mode 100644
index 0000000..71d540a
--- /dev/null
+++ b/web/src/pages/NewPart2Page/NewPart2Page.stories.js
@@ -0,0 +1,7 @@
+import NewPart2Page from './NewPart2Page'
+
+export const generated = () => {
+ return
+}
+
+export default { title: 'Pages/NewPart2Page' }
diff --git a/web/src/pages/NewPart2Page/NewPart2Page.test.js b/web/src/pages/NewPart2Page/NewPart2Page.test.js
new file mode 100644
index 0000000..439a42b
--- /dev/null
+++ b/web/src/pages/NewPart2Page/NewPart2Page.test.js
@@ -0,0 +1,11 @@
+import { render } from '@redwoodjs/testing'
+
+import NewPart2Page from './NewPart2Page'
+
+describe('NewPart2Page', () => {
+ it('renders successfully', () => {
+ expect(() => {
+ render()
+ }).not.toThrow()
+ })
+})