From 2791dca412bed4bea913af4fd8d3f1250fe11b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C4=B1dvan=20Akca?= Date: Fri, 31 Mar 2023 12:35:59 +0300 Subject: [PATCH 1/3] feat(profile): add capability to update user's full name --- .../src/graphql/mutations/update-user.ts | 2 + packages/backend/src/graphql/schema.graphql | 1 + .../web/src/graphql/mutations/update-user.ts | 1 + packages/web/src/locales/en.json | 5 +- .../web/src/pages/ProfileSettings/index.tsx | 58 +++++++++++++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/graphql/mutations/update-user.ts b/packages/backend/src/graphql/mutations/update-user.ts index 94515464..8e0a5de8 100644 --- a/packages/backend/src/graphql/mutations/update-user.ts +++ b/packages/backend/src/graphql/mutations/update-user.ts @@ -4,6 +4,7 @@ type Params = { input: { email: string; password: string; + fullName: string; }; }; @@ -15,6 +16,7 @@ const updateUser = async ( const user = await context.currentUser.$query().patchAndFetch({ email: params.input.email, password: params.input.password, + fullName: params.input.fullName, }); return user; diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index 4dec2ecc..458abe2e 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -351,6 +351,7 @@ input CreateUserInput { input UpdateUserInput { email: String password: String + fullName: String } input ForgotPasswordInput { diff --git a/packages/web/src/graphql/mutations/update-user.ts b/packages/web/src/graphql/mutations/update-user.ts index fa188cc7..e445a4c9 100644 --- a/packages/web/src/graphql/mutations/update-user.ts +++ b/packages/web/src/graphql/mutations/update-user.ts @@ -5,6 +5,7 @@ export const UPDATE_USER = gql` updateUser(input: $input) { id email + fullName updatedAt } } diff --git a/packages/web/src/locales/en.json b/packages/web/src/locales/en.json index 56b65f62..324a48f8 100644 --- a/packages/web/src/locales/en.json +++ b/packages/web/src/locales/en.json @@ -83,8 +83,11 @@ "execution.noDataTitle": "No data", "execution.noDataMessage": "We successfully ran the execution, but there was no new data to process.", "profileSettings.title": "My Profile", + "profileSettings.fullName": "Full name", + "profileSettings.updateFullName": "Update full name", "profileSettings.email": "Email", "profileSettings.updateEmail": "Update email", + "profileSettings.updatedFullName": "Your full name has been updated.", "profileSettings.newPassword": "New password", "profileSettings.confirmNewPassword": "Confirm new password", "profileSettings.updatedEmail": "Your email has been updated.", @@ -154,4 +157,4 @@ "invoices.amount": "Amount", "invoices.invoice": "Invoice", "invoices.link": "Link" -} \ No newline at end of file +} diff --git a/packages/web/src/pages/ProfileSettings/index.tsx b/packages/web/src/pages/ProfileSettings/index.tsx index f13968f1..921ec74c 100644 --- a/packages/web/src/pages/ProfileSettings/index.tsx +++ b/packages/web/src/pages/ProfileSettings/index.tsx @@ -19,6 +19,12 @@ import { UPDATE_USER } from 'graphql/mutations/update-user'; import useFormatMessage from 'hooks/useFormatMessage'; import useCurrentUser from 'hooks/useCurrentUser'; +const fullNameValidationSchema = yup + .object({ + fullName: yup.string().required(), + }) + .required(); + const emailValidationSchema = yup .object({ email: yup.string().email().required(), @@ -49,6 +55,22 @@ function ProfileSettings() { const formatMessage = useFormatMessage(); const [updateUser] = useMutation(UPDATE_USER); + const handleFullNameUpdate = async (data: any) => { + const fullName = data.fullName; + + await updateUser({ + variables: { + input: { + fullName, + }, + }, + }); + + enqueueSnackbar(formatMessage('profileSettings.updatedFullName'), { + variant: 'success', + }); + }; + const handleEmailUpdate = async (data: any) => { const email = data.email; @@ -100,6 +122,42 @@ function ProfileSettings() { + ( + <> + + + + + )} + /> + Date: Wed, 5 Apr 2023 15:07:28 +0300 Subject: [PATCH 2/3] feat(profile): combine forms --- packages/web/src/locales/en.json | 8 +- .../web/src/pages/ProfileSettings/index.tsx | 138 ++---------------- 2 files changed, 18 insertions(+), 128 deletions(-) diff --git a/packages/web/src/locales/en.json b/packages/web/src/locales/en.json index 324a48f8..3ee5fd94 100644 --- a/packages/web/src/locales/en.json +++ b/packages/web/src/locales/en.json @@ -84,15 +84,11 @@ "execution.noDataMessage": "We successfully ran the execution, but there was no new data to process.", "profileSettings.title": "My Profile", "profileSettings.fullName": "Full name", - "profileSettings.updateFullName": "Update full name", "profileSettings.email": "Email", - "profileSettings.updateEmail": "Update email", - "profileSettings.updatedFullName": "Your full name has been updated.", + "profileSettings.updateProfile": "Update your profile", + "profileSettings.updatedProfile": "Your profile has been updated.", "profileSettings.newPassword": "New password", "profileSettings.confirmNewPassword": "Confirm new password", - "profileSettings.updatedEmail": "Your email has been updated.", - "profileSettings.updatedPassword": "Your password has been updated.", - "profileSettings.updatePassword": "Update password", "profileSettings.deleteMyAccount": "Delete my account", "profileSettings.deleteAccount": "Delete account", "profileSettings.deleteAccountSubtitle": "This will permanently delete...", diff --git a/packages/web/src/pages/ProfileSettings/index.tsx b/packages/web/src/pages/ProfileSettings/index.tsx index 921ec74c..fe08070f 100644 --- a/packages/web/src/pages/ProfileSettings/index.tsx +++ b/packages/web/src/pages/ProfileSettings/index.tsx @@ -19,24 +19,13 @@ import { UPDATE_USER } from 'graphql/mutations/update-user'; import useFormatMessage from 'hooks/useFormatMessage'; import useCurrentUser from 'hooks/useCurrentUser'; -const fullNameValidationSchema = yup +const validationSchema = yup .object({ fullName: yup.string().required(), - }) - .required(); - -const emailValidationSchema = yup - .object({ email: yup.string().email().required(), - }) - .required(); - -const passwordValidationSchema = yup - .object({ - password: yup.string().required(), + password: yup.string(), confirmPassword: yup .string() - .required() .oneOf([yup.ref('password')], 'Passwords must match'), }) .required(); @@ -49,71 +38,29 @@ const StyledForm = styled(Form)` function ProfileSettings() { const [showDeleteAccountConfirmation, setShowDeleteAccountConfirmation] = React.useState(false); - const [passwordDefaultValues, setPasswordDefaultValues] = React.useState({}); const { enqueueSnackbar } = useSnackbar(); const currentUser = useCurrentUser(); const formatMessage = useFormatMessage(); const [updateUser] = useMutation(UPDATE_USER); - const handleFullNameUpdate = async (data: any) => { - const fullName = data.fullName; - + const handleProfileSettingsUpdate = async (data: any) => { + const { fullName , password, email } = data; await updateUser({ variables: { input: { fullName, - }, - }, - }); - - enqueueSnackbar(formatMessage('profileSettings.updatedFullName'), { - variant: 'success', - }); - }; - - const handleEmailUpdate = async (data: any) => { - const email = data.email; - - await updateUser({ - variables: { - input: { - email, - }, - }, - optimisticResponse: { - updateUser: { - __typename: 'User', - email, - }, - }, - }); - - enqueueSnackbar(formatMessage('profileSettings.updatedEmail'), { - variant: 'success', - }); - }; - - const handlePasswordUpdate = async (data: any) => { - const password = data.password; - - setPasswordDefaultValues({ - password, - confirmPassword: data.confirmPassword, - }); - - await updateUser({ - variables: { - input: { password, + email, }, }, }); - enqueueSnackbar(formatMessage('profileSettings.updatedPassword'), { + enqueueSnackbar(formatMessage('profileSettings.updatedProfile'), { variant: 'success', }); }; + return ( @@ -123,9 +70,9 @@ function ProfileSettings() { - - - )} - /> - - ( - <> - - - )} - /> - - ( - <> @@ -225,7 +119,7 @@ function ProfileSettings() { fullWidth name="confirmPassword" label={formatMessage('profileSettings.confirmNewPassword')} - margin="normal" + margin='dense' type="password" error={ touchedFields.confirmPassword && !!errors?.confirmPassword @@ -242,7 +136,7 @@ function ProfileSettings() { type="submit" disabled={!isDirty || !isValid || isSubmitting} > - {formatMessage('profileSettings.updatePassword')} + {formatMessage('profileSettings.updateProfile')} )} From c64ca9d9b7a50748a24c6f0e8ff2e3c157c16892 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Thu, 6 Apr 2023 13:34:43 +0000 Subject: [PATCH 3/3] fix(ProfileSettings): don't submit password unless changed --- .../web/src/graphql/mutations/update-user.ts | 3 +- .../src/graphql/queries/get-current-user.ts | 2 -- .../web/src/pages/ProfileSettings/index.tsx | 28 ++++++++++++++++--- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/packages/web/src/graphql/mutations/update-user.ts b/packages/web/src/graphql/mutations/update-user.ts index e445a4c9..74324829 100644 --- a/packages/web/src/graphql/mutations/update-user.ts +++ b/packages/web/src/graphql/mutations/update-user.ts @@ -4,9 +4,8 @@ export const UPDATE_USER = gql` mutation UpdateUser($input: UpdateUserInput) { updateUser(input: $input) { id - email fullName - updatedAt + email } } `; diff --git a/packages/web/src/graphql/queries/get-current-user.ts b/packages/web/src/graphql/queries/get-current-user.ts index 4d3151c3..9a17de1f 100644 --- a/packages/web/src/graphql/queries/get-current-user.ts +++ b/packages/web/src/graphql/queries/get-current-user.ts @@ -6,8 +6,6 @@ export const GET_CURRENT_USER = gql` id fullName email - createdAt - updatedAt } } `; diff --git a/packages/web/src/pages/ProfileSettings/index.tsx b/packages/web/src/pages/ProfileSettings/index.tsx index fe08070f..4cda68e6 100644 --- a/packages/web/src/pages/ProfileSettings/index.tsx +++ b/packages/web/src/pages/ProfileSettings/index.tsx @@ -19,6 +19,12 @@ import { UPDATE_USER } from 'graphql/mutations/update-user'; import useFormatMessage from 'hooks/useFormatMessage'; import useCurrentUser from 'hooks/useCurrentUser'; +type TMutationInput = { + fullName: string; + email: string; + password?: string; +} + const validationSchema = yup .object({ fullName: yup.string().required(), @@ -43,13 +49,27 @@ function ProfileSettings() { const formatMessage = useFormatMessage(); const [updateUser] = useMutation(UPDATE_USER); - const handleProfileSettingsUpdate = async (data: any) => { - const { fullName , password, email } = data; + const handleProfileSettingsUpdate = async (data: any) => { + const { fullName, password, email } = data; + + const mutationInput: TMutationInput = { + fullName, + email, + } + + if (password) { + mutationInput.password = password; + } + await updateUser({ variables: { - input: { + input: mutationInput, + }, + optimisticResponse: { + updateUser: { + __typename: 'User', + id: currentUser.id, fullName, - password, email, }, },