@blocklet/payment-react 1.14.21 → 1.14.23

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 (137) hide show
  1. package/README.md +77 -0
  2. package/es/checkout/donate.d.ts +4 -2
  3. package/es/checkout/donate.js +13 -10
  4. package/es/checkout/form.d.ts +1 -1
  5. package/es/checkout/form.js +50 -4
  6. package/es/checkout/table.d.ts +1 -1
  7. package/es/checkout/table.js +11 -1
  8. package/es/components/blockchain/tx.js +2 -1
  9. package/es/components/country-select.d.ts +16 -0
  10. package/es/components/country-select.js +82 -0
  11. package/es/components/input.d.ts +21 -21
  12. package/es/components/input.js +43 -42
  13. package/es/components/livemode.js +1 -0
  14. package/es/components/pricing-table.js +0 -2
  15. package/es/components/status.js +2 -3
  16. package/es/components/table.d.ts +2 -0
  17. package/es/components/table.js +186 -0
  18. package/es/contexts/payment.d.ts +2 -0
  19. package/es/contexts/payment.js +5 -2
  20. package/es/history/invoice/list.d.ts +3 -1
  21. package/es/history/invoice/list.js +215 -48
  22. package/es/hooks/mobile.d.ts +4 -0
  23. package/es/hooks/mobile.js +10 -0
  24. package/es/index.d.ts +5 -1
  25. package/es/index.js +7 -1
  26. package/es/libs/util.d.ts +21 -8
  27. package/es/libs/util.js +92 -28
  28. package/es/locales/en.js +22 -7
  29. package/es/locales/index.d.ts +0 -1
  30. package/es/locales/index.js +10 -1
  31. package/es/locales/zh.js +21 -6
  32. package/es/payment/error.js +2 -2
  33. package/es/payment/footer.js +1 -1
  34. package/es/payment/form/address.d.ts +9 -2
  35. package/es/payment/form/address.js +69 -69
  36. package/es/payment/form/currency.js +39 -25
  37. package/es/payment/form/index.d.ts +1 -1
  38. package/es/payment/form/index.js +83 -81
  39. package/es/payment/form/phone.js +15 -51
  40. package/es/payment/index.d.ts +3 -10
  41. package/es/payment/index.js +295 -224
  42. package/es/payment/product-card.js +4 -4
  43. package/es/payment/product-donation.js +9 -3
  44. package/es/payment/product-item.d.ts +2 -2
  45. package/es/payment/product-item.js +120 -81
  46. package/es/payment/summary.js +188 -118
  47. package/es/theme/index.css +240 -0
  48. package/es/theme/index.d.ts +14 -0
  49. package/es/theme/index.js +256 -0
  50. package/es/theme/typography.d.ts +2 -0
  51. package/es/theme/typography.js +53 -0
  52. package/es/types/index.d.ts +16 -0
  53. package/lib/checkout/donate.d.ts +4 -2
  54. package/lib/checkout/donate.js +23 -2
  55. package/lib/checkout/form.d.ts +1 -1
  56. package/lib/checkout/form.js +60 -15
  57. package/lib/checkout/table.d.ts +1 -1
  58. package/lib/checkout/table.js +22 -1
  59. package/lib/components/blockchain/tx.js +4 -1
  60. package/lib/components/country-select.d.ts +16 -0
  61. package/lib/components/country-select.js +115 -0
  62. package/lib/components/input.d.ts +21 -21
  63. package/lib/components/input.js +21 -12
  64. package/lib/components/livemode.js +1 -0
  65. package/lib/components/pricing-table.js +0 -2
  66. package/lib/components/status.js +2 -3
  67. package/lib/components/table.d.ts +2 -0
  68. package/lib/components/table.js +220 -0
  69. package/lib/contexts/payment.d.ts +2 -0
  70. package/lib/contexts/payment.js +4 -1
  71. package/lib/history/invoice/list.d.ts +3 -1
  72. package/lib/history/invoice/list.js +290 -62
  73. package/lib/hooks/mobile.d.ts +4 -0
  74. package/lib/hooks/mobile.js +17 -0
  75. package/lib/index.d.ts +5 -1
  76. package/lib/index.js +36 -0
  77. package/lib/libs/util.d.ts +21 -8
  78. package/lib/libs/util.js +115 -37
  79. package/lib/locales/en.js +22 -7
  80. package/lib/locales/index.d.ts +0 -1
  81. package/lib/locales/index.js +14 -3
  82. package/lib/locales/zh.js +21 -6
  83. package/lib/payment/error.js +5 -1
  84. package/lib/payment/footer.js +1 -1
  85. package/lib/payment/form/address.d.ts +9 -2
  86. package/lib/payment/form/address.js +67 -59
  87. package/lib/payment/form/currency.js +31 -24
  88. package/lib/payment/form/index.d.ts +1 -1
  89. package/lib/payment/form/index.js +92 -93
  90. package/lib/payment/form/phone.js +11 -59
  91. package/lib/payment/index.d.ts +3 -10
  92. package/lib/payment/index.js +302 -225
  93. package/lib/payment/product-card.js +5 -4
  94. package/lib/payment/product-donation.js +11 -7
  95. package/lib/payment/product-item.d.ts +2 -2
  96. package/lib/payment/product-item.js +38 -19
  97. package/lib/payment/summary.js +219 -127
  98. package/lib/theme/index.css +240 -0
  99. package/lib/theme/index.d.ts +14 -0
  100. package/lib/theme/index.js +273 -0
  101. package/lib/theme/typography.d.ts +2 -0
  102. package/lib/theme/typography.js +59 -0
  103. package/lib/types/index.d.ts +16 -0
  104. package/package.json +14 -11
  105. package/src/checkout/donate.tsx +25 -11
  106. package/src/checkout/form.tsx +63 -15
  107. package/src/checkout/table.tsx +20 -1
  108. package/src/components/blockchain/tx.tsx +2 -1
  109. package/src/components/country-select.tsx +93 -0
  110. package/src/components/input.tsx +49 -46
  111. package/src/components/livemode.tsx +1 -0
  112. package/src/components/pricing-table.tsx +0 -2
  113. package/src/components/status.tsx +1 -2
  114. package/src/components/table.tsx +200 -0
  115. package/src/contexts/payment.tsx +6 -1
  116. package/src/history/invoice/list.tsx +254 -49
  117. package/src/hooks/mobile.ts +13 -0
  118. package/src/index.ts +7 -0
  119. package/src/libs/util.ts +120 -31
  120. package/src/locales/en.tsx +18 -4
  121. package/src/locales/index.tsx +10 -3
  122. package/src/locales/zh.tsx +17 -3
  123. package/src/payment/error.tsx +2 -2
  124. package/src/payment/footer.tsx +1 -1
  125. package/src/payment/form/address.tsx +56 -47
  126. package/src/payment/form/currency.tsx +29 -23
  127. package/src/payment/form/index.tsx +89 -76
  128. package/src/payment/form/phone.tsx +14 -51
  129. package/src/payment/index.tsx +298 -231
  130. package/src/payment/product-card.tsx +4 -4
  131. package/src/payment/product-donation.tsx +9 -4
  132. package/src/payment/product-item.tsx +49 -20
  133. package/src/payment/summary.tsx +191 -108
  134. package/src/theme/index.css +240 -0
  135. package/src/theme/index.tsx +271 -0
  136. package/src/theme/typography.ts +56 -0
  137. package/src/types/index.ts +17 -0
