@riosst100/pwa-marketplace 3.2.4 → 3.2.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/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 +13 -10
- package/src/components/BecomeSellerPage/becomeSellerPage.js +29 -10
- package/src/components/BecomeSellerPage/becomeSellerPage.module.css +21 -0
- 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/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 +21 -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/SocialLogin/socialLogin.gql.js +106 -0
- package/src/talons/SocialLogin/useSocialLogin.js +169 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
3
|
import modalClasses from '@riosst100/pwa-marketplace/src/components/AgeVerification/ageVerificationModal.module.css';
|
|
4
|
-
import { AgeVerificationModalShimmer } from '@riosst100/pwa-marketplace/src/components/SellerCoupon';
|
|
4
|
+
// import { AgeVerificationModalShimmer } from '@riosst100/pwa-marketplace/src/components/SellerCoupon';
|
|
5
5
|
|
|
6
6
|
// Reuse day diff logic
|
|
7
7
|
const dayDiff = (toDate) => {
|
|
@@ -92,7 +92,7 @@ const AgeVerificationModal = ({
|
|
|
92
92
|
<button type="button" className={modalClasses.closeBtn} onClick={handleClose} aria-label="Close coupon modal">×</button>
|
|
93
93
|
</div>
|
|
94
94
|
<div className={modalClasses.body}>
|
|
95
|
-
{couponLoading && <AgeVerificationModalShimmer />}
|
|
95
|
+
{/* {couponLoading && <AgeVerificationModalShimmer />} */}
|
|
96
96
|
{!couponLoading && couponError && <p className={modalClasses.metaText}>Failed to load coupons.</p>}
|
|
97
97
|
{!couponLoading && !couponError && !items.length && <p className={modalClasses.metaText}>No coupons available.</p>}
|
|
98
98
|
{!couponLoading && !couponError && items.length > 0 && (
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default } from './ageVerificationModal';
|
|
2
|
-
export { default as AgeVerificationModalShimmer } from './ageVerificationModal.shimmer';
|
|
2
|
+
// export { default as AgeVerificationModalShimmer } from './ageVerificationModal.shimmer';
|
|
@@ -25,6 +25,9 @@ import Postcode from '@magento/venia-ui/lib/components/Postcode';
|
|
|
25
25
|
import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
|
|
26
26
|
import { Link } from 'react-router-dom';
|
|
27
27
|
import cn from 'classnames';
|
|
28
|
+
import { BrowserPersistence } from '@magento/peregrine/lib/util';
|
|
29
|
+
|
|
30
|
+
const storage = new BrowserPersistence();
|
|
28
31
|
|
|
29
32
|
const BecomeSeller = props => {
|
|
30
33
|
const talonProps = useBecomeSeller({
|
|
@@ -47,6 +50,9 @@ const BecomeSeller = props => {
|
|
|
47
50
|
const { formatMessage } = useIntl();
|
|
48
51
|
const classes = useStyle(defaultClasses, props.classes);
|
|
49
52
|
|
|
53
|
+
const websiteCountry = storage.getItem('website_code') && storage.getItem('website_code') != "base" ? '/' + storage.getItem('website_code') : '';
|
|
54
|
+
const sellerDashboardUrl = process.env.MAGENTO_BACKEND_URL ? process.env.MAGENTO_BACKEND_URL + websiteCountry : '';
|
|
55
|
+
|
|
50
56
|
const submitButton = (
|
|
51
57
|
<Button
|
|
52
58
|
className={cn(classes.submitButton, 'w-full')}
|
|
@@ -89,12 +95,12 @@ const BecomeSeller = props => {
|
|
|
89
95
|
onSubmit={handleSubmit}
|
|
90
96
|
onChange={handleChange}
|
|
91
97
|
>
|
|
92
|
-
<h2 data-cy="BecomeSeller-title" className="capitalize text-lg font-medium mb-[70px]">
|
|
98
|
+
{/* <h2 data-cy="BecomeSeller-title" className="capitalize text-lg font-medium mb-[70px]">
|
|
93
99
|
<FormattedMessage
|
|
94
100
|
id={'becomeSeller.becomeSellerText'}
|
|
95
101
|
defaultMessage={'Register as Seller'}
|
|
96
102
|
/>
|
|
97
|
-
</h2>
|
|
103
|
+
</h2> */}
|
|
98
104
|
<FormError errors={Array.from(errors.values())} />
|
|
99
105
|
<h3 className='text-[16px] leading-5 font-medium text-left mb-[30px]'>
|
|
100
106
|
<FormattedMessage
|
|
@@ -416,22 +422,19 @@ const BecomeSeller = props => {
|
|
|
416
422
|
{submitButton}
|
|
417
423
|
</div>
|
|
418
424
|
<div className='block'>
|
|
419
|
-
<span className='text-
|
|
425
|
+
<span className='text-sm font-normal'>
|
|
420
426
|
<FormattedMessage
|
|
421
427
|
id={'createAccount.alreadyHaveAccount'}
|
|
422
|
-
defaultMessage={"Already have an account
|
|
428
|
+
defaultMessage={"Already have an seller account?"}
|
|
423
429
|
/>
|
|
424
430
|
</span>
|
|
425
431
|
{' '}
|
|
426
|
-
<
|
|
427
|
-
to={'/sign-in'}
|
|
428
|
-
className='text-xs font-normal text-blue-700 underline'
|
|
429
|
-
>
|
|
432
|
+
<a href={sellerDashboardUrl + "/lofmarketplace/seller/login"} className='text-sm font-normal text-blue-700 underline'>
|
|
430
433
|
<FormattedMessage
|
|
431
434
|
id={'createAccount.SignInAsSeller'}
|
|
432
|
-
defaultMessage={"Sign
|
|
435
|
+
defaultMessage={"Sign In to Seller Dashboard"}
|
|
433
436
|
/>
|
|
434
|
-
</
|
|
437
|
+
</a>
|
|
435
438
|
</div>
|
|
436
439
|
</Form>
|
|
437
440
|
) : '';
|
|
@@ -7,7 +7,7 @@ import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
|
7
7
|
import BecomeSeller from '@riosst100/pwa-marketplace/src/components/BecomeSeller';
|
|
8
8
|
import { StoreTitle } from '@magento/venia-ui/lib/components/Head';
|
|
9
9
|
import defaultClasses from './becomeSellerPage.module.css';
|
|
10
|
-
|
|
10
|
+
import cn from 'classnames';
|
|
11
11
|
|
|
12
12
|
const BecomeSellerPage = props => {
|
|
13
13
|
const classes = useStyle(defaultClasses, props.classes);
|
|
@@ -17,15 +17,34 @@ const BecomeSellerPage = props => {
|
|
|
17
17
|
const { isSeller } = becomeSellerProps
|
|
18
18
|
|
|
19
19
|
return !isSeller ? (
|
|
20
|
-
<div className={classes.
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
<
|
|
20
|
+
<div className={classes.rootContainer}>
|
|
21
|
+
<div className={cn(classes.leftContent, '!py-[60px]')}>
|
|
22
|
+
<StoreTitle>
|
|
23
|
+
{formatMessage({
|
|
24
|
+
id: 'signInPage.title',
|
|
25
|
+
defaultMessage: 'Sign In'
|
|
26
|
+
})}
|
|
27
|
+
</StoreTitle>
|
|
28
|
+
<div className={cn(classes.leftContentContainer, '')}>
|
|
29
|
+
<div class="auth-left">
|
|
30
|
+
<img src="https://img.freepik.com/premium-vector/verified-seller-illustration-concept-white-background_701961-240.jpg" width="100%" />
|
|
31
|
+
<p style={{
|
|
32
|
+
"fontSize": "20px",
|
|
33
|
+
"fontWeight": 500
|
|
34
|
+
}}>Create a seller account and start selling your collectibles today.</p>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div className={classes.root}>
|
|
39
|
+
<StoreTitle>
|
|
40
|
+
{formatMessage({
|
|
41
|
+
id: 'becomeSellerPage.title',
|
|
42
|
+
defaultMessage: 'Become a Seller'
|
|
43
|
+
})}
|
|
44
|
+
</StoreTitle>
|
|
45
|
+
<div className="lg_border-2 lg_border-solid lg_border-subtle lg_rounded-md !border !border-gray-100 !rounded-lg">
|
|
46
|
+
<BecomeSeller {...becomeSellerProps} />
|
|
47
|
+
</div>
|
|
29
48
|
</div>
|
|
30
49
|
</div>
|
|
31
50
|
) : ''
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
.root {
|
|
2
|
+
composes: gap-y-md from global;
|
|
3
|
+
composes: grid from global;
|
|
4
|
+
/* composes: justify-center from global; */
|
|
5
|
+
composes: px-0 from global;
|
|
6
|
+
composes: py-md from global;
|
|
7
|
+
composes: text-center from global;
|
|
8
|
+
grid-template-columns: minmax(auto, 80%);
|
|
9
|
+
justify-content: right;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.leftContent {
|
|
2
13
|
composes: gap-y-md from global;
|
|
3
14
|
composes: grid from global;
|
|
4
15
|
composes: justify-center from global;
|
|
@@ -10,4 +21,14 @@
|
|
|
10
21
|
|
|
11
22
|
.header {
|
|
12
23
|
composes: font-serif from global;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.leftContentContainer {
|
|
27
|
+
text-align: left;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.rootContainer {
|
|
31
|
+
justify-content: space-around;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: normal;
|
|
13
34
|
}
|
|
@@ -4,13 +4,14 @@ import { useIntl } from 'react-intl';
|
|
|
4
4
|
import ModalRFQ from './modalRfq';
|
|
5
5
|
import cn from 'classnames';
|
|
6
6
|
|
|
7
|
-
const RFQ = ({ disabled, classes: customClasses = {} }) => {
|
|
7
|
+
const RFQ = ({ productId, disabled, classes: customClasses = {} }) => {
|
|
8
|
+
|
|
8
9
|
const [open, setOpen] = useState(false);
|
|
9
10
|
const { formatMessage } = useIntl();
|
|
10
11
|
|
|
11
12
|
return (
|
|
12
13
|
<>
|
|
13
|
-
<ModalRFQ open={open} setOpen={setOpen} />
|
|
14
|
+
<ModalRFQ open={open} setOpen={setOpen} productId={productId} />
|
|
14
15
|
|
|
15
16
|
<Button
|
|
16
17
|
data-cy="ProductFullDetail-RFQ"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
2
|
import Button from '@magento/venia-ui/lib/components/Button';
|
|
3
3
|
import Modal from '@riosst100/pwa-marketplace/src/components/Modal';
|
|
4
4
|
import { X } from 'react-feather';
|
|
@@ -13,35 +13,108 @@ import { useIntl } from 'react-intl';
|
|
|
13
13
|
import { useDropzone } from "react-dropzone";
|
|
14
14
|
import { DocumentUpload } from 'iconsax-react';
|
|
15
15
|
import cn from 'classnames';
|
|
16
|
+
import { useToasts } from '@magento/peregrine/lib/Toasts/useToasts';
|
|
17
|
+
import { useRFQ } from '@riosst100/pwa-marketplace/src/talons/RFQ/useRFQ';
|
|
16
18
|
|
|
17
19
|
import "react-datepicker/dist/react-datepicker.css";
|
|
18
20
|
|
|
19
21
|
const RFQModalForm = (props) => {
|
|
20
22
|
|
|
21
|
-
const { open = false, setOpen = () => { } } = props;
|
|
23
|
+
const { productId, open = false, setOpen = () => { } } = props;
|
|
24
|
+
|
|
22
25
|
const { formatMessage } = useIntl();
|
|
26
|
+
const [, { addToast }] = useToasts();
|
|
27
|
+
const { handleCreateQuickRfq, createState } = useRFQ();
|
|
23
28
|
|
|
24
29
|
const [startDate, setStartDate] = useState(new Date());
|
|
25
30
|
|
|
26
|
-
// Upload
|
|
31
|
+
// Upload File with remove capability
|
|
32
|
+
const [uploadedFiles, setUploadedFiles] = useState([]);
|
|
33
|
+
const onDrop = useCallback((accepted) => {
|
|
34
|
+
setUploadedFiles(prev => [...prev, ...accepted]);
|
|
35
|
+
}, []);
|
|
36
|
+
|
|
27
37
|
const {
|
|
28
|
-
acceptedFiles,
|
|
29
38
|
getRootProps,
|
|
30
39
|
getInputProps,
|
|
31
40
|
isDragActive
|
|
32
|
-
} = useDropzone();
|
|
41
|
+
} = useDropzone({ onDrop });
|
|
33
42
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
const handleRemoveFile = useCallback((index) => {
|
|
44
|
+
setUploadedFiles(prev => prev.filter((_, i) => i !== index));
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
const files = uploadedFiles.map((file, idx) => (
|
|
48
|
+
<div key={(file.path || file.name) + idx} className='flex items-center justify-between gap-2 mb-1'>
|
|
49
|
+
<span className='block font-medium'>
|
|
50
|
+
{(file.path || file.name)} - {Math.round(file.size / 1000)} kB
|
|
51
|
+
</span>
|
|
52
|
+
<button
|
|
53
|
+
type='button'
|
|
54
|
+
className='text-red-600 text-sm underline'
|
|
55
|
+
onClick={() => handleRemoveFile(idx)}
|
|
56
|
+
>
|
|
57
|
+
Remove
|
|
58
|
+
</button>
|
|
37
59
|
</div>
|
|
38
60
|
));
|
|
39
61
|
|
|
62
|
+
const handleSubmit = useCallback(async values => {
|
|
63
|
+
console.log('[RFQ] submit values', values);
|
|
64
|
+
const input = {
|
|
65
|
+
product_id: productId,
|
|
66
|
+
quantity: values.quote_qty ? Number(values.quote_qty) : undefined,
|
|
67
|
+
comment: values.quote_comment,
|
|
68
|
+
customer_phone: values.phone_number,
|
|
69
|
+
price_per_product: values.quote_price_per_unit
|
|
70
|
+
? Number(values.quote_price_per_unit)
|
|
71
|
+
: undefined,
|
|
72
|
+
date_need_quote: startDate ? startDate.toISOString() : undefined,
|
|
73
|
+
files: uploadedFiles.length
|
|
74
|
+
? uploadedFiles.map(file => ({
|
|
75
|
+
file_name: (file && (file.name || file.path)) || '',
|
|
76
|
+
// Browsers do not expose real file system paths; use name as a stable placeholder
|
|
77
|
+
file_path: (file && (file.path || file.name)) || '',
|
|
78
|
+
// Ensure a valid MIME string; default if missing
|
|
79
|
+
file_type: (file && file.type) ? file.type : 'application/octet-stream'
|
|
80
|
+
}))
|
|
81
|
+
: undefined
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
console.log('[RFQ] input payload', input);
|
|
85
|
+
|
|
86
|
+
Object.keys(input).forEach(key => input[key] === undefined && delete input[key]);
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const result = await handleCreateQuickRfq(input);
|
|
90
|
+
console.log('[RFQ] mutation result', result);
|
|
91
|
+
addToast({
|
|
92
|
+
type: 'success',
|
|
93
|
+
message: formatMessage({
|
|
94
|
+
id: 'productFullDetail.rfqSuccess',
|
|
95
|
+
defaultMessage: 'Quote request sent successfully.'
|
|
96
|
+
}),
|
|
97
|
+
timeout: 3000
|
|
98
|
+
});
|
|
99
|
+
setOpen(false);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error('[RFQ] createQuickRfq failed', error);
|
|
102
|
+
addToast({
|
|
103
|
+
type: 'error',
|
|
104
|
+
message: formatMessage({
|
|
105
|
+
id: 'productFullDetail.rfqFailed',
|
|
106
|
+
defaultMessage: 'Unable to send quote request. Please try again.'
|
|
107
|
+
}),
|
|
108
|
+
timeout: 4000
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}, [uploadedFiles, addToast, formatMessage, handleCreateQuickRfq, setOpen, startDate]);
|
|
112
|
+
|
|
40
113
|
return (
|
|
41
114
|
<>
|
|
42
115
|
<Modal
|
|
43
116
|
open={open}
|
|
44
|
-
className='!p-[
|
|
117
|
+
className='!p-[20px] md_min-w-[550px] modal_bid'
|
|
45
118
|
>
|
|
46
119
|
<div className='modal_bid-content'>
|
|
47
120
|
<div className='header_title-modal flex justify-between mb-4'>
|
|
@@ -59,59 +132,71 @@ const RFQModalForm = (props) => {
|
|
|
59
132
|
</button>
|
|
60
133
|
</div>
|
|
61
134
|
|
|
62
|
-
<div className='flex flex-col gap-y-[
|
|
135
|
+
<div className='flex flex-col gap-y-[8px]'>
|
|
63
136
|
<Form
|
|
64
137
|
data-cy="form_bid"
|
|
65
|
-
className="flex flex-col gap-y-
|
|
138
|
+
className="flex flex-col gap-y-2"
|
|
66
139
|
initialValues={{}}
|
|
67
|
-
onSubmit={
|
|
68
|
-
onChange={
|
|
140
|
+
onSubmit={handleSubmit}
|
|
141
|
+
onChange={values => {
|
|
142
|
+
console.log('[RFQ] form change', values);
|
|
143
|
+
}}
|
|
144
|
+
onSubmitFailure={(errors, values) => {
|
|
145
|
+
console.warn('[RFQ] form submit failed', { errors, values });
|
|
146
|
+
}}
|
|
69
147
|
>
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
148
|
+
{({ formApi }) => (
|
|
149
|
+
<>
|
|
150
|
+
<div className="flex flex-col md_flex-row gap-2">
|
|
151
|
+
<div className="md_flex-1">
|
|
152
|
+
<Field
|
|
153
|
+
id="quote_price_per_unit_field"
|
|
154
|
+
label={
|
|
155
|
+
formatMessage({
|
|
156
|
+
id: 'productFullDetail.QuotePricePerUnit',
|
|
157
|
+
defaultMessage:
|
|
158
|
+
'Quote Price Per Unit'
|
|
159
|
+
})
|
|
160
|
+
}
|
|
161
|
+
>
|
|
162
|
+
<TextInput
|
|
163
|
+
id="quote_price_per_unit"
|
|
164
|
+
field="quote_price_per_unit"
|
|
165
|
+
validate={isRequired}
|
|
166
|
+
validateOnBlur
|
|
167
|
+
mask={value => value && value.trim()}
|
|
168
|
+
maskOnBlur={true}
|
|
169
|
+
data-cy="quote_price_per_unit"
|
|
170
|
+
aria-label={'quote_price_per_unit'}
|
|
171
|
+
placeholder={'10.00'}
|
|
172
|
+
/>
|
|
173
|
+
</Field>
|
|
174
|
+
</div>
|
|
175
|
+
<div className="md_flex-1">
|
|
176
|
+
<Field
|
|
177
|
+
id="quote_qty_field"
|
|
178
|
+
label={
|
|
179
|
+
formatMessage({
|
|
180
|
+
id: 'productFullDetail.QuoteQuantity',
|
|
181
|
+
defaultMessage:
|
|
182
|
+
'Quote Quantity'
|
|
183
|
+
})
|
|
184
|
+
}
|
|
185
|
+
>
|
|
186
|
+
<TextInput
|
|
187
|
+
id="quote_qty"
|
|
188
|
+
field="quote_qty"
|
|
189
|
+
validate={isRequired}
|
|
190
|
+
validateOnBlur
|
|
191
|
+
mask={value => value && value.trim()}
|
|
192
|
+
maskOnBlur={true}
|
|
193
|
+
data-cy="quote_qty"
|
|
194
|
+
aria-label={'quote_qty'}
|
|
195
|
+
placeholder={'10'}
|
|
196
|
+
/>
|
|
197
|
+
</Field>
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
115
200
|
|
|
116
201
|
<Field
|
|
117
202
|
id="date_need_quote_field"
|
|
@@ -149,7 +234,7 @@ const RFQModalForm = (props) => {
|
|
|
149
234
|
maskOnBlur={true}
|
|
150
235
|
data-cy="phone_number"
|
|
151
236
|
aria-label={'phone_number'}
|
|
152
|
-
placeholder={'
|
|
237
|
+
placeholder={'(123) 456-7890'}
|
|
153
238
|
/>
|
|
154
239
|
</Field>
|
|
155
240
|
|
|
@@ -178,7 +263,7 @@ const RFQModalForm = (props) => {
|
|
|
178
263
|
<section className="wfp--dropzone">
|
|
179
264
|
<div
|
|
180
265
|
{...getRootProps({ isDragActive })}
|
|
181
|
-
className='border border-blue-600 rounded-md border-dashed flex flex-col justify-center items-center py-
|
|
266
|
+
className='border border-blue-600 rounded-md border-dashed flex flex-col justify-center items-center py-3'
|
|
182
267
|
>
|
|
183
268
|
<input {...getInputProps()} />
|
|
184
269
|
<DocumentUpload
|
|
@@ -187,7 +272,7 @@ const RFQModalForm = (props) => {
|
|
|
187
272
|
/>
|
|
188
273
|
<div className='mt-2 text-blue-600'>Drop files or click here to upload</div>
|
|
189
274
|
</div>
|
|
190
|
-
{files && (
|
|
275
|
+
{files && files.length > 0 && (
|
|
191
276
|
<div className="wfp--dropzone__file-list mt-4">
|
|
192
277
|
<ul>{files}</ul>
|
|
193
278
|
</div>
|
|
@@ -201,7 +286,11 @@ const RFQModalForm = (props) => {
|
|
|
201
286
|
classes={{
|
|
202
287
|
content: 'capitalize text-[16px] font-medium'
|
|
203
288
|
}}
|
|
204
|
-
|
|
289
|
+
type="button"
|
|
290
|
+
onClick={() => {
|
|
291
|
+
console.log('[RFQ] Cancel clicked, closing modal');
|
|
292
|
+
setOpen(false);
|
|
293
|
+
}}
|
|
205
294
|
>
|
|
206
295
|
{
|
|
207
296
|
formatMessage({
|
|
@@ -216,22 +305,47 @@ const RFQModalForm = (props) => {
|
|
|
216
305
|
classes={{
|
|
217
306
|
content: 'capitalize text-[16px] font-medium'
|
|
218
307
|
}}
|
|
308
|
+
type="button"
|
|
309
|
+
onPress={() => {
|
|
310
|
+
console.log('[RFQ] Submit pressed, calling formApi.submitForm()');
|
|
311
|
+
formApi.submitForm();
|
|
312
|
+
}}
|
|
313
|
+
disabled={createState?.loading}
|
|
314
|
+
data-cy="rfq-submit"
|
|
219
315
|
>
|
|
220
|
-
{
|
|
221
|
-
formatMessage({
|
|
222
|
-
id: 'productFullDetail.
|
|
223
|
-
defaultMessage:
|
|
224
|
-
'Send Request'
|
|
316
|
+
{createState?.loading
|
|
317
|
+
? formatMessage({
|
|
318
|
+
id: 'productFullDetail.SendingRequest',
|
|
319
|
+
defaultMessage: 'Sending...'
|
|
225
320
|
})
|
|
226
|
-
|
|
321
|
+
: formatMessage({
|
|
322
|
+
id: 'productFullDetail.SendRequest',
|
|
323
|
+
defaultMessage: 'Send Request'
|
|
324
|
+
})}
|
|
227
325
|
</Button>
|
|
228
326
|
</div>
|
|
327
|
+
</>
|
|
328
|
+
)}
|
|
229
329
|
</Form>
|
|
230
330
|
</div>
|
|
231
331
|
</div>
|
|
232
332
|
</Modal>
|
|
233
333
|
<style jsx="true">
|
|
234
334
|
{`
|
|
335
|
+
/* Modal container adjustments to prevent clipping */
|
|
336
|
+
.modal_bid-content {
|
|
337
|
+
max-height: 90vh;
|
|
338
|
+
overflow-y: auto;
|
|
339
|
+
}
|
|
340
|
+
@media (min-width: 768px) {
|
|
341
|
+
.md_min-w-[550px] {
|
|
342
|
+
min-width: 550px;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/* Ensure inner form sections don't overflow */
|
|
346
|
+
.wfp--dropzone {
|
|
347
|
+
max-width: 100%;
|
|
348
|
+
}
|
|
235
349
|
.react-datepicker__input-container>input:focus-visible,
|
|
236
350
|
.react-datepicker__input-container>input:focus,
|
|
237
351
|
.react-datepicker__input-container>input:active {
|
|
@@ -240,6 +354,10 @@ const RFQModalForm = (props) => {
|
|
|
240
354
|
.react-datepicker-popper[data-placement^=bottom] .react-datepicker__triangle::after {
|
|
241
355
|
left: 25px;
|
|
242
356
|
}
|
|
357
|
+
/* Keep datepicker within viewport */
|
|
358
|
+
.react-datepicker-popper {
|
|
359
|
+
z-index: 1000;
|
|
360
|
+
}
|
|
243
361
|
`}
|
|
244
362
|
</style>
|
|
245
363
|
</>
|