@riosst100/pwa-marketplace 1.9.2 → 1.9.4

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 (25) hide show
  1. package/package.json +4 -2
  2. package/src/componentOverrideMapping.js +1 -0
  3. package/src/components/AccountLayout/accountlayout.module.css +11 -1
  4. package/src/components/AccountLayout/index.js +60 -13
  5. package/src/components/CrossSeller/starIcon.js +2 -5
  6. package/src/components/FavoriteSeller/favoriteSeller.js +32 -0
  7. package/src/components/FavoriteSeller/index.js +14 -0
  8. package/src/components/FavoriteSeller/item.js +140 -0
  9. package/src/components/FilterTop/CurrentTopFilters/currentTopFilter.js +1 -1
  10. package/src/components/FilterTop/FilterBlockList/filterTopItemGroup.js +1 -1
  11. package/src/components/LiveChat/chatContent.js +4 -4
  12. package/src/components/RFQ/index.js +39 -0
  13. package/src/components/RFQ/modalRfq.js +249 -0
  14. package/src/components/RFQPage/index.js +14 -0
  15. package/src/components/RFQPage/orderRow.js +318 -0
  16. package/src/components/RFQPage/quoteDetail.js +342 -0
  17. package/src/components/RFQPage/quoteDetailPage.js +14 -0
  18. package/src/components/RFQPage/quoteList.js +227 -0
  19. package/src/intercept.js +28 -0
  20. package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.js +2 -1
  21. package/src/overwrites/venia-ui/lib/components/ProductFullDetail/components/auctionDetail.js +0 -1
  22. package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +5 -0
  23. package/src/overwrites/venia-ui/lib/components/TextArea/index.js +1 -0
  24. package/src/overwrites/venia-ui/lib/components/TextArea/textArea.js +44 -0
  25. package/src/overwrites/venia-ui/lib/components/TextArea/textArea.module.css +27 -0
