@blocklet/payment-react 1.13.113

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 (173) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +29 -0
  3. package/babel.config.es.js +8 -0
  4. package/build.config.ts +29 -0
  5. package/es/api.d.ts +2 -0
  6. package/es/api.js +18 -0
  7. package/es/checkout/index.d.ts +15 -0
  8. package/es/checkout/index.js +61 -0
  9. package/es/components/input.d.ts +23 -0
  10. package/es/components/input.js +44 -0
  11. package/es/components/livemode.d.ts +2 -0
  12. package/es/components/livemode.js +24 -0
  13. package/es/components/pricing-table.d.ts +18 -0
  14. package/es/components/pricing-table.js +175 -0
  15. package/es/components/status.d.ts +3 -0
  16. package/es/components/status.js +20 -0
  17. package/es/components/switch.d.ts +6 -0
  18. package/es/components/switch.js +42 -0
  19. package/es/contexts/payment.d.ts +29 -0
  20. package/es/contexts/payment.js +45 -0
  21. package/es/dayjs.d.ts +2 -0
  22. package/es/dayjs.js +14 -0
  23. package/es/index.d.ts +16 -0
  24. package/es/index.js +29 -0
  25. package/es/locales/en.d.ts +2 -0
  26. package/es/locales/en.js +213 -0
  27. package/es/locales/index.d.ts +10 -0
  28. package/es/locales/index.js +20 -0
  29. package/es/locales/zh.d.ts +2 -0
  30. package/es/locales/zh.js +213 -0
  31. package/es/payment/amount.d.ts +12 -0
  32. package/es/payment/amount.js +22 -0
  33. package/es/payment/error.d.ts +13 -0
  34. package/es/payment/error.js +12 -0
  35. package/es/payment/footer.d.ts +4 -0
  36. package/es/payment/footer.js +9 -0
  37. package/es/payment/form/addon.d.ts +2 -0
  38. package/es/payment/form/addon.js +14 -0
  39. package/es/payment/form/address.d.ts +7 -0
  40. package/es/payment/form/address.js +119 -0
  41. package/es/payment/form/index.d.ts +9 -0
  42. package/es/payment/form/index.js +337 -0
  43. package/es/payment/form/phone.d.ts +4 -0
  44. package/es/payment/form/phone.js +97 -0
  45. package/es/payment/form/stripe.d.ts +13 -0
  46. package/es/payment/form/stripe.js +158 -0
  47. package/es/payment/header.d.ts +7 -0
  48. package/es/payment/header.js +29 -0
  49. package/es/payment/index.d.ts +28 -0
  50. package/es/payment/index.js +327 -0
  51. package/es/payment/product-card.d.ts +21 -0
  52. package/es/payment/product-card.js +34 -0
  53. package/es/payment/product-item.d.ts +19 -0
  54. package/es/payment/product-item.js +107 -0
  55. package/es/payment/product-skeleton.d.ts +4 -0
  56. package/es/payment/product-skeleton.js +34 -0
  57. package/es/payment/skeleton/overview.d.ts +2 -0
  58. package/es/payment/skeleton/overview.js +13 -0
  59. package/es/payment/skeleton/payment.d.ts +2 -0
  60. package/es/payment/skeleton/payment.js +19 -0
  61. package/es/payment/success.d.ts +8 -0
  62. package/es/payment/success.js +164 -0
  63. package/es/payment/summary.d.ts +12 -0
  64. package/es/payment/summary.js +178 -0
  65. package/es/theme.d.ts +1 -0
  66. package/es/theme.js +17 -0
  67. package/es/types/index.d.ts +19 -0
  68. package/es/types/index.js +0 -0
  69. package/es/types/shims.d.ts +18 -0
  70. package/es/util.d.ts +52 -0
  71. package/es/util.js +390 -0
  72. package/lib/api.d.ts +2 -0
  73. package/lib/api.js +26 -0
  74. package/lib/checkout/index.d.ts +15 -0
  75. package/lib/checkout/index.js +83 -0
  76. package/lib/components/input.d.ts +23 -0
  77. package/lib/components/input.js +72 -0
  78. package/lib/components/livemode.d.ts +2 -0
  79. package/lib/components/livemode.js +29 -0
  80. package/lib/components/pricing-table.d.ts +18 -0
  81. package/lib/components/pricing-table.js +232 -0
  82. package/lib/components/status.d.ts +3 -0
  83. package/lib/components/status.js +23 -0
  84. package/lib/components/switch.d.ts +6 -0
  85. package/lib/components/switch.js +51 -0
  86. package/lib/contexts/payment.d.ts +29 -0
  87. package/lib/contexts/payment.js +73 -0
  88. package/lib/dayjs.d.ts +2 -0
  89. package/lib/dayjs.js +21 -0
  90. package/lib/index.d.ts +16 -0
  91. package/lib/index.js +143 -0
  92. package/lib/locales/en.d.ts +2 -0
  93. package/lib/locales/en.js +220 -0
  94. package/lib/locales/index.d.ts +10 -0
  95. package/lib/locales/index.js +33 -0
  96. package/lib/locales/zh.d.ts +2 -0
  97. package/lib/locales/zh.js +220 -0
  98. package/lib/payment/amount.d.ts +12 -0
  99. package/lib/payment/amount.js +28 -0
  100. package/lib/payment/error.d.ts +13 -0
  101. package/lib/payment/error.js +52 -0
  102. package/lib/payment/footer.d.ts +4 -0
  103. package/lib/payment/footer.js +25 -0
  104. package/lib/payment/form/addon.d.ts +2 -0
  105. package/lib/payment/form/addon.js +37 -0
  106. package/lib/payment/form/address.d.ts +7 -0
  107. package/lib/payment/form/address.js +152 -0
  108. package/lib/payment/form/index.d.ts +9 -0
  109. package/lib/payment/form/index.js +464 -0
  110. package/lib/payment/form/phone.d.ts +4 -0
  111. package/lib/payment/form/phone.js +133 -0
  112. package/lib/payment/form/stripe.d.ts +13 -0
  113. package/lib/payment/form/stripe.js +213 -0
  114. package/lib/payment/header.d.ts +7 -0
  115. package/lib/payment/header.js +58 -0
  116. package/lib/payment/index.d.ts +28 -0
  117. package/lib/payment/index.js +382 -0
  118. package/lib/payment/product-card.d.ts +21 -0
  119. package/lib/payment/product-card.js +81 -0
  120. package/lib/payment/product-item.d.ts +19 -0
  121. package/lib/payment/product-item.js +160 -0
  122. package/lib/payment/product-skeleton.d.ts +4 -0
  123. package/lib/payment/product-skeleton.js +71 -0
  124. package/lib/payment/skeleton/overview.d.ts +2 -0
  125. package/lib/payment/skeleton/overview.js +48 -0
  126. package/lib/payment/skeleton/payment.d.ts +2 -0
  127. package/lib/payment/skeleton/payment.js +54 -0
  128. package/lib/payment/success.d.ts +8 -0
  129. package/lib/payment/success.js +215 -0
  130. package/lib/payment/summary.d.ts +12 -0
  131. package/lib/payment/summary.js +225 -0
  132. package/lib/theme.d.ts +1 -0
  133. package/lib/theme.js +19 -0
  134. package/lib/types/index.d.ts +19 -0
  135. package/lib/types/index.js +1 -0
  136. package/lib/types/shims.d.ts +18 -0
  137. package/lib/util.d.ts +52 -0
  138. package/lib/util.js +487 -0
  139. package/package.json +104 -0
  140. package/src/api.ts +24 -0
  141. package/src/checkout/index.tsx +74 -0
  142. package/src/components/input.tsx +58 -0
  143. package/src/components/livemode.tsx +23 -0
  144. package/src/components/pricing-table.tsx +207 -0
  145. package/src/components/status.tsx +19 -0
  146. package/src/components/switch.tsx +48 -0
  147. package/src/contexts/payment.tsx +74 -0
  148. package/src/dayjs.ts +17 -0
  149. package/src/index.ts +32 -0
  150. package/src/locales/en.tsx +218 -0
  151. package/src/locales/index.tsx +30 -0
  152. package/src/locales/zh.tsx +214 -0
  153. package/src/payment/amount.tsx +24 -0
  154. package/src/payment/error.tsx +29 -0
  155. package/src/payment/footer.tsx +12 -0
  156. package/src/payment/form/addon.tsx +24 -0
  157. package/src/payment/form/address.tsx +119 -0
  158. package/src/payment/form/index.tsx +401 -0
  159. package/src/payment/form/phone.tsx +103 -0
  160. package/src/payment/form/stripe.tsx +195 -0
  161. package/src/payment/header.tsx +40 -0
  162. package/src/payment/index.tsx +367 -0
  163. package/src/payment/product-card.tsx +55 -0
  164. package/src/payment/product-item.tsx +121 -0
  165. package/src/payment/product-skeleton.tsx +39 -0
  166. package/src/payment/skeleton/overview.tsx +21 -0
  167. package/src/payment/skeleton/payment.tsx +35 -0
  168. package/src/payment/success.tsx +186 -0
  169. package/src/payment/summary.tsx +198 -0
  170. package/src/theme.ts +18 -0
  171. package/src/types/index.ts +29 -0
  172. package/src/types/shims.d.ts +18 -0
  173. package/src/util.ts +543 -0