package/src/libs/util.ts CHANGED
@@ -24,7 +24,7 @@ import { joinURL } from 'ufo';
24
24
 
25
25
  import { t } from '../locales';
26
26
  import dayjs from './dayjs';
27
- import { PricingRenderProps } from '../types';
27
+ import { ActionProps, PricingRenderProps } from '../types';
28
28
 
29
29
  export const PAYMENT_KIT_DID = 'z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk';
30
30
 
@@ -533,6 +533,32 @@ export function formatUpsellSaving(items: TLineItemExpanded[], currency: TPaymen
533
533
  return Number(before.sub(after).mul(new BN(100)).div(before).toString()).toFixed(0);
534
534
  }
535
535
 
536
+ export function formatMeteredThen(
537
+ subscription: string,
538
+ recurring: string,
539
+ hasMetered: boolean,
540
+ locale: string = 'en'
541
+ ): string {
542
+ if (hasMetered) {
543
+ return t('payment.checkout.meteredThen', locale, { subscription, recurring });
544
+ }
545
+ return t('payment.checkout.then', locale, { subscription, recurring });
546
+ }
547
+
548
+ export function formatPriceDisplay(
549
+ { amount, then, actualAmount, showThen }: { amount: string; then?: string; actualAmount: string; showThen?: boolean },
550
+ recurring: string,
551
+ hasMetered: boolean,
552
+ locale: string = 'en'
553
+ ) {
554
+ if (Number(actualAmount) === 0 && hasMetered) {
555
+ return t('payment.checkout.metered', locale, { recurring });
556
+ }
557
+ if (showThen) {
558
+ return [amount, then].filter(Boolean).join(', ');
559
+ }
560
+ return [amount, then].filter(Boolean).join(' ');
561
+ }
536
562
  export function formatCheckoutHeadlines(
537
563
  items: TLineItemExpanded[],
538
564
  currency: TPaymentCurrency,
@@ -543,9 +569,13 @@ export function formatCheckoutHeadlines(
543
569
  amount: string;
544
570
  then?: string;
545
571
  secondary?: string;
572
+ showThen?: boolean;
573
+ actualAmount: string;
574
+ priceDisplay: string;
546
575
  } {
547
576
  const brand = getStatementDescriptor(items);
548
577
  const { total } = getCheckoutAmount(items, currency, trialInDays > 0);
578
+ const actualAmount = fromUnitToToken(total, currency.decimal);
549
579
  const amount = `${fromUnitToToken(total, currency.decimal)} ${currency.symbol}`;
550
580
 
551
581
  // empty
@@ -554,6 +584,8 @@ export function formatCheckoutHeadlines(
554
584
  action: t('payment.checkout.empty', locale),
555
585
  amount: '0',
556
586
  then: '',
587
+ actualAmount: '0',
588
+ priceDisplay: '0',
557
589
  };
558
590
  }
559
591
 
@@ -563,10 +595,10 @@ export function formatCheckoutHeadlines(
563
595
  if (items.every((x) => x.price.type === 'one_time')) {
564
596
  const action = t('payment.checkout.pay', locale, { payee: brand });
565
597
  if (items.length > 1) {
566
- return { action, amount };
598
+ return { action, amount, actualAmount, priceDisplay: amount };
567
599
  }
568
600
 
569
- return { action, amount, then: '' };
601
+ return { action, amount, then: '', actualAmount, priceDisplay: amount };
570
602
  }
571
603
 
572
604
  const item = items.find((x) => x.price.type === 'recurring');
@@ -576,10 +608,9 @@ export function formatCheckoutHeadlines(
576
608
  'per',
577
609
  locale
578
610
  );
579
-
611
+ const hasMetered = items.some((x) => x.price.type === 'recurring' && x.price.recurring?.usage_type === 'metered');
580
612
  // all recurring
581
613
  if (items.every((x) => x.price.type === 'recurring')) {
582
- const hasMetered = items.some((x) => x.price.type === 'recurring' && x.price.recurring?.usage_type === 'metered');
583
614
  const subscription = [
584
615
  hasMetered ? t('payment.checkout.least', locale) : '',
585
616
  fromUnitToToken(
@@ -597,32 +628,54 @@ export function formatCheckoutHeadlines(
597
628
  .join(' ');
598
629
  if (items.length > 1) {
599
630
  if (trialInDays > 0) {
600
- return {
631
+ const result = {
601
632
  action: t('payment.checkout.try2', locale, { name, count: items.length - 1 }),
602
633
  amount: t('payment.checkout.free', locale, { count: trialInDays }),
603
- then: t('payment.checkout.then', locale, { subscription, recurring }),
634
+ then: formatMeteredThen(subscription, recurring, hasMetered && Number(subscription) === 0, locale),
635
+ showThen: true,
636
+ actualAmount: '0',
637
+ };
638
+ return {
639
+ ...result,
640
+ priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
604
641
  };
605
642
  }
606
-
607
- return {
643
+ const result = {
608
644
  action: t('payment.checkout.sub2', locale, { name, count: items.length - 1 }),
609
645
  amount,
610
- then: recurring,
646
+ then: hasMetered ? t('payment.checkout.meteredThen', locale, { recurring }) : recurring,
647
+ showThen: hasMetered,
648
+ actualAmount,
649
+ };
650
+ return {
651
+ ...result,
652
+ priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
611
653
  };
612
654
  }
613
655
 
614
656
  if (trialInDays > 0) {
615
- return {
657
+ const result = {
616
658
  action: t('payment.checkout.try1', locale, { name }),
617
659
  amount: t('payment.checkout.free', locale, { count: trialInDays }),
618
- then: t('payment.checkout.then', locale, { subscription, recurring }),
660
+ then: formatMeteredThen(subscription, recurring, hasMetered && Number(subscription) === 0, locale),
661
+ showThen: true,
662
+ actualAmount: '0',
663
+ };
664
+ return {
665
+ ...result,
666
+ priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
619
667
  };
620
668
  }
621
-
622
- return {
669
+ const result = {
623
670
  action: t('payment.checkout.sub1', locale, { name }),
624
671
  amount,
625
- then: recurring,
672
+ then: hasMetered ? t('payment.checkout.meteredThen', locale, { recurring }) : recurring,
673
+ showThen: hasMetered,
674
+ actualAmount,
675
+ };
676
+ return {
677
+ ...result,
678
+ priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
626
679
  };
627
680
  }
628
681
 
@@ -639,10 +692,22 @@ export function formatCheckoutHeadlines(
639
692
  currency.decimal
640
693
  );
641
694
 
642
- return {
695
+ const result = {
643
696
  action: t('payment.checkout.pay', locale, { payee: brand }),
644
697
  amount,
645
- then: t('payment.checkout.then', locale, { subscription: `${subscription} ${currency.symbol}`, recurring }),
698
+ then: formatMeteredThen(
699
+ `${subscription} ${currency.symbol}`,
700
+ recurring,
701
+ hasMetered && Number(subscription) === 0,
702
+ locale
703
+ ),
704
+ showThen: true,
705
+ actualAmount,
706
+ };
707
+
708
+ return {
709
+ ...result,
710
+ priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
646
711
  };
647
712
  }
648
713
 
@@ -690,48 +755,65 @@ export function formatSubscriptionProduct(items: TSubscriptionItemExpanded[], ma
690
755
  }
691
756
 
692
757
  export const getSubscriptionTimeSummary = (subscription: TSubscriptionExpanded) => {
693
- const lines = [`Started on ${formatToDate(subscription.start_date * 1000)}`];
758
+ const lines = [`Start on ${formatToDate(subscription.start_date * 1000, 'en', 'YYYY-MM-DD')}`];
759
+
760
+ const getLineTimeMessage = (time: number) => {
761
+ const curDay = dayjs().isSame(dayjs(time), 'day');
762
+ const timeFormat = curDay ? 'HH:mm:ss' : 'YYYY-MM-DD';
763
+ return `${curDay ? 'in' : 'on'} ${formatToDate(time, 'en', timeFormat)}`;
764
+ };
765
+
694
766
  if (subscription.status === 'active' || subscription.status === 'trialing') {
695
767
  if (subscription.cancel_at) {
696
- lines.push(`will cancel on ${formatToDate(subscription.cancel_at * 1000)}`);
768
+ lines.push(`Ended ${getLineTimeMessage(subscription.cancel_at * 1000)}`);
697
769
  } else if (subscription.cancel_at_period_end) {
698
- lines.push(`will cancel on ${formatToDate(subscription.current_period_end * 1000)}`);
770
+ lines.push(`Ended ${getLineTimeMessage(subscription.current_period_end * 1000)}`);
699
771
  } else {
700
- lines.push(`will renew on ${formatToDate(subscription.current_period_end * 1000)}`);
772
+ lines.push(`Renew ${getLineTimeMessage(subscription.current_period_end * 1000)}`);
701
773
  }
702
774
  } else if (subscription.status === 'past_due') {
703
- lines.push(`will cancel on ${formatToDate((subscription.cancel_at || subscription.current_period_end) * 1000)}`);
775
+ lines.push(`Ended ${getLineTimeMessage((subscription.cancel_at || subscription.current_period_end) * 1000)}`);
704
776
  } else if (subscription.status === 'canceled') {
705
- lines.push(`canceled on ${formatToDate(subscription.canceled_at * 1000)}`);
777
+ lines.push(`Ended ${getLineTimeMessage(subscription.canceled_at * 1000)}`);
706
778
  }
707
779
 
708
- return lines.join(', ');
780
+ return lines.join(',');
709
781
  };
710
782
 
711
- export const getSubscriptionAction = (subscription: TSubscriptionExpanded) => {
783
+ export const getSubscriptionAction = (
784
+ subscription: TSubscriptionExpanded,
785
+ actionProps: ActionProps
786
+ ): {
787
+ action: string;
788
+ variant: string;
789
+ color: string;
790
+ canRenew: boolean;
791
+ text?: string;
792
+ sx?: any;
793
+ } | null => {
712
794
  if (subscription.status === 'active' || subscription.status === 'trialing') {
713
795
  if (subscription.cancel_at_period_end) {
714
796
  if (subscription.cancelation_details?.reason === 'payment_failed') {
715
797
  return null;
716
798
  }
717
799
 
718
- return { action: 'recover', variant: 'contained', color: 'primary', canRenew: false };
800
+ return { action: 'recover', variant: 'contained', color: 'primary', canRenew: false, ...actionProps?.recover };
719
801
  }
720
802
 
721
803
  if (subscription.cancel_at && subscription.cancel_at !== subscription.current_period_end) {
722
804
  return null;
723
805
  }
724
806
 
725
- return { action: 'cancel', variant: 'outlined', color: 'inherit', canRenew: false };
807
+ return { action: 'cancel', variant: 'outlined', color: 'inherit', canRenew: false, ...actionProps?.cancel };
726
808
  }
727
809
 
728
810
  if (subscription.status === 'past_due') {
729
811
  const canRenew = subscription.cancel_at && subscription.cancel_at !== subscription.current_period_end;
730
- return { action: 'pastDue', variant: 'contained', color: 'primary', canRenew };
812
+ return { action: 'pastDue', variant: 'contained', color: 'primary', canRenew, ...actionProps?.pastDue };
731
813
  }
732
814
 
733
815
  if (subscription.status !== 'canceled' && subscription.cancel_at_period_end) {
734
- return { action: 'recover', variant: 'contained', color: 'primary', canRenew: false };
816
+ return { action: 'recover', variant: 'contained', color: 'primary', canRenew: false, ...actionProps?.recover };
735
817
  }
736
818
 
737
819
  return null;
@@ -855,9 +937,9 @@ export function formatTotalPrice({
855
937
  const unitValue = new BN(price.custom_unit_amount || price.unit_amount);
856
938
  const currency: TPaymentCurrency = price?.currency ?? {};
857
939
 
858
- const total = `${fromUnitToToken(unitValue.mul(new BN(quantity)), currency.decimal)} ${currency.symbol}`;
940
+ const total = `${fromUnitToToken(unitValue.mul(new BN(quantity)), currency.decimal)} ${currency.symbol} `;
859
941
 
860
- const unit = `${fromUnitToToken(unitValue, currency.decimal)} ${currency.symbol}`;
942
+ const unit = `${fromUnitToToken(unitValue, currency.decimal)} ${currency.symbol} `;
861
943
 
862
944
  const appendUnit = (v: string, alt: string) => {
863
945
  if (product.unit_label) {
@@ -893,6 +975,13 @@ export function formatQuantityInventory(price: TPrice, quantity: string | number
893
975
  return '';
894
976
  }
895
977
 
978
+ export function formatSubscriptionStatus(status: string) {
979
+ if (status === 'canceled') {
980
+ return 'Ended';
981
+ }
982
+ return status;
983
+ }
984
+
896
985
  export function formatAmountPrecisionLimit(amount: string, locale = 'en', precision: number = 6) {
897
986
  if (!amount) {
898
987
  return '';
@@ -62,7 +62,7 @@ export default flat({
62
62
  continue: 'Continue',
63
63
  qty: 'Qty {count}',
64
64
  each: '{unit} each',
65
- trial: 'Free for {count} days',
65
+ trial: "Free for {count} day{count > 1 ? 's' : ''}",
66
66
  billed: 'billed {rule}',
67
67
  metered: 'based on usage',
68
68
  hour: 'hour',
@@ -111,11 +111,13 @@ export default flat({
111
111
  subscription: 'View subscription',
112
112
  invoice: 'View invoice',
113
113
  },
114
+ paymentRequired: 'Payment Required',
114
115
  staking: {
115
116
  title: 'Staking Required',
116
117
  tooltip:
117
118
  'Staking is used to ensure that future invoices can be paid normally. Revoking the staking from DID Wallet means canceling the subscription.',
118
119
  },
120
+ stakingConfirm: 'In this payment, the staked amount is separate from the product cost.',
119
121
  donation: {
120
122
  between: 'Please enter an amount between {min} and {max}.',
121
123
  custom: 'Custom Amount',
@@ -132,7 +134,9 @@ export default flat({
132
134
  sub1: 'Subscribe to {name}',
133
135
  sub2: 'Subscribe to {name} and {count} more',
134
136
  then: 'Then {subscription} {recurring}',
135
- free: '{count} days free',
137
+ meteredThen: 'Then {recurring} based on usage',
138
+ metered: '{recurring} based on usage',
139
+ free: "{count} day{count > 1 ? 's' : ''} free",
136
140
  least: 'continue with at least',
137
141
  completed: {
138
142
  payment: 'Thanks for your purchase',
@@ -141,8 +145,7 @@ export default flat({
141
145
  donate: 'Thanks for your support',
142
146
  tip: 'A payment to {payee} has been completed. You can view the details of this payment in your account.',
143
147
  },
144
- confirm:
145
- 'By confirming your subscription, you allow {payee} to charge your account or slashing your staking for this and future payments in accordance with their terms. You can always cancel your subscription, or revoking your staking from DID Wallet.',
148
+ confirm: 'Confirming allows {payee} to charge or reduce your staking. You can cancel or revoke staking anytime.',
146
149
  required: 'Required',
147
150
  invalid: 'Invalid',
148
151
  billing: {
@@ -185,12 +188,16 @@ export default flat({
185
188
  title: 'Nothing to show here',
186
189
  description: 'Seems this checkoutSession is not configured properly',
187
190
  },
191
+ orderSummary: 'Order Summary',
192
+ paymentDetails: 'Payment Details',
193
+ productListTotal: 'Includes {total} items',
188
194
  },
189
195
  customer: {
190
196
  payments: 'Payment History',
191
197
  invoices: 'Invoice History',
192
198
  details: 'Details',
193
199
  summary: 'Summary',
200
+ specifics: 'Specifics',
194
201
  update: 'Update Information',
195
202
  empty: 'Seems you do not have any subscriptions or payments here',
196
203
  cancel: {
@@ -272,12 +279,16 @@ export default flat({
272
279
  renewError: 'Failed to renew the subscription',
273
280
  empty: 'There are no invoices',
274
281
  next: 'No invoices yet, next invoice will be generated on {date}',
282
+ invoiceNumber: 'Invoice Number',
283
+ emptyList: 'No Invoice',
275
284
  },
276
285
  payment: {
277
286
  empty: 'There are no payments',
287
+ emptyList: 'No Payment',
278
288
  },
279
289
  refund: {
280
290
  empty: 'There are no refunds',
291
+ emptyList: 'No Refund',
281
292
  },
282
293
  subscriptions: {
283
294
  plan: 'Plan',
@@ -311,4 +322,7 @@ export default flat({
311
322
  [RefundType.stakeReturn]: 'Stake Return',
312
323
  },
313
324
  },
325
+ empty: {
326
+ records: 'No matching records found',
327
+ },
314
328
  });
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable no-prototype-builtins */
2
+ import { template } from 'lodash';
2
3
  import en from './en';
3
4
  import zh from './zh';
4
5
 
@@ -8,9 +9,15 @@ export const translations = {
8
9
  en,
9
10
  };
10
11
 
11
- export const replace = (template: string, data: Record<string, any> = {}) =>
12
- template.replace(/{(\w*)}/g, (_, key) => (data.hasOwnProperty(key) ? data[key] : ''));
13
-
12
+ const replace = (t: string, data: Record<string, any> = {}): string => {
13
+ try {
14
+ const compiled = template(t, { interpolate: /{([\s\S]+?)}/g, escape: /{([\s\S]+?)}/g });
15
+ return compiled(data);
16
+ } catch (e) {
17
+ console.error(`Error evaluating template: ${t}`, e);
18
+ return '';
19
+ }
20
+ };
14
21
  export const createTranslator = ({ fallbackLocale = 'en' }: { fallbackLocale?: string }, langs: any = translations) => {
15
22
  return (key: string, locale = fallbackLocale, data: Record<string, any> = {}) => {
16
23
  if (!langs[locale] || !langs[locale][key]) {
@@ -111,10 +111,12 @@ export default flat({
111
111
  subscription: '查看订阅',
112
112
  invoice: '查看账单',
113
113
  },
114
+ paymentRequired: '支付数量',
114
115
  staking: {
115
116
  title: '质押数量',
116
117
  tooltip: '质押相当于保证金,用于确保未来的账单能够正常扣款,如果你从 DID Wallet 撤销质押,订阅也会被取消。',
117
118
  },
119
+ stakingConfirm: '在此支付中,质押金额与产品费用分开',
118
120
  donation: {
119
121
  between: '金额必须大于 {min} 且小于 {max}',
120
122
  custom: '输入金额',
@@ -131,7 +133,9 @@ export default flat({
131
133
  sub1: '订阅 {name}',
132
134
  sub2: '订阅 {name} 等{count}个产品',
133
135
  then: '然后 {subscription} {recurring}',
134
- free: '{count}',
136
+ meteredThen: '然后{recurring}按用量计费',
137
+ metered: '{recurring}按用量计费',
138
+ free: '免费试用 {count} 天',
135
139
  least: '至少',
136
140
  completed: {
137
141
  payment: '感谢您的购买',
@@ -140,8 +144,7 @@ export default flat({
140
144
  donate: '感谢您的支持',
141
145
  tip: '向{payee}的付款已完成。您可以在您的账户中查看此付款的详细信息。',
142
146
  },
143
- confirm:
144
- '通过确认您的订阅,您允许{payee}按照其条款对您的账户进行付款或者罚没您的质押。您随时可以取消您的订阅,或者撤销质押。',
147
+ confirm: '确认允许{payee}对您的账户进行付款或者罚没您的质押。您随时可以取消您的订阅,或者撤销质押。',
145
148
  required: '必填项',
146
149
  invalid: '无效',
147
150
  billing: {
@@ -182,12 +185,16 @@ export default flat({
182
185
  title: '没有任何购买项目',
183
186
  description: '可能这个付款链接没有正确配置',
184
187
  },
188
+ orderSummary: '订单概览',
189
+ paymentDetails: '支付信息',
190
+ productListTotal: '包括 {total} 项',
185
191
  },
186
192
  customer: {
187
193
  payments: '支付历史',
188
194
  invoices: '账单历史',
189
195
  details: '账户详情',
190
196
  summary: '计费摘要',
197
+ specifics: '具体信息',
191
198
  update: '更新客户信息',
192
199
  empty: '看起来您在这里没有任何订阅或支付',
193
200
  cancel: {
@@ -264,12 +271,16 @@ export default flat({
264
271
  renewError: '订阅恢复失败',
265
272
  empty: '没有任何账单',
266
273
  next: '还没有账单,下次账单将在 {date} 生成',
274
+ invoiceNumber: '账单编号',
275
+ emptyList: '没有账单',
267
276
  },
268
277
  payment: {
269
278
  empty: '没有支付记录',
279
+ emptyList: '没有支付记录',
270
280
  },
271
281
  refund: {
272
282
  empty: '没有退款记录',
283
+ emptyList: '没有退款记录',
273
284
  },
274
285
  subscriptions: {
275
286
  plan: '订阅',
@@ -303,4 +314,7 @@ export default flat({
303
314
  [RefundType.stakeReturn]: '退押金',
304
315
  },
305
316
  },
317
+ empty: {
318
+ records: '没有找到匹配的记录',
319
+ },
306
320
  });
@@ -13,7 +13,7 @@ type Props = {
13
13
  function getHeightStyle(mode: ModeType | undefined): any {
14
14
  switch (mode) {
15
15
  case 'standalone':
16
- return { height: '100vh' }; // 独立模式下,高度为100vh
16
+ return { height: '100vh', maxHeight: '100%' }; // 独立模式下,高度为100vh
17
17
  default:
18
18
  return { height: 'auto', minHeight: 200 }; // 默认情况下,高度根据内容自动调整
19
19
  }
@@ -29,7 +29,7 @@ export default function PaymentError({ title, description, button, mode }: Props
29
29
  <Typography variant="body1" sx={{ mb: 2, textAlign: 'center' }}>
30
30
  {description}
31
31
  </Typography>
32
- <Button variant="text" size="small" component={Link} href={window.blocklet?.appUrl}>
32
+ <Button variant="text" size="small" sx={{ color: 'text.link' }} component={Link} href={window.blocklet?.appUrl}>
33
33
  {button}
34
34
  </Button>
35
35
  </Stack>
@@ -2,7 +2,7 @@ import { Typography } from '@mui/material';
2
2
 
3
3
  export default function CheckoutFooter({ ...props }) {
4
4
  return (
5
- <Typography color="text.secondary" fontSize={12} {...props}>
5
+ <Typography color="text.lighter" fontSize={12} {...props}>
6
6
  Powered by{' '}
7
7
  <Typography component="span" sx={{ fontWeight: 'bold', fontSize: 12 }}>
8
8
  ArcBlock
@@ -1,53 +1,59 @@
1
1
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
2
- import { Fade, Stack, Typography } from '@mui/material';
2
+ import { Fade, FormLabel, InputAdornment, Stack, SxProps } from '@mui/material';
3
3
  import { Controller, useFormContext } from 'react-hook-form';
4
- import { CountrySelector } from 'react-international-phone';
5
-
6
4
  import FormInput from '../../components/input';
5
+ import CountrySelect from '../../components/country-select';
7
6
 
8
7
  type Props = {
9
8
  mode: string;
10
9
  stripe: boolean;
10
+ sx?: SxProps;
11
+ };
12
+
13
+ AddressForm.defaultProps = {
14
+ sx: {},
11
15
  };
12
16
 
13
- export default function AddressForm({ mode, stripe }: Props) {
17
+ export default function AddressForm({ mode, stripe, sx = {} }: Props) {
14
18
  const { t } = useLocaleContext();
15
- const { control, setValue } = useFormContext();
19
+ const { control } = useFormContext();
16
20
 
17
21
  if (mode === 'required') {
18
22
  return (
19
23
  <Fade in>
20
- <Stack className="cko-payment-address cko-payment-form">
21
- <Typography sx={{ mb: 1, color: 'text.primary', fontWeight: 600 }}>
22
- {t(`payment.checkout.billing.${mode}`)}
23
- </Typography>
24
+ <Stack className="cko-payment-address cko-payment-form" sx={sx}>
25
+ <FormLabel className="base-label">{t(`payment.checkout.billing.${mode}`)}</FormLabel>
24
26
  <Stack direction="column" className="cko-payment-form" spacing={0}>
25
27
  <Stack direction="row" spacing={0}>
26
- <Controller
27
- name="billing_address.country"
28
- control={control}
29
- render={({ field }) => (
30
- <CountrySelector
31
- selectedCountry={field.value}
32
- onSelect={({ iso2 }) => setValue(field.name, iso2)}
33
- buttonStyle={{
34
- width: '64px',
35
- height: '40px',
36
- border: '1px solid #ccc',
37
- marginLeft: -1,
38
- marginTop: -1,
39
- }}
40
- />
41
- )}
42
- />
43
28
  <FormInput
44
29
  name="billing_address.postal_code"
45
30
  rules={{ required: t('payment.checkout.required') }}
46
31
  errorPosition="right"
47
32
  variant="outlined"
48
33
  placeholder={t('payment.checkout.billing.postal_code')}
34
+ InputProps={{
35
+ startAdornment: (
36
+ <InputAdornment position="start">
37
+ <Controller
38
+ name="billing_address.country"
39
+ control={control}
40
+ render={({ field }) => (
41
+ <CountrySelect
42
+ {...field}
43
+ sx={{
44
+ '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
45
+ borderColor: 'transparent',
46
+ },
47
+ }}
48
+ />
49
+ )}
50
+ />
51
+ </InputAdornment>
52
+ ),
53
+ }}
49
54
  />
50
55
  </Stack>
56
+ <FormLabel className="base-label">{t('payment.checkout.billing.state')}</FormLabel>
51
57
  <FormInput
52
58
  name="billing_address.state"
53
59
  rules={{ required: t('payment.checkout.required') }}
@@ -55,6 +61,7 @@ export default function AddressForm({ mode, stripe }: Props) {
55
61
  variant="outlined"
56
62
  placeholder={t('payment.checkout.billing.state')}
57
63
  />
64
+ <FormLabel className="base-label">{t('payment.checkout.billing.line1')}</FormLabel>
58
65
  <FormInput
59
66
  name="billing_address.line1"
60
67
  rules={{ required: t('payment.checkout.required') }}
@@ -62,6 +69,7 @@ export default function AddressForm({ mode, stripe }: Props) {
62
69
  variant="outlined"
63
70
  placeholder={t('payment.checkout.billing.line1')}
64
71
  />
72
+ <FormLabel className="base-label">{t('payment.checkout.billing.city')}</FormLabel>
65
73
  <FormInput
66
74
  name="billing_address.city"
67
75
  rules={{ required: t('payment.checkout.required') }}
@@ -78,29 +86,10 @@ export default function AddressForm({ mode, stripe }: Props) {
78
86
  if (stripe) {
79
87
  return (
80
88
  <Fade in>
81
- <Stack className="cko-payment-address cko-payment-form">
82
- <Typography sx={{ mb: 1, color: 'text.primary', fontWeight: 600 }}>
83
- {t(`payment.checkout.billing.${mode}`)}
84
- </Typography>
89
+ <Stack className="cko-payment-address cko-payment-form" sx={sx}>
90
+ <FormLabel className="base-label">{t(`payment.checkout.billing.${mode}`)}</FormLabel>
85
91
  <Stack direction="column" className="cko-payment-form" spacing={0}>
86
92
  <Stack direction="row" spacing={0}>
87
- <Controller
88
- name="billing_address.country"
89
- control={control}
90
- render={({ field }) => (
91
- <CountrySelector
92
- selectedCountry={field.value}
93
- onSelect={({ iso2 }) => setValue(field.name, iso2)}
94
- buttonStyle={{
95
- width: '64px',
96
- height: '40px',
97
- border: '1px solid #ccc',
98
- marginLeft: -1,
99
- marginTop: -1,
100
- }}
101
- />
102
- )}
103
- />
104
93
  <FormInput
105
94
  name="billing_address.postal_code"
106
95
  rules={{ required: t('payment.checkout.required') }}
@@ -108,6 +97,26 @@ export default function AddressForm({ mode, stripe }: Props) {
108
97
  variant="outlined"
109
98
  placeholder={t('payment.checkout.billing.postal_code')}
110
99
  wrapperStyle={{ height: '40px' }}
100
+ InputProps={{
101
+ startAdornment: (
102
+ <InputAdornment position="start">
103
+ <Controller
104
+ name="billing_address.country"
105
+ control={control}
106
+ render={({ field }) => (
107
+ <CountrySelect
108
+ {...field}
109
+ sx={{
110
+ '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
111
+ borderColor: 'transparent',
112
+ },
113
+ }}
114
+ />
115
+ )}
116
+ />
117
+ </InputAdornment>
118
+ ),
119
+ }}
111
120
  />
112
121
  </Stack>
113
122
  </Stack>