@riosst100/pwa-marketplace 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/package.json +1 -1
  2. package/src/componentOverrideMapping.js +5 -1
  3. package/src/components/BecomeSeller/becomeSeller.js +184 -81
  4. package/src/components/BecomeSeller/becomeSeller.module.css +2 -3
  5. package/src/components/BecomeSellerLink/becomeSellerLink.js +45 -0
  6. package/src/components/BecomeSellerLink/becomeSellerLink.module.css +13 -0
  7. package/src/components/BecomeSellerPage/becomeSellerPage.js +9 -13
  8. package/src/components/BecomeSellerPage/becomeSellerPage.module.css +21 -0
  9. package/src/components/SellerAccountPage/index.js +1 -0
  10. package/src/components/SellerAccountPage/sellerAccountPage.js +138 -0
  11. package/src/components/SellerAccountPage/sellerAccountPage.module.css +55 -0
  12. package/src/components/SellerVerification/index.js +1 -0
  13. package/src/components/SellerVerification/sellerVerification.js +198 -0
  14. package/src/components/SellerVerification/sellerVerification.module.css +47 -0
  15. package/src/components/SellerVerificationPage/index.js +1 -0
  16. package/src/components/SellerVerificationPage/sellerVerificationPage.js +43 -0
  17. package/src/components/SellerVerificationPage/sellerVerificationPage.module.css +21 -0
  18. package/src/components/WebsiteSwitcher/websiteSwitcher.js +109 -0
  19. package/src/components/WebsiteSwitcher/websiteSwitcher.module.css +111 -0
  20. package/src/components/WebsiteSwitcher/websiteSwitcher.shimmer.js +6 -0
  21. package/src/components/WebsiteSwitcher/websiteSwitcherItem.js +47 -0
  22. package/src/components/WebsiteSwitcher/websiteSwitcherItem.module.css +20 -0
  23. package/src/intercept.js +40 -37
  24. package/src/overwrites/peregrine/lib/store/actions/user/asyncActions.js +96 -0
  25. package/src/overwrites/peregrine/lib/talons/AccountMenu/useAccountMenuItems.js +65 -0
  26. package/src/overwrites/peregrine/lib/talons/SignIn/signIn.gql.js +56 -0
  27. package/src/overwrites/peregrine/lib/talons/SignIn/useSignIn.js +226 -0
  28. package/src/overwrites/venia-ui/lib/components/Header/header.js +2 -2
  29. package/src/overwrites/venia-ui/lib/components/Header/storeSwitcher.js +2 -2
  30. package/src/talons/BecomeSeller/becomeSeller.gql.js +46 -0
  31. package/src/talons/BecomeSeller/useBecomeSeller.js +146 -0
  32. package/src/talons/BecomeSellerLink/useBecomeSellerLink.js +11 -0
  33. package/src/talons/BecomeSellerPage/useBecomeSellerPage.js +66 -0
  34. package/src/talons/SellerAccountPage/useSellerAccountPage.js +174 -0
  35. package/src/talons/WebsiteByIp/useWebsiteByIp.js +2 -0
  36. package/src/talons/WebsiteSwitcher/useWebsiteSwitcher.js +218 -0
  37. package/src/talons/WebsiteSwitcher/websiteSwitcher.gql.js +45 -0