@@ -0,0 +1,107 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
3
+ import { Stack, Typography } from "@mui/material";
4
+ import Status from "../components/status.js";
5
+ import Switch from "../components/switch.js";
6
+ import { formatLineItemPricing, formatPrice, formatRecurring, formatUpsellSaving } from "../util.js";
7
+ import ProductCard from "./product-card.js";
8
+ ProductItem.defaultProps = {
9
+ mode: "normal",
10
+ children: null
11
+ };
12
+ export default function ProductItem({ item, session, currency, mode, children, onUpsell, onDownsell }) {
13
+ const { t, locale } = useLocaleContext();
14
+ const pricing = formatLineItemPricing(item, currency, session.subscription_data?.trial_period_days || 0, locale);
15
+ const saving = formatUpsellSaving(session, currency);
16
+ const metered = item.price?.recurring?.usage_type === "metered" ? t("common.metered") : "";
17
+ const canUpsell = mode === "normal" && session.line_items.length === 1;
18
+ return /* @__PURE__ */ jsxs(Stack, { direction: "column", alignItems: "flex-start", spacing: 1, sx: { width: "100%" }, children: [
19
+ /* @__PURE__ */ jsxs(Stack, { direction: "column", alignItems: "flex-end", sx: { width: "100%" }, children: [
20
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", justifyContent: "space-between", sx: { width: "100%" }, children: [
21
+ /* @__PURE__ */ jsx(
22
+ ProductCard,
23
+ {
24
+ logo: item.price.product?.images[0],
25
+ name: item.price.product?.name,
26
+ description: item.price.product?.description,
27
+ extra: item.price.type === "recurring" && item.price.recurring ? [pricing.quantity, t("common.billed", { rule: `${formatRecurring(item.upsell_price?.recurring || item.price.recurring, true, "per", locale)} ${metered}` })].filter(Boolean).join(", ") : pricing.quantity
28
+ }
29
+ ),
30
+ /* @__PURE__ */ jsxs(Stack, { direction: "column", alignItems: "flex-end", flex: 1, children: [
31
+ /* @__PURE__ */ jsx(Typography, { sx: { color: "text.primary", fontWeight: 500 }, gutterBottom: true, children: pricing.primary }),
32
+ pricing.secondary && /* @__PURE__ */ jsx(Typography, { sx: { fontSize: "0.85rem", color: "text.secondary" }, children: pricing.secondary })
33
+ ] })
34
+ ] }),
35
+ children
36
+ ] }),
37
+ canUpsell && !item.upsell_price_id && item.price.upsell?.upsells_to && /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", justifyContent: "space-between", sx: { width: "100%" }, children: [
38
+ /* @__PURE__ */ jsxs(
39
+ Typography,
40
+ {
41
+ component: "label",
42
+ htmlFor: "upsell-switch",
43
+ sx: {
44
+ fontSize: 12,
45
+ cursor: "pointer",
46
+ color: "text.primary"
47
+ },
48
+ children: [
49
+ /* @__PURE__ */ jsx(
50
+ Switch,
51
+ {
52
+ id: "upsell-switch",
53
+ sx: { mr: 1 },
54
+ variant: "success",
55
+ checked: false,
56
+ onChange: () => onUpsell(item.price_id, item.price.upsell?.upsells_to_id)
57
+ }
58
+ ),
59
+ t("payment.checkout.upsell.save", {
60
+ recurring: formatRecurring(item.price.upsell.upsells_to.recurring, true, "per", locale)
61
+ }),
62
+ /* @__PURE__ */ jsx(
63
+ Status,
64
+ {
65
+ label: t("payment.checkout.upsell.off", { saving }),
66
+ color: "primary",
67
+ variant: "outlined",
68
+ sx: { ml: 1 }
69
+ }
70
+ )
71
+ ]
72
+ }
73
+ ),
74
+ /* @__PURE__ */ jsx(Typography, { component: "span", sx: { fontSize: 12 }, children: formatPrice(item.price.upsell.upsells_to, currency, item.price.product?.unit_label, 1, true, locale) })
75
+ ] }),
76
+ canUpsell && item.upsell_price_id && /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", justifyContent: "space-between", sx: { width: "100%" }, children: [
77
+ /* @__PURE__ */ jsxs(
78
+ Typography,
79
+ {
80
+ component: "label",
81
+ htmlFor: "upsell-switch",
82
+ sx: {
83
+ fontSize: 12,
84
+ cursor: "pointer",
85
+ color: "text.secondary"
86
+ },
87
+ children: [
88
+ /* @__PURE__ */ jsx(
89
+ Switch,
90
+ {
91
+ id: "upsell-switch",
92
+ sx: { mr: 1 },
93
+ variant: "success",
94
+ checked: true,
95
+ onChange: () => onDownsell(item.upsell_price_id)
96
+ }
97
+ ),
98
+ t("payment.checkout.upsell.revert", {
99
+ recurring: t(`common.${formatRecurring(item.price.recurring)}`)
100
+ })
101
+ ]
102
+ }
103
+ ),
104
+ /* @__PURE__ */ jsx(Typography, { component: "span", sx: { fontSize: 12 }, children: formatPrice(item.price, currency, item.price.product?.unit_label, 1, true, locale) })
105
+ ] })
106
+ ] });
107
+ }
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export default function ProductSkeleton({ count }: {
3
+ count: number;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,34 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fade, Skeleton, Stack, Typography } from "@mui/material";
3
+ export default function ProductSkeleton({ count }) {
4
+ return /* @__PURE__ */ jsx(Fade, { in: true, children: /* @__PURE__ */ jsxs(
5
+ Stack,
6
+ {
7
+ direction: "column",
8
+ alignItems: "center",
9
+ padding: 4,
10
+ spacing: 1,
11
+ sx: {
12
+ width: 320,
13
+ border: "1px solid #eee",
14
+ borderRadius: 1,
15
+ transition: "border-color 0.3s ease 0s, box-shadow 0.3s ease 0s",
16
+ boxShadow: "0 4px 8px rgba(0, 0, 0, 20%)",
17
+ "&:hover": {
18
+ borderColor: "#ddd",
19
+ boxShadow: "0 8px 16px rgba(0, 0, 0, 20%)"
20
+ }
21
+ },
22
+ children: [
23
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h4", sx: { width: "50%" }, children: /* @__PURE__ */ jsx(Skeleton, {}) }),
24
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", sx: { fontSize: "1rem", width: "60%" } }),
25
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h3", sx: { width: "60%" }, children: /* @__PURE__ */ jsx(Skeleton, {}) }),
26
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h3", sx: { width: "100%" }, children: /* @__PURE__ */ jsx(Skeleton, {}) }),
27
+ Array.from({ length: count }).map((_, i) => (
28
+ // eslint-disable-next-line react/no-array-index-key
29
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", sx: { fontSize: "1rem", width: "60%" } }, i)
30
+ ))
31
+ ]
32
+ }
33
+ ) });
34
+ }
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export default function OverviewSkeleton(): import("react").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fade, Skeleton, Stack, Typography } from "@mui/material";
3
+ export default function OverviewSkeleton() {
4
+ return /* @__PURE__ */ jsx(Fade, { in: true, children: /* @__PURE__ */ jsxs(Stack, { direction: "column", children: [
5
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 2, children: [
6
+ /* @__PURE__ */ jsx(Skeleton, { variant: "circular", width: 32, height: 32 }),
7
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", sx: { fontSize: "2rem", width: "40%" } })
8
+ ] }),
9
+ /* @__PURE__ */ jsx(Typography, { mt: 3, component: "div", variant: "h4", children: /* @__PURE__ */ jsx(Skeleton, {}) }),
10
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h2", children: /* @__PURE__ */ jsx(Skeleton, {}) }),
11
+ /* @__PURE__ */ jsx(Skeleton, { sx: { mt: 3 }, variant: "rounded", width: 200, height: 200 })
12
+ ] }) });
13
+ }
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export default function PaymentSkeleton(): import("react").JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Box, Fade, Skeleton, Stack, Typography } from "@mui/material";
3
+ export default function PaymentSkeleton() {
4
+ return /* @__PURE__ */ jsx(Fade, { in: true, children: /* @__PURE__ */ jsxs(Stack, { direction: "column", spacing: 3, children: [
5
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", sx: { fontSize: "2rem", width: "40%" } }),
6
+ /* @__PURE__ */ jsxs(Box, { children: [
7
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h4", children: /* @__PURE__ */ jsx(Skeleton, {}) }),
8
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h1", children: /* @__PURE__ */ jsx(Skeleton, {}) })
9
+ ] }),
10
+ /* @__PURE__ */ jsxs(Box, { children: [
11
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h4", children: /* @__PURE__ */ jsx(Skeleton, {}) }),
12
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h1", children: /* @__PURE__ */ jsx(Skeleton, {}) })
13
+ ] }),
14
+ /* @__PURE__ */ jsxs(Box, { children: [
15
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h4", children: /* @__PURE__ */ jsx(Skeleton, {}) }),
16
+ /* @__PURE__ */ jsx(Typography, { component: "div", variant: "h1", children: /* @__PURE__ */ jsx(Skeleton, {}) })
17
+ ] })
18
+ ] }) });
19
+ }
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ type Props = {
3
+ message: string;
4
+ action: string;
5
+ payee: string;
6
+ };
7
+ export default function PaymentSuccess({ message, action, payee }: Props): import("react").JSX.Element;
8
+ export {};
@@ -0,0 +1,164 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
3
+ import { Grow, Link, Stack, Typography } from "@mui/material";
4
+ import { styled } from "@mui/system";
5
+ import { joinURL } from "ufo";
6
+ import { usePaymentContext } from "../contexts/payment.js";
7
+ export default function PaymentSuccess({ message, action, payee }) {
8
+ const { t } = useLocaleContext();
9
+ const { prefix } = usePaymentContext();
10
+ return /* @__PURE__ */ jsx(Grow, { in: true, children: /* @__PURE__ */ jsxs(Stack, { direction: "column", alignItems: "center", justifyContent: "center", sx: { height: 360 }, children: [
11
+ /* @__PURE__ */ jsx(Div, { children: /* @__PURE__ */ jsxs("div", { className: "check-icon", children: [
12
+ /* @__PURE__ */ jsx("span", { className: "icon-line line-tip" }),
13
+ /* @__PURE__ */ jsx("span", { className: "icon-line line-long" }),
14
+ /* @__PURE__ */ jsx("div", { className: "icon-circle" }),
15
+ /* @__PURE__ */ jsx("div", { className: "icon-fix" })
16
+ ] }) }),
17
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", color: "text.primary", mb: 3, children: message }),
18
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", color: "text.secondary", textAlign: "center", children: t("payment.checkout.completed.tip", { payee }) }),
19
+ ["subscription", "setup"].includes(action) && /* @__PURE__ */ jsx(Typography, { textAlign: "center", sx: { mt: 2 }, children: /* @__PURE__ */ jsx(Link, { href: joinURL(prefix, "/customer"), children: t("payment.checkout.portal", { payee }) }) })
20
+ ] }) });
21
+ }
22
+ const Div = styled("div")`
23
+ width: 80px;
24
+ height: 115px;
25
+
26
+ .check-icon {
27
+ width: 80px;
28
+ height: 80px;
29
+ position: relative;
30
+ border-radius: 50%;
31
+ box-sizing: content-box;
32
+ border: 4px solid ${(props) => props.theme.palette.success.main};
33
+ }
34
+ .check-icon::before {
35
+ top: 3px;
36
+ left: -2px;
37
+ width: 30px;
38
+ transform-origin: 100% 50%;
39
+ border-radius: 100px 0 0 100px;
40
+ }
41
+ .check-icon::after {
42
+ top: 0;
43
+ left: 30px;
44
+ width: 60px;
45
+ transform-origin: 0 50%;
46
+ border-radius: 0 100px 100px 0;
47
+ animation: rotate-circle 4.25s ease-in;
48
+ }
49
+ .check-icon::before,
50
+ .check-icon::after {
51
+ content: '';
52
+ height: 100px;
53
+ position: absolute;
54
+ background: #ffffff;
55
+ transform: rotate(-45deg);
56
+ }
57
+ .check-icon .icon-line {
58
+ height: 5px;
59
+ background-color: ${(props) => props.theme.palette.success.main};
60
+ display: block;
61
+ border-radius: 2px;
62
+ position: absolute;
63
+ z-index: 10;
64
+ }
65
+ .check-icon .icon-line.line-tip {
66
+ top: 46px;
67
+ left: 14px;
68
+ width: 25px;
69
+ transform: rotate(45deg);
70
+ animation: icon-line-tip 0.75s;
71
+ }
72
+ .check-icon .icon-line.line-long {
73
+ top: 38px;
74
+ right: 8px;
75
+ width: 47px;
76
+ transform: rotate(-45deg);
77
+ animation: icon-line-long 0.75s;
78
+ }
79
+ .check-icon .icon-circle {
80
+ top: -4px;
81
+ left: -4px;
82
+ z-index: 10;
83
+ width: 80px;
84
+ height: 80px;
85
+ border-radius: 50%;
86
+ position: absolute;
87
+ box-sizing: content-box;
88
+ border: 4px solid rgba(76, 175, 80, 0.5);
89
+ }
90
+ .check-icon .icon-fix {
91
+ top: 8px;
92
+ width: 5px;
93
+ left: 26px;
94
+ z-index: 1;
95
+ height: 85px;
96
+ position: absolute;
97
+ transform: rotate(-45deg);
98
+ background-color: #ffffff;
99
+ }
100
+
101
+ @keyframes rotate-circle {
102
+ 0% {
103
+ transform: rotate(-45deg);
104
+ }
105
+ 5% {
106
+ transform: rotate(-45deg);
107
+ }
108
+ 12% {
109
+ transform: rotate(-405deg);
110
+ }
111
+ 100% {
112
+ transform: rotate(-405deg);
113
+ }
114
+ }
115
+ @keyframes icon-line-tip {
116
+ 0% {
117
+ width: 0;
118
+ left: 1px;
119
+ top: 19px;
120
+ }
121
+ 54% {
122
+ width: 0;
123
+ left: 1px;
124
+ top: 19px;
125
+ }
126
+ 70% {
127
+ width: 50px;
128
+ left: -8px;
129
+ top: 37px;
130
+ }
131
+ 84% {
132
+ width: 17px;
133
+ left: 21px;
134
+ top: 48px;
135
+ }
136
+ 100% {
137
+ width: 25px;
138
+ left: 14px;
139
+ top: 45px;
140
+ }
141
+ }
142
+ @keyframes icon-line-long {
143
+ 0% {
144
+ width: 0;
145
+ right: 46px;
146
+ top: 54px;
147
+ }
148
+ 65% {
149
+ width: 0;
150
+ right: 46px;
151
+ top: 54px;
152
+ }
153
+ 84% {
154
+ width: 55px;
155
+ right: 0px;
156
+ top: 35px;
157
+ }
158
+ 100% {
159
+ width: 47px;
160
+ right: 8px;
161
+ top: 38px;
162
+ }
163
+ }
164
+ `;
@@ -0,0 +1,12 @@
1
+ /// <reference types="react" />
2
+ import type { TCheckoutSessionExpanded, TPaymentCurrency } from '@blocklet/payment-types';
3
+ type Props = {
4
+ checkoutSession: TCheckoutSessionExpanded;
5
+ currency: TPaymentCurrency;
6
+ onUpsell: Function;
7
+ onDownsell: Function;
8
+ onApplyCrossSell: Function;
9
+ onCancelCrossSell: Function;
10
+ };
11
+ export default function PaymentSummary({ checkoutSession, currency, onUpsell, onDownsell, onApplyCrossSell, onCancelCrossSell, }: Props): import("react").JSX.Element;
12
+ export {};
@@ -0,0 +1,178 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
3
+ import { LoadingButton } from "@mui/lab";
4
+ import { Fade, Grow, Stack, Typography, keyframes } from "@mui/material";
5
+ import { useRequest, useSetState } from "ahooks";
6
+ import noop from "lodash/noop";
7
+ import useBus from "use-bus";
8
+ import api from "../api.js";
9
+ import Status from "../components/status.js";
10
+ import { formatCheckoutHeadlines } from "../util.js";
11
+ import PaymentAmount from "./amount.js";
12
+ import ProductItem from "./product-item.js";
13
+ const shake = keyframes`
14
+ 0% {
15
+ transform: rotate(0deg);
16
+ }
17
+ 25% {
18
+ transform: rotate(2deg);
19
+ }
20
+ 50% {
21
+ transform: rotate(0eg);
22
+ }
23
+ 75% {
24
+ transform: rotate(-2deg);
25
+ }
26
+ 100% {
27
+ transform: rotate(0deg);
28
+ }
29
+ `;
30
+ async function fetchCrossSell(id) {
31
+ try {
32
+ const { data } = await api.get(`/api/checkout-sessions/${id}/cross-sell`);
33
+ if (!data.error) {
34
+ return data;
35
+ }
36
+ return null;
37
+ } catch (err) {
38
+ return null;
39
+ }
40
+ }
41
+ export default function PaymentSummary({
42
+ checkoutSession,
43
+ currency,
44
+ onUpsell,
45
+ onDownsell,
46
+ onApplyCrossSell,
47
+ onCancelCrossSell
48
+ }) {
49
+ const { t, locale } = useLocaleContext();
50
+ const [state, setState] = useSetState({ loading: false, shake: false });
51
+ const { data, runAsync } = useRequest(() => fetchCrossSell(checkoutSession.id));
52
+ const headlines = formatCheckoutHeadlines(checkoutSession, currency, locale);
53
+ useBus(
54
+ "error.REQUIRE_CROSS_SELL",
55
+ () => {
56
+ setState({ shake: true });
57
+ setTimeout(() => {
58
+ setState({ shake: false });
59
+ }, 1e3);
60
+ },
61
+ []
62
+ );
63
+ const handleUpsell = async (from, to) => {
64
+ await onUpsell(from, to);
65
+ runAsync();
66
+ };
67
+ const handleDownsell = async (from) => {
68
+ await onDownsell(from);
69
+ runAsync();
70
+ };
71
+ const handleApplyCrossSell = async () => {
72
+ if (data) {
73
+ try {
74
+ setState({ loading: true });
75
+ await onApplyCrossSell(data.id);
76
+ } catch (err) {
77
+ console.error(err);
78
+ } finally {
79
+ setState({ loading: false });
80
+ }
81
+ }
82
+ };
83
+ const handleCancelCrossSell = async () => {
84
+ try {
85
+ setState({ loading: true });
86
+ await onCancelCrossSell();
87
+ } catch (err) {
88
+ console.error(err);
89
+ } finally {
90
+ setState({ loading: false });
91
+ }
92
+ };
93
+ return /* @__PURE__ */ jsx(Fade, { in: true, children: /* @__PURE__ */ jsxs(
94
+ Stack,
95
+ {
96
+ className: "cko-product",
97
+ direction: "column",
98
+ sx: {
99
+ mt: 8
100
+ },
101
+ children: [
102
+ /* @__PURE__ */ jsxs(Stack, { className: "cko-product-summary", direction: "column", alignItems: "flex-start", sx: { mb: 4 }, children: [
103
+ /* @__PURE__ */ jsx(Typography, { sx: { fontWeight: 500, fontSize: "1.15rem", color: "text.secondary" }, children: headlines.action }),
104
+ /* @__PURE__ */ jsx(PaymentAmount, { amount: headlines.amount }),
105
+ headlines.then && /* @__PURE__ */ jsx(Typography, { sx: { fontSize: "0.9rem", color: "text.secondary" }, children: headlines.then })
106
+ ] }),
107
+ /* @__PURE__ */ jsx(Stack, { spacing: 2, children: checkoutSession.line_items.map((x) => /* @__PURE__ */ jsx(
108
+ ProductItem,
109
+ {
110
+ item: x,
111
+ session: checkoutSession,
112
+ currency,
113
+ onUpsell: handleUpsell,
114
+ onDownsell: handleDownsell,
115
+ children: x.cross_sell && /* @__PURE__ */ jsx(
116
+ LoadingButton,
117
+ {
118
+ size: "small",
119
+ loadingPosition: "end",
120
+ color: "error",
121
+ variant: "text",
122
+ loading: state.loading,
123
+ onClick: handleCancelCrossSell,
124
+ children: t("payment.checkout.cross_sell.remove")
125
+ }
126
+ )
127
+ },
128
+ x.price_id
129
+ )) }),
130
+ data && checkoutSession.line_items.some((x) => x.price_id === data.id) === false && /* @__PURE__ */ jsx(Grow, { in: true, children: /* @__PURE__ */ jsxs(
131
+ Stack,
132
+ {
133
+ direction: "column",
134
+ alignItems: "flex-end",
135
+ spacing: 0.5,
136
+ sx: {
137
+ border: "1px solid #eee",
138
+ borderRadius: 1,
139
+ padding: 1,
140
+ animation: state.shake ? `${shake} 0.2s 5 ease-in-out` : "none",
141
+ mt: {
142
+ xs: 4,
143
+ md: 8
144
+ }
145
+ },
146
+ children: [
147
+ /* @__PURE__ */ jsx(
148
+ ProductItem,
149
+ {
150
+ item: { quantity: 1, price: data, price_id: data.id, cross_sell: true },
151
+ session: checkoutSession,
152
+ currency,
153
+ onUpsell: noop,
154
+ onDownsell: noop
155
+ }
156
+ ),
157
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", justifyContent: "space-between", sx: { width: 1 }, children: [
158
+ /* @__PURE__ */ jsx(Typography, { children: checkoutSession.cross_sell_behavior === "required" && /* @__PURE__ */ jsx(Status, { label: t("payment.checkout.required"), color: "info", variant: "outlined", sx: { mr: 1 } }) }),
159
+ /* @__PURE__ */ jsx(
160
+ LoadingButton,
161
+ {
162
+ size: "small",
163
+ loadingPosition: "end",
164
+ color: checkoutSession.cross_sell_behavior === "required" ? "info" : "info",
165
+ variant: checkoutSession.cross_sell_behavior === "required" ? "text" : "text",
166
+ loading: state.loading,
167
+ onClick: handleApplyCrossSell,
168
+ children: t("payment.checkout.cross_sell.add")
169
+ }
170
+ )
171
+ ] })
172
+ ]
173
+ }
174
+ ) })
175
+ ]
176
+ }
177
+ ) });
178
+ }
package/es/theme.d.ts ADDED
@@ -0,0 +1 @@
1
+ export default function create(settings?: any): any;
package/es/theme.js ADDED
@@ -0,0 +1,17 @@
1
+ import { createTheme } from "@arcblock/ux/lib/Theme";
2
+ import merge from "lodash/merge";
3
+ export default function create(settings = {}) {
4
+ return createTheme(
5
+ merge(
6
+ {
7
+ typography: {
8
+ fontSize: 14,
9
+ allVariants: {
10
+ textTransform: "none"
11
+ }
12
+ }
13
+ },
14
+ settings
15
+ )
16
+ );
17
+ }
@@ -0,0 +1,19 @@
1
+ import type { TCheckoutSessionExpanded, TCustomer, TPaymentIntent, TPaymentLink, TPaymentMethodExpanded } from '@blocklet/payment-types';
2
+ import { LiteralUnion } from 'type-fest';
3
+ export type CheckoutContext = {
4
+ checkoutSession: TCheckoutSessionExpanded;
5
+ paymentMethods: TPaymentMethodExpanded[];
6
+ paymentLink?: TPaymentLink;
7
+ paymentIntent?: TPaymentIntent;
8
+ customer?: TCustomer;
9
+ mode: LiteralUnion<'standalone' | 'inline' | 'popup', string>;
10
+ };
11
+ export type CheckoutProps = Partial<CheckoutCallbacks> & {
12
+ id: string;
13
+ extraParams?: Record<string, any>;
14
+ mode?: LiteralUnion<'standalone' | 'inline' | 'popup', string>;
15
+ };
16
+ export type CheckoutCallbacks = {
17
+ onPaid: (res: CheckoutContext) => void;
18
+ onError: (err: Error) => void;
19
+ };
File without changes
@@ -0,0 +1,18 @@
1
+ declare module '@arcblock/ux/*';
2
+ declare module '@arcblock/did-connect/*';
3
+
4
+ declare module '*.png';
5
+
6
+ declare module 'google-libphonenumber';
7
+
8
+ declare module 'flat';
9
+
10
+ declare module '@arcblock/*';
11
+
12
+ declare module '@blocklet/*';
13
+
14
+ declare module 'pretty-ms-i18n';
15
+
16
+ declare interface Window {
17
+ blocklet: any;
18
+ }
package/es/util.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ /// <reference types="react" />
2
+ import type { PriceCurrency, PriceRecurring, TCheckoutSessionExpanded, TLineItemExpanded, TPaymentCurrency, TPaymentMethodExpanded, TPrice, TSubscriptionExpanded } from '@blocklet/payment-types';
3
+ export declare const PAYMENT_KIT_DID = "z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk";
4
+ export declare const getPrefix: () => any;
5
+ export declare function formatToDate(date: Date | string | number, locale?: string): any;
6
+ export declare function formatToDatetime(date: Date | string | number, locale?: string): any;
7
+ export declare function formatTime(date: Date | string | number, format?: string, locale?: string): any;
8
+ export declare function formatDateTime(date: Date | string | number, locale?: string): any;
9
+ export declare const formatLocale: (locale?: string) => string;
10
+ export declare const formatPrettyMsLocale: (locale: string) => "zh_CN" | "en_US";
11
+ export declare const formatError: (err: any) => any;
12
+ export declare const formatPrice: (price: TPrice, currency: TPaymentCurrency, unit_label?: string, quantity?: number, bn?: boolean, locale?: string) => string;
13
+ export declare const formatPriceAmount: (price: TPrice, currency: TPaymentCurrency, unit_label?: string, quantity?: number, bn?: boolean) => string;
14
+ export declare function getStatementDescriptor(items: any[]): any;
15
+ export declare function formatRecurring(recurring: PriceRecurring, translate?: boolean, separator?: string, locale?: string): string;
16
+ export declare function getPriceUintAmountByCurrency(price: TPrice, currency: TPaymentCurrency): string;
17
+ export declare function getPriceCurrencyOptions(price: TPrice): PriceCurrency[];
18
+ export declare function formatLineItemPricing(item: TLineItemExpanded, currency: TPaymentCurrency, trial: number, locale?: string): {
19
+ primary: string;
20
+ secondary?: string;
21
+ quantity: string;
22
+ };
23
+ export declare function getCheckoutAmount(items: TLineItemExpanded[], currency: TPaymentCurrency, includeFreeTrial?: boolean, upsell?: boolean): {
24
+ subtotal: any;
25
+ total: any;
26
+ renew: any;
27
+ discount: string;
28
+ shipping: string;
29
+ tax: string;
30
+ };
31
+ export declare function getRecurringPeriod(recurring: PriceRecurring): number;
32
+ export declare function formatUpsellSaving(session: TCheckoutSessionExpanded, currency: TPaymentCurrency): string;
33
+ export declare function formatCheckoutHeadlines(session: TCheckoutSessionExpanded, currency: TPaymentCurrency, locale?: string): {
34
+ action: string;
35
+ amount: string;
36
+ then?: string;
37
+ secondary?: string;
38
+ };
39
+ export declare function formatAmount(amount: string, decimals: number): string;
40
+ export declare function findCurrency(methods: TPaymentMethodExpanded[], currencyId: string): import("sequelize").InferAttributes<import("@blocklet/payment-types").PaymentCurrency, {
41
+ omit: never;
42
+ }> | null;
43
+ export declare function isValidCountry(code: string): boolean;
44
+ export declare function stopEvent(e: React.SyntheticEvent<any>): void;
45
+ export declare function sleep(ms: number): Promise<unknown>;
46
+ export declare const getSubscriptionTimeSummary: (subscription: TSubscriptionExpanded) => string;
47
+ export declare const getSubscriptionAction: (subscription: TSubscriptionExpanded) => {
48
+ action: string;
49
+ variant: string;
50
+ color: string;
51
+ } | null;
52
+ export declare const mergeExtraParams: (extra?: Record<string, any>) => string;