@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.
- package/package.json +1 -1
- package/src/componentOverrideMapping.js +5 -1
- package/src/components/BecomeSeller/becomeSeller.js +184 -81
- package/src/components/BecomeSeller/becomeSeller.module.css +2 -3
- package/src/components/BecomeSellerLink/becomeSellerLink.js +45 -0
- package/src/components/BecomeSellerLink/becomeSellerLink.module.css +13 -0
- package/src/components/BecomeSellerPage/becomeSellerPage.js +9 -13
- package/src/components/BecomeSellerPage/becomeSellerPage.module.css +21 -0
- package/src/components/SellerAccountPage/index.js +1 -0
- package/src/components/SellerAccountPage/sellerAccountPage.js +138 -0
- package/src/components/SellerAccountPage/sellerAccountPage.module.css +55 -0
- package/src/components/SellerVerification/index.js +1 -0
- package/src/components/SellerVerification/sellerVerification.js +198 -0
- package/src/components/SellerVerification/sellerVerification.module.css +47 -0
- package/src/components/SellerVerificationPage/index.js +1 -0
- package/src/components/SellerVerificationPage/sellerVerificationPage.js +43 -0
- package/src/components/SellerVerificationPage/sellerVerificationPage.module.css +21 -0
- package/src/components/WebsiteSwitcher/websiteSwitcher.js +109 -0
- package/src/components/WebsiteSwitcher/websiteSwitcher.module.css +111 -0
- package/src/components/WebsiteSwitcher/websiteSwitcher.shimmer.js +6 -0
- package/src/components/WebsiteSwitcher/websiteSwitcherItem.js +47 -0
- package/src/components/WebsiteSwitcher/websiteSwitcherItem.module.css +20 -0
- package/src/intercept.js +40 -37
- package/src/overwrites/peregrine/lib/store/actions/user/asyncActions.js +96 -0
- package/src/overwrites/peregrine/lib/talons/AccountMenu/useAccountMenuItems.js +65 -0
- package/src/overwrites/peregrine/lib/talons/SignIn/signIn.gql.js +56 -0
- package/src/overwrites/peregrine/lib/talons/SignIn/useSignIn.js +226 -0
- package/src/overwrites/venia-ui/lib/components/Header/header.js +2 -2
- package/src/overwrites/venia-ui/lib/components/Header/storeSwitcher.js +2 -2
- package/src/talons/BecomeSeller/becomeSeller.gql.js +46 -0
- package/src/talons/BecomeSeller/useBecomeSeller.js +146 -0
- package/src/talons/BecomeSellerLink/useBecomeSellerLink.js +11 -0
- package/src/talons/BecomeSellerPage/useBecomeSellerPage.js +66 -0
- package/src/talons/SellerAccountPage/useSellerAccountPage.js +174 -0
- package/src/talons/WebsiteByIp/useWebsiteByIp.js +2 -0
- package/src/talons/WebsiteSwitcher/useWebsiteSwitcher.js +218 -0
- 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/
|
|
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/
|
|
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
|
+
};
|