@blocklet/payment-react 1.19.0 → 1.19.1
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/components/blockchain/tx.d.ts +1 -1
- package/es/components/blockchain/tx.js +9 -11
- package/es/components/country-select.d.ts +1 -1
- package/es/components/date-range-picker.d.ts +13 -0
- package/es/components/date-range-picker.js +279 -0
- package/es/components/input.d.ts +5 -2
- package/es/components/input.js +6 -2
- package/es/components/label.d.ts +7 -0
- package/es/components/label.js +49 -0
- package/es/components/loading-button.d.ts +1 -1
- package/es/history/credit/grants-list.d.ts +14 -0
- package/es/history/credit/grants-list.js +215 -0
- package/es/history/credit/transactions-list.d.ts +13 -0
- package/es/history/credit/transactions-list.js +255 -0
- package/es/history/invoice/list.js +21 -1
- package/es/index.d.ts +5 -1
- package/es/index.js +10 -1
- package/es/libs/util.d.ts +2 -0
- package/es/libs/util.js +12 -0
- package/es/locales/en.js +20 -2
- package/es/locales/zh.js +20 -2
- package/es/payment/form/index.js +44 -6
- package/es/payment/index.js +18 -3
- package/es/payment/product-item.d.ts +8 -1
- package/es/payment/product-item.js +137 -5
- package/es/payment/summary.d.ts +3 -1
- package/es/payment/summary.js +9 -0
- package/lib/components/blockchain/tx.d.ts +1 -1
- package/lib/components/blockchain/tx.js +9 -8
- package/lib/components/country-select.d.ts +1 -1
- package/lib/components/date-range-picker.d.ts +13 -0
- package/lib/components/date-range-picker.js +329 -0
- package/lib/components/input.d.ts +5 -2
- package/lib/components/input.js +8 -4
- package/lib/components/label.d.ts +7 -0
- package/lib/components/label.js +60 -0
- package/lib/components/loading-button.d.ts +1 -1
- package/lib/history/credit/grants-list.d.ts +14 -0
- package/lib/history/credit/grants-list.js +277 -0
- package/lib/history/credit/transactions-list.d.ts +13 -0
- package/lib/history/credit/transactions-list.js +301 -0
- package/lib/history/invoice/list.js +24 -0
- package/lib/index.d.ts +5 -1
- package/lib/index.js +39 -0
- package/lib/libs/util.d.ts +2 -0
- package/lib/libs/util.js +14 -0
- package/lib/locales/en.js +20 -2
- package/lib/locales/zh.js +20 -2
- package/lib/payment/form/index.js +45 -6
- package/lib/payment/index.js +20 -2
- package/lib/payment/product-item.d.ts +8 -1
- package/lib/payment/product-item.js +144 -4
- package/lib/payment/summary.d.ts +3 -1
- package/lib/payment/summary.js +9 -0
- package/package.json +3 -3
- package/src/components/blockchain/tx.tsx +9 -15
- package/src/components/country-select.tsx +2 -2
- package/src/components/date-range-picker.tsx +310 -0
- package/src/components/input.tsx +14 -3
- package/src/components/label.tsx +58 -0
- package/src/components/loading-button.tsx +1 -1
- package/src/history/credit/grants-list.tsx +276 -0
- package/src/history/credit/transactions-list.tsx +317 -0
- package/src/history/invoice/list.tsx +18 -1
- package/src/index.ts +9 -0
- package/src/libs/util.ts +14 -0
- package/src/locales/en.tsx +20 -0
- package/src/locales/zh.tsx +19 -0
- package/src/payment/form/address.tsx +2 -2
- package/src/payment/form/index.tsx +110 -52
- package/src/payment/index.tsx +17 -1
- package/src/payment/product-item.tsx +152 -4
- package/src/payment/summary.tsx +13 -2
package/es/locales/zh.js
CHANGED
|
@@ -31,6 +31,10 @@ export default flat({
|
|
|
31
31
|
change: "\u66F4\u6362",
|
|
32
32
|
confirm: "\u786E\u8BA4",
|
|
33
33
|
cancel: "\u53D6\u6D88",
|
|
34
|
+
clear: "\u6E05\u7A7A",
|
|
35
|
+
selectTimeRange: "\u9009\u62E9\u65F6\u95F4\u8303\u56F4",
|
|
36
|
+
startDate: "\u5F00\u59CB\u65E5\u671F",
|
|
37
|
+
endDate: "\u7ED3\u675F\u65E5\u671F",
|
|
34
38
|
close: "\u5173\u95ED",
|
|
35
39
|
back: "\u8FD4\u56DE",
|
|
36
40
|
every: "\u6BCF",
|
|
@@ -100,7 +104,8 @@ export default flat({
|
|
|
100
104
|
scan: "\u4F7F\u7528\u4EE5\u4E0B\u65B9\u5F0F\u5B8C\u6210\u672C\u6B21{action}",
|
|
101
105
|
confirm: "\u786E\u8BA4",
|
|
102
106
|
cancel: "\u53D6\u6D88"
|
|
103
|
-
}
|
|
107
|
+
},
|
|
108
|
+
paymentMethod: "\u652F\u4ED8\u65B9\u5F0F"
|
|
104
109
|
},
|
|
105
110
|
payment: {
|
|
106
111
|
checkout: {
|
|
@@ -212,6 +217,11 @@ export default flat({
|
|
|
212
217
|
add: "\u6DFB\u52A0\u5230\u8BA2\u5355",
|
|
213
218
|
remove: "\u4ECE\u8BA2\u5355\u79FB\u9664"
|
|
214
219
|
},
|
|
220
|
+
credit: {
|
|
221
|
+
oneTimeInfo: "\u4ED8\u6B3E\u5B8C\u6210\u540E\u60A8\u5C06\u83B7\u5F97 {amount} {symbol} \u989D\u5EA6",
|
|
222
|
+
recurringInfo: "\u60A8\u5C06{period}\u83B7\u5F97 {amount} {symbol} \u989D\u5EA6",
|
|
223
|
+
expiresIn: "\u989D\u5EA6\u6709\u6548\u671F\u4E3A {duration} {unit}"
|
|
224
|
+
},
|
|
215
225
|
emptyItems: {
|
|
216
226
|
title: "\u6CA1\u6709\u4EFB\u4F55\u8D2D\u4E70\u9879\u76EE",
|
|
217
227
|
description: "\u53EF\u80FD\u8FD9\u4E2A\u4ED8\u6B3E\u94FE\u63A5\u6CA1\u6709\u6B63\u786E\u914D\u7F6E"
|
|
@@ -232,7 +242,15 @@ export default flat({
|
|
|
232
242
|
payer: "\u8D26\u6237\u5730\u5740",
|
|
233
243
|
amount: "\u652F\u4ED8\u91D1\u989D",
|
|
234
244
|
failed: "\u8D26\u6237\u53D1\u751F\u53D8\u5316\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5B8C\u6210\u652F\u4ED8\uFF0C\u8BF7\u624B\u52A8\u652F\u4ED8\u3002",
|
|
235
|
-
balanceLink: "\u67E5\u770B\u4F59\u989D"
|
|
245
|
+
balanceLink: "\u67E5\u770B\u4F59\u989D",
|
|
246
|
+
credit: {
|
|
247
|
+
title: "\u786E\u8BA4\u989D\u5EA6\u652F\u4ED8",
|
|
248
|
+
availableAmount: "\u53EF\u7528\u989D\u5EA6\uFF1A{amount}",
|
|
249
|
+
confirmMessage: "\u60A8\u5C06\u4F7F\u7528 {amount} \u989D\u5EA6\u6765\u8BA2\u9605\u6B64\u670D\u52A1\u3002",
|
|
250
|
+
meteringSubscriptionMessage: "\u6B64\u8BA2\u9605\u670D\u52A1\u5C06\u6839\u636E\u5B9E\u9645\u4F7F\u7528\u60C5\u51B5\u5B9E\u65F6\u6263\u9664\u989D\u5EA6\u3002\u60A8\u5F53\u524D\u53EF\u7528\u989D\u5EA6\u4E3A {available}\uFF0C\u786E\u8BA4\u662F\u5426\u7EE7\u7EED\uFF1F",
|
|
251
|
+
insufficientTitle: "\u989D\u5EA6\u4E0D\u8DB3",
|
|
252
|
+
insufficientMessage: "\u6B64\u8BA2\u9605\u670D\u52A1\u5C06\u6839\u636E\u5B9E\u9645\u4F7F\u7528\u60C5\u51B5\u5B9E\u65F6\u6263\u9664\u989D\u5EA6\u3002\u60A8\u5F53\u524D\u53EF\u7528\u989D\u5EA6\u4E0D\u8DB3\uFF0C\u8BF7\u5148\u5145\u503C\u989D\u5EA6\u3002"
|
|
253
|
+
}
|
|
236
254
|
}
|
|
237
255
|
},
|
|
238
256
|
customer: {
|
package/es/payment/form/index.js
CHANGED
|
@@ -131,7 +131,8 @@ export default function PaymentForm({
|
|
|
131
131
|
customer,
|
|
132
132
|
customerLimited: false,
|
|
133
133
|
stripePaying: false,
|
|
134
|
-
fastCheckoutInfo: null
|
|
134
|
+
fastCheckoutInfo: null,
|
|
135
|
+
creditInsufficientInfo: null
|
|
135
136
|
});
|
|
136
137
|
const currencies = flattenPaymentMethods(paymentMethods);
|
|
137
138
|
const onCheckoutComplete = useMemoizedFn(async ({ response }) => {
|
|
@@ -300,6 +301,9 @@ export default function PaymentForm({
|
|
|
300
301
|
const handleFastCheckoutCancel = () => {
|
|
301
302
|
setState({ fastCheckoutInfo: null });
|
|
302
303
|
};
|
|
304
|
+
const handleCreditInsufficientClose = () => {
|
|
305
|
+
setState({ creditInsufficientInfo: null });
|
|
306
|
+
};
|
|
303
307
|
const openConnect = () => {
|
|
304
308
|
try {
|
|
305
309
|
if (!["arcblock", "ethereum", "base"].includes(method.type)) {
|
|
@@ -355,7 +359,27 @@ export default function PaymentForm({
|
|
|
355
359
|
customerLimited: false
|
|
356
360
|
});
|
|
357
361
|
if (["arcblock", "ethereum", "base"].includes(method.type)) {
|
|
358
|
-
if (
|
|
362
|
+
if (paymentCurrency?.type === "credit") {
|
|
363
|
+
if (result.data.creditSufficient === true) {
|
|
364
|
+
setState({
|
|
365
|
+
fastCheckoutInfo: {
|
|
366
|
+
open: true,
|
|
367
|
+
loading: false,
|
|
368
|
+
sourceType: "credit",
|
|
369
|
+
amount: result.data.fastPayInfo?.amount || "0",
|
|
370
|
+
payer: result.data.fastPayInfo?.payer,
|
|
371
|
+
availableCredit: result.data.fastPayInfo?.amount || "0",
|
|
372
|
+
balance: result.data.fastPayInfo?.token?.balance || "0"
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
} else {
|
|
376
|
+
setState({
|
|
377
|
+
creditInsufficientInfo: {
|
|
378
|
+
open: true
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
} else if ((result.data.balance?.sufficient || result.data.delegation?.sufficient) && !isDonationMode && result.data.fastPayInfo) {
|
|
359
383
|
setState({
|
|
360
384
|
fastCheckoutInfo: {
|
|
361
385
|
open: true,
|
|
@@ -445,8 +469,10 @@ export default function PaymentForm({
|
|
|
445
469
|
{
|
|
446
470
|
onConfirm: handleFastCheckoutConfirm,
|
|
447
471
|
onCancel: handleFastCheckoutCancel,
|
|
448
|
-
title: t("payment.checkout.fastPay.title"),
|
|
449
|
-
message: /* @__PURE__ */
|
|
472
|
+
title: state.fastCheckoutInfo.sourceType === "credit" ? t("payment.checkout.fastPay.credit.title") : t("payment.checkout.fastPay.title"),
|
|
473
|
+
message: state.fastCheckoutInfo.sourceType === "credit" ? /* @__PURE__ */ jsx(Typography, { children: t("payment.checkout.fastPay.credit.meteringSubscriptionMessage", {
|
|
474
|
+
available: `${fromUnitToToken(state.fastCheckoutInfo?.balance || "0", paymentCurrency?.decimal || 18).toString()} ${paymentCurrency?.symbol}`
|
|
475
|
+
}) }) : /* @__PURE__ */ jsxs(Stack, { children: [
|
|
450
476
|
/* @__PURE__ */ jsx(Typography, { children: t("payment.checkout.fastPay.autoPaymentReason") }),
|
|
451
477
|
/* @__PURE__ */ jsx(Divider, { sx: { mt: 1.5, mb: 1.5 } }),
|
|
452
478
|
/* @__PURE__ */ jsxs(Stack, { spacing: 1, children: [
|
|
@@ -521,6 +547,16 @@ export default function PaymentForm({
|
|
|
521
547
|
color: "primary"
|
|
522
548
|
}
|
|
523
549
|
);
|
|
550
|
+
const CreditInsufficientDialog = state.creditInsufficientInfo && /* @__PURE__ */ jsx(
|
|
551
|
+
ConfirmDialog,
|
|
552
|
+
{
|
|
553
|
+
onConfirm: handleCreditInsufficientClose,
|
|
554
|
+
onCancel: handleCreditInsufficientClose,
|
|
555
|
+
title: t("payment.checkout.fastPay.credit.insufficientTitle"),
|
|
556
|
+
message: /* @__PURE__ */ jsx(Typography, { children: t("payment.checkout.fastPay.credit.insufficientMessage") }),
|
|
557
|
+
confirm: t("common.confirm")
|
|
558
|
+
}
|
|
559
|
+
);
|
|
524
560
|
if (onlyShowBtn) {
|
|
525
561
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
526
562
|
/* @__PURE__ */ jsx(Box, { className: "cko-payment-submit-btn", children: /* @__PURE__ */ jsxs(
|
|
@@ -573,7 +609,8 @@ export default function PaymentForm({
|
|
|
573
609
|
}
|
|
574
610
|
}
|
|
575
611
|
),
|
|
576
|
-
FastCheckoutConfirmDialog
|
|
612
|
+
FastCheckoutConfirmDialog,
|
|
613
|
+
CreditInsufficientDialog
|
|
577
614
|
] });
|
|
578
615
|
}
|
|
579
616
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -768,6 +805,7 @@ export default function PaymentForm({
|
|
|
768
805
|
}
|
|
769
806
|
}
|
|
770
807
|
),
|
|
771
|
-
FastCheckoutConfirmDialog
|
|
808
|
+
FastCheckoutConfirmDialog,
|
|
809
|
+
CreditInsufficientDialog
|
|
772
810
|
] });
|
|
773
811
|
}
|
package/es/payment/index.js
CHANGED
|
@@ -18,7 +18,8 @@ import {
|
|
|
18
18
|
getQueryParams,
|
|
19
19
|
getStatementDescriptor,
|
|
20
20
|
isMobileSafari,
|
|
21
|
-
isValidCountry
|
|
21
|
+
isValidCountry,
|
|
22
|
+
showStaking
|
|
22
23
|
} from "../libs/util.js";
|
|
23
24
|
import PaymentError from "./error.js";
|
|
24
25
|
import CheckoutFooter from "./footer.js";
|
|
@@ -166,6 +167,18 @@ function PaymentInner({
|
|
|
166
167
|
Toast.error(formatError(err));
|
|
167
168
|
}
|
|
168
169
|
};
|
|
170
|
+
const onQuantityChange = async (itemId, quantity) => {
|
|
171
|
+
try {
|
|
172
|
+
const { data } = await api.put(`/api/checkout-sessions/${state.checkoutSession.id}/adjust-quantity`, {
|
|
173
|
+
itemId,
|
|
174
|
+
quantity
|
|
175
|
+
});
|
|
176
|
+
setState({ checkoutSession: data });
|
|
177
|
+
} catch (err) {
|
|
178
|
+
console.error(err);
|
|
179
|
+
Toast.error(formatError(err));
|
|
180
|
+
}
|
|
181
|
+
};
|
|
169
182
|
const onCancelCrossSell = async () => {
|
|
170
183
|
try {
|
|
171
184
|
const { data } = await api.delete(`/api/checkout-sessions/${state.checkoutSession.id}/cross-sell`);
|
|
@@ -211,17 +224,19 @@ function PaymentInner({
|
|
|
211
224
|
// @ts-ignore
|
|
212
225
|
state.checkoutSession.subscription_data?.min_stake_amount || 0
|
|
213
226
|
),
|
|
214
|
-
showStaking: method
|
|
227
|
+
showStaking: showStaking(method, currency, !!state.checkoutSession.subscription_data?.no_stake),
|
|
215
228
|
currency,
|
|
216
229
|
onUpsell,
|
|
217
230
|
onDownsell,
|
|
231
|
+
onQuantityChange,
|
|
218
232
|
onApplyCrossSell,
|
|
219
233
|
onCancelCrossSell,
|
|
220
234
|
onChangeAmount,
|
|
221
235
|
checkoutSessionId: state.checkoutSession.id,
|
|
222
236
|
crossSellBehavior: state.checkoutSession.cross_sell_behavior,
|
|
223
237
|
donationSettings: paymentLink?.donation_settings,
|
|
224
|
-
action
|
|
238
|
+
action,
|
|
239
|
+
completed
|
|
225
240
|
}
|
|
226
241
|
),
|
|
227
242
|
mode === "standalone" && !isMobile && /* @__PURE__ */ jsx(CheckoutFooter, { className: "cko-footer", sx: { color: "text.lighter" } })
|
|
@@ -10,6 +10,13 @@ type Props = {
|
|
|
10
10
|
onDownsell: Function;
|
|
11
11
|
mode?: 'normal' | 'cross-sell';
|
|
12
12
|
children?: React.ReactNode;
|
|
13
|
+
adjustableQuantity?: {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
minimum?: number;
|
|
16
|
+
maximum?: number;
|
|
17
|
+
};
|
|
18
|
+
onQuantityChange?: (itemId: string, quantity: number) => void;
|
|
19
|
+
completed?: boolean;
|
|
13
20
|
};
|
|
14
|
-
export default function ProductItem({ item, items, trialInDays, trialEnd, currency, mode, children, onUpsell, onDownsell, }: Props): JSX.Element;
|
|
21
|
+
export default function ProductItem({ item, items, trialInDays, trialEnd, currency, mode, children, onUpsell, onDownsell, completed, adjustableQuantity, onQuantityChange, }: Props): JSX.Element;
|
|
15
22
|
export {};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
3
|
-
import { Box, Stack, Typography } from "@mui/material";
|
|
4
|
-
import {
|
|
3
|
+
import { Box, Stack, Typography, IconButton, TextField, Alert } from "@mui/material";
|
|
4
|
+
import { Add, Remove } from "@mui/icons-material";
|
|
5
|
+
import { useMemo, useState } from "react";
|
|
5
6
|
import Status from "../components/status.js";
|
|
6
7
|
import Switch from "../components/switch-button.js";
|
|
7
8
|
import {
|
|
9
|
+
findCurrency,
|
|
8
10
|
formatLineItemPricing,
|
|
9
11
|
formatPrice,
|
|
10
12
|
formatQuantityInventory,
|
|
@@ -13,6 +15,7 @@ import {
|
|
|
13
15
|
} from "../libs/util.js";
|
|
14
16
|
import ProductCard from "./product-card.js";
|
|
15
17
|
import dayjs from "../libs/dayjs.js";
|
|
18
|
+
import { usePaymentContext } from "../contexts/payment.js";
|
|
16
19
|
export default function ProductItem({
|
|
17
20
|
item,
|
|
18
21
|
items,
|
|
@@ -22,13 +25,77 @@ export default function ProductItem({
|
|
|
22
25
|
mode = "normal",
|
|
23
26
|
children = null,
|
|
24
27
|
onUpsell,
|
|
25
|
-
onDownsell
|
|
28
|
+
onDownsell,
|
|
29
|
+
completed = false,
|
|
30
|
+
adjustableQuantity = { enabled: false },
|
|
31
|
+
onQuantityChange = () => {
|
|
32
|
+
}
|
|
26
33
|
}) {
|
|
27
34
|
const { t, locale } = useLocaleContext();
|
|
35
|
+
const { settings } = usePaymentContext();
|
|
28
36
|
const pricing = formatLineItemPricing(item, currency, { trialEnd, trialInDays }, locale);
|
|
29
37
|
const saving = formatUpsellSaving(items, currency);
|
|
30
38
|
const metered = item.price?.recurring?.usage_type === "metered" ? t("common.metered") : "";
|
|
31
39
|
const canUpsell = mode === "normal" && items.length === 1;
|
|
40
|
+
const isCreditProduct = item.price.product?.type === "credit" && item.price.metadata?.credit_config?.credit_amount;
|
|
41
|
+
const creditAmount = isCreditProduct ? Number(item.price.metadata.credit_config.credit_amount) : 0;
|
|
42
|
+
const creditCurrency = isCreditProduct ? findCurrency(settings.paymentMethods, item.price.metadata?.credit_config?.currency_id ?? "") : null;
|
|
43
|
+
const validDuration = item.price.metadata?.credit_config?.valid_duration_value;
|
|
44
|
+
const validDurationUnit = item.price.metadata?.credit_config?.valid_duration_unit || "days";
|
|
45
|
+
const [localQuantity, setLocalQuantity] = useState(item.quantity);
|
|
46
|
+
const canAdjustQuantity = adjustableQuantity.enabled && mode === "normal";
|
|
47
|
+
const minQuantity = Math.max(adjustableQuantity.minimum || 1, 1);
|
|
48
|
+
const quantityAvailable = Math.min(item.price.quantity_limit_per_checkout, item.price.quantity_available);
|
|
49
|
+
const maxQuantity = Math.min(adjustableQuantity.maximum || 999, quantityAvailable || 999);
|
|
50
|
+
const handleQuantityChange = (newQuantity) => {
|
|
51
|
+
if (newQuantity >= minQuantity && newQuantity <= maxQuantity) {
|
|
52
|
+
setLocalQuantity(newQuantity);
|
|
53
|
+
if (formatQuantityInventory(item.price, newQuantity, locale)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
onQuantityChange(item.price_id, newQuantity);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const handleQuantityIncrease = () => {
|
|
60
|
+
if (localQuantity < maxQuantity) {
|
|
61
|
+
handleQuantityChange(localQuantity + 1);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const handleQuantityDecrease = () => {
|
|
65
|
+
if (localQuantity > minQuantity) {
|
|
66
|
+
handleQuantityChange(localQuantity - 1);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const handleQuantityInputChange = (event) => {
|
|
70
|
+
const value = parseInt(event.target.value, 10);
|
|
71
|
+
if (!Number.isNaN(value)) {
|
|
72
|
+
handleQuantityChange(value);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const formatCreditInfo = () => {
|
|
76
|
+
if (!isCreditProduct) return null;
|
|
77
|
+
const isRecurring = item.price.type === "recurring";
|
|
78
|
+
const totalCredit = creditAmount * localQuantity;
|
|
79
|
+
let message = "";
|
|
80
|
+
if (isRecurring) {
|
|
81
|
+
message = t("payment.checkout.credit.recurringInfo", {
|
|
82
|
+
amount: totalCredit,
|
|
83
|
+
period: formatRecurring(item.price.recurring, true, "per", locale)
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
message = t("payment.checkout.credit.oneTimeInfo", {
|
|
87
|
+
amount: totalCredit,
|
|
88
|
+
symbol: creditCurrency?.symbol || "Credits"
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (validDuration && validDuration > 0) {
|
|
92
|
+
message += `\uFF0C${t("payment.checkout.credit.expiresIn", {
|
|
93
|
+
duration: validDuration,
|
|
94
|
+
unit: t(`common.${validDurationUnit}`)
|
|
95
|
+
})}`;
|
|
96
|
+
}
|
|
97
|
+
return message;
|
|
98
|
+
};
|
|
32
99
|
const primaryText = useMemo(() => {
|
|
33
100
|
const price = item.upsell_price || item.price || {};
|
|
34
101
|
const isRecurring = price?.type === "recurring" && price?.recurring;
|
|
@@ -38,6 +105,7 @@ export default function ProductItem({
|
|
|
38
105
|
}
|
|
39
106
|
return pricing.primary;
|
|
40
107
|
}, [trialInDays, trialEnd, pricing, item, locale]);
|
|
108
|
+
const quantityInventoryError = formatQuantityInventory(item.price, localQuantity, locale);
|
|
41
109
|
return /* @__PURE__ */ jsxs(
|
|
42
110
|
Stack,
|
|
43
111
|
{
|
|
@@ -105,10 +173,10 @@ export default function ProductItem({
|
|
|
105
173
|
]
|
|
106
174
|
}
|
|
107
175
|
),
|
|
108
|
-
|
|
176
|
+
quantityInventoryError ? /* @__PURE__ */ jsx(
|
|
109
177
|
Status,
|
|
110
178
|
{
|
|
111
|
-
label:
|
|
179
|
+
label: quantityInventoryError,
|
|
112
180
|
variant: "outlined",
|
|
113
181
|
sx: {
|
|
114
182
|
mt: 1,
|
|
@@ -118,6 +186,70 @@ export default function ProductItem({
|
|
|
118
186
|
}
|
|
119
187
|
}
|
|
120
188
|
) : null,
|
|
189
|
+
canAdjustQuantity && !completed && /* @__PURE__ */ jsx(Box, { sx: { mt: 1, p: 1 }, children: /* @__PURE__ */ jsxs(
|
|
190
|
+
Stack,
|
|
191
|
+
{
|
|
192
|
+
direction: "row",
|
|
193
|
+
spacing: 1,
|
|
194
|
+
sx: {
|
|
195
|
+
alignItems: "center"
|
|
196
|
+
},
|
|
197
|
+
children: [
|
|
198
|
+
/* @__PURE__ */ jsxs(
|
|
199
|
+
Typography,
|
|
200
|
+
{
|
|
201
|
+
variant: "body2",
|
|
202
|
+
sx: {
|
|
203
|
+
color: "text.secondary",
|
|
204
|
+
minWidth: "fit-content"
|
|
205
|
+
},
|
|
206
|
+
children: [
|
|
207
|
+
t("common.quantity"),
|
|
208
|
+
":"
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
),
|
|
212
|
+
/* @__PURE__ */ jsx(
|
|
213
|
+
IconButton,
|
|
214
|
+
{
|
|
215
|
+
size: "small",
|
|
216
|
+
onClick: handleQuantityDecrease,
|
|
217
|
+
disabled: localQuantity <= minQuantity,
|
|
218
|
+
sx: { minWidth: 32, width: 32, height: 32 },
|
|
219
|
+
children: /* @__PURE__ */ jsx(Remove, { fontSize: "small" })
|
|
220
|
+
}
|
|
221
|
+
),
|
|
222
|
+
/* @__PURE__ */ jsx(
|
|
223
|
+
TextField,
|
|
224
|
+
{
|
|
225
|
+
size: "small",
|
|
226
|
+
value: localQuantity,
|
|
227
|
+
onChange: handleQuantityInputChange,
|
|
228
|
+
sx: { width: 60 },
|
|
229
|
+
type: "number",
|
|
230
|
+
slotProps: {
|
|
231
|
+
htmlInput: {
|
|
232
|
+
min: minQuantity,
|
|
233
|
+
max: maxQuantity,
|
|
234
|
+
style: { textAlign: "center", padding: "4px" }
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
),
|
|
239
|
+
/* @__PURE__ */ jsx(
|
|
240
|
+
IconButton,
|
|
241
|
+
{
|
|
242
|
+
size: "small",
|
|
243
|
+
onClick: handleQuantityIncrease,
|
|
244
|
+
disabled: localQuantity >= maxQuantity,
|
|
245
|
+
sx: { minWidth: 32, width: 32, height: 32 },
|
|
246
|
+
children: /* @__PURE__ */ jsx(Add, { fontSize: "small" })
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
) }),
|
|
252
|
+
isCreditProduct && /* @__PURE__ */ jsx(Alert, { severity: "info", sx: { mt: 1, fontSize: "0.875rem" }, icon: false, children: formatCreditInfo() }),
|
|
121
253
|
children
|
|
122
254
|
]
|
|
123
255
|
}
|
package/es/payment/summary.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ type Props = {
|
|
|
8
8
|
showStaking?: boolean;
|
|
9
9
|
onUpsell?: Function;
|
|
10
10
|
onDownsell?: Function;
|
|
11
|
+
onQuantityChange?: Function;
|
|
11
12
|
onChangeAmount?: Function;
|
|
12
13
|
onApplyCrossSell?: Function;
|
|
13
14
|
onCancelCrossSell?: Function;
|
|
@@ -15,6 +16,7 @@ type Props = {
|
|
|
15
16
|
crossSellBehavior?: string;
|
|
16
17
|
donationSettings?: DonationSettings;
|
|
17
18
|
action?: string;
|
|
19
|
+
completed?: boolean;
|
|
18
20
|
};
|
|
19
|
-
export default function PaymentSummary({ items, currency, trialInDays, billingThreshold, onUpsell, onDownsell, onApplyCrossSell, onCancelCrossSell, onChangeAmount, checkoutSessionId, crossSellBehavior, showStaking, donationSettings, action, trialEnd, ...rest }: Props): import("react").JSX.Element;
|
|
21
|
+
export default function PaymentSummary({ items, currency, trialInDays, billingThreshold, onUpsell, onDownsell, onQuantityChange, onApplyCrossSell, onCancelCrossSell, onChangeAmount, checkoutSessionId, crossSellBehavior, showStaking, donationSettings, action, trialEnd, completed, ...rest }: Props): import("react").JSX.Element;
|
|
20
22
|
export {};
|
package/es/payment/summary.js
CHANGED
|
@@ -73,6 +73,7 @@ export default function PaymentSummary({
|
|
|
73
73
|
billingThreshold,
|
|
74
74
|
onUpsell = noop,
|
|
75
75
|
onDownsell = noop,
|
|
76
|
+
onQuantityChange = noop,
|
|
76
77
|
onApplyCrossSell = noop,
|
|
77
78
|
onCancelCrossSell = noop,
|
|
78
79
|
onChangeAmount = noop,
|
|
@@ -82,6 +83,7 @@ export default function PaymentSummary({
|
|
|
82
83
|
donationSettings = void 0,
|
|
83
84
|
action = "",
|
|
84
85
|
trialEnd = 0,
|
|
86
|
+
completed = false,
|
|
85
87
|
...rest
|
|
86
88
|
}) {
|
|
87
89
|
const { t, locale } = useLocaleContext();
|
|
@@ -111,6 +113,10 @@ export default function PaymentSummary({
|
|
|
111
113
|
await onUpsell(from, to);
|
|
112
114
|
runAsync();
|
|
113
115
|
};
|
|
116
|
+
const handleQuantityChange = async (itemId, quantity) => {
|
|
117
|
+
await onQuantityChange(itemId, quantity);
|
|
118
|
+
runAsync();
|
|
119
|
+
};
|
|
114
120
|
const handleDownsell = async (from) => {
|
|
115
121
|
await onDownsell(from);
|
|
116
122
|
runAsync();
|
|
@@ -166,6 +172,9 @@ export default function PaymentSummary({
|
|
|
166
172
|
currency,
|
|
167
173
|
onUpsell: handleUpsell,
|
|
168
174
|
onDownsell: handleDownsell,
|
|
175
|
+
adjustableQuantity: x.adjustable_quantity,
|
|
176
|
+
completed,
|
|
177
|
+
onQuantityChange: handleQuantityChange,
|
|
169
178
|
children: x.cross_sell && /* @__PURE__ */ jsxs(
|
|
170
179
|
Stack,
|
|
171
180
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PaymentDetails, TPaymentMethod } from '@blocklet/payment-types';
|
|
2
|
-
export default function TxLink(
|
|
2
|
+
export default function TxLink({ details, method, mode, align, }: {
|
|
3
3
|
details: PaymentDetails;
|
|
4
4
|
method: TPaymentMethod;
|
|
5
5
|
mode?: 'customer' | 'dashboard';
|
|
@@ -10,15 +10,16 @@ var _iconsMaterial = require("@mui/icons-material");
|
|
|
10
10
|
var _material = require("@mui/material");
|
|
11
11
|
var _system = require("@mui/system");
|
|
12
12
|
var _util = require("../../libs/util");
|
|
13
|
-
function TxLink(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
function TxLink({
|
|
14
|
+
details,
|
|
15
|
+
method,
|
|
16
|
+
mode = "dashboard",
|
|
17
|
+
align = "left"
|
|
18
|
+
}) {
|
|
18
19
|
const {
|
|
19
20
|
t
|
|
20
21
|
} = (0, _context.useLocaleContext)();
|
|
21
|
-
if (!
|
|
22
|
+
if (!details || mode === "customer" && method.type === "stripe") {
|
|
22
23
|
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
23
24
|
component: "small",
|
|
24
25
|
sx: {
|
|
@@ -30,7 +31,7 @@ function TxLink(rawProps) {
|
|
|
30
31
|
const {
|
|
31
32
|
text,
|
|
32
33
|
link
|
|
33
|
-
} = (0, _util.getTxLink)(
|
|
34
|
+
} = (0, _util.getTxLink)(method, details);
|
|
34
35
|
if (link && text) {
|
|
35
36
|
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Link, {
|
|
36
37
|
href: link,
|
|
@@ -39,7 +40,7 @@ function TxLink(rawProps) {
|
|
|
39
40
|
children: /* @__PURE__ */(0, _jsxRuntime.jsxs)(Root, {
|
|
40
41
|
direction: "row",
|
|
41
42
|
alignItems: "center",
|
|
42
|
-
justifyContent:
|
|
43
|
+
justifyContent: align === "left" ? "flex-start" : "flex-end",
|
|
43
44
|
sx: {
|
|
44
45
|
color: "text.link"
|
|
45
46
|
},
|
|
@@ -8,5 +8,5 @@ export type CountrySelectProps = {
|
|
|
8
8
|
showDialCode?: boolean;
|
|
9
9
|
};
|
|
10
10
|
export default function CountrySelect({ ref, value, onChange, name, sx, showDialCode, }: CountrySelectProps & {
|
|
11
|
-
ref?: React.RefObject<HTMLDivElement>;
|
|
11
|
+
ref?: React.RefObject<HTMLDivElement | null>;
|
|
12
12
|
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface DateRangeValue {
|
|
2
|
+
start: number | undefined;
|
|
3
|
+
end: number | undefined;
|
|
4
|
+
}
|
|
5
|
+
export interface DateRangePickerProps {
|
|
6
|
+
value: DateRangeValue;
|
|
7
|
+
onChange: (value: DateRangeValue) => void;
|
|
8
|
+
label?: string;
|
|
9
|
+
size?: 'small' | 'medium';
|
|
10
|
+
fullWidth?: boolean;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export default function DateRangePicker({ value, onChange, label, size, fullWidth, disabled, }: DateRangePickerProps): import("react").JSX.Element;
|