@riosst100/pwa-marketplace 3.2.5 → 3.2.7
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/components/AgeVerification/ageVerificationModal.js +2 -2
- package/src/components/AgeVerification/index.js +1 -1
- package/src/components/BecomeSeller/becomeSeller.js +15 -12
- package/src/components/BecomeSellerPage/becomeSellerPage.js +29 -10
- package/src/components/BecomeSellerPage/becomeSellerPage.module.css +21 -0
- package/src/components/LiveChat/MessagesModal.js +6 -6
- package/src/components/RFQ/index.js +3 -2
- package/src/components/RFQ/modalRfq.js +186 -68
- package/src/components/RFQPage/orderRow.js +84 -249
- package/src/components/RFQPage/orderRow.module.css +146 -0
- package/src/components/RFQPage/quoteDetail.js +173 -86
- package/src/components/RFQPage/quoteList.js +87 -65
- package/src/components/SellerMegaMenu/sellerMegaMenu.js +3 -1
- package/src/components/SellerMegaMenu/sellerMegaMenuItem.js +1 -1
- package/src/components/SellerMegaMenu/sellerMegaMenuItem.module.css +2 -1
- package/src/components/SocialLogin/googleSignInButton.js +50 -0
- package/src/components/SocialLogin/index.js +1 -10
- package/src/components/SocialLogin/socialLogin.js +28 -23
- package/src/components/WebsiteSwitcher/websiteSwitcherItem.js +0 -7
- package/src/overwrites/venia-ui/lib/components/Adapter/adapter.js +3 -1
- package/src/overwrites/venia-ui/lib/components/CreateAccount/createAccount.js +4 -4
- package/src/overwrites/venia-ui/lib/components/CreateAccountPage/createAccountPage.js +28 -9
- package/src/overwrites/venia-ui/lib/components/CreateAccountPage/createAccountPage.module.css +12 -2
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderRow.js +1 -1
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +1 -0
- package/src/overwrites/venia-ui/lib/components/SignIn/signIn.js +23 -30
- package/src/overwrites/venia-ui/lib/components/SignInPage/signInPage.js +22 -9
- package/src/overwrites/venia-ui/lib/components/SignInPage/signInPage.module.css +10 -0
- package/src/talons/RFQ/rfq.gql.js +162 -0
- package/src/talons/RFQ/useRFQ.js +81 -0
- package/src/talons/SellerMegaMenu/megaMenu.gql.js +4 -3
- package/src/talons/SellerMegaMenu/useSellerMegaMenu.js +106 -33
- package/src/talons/SellerMegaMenu/useSellerMegaMenuItem.js +1 -1
- package/src/talons/SellerProducts/useProductContent.js +11 -7
- package/src/talons/SocialLogin/socialLogin.gql.js +106 -0
- package/src/talons/SocialLogin/useSocialLogin.js +169 -0
|
@@ -1,79 +1,101 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { useIntl } from 'react-intl';
|
|
3
3
|
import { StoreTitle } from '@magento/venia-ui/lib/components/Head';
|
|
4
4
|
import Image from '@magento/venia-ui/lib/components/Image';
|
|
5
|
-
import { Link } from 'react-router-dom';
|
|
5
|
+
import { Link, useParams, useLocation } from 'react-router-dom';
|
|
6
6
|
import Button from '@magento/venia-ui/lib/components/Button';
|
|
7
7
|
import ChatContent from '../LiveChat/chatContent';
|
|
8
8
|
import cn from 'classnames';
|
|
9
9
|
import { Send } from 'iconsax-react';
|
|
10
|
+
import Price from '@magento/venia-ui/lib/components/Price';
|
|
11
|
+
import { useRFQ } from '@riosst100/pwa-marketplace/src/talons/RFQ/useRFQ';
|
|
12
|
+
import LoadingIndicator from '@magento/venia-ui/lib/components/LoadingIndicator';
|
|
10
13
|
|
|
11
14
|
const quoteDetail = () => {
|
|
12
15
|
const { formatMessage } = useIntl();
|
|
16
|
+
const { id } = useParams();
|
|
17
|
+
const location = useLocation();
|
|
18
|
+
const locationRfq = location && location.state && location.state.rfq ? location.state.rfq : null;
|
|
19
|
+
const { loadRfqDetail, rfqDetailState, handleSendRfqMessage, startDetailPolling, stopDetailPolling, handleConvertQuickrfqToCart } = useRFQ();
|
|
20
|
+
const [messageText, setMessageText] = useState('');
|
|
21
|
+
const [isSending, setIsSending] = useState(false);
|
|
22
|
+
const [sendError, setSendError] = useState(null);
|
|
23
|
+
const detailData = rfqDetailState && rfqDetailState.data ? rfqDetailState.data.quickrfqDetail : null;
|
|
24
|
+
const detailLoading = rfqDetailState ? rfqDetailState.loading : false;
|
|
25
|
+
const detailError = rfqDetailState ? rfqDetailState.error : null;
|
|
13
26
|
const PAGE_TITLE = formatMessage({
|
|
14
27
|
id: 'Quotes.pageTitleTextQuoteDetail',
|
|
15
28
|
defaultMessage: 'Quote Detail'
|
|
16
29
|
});
|
|
17
30
|
|
|
31
|
+
// prefer image from info_buy_request if available; otherwise use placeholder
|
|
18
32
|
const urlImage = 'https://pwa-tcgcollective.local:8255/media/catalog/product/s/-/s-l1600_6__1.jpg?auto=webp&format=pjpg&width=495&height=618.75&fit=cover';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!locationRfq) {
|
|
36
|
+
const parsedId = id ? parseInt(id, 10) : NaN;
|
|
37
|
+
if (!isNaN(parsedId)) {
|
|
38
|
+
const variables = { quickrfqId: parsedId };
|
|
39
|
+
loadRfqDetail(variables);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}, [id, locationRfq, loadRfqDetail]);
|
|
43
|
+
|
|
44
|
+
// start polling messages every 5s while on detail page; stop on unmount
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (typeof startDetailPolling === 'function' && typeof stopDetailPolling === 'function') {
|
|
47
|
+
startDetailPolling(5000);
|
|
48
|
+
return () => stopDetailPolling();
|
|
49
|
+
}
|
|
50
|
+
}, [startDetailPolling, stopDetailPolling]);
|
|
51
|
+
|
|
52
|
+
const rfq = locationRfq || detailData || {};
|
|
53
|
+
const quickrfqIdValue = rfq && rfq.quickrfq_id ? (typeof rfq.quickrfq_id === 'number' ? rfq.quickrfq_id : parseInt(rfq.quickrfq_id, 10)) : (id ? parseInt(id, 10) : null);
|
|
54
|
+
const [isConverting, setIsConverting] = useState(false);
|
|
55
|
+
const [convertError, setConvertError] = useState(null);
|
|
56
|
+
const [convertSuccess, setConvertSuccess] = useState(null);
|
|
57
|
+
const status = rfq && rfq.status ? rfq.status : '-';
|
|
58
|
+
const quantity = rfq && rfq.quantity ? rfq.quantity : '-';
|
|
59
|
+
const pricePerProduct = rfq && rfq.price_per_product ? rfq.price_per_product : null;
|
|
60
|
+
const productName = rfq && rfq.product_name ? rfq.product_name : '-';
|
|
61
|
+
const currency = pricePerProduct && pricePerProduct.currency ? pricePerProduct.currency : (rfq && rfq.store_currency_code ? rfq.store_currency_code : '');
|
|
62
|
+
const unitValue = pricePerProduct && typeof pricePerProduct.value === 'number' ? pricePerProduct.value : null;
|
|
63
|
+
const qtyNumber = typeof quantity === 'number' ? quantity : (typeof quantity === 'string' ? parseFloat(quantity) : 0);
|
|
64
|
+
const expectedTotal = unitValue !== null && !isNaN(qtyNumber) ? unitValue * qtyNumber : null;
|
|
65
|
+
const contactName = rfq && rfq.contact_name ? rfq.contact_name : '-';
|
|
66
|
+
const email = rfq && rfq.email ? rfq.email : '-';
|
|
67
|
+
const phone = rfq && rfq.phone ? rfq.phone : '-';
|
|
68
|
+
const dateNeedQuote = rfq && rfq.date_need_quote ? rfq.date_need_quote : '-';
|
|
69
|
+
|
|
70
|
+
const isInitialLoading = detailLoading && !detailData;
|
|
71
|
+
if (isInitialLoading && !locationRfq) {
|
|
72
|
+
return <LoadingIndicator />;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (detailError && !locationRfq) {
|
|
76
|
+
return (
|
|
77
|
+
<div className="p-4">
|
|
78
|
+
<div className="text-red-600 text-sm">
|
|
79
|
+
{formatMessage({ id: 'Quotes.detailError', defaultMessage: 'Failed to load quote detail.' })}
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// map backend messages to ChatContent shape using customer_id
|
|
86
|
+
const chatData = Array.isArray(rfq && rfq.messages)
|
|
87
|
+
? rfq.messages.map(m => ({
|
|
88
|
+
message: m && m.message ? m.message : '',
|
|
89
|
+
type: m && m.customer_id === 0 ? 'seller' : 'buyer',
|
|
90
|
+
timeStamp: m && m.created_at ? m.created_at : ''
|
|
91
|
+
}))
|
|
92
|
+
: [];
|
|
71
93
|
|
|
72
94
|
return (
|
|
73
95
|
<div className='relative grid gap-y-md'>
|
|
74
96
|
<StoreTitle>{PAGE_TITLE}</StoreTitle>
|
|
75
97
|
<div aria-live="polite" className="text-xl font-medium text-left">
|
|
76
|
-
{PAGE_TITLE} -
|
|
98
|
+
{PAGE_TITLE} - #{id}
|
|
77
99
|
</div>
|
|
78
100
|
<div className='rounded-md border border-gray-100 px-4 py-6 flex flex-col-reverse md_flex-row justify-between gap-x-10'>
|
|
79
101
|
<div className='flex flex-col gap-y-4 w-full md_w-6/12'>
|
|
@@ -88,7 +110,7 @@ const quoteDetail = () => {
|
|
|
88
110
|
}
|
|
89
111
|
</span>
|
|
90
112
|
<span className='font-medium block text-blue-700'>
|
|
91
|
-
|
|
113
|
+
{status}
|
|
92
114
|
</span>
|
|
93
115
|
</p>
|
|
94
116
|
</div>
|
|
@@ -103,7 +125,7 @@ const quoteDetail = () => {
|
|
|
103
125
|
}
|
|
104
126
|
</span>
|
|
105
127
|
<span className='font-normal block'>
|
|
106
|
-
|
|
128
|
+
{quantity} Units
|
|
107
129
|
</span>
|
|
108
130
|
</p>
|
|
109
131
|
</div>
|
|
@@ -118,7 +140,7 @@ const quoteDetail = () => {
|
|
|
118
140
|
}
|
|
119
141
|
</span>
|
|
120
142
|
<span className='font-normal block'>
|
|
121
|
-
|
|
143
|
+
-
|
|
122
144
|
</span>
|
|
123
145
|
</p>
|
|
124
146
|
</div>
|
|
@@ -133,7 +155,13 @@ const quoteDetail = () => {
|
|
|
133
155
|
}
|
|
134
156
|
</span>
|
|
135
157
|
<span className='font-normal block'>
|
|
136
|
-
|
|
158
|
+
{unitValue !== null ? (
|
|
159
|
+
<>
|
|
160
|
+
<Price currencyCode={currency} value={unitValue} /> {' '} Per Unit
|
|
161
|
+
</>
|
|
162
|
+
) : (
|
|
163
|
+
'-'
|
|
164
|
+
)}
|
|
137
165
|
</span>
|
|
138
166
|
</p>
|
|
139
167
|
</div>
|
|
@@ -148,7 +176,7 @@ const quoteDetail = () => {
|
|
|
148
176
|
}
|
|
149
177
|
</span>
|
|
150
178
|
<span className='font-normal block'>
|
|
151
|
-
|
|
179
|
+
-
|
|
152
180
|
</span>
|
|
153
181
|
</p>
|
|
154
182
|
</div>
|
|
@@ -163,7 +191,11 @@ const quoteDetail = () => {
|
|
|
163
191
|
}
|
|
164
192
|
</span>
|
|
165
193
|
<span className='font-medium block'>
|
|
166
|
-
|
|
194
|
+
{expectedTotal !== null ? (
|
|
195
|
+
<Price currencyCode={currency} value={expectedTotal} />
|
|
196
|
+
) : (
|
|
197
|
+
'-'
|
|
198
|
+
)} {' '} Units
|
|
167
199
|
</span>
|
|
168
200
|
</p>
|
|
169
201
|
</div>
|
|
@@ -178,7 +210,7 @@ const quoteDetail = () => {
|
|
|
178
210
|
}
|
|
179
211
|
</span>
|
|
180
212
|
<span className='font-normal block'>
|
|
181
|
-
|
|
213
|
+
-
|
|
182
214
|
</span>
|
|
183
215
|
</p>
|
|
184
216
|
</div>
|
|
@@ -193,7 +225,7 @@ const quoteDetail = () => {
|
|
|
193
225
|
}
|
|
194
226
|
</span>
|
|
195
227
|
<span className='font-normal block'>
|
|
196
|
-
|
|
228
|
+
-
|
|
197
229
|
</span>
|
|
198
230
|
</p>
|
|
199
231
|
<small className='text-[10px] text-gray-600'>
|
|
@@ -216,7 +248,7 @@ const quoteDetail = () => {
|
|
|
216
248
|
}
|
|
217
249
|
</span>
|
|
218
250
|
<span className='font-normal block'>
|
|
219
|
-
|
|
251
|
+
-
|
|
220
252
|
</span>
|
|
221
253
|
</p>
|
|
222
254
|
</div>
|
|
@@ -231,7 +263,7 @@ const quoteDetail = () => {
|
|
|
231
263
|
}
|
|
232
264
|
</span>
|
|
233
265
|
<span className='font-normal block'>
|
|
234
|
-
|
|
266
|
+
{dateNeedQuote}
|
|
235
267
|
</span>
|
|
236
268
|
</p>
|
|
237
269
|
</div>
|
|
@@ -246,7 +278,7 @@ const quoteDetail = () => {
|
|
|
246
278
|
}
|
|
247
279
|
</span>
|
|
248
280
|
<span className='font-normal block'>
|
|
249
|
-
|
|
281
|
+
-
|
|
250
282
|
</span>
|
|
251
283
|
</p>
|
|
252
284
|
</div>
|
|
@@ -260,29 +292,56 @@ const quoteDetail = () => {
|
|
|
260
292
|
root: ' relative self-center mb-5'
|
|
261
293
|
}}
|
|
262
294
|
/>
|
|
263
|
-
|
|
264
295
|
<p className='text-[16px] font-medium text-colorDefault text-center'>
|
|
265
|
-
|
|
296
|
+
{unitValue !== null ? (
|
|
297
|
+
<Price currencyCode={currency} value={unitValue} />
|
|
298
|
+
) : (
|
|
299
|
+
'-'
|
|
300
|
+
)}
|
|
266
301
|
</p>
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
POP MART Star Wars Series Blind Box Confirmed Figures Designer Art New Toys Gift
|
|
302
|
+
<div className="max-w-[360px] self-center mb-5 text-center">
|
|
303
|
+
<span className=" text-[13px] block font-medium text-colorDefault w-full">
|
|
304
|
+
{productName}
|
|
271
305
|
</span>
|
|
272
|
-
</
|
|
306
|
+
</div>
|
|
273
307
|
<Button
|
|
274
308
|
priority='high'
|
|
275
309
|
classes={{
|
|
276
310
|
content: 'capitalize text-[16px] font-medium'
|
|
277
311
|
}}
|
|
312
|
+
disabled={isConverting || !quickrfqIdValue || isNaN(quickrfqIdValue)}
|
|
313
|
+
aria-busy={isConverting}
|
|
314
|
+
onPress={async () => {
|
|
315
|
+
const qid = quickrfqIdValue;
|
|
316
|
+
if (!qid || isNaN(qid)) return;
|
|
317
|
+
try {
|
|
318
|
+
setConvertError(null);
|
|
319
|
+
setConvertSuccess(null);
|
|
320
|
+
setIsConverting(true);
|
|
321
|
+
const res = await handleConvertQuickrfqToCart(qid);
|
|
322
|
+
const payload = res && res.data && res.data.convertQuickrfqToCart ? res.data.convertQuickrfqToCart : null;
|
|
323
|
+
if (payload && payload.status) {
|
|
324
|
+
setConvertSuccess(payload.message || 'Converted to cart.');
|
|
325
|
+
} else {
|
|
326
|
+
setConvertError('Failed to convert quote to cart.');
|
|
327
|
+
}
|
|
328
|
+
} catch (e) {
|
|
329
|
+
setConvertError('Failed to convert quote to cart.');
|
|
330
|
+
} finally {
|
|
331
|
+
setIsConverting(false);
|
|
332
|
+
}
|
|
333
|
+
}}
|
|
278
334
|
>
|
|
279
|
-
{
|
|
280
|
-
formatMessage({
|
|
281
|
-
|
|
282
|
-
defaultMessage: 'Add To Cart'
|
|
283
|
-
})
|
|
284
|
-
}
|
|
335
|
+
{isConverting
|
|
336
|
+
? formatMessage({ id: 'Quotes.converting', defaultMessage: 'Add To Cart…' })
|
|
337
|
+
: formatMessage({ id: 'Quotes.addToCart', defaultMessage: 'Add To Cart' })}
|
|
285
338
|
</Button>
|
|
339
|
+
{convertError ? (
|
|
340
|
+
<div className='text-red-600 text-[12px] mt-2 text-center'>{convertError}</div>
|
|
341
|
+
) : null}
|
|
342
|
+
{convertSuccess ? (
|
|
343
|
+
<div className='text-green-600 text-[12px] mt-2 text-center'>{convertSuccess}</div>
|
|
344
|
+
) : null}
|
|
286
345
|
</div>
|
|
287
346
|
</div>
|
|
288
347
|
<div className=' flex flex-col mb-10'>
|
|
@@ -291,12 +350,14 @@ const quoteDetail = () => {
|
|
|
291
350
|
</div>
|
|
292
351
|
<div className='rounded-md border border-gray-100 p-4 pr-0 pt-0 flex flex-col gap-y-6'>
|
|
293
352
|
<div className='max-h-[600px] overflow-auto relative chat-container pr-4 pt-4'>
|
|
294
|
-
<ChatContent chatData={
|
|
353
|
+
<ChatContent chatData={chatData} />
|
|
295
354
|
</div>
|
|
296
355
|
<div className='flex gap-2 pr-4'>
|
|
297
356
|
<textarea
|
|
298
357
|
className='w-full focus-visible_outline-none border border-gray-100 p-1 rounded-md'
|
|
299
358
|
cols={5}
|
|
359
|
+
value={messageText}
|
|
360
|
+
onChange={e => setMessageText(e.target.value)}
|
|
300
361
|
/>
|
|
301
362
|
<Button
|
|
302
363
|
priority='high'
|
|
@@ -304,15 +365,41 @@ const quoteDetail = () => {
|
|
|
304
365
|
content: "flex justify-center gap-x-2.5 items-center text-[14px] font-medium capitalize"
|
|
305
366
|
}}
|
|
306
367
|
className={cn(
|
|
307
|
-
"
|
|
308
|
-
|
|
368
|
+
"px-6 py-2 rounded-full text-white border focus-visible_outline-none",
|
|
369
|
+
isSending
|
|
370
|
+
? "bg-gray-400 border-gray-400"
|
|
371
|
+
: "bg-blue-600 border-blue-600 hover_bg-blue-700 hover_border-blue-700"
|
|
309
372
|
)}
|
|
373
|
+
disabled={isSending || !(messageText || '').trim()}
|
|
374
|
+
aria-busy={isSending}
|
|
375
|
+
onPress={async () => {
|
|
376
|
+
const qid = quickrfqIdValue;
|
|
377
|
+
const msg = (messageText || '').trim();
|
|
378
|
+
if (!qid || isNaN(qid) || msg.length === 0) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
try {
|
|
382
|
+
setSendError(null);
|
|
383
|
+
setIsSending(true);
|
|
384
|
+
await handleSendRfqMessage({ quickrfq_id: qid, message: msg });
|
|
385
|
+
setMessageText('');
|
|
386
|
+
await loadRfqDetail({ quickrfqId: qid });
|
|
387
|
+
} catch (err) {
|
|
388
|
+
setSendError('Failed to send message.');
|
|
389
|
+
} finally {
|
|
390
|
+
setIsSending(false);
|
|
391
|
+
}
|
|
392
|
+
}}
|
|
310
393
|
>
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
394
|
+
{isSending ? (
|
|
395
|
+
<span className='text-white text-[14px]'>Sending…</span>
|
|
396
|
+
) : (
|
|
397
|
+
<Send size="24" className='text-white' />
|
|
398
|
+
)}
|
|
315
399
|
</Button>
|
|
400
|
+
{sendError ? (
|
|
401
|
+
<span className='text-red-600 text-[12px] self-center'>{sendError}</span>
|
|
402
|
+
) : null}
|
|
316
403
|
</div>
|
|
317
404
|
</div>
|
|
318
405
|
</div>
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import React, { useMemo, useEffect } from 'react';
|
|
1
|
+
import React, { useMemo, useEffect, useState, useCallback } from 'react';
|
|
2
2
|
import { useIntl, FormattedMessage } from 'react-intl';
|
|
3
|
-
import {
|
|
4
|
-
Search as SearchIcon,
|
|
5
|
-
AlertCircle as AlertCircleIcon,
|
|
6
|
-
ArrowRight as SubmitIcon
|
|
7
|
-
} from 'react-feather';
|
|
3
|
+
import { AlertCircle as AlertCircleIcon } from 'react-feather';
|
|
8
4
|
import { shape, string } from 'prop-types';
|
|
9
5
|
import { Form } from 'informed';
|
|
10
6
|
|
|
11
7
|
import { useToasts } from '@magento/peregrine/lib/Toasts';
|
|
12
|
-
import OrderHistoryContextProvider from '@magento/peregrine/lib/talons/OrderHistoryPage/orderHistoryContext';
|
|
13
|
-
import { useOrderHistoryPage } from '@magento/peregrine/lib/talons/OrderHistoryPage/useOrderHistoryPage';
|
|
14
|
-
|
|
15
8
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
16
9
|
import Button from '@magento/venia-ui/lib/components/Button';
|
|
17
10
|
import Icon from '@magento/venia-ui/lib/components/Icon';
|
|
@@ -23,7 +16,7 @@ import defaultClasses from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/l
|
|
|
23
16
|
import OrderRow from './orderRow';
|
|
24
17
|
import ResetButton from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/OrderHistoryPage/resetButton';
|
|
25
18
|
import { SearchNormal } from 'iconsax-react';
|
|
26
|
-
import
|
|
19
|
+
import { useRFQ } from '@riosst100/pwa-marketplace/src/talons/RFQ/useRFQ';
|
|
27
20
|
|
|
28
21
|
const errorIcon = (
|
|
29
22
|
<Icon
|
|
@@ -33,21 +26,13 @@ const errorIcon = (
|
|
|
33
26
|
}}
|
|
34
27
|
/>
|
|
35
28
|
);
|
|
36
|
-
|
|
29
|
+
// no search icon needed
|
|
37
30
|
|
|
38
31
|
const QuoteList = props => {
|
|
39
|
-
const
|
|
40
|
-
const {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
handleReset,
|
|
44
|
-
handleSubmit,
|
|
45
|
-
isBackgroundLoading,
|
|
46
|
-
isLoadingWithoutData,
|
|
47
|
-
orders,
|
|
48
|
-
pageInfo,
|
|
49
|
-
searchText
|
|
50
|
-
} = talonProps;
|
|
32
|
+
const { loadRfqList, rfqListState } = useRFQ();
|
|
33
|
+
const { data: rfqListData, loading: rfqLoading, error: rfqError } = rfqListState || {};
|
|
34
|
+
const [searchText, setSearchText] = useState('');
|
|
35
|
+
const [submittedSearch, setSubmittedSearch] = useState('');
|
|
51
36
|
const [, { addToast }] = useToasts();
|
|
52
37
|
const { formatMessage } = useIntl();
|
|
53
38
|
const PAGE_TITLE = formatMessage({
|
|
@@ -59,43 +44,41 @@ const QuoteList = props => {
|
|
|
59
44
|
defaultMessage: 'Search by Quote Number'
|
|
60
45
|
});
|
|
61
46
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
{ count: orders.length }
|
|
68
|
-
);
|
|
47
|
+
// derive items
|
|
48
|
+
const rfqItems = rfqListData?.quickrfqList?.items || [];
|
|
49
|
+
const totalCount = rfqListData?.quickrfqList?.total_count || 0;
|
|
50
|
+
const pageInfo = rfqListData?.quickrfqList?.page_info || null;
|
|
69
51
|
|
|
70
52
|
const classes = useStyle(defaultClasses, props.classes);
|
|
71
53
|
|
|
72
54
|
const orderRows = useMemo(() => {
|
|
73
|
-
return
|
|
74
|
-
|
|
55
|
+
return rfqItems.map(item => {
|
|
56
|
+
const key = `${item.quickrfq_id}-${item.update_date || item.create_date}`;
|
|
57
|
+
return <OrderRow key={key} rfq={item} />;
|
|
75
58
|
});
|
|
76
|
-
}, [
|
|
59
|
+
}, [rfqItems]);
|
|
77
60
|
|
|
78
61
|
const pageContents = useMemo(() => {
|
|
79
|
-
if (
|
|
62
|
+
if (rfqLoading && !rfqItems.length) {
|
|
80
63
|
return <LoadingIndicator />;
|
|
81
|
-
} else if (!
|
|
64
|
+
} else if (!rfqLoading && submittedSearch && !rfqItems.length) {
|
|
82
65
|
return (
|
|
83
66
|
<h3 className={classes.emptyHistoryMessage}>
|
|
84
67
|
<FormattedMessage
|
|
85
|
-
id={'
|
|
86
|
-
defaultMessage={`
|
|
68
|
+
id={'quotesPage.invalidQuoteNumber'}
|
|
69
|
+
defaultMessage={`Quote "${submittedSearch}" was not found.`}
|
|
87
70
|
values={{
|
|
88
|
-
number:
|
|
71
|
+
number: submittedSearch
|
|
89
72
|
}}
|
|
90
73
|
/>
|
|
91
74
|
</h3>
|
|
92
75
|
);
|
|
93
|
-
} else if (!
|
|
76
|
+
} else if (!rfqLoading && !rfqItems.length) {
|
|
94
77
|
return (
|
|
95
78
|
<h3 className={classes.emptyHistoryMessage}>
|
|
96
79
|
<FormattedMessage
|
|
97
|
-
id={'
|
|
98
|
-
defaultMessage={"You don't have any
|
|
80
|
+
id={'quotesPage.emptyDataMessage'}
|
|
81
|
+
defaultMessage={"You don't have any quotes yet."}
|
|
99
82
|
/>
|
|
100
83
|
</h3>
|
|
101
84
|
);
|
|
@@ -112,13 +95,24 @@ const QuoteList = props => {
|
|
|
112
95
|
}, [
|
|
113
96
|
classes.emptyHistoryMessage,
|
|
114
97
|
classes.orderHistoryTable,
|
|
115
|
-
|
|
116
|
-
isLoadingWithoutData,
|
|
98
|
+
rfqLoading,
|
|
117
99
|
orderRows,
|
|
118
|
-
|
|
119
|
-
|
|
100
|
+
rfqItems.length,
|
|
101
|
+
submittedSearch
|
|
120
102
|
]);
|
|
121
103
|
|
|
104
|
+
const handleReset = useCallback(() => {
|
|
105
|
+
setSearchText('');
|
|
106
|
+
setSubmittedSearch('');
|
|
107
|
+
loadRfqList({
|
|
108
|
+
variables: {
|
|
109
|
+
currentPage: 1,
|
|
110
|
+
pageSize: 20,
|
|
111
|
+
filters: {}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}, [loadRfqList]);
|
|
115
|
+
|
|
122
116
|
const resetButtonElement = searchText ? (
|
|
123
117
|
<ResetButton onReset={handleReset} />
|
|
124
118
|
) : null;
|
|
@@ -128,18 +122,36 @@ const QuoteList = props => {
|
|
|
128
122
|
);
|
|
129
123
|
|
|
130
124
|
const pageInfoLabel = pageInfo ? (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
125
|
+
(() => {
|
|
126
|
+
const currentPage = pageInfo.current_page || 1;
|
|
127
|
+
const pageSize = pageInfo.page_size || 20;
|
|
128
|
+
const total = totalCount || 0;
|
|
129
|
+
const current = Math.min(currentPage * pageSize, total);
|
|
130
|
+
return (
|
|
131
|
+
<FormattedMessage
|
|
132
|
+
defaultMessage={'Showing {current} of {total}'}
|
|
133
|
+
id={'rfqList.pageInfo'}
|
|
134
|
+
values={{ current, total }}
|
|
135
|
+
/>
|
|
136
|
+
);
|
|
137
|
+
})()
|
|
136
138
|
) : null;
|
|
137
139
|
|
|
138
|
-
const loadMoreButton =
|
|
140
|
+
const loadMoreButton = pageInfo && pageInfo.current_page < Math.ceil((totalCount || 0) / (pageInfo.page_size || 20)) ? (
|
|
139
141
|
<Button
|
|
140
142
|
classes={{ root_lowPriority: classes.loadMoreButton }}
|
|
141
|
-
disabled={
|
|
142
|
-
onClick={
|
|
143
|
+
disabled={rfqLoading}
|
|
144
|
+
onClick={() =>
|
|
145
|
+
loadRfqList({
|
|
146
|
+
variables: {
|
|
147
|
+
currentPage: (pageInfo.current_page || 1) + 1,
|
|
148
|
+
pageSize: pageInfo.page_size || 20,
|
|
149
|
+
filters: submittedSearch
|
|
150
|
+
? { quickrfq_id: { eq: submittedSearch } }
|
|
151
|
+
: {}
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
}
|
|
143
155
|
priority="low"
|
|
144
156
|
>
|
|
145
157
|
<FormattedMessage
|
|
@@ -150,20 +162,34 @@ const QuoteList = props => {
|
|
|
150
162
|
) : null;
|
|
151
163
|
|
|
152
164
|
useEffect(() => {
|
|
153
|
-
|
|
165
|
+
// initial load
|
|
166
|
+
loadRfqList({
|
|
167
|
+
variables: { currentPage: 1, pageSize: 20, filters: {} }
|
|
168
|
+
});
|
|
169
|
+
}, [loadRfqList]);
|
|
170
|
+
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
if (rfqError?.message) {
|
|
154
173
|
addToast({
|
|
155
174
|
type: 'error',
|
|
156
175
|
icon: errorIcon,
|
|
157
|
-
message:
|
|
176
|
+
message: rfqError.message,
|
|
158
177
|
dismissable: true,
|
|
159
178
|
timeout: 10000
|
|
160
179
|
});
|
|
161
180
|
}
|
|
162
|
-
}, [addToast,
|
|
181
|
+
}, [addToast, rfqError]);
|
|
182
|
+
|
|
183
|
+
const handleSubmit = useCallback(({ values }) => {
|
|
184
|
+
const search = values?.search?.trim() || '';
|
|
185
|
+
setSearchText(search);
|
|
186
|
+
setSubmittedSearch(search);
|
|
187
|
+
const filters = search ? { quickrfq_id: { eq: search } } : {};
|
|
188
|
+
loadRfqList({ variables: { currentPage: 1, pageSize: 20, filters } });
|
|
189
|
+
}, [loadRfqList]);
|
|
163
190
|
|
|
164
191
|
return (
|
|
165
|
-
<
|
|
166
|
-
<div className="grid gap-y-md">
|
|
192
|
+
<div className="grid gap-y-md">
|
|
167
193
|
<StoreTitle>{PAGE_TITLE}</StoreTitle>
|
|
168
194
|
<div aria-live="polite" className="text-xl font-medium text-left">
|
|
169
195
|
{PAGE_TITLE}
|
|
@@ -175,8 +201,6 @@ const QuoteList = props => {
|
|
|
175
201
|
<div className={classes.filterRow}>
|
|
176
202
|
<Form className="flex gap-x-1 border border-gray-100 rounded-full px-[15px] w-[calc(100%-120px)] max-w-[450px]" onSubmit={handleSubmit}>
|
|
177
203
|
<TextInput
|
|
178
|
-
// after={resetButtonElement}
|
|
179
|
-
// before={searchIcon}
|
|
180
204
|
field="search"
|
|
181
205
|
id={classes.search}
|
|
182
206
|
placeholder={SEARCH_PLACE_HOLDER}
|
|
@@ -191,12 +215,11 @@ const QuoteList = props => {
|
|
|
191
215
|
) : (
|
|
192
216
|
<Button
|
|
193
217
|
className="focus-visible_outline-none"
|
|
194
|
-
disabled={
|
|
195
|
-
isBackgroundLoading || isLoadingWithoutData
|
|
196
|
-
}
|
|
218
|
+
disabled={rfqLoading}
|
|
197
219
|
priority={'high'}
|
|
198
|
-
type="
|
|
220
|
+
type="button"
|
|
199
221
|
aria-label="submit"
|
|
222
|
+
onPress={(_evt, formApi) => formApi.submitForm()}
|
|
200
223
|
>
|
|
201
224
|
{submitIcon}
|
|
202
225
|
</Button>
|
|
@@ -207,7 +230,6 @@ const QuoteList = props => {
|
|
|
207
230
|
{pageContents}
|
|
208
231
|
{loadMoreButton}
|
|
209
232
|
</div>
|
|
210
|
-
</OrderHistoryContextProvider >
|
|
211
233
|
);
|
|
212
234
|
};
|
|
213
235
|
|