@riosst100/pwa-marketplace 2.9.4 → 2.9.6
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/i18n/en_US.json +1 -0
- package/i18n/id_ID.json +1 -0
- package/package.json +1 -1
- package/src/componentOverrideMapping.js +6 -1
- package/src/components/ConfirmEmailPage/confirmEmail.js +76 -0
- package/src/components/ConfirmEmailPage/confirmEmail.module.css +71 -0
- package/src/components/ConfirmEmailPage/index.js +1 -0
- package/src/components/FavoriteSellerPage/favoriteSeller.js +0 -1
- package/src/components/FavoriteSellerPage/item.js +0 -2
- package/src/components/OrderDetail/components/itemsOrdered.js +94 -82
- package/src/components/OrderDetail/components/rmaList.js +80 -88
- package/src/components/OrderDetail/orderDetail.js +154 -95
- package/src/components/RMAPage/RMACreate.js +225 -36
- package/src/components/RMAPage/RMADetail.js +141 -89
- package/src/components/RMAPage/RMAList.js +38 -57
- package/src/components/RMAPage/components/productItem.js +55 -30
- package/src/components/RMAPage/orderRow.js +109 -254
- package/src/components/VerifyEmailPage/verifyEmail.js +33 -10
- package/src/intercept.js +8 -1
- package/src/overwrites/peregrine/lib/talons/CartPage/PriceSummary/usePriceSummary.js +2 -2
- package/src/overwrites/peregrine/lib/talons/CheckoutPage/PaymentInformation/paymentMethods.gql.js +45 -0
- package/src/overwrites/peregrine/lib/talons/OrderHistoryPage/orderHistoryPage.gql.js +117 -0
- package/src/overwrites/peregrine/lib/talons/OrderHistoryPage/orderRow.gql.js +46 -0
- package/src/overwrites/peregrine/lib/talons/OrderHistoryPage/useOrderRow.js +112 -0
- package/src/overwrites/peregrine/lib/talons/RMAPage/rmaPage.gql.js +170 -0
- package/src/overwrites/venia-ui/lib/components/AccountInformationPage/DeleteAccount.js +5 -37
- package/src/overwrites/venia-ui/lib/components/Adapter/adapter.js +3 -1
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderHistoryPage.js +10 -2
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderRow.js +158 -79
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderRow.module.css +3 -3
- package/src/overwrites/venia-ui/lib/components/StoreCodeRoute/storeCodeRoute.js +1 -1
- package/src/talons/AccountInformationPage/deleteAccount.gql.js +23 -0
- package/src/talons/AccountInformationPage/useDeleteAccount.js +98 -0
- package/src/talons/ConfirmEmailPage/confirmEmailPage.gql.js +20 -0
- package/src/talons/ConfirmEmailPage/useConfirmEmailPage.js +78 -0
- package/src/talons/OrderHistoryPage/useOrderHistoryPage.js +115 -0
- package/src/talons/RMAPage/useRmaPage.js +145 -0
- package/src/talons/VerifyEmailPage/useVerifyEmailPage.js +73 -0
- package/src/talons/VerifyEmailPage/verifyEmailPage.gql.js +36 -0
|
@@ -10,7 +10,7 @@ import { Form } from 'informed';
|
|
|
10
10
|
|
|
11
11
|
import { useToasts } from '@magento/peregrine/lib/Toasts';
|
|
12
12
|
import OrderHistoryContextProvider from '@magento/peregrine/lib/talons/OrderHistoryPage/orderHistoryContext';
|
|
13
|
-
import { useOrderHistoryPage } from '@
|
|
13
|
+
import { useOrderHistoryPage } from '@riosst100/pwa-marketplace/src/talons/OrderHistoryPage/useOrderHistoryPage';
|
|
14
14
|
|
|
15
15
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
16
16
|
import Button from '@magento/venia-ui/lib/components/Button';
|
|
@@ -24,6 +24,7 @@ import OrderRow from './orderRow';
|
|
|
24
24
|
import ResetButton from './resetButton';
|
|
25
25
|
import { SearchNormal } from 'iconsax-react';
|
|
26
26
|
import cn from 'classnames';
|
|
27
|
+
import Pagination from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/Pagination';
|
|
27
28
|
|
|
28
29
|
const errorIcon = (
|
|
29
30
|
<Icon
|
|
@@ -46,7 +47,8 @@ const OrderHistoryPage = props => {
|
|
|
46
47
|
isLoadingWithoutData,
|
|
47
48
|
orders,
|
|
48
49
|
pageInfo,
|
|
49
|
-
searchText
|
|
50
|
+
searchText,
|
|
51
|
+
pageControl
|
|
50
52
|
} = talonProps;
|
|
51
53
|
const [, { addToast }] = useToasts();
|
|
52
54
|
const { formatMessage } = useIntl();
|
|
@@ -205,6 +207,12 @@ const OrderHistoryPage = props => {
|
|
|
205
207
|
<span className={classes.pageInfo}>{pageInfoLabel}</span>
|
|
206
208
|
</div>
|
|
207
209
|
{pageContents}
|
|
210
|
+
{/* Pagination Controls */}
|
|
211
|
+
<div className="mt-4">
|
|
212
|
+
{pageControl?.totalPages > 1 ? (
|
|
213
|
+
<Pagination pageControl={pageControl} />
|
|
214
|
+
) : null}
|
|
215
|
+
</div>
|
|
208
216
|
{loadMoreButton}
|
|
209
217
|
</div>
|
|
210
218
|
</OrderHistoryContextProvider >
|
|
@@ -12,13 +12,14 @@ import OrderProgressBar from './orderProgressBar';
|
|
|
12
12
|
import OrderDetails from './OrderDetails';
|
|
13
13
|
import defaultClasses from './orderRow.module.css';
|
|
14
14
|
import cn from 'classnames';
|
|
15
|
-
import { Verify } from 'iconsax-react';
|
|
15
|
+
import { Verify, Shop } from 'iconsax-react';
|
|
16
16
|
import PlaceholderImage from '@magento/venia-ui/lib/components/Image/placeholderImage';
|
|
17
|
-
import { Link } from 'react-router-dom';
|
|
17
|
+
import { Link, useHistory } from 'react-router-dom';
|
|
18
18
|
|
|
19
19
|
const OrderRow = props => {
|
|
20
20
|
const { order } = props;
|
|
21
21
|
const { formatMessage } = useIntl();
|
|
22
|
+
const history = useHistory();
|
|
22
23
|
const {
|
|
23
24
|
invoices,
|
|
24
25
|
items,
|
|
@@ -28,6 +29,7 @@ const OrderRow = props => {
|
|
|
28
29
|
status,
|
|
29
30
|
total
|
|
30
31
|
} = order;
|
|
32
|
+
|
|
31
33
|
const { grand_total: grandTotal } = total;
|
|
32
34
|
const { currency, value: orderTotal } = grandTotal;
|
|
33
35
|
|
|
@@ -72,6 +74,11 @@ const OrderRow = props => {
|
|
|
72
74
|
|
|
73
75
|
const classes = useStyle(defaultClasses, props.classes);
|
|
74
76
|
|
|
77
|
+
// Determine seller/store name from first item if available
|
|
78
|
+
const sellerName = items && items.length > 0 && items[0] && items[0].seller_name
|
|
79
|
+
? items[0].seller_name
|
|
80
|
+
: '-';
|
|
81
|
+
|
|
75
82
|
const contentClass = isOpen ? classes.content : classes.content_collapsed;
|
|
76
83
|
|
|
77
84
|
const contentToggleIconSrc = isOpen ? ChevronUp : ChevronDown;
|
|
@@ -94,7 +101,7 @@ const OrderRow = props => {
|
|
|
94
101
|
);
|
|
95
102
|
|
|
96
103
|
const badgeStatusStyle = () => {
|
|
97
|
-
return '
|
|
104
|
+
return 'text-blue-700 text-[14px] font-medium py-[5px] border-none';
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
const thumbnailProps = {
|
|
@@ -103,13 +110,88 @@ const OrderRow = props => {
|
|
|
103
110
|
width: 50
|
|
104
111
|
};
|
|
105
112
|
|
|
113
|
+
|
|
114
|
+
// Helper to resolve a product image by SKU with graceful fallback, now prefers product_image_url from order.items
|
|
115
|
+
const getThumbnailForSku = (sku, fallbackLabel, idx) => {
|
|
116
|
+
let url = null;
|
|
117
|
+
let label = fallbackLabel;
|
|
118
|
+
// Prefer product_image_url from order.items if present and is a non-empty string
|
|
119
|
+
if (items && items[idx] && typeof items[idx].product_image_url === 'string' && items[idx].product_image_url.trim() !== '') {
|
|
120
|
+
url = items[idx].product_image_url;
|
|
121
|
+
} else if (imagesData && typeof imagesData === 'object') {
|
|
122
|
+
const byKey = sku && imagesData[sku];
|
|
123
|
+
const byValue = !byKey && sku
|
|
124
|
+
? Object.values(imagesData).find(entry => entry?.sku === sku)
|
|
125
|
+
: null;
|
|
126
|
+
const chosen = byKey || byValue;
|
|
127
|
+
if (chosen?.thumbnail?.url && typeof chosen.thumbnail.url === 'string' && chosen.thumbnail.url.trim() !== '') {
|
|
128
|
+
url = chosen.thumbnail.url;
|
|
129
|
+
label = chosen.thumbnail.label || label;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// If url is not a non-empty string, fallback to null (will trigger placeholder)
|
|
133
|
+
if (typeof url !== 'string' || url.trim() === '') {
|
|
134
|
+
url = null;
|
|
135
|
+
}
|
|
136
|
+
return { url, label };
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const showNewReturnButton = status === 'Complete' || derivedStatus === formatMessage({ id: 'orderRow.deliveredText', defaultMessage: 'Delivered' });
|
|
140
|
+
|
|
141
|
+
const handleNewReturn = () => {
|
|
142
|
+
// Inject product_image per item with safe fallbacks (prefer product_image_url from query)
|
|
143
|
+
let orderWithImages = { ...order };
|
|
144
|
+
if (orderWithImages.items && Array.isArray(orderWithImages.items)) {
|
|
145
|
+
orderWithImages = {
|
|
146
|
+
...orderWithImages,
|
|
147
|
+
items: orderWithImages.items.map(it => {
|
|
148
|
+
// Start with empty string to avoid undefined passed to Image component downstream
|
|
149
|
+
let product_image = '';
|
|
150
|
+
// 1) Prefer product_image_url from order items (added by query)
|
|
151
|
+
if (typeof it.product_image_url === 'string' && it.product_image_url.trim() !== '') {
|
|
152
|
+
product_image = it.product_image_url;
|
|
153
|
+
}
|
|
154
|
+
// 2) Fallback to imagesData thumbnail url (if available)
|
|
155
|
+
else if (
|
|
156
|
+
imagesData &&
|
|
157
|
+
it.product_sku &&
|
|
158
|
+
imagesData[it.product_sku]?.thumbnail?.url &&
|
|
159
|
+
typeof imagesData[it.product_sku].thumbnail.url === 'string' &&
|
|
160
|
+
imagesData[it.product_sku].thumbnail.url.trim() !== ''
|
|
161
|
+
) {
|
|
162
|
+
product_image = imagesData[it.product_sku].thumbnail.url;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
...it,
|
|
167
|
+
// Keep product_image_url as-is, add product_image for RMACreate consumers
|
|
168
|
+
product_image
|
|
169
|
+
};
|
|
170
|
+
})
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
localStorage.setItem('rma_order', JSON.stringify(orderWithImages));
|
|
175
|
+
} catch (e) {}
|
|
176
|
+
history.push({
|
|
177
|
+
pathname: `/return/create/${orderNumber}`,
|
|
178
|
+
state: { order: orderWithImages }
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
|
|
106
182
|
return (
|
|
107
183
|
<li className={classes.root}>
|
|
108
|
-
<div className='flex flex-col md_flex-row justify-between mb-2.5'>
|
|
109
|
-
<div className='flex flex-col'>
|
|
110
|
-
<div className="flex gap-x-[15px] flex-
|
|
111
|
-
<
|
|
112
|
-
|
|
184
|
+
<div className='flex flex-col md_flex-row md_items-start justify-between mb-2.5'>
|
|
185
|
+
<div className='flex flex-col ml-[14px] mt-[5px]'>
|
|
186
|
+
<div className="flex gap-x-[15px] flex-col">
|
|
187
|
+
<div className='flex gap-x-[5px] items-center'>
|
|
188
|
+
<Shop size={17} className='text-blue-700' variant="Bold" />
|
|
189
|
+
<span className='text-[14px] font-medium text-blue-700'>
|
|
190
|
+
{sellerName}
|
|
191
|
+
</span>
|
|
192
|
+
<span>|</span>
|
|
193
|
+
<span className="text-blue-700 text-[14px]">#{orderNumber}</span>
|
|
194
|
+
</div>
|
|
113
195
|
</div>
|
|
114
196
|
</div>
|
|
115
197
|
<div className='flex flex-col'>
|
|
@@ -121,90 +203,86 @@ const OrderRow = props => {
|
|
|
121
203
|
</div>
|
|
122
204
|
</div>
|
|
123
205
|
<div className='flex flex-col md_flex-row justify-between mb-2.5'>
|
|
124
|
-
<div className='flex flex-col'>
|
|
125
|
-
<div className='flex gap-x-[5px] mb-2.5'>
|
|
126
|
-
<Verify size={17} className='text-blue-700' variant="Bold" />
|
|
127
|
-
<span className='text-xs font-medium text-[rgba(25, 34, 42, 0.7)]'>
|
|
128
|
-
Gundam Info
|
|
129
|
-
</span>
|
|
130
|
-
</div>
|
|
206
|
+
<div className='flex flex-col ml-[5px]'>
|
|
131
207
|
<div className='flex flex-row'>
|
|
132
|
-
<div>
|
|
133
|
-
|
|
208
|
+
<div className={cn('flex flex-col gap-2')}>
|
|
209
|
+
{items && items.length > 0 && items.map((it, idx) => {
|
|
210
|
+
const { url, label } = getThumbnailForSku(it.product_sku, it.product_name, idx);
|
|
211
|
+
return (
|
|
212
|
+
<div key={it.id || idx} className={classes.productImage}>
|
|
213
|
+
{url ? (
|
|
214
|
+
<img
|
|
215
|
+
src={url}
|
|
216
|
+
alt={label}
|
|
217
|
+
width={80}
|
|
218
|
+
className={classes.thumbnail}
|
|
219
|
+
/>
|
|
220
|
+
) : (
|
|
221
|
+
<PlaceholderImage alt={it.product_name} classes={{ root: classes.thumbnail }} width={60} />
|
|
222
|
+
)}
|
|
223
|
+
</div>
|
|
224
|
+
);
|
|
225
|
+
})}
|
|
134
226
|
</div>
|
|
135
|
-
<div className='flex flex-col max-w-[
|
|
136
|
-
|
|
137
|
-
<
|
|
138
|
-
{
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
</
|
|
149
|
-
|
|
227
|
+
<div className='flex flex-col max-w-[375px] gap-8'>
|
|
228
|
+
{items && items.length > 0 && items.map((it, idx) => (
|
|
229
|
+
<div key={it.id || idx} className='flex flex-col gap-1 pb-2 last_pb-0'>
|
|
230
|
+
<div className={cn(classes.productName, 'text-[14] font-medium')}>
|
|
231
|
+
<span>{it.product_name}</span>
|
|
232
|
+
</div>
|
|
233
|
+
<div className="text-[14] text-gray-300">
|
|
234
|
+
<span>Qty : {`${it.quantity_ordered}`}</span>
|
|
235
|
+
<br />
|
|
236
|
+
<span>
|
|
237
|
+
Price : <Price currencyCode={it?.product_sale_price?.currency} value={it?.product_sale_price?.value} />
|
|
238
|
+
</span>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
))}
|
|
150
242
|
</div>
|
|
151
243
|
</div>
|
|
152
244
|
</div>
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
245
|
+
{/* Right column: bottom-aligned Order Total + CTA */}
|
|
246
|
+
<div className='flex flex-col items-end gap-2 md_pl-10 md_self-end mr-4 mb-1'>
|
|
247
|
+
<div className="md_text-right">
|
|
248
|
+
<span className="text-[14] text-gray-200 block mb-1">
|
|
156
249
|
<FormattedMessage
|
|
157
250
|
id={'orderRow.orderTotalText'}
|
|
158
251
|
defaultMessage={'Order Total'}
|
|
159
252
|
/>
|
|
160
253
|
</span>
|
|
161
|
-
<div className="text-lg font-medium
|
|
254
|
+
<div className="text-lg font-medium">{orderTotalPrice}</div>
|
|
255
|
+
</div>
|
|
256
|
+
<div className="flex flex-row gap-2 w-full justify-end items-center">
|
|
257
|
+
{showNewReturnButton && (
|
|
258
|
+
<button
|
|
259
|
+
type="button"
|
|
260
|
+
className="bg-blue-700 hover:bg-white hover:text-blue-700 hover:border hover:border-blue-700 rounded-full px-[30px] py-[5px] text-[13px] font-medium text-white transition-all duration-300 ease-in-out"
|
|
261
|
+
onClick={handleNewReturn}
|
|
262
|
+
>
|
|
263
|
+
<FormattedMessage
|
|
264
|
+
id={'orderRow.newReturn'}
|
|
265
|
+
defaultMessage={'New Return'}
|
|
266
|
+
/>
|
|
267
|
+
</button>
|
|
268
|
+
)}
|
|
269
|
+
<Link
|
|
270
|
+
to={{
|
|
271
|
+
pathname: `/order-history/view/${orderNumber}`,
|
|
272
|
+
state: { order }
|
|
273
|
+
}}
|
|
274
|
+
>
|
|
275
|
+
<span className="bg-blue-700 hover:bg-white hover:text-blue-700 hover:border hover:border-blue-700 rounded-full px-[30px] py-[5px] text-[13px] font-medium text-white transition-all duration-300 ease-in-out">
|
|
276
|
+
<FormattedMessage
|
|
277
|
+
id={'orderRow.ViewTransactionDetail'}
|
|
278
|
+
defaultMessage={'View Order Detail'}
|
|
279
|
+
/>
|
|
280
|
+
</span>
|
|
281
|
+
</Link>
|
|
162
282
|
</div>
|
|
163
283
|
</div>
|
|
164
284
|
</div>
|
|
165
|
-
|
|
166
|
-
{/* <button
|
|
167
|
-
className={cn(classes.contentToggleContainer, '!p-0 !border-0')}
|
|
168
|
-
onClick={handleContentToggle}
|
|
169
|
-
type="button"
|
|
170
|
-
aria-expanded={isOpen}
|
|
171
|
-
>
|
|
172
|
-
<span className="text-[13px] font-medium text-blue-700 underline">
|
|
173
|
-
<FormattedMessage
|
|
174
|
-
id={'orderRow.ViewTransactionDetail'}
|
|
175
|
-
defaultMessage={'View Transaction Detail'}
|
|
176
|
-
/>
|
|
177
|
-
</span>
|
|
178
|
-
</button> */}
|
|
179
|
-
<Link to="/order-history/view/123213">
|
|
180
|
-
<span className="text-[13px] font-medium text-blue-700 underline">
|
|
181
|
-
<FormattedMessage
|
|
182
|
-
id={'orderRow.ViewTransactionDetail'}
|
|
183
|
-
defaultMessage={'View Transaction Detail'}
|
|
184
|
-
/>
|
|
185
|
-
</span>
|
|
186
|
-
</Link>
|
|
187
|
-
</div>
|
|
188
|
-
|
|
189
|
-
{/* <div className={classes.orderDateContainer}>
|
|
190
|
-
<span className={classes.orderDateLabel}>
|
|
191
|
-
<FormattedMessage
|
|
192
|
-
id={'orderRow.orderDateText'}
|
|
193
|
-
defaultMessage={'Order Date'}
|
|
194
|
-
/>
|
|
195
|
-
</span>
|
|
196
|
-
<span className={classes.orderDate}>{formattedDate}</span>
|
|
197
|
-
</div> */}
|
|
198
|
-
{/* <div className={classes.orderItemsContainer}>
|
|
199
|
-
{collapsedImageGalleryElement}
|
|
200
|
-
</div> */}
|
|
201
|
-
{/* <div className={classes.orderStatusContainer}>
|
|
202
|
-
<span className={classes.orderStatusBadge}>
|
|
203
|
-
{derivedStatus}
|
|
204
|
-
</span>
|
|
205
|
-
<OrderProgressBar status={derivedStatus} />
|
|
206
|
-
</div> */}
|
|
207
|
-
<div className={cn(contentClass, '!py-4 mt-4')}>{orderDetails}</div>
|
|
285
|
+
|
|
208
286
|
</li>
|
|
209
287
|
);
|
|
210
288
|
};
|
|
@@ -259,6 +337,7 @@ OrderRow.propTypes = {
|
|
|
259
337
|
value: string
|
|
260
338
|
})
|
|
261
339
|
),
|
|
340
|
+
seller_name: string,
|
|
262
341
|
quantity_ordered: number
|
|
263
342
|
})
|
|
264
343
|
),
|
|
@@ -101,14 +101,14 @@
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
.orderStatusBadge {
|
|
104
|
-
composes: border from global;
|
|
104
|
+
/* composes: border from global;
|
|
105
105
|
composes: border-solid from global;
|
|
106
|
-
composes: border-subtle from global;
|
|
106
|
+
composes: border-subtle from global; */
|
|
107
107
|
composes: font-bold from global;
|
|
108
108
|
composes: justify-self-start from global;
|
|
109
109
|
composes: px-xs from global;
|
|
110
110
|
composes: py-1 from global;
|
|
111
|
-
composes: rounded-md from global;
|
|
111
|
+
/* composes: rounded-md from global; */
|
|
112
112
|
composes: text-2xs from global;
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -41,7 +41,7 @@ const StoreCodeRoute = () => {
|
|
|
41
41
|
// the storage value and refresh so that we start using the new code.
|
|
42
42
|
useEffect(() => {
|
|
43
43
|
if (!websiteCodeInUrl) {
|
|
44
|
-
history.replace(location.pathname)
|
|
44
|
+
history.replace(location.pathname + location.search)
|
|
45
45
|
} else if (websiteCodeInUrl && websiteCodeInUrl !== currentWebsiteCode) {
|
|
46
46
|
let storeCodeInUrl = websiteStores[websiteCodeInUrl];
|
|
47
47
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { gql } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
export const DELETE_ACCOUNT = gql`
|
|
4
|
+
mutation DeleteAccount {
|
|
5
|
+
deleteCustomerAccount {
|
|
6
|
+
success
|
|
7
|
+
message
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
export const SIGN_OUT = gql`
|
|
13
|
+
mutation SignOutFromMenu {
|
|
14
|
+
revokeCustomerToken {
|
|
15
|
+
result
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
export default {
|
|
21
|
+
deleteAccountMutation: DELETE_ACCOUNT,
|
|
22
|
+
signOutMutation: SIGN_OUT
|
|
23
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
|
|
2
|
+
import { useCallback, useMemo, useState, useRef, useEffect } from 'react';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import { useMutation, useQuery } from '@apollo/client';
|
|
5
|
+
import { useUserContext } from '@magento/peregrine/lib/context/user';
|
|
6
|
+
import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
7
|
+
import DEFAULT_OPERATIONS from './deleteAccount.gql';
|
|
8
|
+
import { useHistory } from 'react-router-dom';
|
|
9
|
+
import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
|
|
10
|
+
import { useToasts } from '@magento/peregrine';
|
|
11
|
+
|
|
12
|
+
export const useDeleteAccount = (props = {}) => {
|
|
13
|
+
const [loading, setLoading] = useState(false);
|
|
14
|
+
const [error, setError] = useState(null);
|
|
15
|
+
const [success, setSuccess] = useState(false);
|
|
16
|
+
|
|
17
|
+
const { formatMessage } = useIntl();
|
|
18
|
+
|
|
19
|
+
const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
|
|
20
|
+
const { signOutMutation } = operations;
|
|
21
|
+
|
|
22
|
+
const history = useHistory();
|
|
23
|
+
|
|
24
|
+
const [isSigningOut, setIsSigningOut] = useState(false);
|
|
25
|
+
const [{ currentUser, isSignedIn }, { signOut }] = useUserContext();
|
|
26
|
+
const [revokeToken] = useMutation(signOutMutation);
|
|
27
|
+
|
|
28
|
+
const [, { dispatch }] = useEventingContext();
|
|
29
|
+
const [, { addToast }] = useToasts();
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
deleteAccountMutation
|
|
33
|
+
} = operations;
|
|
34
|
+
|
|
35
|
+
const [deleteAccount, { data: deleteAccountData, error: deleteAccountError, loading: deleteAccountLoading}] = useMutation(
|
|
36
|
+
deleteAccountMutation,
|
|
37
|
+
{
|
|
38
|
+
fetchPolicy: 'no-cache'
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const handleDeleteAccount = useCallback(() => {
|
|
43
|
+
deleteAccount({});
|
|
44
|
+
}, [
|
|
45
|
+
setLoading,
|
|
46
|
+
deleteAccount,
|
|
47
|
+
deleteAccountError,
|
|
48
|
+
deleteAccountData
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
const handleSignOut = useCallback(async () => {
|
|
52
|
+
setIsSigningOut(true);
|
|
53
|
+
|
|
54
|
+
dispatch({
|
|
55
|
+
type: 'USER_SIGN_OUT',
|
|
56
|
+
payload: currentUser
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Delete cart/user data from the redux stor`e.
|
|
60
|
+
await signOut({ revokeToken });
|
|
61
|
+
|
|
62
|
+
}, [history, revokeToken, signOut, dispatch, currentUser]);
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (deleteAccountLoading) {
|
|
66
|
+
setLoading(true);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (deleteAccountData && !deleteAccountLoading) {
|
|
70
|
+
if (deleteAccountData.deleteCustomerAccount.success) {
|
|
71
|
+
addToast({
|
|
72
|
+
type: 'info',
|
|
73
|
+
message: formatMessage({
|
|
74
|
+
id: 'deleteAccount.deleteAccountSuccess',
|
|
75
|
+
defaultMessage: 'Your account is deleted successfully.'
|
|
76
|
+
}),
|
|
77
|
+
timeout: 10000
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
handleSignOut();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
setLoading(false);
|
|
84
|
+
}
|
|
85
|
+
}, [
|
|
86
|
+
deleteAccountData,
|
|
87
|
+
deleteAccountLoading,
|
|
88
|
+
handleSignOut,
|
|
89
|
+
addToast
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
loading,
|
|
94
|
+
error,
|
|
95
|
+
success,
|
|
96
|
+
handleDeleteAccount
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { gql } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
export const CONFIRM_EMAIL = gql`
|
|
4
|
+
mutation ConfirmEmail(
|
|
5
|
+
$id: Int!
|
|
6
|
+
$key: String!
|
|
7
|
+
) {
|
|
8
|
+
confirmCustomerEmail(
|
|
9
|
+
id: $id
|
|
10
|
+
key: $key
|
|
11
|
+
) {
|
|
12
|
+
success
|
|
13
|
+
message
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export default {
|
|
19
|
+
confirmCustomerEmailMutation: CONFIRM_EMAIL
|
|
20
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
|
|
2
|
+
import { useCallback, useEffect } from 'react';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import { useMutation } from '@apollo/client';
|
|
5
|
+
import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
6
|
+
import DEFAULT_OPERATIONS from './confirmEmailPage.gql';
|
|
7
|
+
import { useHistory } from 'react-router-dom';
|
|
8
|
+
import { useToasts } from '@magento/peregrine';
|
|
9
|
+
|
|
10
|
+
export const useConfirmEmailPage = (props = {}) => {
|
|
11
|
+
const { formatMessage } = useIntl();
|
|
12
|
+
|
|
13
|
+
const { id, key } = props;
|
|
14
|
+
|
|
15
|
+
const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
|
|
16
|
+
|
|
17
|
+
const history = useHistory();
|
|
18
|
+
|
|
19
|
+
const [, { addToast }] = useToasts();
|
|
20
|
+
|
|
21
|
+
const {
|
|
22
|
+
confirmCustomerEmailMutation
|
|
23
|
+
} = operations;
|
|
24
|
+
|
|
25
|
+
const [confirmEmail, { called: called, data: data, error: error, loading: loading}] = useMutation(
|
|
26
|
+
confirmCustomerEmailMutation,
|
|
27
|
+
{
|
|
28
|
+
fetchPolicy: 'no-cache'
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const handleConfirmEmail = useCallback(() => {
|
|
33
|
+
confirmEmail({
|
|
34
|
+
variables: {
|
|
35
|
+
id,
|
|
36
|
+
key
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}, [
|
|
40
|
+
confirmEmail,
|
|
41
|
+
id,
|
|
42
|
+
key
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
const shouldShowLoadingIndicator = called && loading;
|
|
46
|
+
const isSuccess = !loading && data && data.confirmCustomerEmail.success ? true : false;
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (data && !loading) {
|
|
51
|
+
if (data.confirmCustomerEmail.success) {
|
|
52
|
+
addToast({
|
|
53
|
+
type: 'success',
|
|
54
|
+
message: formatMessage({
|
|
55
|
+
id: 'emailConfirmation.confirmEmailSuccess',
|
|
56
|
+
defaultMessage: data.confirmCustomerEmail.message
|
|
57
|
+
}),
|
|
58
|
+
timeout: 10000
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// history.go(0)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}, [
|
|
65
|
+
data,
|
|
66
|
+
loading,
|
|
67
|
+
addToast
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
loading,
|
|
72
|
+
error,
|
|
73
|
+
data,
|
|
74
|
+
handleConfirmEmail,
|
|
75
|
+
shouldShowLoadingIndicator,
|
|
76
|
+
isSuccess
|
|
77
|
+
};
|
|
78
|
+
}
|