@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.
Files changed (73) hide show
  1. package/es/components/blockchain/tx.d.ts +1 -1
  2. package/es/components/blockchain/tx.js +9 -11
  3. package/es/components/country-select.d.ts +1 -1
  4. package/es/components/date-range-picker.d.ts +13 -0
  5. package/es/components/date-range-picker.js +279 -0
  6. package/es/components/input.d.ts +5 -2
  7. package/es/components/input.js +6 -2
  8. package/es/components/label.d.ts +7 -0
  9. package/es/components/label.js +49 -0
  10. package/es/components/loading-button.d.ts +1 -1
  11. package/es/history/credit/grants-list.d.ts +14 -0
  12. package/es/history/credit/grants-list.js +215 -0
  13. package/es/history/credit/transactions-list.d.ts +13 -0
  14. package/es/history/credit/transactions-list.js +255 -0
  15. package/es/history/invoice/list.js +21 -1
  16. package/es/index.d.ts +5 -1
  17. package/es/index.js +10 -1
  18. package/es/libs/util.d.ts +2 -0
  19. package/es/libs/util.js +12 -0
  20. package/es/locales/en.js +20 -2
  21. package/es/locales/zh.js +20 -2
  22. package/es/payment/form/index.js +44 -6
  23. package/es/payment/index.js +18 -3
  24. package/es/payment/product-item.d.ts +8 -1
  25. package/es/payment/product-item.js +137 -5
  26. package/es/payment/summary.d.ts +3 -1
  27. package/es/payment/summary.js +9 -0
  28. package/lib/components/blockchain/tx.d.ts +1 -1
  29. package/lib/components/blockchain/tx.js +9 -8
  30. package/lib/components/country-select.d.ts +1 -1
  31. package/lib/components/date-range-picker.d.ts +13 -0
  32. package/lib/components/date-range-picker.js +329 -0
  33. package/lib/components/input.d.ts +5 -2
  34. package/lib/components/input.js +8 -4
  35. package/lib/components/label.d.ts +7 -0
  36. package/lib/components/label.js +60 -0
  37. package/lib/components/loading-button.d.ts +1 -1
  38. package/lib/history/credit/grants-list.d.ts +14 -0
  39. package/lib/history/credit/grants-list.js +277 -0
  40. package/lib/history/credit/transactions-list.d.ts +13 -0
  41. package/lib/history/credit/transactions-list.js +301 -0
  42. package/lib/history/invoice/list.js +24 -0
  43. package/lib/index.d.ts +5 -1
  44. package/lib/index.js +39 -0
  45. package/lib/libs/util.d.ts +2 -0
  46. package/lib/libs/util.js +14 -0
  47. package/lib/locales/en.js +20 -2
  48. package/lib/locales/zh.js +20 -2
  49. package/lib/payment/form/index.js +45 -6
  50. package/lib/payment/index.js +20 -2
  51. package/lib/payment/product-item.d.ts +8 -1
  52. package/lib/payment/product-item.js +144 -4
  53. package/lib/payment/summary.d.ts +3 -1
  54. package/lib/payment/summary.js +9 -0
  55. package/package.json +3 -3
  56. package/src/components/blockchain/tx.tsx +9 -15
  57. package/src/components/country-select.tsx +2 -2
  58. package/src/components/date-range-picker.tsx +310 -0
  59. package/src/components/input.tsx +14 -3
  60. package/src/components/label.tsx +58 -0
  61. package/src/components/loading-button.tsx +1 -1
  62. package/src/history/credit/grants-list.tsx +276 -0
  63. package/src/history/credit/transactions-list.tsx +317 -0
  64. package/src/history/invoice/list.tsx +18 -1
  65. package/src/index.ts +9 -0
  66. package/src/libs/util.ts +14 -0
  67. package/src/locales/en.tsx +20 -0
  68. package/src/locales/zh.tsx +19 -0
  69. package/src/payment/form/address.tsx +2 -2
  70. package/src/payment/form/index.tsx +110 -52
  71. package/src/payment/index.tsx +17 -1
  72. package/src/payment/product-item.tsx +152 -4
  73. 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: {
@@ -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 ((result.data.balance?.sufficient || result.data.delegation?.sufficient) && !isDonationMode && result.data.fastPayInfo) {
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__ */ jsxs(Stack, { children: [
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
  }
@@ -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.type === "arcblock" && !state.checkoutSession.subscription_data?.no_stake,
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 { useMemo } from "react";
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
- formatQuantityInventory(item.price, item.quantity, locale) ? /* @__PURE__ */ jsx(
176
+ quantityInventoryError ? /* @__PURE__ */ jsx(
109
177
  Status,
110
178
  {
111
- label: formatQuantityInventory(item.price, item.quantity, locale),
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
  }
@@ -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 {};
@@ -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(rawProps: {
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(rawProps) {
14
- const props = Object.assign({
15
- mode: "dashboard",
16
- align: "left"
17
- }, rawProps);
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 (!props.details || props.mode === "customer" && props.method.type === "stripe") {
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)(props.method, props.details);
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: props.align === "left" ? "flex-start" : "flex-end",
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;