@riosst100/pwa-marketplace 2.8.8 → 2.8.9
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/PaymentMethod/PaypalExpress/paypalExpress.js +3 -2
- package/src/components/PaymentMethod/Xendit/xendit.js +53 -0
- package/src/components/ProductReviewItem/index.js +1 -0
- package/src/components/ProductReviewItem/productReviewItem.js +67 -0
- package/src/components/SellerReview/sellerReview.js +21 -25
- package/src/components/VerifyEmailPage/index.js +1 -0
- package/src/components/VerifyEmailPage/verifyEmail.js +79 -0
- package/src/components/VerifyEmailPage/verifyEmail.module.css +71 -0
- package/src/intercept.js +8 -0
- package/src/overwrites/peregrine/lib/talons/CheckoutPage/checkoutPage.extended.gql.js +88 -0
- package/src/overwrites/peregrine/lib/talons/CheckoutPage/useCheckoutPage.js +124 -13
- package/src/overwrites/peregrine/lib/talons/CheckoutPage/xendit.gql.js +15 -0
- package/src/overwrites/venia-ui/lib/components/Checkbox/checkbox.module.css +2 -0
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/BillingAddress/billingAddress.module.css +9 -1
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/ItemsReview/itemsReview.module.css +3 -2
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/OrderConfirmationPage/orderConfirmationPage.js +68 -44
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/OrderConfirmationPage/orderConfirmationPage.module.css +102 -5
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentInformation.module.css +6 -0
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethodCollection.js +6 -20
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.js +33 -2
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.module.css +13 -3
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/PaymentInformation/summary.module.css +3 -1
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/checkoutPage.module.css +14 -3
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/components/modalFormReview.js +2 -2
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/components/productReview.js +156 -38
- package/src/talons/PaymentMethod/PaypalExpress/usePaypalExpress.js +5 -1
|
@@ -13,10 +13,59 @@ import { setCheckoutState} from '@magento/peregrine/lib/store/actions/cart';
|
|
|
13
13
|
|
|
14
14
|
import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
15
15
|
|
|
16
|
-
import DEFAULT_OPERATIONS from '@
|
|
16
|
+
import DEFAULT_OPERATIONS from '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/CheckoutPage/checkoutPage.extended.gql.js';
|
|
17
17
|
|
|
18
18
|
import CheckoutError from '@magento/peregrine/lib/talons/CheckoutPage/CheckoutError';
|
|
19
19
|
import { useGoogleReCaptcha } from '@magento/peregrine/lib/hooks/useGoogleReCaptcha';
|
|
20
|
+
import { XENDIT_CREATE_INVOICE } from '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/CheckoutPage/xendit.gql';
|
|
21
|
+
|
|
22
|
+
// Lightweight UI helper: show a full-screen overlay when redirecting to Xendit
|
|
23
|
+
const XENDIT_OVERLAY_ID = 'xendit-redirect-overlay';
|
|
24
|
+
function showXenditRedirectOverlay() {
|
|
25
|
+
if (typeof document === 'undefined') return;
|
|
26
|
+
if (document.getElementById(XENDIT_OVERLAY_ID)) return;
|
|
27
|
+
|
|
28
|
+
const style = document.createElement('style');
|
|
29
|
+
style.type = 'text/css';
|
|
30
|
+
style.textContent = `@keyframes xendit-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }`;
|
|
31
|
+
document.head.appendChild(style);
|
|
32
|
+
|
|
33
|
+
const overlay = document.createElement('div');
|
|
34
|
+
overlay.id = XENDIT_OVERLAY_ID;
|
|
35
|
+
overlay.setAttribute('data-cy', 'xendit-redirect-overlay');
|
|
36
|
+
overlay.style.cssText = [
|
|
37
|
+
'position:fixed',
|
|
38
|
+
'inset:0',
|
|
39
|
+
'background:rgba(0,0,0,0.85)',
|
|
40
|
+
'color:#fff',
|
|
41
|
+
'display:flex',
|
|
42
|
+
'flex-direction:column',
|
|
43
|
+
'align-items:center',
|
|
44
|
+
'justify-content:center',
|
|
45
|
+
'z-index:2147483647',
|
|
46
|
+
'text-align:center',
|
|
47
|
+
'padding:24px'
|
|
48
|
+
].join(';');
|
|
49
|
+
|
|
50
|
+
const spinner = document.createElement('div');
|
|
51
|
+
spinner.style.cssText = [
|
|
52
|
+
'width:48px',
|
|
53
|
+
'height:48px',
|
|
54
|
+
'border:4px solid #ffffff',
|
|
55
|
+
'border-top-color:transparent',
|
|
56
|
+
'border-radius:50%',
|
|
57
|
+
'animation:xendit-spin 1s linear infinite',
|
|
58
|
+
'margin-bottom:16px'
|
|
59
|
+
].join(';');
|
|
60
|
+
|
|
61
|
+
const text = document.createElement('div');
|
|
62
|
+
text.textContent = 'Redirecting you to Xendit payment page…';
|
|
63
|
+
text.style.cssText = 'font-size:16px; opacity:0.33;';
|
|
64
|
+
|
|
65
|
+
overlay.appendChild(spinner);
|
|
66
|
+
overlay.appendChild(text);
|
|
67
|
+
document.body.appendChild(overlay);
|
|
68
|
+
}
|
|
20
69
|
|
|
21
70
|
export const CHECKOUT_STEP = {
|
|
22
71
|
SHIPPING_ADDRESS: 1,
|
|
@@ -115,6 +164,12 @@ export const useCheckoutPage = (props = {}) => {
|
|
|
115
164
|
}
|
|
116
165
|
] = useMutation(placeOrderMutation);
|
|
117
166
|
|
|
167
|
+
// Xendit: create invoice after successful placeOrder
|
|
168
|
+
const [
|
|
169
|
+
xenditCreateInvoice,
|
|
170
|
+
{ data: xenditInvoiceData, loading: xenditInvoiceLoading, error: xenditInvoiceError }
|
|
171
|
+
] = useMutation(XENDIT_CREATE_INVOICE);
|
|
172
|
+
|
|
118
173
|
const [
|
|
119
174
|
getOrderDetails,
|
|
120
175
|
{ data: orderDetailsData, loading: orderDetailsLoading }
|
|
@@ -237,6 +292,9 @@ export const useCheckoutPage = (props = {}) => {
|
|
|
237
292
|
}, [checkoutStep]);
|
|
238
293
|
|
|
239
294
|
const [isPlacingOrder, setIsPlacingOrder] = useState(false);
|
|
295
|
+
// When true, we intentionally hide the OrderConfirmationPage (orderNumber)
|
|
296
|
+
// to allow external payment (Xendit) to complete first.
|
|
297
|
+
const [suppressOrderConfirmation, setSuppressOrderConfirmation] = useState(false);
|
|
240
298
|
|
|
241
299
|
const handlePlaceOrder = useCallback(async () => {
|
|
242
300
|
// Fetch order details and then use an effect to actually place the
|
|
@@ -273,20 +331,68 @@ export const useCheckoutPage = (props = {}) => {
|
|
|
273
331
|
async function placeOrderAndCleanup() {
|
|
274
332
|
try {
|
|
275
333
|
const reCaptchaData = await generateReCaptchaData();
|
|
276
|
-
|
|
277
|
-
await placeOrder({
|
|
334
|
+
// Execute placeOrder and get the order number directly from the response
|
|
335
|
+
const placeOrderResult = await placeOrder({
|
|
278
336
|
variables: {
|
|
279
337
|
cartId
|
|
280
338
|
},
|
|
281
339
|
...reCaptchaData
|
|
282
340
|
});
|
|
283
|
-
// Cleanup stale cart and customer info.
|
|
284
|
-
await removeCart();
|
|
285
|
-
await apolloClient.clearCacheData(apolloClient, 'cart');
|
|
286
341
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
342
|
+
const orderNumber =
|
|
343
|
+
placeOrderResult?.data?.placeOrder?.order?.order_number;
|
|
344
|
+
// If payment is Xendit, create invoice and redirect BEFORE cleaning up cart
|
|
345
|
+
const selectedPayment = orderDetailsData?.cart?.selected_payment_method;
|
|
346
|
+
const paymentCode = selectedPayment?.code;
|
|
347
|
+
const paymentTitle = selectedPayment?.title;
|
|
348
|
+
const isXendit =
|
|
349
|
+
(paymentCode && paymentCode.toLowerCase() === 'xendit') ||
|
|
350
|
+
(paymentTitle && paymentTitle.toLowerCase().includes('xendit'));
|
|
351
|
+
if (isXendit && orderNumber) {
|
|
352
|
+
try {
|
|
353
|
+
// Prevent success page from rendering; we'll redirect to Xendit first
|
|
354
|
+
setSuppressOrderConfirmation(true);
|
|
355
|
+
const res = await xenditCreateInvoice({
|
|
356
|
+
variables: { orderId: orderNumber }
|
|
357
|
+
});
|
|
358
|
+
const payload = res?.data?.xenditCreateInvoice;
|
|
359
|
+
const url = payload?.invoice_url;
|
|
360
|
+
if (url) {
|
|
361
|
+
// Show overlay to inform user before redirecting
|
|
362
|
+
showXenditRedirectOverlay();
|
|
363
|
+
// Perform cart cleanup before redirecting away
|
|
364
|
+
try {
|
|
365
|
+
await removeCart();
|
|
366
|
+
await apolloClient.clearCacheData(apolloClient, 'cart');
|
|
367
|
+
await createCart({ fetchCartId });
|
|
368
|
+
} catch (cleanupErr) {
|
|
369
|
+
// eslint-disable-next-line no-console
|
|
370
|
+
console.warn('Cleanup before Xendit redirect failed', cleanupErr);
|
|
371
|
+
}
|
|
372
|
+
// Give the browser a brief moment to paint the overlay
|
|
373
|
+
setTimeout(() => {
|
|
374
|
+
// Redirect in the SAME TAB per requested flow
|
|
375
|
+
window.location.assign(url);
|
|
376
|
+
}, 2000);
|
|
377
|
+
} else {
|
|
378
|
+
// eslint-disable-next-line no-console
|
|
379
|
+
console.warn(
|
|
380
|
+
'Xendit: invoice_url missing in response'
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
} catch (err) {
|
|
384
|
+
// eslint-disable-next-line no-console
|
|
385
|
+
console.error(
|
|
386
|
+
'Xendit: failed to create invoice',
|
|
387
|
+
err
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
} else {
|
|
391
|
+
// Non-Xendit: proceed with normal cleanup
|
|
392
|
+
await removeCart();
|
|
393
|
+
await apolloClient.clearCacheData(apolloClient, 'cart');
|
|
394
|
+
await createCart({ fetchCartId });
|
|
395
|
+
}
|
|
290
396
|
} catch (err) {
|
|
291
397
|
console.error(
|
|
292
398
|
'An error occurred during when placing the order',
|
|
@@ -365,7 +471,11 @@ export const useCheckoutPage = (props = {}) => {
|
|
|
365
471
|
type: 'CHECKOUT_PLACE_ORDER_BUTTON_CLICKED',
|
|
366
472
|
payload: eventPayload
|
|
367
473
|
});
|
|
368
|
-
} else if (
|
|
474
|
+
} else if (
|
|
475
|
+
placeOrderData &&
|
|
476
|
+
orderDetailsData?.cart.id === cartId &&
|
|
477
|
+
!suppressOrderConfirmation
|
|
478
|
+
) {
|
|
369
479
|
dispatch({
|
|
370
480
|
type: 'ORDER_CONFIRMATION_PAGE_VIEW',
|
|
371
481
|
payload: {
|
|
@@ -386,6 +496,7 @@ export const useCheckoutPage = (props = {}) => {
|
|
|
386
496
|
dispatch,
|
|
387
497
|
placeOrderData,
|
|
388
498
|
isPlacingOrder,
|
|
499
|
+
suppressOrderConfirmation,
|
|
389
500
|
reviewOrderButtonClicked
|
|
390
501
|
]);
|
|
391
502
|
|
|
@@ -408,9 +519,9 @@ export const useCheckoutPage = (props = {}) => {
|
|
|
408
519
|
isUpdating,
|
|
409
520
|
orderDetailsData,
|
|
410
521
|
orderDetailsLoading,
|
|
411
|
-
orderNumber:
|
|
412
|
-
|
|
413
|
-
null,
|
|
522
|
+
orderNumber: suppressOrderConfirmation
|
|
523
|
+
? null
|
|
524
|
+
: (placeOrderData && placeOrderData.placeOrder.order.order_number) || null,
|
|
414
525
|
placeOrderLoading,
|
|
415
526
|
placeOrderButtonClicked,
|
|
416
527
|
setCheckoutStep,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { gql } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
export const XENDIT_CREATE_INVOICE = gql`
|
|
4
|
+
mutation xenditCreateInvoice($orderId: String!) {
|
|
5
|
+
xenditCreateInvoice(input: { order_id: $orderId }) {
|
|
6
|
+
invoice_url
|
|
7
|
+
mode
|
|
8
|
+
xendit_qrcode_external_id
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
XENDIT_CREATE_INVOICE
|
|
15
|
+
};
|
package/src/overwrites/venia-ui/lib/components/CheckoutPage/BillingAddress/billingAddress.module.css
CHANGED
|
@@ -23,7 +23,10 @@
|
|
|
23
23
|
|
|
24
24
|
composes: lg_col-end-span1 from global;
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
.cardTitle{
|
|
27
|
+
font-weight: 500;
|
|
28
|
+
font-size: 16px;
|
|
29
|
+
}
|
|
27
30
|
.country,
|
|
28
31
|
.street1,
|
|
29
32
|
.street2,
|
|
@@ -33,4 +36,9 @@
|
|
|
33
36
|
.postal_code,
|
|
34
37
|
.phone_number {
|
|
35
38
|
composes: col-end-span2 from global;
|
|
39
|
+
margin-left: 5px;
|
|
36
40
|
}
|
|
41
|
+
.address_check{
|
|
42
|
+
margin-top: 5px;
|
|
43
|
+
margin-left: 5px;
|
|
44
|
+
}
|
package/src/overwrites/venia-ui/lib/components/CheckoutPage/ItemsReview/itemsReview.module.css
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
.items_review_container {
|
|
2
|
-
composes: border-
|
|
2
|
+
composes: border-1 from global;
|
|
3
3
|
composes: border-solid from global;
|
|
4
|
-
composes: border-subtle from global;
|
|
4
|
+
/* composes: border-subtle from global; */
|
|
5
|
+
border: 1px solid #E6E9EA;
|
|
5
6
|
composes: rounded-md from global;
|
|
6
7
|
min-height: 2rem;
|
|
7
8
|
}
|
|
@@ -5,6 +5,7 @@ import { useOrderConfirmationPage } from '@magento/peregrine/lib/talons/Checkout
|
|
|
5
5
|
|
|
6
6
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
7
7
|
import { StoreTitle } from '@magento/venia-ui/lib/components/Head';
|
|
8
|
+
import { Link } from 'react-router-dom';
|
|
8
9
|
import CreateAccount from './createAccount';
|
|
9
10
|
import ItemsReview from '../ItemsReview';
|
|
10
11
|
import defaultClasses from './orderConfirmationPage.module.css';
|
|
@@ -63,6 +64,8 @@ const OrderConfirmationPage = props => {
|
|
|
63
64
|
const nameString = `${firstname} ${lastname}`;
|
|
64
65
|
const additionalAddressString = `${city}, ${region} ${postcode} ${country}`;
|
|
65
66
|
|
|
67
|
+
// copy button removed per request
|
|
68
|
+
|
|
66
69
|
return (
|
|
67
70
|
<div className={classes.root} data-cy="OrderConfirmationPage-root">
|
|
68
71
|
<StoreTitle>
|
|
@@ -72,52 +75,73 @@ const OrderConfirmationPage = props => {
|
|
|
72
75
|
})}
|
|
73
76
|
</StoreTitle>
|
|
74
77
|
<div className={classes.mainContainer}>
|
|
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
|
-
{additionalAddressString}
|
|
109
|
-
</span>
|
|
78
|
+
<div className={classes.successHeader}>
|
|
79
|
+
<div className={classes.iconCheck} aria-hidden="true">
|
|
80
|
+
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
81
|
+
<circle cx="12" cy="12" r="11" stroke="currentColor" strokeWidth="2" opacity="0.4" />
|
|
82
|
+
<path d="M7 12.5L10.2 16L17 8" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
83
|
+
</svg>
|
|
84
|
+
</div>
|
|
85
|
+
<h2
|
|
86
|
+
data-cy="OrderConfirmationPage-header"
|
|
87
|
+
className={classes.heading}
|
|
88
|
+
>
|
|
89
|
+
<FormattedMessage
|
|
90
|
+
id={'checkoutPage.thankYou'}
|
|
91
|
+
defaultMessage={'Thank you for your order!'}
|
|
92
|
+
/>
|
|
93
|
+
</h2>
|
|
94
|
+
<div
|
|
95
|
+
data-cy="OrderConfirmationPage-orderNumber"
|
|
96
|
+
className={classes.orderNumberRow}
|
|
97
|
+
>
|
|
98
|
+
<div className={classes.orderNumberText}>
|
|
99
|
+
<FormattedMessage
|
|
100
|
+
id={'checkoutPage.orderNumber'}
|
|
101
|
+
defaultMessage={'Order Number: {orderNumber}'}
|
|
102
|
+
values={{ orderNumber }}
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
<div className={classes.actions}>
|
|
107
|
+
<Link to="/" className={classes.primaryAction} data-cy="OrderConfirmationPage-continueShopping">
|
|
108
|
+
<FormattedMessage id={'checkoutPage.continueShopping'} defaultMessage={'Continue Shopping'} />
|
|
109
|
+
</Link>
|
|
110
|
+
</div>
|
|
110
111
|
</div>
|
|
111
|
-
<div
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
<div className={classes.detailsGrid}>
|
|
113
|
+
<div className={classes.card}>
|
|
114
|
+
<div
|
|
115
|
+
data-cy="OrderConfirmationPage-shippingInfoHeading"
|
|
116
|
+
className={classes.cardHeading}
|
|
117
|
+
>
|
|
118
|
+
<FormattedMessage
|
|
119
|
+
id={'global.shippingInformation'}
|
|
120
|
+
defaultMessage={'Shipping Information'}
|
|
121
|
+
/>
|
|
122
|
+
</div>
|
|
123
|
+
<div className={classes.shippingInfo}>
|
|
124
|
+
<span className={classes.email}>{email}</span>
|
|
125
|
+
<span className={classes.name}>{nameString}</span>
|
|
126
|
+
{streetRows}
|
|
127
|
+
<span className={classes.addressAdditional}>
|
|
128
|
+
{additionalAddressString}
|
|
129
|
+
</span>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
<div className={classes.card}>
|
|
133
|
+
<div
|
|
134
|
+
data-cy="OrderConfirmationPage-shippingMethodHeading"
|
|
135
|
+
className={classes.cardHeading}
|
|
136
|
+
>
|
|
137
|
+
<FormattedMessage
|
|
138
|
+
id={'global.shippingMethod'}
|
|
139
|
+
defaultMessage={'Shipping Method'}
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
<div className={classes.shippingMethod}>{shippingMethod}</div>
|
|
143
|
+
</div>
|
|
119
144
|
</div>
|
|
120
|
-
<div className={classes.shippingMethod}>{shippingMethod}</div>
|
|
121
145
|
<div className={classes.itemsReview}>
|
|
122
146
|
<ItemsReview data={data} />
|
|
123
147
|
</div>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* prettier-ignore */
|
|
2
1
|
.root {
|
|
3
2
|
composes: gap-xs from global;
|
|
4
3
|
composes: grid from global;
|
|
@@ -9,17 +8,17 @@
|
|
|
9
8
|
composes: px-sm from global;
|
|
10
9
|
composes: py-sm from global;
|
|
11
10
|
|
|
12
|
-
composes: lg_gap-md from global;
|
|
11
|
+
/* composes: lg_gap-md from global; */
|
|
13
12
|
/* TODO @TW: review (B7) */
|
|
14
|
-
composes: lg_grid-cols-[2fr,1fr] from global;
|
|
13
|
+
/* composes: lg_grid-cols-[2fr,1fr] from global;
|
|
15
14
|
composes: lg_px-lg from global;
|
|
16
|
-
composes: lg_py-md from global;
|
|
15
|
+
composes: lg_py-md from global; */
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
.mainContainer {
|
|
20
19
|
composes: col-start-1 from global;
|
|
21
20
|
composes: grid from global;
|
|
22
|
-
composes: gap-y-
|
|
21
|
+
composes: gap-y-sm from global;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
.sidebarContainer {
|
|
@@ -44,6 +43,72 @@
|
|
|
44
43
|
composes: header;
|
|
45
44
|
}
|
|
46
45
|
|
|
46
|
+
.successHeader {
|
|
47
|
+
composes: grid from global;
|
|
48
|
+
composes: gap-y-xs from global;
|
|
49
|
+
composes: rounded-md from global;
|
|
50
|
+
composes: border from global;
|
|
51
|
+
border-color: #E6E9EA;
|
|
52
|
+
composes: bg-surface from global;
|
|
53
|
+
composes: p-md from global;
|
|
54
|
+
composes: text-center from global;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.iconCheck {
|
|
58
|
+
composes: mx-auto from global;
|
|
59
|
+
composes: h-14 from global;
|
|
60
|
+
composes: w-14 from global;
|
|
61
|
+
color: #f76b1c;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.orderNumberRow {
|
|
65
|
+
composes: flex from global;
|
|
66
|
+
composes: items-center from global;
|
|
67
|
+
composes: justify-center from global;
|
|
68
|
+
composes: gap-x-xs from global;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.orderNumberText {
|
|
72
|
+
composes: header;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.copyBtn {
|
|
76
|
+
composes: text-sm from global;
|
|
77
|
+
composes: px-sm from global;
|
|
78
|
+
composes: py-2xs from global;
|
|
79
|
+
composes: rounded from global;
|
|
80
|
+
composes: border from global;
|
|
81
|
+
composes: border-subtle from global;
|
|
82
|
+
composes: hover_bg-subtle from global;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.actions {
|
|
86
|
+
composes: flex from global;
|
|
87
|
+
composes: gap-x-xs from global;
|
|
88
|
+
composes: justify-center from global;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.primaryAction {
|
|
92
|
+
composes: inline-flex from global;
|
|
93
|
+
composes: items-center from global;
|
|
94
|
+
composes: justify-center from global;
|
|
95
|
+
composes: px-lg from global;
|
|
96
|
+
composes: py-xs from global;
|
|
97
|
+
composes: rounded-full from global;
|
|
98
|
+
composes: font-semibold from global;
|
|
99
|
+
color: #fff;
|
|
100
|
+
background: #f76b1c;
|
|
101
|
+
border: 1px solid #f76b1c;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.primaryAction:hover {
|
|
105
|
+
color: #fff;
|
|
106
|
+
background: #f26313;
|
|
107
|
+
border: 1px solid #f26313;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.secondaryAction { display: none; }
|
|
111
|
+
|
|
47
112
|
.shippingInfoHeading {
|
|
48
113
|
composes: header;
|
|
49
114
|
}
|
|
@@ -68,3 +133,35 @@
|
|
|
68
133
|
.additionalText {
|
|
69
134
|
composes: text;
|
|
70
135
|
}
|
|
136
|
+
|
|
137
|
+
.detailsGrid {
|
|
138
|
+
composes: grid from global;
|
|
139
|
+
composes: gap-sm from global;
|
|
140
|
+
composes: md_grid-cols-2 from global;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.card {
|
|
144
|
+
composes: rounded-md from global;
|
|
145
|
+
composes: border from global;
|
|
146
|
+
border-color: #E6E9EA;
|
|
147
|
+
composes: bg-surface from global;
|
|
148
|
+
composes: p-md from global;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.cardHeading {
|
|
152
|
+
composes: header;
|
|
153
|
+
composes: mb-2xs from global;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.itemsReview {
|
|
157
|
+
composes: rounded-md from global;
|
|
158
|
+
composes: border from global;
|
|
159
|
+
border-color: #E6E9EA;
|
|
160
|
+
composes: bg-surface from global;
|
|
161
|
+
composes: p-md from global;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.heading {
|
|
165
|
+
composes: font-bold from global;
|
|
166
|
+
composes: text-2xl from global;
|
|
167
|
+
}
|
|
@@ -1,23 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* add new payment component mappings for the checkout page.
|
|
2
|
+
* Delegate to Venia's canonical payment method collection so build-target
|
|
3
|
+
* augmentation (checkoutPagePaymentTypes) from third-party integrations works.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A payment definition object that describes a payment in your storefront.
|
|
12
|
-
*
|
|
13
|
-
* @typedef {Object} PaymentDefinition
|
|
14
|
-
* @property {string} paymentCode is use to map your payment
|
|
15
|
-
* @property {string} importPath Resolvable path to the component the
|
|
16
|
-
* Route component will render
|
|
17
|
-
*
|
|
18
|
-
* @example <caption>A custom payment method</caption>
|
|
19
|
-
* const myCustomPayment = {
|
|
20
|
-
* paymentCode: 'cc',
|
|
21
|
-
* importPath: '@partner/module/path_to_your_component'
|
|
22
|
-
* }
|
|
5
|
+
* Note: Keeping a local empty object here prevents integrations like
|
|
6
|
+
* Stripe/MultiSafepay from registering their UI components, resulting in
|
|
7
|
+
* "There was an error loading payments" on checkout.
|
|
23
8
|
*/
|
|
9
|
+
export { default } from '@magento/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethodCollection';
|
package/src/overwrites/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.js
CHANGED
|
@@ -37,7 +37,30 @@ const PaymentMethods = props => {
|
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
// Warn if Magento exposes payment methods that don't have a mapped UI component.
|
|
41
|
+
const knownCodes = Object.keys(payments);
|
|
42
|
+
const unknownMethods = availablePaymentMethods.filter(
|
|
43
|
+
({ code }) => !knownCodes.includes(code)
|
|
44
|
+
);
|
|
45
|
+
if (unknownMethods.length) {
|
|
46
|
+
// eslint-disable-next-line no-console
|
|
47
|
+
console.warn(
|
|
48
|
+
'Checkout: Ditemukan metode pembayaran yang belum dipetakan:',
|
|
49
|
+
unknownMethods.map(m => m.code),
|
|
50
|
+
'\nPastikan metode tersebut terdaftar melalui target build Venia "checkoutPagePaymentTypes" atau ditambahkan ke paymentMethodCollection.'
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Title fallback map to ensure labels are always visible.
|
|
55
|
+
const TITLE_FALLBACK = {
|
|
56
|
+
braintree: 'Credit/Debit Card',
|
|
57
|
+
paypal_express: 'PayPal Express Checkout',
|
|
58
|
+
paypal_express_bml: 'PayPal Credit',
|
|
59
|
+
checkmo: 'Check / Money Order',
|
|
60
|
+
xendit: 'Xendit',
|
|
61
|
+
cc: 'Credit Card',
|
|
62
|
+
free: 'Free'
|
|
63
|
+
};
|
|
41
64
|
|
|
42
65
|
const radios = availablePaymentMethods
|
|
43
66
|
.map(({ code, title }) => {
|
|
@@ -48,6 +71,7 @@ const PaymentMethods = props => {
|
|
|
48
71
|
|
|
49
72
|
const id = `paymentMethod--${code}`;
|
|
50
73
|
const isSelected = currentSelectedPaymentMethod === code;
|
|
74
|
+
const displayTitle = title || TITLE_FALLBACK[code] || code;
|
|
51
75
|
const PaymentMethodComponent = payments[code];
|
|
52
76
|
const renderedComponent = isSelected ? (
|
|
53
77
|
<PaymentMethodComponent
|
|
@@ -55,6 +79,7 @@ const PaymentMethods = props => {
|
|
|
55
79
|
onPaymentError={onPaymentError}
|
|
56
80
|
resetShouldSubmit={resetShouldSubmit}
|
|
57
81
|
shouldSubmit={shouldSubmit}
|
|
82
|
+
currentSelectedPaymentMethod={currentSelectedPaymentMethod}
|
|
58
83
|
/>
|
|
59
84
|
) : null;
|
|
60
85
|
|
|
@@ -62,7 +87,7 @@ const PaymentMethods = props => {
|
|
|
62
87
|
<div key={code} className={classes.payment_method}>
|
|
63
88
|
<Radio
|
|
64
89
|
id={id}
|
|
65
|
-
label={
|
|
90
|
+
label={displayTitle}
|
|
66
91
|
value={code}
|
|
67
92
|
classes={{
|
|
68
93
|
label: classes.radio_label
|
|
@@ -95,6 +120,12 @@ const PaymentMethods = props => {
|
|
|
95
120
|
|
|
96
121
|
return (
|
|
97
122
|
<div className={classes.root}>
|
|
123
|
+
<h5 className={classes.cardTitle}>
|
|
124
|
+
{formatMessage({
|
|
125
|
+
id: 'checkoutPage.paymentInformation',
|
|
126
|
+
defaultMessage: 'Payment Information'
|
|
127
|
+
})}
|
|
128
|
+
</h5>
|
|
98
129
|
<RadioGroup
|
|
99
130
|
classes={{ root: classes.radio_group }}
|
|
100
131
|
field="selectedPaymentMethod"
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
.root {
|
|
2
2
|
composes: grid from global;
|
|
3
|
-
composes: p-md from global;
|
|
3
|
+
/* composes: p-md from global; */
|
|
4
4
|
composes: pb-s from global;
|
|
5
|
+
padding: 1rem;
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
.radio_group {
|
|
@@ -10,10 +11,11 @@
|
|
|
10
11
|
|
|
11
12
|
.payment_method {
|
|
12
13
|
composes: border-b from global;
|
|
13
|
-
composes: border-solid from global;
|
|
14
|
-
composes: border-subtle from global;
|
|
14
|
+
/* composes: border-solid from global; */
|
|
15
|
+
/* composes: border-subtle from global; */
|
|
15
16
|
composes: pb-xs from global;
|
|
16
17
|
composes: pt-xs from global;
|
|
18
|
+
border-color: lightgray;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
/* TODO @TW: cannot compose */
|
|
@@ -32,3 +34,11 @@
|
|
|
32
34
|
composes: gap-2xs from global;
|
|
33
35
|
composes: text-error from global;
|
|
34
36
|
}
|
|
37
|
+
.cardTitle{
|
|
38
|
+
font-weight: 500;
|
|
39
|
+
font-size: 16px;
|
|
40
|
+
}
|
|
41
|
+
.address_check{
|
|
42
|
+
margin-left: 5px;
|
|
43
|
+
margin-top: 5px;
|
|
44
|
+
}
|