@@ -0,0 +1,249 @@
1
+ import React, { useState, useC } from 'react';
2
+ import Button from '@magento/venia-ui/lib/components/Button';
3
+ import Modal from '@riosst100/pwa-marketplace/src/components/Modal';
4
+ import { X } from 'react-feather';
5
+ import { primary900 } from '@riosst100/pwa-marketplace/src/theme/vars';
6
+ import Field from '@magento/venia-ui/lib/components/Field';
7
+ import TextInput from '@magento/venia-ui/lib/components/TextInput';
8
+ import TextArea from '@magento/venia-ui/lib/components/TextArea';
9
+ import { isRequired } from '@magento/venia-ui/lib/util/formValidators';
10
+ import DatePicker from "react-datepicker";
11
+ import { Form } from 'informed';
12
+ import { useIntl } from 'react-intl';
13
+ import { useDropzone } from "react-dropzone";
14
+ import { DocumentUpload } from 'iconsax-react';
15
+ import cn from 'classnames';
16
+
17
+ import "react-datepicker/dist/react-datepicker.css";
18
+
19
+ const RFQModalForm = (props) => {
20
+
21
+ const { open = false, setOpen = () => { } } = props;
22
+ const { formatMessage } = useIntl();
23
+
24
+ const [startDate, setStartDate] = useState(new Date());
25
+
26
+ // Upload FIle
27
+ const {
28
+ acceptedFiles,
29
+ getRootProps,
30
+ getInputProps,
31
+ isDragActive
32
+ } = useDropzone();
33
+
34
+ const files = acceptedFiles.map((file) => (
35
+ <div key={file.path} className='block font-medium mb-1'>
36
+ {file.path} - {Math.round(file.size / 1000)} kB
37
+ </div>
38
+ ));
39
+
40
+ return (
41
+ <>
42
+ <Modal
43
+ open={open}
44
+ className='!p-[30px] md_min-w-[550px] modal_bid'
45
+ >
46
+ <div className='modal_bid-content'>
47
+ <div className='header_title-modal flex justify-between mb-4'>
48
+ <div className='text-lg text-black font-semibold'>
49
+ {
50
+ formatMessage({
51
+ id: 'productFullDetail.RequestQuote',
52
+ defaultMessage:
53
+ 'Request a Quote'
54
+ })
55
+ }
56
+ </div>
57
+ <button onClick={() => { setOpen(!open) }} >
58
+ <X size={24} color={primary900} />
59
+ </button>
60
+ </div>
61
+
62
+ <div className='flex flex-col gap-y-[16px]'>
63
+ <Form
64
+ data-cy="form_bid"
65
+ className="flex flex-col gap-y-4"
66
+ initialValues={{}}
67
+ onSubmit={() => { }}
68
+ onChange={() => { }}
69
+ >
70
+ <Field
71
+ id="quote_price_per_unit_field"
72
+ label={
73
+ formatMessage({
74
+ id: 'productFullDetail.QuotePricePerUnit',
75
+ defaultMessage:
76
+ 'Quote Price Per Unit'
77
+ })
78
+ }
79
+ >
80
+ <TextInput
81
+ id="quote_price_per_unit"
82
+ field="quote_price_per_unit"
83
+ validate={isRequired}
84
+ validateOnBlur
85
+ mask={value => value && value.trim()}
86
+ maskOnBlur={true}
87
+ data-cy="quote_price_per_unit"
88
+ aria-label={'quote_price_per_unit'}
89
+ placeholder={'10.00'}
90
+ />
91
+ </Field>
92
+
93
+ <Field
94
+ id="quote_qty_field"
95
+ label={
96
+ formatMessage({
97
+ id: 'productFullDetail.QuoteQuantity',
98
+ defaultMessage:
99
+ 'Quote Quantity'
100
+ })
101
+ }
102
+ >
103
+ <TextInput
104
+ id="quote_qty"
105
+ field="quote_qty"
106
+ validate={isRequired}
107
+ validateOnBlur
108
+ mask={value => value && value.trim()}
109
+ maskOnBlur={true}
110
+ data-cy="quote_qty"
111
+ aria-label={'quote_qty'}
112
+ placeholder={'10'}
113
+ />
114
+ </Field>
115
+
116
+ <Field
117
+ id="date_need_quote_field"
118
+ label={
119
+ formatMessage({
120
+ id: 'productFullDetail.dateNeedQuote',
121
+ defaultMessage:
122
+ 'Date Need Quote'
123
+ })
124
+ }
125
+ >
126
+ <DatePicker
127
+ className='w-full border border-gray-100 rounded-md px-[10px] py-[5px] min-h-[40px]'
128
+ selected={startDate}
129
+ onChange={(date) => setStartDate(date)}
130
+ />
131
+ </Field>
132
+
133
+ <Field
134
+ id="phone_number_field"
135
+ label={
136
+ formatMessage({
137
+ id: 'productFullDetail.phoneNumber',
138
+ defaultMessage:
139
+ 'Phone Number'
140
+ })
141
+ }
142
+ >
143
+ <TextInput
144
+ id="phone_number"
145
+ field="phone_number"
146
+ validate={isRequired}
147
+ validateOnBlur
148
+ mask={value => value && value.trim()}
149
+ maskOnBlur={true}
150
+ data-cy="phone_number"
151
+ aria-label={'phone_number'}
152
+ placeholder={'10'}
153
+ />
154
+ </Field>
155
+
156
+ <Field
157
+ id="quote_comment_field"
158
+ label={
159
+ formatMessage({
160
+ id: 'productFullDetail.addYourComment',
161
+ defaultMessage:
162
+ 'Add Your Comment'
163
+ })
164
+ }
165
+ >
166
+ <TextArea
167
+ id="quote_comment"
168
+ field="quote_comment"
169
+ validateOnBlur
170
+ mask={value => value && value.trim()}
171
+ maskOnBlur={true}
172
+ data-cy="quote_comment"
173
+ aria-label={'quote_comment'}
174
+ placeholder={'Your Comment'}
175
+ />
176
+ </Field>
177
+
178
+ <section className="wfp--dropzone">
179
+ <div
180
+ {...getRootProps({ isDragActive })}
181
+ className='border border-blue-600 rounded-md border-dashed flex flex-col justify-center items-center py-6'
182
+ >
183
+ <input {...getInputProps()} />
184
+ <DocumentUpload
185
+ size="32"
186
+ color="#6243FA"
187
+ />
188
+ <div className='mt-2 text-blue-600'>Drop files or click here to upload</div>
189
+ </div>
190
+ {files && (
191
+ <div className="wfp--dropzone__file-list mt-4">
192
+ <ul>{files}</ul>
193
+ </div>
194
+ )}
195
+ </section>
196
+
197
+
198
+ <div className='actions flex justify-end gap-x-2.5 mt-4'>
199
+ <Button
200
+ priority='low'
201
+ classes={{
202
+ content: 'capitalize text-[16px] font-semibold'
203
+ }}
204
+ onClick={() => setOpen(false)}
205
+ >
206
+ {
207
+ formatMessage({
208
+ id: 'productFullDetail.cancel',
209
+ defaultMessage:
210
+ 'Cancel'
211
+ })
212
+ }
213
+ </Button>
214
+ <Button
215
+ priority='high'
216
+ classes={{
217
+ content: 'capitalize text-[16px] font-semibold'
218
+ }}
219
+ >
220
+ {
221
+ formatMessage({
222
+ id: 'productFullDetail.SendRequest',
223
+ defaultMessage:
224
+ 'Send Request'
225
+ })
226
+ }
227
+ </Button>
228
+ </div>
229
+ </Form>
230
+ </div>
231
+ </div>
232
+ </Modal>
233
+ <style jsx>
234
+ {`
235
+ .react-datepicker__input-container>input:focus-visible,
236
+ .react-datepicker__input-container>input:focus,
237
+ .react-datepicker__input-container>input:active {
238
+ outline: none;
239
+ }
240
+ .react-datepicker-popper[data-placement^=bottom] .react-datepicker__triangle::after {
241
+ left: 25px;
242
+ }
243
+ `}
244
+ </style>
245
+ </>
246
+ )
247
+ }
248
+
249
+ export default RFQModalForm;
@@ -0,0 +1,14 @@
1
+ import AccountLayout from '@riosst100/pwa-marketplace/src/components/AccountLayout';
2
+ import QuoteList from '@riosst100/pwa-marketplace/src/components/RFQPage/quoteList';
3
+
4
+ import React from 'react'
5
+
6
+ const index = () => {
7
+ return (
8
+ <AccountLayout>
9
+ <QuoteList />
10
+ </AccountLayout>
11
+ )
12
+ }
13
+
14
+ export default index;
@@ -0,0 +1,318 @@
1
+ import React from 'react';
2
+ import { arrayOf, number, shape, string } from 'prop-types';
3
+ import { ChevronDown, ChevronUp } from 'react-feather';
4
+ import { FormattedMessage, useIntl } from 'react-intl';
5
+ import Price from '@magento/venia-ui/lib/components/Price';
6
+ import { useOrderRow } from '@magento/peregrine/lib/talons/OrderHistoryPage/useOrderRow';
7
+
8
+ import { useStyle } from '@magento/venia-ui/lib/classify';
9
+ import Icon from '@magento/venia-ui/lib/components/Icon';
10
+ import CollapsedImageGallery from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/OrderHistoryPage/collapsedImageGallery';
11
+ import OrderDetails from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/OrderHistoryPage/OrderDetails';
12
+ import defaultClasses from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderRow.module.css';
13
+ import cn from 'classnames';
14
+ import { Verify } from 'iconsax-react';
15
+ import PlaceholderImage from '@magento/venia-ui/lib/components/Image/placeholderImage';
16
+ import { Link } from 'react-router-dom';
17
+
18
+ const OrderRow = props => {
19
+ const { order } = props;
20
+ const { formatMessage } = useIntl();
21
+ const {
22
+ invoices,
23
+ items,
24
+ number: orderNumber,
25
+ order_date: orderDate,
26
+ shipments,
27
+ status,
28
+ total
29
+ } = order;
30
+ const { grand_total: grandTotal } = total;
31
+ const { currency, value: orderTotal } = grandTotal;
32
+
33
+ // Convert date to ISO-8601 format so Safari can also parse it
34
+ const isoFormattedDate = orderDate.replace(' ', 'T');
35
+ const formattedDate = new Date(isoFormattedDate).toLocaleDateString(
36
+ undefined,
37
+ {
38
+ year: 'numeric',
39
+ month: 'short',
40
+ day: 'numeric'
41
+ }
42
+ );
43
+
44
+ const hasInvoice = !!invoices.length;
45
+ const hasShipment = !!shipments.length;
46
+ let derivedStatus;
47
+ if (status === 'Complete') {
48
+ derivedStatus = formatMessage({
49
+ id: 'Quotes.deliveredText',
50
+ defaultMessage: 'Delivered'
51
+ });
52
+ } else if (hasShipment) {
53
+ derivedStatus = formatMessage({
54
+ id: 'Quotes.shippedText',
55
+ defaultMessage: 'Shipped'
56
+ });
57
+ } else if (hasInvoice) {
58
+ derivedStatus = formatMessage({
59
+ id: 'Quotes.readyToShipText',
60
+ defaultMessage: 'Ready to ship'
61
+ });
62
+ } else {
63
+ derivedStatus = formatMessage({
64
+ id: 'Quotes.new',
65
+ defaultMessage: 'New'
66
+ });
67
+ }
68
+
69
+ const talonProps = useOrderRow({ items });
70
+ const { loading, isOpen, imagesData } = talonProps;
71
+
72
+ const classes = useStyle(defaultClasses, props.classes);
73
+
74
+ const contentClass = isOpen ? classes.content : classes.content_collapsed;
75
+
76
+ const contentToggleIconSrc = isOpen ? ChevronUp : ChevronDown;
77
+
78
+ const contentToggleIcon = <Icon src={contentToggleIconSrc} size={24} />;
79
+
80
+ const collapsedImageGalleryElement = isOpen ? null : (
81
+ <CollapsedImageGallery items={imagesData} />
82
+ );
83
+
84
+ const orderDetails = loading ? null : (
85
+ <OrderDetails orderData={order} imagesData={imagesData} />
86
+ );
87
+
88
+ const orderTotalPrice =
89
+ currency && orderTotal !== null ? (
90
+ <Price currencyCode={currency} value={orderTotal} />
91
+ ) : (
92
+ '-'
93
+ );
94
+
95
+ const badgeStatusStyle = () => {
96
+ return 'bg-[#F1EFF6] text-blue-700 text-[14px] font-semibold rounded-full px-[30px] py-[5px] border-none';
97
+ }
98
+
99
+ const thumbnailProps = {
100
+ alt: items[0].product_name,
101
+ classes: { root: classes.thumbnail },
102
+ width: 50
103
+ };
104
+
105
+ return (
106
+ <li className={classes.root}>
107
+ <div className='flex flex-col md_flex-row justify-between mb-2.5'>
108
+ <div className='flex flex-col'>
109
+ <div className="flex gap-x-[15px] flex-row">
110
+ <span className="text-[14px] text-colorDefault">{formattedDate}</span>
111
+ <span className="text-gray-200 text-[14px]">{orderNumber}</span>
112
+ </div>
113
+ </div>
114
+ <div className='flex flex-col'>
115
+ <div className='flex w-full justify-start mt-2.5 md_mt-0 md_justify-end'>
116
+ <span className={cn(classes.orderStatusBadge, badgeStatusStyle())}>
117
+ {derivedStatus}
118
+ </span>
119
+ </div>
120
+ </div>
121
+ </div>
122
+ <div className='flex flex-col md_flex-row justify-between mb-2.5'>
123
+ <div className='flex flex-col'>
124
+ <div className='flex gap-x-[5px] mb-2.5'>
125
+ <Verify size={17} className='text-blue-700' variant="Bold" />
126
+ <span className='text-xs font-medium text-[rgba(25, 34, 42, 0.7)]'>
127
+ Gundam Info
128
+ </span>
129
+ </div>
130
+ <div className='flex flex-row'>
131
+ <div>
132
+ <PlaceholderImage {...thumbnailProps} />
133
+ </div>
134
+ <div className='flex flex-col max-w-[260px] gap-2.5'>
135
+ <div className={cn(classes.productName, 'text-[14] font-medium')}>
136
+ <span>
137
+ {items[0]?.product_name}
138
+ </span>
139
+ </div>
140
+ <div className="text-[14] text-gray-200">
141
+ <span>
142
+ {`${items[0]?.quantity_ordered}X`}
143
+ </span>
144
+ {' '}
145
+ <span>
146
+ <Price currencyCode={items[0]?.product_sale_price?.currency} value={items[0]?.product_sale_price?.value} />
147
+ </span>
148
+ </div>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ <div className='flex flex-col'>
153
+ <div className="md_px-10 py-3 md_border-l border-gray-100">
154
+ <span className="text-[14] text-gray-200 text-left md_text-center block mb-2">
155
+ <FormattedMessage
156
+ id={'orderRow.orderTotalText'}
157
+ defaultMessage={'Order Total'}
158
+ />
159
+ </span>
160
+ <div className="text-lg font-semibold text-left md_text-center block">{orderTotalPrice}</div>
161
+ </div>
162
+ </div>
163
+ </div>
164
+ <div className='flex flex-row justify-end py-[5px]'>
165
+ <Link to="/quotes/DEV123123123">
166
+ <span className="text-[13px] font-medium text-blue-700 underline">
167
+ <FormattedMessage
168
+ id={'orderRow.ViewTransactionDetail'}
169
+ defaultMessage={'View Transaction Detail'}
170
+ />
171
+ </span>
172
+ </Link>
173
+ </div>
174
+
175
+ {/* <div className={classes.orderDateContainer}>
176
+ <span className={classes.orderDateLabel}>
177
+ <FormattedMessage
178
+ id={'orderRow.orderDateText'}
179
+ defaultMessage={'Order Date'}
180
+ />
181
+ </span>
182
+ <span className={classes.orderDate}>{formattedDate}</span>
183
+ </div> */}
184
+ {/* <div className={classes.orderItemsContainer}>
185
+ {collapsedImageGalleryElement}
186
+ </div> */}
187
+ {/* <div className={classes.orderStatusContainer}>
188
+ <span className={classes.orderStatusBadge}>
189
+ {derivedStatus}
190
+ </span>
191
+ <OrderProgressBar status={derivedStatus} />
192
+ </div> */}
193
+ <div className={cn(contentClass, '!py-4 mt-4')}>{orderDetails}</div>
194
+ </li>
195
+ );
196
+ };
197
+
198
+ export default OrderRow;
199
+
200
+ OrderRow.propTypes = {
201
+ classes: shape({
202
+ root: string,
203
+ cell: string,
204
+ stackedCell: string,
205
+ label: string,
206
+ value: string,
207
+ orderNumberContainer: string,
208
+ orderDateContainer: string,
209
+ orderTotalContainer: string,
210
+ orderStatusContainer: string,
211
+ orderItemsContainer: string,
212
+ contentToggleContainer: string,
213
+ orderNumberLabel: string,
214
+ orderDateLabel: string,
215
+ orderTotalLabel: string,
216
+ orderNumber: string,
217
+ orderDate: string,
218
+ orderTotal: string,
219
+ orderStatusBadge: string,
220
+ content: string,
221
+ content_collapsed: string
222
+ }),
223
+ order: shape({
224
+ billing_address: shape({
225
+ city: string,
226
+ country_code: string,
227
+ firstname: string,
228
+ lastname: string,
229
+ postcode: string,
230
+ region_id: string,
231
+ street: arrayOf(string)
232
+ }),
233
+ items: arrayOf(
234
+ shape({
235
+ id: string,
236
+ product_name: string,
237
+ product_sale_price: shape({
238
+ currency: string,
239
+ value: number
240
+ }),
241
+ product_sku: string,
242
+ selected_options: arrayOf(
243
+ shape({
244
+ label: string,
245
+ value: string
246
+ })
247
+ ),
248
+ quantity_ordered: number
249
+ })
250
+ ),
251
+ invoices: arrayOf(
252
+ shape({
253
+ id: string
254
+ })
255
+ ),
256
+ number: string,
257
+ order_date: string,
258
+ payment_methods: arrayOf(
259
+ shape({
260
+ type: string,
261
+ additional_data: arrayOf(
262
+ shape({
263
+ name: string,
264
+ value: string
265
+ })
266
+ )
267
+ })
268
+ ),
269
+ shipping_address: shape({
270
+ city: string,
271
+ country_code: string,
272
+ firstname: string,
273
+ lastname: string,
274
+ postcode: string,
275
+ region_id: string,
276
+ street: arrayOf(string),
277
+ telephone: string
278
+ }),
279
+ shipping_method: string,
280
+ shipments: arrayOf(
281
+ shape({
282
+ id: string,
283
+ tracking: arrayOf(
284
+ shape({
285
+ number: string
286
+ })
287
+ )
288
+ })
289
+ ),
290
+ status: string,
291
+ total: shape({
292
+ discounts: arrayOf(
293
+ shape({
294
+ amount: shape({
295
+ currency: string,
296
+ value: number
297
+ })
298
+ })
299
+ ),
300
+ grand_total: shape({
301
+ currency: string,
302
+ value: number
303
+ }),
304
+ subtotal: shape({
305
+ currency: string,
306
+ value: number
307
+ }),
308
+ total_tax: shape({
309
+ currency: string,
310
+ value: number
311
+ }),
312
+ total_shipping: shape({
313
+ currency: string,
314
+ value: number
315
+ })
316
+ })
317
+ })
318
+ };