@@ -0,0 +1,226 @@
1
+ import { useCallback, useRef, useState, useMemo } from 'react';
2
+ import { useApolloClient, useMutation } from '@apollo/client';
3
+
4
+ import { useGoogleReCaptcha } from '@magento/peregrine/lib/hooks/useGoogleReCaptcha/useGoogleReCaptcha';
5
+ import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
6
+ import { useCartContext } from '@magento/peregrine/lib/context/cart';
7
+ import { useUserContext } from '@magento/peregrine/lib/context/user';
8
+ import { useAwaitQuery } from '@magento/peregrine/lib/hooks/useAwaitQuery';
9
+ import { retrieveCartId } from '@magento/peregrine/lib/store/actions/cart';
10
+
11
+ import DEFAULT_OPERATIONS from '@magento/peregrine/lib/talons/SignIn/signIn.gql';
12
+ import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
13
+ import { BrowserPersistence } from '@magento/peregrine/lib/util';
14
+
15
+ const storage = new BrowserPersistence();
16
+
17
+ export const useSignIn = props => {
18
+ const {
19
+ handleTriggerClick,
20
+ getCartDetailsQuery,
21
+ setDefaultUsername,
22
+ showCreateAccount,
23
+ showForgotPassword
24
+ } = props;
25
+
26
+ const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
27
+ const {
28
+ createCartMutation,
29
+ getCustomerQuery,
30
+ mergeCartsMutation,
31
+ signInMutation
32
+ } = operations;
33
+
34
+ const apolloClient = useApolloClient();
35
+ const [isSigningIn, setIsSigningIn] = useState(false);
36
+
37
+ const [
38
+ { cartId },
39
+ { createCart, removeCart, getCartDetails }
40
+ ] = useCartContext();
41
+
42
+ const [
43
+ { isGettingDetails, getDetailsError },
44
+ { getUserDetails, setToken }
45
+ ] = useUserContext();
46
+
47
+ const [, { dispatch }] = useEventingContext();
48
+
49
+ const [signIn, { error: signInError }] = useMutation(signInMutation, {
50
+ fetchPolicy: 'no-cache'
51
+ });
52
+
53
+ const {
54
+ generateReCaptchaData,
55
+ recaptchaLoading,
56
+ recaptchaWidgetProps
57
+ } = useGoogleReCaptcha({
58
+ currentForm: 'CUSTOMER_LOGIN',
59
+ formAction: 'signIn'
60
+ });
61
+
62
+ const [fetchCartId] = useMutation(createCartMutation);
63
+ const [mergeCarts] = useMutation(mergeCartsMutation);
64
+ const fetchUserDetails = useAwaitQuery(getCustomerQuery);
65
+ const fetchCartDetails = useAwaitQuery(getCartDetailsQuery);
66
+
67
+ const formApiRef = useRef(null);
68
+ const setFormApi = useCallback(api => (formApiRef.current = api), []);
69
+
70
+ const handleSubmit = useCallback(
71
+ async ({ email, password }) => {
72
+ setIsSigningIn(true);
73
+ // handleTriggerClick();
74
+ try {
75
+ // Get source cart id (guest cart id).
76
+ const sourceCartId = cartId;
77
+
78
+ // Get recaptchaV3 data for login
79
+ const recaptchaData = await generateReCaptchaData();
80
+
81
+ // Sign in and set the token.
82
+ const signInResponse = await signIn({
83
+ variables: {
84
+ email,
85
+ password
86
+ },
87
+ ...recaptchaData
88
+ });
89
+
90
+ const token = signInResponse.data.generateCustomerToken.token;
91
+ await setToken(token);
92
+
93
+ // Clear all cart/customer data from cache and redux.
94
+ await apolloClient.clearCacheData(apolloClient, 'cart');
95
+ await apolloClient.clearCacheData(apolloClient, 'customer');
96
+ await removeCart();
97
+
98
+ // Create and get the customer's cart id.
99
+ await createCart({
100
+ fetchCartId
101
+ });
102
+ const destinationCartId = await retrieveCartId();
103
+
104
+ // Merge the guest cart into the customer cart.
105
+ await mergeCarts({
106
+ variables: {
107
+ destinationCartId,
108
+ sourceCartId
109
+ }
110
+ });
111
+
112
+ // Ensure old stores are updated with any new data.
113
+
114
+ await getUserDetails({ fetchUserDetails });
115
+
116
+ const { data } = await fetchUserDetails({
117
+ fetchPolicy: 'cache-only'
118
+ });
119
+
120
+ console.log(data.customer)
121
+
122
+ if (data.customer.is_seller) {
123
+ storage.setItem('is_seller', true);
124
+ }
125
+
126
+ dispatch({
127
+ type: 'USER_SIGN_IN',
128
+ payload: {
129
+ ...data.customer
130
+ }
131
+ });
132
+
133
+ getCartDetails({ fetchCartId, fetchCartDetails });
134
+ } catch (error) {
135
+ if (process.env.NODE_ENV !== 'production') {
136
+ console.error(error);
137
+ }
138
+
139
+ setIsSigningIn(false);
140
+ }
141
+ },
142
+ [
143
+ cartId,
144
+ generateReCaptchaData,
145
+ signIn,
146
+ setToken,
147
+ apolloClient,
148
+ removeCart,
149
+ createCart,
150
+ fetchCartId,
151
+ mergeCarts,
152
+ getUserDetails,
153
+ fetchUserDetails,
154
+ getCartDetails,
155
+ fetchCartDetails,
156
+ dispatch,
157
+ handleTriggerClick
158
+ ]
159
+ );
160
+
161
+ const handleForgotPassword = useCallback(() => {
162
+ const { current: formApi } = formApiRef;
163
+
164
+ if (formApi) {
165
+ setDefaultUsername(formApi.getValue('email'));
166
+ }
167
+
168
+ showForgotPassword();
169
+ }, [setDefaultUsername, showForgotPassword]);
170
+
171
+ const forgotPasswordHandleEnterKeyPress = useCallback(() => {
172
+ event => {
173
+ if (event.key === 'Enter') {
174
+ handleForgotPassword();
175
+ }
176
+ };
177
+ }, [handleForgotPassword]);
178
+
179
+ const handleCreateAccount = useCallback(() => {
180
+ const { current: formApi } = formApiRef;
181
+
182
+ if (formApi) {
183
+ setDefaultUsername(formApi.getValue('email'));
184
+ }
185
+
186
+ showCreateAccount();
187
+ }, [setDefaultUsername, showCreateAccount]);
188
+
189
+ const handleEnterKeyPress = useCallback(() => {
190
+ event => {
191
+ if (event.key === 'Enter') {
192
+ handleCreateAccount();
193
+ }
194
+ };
195
+ }, [handleCreateAccount]);
196
+
197
+ const signinHandleEnterKeyPress = useCallback(() => {
198
+ event => {
199
+ if (event.key === 'Enter') {
200
+ handleSubmit();
201
+ }
202
+ };
203
+ }, [handleSubmit]);
204
+
205
+ const errors = useMemo(
206
+ () =>
207
+ new Map([
208
+ ['getUserDetailsQuery', getDetailsError],
209
+ ['signInMutation', signInError]
210
+ ]),
211
+ [getDetailsError, signInError]
212
+ );
213
+
214
+ return {
215
+ errors,
216
+ handleCreateAccount,
217
+ handleEnterKeyPress,
218
+ signinHandleEnterKeyPress,
219
+ handleForgotPassword,
220
+ forgotPasswordHandleEnterKeyPress,
221
+ handleSubmit,
222
+ isBusy: isGettingDetails || isSigningIn || recaptchaLoading,
223
+ setFormApi,
224
+ recaptchaWidgetProps
225
+ };
226
+ };
@@ -14,9 +14,9 @@ import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
14
14
  import { useStyle } from '@magento/venia-ui/lib/classify';
