@blocklet/payment-react 1.26.1 → 1.26.3
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/es/checkout-v2/components/dialogs/checkout-dialogs.js +2 -0
- package/es/checkout-v2/components/left/cross-sell-card.js +3 -3
- package/es/checkout-v2/components/left/product-item-card.js +9 -3
- package/es/checkout-v2/components/left/promotion-input.d.ts +4 -1
- package/es/checkout-v2/components/left/promotion-input.js +8 -13
- package/es/checkout-v2/components/right/customer-info-card.d.ts +2 -0
- package/es/checkout-v2/components/right/customer-info-card.js +22 -14
- package/es/checkout-v2/components/right/status-feedback.js +1 -1
- package/es/checkout-v2/components/right/submit-button.js +3 -1
- package/es/checkout-v2/layouts/checkout-layout.js +13 -3
- package/es/checkout-v2/panels/left/composite-panel.js +27 -6
- package/es/checkout-v2/panels/right/payment-panel.js +40 -9
- package/es/checkout-v2/utils/format.d.ts +1 -1
- package/es/checkout-v2/utils/format.js +1 -0
- package/es/checkout-v2/views/error-view.d.ts +1 -1
- package/es/checkout-v2/views/error-view.js +9 -0
- package/es/checkout-v2/views/success-view.js +3 -1
- package/es/components/over-due-invoice-payment.js +5 -3
- package/es/components/service-suspended-dialog.d.ts +4 -0
- package/es/components/service-suspended-dialog.js +61 -0
- package/es/libs/util.d.ts +8 -0
- package/es/libs/util.js +3 -0
- package/es/locales/en.js +4 -0
- package/es/locales/zh.js +4 -0
- package/es/payment/form/index.js +17 -0
- package/es/payment/index.js +15 -4
- package/lib/checkout-v2/components/dialogs/checkout-dialogs.js +4 -0
- package/lib/checkout-v2/components/left/cross-sell-card.js +2 -2
- package/lib/checkout-v2/components/left/product-item-card.js +9 -2
- package/lib/checkout-v2/components/left/promotion-input.d.ts +4 -1
- package/lib/checkout-v2/components/left/promotion-input.js +12 -19
- package/lib/checkout-v2/components/right/customer-info-card.d.ts +2 -0
- package/lib/checkout-v2/components/right/customer-info-card.js +19 -13
- package/lib/checkout-v2/components/right/status-feedback.js +1 -1
- package/lib/checkout-v2/components/right/submit-button.js +3 -1
- package/lib/checkout-v2/layouts/checkout-layout.js +28 -5
- package/lib/checkout-v2/panels/left/composite-panel.js +20 -5
- package/lib/checkout-v2/panels/right/payment-panel.js +46 -7
- package/lib/checkout-v2/utils/format.d.ts +1 -1
- package/lib/checkout-v2/utils/format.js +7 -0
- package/lib/checkout-v2/views/error-view.d.ts +1 -1
- package/lib/checkout-v2/views/error-view.js +9 -0
- package/lib/checkout-v2/views/success-view.js +2 -0
- package/lib/components/over-due-invoice-payment.js +12 -2
- package/lib/components/service-suspended-dialog.d.ts +4 -0
- package/lib/components/service-suspended-dialog.js +97 -0
- package/lib/libs/util.d.ts +8 -0
- package/lib/libs/util.js +4 -0
- package/lib/locales/en.js +4 -0
- package/lib/locales/zh.js +4 -0
- package/lib/payment/form/index.js +23 -0
- package/lib/payment/index.js +15 -4
- package/package.json +4 -4
- package/src/checkout-v2/components/dialogs/checkout-dialogs.tsx +4 -0
- package/src/checkout-v2/components/left/cross-sell-card.tsx +3 -3
- package/src/checkout-v2/components/left/product-item-card.tsx +18 -8
- package/src/checkout-v2/components/left/promotion-input.tsx +17 -17
- package/src/checkout-v2/components/right/customer-info-card.tsx +29 -16
- package/src/checkout-v2/components/right/status-feedback.tsx +2 -2
- package/src/checkout-v2/components/right/submit-button.tsx +2 -0
- package/src/checkout-v2/layouts/checkout-layout.tsx +25 -10
- package/src/checkout-v2/panels/left/composite-panel.tsx +28 -6
- package/src/checkout-v2/panels/right/payment-panel.tsx +32 -5
- package/src/checkout-v2/utils/format.ts +2 -0
- package/src/checkout-v2/views/error-view.tsx +11 -1
- package/src/checkout-v2/views/success-view.tsx +3 -1
- package/src/components/over-due-invoice-payment.tsx +6 -3
- package/src/components/service-suspended-dialog.tsx +64 -0
- package/src/libs/util.ts +7 -0
- package/src/locales/en.tsx +4 -0
- package/src/locales/zh.tsx +4 -0
- package/src/payment/form/index.tsx +20 -0
- package/src/payment/index.tsx +26 -4
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TPaymentCurrency } from '@blocklet/payment-types';
|
|
2
|
+
export { primaryContrastColor } from '../../libs/util';
|
|
2
3
|
export declare const INTERVAL_LOCALE_KEY: Record<string, string>;
|
|
3
4
|
export declare function countryCodeToFlag(code: string): string;
|
|
4
5
|
export declare function formatTokenAmount(unitAmount: string | number | bigint, currency: TPaymentCurrency | null): string;
|
|
@@ -56,4 +57,3 @@ interface ItemMeta {
|
|
|
56
57
|
* Works for the "primary product" header above the item list.
|
|
57
58
|
*/
|
|
58
59
|
export declare function getSessionHeaderMeta(t: TFn, session: any, product: any, items: any[]): ItemMeta;
|
|
59
|
-
export {};
|
|
@@ -10,9 +10,16 @@ exports.formatTokenAmount = formatTokenAmount;
|
|
|
10
10
|
exports.formatTrialText = formatTrialText;
|
|
11
11
|
exports.getSessionHeaderMeta = getSessionHeaderMeta;
|
|
12
12
|
exports.getUnitAmountForCurrency = getUnitAmountForCurrency;
|
|
13
|
+
Object.defineProperty(exports, "primaryContrastColor", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () {
|
|
16
|
+
return _util2.primaryContrastColor;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
13
19
|
exports.tSafe = tSafe;
|
|
14
20
|
exports.whiteTooltipSx = void 0;
|
|
15
21
|
var _util = require("@ocap/util");
|
|
22
|
+
var _util2 = require("../../libs/util");
|
|
16
23
|
const INTERVAL_LOCALE_KEY = exports.INTERVAL_LOCALE_KEY = {
|
|
17
24
|
day: "common.daily",
|
|
18
25
|
week: "common.weekly",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
interface ErrorViewProps {
|
|
2
2
|
error: string;
|
|
3
|
-
errorCode?: 'SESSION_EXPIRED' | 'EMPTY_LINE_ITEMS' | null;
|
|
3
|
+
errorCode?: 'SESSION_EXPIRED' | 'EMPTY_LINE_ITEMS' | 'STOP_ACCEPTING_ORDERS' | null;
|
|
4
4
|
mode?: string;
|
|
5
5
|
}
|
|
6
6
|
export default function ErrorView({ error, errorCode, mode }: ErrorViewProps): import("react").JSX.Element;
|
|
@@ -10,6 +10,7 @@ var _styles = require("@mui/material/styles");
|
|
|
10
10
|
var _ArrowBack = _interopRequireDefault(require("@mui/icons-material/ArrowBack"));
|
|
11
11
|
var _Header = _interopRequireDefault(require("@blocklet/ui-react/lib/Header"));
|
|
12
12
|
var _context = require("@arcblock/ux/lib/Locale/context");
|
|
13
|
+
var _format = require("../utils/format");
|
|
13
14
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
15
|
function GeometricDecoration() {
|
|
15
16
|
const theme = (0, _styles.useTheme)();
|
|
@@ -149,6 +150,13 @@ function getErrorConfig(errorCode, error, t) {
|
|
|
149
150
|
color: "#94a3b8"
|
|
150
151
|
};
|
|
151
152
|
}
|
|
153
|
+
if (errorCode === "STOP_ACCEPTING_ORDERS") {
|
|
154
|
+
return {
|
|
155
|
+
title: t("payment.checkout.stopAcceptingOrders.title"),
|
|
156
|
+
description: t("payment.checkout.stopAcceptingOrders.description"),
|
|
157
|
+
color: "#f59e0b"
|
|
158
|
+
};
|
|
159
|
+
}
|
|
152
160
|
return {
|
|
153
161
|
title: t("payment.checkout.error.title"),
|
|
154
162
|
description: error,
|
|
@@ -223,6 +231,7 @@ function ErrorContent({
|
|
|
223
231
|
fontWeight: 600,
|
|
224
232
|
fontSize: 16,
|
|
225
233
|
letterSpacing: "0.02em",
|
|
234
|
+
color: th => (0, _format.primaryContrastColor)(th),
|
|
226
235
|
boxShadow: `0 8px 32px -4px ${(0, _styles.alpha)(primaryColor, 0.3)}`,
|
|
227
236
|
"&:hover": {
|
|
228
237
|
boxShadow: `0 12px 40px -4px ${(0, _styles.alpha)(primaryColor, 0.4)}`,
|
|
@@ -537,6 +537,7 @@ function SubscriptionLinks({
|
|
|
537
537
|
md: 17
|
|
538
538
|
},
|
|
539
539
|
letterSpacing: "0.02em",
|
|
540
|
+
color: theme => (0, _format.primaryContrastColor)(theme),
|
|
540
541
|
boxShadow: "0 8px 24px -4px rgba(59,130,246,0.25)",
|
|
541
542
|
"&:hover": {
|
|
542
543
|
boxShadow: "0 12px 28px -4px rgba(59,130,246,0.35)"
|
|
@@ -577,6 +578,7 @@ function InvoiceLink({
|
|
|
577
578
|
md: 17
|
|
578
579
|
},
|
|
579
580
|
letterSpacing: "0.02em",
|
|
581
|
+
color: theme => (0, _format.primaryContrastColor)(theme),
|
|
580
582
|
boxShadow: "0 8px 24px -4px rgba(59,130,246,0.25)",
|
|
581
583
|
"&:hover": {
|
|
582
584
|
boxShadow: "0 12px 28px -4px rgba(59,130,246,0.35)"
|
|
@@ -335,11 +335,15 @@ function OverdueInvoicePayment({
|
|
|
335
335
|
} = item;
|
|
336
336
|
const inProcess = payLoading && selectCurrencyId === currency.id;
|
|
337
337
|
const status = paymentStatus[currency.id] || "idle";
|
|
338
|
+
const containedColorSx = (options?.variant || "contained") === "contained" ? {
|
|
339
|
+
color: th => (0, _util.primaryContrastColor)(th)
|
|
340
|
+
} : {};
|
|
338
341
|
if (status === "success") {
|
|
339
342
|
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Button, {
|
|
340
343
|
variant: options?.variant || "contained",
|
|
341
344
|
size: "small",
|
|
342
345
|
onClick: () => checkAndHandleInvoicePaid(currency.id),
|
|
346
|
+
sx: containedColorSx,
|
|
343
347
|
...(primaryButton ? {} : {
|
|
344
348
|
color: "success",
|
|
345
349
|
startIcon: /* @__PURE__ */(0, _jsxRuntime.jsx)(_iconsMaterial.CheckCircle, {})
|
|
@@ -378,7 +382,10 @@ function OverdueInvoicePayment({
|
|
|
378
382
|
disabled: paying || status === "processing",
|
|
379
383
|
loading: paying || status === "processing",
|
|
380
384
|
onClick: onPay,
|
|
381
|
-
sx:
|
|
385
|
+
sx: {
|
|
386
|
+
...containedColorSx,
|
|
387
|
+
...(options?.sx || {})
|
|
388
|
+
},
|
|
382
389
|
children: buttonText
|
|
383
390
|
})
|
|
384
391
|
});
|
|
@@ -389,7 +396,10 @@ function OverdueInvoicePayment({
|
|
|
389
396
|
disabled: inProcess,
|
|
390
397
|
loading: inProcess,
|
|
391
398
|
onClick: () => handlePay(item),
|
|
392
|
-
sx:
|
|
399
|
+
sx: {
|
|
400
|
+
...containedColorSx,
|
|
401
|
+
...(options?.sx || {})
|
|
402
|
+
},
|
|
393
403
|
children: status === "error" ? t("payment.subscription.overdue.retry") : t("payment.subscription.overdue.payNow")
|
|
394
404
|
});
|
|
395
405
|
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
module.exports = ServiceSuspendedDialog;
|
|
7
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
8
|
+
var _material = require("@mui/material");
|
|
9
|
+
var _styles = require("@mui/material/styles");
|
|
10
|
+
var _PauseCircleOutline = _interopRequireDefault(require("@mui/icons-material/PauseCircleOutline"));
|
|
11
|
+
var _context = require("@arcblock/ux/lib/Locale/context");
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
function ServiceSuspendedDialog({
|
|
14
|
+
open,
|
|
15
|
+
onClose
|
|
16
|
+
}) {
|
|
17
|
+
const {
|
|
18
|
+
t
|
|
19
|
+
} = (0, _context.useLocaleContext)();
|
|
20
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Dialog, {
|
|
21
|
+
open,
|
|
22
|
+
onClose,
|
|
23
|
+
PaperProps: {
|
|
24
|
+
sx: {
|
|
25
|
+
borderRadius: 3,
|
|
26
|
+
maxWidth: 400,
|
|
27
|
+
mx: "auto",
|
|
28
|
+
overflow: "hidden"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.DialogContent, {
|
|
32
|
+
sx: {
|
|
33
|
+
p: 0
|
|
34
|
+
},
|
|
35
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
36
|
+
alignItems: "center",
|
|
37
|
+
sx: {
|
|
38
|
+
pt: 4,
|
|
39
|
+
pb: 3,
|
|
40
|
+
px: 4,
|
|
41
|
+
textAlign: "center"
|
|
42
|
+
},
|
|
43
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
44
|
+
sx: {
|
|
45
|
+
width: 64,
|
|
46
|
+
height: 64,
|
|
47
|
+
borderRadius: "50%",
|
|
48
|
+
display: "flex",
|
|
49
|
+
alignItems: "center",
|
|
50
|
+
justifyContent: "center",
|
|
51
|
+
bgcolor: theme => (0, _styles.alpha)(theme.palette.warning.main, 0.1),
|
|
52
|
+
mb: 2.5
|
|
53
|
+
},
|
|
54
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_PauseCircleOutline.default, {
|
|
55
|
+
sx: {
|
|
56
|
+
fontSize: 36,
|
|
57
|
+
color: "warning.main"
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
61
|
+
sx: {
|
|
62
|
+
fontWeight: 700,
|
|
63
|
+
fontSize: 18,
|
|
64
|
+
mb: 1,
|
|
65
|
+
color: "text.primary"
|
|
66
|
+
},
|
|
67
|
+
children: t("payment.checkout.stopAcceptingOrders.title")
|
|
68
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
69
|
+
sx: {
|
|
70
|
+
color: "text.secondary",
|
|
71
|
+
fontSize: 14,
|
|
72
|
+
lineHeight: 1.6
|
|
73
|
+
},
|
|
74
|
+
children: t("payment.checkout.stopAcceptingOrders.description")
|
|
75
|
+
})]
|
|
76
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
77
|
+
sx: {
|
|
78
|
+
px: 4,
|
|
79
|
+
pb: 3
|
|
80
|
+
},
|
|
81
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Button, {
|
|
82
|
+
fullWidth: true,
|
|
83
|
+
variant: "contained",
|
|
84
|
+
disableElevation: true,
|
|
85
|
+
onClick: onClose,
|
|
86
|
+
sx: {
|
|
87
|
+
borderRadius: 2,
|
|
88
|
+
textTransform: "none",
|
|
89
|
+
fontWeight: 600,
|
|
90
|
+
py: 1
|
|
91
|
+
},
|
|
92
|
+
children: t("common.know")
|
|
93
|
+
})
|
|
94
|
+
})]
|
|
95
|
+
})
|
|
96
|
+
});
|
|
97
|
+
}
|
package/lib/libs/util.d.ts
CHANGED
|
@@ -194,3 +194,11 @@ export declare function getTokenBalanceLink(method: TPaymentMethod, address: str
|
|
|
194
194
|
export declare function isCreditMetered(price: TPrice): boolean;
|
|
195
195
|
export declare function showStaking(method: TPaymentMethod, currency: TPaymentCurrency, noStake: boolean): boolean;
|
|
196
196
|
export declare function formatLinkWithLocale(url: string, locale?: string): string;
|
|
197
|
+
export declare function primaryContrastColor(theme: {
|
|
198
|
+
palette: {
|
|
199
|
+
primary: {
|
|
200
|
+
main: string;
|
|
201
|
+
};
|
|
202
|
+
getContrastText: (bg: string) => string;
|
|
203
|
+
};
|
|
204
|
+
}): string;
|
package/lib/libs/util.js
CHANGED
|
@@ -75,6 +75,7 @@ exports.lazyLoad = lazyLoad;
|
|
|
75
75
|
exports.mergeExtraParams = void 0;
|
|
76
76
|
exports.openDonationSettings = openDonationSettings;
|
|
77
77
|
exports.parseMarkedText = parseMarkedText;
|
|
78
|
+
exports.primaryContrastColor = primaryContrastColor;
|
|
78
79
|
exports.showStaking = showStaking;
|
|
79
80
|
exports.sleep = sleep;
|
|
80
81
|
exports.stopEvent = stopEvent;
|
|
@@ -1644,4 +1645,7 @@ function formatLinkWithLocale(url, locale) {
|
|
|
1644
1645
|
const separator = url.includes("?") ? "&" : "?";
|
|
1645
1646
|
return `${url}${separator}locale=${locale}`;
|
|
1646
1647
|
}
|
|
1648
|
+
}
|
|
1649
|
+
function primaryContrastColor(theme) {
|
|
1650
|
+
return theme.palette.getContrastText(theme.palette.primary.main);
|
|
1647
1651
|
}
|
package/lib/locales/en.js
CHANGED
|
@@ -387,6 +387,10 @@ module.exports = (0, _flat.default)({
|
|
|
387
387
|
title: "Nothing to show here",
|
|
388
388
|
description: "It seems this checkout session is not configured properly"
|
|
389
389
|
},
|
|
390
|
+
stopAcceptingOrders: {
|
|
391
|
+
title: "Service Suspended",
|
|
392
|
+
description: "New order placement is temporarily unavailable due to a system-level service suspension."
|
|
393
|
+
},
|
|
390
394
|
error: {
|
|
391
395
|
title: "Something went wrong"
|
|
392
396
|
},
|
package/lib/locales/zh.js
CHANGED
|
@@ -416,6 +416,10 @@ module.exports = (0, _flat.default)({
|
|
|
416
416
|
title: "\u6CA1\u6709\u4EFB\u4F55\u8D2D\u4E70\u9879\u76EE",
|
|
417
417
|
description: "\u53EF\u80FD\u8FD9\u4E2A\u4ED8\u6B3E\u94FE\u63A5\u6CA1\u6709\u6B63\u786E\u914D\u7F6E"
|
|
418
418
|
},
|
|
419
|
+
stopAcceptingOrders: {
|
|
420
|
+
title: "\u6682\u505C\u670D\u52A1",
|
|
421
|
+
description: "\u56E0\u7CFB\u7EDF\u7B56\u7565\u8C03\u6574\uFF0C\u5F53\u524D\u5DF2\u6682\u505C\u65B0\u8BA2\u5355\u670D\u52A1\u3002"
|
|
422
|
+
},
|
|
419
423
|
error: {
|
|
420
424
|
title: "\u51FA\u4E86\u70B9\u95EE\u9898"
|
|
421
425
|
},
|
|
@@ -40,6 +40,7 @@ var _loadingButton = _interopRequireDefault(require("../../components/loading-bu
|
|
|
40
40
|
var _overDueInvoicePayment = _interopRequireDefault(require("../../components/over-due-invoice-payment"));
|
|
41
41
|
var _currency2 = require("../../libs/currency");
|
|
42
42
|
var _confirm = _interopRequireDefault(require("../../components/confirm"));
|
|
43
|
+
var _serviceSuspendedDialog = _interopRequireDefault(require("../../components/service-suspended-dialog"));
|
|
43
44
|
var _priceChangeConfirm = _interopRequireDefault(require("../../components/price-change-confirm"));
|
|
44
45
|
var _validator = require("../../libs/validator");
|
|
45
46
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -181,6 +182,7 @@ function PaymentForm({
|
|
|
181
182
|
stripeContext: void 0,
|
|
182
183
|
customer,
|
|
183
184
|
customerLimited: false,
|
|
185
|
+
serviceSuspended: false,
|
|
184
186
|
stripePaying: false,
|
|
185
187
|
fastCheckoutInfo: null,
|
|
186
188
|
creditInsufficientInfo: null,
|
|
@@ -1039,6 +1041,12 @@ function PaymentForm({
|
|
|
1039
1041
|
customerLimited: true
|
|
1040
1042
|
});
|
|
1041
1043
|
}
|
|
1044
|
+
if (errorCode === "STOP_ACCEPTING_ORDERS") {
|
|
1045
|
+
shouldToast = false;
|
|
1046
|
+
setState({
|
|
1047
|
+
serviceSuspended: true
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1042
1050
|
}
|
|
1043
1051
|
if (shouldToast) {
|
|
1044
1052
|
_Toast.default.error((0, _util2.formatError)(err));
|
|
@@ -1307,6 +1315,11 @@ function PaymentForm({
|
|
|
1307
1315
|
}),
|
|
1308
1316
|
title: t("payment.customer.pastDue.alert.title")
|
|
1309
1317
|
}
|
|
1318
|
+
}), state.serviceSuspended && /* @__PURE__ */(0, _jsxRuntime.jsx)(_serviceSuspendedDialog.default, {
|
|
1319
|
+
open: true,
|
|
1320
|
+
onClose: () => setState({
|
|
1321
|
+
serviceSuspended: false
|
|
1322
|
+
})
|
|
1310
1323
|
}), FastCheckoutConfirmDialog, CreditInsufficientDialog, PriceUpdatedDialog, state.priceChangeConfirm?.open && /* @__PURE__ */(0, _jsxRuntime.jsx)(_priceChangeConfirm.default, {
|
|
1311
1324
|
open: true,
|
|
1312
1325
|
changePercent: state.priceChangeConfirm.changePercent,
|
|
@@ -1617,6 +1630,16 @@ function PaymentForm({
|
|
|
1617
1630
|
}),
|
|
1618
1631
|
title: t("payment.customer.pastDue.alert.title")
|
|
1619
1632
|
}
|
|
1633
|
+
}), state.serviceSuspended && /* @__PURE__ */(0, _jsxRuntime.jsx)(_confirm.default, {
|
|
1634
|
+
onConfirm: () => setState({
|
|
1635
|
+
serviceSuspended: false
|
|
1636
|
+
}),
|
|
1637
|
+
onCancel: () => setState({
|
|
1638
|
+
serviceSuspended: false
|
|
1639
|
+
}),
|
|
1640
|
+
title: t("payment.checkout.stopAcceptingOrders.title"),
|
|
1641
|
+
message: t("payment.checkout.stopAcceptingOrders.description"),
|
|
1642
|
+
confirm: t("common.confirm")
|
|
1620
1643
|
}), FastCheckoutConfirmDialog, CreditInsufficientDialog, PriceUpdatedDialog, state.priceChangeConfirm?.open && /* @__PURE__ */(0, _jsxRuntime.jsx)(_priceChangeConfirm.default, {
|
|
1621
1644
|
open: true,
|
|
1622
1645
|
changePercent: state.priceChangeConfirm.changePercent,
|
package/lib/payment/index.js
CHANGED
|
@@ -87,6 +87,10 @@ function PaymentInner({
|
|
|
87
87
|
return Array.from(currencyIds);
|
|
88
88
|
}, [paymentMethods]);
|
|
89
89
|
const defaultCurrencyId = (0, _react.useMemo)(() => {
|
|
90
|
+
const hasAppliedDiscount = Boolean(state.checkoutSession?.discounts?.length);
|
|
91
|
+
if (hasAppliedDiscount && state.checkoutSession.currency_id && availableCurrencyIds.includes(state.checkoutSession.currency_id)) {
|
|
92
|
+
return state.checkoutSession.currency_id;
|
|
93
|
+
}
|
|
90
94
|
if (query.currencyId && availableCurrencyIds.includes(query.currencyId)) {
|
|
91
95
|
return query.currencyId;
|
|
92
96
|
}
|
|
@@ -104,7 +108,7 @@ function PaymentInner({
|
|
|
104
108
|
return state.checkoutSession.currency_id;
|
|
105
109
|
}
|
|
106
110
|
return availableCurrencyIds?.[0];
|
|
107
|
-
}, [query.currencyId, availableCurrencyIds, session?.user, state.checkoutSession
|
|
111
|
+
}, [query.currencyId, availableCurrencyIds, session?.user, state.checkoutSession, paymentMethods]);
|
|
108
112
|
const defaultMethodId = paymentMethods.find(m => m.payment_currencies.some(c => c.id === defaultCurrencyId))?.id;
|
|
109
113
|
const hideSummaryCard = mode.endsWith("-minimal") || !showCheckoutSummary;
|
|
110
114
|
const methods = (0, _reactHookForm.useForm)({
|
|
@@ -127,13 +131,20 @@ function PaymentInner({
|
|
|
127
131
|
}
|
|
128
132
|
});
|
|
129
133
|
(0, _react.useEffect)(() => {
|
|
134
|
+
const hasAppliedDiscount = Boolean(state.checkoutSession?.discounts?.length);
|
|
135
|
+
const currentCurrency = methods.getValues("payment_currency");
|
|
136
|
+
const currentMethod = methods.getValues("payment_method");
|
|
130
137
|
if (defaultCurrencyId) {
|
|
131
|
-
|
|
138
|
+
if (!hasAppliedDiscount || !currentCurrency) {
|
|
139
|
+
methods.setValue("payment_currency", defaultCurrencyId);
|
|
140
|
+
}
|
|
132
141
|
}
|
|
133
142
|
if (defaultMethodId) {
|
|
134
|
-
|
|
143
|
+
if (!hasAppliedDiscount || !currentMethod) {
|
|
144
|
+
methods.setValue("payment_method", defaultMethodId);
|
|
145
|
+
}
|
|
135
146
|
}
|
|
136
|
-
}, [defaultCurrencyId, defaultMethodId]);
|
|
147
|
+
}, [defaultCurrencyId, defaultMethodId, state.checkoutSession.discounts]);
|
|
137
148
|
(0, _react.useEffect)(() => {
|
|
138
149
|
if (!(0, _util2.isMobileSafari)()) {
|
|
139
150
|
return () => {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/payment-react",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.3",
|
|
4
4
|
"description": "Reusable react components for payment kit v2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@arcblock/react-hooks": "^3.5.1",
|
|
60
60
|
"@arcblock/ux": "^3.5.1",
|
|
61
61
|
"@arcblock/ws": "^1.28.5",
|
|
62
|
-
"@blocklet/payment-react-headless": "1.26.
|
|
62
|
+
"@blocklet/payment-react-headless": "1.26.3",
|
|
63
63
|
"@blocklet/theme": "^3.5.1",
|
|
64
64
|
"@blocklet/ui-react": "^3.5.1",
|
|
65
65
|
"@mui/icons-material": "^7.1.2",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"@babel/core": "^7.27.4",
|
|
98
98
|
"@babel/preset-env": "^7.27.2",
|
|
99
99
|
"@babel/preset-react": "^7.27.1",
|
|
100
|
-
"@blocklet/payment-types": "1.26.
|
|
100
|
+
"@blocklet/payment-types": "1.26.3",
|
|
101
101
|
"@storybook/addon-essentials": "^7.6.20",
|
|
102
102
|
"@storybook/addon-interactions": "^7.6.20",
|
|
103
103
|
"@storybook/addon-links": "^7.6.20",
|
|
@@ -128,5 +128,5 @@
|
|
|
128
128
|
"vite-plugin-babel": "^1.3.1",
|
|
129
129
|
"vite-plugin-node-polyfills": "^0.23.0"
|
|
130
130
|
},
|
|
131
|
-
"gitHead": "
|
|
131
|
+
"gitHead": "18c5d045139c572b52465e15c4c63b3e327efab5"
|
|
132
132
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import StripeForm from '../../../payment/form/stripe';
|
|
10
10
|
import ConfirmDialog from '../../../components/confirm';
|
|
11
11
|
import PriceChangeConfirm from '../../../components/price-change-confirm';
|
|
12
|
+
import ServiceSuspendedDialog from '../../../components/service-suspended-dialog';
|
|
12
13
|
import { formatTokenAmount } from '../../utils/format';
|
|
13
14
|
|
|
14
15
|
function getRedirectUrl(session: any): string | undefined {
|
|
@@ -119,6 +120,9 @@ export default function CheckoutDialogs() {
|
|
|
119
120
|
/>
|
|
120
121
|
)}
|
|
121
122
|
|
|
123
|
+
{/* Service Suspended Dialog */}
|
|
124
|
+
{(submit.context as any)?.type === 'service_suspended' && <ServiceSuspendedDialog open onClose={submit.cancel} />}
|
|
125
|
+
|
|
122
126
|
{/* Credit Insufficient Dialog (matches V1 ConfirmDialog) */}
|
|
123
127
|
{submit.status === 'credit_insufficient' && submit.context?.type === 'credit_insufficient' && (
|
|
124
128
|
<ConfirmDialog
|
|
@@ -3,7 +3,7 @@ import ShoppingCartCheckoutIcon from '@mui/icons-material/ShoppingCartCheckout';
|
|
|
3
3
|
import { Avatar, Box, Button, Chip, Stack, Typography } from '@mui/material';
|
|
4
4
|
import type { TPaymentCurrency, TPrice } from '@blocklet/payment-types';
|
|
5
5
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
6
|
-
import { formatDynamicUnitPrice, tSafe, INTERVAL_LOCALE_KEY } from '../../utils/format';
|
|
6
|
+
import { formatDynamicUnitPrice, tSafe, INTERVAL_LOCALE_KEY, primaryContrastColor } from '../../utils/format';
|
|
7
7
|
|
|
8
8
|
interface CrossSellCardProps {
|
|
9
9
|
crossSellItem: TPrice;
|
|
@@ -53,7 +53,7 @@ export default function CrossSellCard({
|
|
|
53
53
|
fontWeight: 900,
|
|
54
54
|
letterSpacing: '0.12em',
|
|
55
55
|
bgcolor: 'primary.main',
|
|
56
|
-
color:
|
|
56
|
+
color: (theme: any) => primaryContrastColor(theme),
|
|
57
57
|
boxShadow: '0 4px 12px rgba(45,124,243,0.2)',
|
|
58
58
|
'& .MuiChip-label': { px: 1.5 },
|
|
59
59
|
}}
|
|
@@ -150,7 +150,7 @@ export default function CrossSellCard({
|
|
|
150
150
|
transition: 'all 0.2s',
|
|
151
151
|
'&:hover': {
|
|
152
152
|
bgcolor: 'primary.main',
|
|
153
|
-
color:
|
|
153
|
+
color: (theme: any) => primaryContrastColor(theme),
|
|
154
154
|
borderColor: 'primary.main',
|
|
155
155
|
},
|
|
156
156
|
'&:active': { transform: 'scale(0.95)' },
|
|
@@ -22,7 +22,13 @@ import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
|
|
|
22
22
|
import type { TLineItemExpanded, TPaymentCurrency } from '@blocklet/payment-types';
|
|
23
23
|
import { getPriceUnitAmountByCurrency } from '@blocklet/payment-react-headless';
|
|
24
24
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
INTERVAL_LOCALE_KEY,
|
|
27
|
+
formatDynamicUnitPrice,
|
|
28
|
+
formatTokenAmount,
|
|
29
|
+
formatTrialText,
|
|
30
|
+
primaryContrastColor,
|
|
31
|
+
} from '../../utils/format';
|
|
26
32
|
|
|
27
33
|
interface ProductItemCardProps {
|
|
28
34
|
item: TLineItemExpanded & { adjustable_quantity?: { enabled: boolean; minimum?: number; maximum?: number } };
|
|
@@ -292,7 +298,7 @@ export default function ProductItemCard({
|
|
|
292
298
|
fontWeight: 900,
|
|
293
299
|
letterSpacing: '0.12em',
|
|
294
300
|
bgcolor: 'primary.main',
|
|
295
|
-
color:
|
|
301
|
+
color: (th: any) => primaryContrastColor(th),
|
|
296
302
|
boxShadow: '0 4px 12px rgba(45,124,243,0.2)',
|
|
297
303
|
'& .MuiChip-label': { px: 1.5 },
|
|
298
304
|
}}
|
|
@@ -467,12 +473,16 @@ export default function ProductItemCard({
|
|
|
467
473
|
{/* Discount chip */}
|
|
468
474
|
{discountCode && perItemDiscount && (
|
|
469
475
|
<Box sx={{ mt: 1.5 }}>
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
+
{isRateLoading ? (
|
|
477
|
+
<Skeleton variant="rounded" width={160} height={22} sx={{ borderRadius: '6px' }} />
|
|
478
|
+
) : (
|
|
479
|
+
<Chip
|
|
480
|
+
icon={<LocalOfferIcon sx={{ color: 'warning.main', fontSize: 'small' }} />}
|
|
481
|
+
label={`${discountCode} (-${perItemDiscount})`}
|
|
482
|
+
size="small"
|
|
483
|
+
sx={{ height: 22, borderRadius: '6px', '& .MuiChip-label': { fontSize: 12 } }}
|
|
484
|
+
/>
|
|
485
|
+
)}
|
|
476
486
|
</Box>
|
|
477
487
|
)}
|
|
478
488
|
|
|
@@ -9,11 +9,13 @@ import {
|
|
|
9
9
|
CircularProgress,
|
|
10
10
|
IconButton,
|
|
11
11
|
InputAdornment,
|
|
12
|
+
Skeleton,
|
|
12
13
|
Stack,
|
|
13
14
|
TextField,
|
|
14
15
|
Typography,
|
|
15
16
|
} from '@mui/material';
|
|
16
17
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
18
|
+
import { formatCouponTerms } from '../../../libs/util';
|
|
17
19
|
|
|
18
20
|
interface PromotionInputProps {
|
|
19
21
|
promotion: {
|
|
@@ -26,17 +28,23 @@ interface PromotionInputProps {
|
|
|
26
28
|
};
|
|
27
29
|
discounts: any[];
|
|
28
30
|
discountAmount: string | null;
|
|
31
|
+
// eslint-disable-next-line react/require-default-props
|
|
32
|
+
currency?: any;
|
|
29
33
|
/** Start with input field visible (skip the "Add promotion code" button) */
|
|
30
34
|
initialShowInput?: boolean;
|
|
35
|
+
/** Show skeleton for the discount amount while switching */
|
|
36
|
+
isAmountLoading?: boolean;
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
export default function PromotionInput({
|
|
34
40
|
promotion,
|
|
35
41
|
discounts,
|
|
36
42
|
discountAmount,
|
|
43
|
+
currency = null,
|
|
37
44
|
initialShowInput = false,
|
|
45
|
+
isAmountLoading = false,
|
|
38
46
|
}: PromotionInputProps) {
|
|
39
|
-
const { t } = useLocaleContext();
|
|
47
|
+
const { t, locale } = useLocaleContext();
|
|
40
48
|
const [showInput, setShowInput] = useState(false);
|
|
41
49
|
const [code, setCode] = useState('');
|
|
42
50
|
const [applying, setApplying] = useState(false);
|
|
@@ -73,19 +81,7 @@ export default function PromotionInput({
|
|
|
73
81
|
const discCode =
|
|
74
82
|
disc.promotion_code_details?.code || disc.verification_data?.code || disc.promotion_code || '';
|
|
75
83
|
const coupon = disc.coupon_details || {};
|
|
76
|
-
const
|
|
77
|
-
coupon.percent_off > 0
|
|
78
|
-
? t('payment.checkout.coupon.percentage', { percent: coupon.percent_off })
|
|
79
|
-
: `${coupon.percent_off || 0}%`;
|
|
80
|
-
let description = '';
|
|
81
|
-
if (coupon.duration === 'repeating' && coupon.duration_in_months) {
|
|
82
|
-
const months = coupon.duration_in_months;
|
|
83
|
-
description = `${couponOff} for ${months} month${months > 1 ? 's' : ''}`;
|
|
84
|
-
} else if (coupon.duration === 'forever') {
|
|
85
|
-
description = t('payment.checkout.coupon.terms.forever', { couponOff });
|
|
86
|
-
} else if (coupon.duration === 'once') {
|
|
87
|
-
description = t('payment.checkout.coupon.terms.once', { couponOff });
|
|
88
|
-
}
|
|
84
|
+
const description = coupon && currency ? formatCouponTerms(coupon, currency, locale) : '';
|
|
89
85
|
return (
|
|
90
86
|
<Stack
|
|
91
87
|
key={disc.promotion_code || disc.coupon || i}
|
|
@@ -115,9 +111,13 @@ export default function PromotionInput({
|
|
|
115
111
|
<CloseIcon sx={{ fontSize: 12, color: '#12b886' }} />
|
|
116
112
|
</IconButton>
|
|
117
113
|
</Stack>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
114
|
+
{isAmountLoading ? (
|
|
115
|
+
<Skeleton variant="text" width={80} height={22} />
|
|
116
|
+
) : (
|
|
117
|
+
<Typography sx={{ color: 'text.primary', fontWeight: 600, fontSize: 14 }}>
|
|
118
|
+
-{discountAmount || '0'}
|
|
119
|
+
</Typography>
|
|
120
|
+
)}
|
|
121
121
|
</Stack>
|
|
122
122
|
);
|
|
123
123
|
})}
|