From cfd0d945376b063656e0c5b4d4958e6c8494788f Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Sat, 19 Feb 2022 15:47:38 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Working=20user=20create=20form?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 22 +++++++++ frontend/package.json | 1 + frontend/src/features/auth/UserCreate.tsx | 48 ++++++++++++++++--- frontend/src/features/auth/createUser.graphql | 10 ++++ frontend/src/types.ts | 22 +++++++++ main/api/mutations/users.py | 2 +- schema.graphql | 7 +++ 7 files changed, 105 insertions(+), 7 deletions(-) create mode 100644 frontend/src/features/auth/createUser.graphql diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b67342e..259bbee 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -18,6 +18,7 @@ "graphql": "^16.3.0", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-hook-form": "^7.27.1", "react-router-dom": "^6.2.1", "use-url-search-params": "^2.5.1" }, @@ -10119,6 +10120,21 @@ "react": "17.0.2" } }, + "node_modules/react-hook-form": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.27.1.tgz", + "integrity": "sha512-N3a7A6zIQ8DJeThisVZGtOUabTbJw+7DHJidmB9w8m3chckv2ZWKb5MHps9d2pPJqmCDoWe53Bos56bYmJms5w==", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -20129,6 +20145,12 @@ "scheduler": "^0.20.2" } }, + "react-hook-form": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.27.1.tgz", + "integrity": "sha512-N3a7A6zIQ8DJeThisVZGtOUabTbJw+7DHJidmB9w8m3chckv2ZWKb5MHps9d2pPJqmCDoWe53Bos56bYmJms5w==", + "requires": {} + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 751e81b..4fbcbf3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -26,6 +26,7 @@ "graphql": "^16.3.0", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-hook-form": "^7.27.1", "react-router-dom": "^6.2.1", "use-url-search-params": "^2.5.1" }, diff --git a/frontend/src/features/auth/UserCreate.tsx b/frontend/src/features/auth/UserCreate.tsx index a8fe541..c7caa7d 100644 --- a/frontend/src/features/auth/UserCreate.tsx +++ b/frontend/src/features/auth/UserCreate.tsx @@ -1,13 +1,49 @@ -import { useQuery } from "@apollo/client"; +import { useMutation } from "@apollo/client"; import React from "react"; +import { SubmitHandler, useForm } from "react-hook-form"; -import { AllUsersDocument } from "../../types"; +import { CreateUserDocument } from "../../types"; + +type FormValues = { + firstName: string; + lastName: string; + email: string; +}; export const UserCreate = () => { - const { data, loading } = useQuery(AllUsersDocument); + const { + register, + handleSubmit, + reset, + formState: { errors }, + } = useForm(); + const [createUser, { loading: creating }] = useMutation(CreateUserDocument); - if (loading) return
Loading...
; + const onSubmit: SubmitHandler = async (data) => { + try { + await createUser({ variables: data }); + } catch (err) { + console.error("woops", err); + return; + } + reset(); + }; - const allUsers = data?.allUsers || []; - return
TODO
; + return ( +
+ + + {errors.firstName && This field is required} +
+ + + {errors.lastName && This field is required} +
+ + + {errors.email && This field is required} +
+ +
+ ); }; diff --git a/frontend/src/features/auth/createUser.graphql b/frontend/src/features/auth/createUser.graphql new file mode 100644 index 0000000..5573228 --- /dev/null +++ b/frontend/src/features/auth/createUser.graphql @@ -0,0 +1,10 @@ +mutation CreateUser($firstName: String!, $lastName: String!, $email: String!) { + createUser(input: {firstName: $firstName, lastName: $lastName, email: $email}) { + id + firstName + lastName + profile { + id + } + } +} diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 51d924d..e6fad2a 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -69,6 +69,7 @@ export type Mutation = { __typename?: 'Mutation'; createDeposit: CreateDepositResponse; createOrder: CreateOrderResponse; + createUser: User; }; @@ -84,6 +85,11 @@ export type MutationCreateOrderArgs = { orderLines: Array; }; + +export type MutationCreateUserArgs = { + input: UserInput; +}; + export type OffsetPaginationInput = { limit?: Scalars['Int']; offset?: Scalars['Int']; @@ -211,6 +217,12 @@ export type User = { profile?: Maybe; }; +export type UserInput = { + email?: InputMaybe; + firstName?: InputMaybe; + lastName?: InputMaybe; +}; + export type UserProfile = { __typename?: 'UserProfile'; balance: Scalars['Float']; @@ -221,6 +233,15 @@ export type UserProfile = { topMonths: Array; }; +export type CreateUserMutationVariables = Exact<{ + firstName: Scalars['String']; + lastName: Scalars['String']; + email: Scalars['String']; +}>; + + +export type CreateUserMutation = { __typename?: 'Mutation', createUser: { __typename?: 'User', id: string, firstName: string, lastName: string, profile?: { __typename?: 'UserProfile', id: string } | null } }; + export type CreateDepositMutationVariables = Exact<{ userId: Scalars['ID']; amount: Scalars['Int']; @@ -286,6 +307,7 @@ export type UserDetailQueryVariables = Exact<{ export type UserDetailQuery = { __typename?: 'Query', user: { __typename?: 'User', id: string, firstName: string, lastName: string, profile?: { __typename?: 'UserProfile', id: string, balance: number, image: string, lastPurchaseDate: any, orderSumTotal: number, topMonths: Array<{ __typename?: 'TopMonth', period: string, sum: number, count: number }> } | null } }; +export const CreateUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"firstName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"lastName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createUser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"firstName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"firstName"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"lastName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"lastName"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const CreateDepositDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateDeposit"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"amount"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createDeposit"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"amount"},"value":{"kind":"Variable","name":{"kind":"Name","value":"amount"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CreateDepositSuccess"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"transaction"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"balance"}}]}}]}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AboveMaxSaldo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"maxSaldo"}},{"kind":"Field","name":{"kind":"Name","value":"above"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FormErrors"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"fields"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const OrderListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"orderList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}},"defaultValue":{"kind":"IntValue","value":"10"}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}},"defaultValue":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"orderList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"order"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"created"},"value":{"kind":"EnumValue","value":"DESC"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"isExternal"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"orderSum"}},{"kind":"Field","name":{"kind":"Name","value":"customer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"balance"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"orderlines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"salePriceExt"}},{"kind":"Field","name":{"kind":"Name","value":"salePriceInt"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const TransactionListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"transactionList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}},"defaultValue":{"kind":"IntValue","value":"10"}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}},"defaultValue":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"transactionList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"order"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"created"},"value":{"kind":"EnumValue","value":"DESC"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"balance"}}]}}]}}]}}]}}]} as unknown as DocumentNode; diff --git a/main/api/mutations/users.py b/main/api/mutations/users.py index 1b56a96..4416c84 100644 --- a/main/api/mutations/users.py +++ b/main/api/mutations/users.py @@ -29,4 +29,4 @@ def register_mutation(input: UserInput) -> User: @strawberry.type class UsersMutations: - register = register_mutation + create_user = register_mutation diff --git a/schema.graphql b/schema.graphql index 11e95f9..a0c7792 100644 --- a/schema.graphql +++ b/schema.graphql @@ -51,6 +51,7 @@ scalar JSONScalar type Mutation { createOrder(customerId: ID!, orderLines: [OrderLineInput!]!, isExternal: Boolean! = false): CreateOrderResponse! createDeposit(userId: ID!, amount: Int!): CreateDepositResponse! + createUser(input: UserInput!): User! } input OffsetPaginationInput { @@ -149,6 +150,12 @@ type User { profile: UserProfile } +input UserInput { + email: String + firstName: String + lastName: String +} + type UserProfile { id: ID! balance: Float!