15
15
  import defaultClasses from '@magento/venia-ui/lib/components/Header/header.module.css';
16
16
  import StoreSwitcher from '@magento/venia-ui/lib/components/Header/storeSwitcher';
17
- import WebsiteSwitcher from '@riosst100/pwa-marketplace/src/components/Header/websiteSwitcher';
17
+ import WebsiteSwitcher from '@riosst100/pwa-marketplace/src/components/WebsiteSwitcher/websiteSwitcher';
18
18
  import CurrencySwitcher from '@magento/venia-ui/lib/components/Header/currencySwitcher';
19
- import BecomeSellerLink from '@riosst100/pwa-marketplace/src/components/Header/becomeSellerLink';
19
+ import BecomeSellerLink from '@riosst100/pwa-marketplace/src/components/BecomeSellerLink/becomeSellerLink';
20
20
  import MegaMenu from '@magento/venia-ui/lib/components/MegaMenu';
21
21
  import PageLoadingIndicator from '@magento/venia-ui/lib/components/PageLoadingIndicator';
22
22
  import { useIntl } from 'react-intl';
@@ -74,7 +74,7 @@ const StoreSwitcher = props => {
74
74
 
75
75
  let triggerLabel;
76
76
  if (hasOnlyOneGroup) {
77
- triggerLabel = `${currentStoreName}`;
77
+ triggerLabel = currentStoreName ? `${currentStoreName}` : '';
78
78
  } else {
79
79
  triggerLabel = `${currentGroupName} - ${currentStoreName}`;
80
80
  }
@@ -90,7 +90,7 @@ const StoreSwitcher = props => {
90
90
  data-cy="StoreSwitcher-trigger"
91
91
  aria-expanded={storeMenuIsOpen}
92
92
  >
93
- {triggerLabel}
93
+ {triggerLabel || ''}
94
94
  </button>
95
95
  <div
96
96
  ref={storeMenuRef}
@@ -0,0 +1,46 @@
1
+ import { gql } from '@apollo/client';
2
+
3
+ export const BECOME_SELLER = gql`
4
+ mutation BecomeSeller(
5
+ $seller_type: String
6
+ $group_id: String!
7
+ $url_key: String!
8
+ $name: String!
9
+ $company: String
10
+ $company_registration_number: String
11
+ $country_id: String
12
+ $address_line_1: String!
13
+ $address_line_2: String
14
+ $city: String!
15
+ $region: String
16
+ $region_id: String
17
+ $postcode: String!
18
+ $contact_number: String!
19
+ ) {
20
+ becomeSeller(
21
+ input: {
22
+ seller_type: $seller_type
23
+ group_id: $group_id
24
+ url_key: $url_key
25
+ name: $name
26
+ company: $company
27
+ company_registration_number: $company_registration_number,
28
+ country_id: $country_id
29
+ address_line_1: $address_line_1
30
+ address_line_2: $address_line_2
31
+ city: $city
32
+ region: $region
33
+ region_id: $region_id
34
+ postcode: $postcode
35
+ contact_number: $contact_number
36
+ }
37
+ ) {
38
+ code
39
+ message
40
+ }
41
+ }
42
+ `;
43
+
44
+ export default {
45
+ becomeSellerMutation: BECOME_SELLER
46
+ };
@@ -0,0 +1,146 @@
1
+ import { useCallback, useMemo, useState } from 'react';
2
+ import { useApolloClient, useMutation } from '@apollo/client';
3
+
4
+ import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
5
+ import { useGoogleReCaptcha } from '@magento/peregrine/lib/hooks/useGoogleReCaptcha';
6
+
7
+ import DEFAULT_OPERATIONS from './becomeSeller.gql';
8
+ import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
9
+
10
+ import { BrowserPersistence } from '@magento/peregrine/lib/util';
11
+
12
+ const storage = new BrowserPersistence();
13
+
14
+ export const useBecomeSeller = props => {
15
+ const { initialValues = {}, onSubmit, onCancel } = props;
16
+
17
+ const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
18
+
19
+ const {
20
+ becomeSellerMutation
21
+ } = operations;
22
+
23
+ const [isSubmitting, setIsSubmitting] = useState(false);
24
+ const [sellerType, setSellerType] = useState('individual');
25
+
26
+ const [, { dispatch }] = useEventingContext();
27
+
28
+ // For create account and sign in mutations, we don't want to cache any
29
+ // personally identifiable information (PII). So we set fetchPolicy to 'no-cache'.
30
+ const [becomeSeller, { error: becomeSellerError }] = useMutation(
31
+ becomeSellerMutation,
32
+ {
33
+ fetchPolicy: 'no-cache'
34
+ }
35
+ );
36
+
37
+ const {
38
+ generateReCaptchaData,
39
+ recaptchaLoading,
40
+ recaptchaWidgetProps
41
+ } = useGoogleReCaptcha({
42
+ currentForm: 'BECOME_SELLER',
43
+ formAction: 'becomeSeller'
44
+ });
45
+
46
+ const handleChange = useCallback(
47
+ async formValues => {
48
+ if (formValues.values.seller) {
49
+ setSellerType(formValues.values.seller.seller_type)
50
+ }
51
+ }
52
+ );
53
+
54
+ const handleSubmit = useCallback(
55
+ async formValues => {
56
+ setIsSubmitting(true);
57
+ try {
58
+
59
+ // Get reCaptchaV3 Data for becomeSeller mutation
60
+ const recaptchaDataForBecomeSeller = await generateReCaptchaData();
61
+
62
+ // Create the account and then sign in.
63
+ const result = await becomeSeller({
64
+ variables: {
65
+ seller_type: sellerType,
66
+ group_id: '',
67
+ url_key: formValues.seller.store_url,
68
+ name: formValues.seller.seller_profile_name,
69
+ company: formValues.seller.company_name,
70
+ company_registration_number: formValues.seller.company_registration_number,
71
+ country_id: formValues.seller.country_id,
72
+ address_line_1: formValues.seller.address_line_1,
73
+ address_line_2: formValues.seller.address_line_2,
74
+ city: formValues.seller.city,
75
+ region: formValues.seller.region,
76
+ region_id: formValues.seller.region_id,
77
+ postcode: formValues.seller.postcode,
78
+ contact_number: formValues.seller.contact_number
79
+ },
80
+ ...recaptchaDataForBecomeSeller
81
+ });
82
+
83
+ if (result.data.becomeSeller.code) {
84
+ storage.setItem('is_seller', true);
85
+
86
+ globalThis.location.assign('/seller-account');
87
+ }
88
+
89
+ dispatch({
90
+ type: 'BECOME_SELLER',
91
+ payload: {
92
+ group_id: 'basic',
93
+ url_key: formValues.seller.store_url
94
+ }
95
+ });
96
+
97
+ // Finally, invoke the post-submission callback.
98
+ if (onSubmit) {
99
+ onSubmit();
100
+ }
101
+ } catch (error) {
102
+ if (process.env.NODE_ENV !== 'production') {
103
+ console.error(error);
104
+ }
105
+ setIsSubmitting(false);
106
+ }
107
+ },
108
+
109
+ [
110
+ generateReCaptchaData,
111
+ becomeSeller,
112
+ onSubmit,
113
+ dispatch
114
+ ]
115
+ );
116
+
117
+ const sanitizedInitialValues = useMemo(() => {
118
+ const { sellerProfileName, companyName, ...rest } = initialValues;
119
+
120
+ return {
121
+ seller: { profile_name: sellerProfileName, company: companyName, country: "AF" },
122
+ ...rest
123
+ };
124
+ }, [initialValues]);
125
+
126
+ const errors = useMemo(
127
+ () =>
128
+ new Map([
129
+ ['becomeSellerQuery', becomeSellerError]
130
+ ]),
131
+ [becomeSellerError]
132
+ );
133
+
134
+ const isSeller = storage.getItem('is_seller') || false;
135
+
136
+ return {
137
+ isSeller,
138
+ errors,
139
+ handleSubmit,
140
+ sellerType,
141
+ handleChange,
142
+ initialValues: sanitizedInitialValues,
143
+ isDisabled: isSubmitting || recaptchaLoading,
144
+ recaptchaWidgetProps
145
+ };
146
+ };
@@ -0,0 +1,11 @@
1
+ import { BrowserPersistence } from '@magento/peregrine/lib/util';
2
+
3
+ const storage = new BrowserPersistence();
4
+
5
+ export const useBecomeSellerLink = (props = {}) => {
6
+ const isSeller = storage.getItem('is_seller') || false;
7
+
8
+ return {
9
+ isSeller
10
+ };
11
+ };
@@ -0,0 +1,66 @@
1
+ import { useCallback, useEffect, useMemo } from 'react';
2
+ import { useHistory, useLocation } from 'react-router-dom';
3
+ import { BrowserPersistence } from '@magento/peregrine/lib/util';
4
+
5
+ const validBecomeSellerParams = ['sellerUrl', 'companyName', 'sellerProfileName'];
6
+
7
+ const storage = new BrowserPersistence();
8
+
9
+ const getBecomeSellerInitialValues = search => {
10
+ const params = new URLSearchParams(search);
11
+
12
+ return validBecomeSellerParams.reduce(
13
+ (values, param) => ({ ...values, [param]: params.get(param) }),
14
+ {}
15
+ );
16
+ };
17
+
18
+ /**
19
+ * @typedef {function} useBecomeSellerPage
20
+ *
21
+ * @param {String} props.signedInRedirectUrl - Url to push when user is signed in
22
+ * @param {String} props.signInPageUrl - Sign In Page url
23
+ *
24
+ * @returns {{
25
+ * becomeSellerProps: object
26
+ * }}
27
+ */
28
+ export const useBecomeSellerPage = props => {
29
+ const { signedInRedirectUrl, signInPageUrl } = props;
30
+ const history = useHistory();
31
+ const { search } = useLocation();
32
+
33
+ const isSeller = storage.getItem('is_seller') || false;
34
+ useEffect(() => {
35
+ if (isSeller) {
36
+ history.push('/')
37
+ }
38
+ }, [isSeller, history])
39
+
40
+ // Keep location state in memory when pushing history and redirect to
41
+ // the `from` url instead when creating an account
42
+ const historyState = useMemo(() => {
43
+ return history && history.location.state ? history.location.state : {};
44
+ }, [history]);
45
+
46
+ const handleOnCancel = useCallback(() => {
47
+ if (signInPageUrl) {
48
+ history.push(signInPageUrl, historyState);
49
+ }
50
+ }, [history, historyState, signInPageUrl]);
51
+
52
+ const initialValues = useMemo(() => getBecomeSellerInitialValues(search), [
53
+ search
54
+ ]);
55
+
56
+ const becomeSellerProps = {
57
+ initialValues,
58
+ isCancelButtonHidden: false,
59
+ onCancel: handleOnCancel,
60
+ isSeller: isSeller
61
+ };
62
+
63
+ return {
64
+ becomeSellerProps
65
+ };
66
+ };
@@ -0,0 +1,174 @@
1
+ import { useCallback, useMemo, useState } from 'react';
2
+ import { useMutation, useQuery } from '@apollo/client';
3
+ import { useUserContext } from '@magento/peregrine/lib/context/user';
4
+ import { useGoogleReCaptcha } from '@magento/peregrine/lib/hooks/useGoogleReCaptcha';
5
+ import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
6
+
7
+ export const useSellerAccountPage = props => {
8
+ const {
9
+ mutations: {
10
+ setCustomerInformationMutation,
11
+ changeCustomerPasswordMutation
12
+ },
13
+ queries: { getCustomerInformationQuery }
14
+ } = props;
15
+
16
+ const [{ isSignedIn }] = useUserContext();
17
+ const [shouldShowNewPassword, setShouldShowNewPassword] = useState(false);
18
+
19
+ const [isUpdateMode, setIsUpdateMode] = useState(false);
20
+
21
+ const [, { dispatch }] = useEventingContext();
22
+
23
+ // Use local state to determine whether to display errors or not.
24
+ // Could be replaced by a "reset mutation" function from apollo client.
25
+ // https://github.com/apollographql/apollo-feature-requests/issues/170
26
+ const [displayError, setDisplayError] = useState(false);
27
+
28
+ const { data: accountInformationData, error: loadDataError } = useQuery(
29
+ getCustomerInformationQuery,
30
+ {
31
+ skip: !isSignedIn,
32
+ fetchPolicy: 'cache-and-network',
33
+ nextFetchPolicy: 'cache-first'
34
+ }
35
+ );
36
+
37
+ const [
38
+ setCustomerInformation,
39
+ {
40
+ error: customerInformationUpdateError,
41
+ loading: isUpdatingCustomerInformation
42
+ }
43
+ ] = useMutation(setCustomerInformationMutation);
44
+
45
+ const [
46
+ changeCustomerPassword,
47
+ {
48
+ error: customerPasswordChangeError,
49
+ loading: isChangingCustomerPassword
50
+ }
51
+ ] = useMutation(changeCustomerPasswordMutation);
52
+
53
+ const {
54
+ generateReCaptchaData,
55
+ recaptchaLoading,
56
+ recaptchaWidgetProps
57
+ } = useGoogleReCaptcha({
58
+ currentForm: 'CUSTOMER_EDIT',
59
+ formAction: 'editCustomer'
60
+ });
61
+
62
+ const initialValues = useMemo(() => {
63
+ if (accountInformationData) {
64
+ return { customer: accountInformationData.customer };
65
+ }
66
+ }, [accountInformationData]);
67
+
68
+ const handleChangePassword = useCallback(() => {
69
+ setShouldShowNewPassword(true);
70
+ }, [setShouldShowNewPassword]);
71
+
72
+ const handleCancel = useCallback(() => {
73
+ setIsUpdateMode(false);
74
+ setShouldShowNewPassword(false);
75
+ }, [setIsUpdateMode]);
76
+
77
+ const showUpdateMode = useCallback(() => {
78
+ setIsUpdateMode(true);
79
+
80
+ // If there were errors from removing/updating info, hide them
81
+ // when we open the modal.
82
+ setDisplayError(false);
83
+ }, [setIsUpdateMode]);
84
+
85
+ const handleSubmit = useCallback(
86
+ async ({ email, firstname, lastname, password, newPassword }) => {
87
+ try {
88
+ email = email.trim();
89
+ firstname = firstname.trim();
90
+ lastname = lastname.trim();
91
+ password = password.trim();
92
+ newPassword = newPassword ? newPassword.trim() : newPassword;
93
+
94
+ if (
95
+ initialValues.customer.email !== email ||
96
+ initialValues.customer.firstname !== firstname ||
97
+ initialValues.customer.lastname !== lastname
98
+ ) {
99
+ await setCustomerInformation({
100
+ variables: {
101
+ customerInput: {
102
+ email,
103
+ firstname,
104
+ lastname,
105
+ // You must send password because it is required
106
+ // when changing email.
107
+ password
108
+ }
109
+ }
110
+ });
111
+ }
112
+ if (password && newPassword) {
113
+ const recaptchaDataForChangeCustomerPassword = await generateReCaptchaData();
114
+ await changeCustomerPassword({
115
+ variables: {
116
+ currentPassword: password,
117
+ newPassword: newPassword
118
+ },
119
+ ...recaptchaDataForChangeCustomerPassword
120
+ });
121
+ }
122
+
123
+ dispatch({
124
+ type: 'USER_ACCOUNT_UPDATE',
125
+ payload: {
126
+ email,
127
+ firstName: firstname,
128
+ lastName: lastname
129
+ }
130
+ });
131
+
132
+ // After submission, close the form if there were no errors.
133
+ handleCancel(false);
134
+ } catch {
135
+ // Make sure any errors from the mutation are displayed.
136
+ setDisplayError(true);
137
+
138
+ // we have an onError link that logs errors, and FormError
139
+ // already renders this error, so just return to avoid
140
+ // triggering the success callback
141
+ return;
142
+ }
143
+ },
144
+ [
145
+ initialValues,
146
+ handleCancel,
147
+ setCustomerInformation,
148
+ generateReCaptchaData,
149
+ changeCustomerPassword,
150
+ dispatch
151
+ ]
152
+ );
153
+
154
+ const errors = displayError
155
+ ? [customerInformationUpdateError, customerPasswordChangeError]
156
+ : [];
157
+
158
+ return {
159
+ handleCancel,
160
+ formErrors: errors,
161
+ handleSubmit,
162
+ handleChangePassword,
163
+ initialValues,
164
+ isDisabled:
165
+ isUpdatingCustomerInformation ||
166
+ isChangingCustomerPassword ||
167
+ recaptchaLoading,
168
+ isUpdateMode,
169
+ loadDataError,
170
+ shouldShowNewPassword,
171
+ showUpdateMode,
172
+ recaptchaWidgetProps
173
+ };
174
+ };