@blocklet/payment-react 1.25.10 → 1.26.0

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 (160) hide show
  1. package/es/checkout-v2/checkout-v2.d.ts +2 -0
  2. package/es/checkout-v2/checkout-v2.js +121 -0
  3. package/es/checkout-v2/components/dialogs/checkout-dialogs.d.ts +1 -0
  4. package/es/checkout-v2/components/dialogs/checkout-dialogs.js +106 -0
  5. package/es/checkout-v2/components/left/billing-toggle.d.ts +6 -0
  6. package/es/checkout-v2/components/left/billing-toggle.js +118 -0
  7. package/es/checkout-v2/components/left/cross-sell-card.d.ts +10 -0
  8. package/es/checkout-v2/components/left/cross-sell-card.js +167 -0
  9. package/es/checkout-v2/components/left/product-item-card.d.ts +26 -0
  10. package/es/checkout-v2/components/left/product-item-card.js +571 -0
  11. package/es/checkout-v2/components/left/promotion-input.d.ts +19 -0
  12. package/es/checkout-v2/components/left/promotion-input.js +178 -0
  13. package/es/checkout-v2/components/left/staking-breakdown.d.ts +9 -0
  14. package/es/checkout-v2/components/left/staking-breakdown.js +48 -0
  15. package/es/checkout-v2/components/left/trial-info.d.ts +13 -0
  16. package/es/checkout-v2/components/left/trial-info.js +48 -0
  17. package/es/checkout-v2/components/right/currency-grid.d.ts +8 -0
  18. package/es/checkout-v2/components/right/currency-grid.js +48 -0
  19. package/es/checkout-v2/components/right/customer-info-card.d.ts +17 -0
  20. package/es/checkout-v2/components/right/customer-info-card.js +156 -0
  21. package/es/checkout-v2/components/right/status-feedback.d.ts +7 -0
  22. package/es/checkout-v2/components/right/status-feedback.js +17 -0
  23. package/es/checkout-v2/components/right/submit-button.d.ts +10 -0
  24. package/es/checkout-v2/components/right/submit-button.js +29 -0
  25. package/es/checkout-v2/components/right/subscription-disclaimer.d.ts +11 -0
  26. package/es/checkout-v2/components/right/subscription-disclaimer.js +8 -0
  27. package/es/checkout-v2/components/shared/exchange-rate-footer.d.ts +23 -0
  28. package/es/checkout-v2/components/shared/exchange-rate-footer.js +182 -0
  29. package/es/checkout-v2/components/shared/scenario-badge.d.ts +6 -0
  30. package/es/checkout-v2/components/shared/scenario-badge.js +47 -0
  31. package/es/checkout-v2/components/shared/total-display.d.ts +7 -0
  32. package/es/checkout-v2/components/shared/total-display.js +84 -0
  33. package/es/checkout-v2/index.d.ts +2 -0
  34. package/es/checkout-v2/index.js +1 -0
  35. package/es/checkout-v2/layouts/checkout-layout.d.ts +7 -0
  36. package/es/checkout-v2/layouts/checkout-layout.js +226 -0
  37. package/es/checkout-v2/panels/left/composite-panel.d.ts +1 -0
  38. package/es/checkout-v2/panels/left/composite-panel.js +423 -0
  39. package/es/checkout-v2/panels/left/credit-topup-panel.d.ts +1 -0
  40. package/es/checkout-v2/panels/left/credit-topup-panel.js +615 -0
  41. package/es/checkout-v2/panels/left/scenario-router.d.ts +1 -0
  42. package/es/checkout-v2/panels/left/scenario-router.js +19 -0
  43. package/es/checkout-v2/panels/right/payment-panel.d.ts +1 -0
  44. package/es/checkout-v2/panels/right/payment-panel.js +644 -0
  45. package/es/checkout-v2/types.d.ts +15 -0
  46. package/es/checkout-v2/types.js +0 -0
  47. package/es/checkout-v2/utils/format.d.ts +59 -0
  48. package/es/checkout-v2/utils/format.js +125 -0
  49. package/es/checkout-v2/utils/scenario-detector.d.ts +3 -0
  50. package/es/checkout-v2/utils/scenario-detector.js +17 -0
  51. package/es/checkout-v2/views/error-view.d.ts +7 -0
  52. package/es/checkout-v2/views/error-view.js +269 -0
  53. package/es/checkout-v2/views/loading-view.d.ts +5 -0
  54. package/es/checkout-v2/views/loading-view.js +158 -0
  55. package/es/checkout-v2/views/success-view.d.ts +29 -0
  56. package/es/checkout-v2/views/success-view.js +614 -0
  57. package/es/components/phone-field.d.ts +14 -0
  58. package/es/components/phone-field.js +96 -0
  59. package/es/index.d.ts +3 -1
  60. package/es/index.js +3 -1
  61. package/es/locales/en.js +45 -6
  62. package/es/locales/zh.js +45 -6
  63. package/es/payment/form/index.js +10 -1
  64. package/lib/checkout-v2/checkout-v2.d.ts +2 -0
  65. package/lib/checkout-v2/checkout-v2.js +151 -0
  66. package/lib/checkout-v2/components/dialogs/checkout-dialogs.d.ts +1 -0
  67. package/lib/checkout-v2/components/dialogs/checkout-dialogs.js +131 -0
  68. package/lib/checkout-v2/components/left/billing-toggle.d.ts +6 -0
  69. package/lib/checkout-v2/components/left/billing-toggle.js +126 -0
  70. package/lib/checkout-v2/components/left/cross-sell-card.d.ts +10 -0
  71. package/lib/checkout-v2/components/left/cross-sell-card.js +257 -0
  72. package/lib/checkout-v2/components/left/product-item-card.d.ts +26 -0
  73. package/lib/checkout-v2/components/left/product-item-card.js +738 -0
  74. package/lib/checkout-v2/components/left/promotion-input.d.ts +19 -0
  75. package/lib/checkout-v2/components/left/promotion-input.js +220 -0
  76. package/lib/checkout-v2/components/left/staking-breakdown.d.ts +9 -0
  77. package/lib/checkout-v2/components/left/staking-breakdown.js +96 -0
  78. package/lib/checkout-v2/components/left/trial-info.d.ts +13 -0
  79. package/lib/checkout-v2/components/left/trial-info.js +82 -0
  80. package/lib/checkout-v2/components/right/currency-grid.d.ts +8 -0
  81. package/lib/checkout-v2/components/right/currency-grid.js +96 -0
  82. package/lib/checkout-v2/components/right/customer-info-card.d.ts +17 -0
  83. package/lib/checkout-v2/components/right/customer-info-card.js +246 -0
  84. package/lib/checkout-v2/components/right/status-feedback.d.ts +7 -0
  85. package/lib/checkout-v2/components/right/status-feedback.js +30 -0
  86. package/lib/checkout-v2/components/right/submit-button.d.ts +10 -0
  87. package/lib/checkout-v2/components/right/submit-button.js +35 -0
  88. package/lib/checkout-v2/components/right/subscription-disclaimer.d.ts +11 -0
  89. package/lib/checkout-v2/components/right/subscription-disclaimer.js +33 -0
  90. package/lib/checkout-v2/components/shared/exchange-rate-footer.d.ts +23 -0
  91. package/lib/checkout-v2/components/shared/exchange-rate-footer.js +282 -0
  92. package/lib/checkout-v2/components/shared/scenario-badge.d.ts +6 -0
  93. package/lib/checkout-v2/components/shared/scenario-badge.js +57 -0
  94. package/lib/checkout-v2/components/shared/total-display.d.ts +7 -0
  95. package/lib/checkout-v2/components/shared/total-display.js +154 -0
  96. package/lib/checkout-v2/index.d.ts +2 -0
  97. package/lib/checkout-v2/index.js +13 -0
  98. package/lib/checkout-v2/layouts/checkout-layout.d.ts +7 -0
  99. package/lib/checkout-v2/layouts/checkout-layout.js +308 -0
  100. package/lib/checkout-v2/panels/left/composite-panel.d.ts +1 -0
  101. package/lib/checkout-v2/panels/left/composite-panel.js +515 -0
  102. package/lib/checkout-v2/panels/left/credit-topup-panel.d.ts +1 -0
  103. package/lib/checkout-v2/panels/left/credit-topup-panel.js +799 -0
  104. package/lib/checkout-v2/panels/left/scenario-router.d.ts +1 -0
  105. package/lib/checkout-v2/panels/left/scenario-router.js +29 -0
  106. package/lib/checkout-v2/panels/right/payment-panel.d.ts +1 -0
  107. package/lib/checkout-v2/panels/right/payment-panel.js +906 -0
  108. package/lib/checkout-v2/types.d.ts +15 -0
  109. package/lib/checkout-v2/types.js +1 -0
  110. package/lib/checkout-v2/utils/format.d.ts +59 -0
  111. package/lib/checkout-v2/utils/format.js +158 -0
  112. package/lib/checkout-v2/utils/scenario-detector.d.ts +3 -0
  113. package/lib/checkout-v2/utils/scenario-detector.js +23 -0
  114. package/lib/checkout-v2/views/error-view.d.ts +7 -0
  115. package/lib/checkout-v2/views/error-view.js +321 -0
  116. package/lib/checkout-v2/views/loading-view.d.ts +5 -0
  117. package/lib/checkout-v2/views/loading-view.js +168 -0
  118. package/lib/checkout-v2/views/success-view.d.ts +29 -0
  119. package/lib/checkout-v2/views/success-view.js +735 -0
  120. package/lib/components/phone-field.d.ts +14 -0
  121. package/lib/components/phone-field.js +130 -0
  122. package/lib/index.d.ts +3 -1
  123. package/lib/index.js +8 -0
  124. package/lib/locales/en.js +45 -6
  125. package/lib/locales/zh.js +45 -6
  126. package/lib/payment/form/index.js +10 -1
  127. package/package.json +4 -3
  128. package/src/checkout-v2/checkout-v2.tsx +155 -0
  129. package/src/checkout-v2/components/dialogs/checkout-dialogs.tsx +134 -0
  130. package/src/checkout-v2/components/left/billing-toggle.tsx +122 -0
  131. package/src/checkout-v2/components/left/cross-sell-card.tsx +170 -0
  132. package/src/checkout-v2/components/left/product-item-card.tsx +634 -0
  133. package/src/checkout-v2/components/left/promotion-input.tsx +207 -0
  134. package/src/checkout-v2/components/left/staking-breakdown.tsx +57 -0
  135. package/src/checkout-v2/components/left/trial-info.tsx +63 -0
  136. package/src/checkout-v2/components/right/currency-grid.tsx +59 -0
  137. package/src/checkout-v2/components/right/customer-info-card.tsx +214 -0
  138. package/src/checkout-v2/components/right/status-feedback.tsx +35 -0
  139. package/src/checkout-v2/components/right/submit-button.tsx +37 -0
  140. package/src/checkout-v2/components/right/subscription-disclaimer.tsx +27 -0
  141. package/src/checkout-v2/components/shared/exchange-rate-footer.tsx +221 -0
  142. package/src/checkout-v2/components/shared/scenario-badge.tsx +51 -0
  143. package/src/checkout-v2/components/shared/total-display.tsx +112 -0
  144. package/src/checkout-v2/index.ts +2 -0
  145. package/src/checkout-v2/layouts/checkout-layout.tsx +232 -0
  146. package/src/checkout-v2/panels/left/composite-panel.tsx +465 -0
  147. package/src/checkout-v2/panels/left/credit-topup-panel.tsx +681 -0
  148. package/src/checkout-v2/panels/left/scenario-router.tsx +22 -0
  149. package/src/checkout-v2/panels/right/payment-panel.tsx +703 -0
  150. package/src/checkout-v2/types.ts +18 -0
  151. package/src/checkout-v2/utils/format.ts +204 -0
  152. package/src/checkout-v2/utils/scenario-detector.ts +30 -0
  153. package/src/checkout-v2/views/error-view.tsx +293 -0
  154. package/src/checkout-v2/views/loading-view.tsx +162 -0
  155. package/src/checkout-v2/views/success-view.tsx +770 -0
  156. package/src/components/phone-field.tsx +119 -0
  157. package/src/index.ts +3 -0
  158. package/src/locales/en.tsx +45 -4
  159. package/src/locales/zh.tsx +43 -4
  160. package/src/payment/form/index.tsx +16 -1
@@ -0,0 +1,59 @@
1
+ import type { TPaymentCurrency } from '@blocklet/payment-types';
2
+ export declare const INTERVAL_LOCALE_KEY: Record<string, string>;
3
+ export declare function countryCodeToFlag(code: string): string;
4
+ export declare function formatTokenAmount(unitAmount: string | number | bigint, currency: TPaymentCurrency | null): string;
5
+ interface CurrencyOption {
6
+ currency_id: string;
7
+ unit_amount: string;
8
+ custom_unit_amount?: {
9
+ preset?: string;
10
+ presets?: string[];
11
+ } | null;
12
+ }
13
+ interface PriceWithDynamic {
14
+ pricing_type?: string;
15
+ base_amount?: string;
16
+ unit_amount?: string;
17
+ base_currency?: string;
18
+ currency_id?: string;
19
+ currency_options?: CurrencyOption[];
20
+ price_currency_options?: CurrencyOption[];
21
+ }
22
+ export declare function getUnitAmountForCurrency(price: PriceWithDynamic | null | undefined, currency: TPaymentCurrency | null): string;
23
+ export declare function formatDynamicUnitPrice(price: PriceWithDynamic | null | undefined, currency: TPaymentCurrency | null, exchangeRate: string | null): string | null;
24
+ export declare function tSafe(t: (key: string, params?: any) => string, key: string, fallback: string): string;
25
+ export declare const whiteTooltipSx: {
26
+ '& .MuiTooltip-tooltip': {
27
+ bgcolor: string;
28
+ color: string;
29
+ border: string;
30
+ borderColor: string;
31
+ borderRadius: string;
32
+ boxShadow: string;
33
+ p: number;
34
+ maxWidth: number;
35
+ fontSize: number;
36
+ };
37
+ '& .MuiTooltip-arrow': {
38
+ color: string;
39
+ '&::before': {
40
+ border: string;
41
+ borderColor: string;
42
+ };
43
+ };
44
+ };
45
+ export declare function formatTrialText(t: (key: string) => string, days: number, interval: string): string;
46
+ type TFn = (key: string, params?: Record<string, any>) => string;
47
+ export type ItemTypeBadge = 'subscription' | 'topup' | 'oneTime';
48
+ interface ItemMeta {
49
+ badge: ItemTypeBadge;
50
+ badgeLabel: string;
51
+ title: string;
52
+ subtitle: string;
53
+ }
54
+ /**
55
+ * Derive structured badge / title / subtitle for a checkout session header.
56
+ * Works for the "primary product" header above the item list.
57
+ */
58
+ export declare function getSessionHeaderMeta(t: TFn, session: any, product: any, items: any[]): ItemMeta;
59
+ export {};
@@ -0,0 +1,125 @@
1
+ import { fromUnitToToken } from "@ocap/util";
2
+ export const INTERVAL_LOCALE_KEY = {
3
+ day: "common.daily",
4
+ week: "common.weekly",
5
+ month: "common.monthly",
6
+ year: "common.yearly"
7
+ };
8
+ export function countryCodeToFlag(code) {
9
+ if (!code || code.length !== 2) return "";
10
+ return String.fromCodePoint(
11
+ ...code.toUpperCase().split("").map((c) => 127397 + c.charCodeAt(0))
12
+ );
13
+ }
14
+ export function formatTokenAmount(unitAmount, currency) {
15
+ if (!unitAmount || !currency) return "0";
16
+ try {
17
+ const tokenAmount = fromUnitToToken(String(unitAmount), currency.decimal || 0);
18
+ const num = Number(tokenAmount);
19
+ if (!Number.isFinite(num)) return "0";
20
+ const abs = Math.abs(num);
21
+ const precision = abs > 0 && abs < 0.01 ? 6 : 2;
22
+ const formatted = num.toLocaleString("en-US", { minimumFractionDigits: 0, maximumFractionDigits: precision });
23
+ return formatted.replace(/\.?0+$/, "") || "0";
24
+ } catch {
25
+ return "0";
26
+ }
27
+ }
28
+ export function getUnitAmountForCurrency(price, currency) {
29
+ if (!price || !currency) return "0";
30
+ const options = price.price_currency_options || price.currency_options || [];
31
+ const option = options.find((x) => x.currency_id === currency.id);
32
+ if (option) {
33
+ if (option.custom_unit_amount) {
34
+ return option.custom_unit_amount.preset || option.custom_unit_amount.presets?.[0] || option.unit_amount;
35
+ }
36
+ return option.unit_amount;
37
+ }
38
+ if (price.currency_id === currency.id) {
39
+ return price.unit_amount || "0";
40
+ }
41
+ return "0";
42
+ }
43
+ export function formatDynamicUnitPrice(price, currency, exchangeRate) {
44
+ if (!price || !currency) return null;
45
+ const isDynamic = price.pricing_type === "dynamic";
46
+ if (isDynamic && exchangeRate && price.base_amount) {
47
+ const rate = Number(exchangeRate);
48
+ if (rate > 0 && Number.isFinite(rate)) {
49
+ const baseUsd = Number(price.base_amount);
50
+ if (baseUsd > 0 && Number.isFinite(baseUsd)) {
51
+ const tokenAmount = baseUsd / rate;
52
+ const abs = Math.abs(tokenAmount);
53
+ const precision = abs > 0 && abs < 0.01 ? 6 : 2;
54
+ return tokenAmount.toLocaleString("en-US", { minimumFractionDigits: 0, maximumFractionDigits: precision }).replace(/\.?0+$/, "") || "0";
55
+ }
56
+ }
57
+ }
58
+ if (!exchangeRate && price.base_amount != null) {
59
+ const baseUsd = Number(price.base_amount);
60
+ if (baseUsd >= 0 && Number.isFinite(baseUsd)) {
61
+ return baseUsd.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
62
+ }
63
+ }
64
+ return formatTokenAmount(getUnitAmountForCurrency(price, currency), currency);
65
+ }
66
+ export function tSafe(t, key, fallback) {
67
+ const v = t(key);
68
+ return v && !v.includes(".") ? v : fallback;
69
+ }
70
+ export const whiteTooltipSx = {
71
+ "& .MuiTooltip-tooltip": {
72
+ bgcolor: "background.paper",
73
+ color: "text.primary",
74
+ border: "1px solid",
75
+ borderColor: "divider",
76
+ borderRadius: "10px",
77
+ boxShadow: "0 8px 24px rgba(0,0,0,0.12)",
78
+ p: 1.5,
79
+ maxWidth: 280,
80
+ fontSize: 12
81
+ },
82
+ "& .MuiTooltip-arrow": {
83
+ color: "background.paper",
84
+ "&::before": { border: "1px solid", borderColor: "divider" }
85
+ }
86
+ };
87
+ export function formatTrialText(t, days, interval) {
88
+ const intervalLabel = t(`common.${interval || "day"}`);
89
+ return `${days} ${intervalLabel}${days > 1 ? "s" : ""} free`;
90
+ }
91
+ export function getSessionHeaderMeta(t, session, product, items) {
92
+ const mode = session?.mode || "payment";
93
+ const isSubscription = ["subscription", "setup"].includes(mode);
94
+ const isCreditTopup = items.length === 1 && mode === "payment" && items[0]?.price?.product?.type === "credit" && items[0]?.price?.metadata?.credit_config;
95
+ let badge;
96
+ if (isCreditTopup) {
97
+ badge = "topup";
98
+ } else if (isSubscription) {
99
+ badge = "subscription";
100
+ } else {
101
+ badge = "oneTime";
102
+ }
103
+ const badgeLabel = t(`payment.checkout.typeBadge.${badge}`);
104
+ const productName = product?.name || items[0]?.price?.product?.name || "";
105
+ let title = productName;
106
+ if (productName) {
107
+ if (isSubscription) {
108
+ title = t("payment.checkout.headerTitle.subscribe", { name: productName });
109
+ } else if (!isCreditTopup) {
110
+ title = t("payment.checkout.headerTitle.purchase", { name: productName });
111
+ }
112
+ }
113
+ let subtitle = "";
114
+ if (isCreditTopup) {
115
+ subtitle = t("payment.checkout.subtitle.creditsTopup");
116
+ } else if (isSubscription) {
117
+ const planName = product?.metadata?.plan_name || product?.metadata?.plan_display_name;
118
+ if (planName) {
119
+ subtitle = planName;
120
+ }
121
+ } else {
122
+ subtitle = t("payment.checkout.subtitle.oneTime");
123
+ }
124
+ return { badge, badgeLabel, title, subtitle };
125
+ }
@@ -0,0 +1,3 @@
1
+ import type { TCheckoutSessionExpanded, TLineItemExpanded } from '@blocklet/payment-types';
2
+ import type { CheckoutScenario } from '../types';
3
+ export declare function detectScenario(session: TCheckoutSessionExpanded | null | undefined, items: TLineItemExpanded[]): CheckoutScenario;
@@ -0,0 +1,17 @@
1
+ export function detectScenario(session, items) {
2
+ if (!session) return "composite";
3
+ const isSingleItem = items.length === 1;
4
+ const isPaymentMode = session.mode === "payment";
5
+ const isSubscriptionMode = ["subscription", "setup"].includes(session.mode || "");
6
+ if (isSingleItem && isPaymentMode) {
7
+ const item = items[0];
8
+ const product = item.price?.product;
9
+ if (product?.type === "credit" && item.price?.metadata?.credit_config) {
10
+ return "credit-topup";
11
+ }
12
+ }
13
+ if (isSingleItem && isSubscriptionMode && !items.some((i) => i.cross_sell)) {
14
+ return "subscription";
15
+ }
16
+ return "composite";
17
+ }
@@ -0,0 +1,7 @@
1
+ interface ErrorViewProps {
2
+ error: string;
3
+ errorCode?: 'SESSION_EXPIRED' | 'EMPTY_LINE_ITEMS' | null;
4
+ mode?: string;
5
+ }
6
+ export default function ErrorView({ error, errorCode, mode }: ErrorViewProps): import("react").JSX.Element;
7
+ export {};
@@ -0,0 +1,269 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Box, Button, Stack, Typography } from "@mui/material";
3
+ import { alpha, useTheme } from "@mui/material/styles";
4
+ import ArrowBackIcon from "@mui/icons-material/ArrowBack";
5
+ import Header from "@blocklet/ui-react/lib/Header";
6
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
7
+ function GeometricDecoration() {
8
+ const theme = useTheme();
9
+ const gridColor = alpha(theme.palette.primary.main, 0.06);
10
+ return /* @__PURE__ */ jsxs(
11
+ Box,
12
+ {
13
+ sx: {
14
+ position: "relative",
15
+ width: { xs: 200, md: 260 },
16
+ height: { xs: 200, md: 260 },
17
+ mb: { xs: 4, md: 6 }
18
+ },
19
+ children: [
20
+ /* @__PURE__ */ jsx(
21
+ Box,
22
+ {
23
+ sx: {
24
+ position: "absolute",
25
+ inset: 0,
26
+ borderRadius: "38% 62% 63% 37% / 41% 44% 56% 59%",
27
+ background: (t) => `linear-gradient(45deg, ${alpha(t.palette.primary.main, 0.1)}, ${alpha(t.palette.primary.main, 0.03)})`,
28
+ filter: "blur(1px)",
29
+ animation: "spin 20s linear infinite",
30
+ "@keyframes spin": { from: { transform: "rotate(0deg)" }, to: { transform: "rotate(360deg)" } }
31
+ }
32
+ }
33
+ ),
34
+ /* @__PURE__ */ jsx(
35
+ Box,
36
+ {
37
+ sx: {
38
+ position: "absolute",
39
+ inset: 0,
40
+ borderRadius: "38% 62% 63% 37% / 41% 44% 56% 59%",
41
+ background: (t) => `linear-gradient(135deg, ${alpha(t.palette.primary.main, 0.07)}, ${alpha(t.palette.primary.main, 0.01)})`,
42
+ filter: "blur(1px)",
43
+ transform: "scale(0.88)",
44
+ opacity: 0.6,
45
+ animation: "spinReverse 15s linear infinite",
46
+ "@keyframes spinReverse": {
47
+ from: { transform: "scale(0.88) rotate(0deg)" },
48
+ to: { transform: "scale(0.88) rotate(-360deg)" }
49
+ }
50
+ }
51
+ }
52
+ ),
53
+ /* @__PURE__ */ jsx(
54
+ Box,
55
+ {
56
+ sx: {
57
+ position: "absolute",
58
+ inset: 0,
59
+ borderRadius: "38% 62% 63% 37% / 41% 44% 56% 59%",
60
+ overflow: "hidden",
61
+ animation: "spin 20s linear infinite"
62
+ },
63
+ children: /* @__PURE__ */ jsxs(
64
+ "svg",
65
+ {
66
+ width: "100%",
67
+ height: "100%",
68
+ viewBox: "0 0 260 260",
69
+ fill: "none",
70
+ xmlns: "http://www.w3.org/2000/svg",
71
+ style: { position: "absolute", inset: 0 },
72
+ children: [
73
+ [52, 87, 122, 157, 192].map((y) => /* @__PURE__ */ jsx("line", { x1: "30", y1: y, x2: "230", y2: y, stroke: gridColor, strokeWidth: "0.5" }, `h${y}`)),
74
+ [52, 87, 122, 157, 192].map((x) => /* @__PURE__ */ jsx("line", { x1: x, y1: "30", x2: x, y2: "230", stroke: gridColor, strokeWidth: "0.5" }, `v${x}`)),
75
+ /* @__PURE__ */ jsx("line", { x1: "52", y1: "52", x2: "192", y2: "192", stroke: gridColor, strokeWidth: "0.5" }),
76
+ /* @__PURE__ */ jsx("line", { x1: "192", y1: "52", x2: "52", y2: "192", stroke: gridColor, strokeWidth: "0.5" }),
77
+ /* @__PURE__ */ jsx("circle", { cx: "130", cy: "130", r: "40", stroke: gridColor, strokeWidth: "0.5" }),
78
+ /* @__PURE__ */ jsx("circle", { cx: "130", cy: "130", r: "75", stroke: gridColor, strokeWidth: "0.5" }),
79
+ [
80
+ [122, 87],
81
+ [157, 87],
82
+ [87, 122],
83
+ [122, 122],
84
+ [157, 122],
85
+ [192, 122],
86
+ [87, 157],
87
+ [122, 157],
88
+ [157, 157],
89
+ [122, 192],
90
+ [157, 192]
91
+ ].map(([cx, cy]) => /* @__PURE__ */ jsx("circle", { cx, cy, r: "1.5", fill: gridColor }, `d${cx}-${cy}`))
92
+ ]
93
+ }
94
+ )
95
+ }
96
+ )
97
+ ]
98
+ }
99
+ );
100
+ }
101
+ function getErrorConfig(errorCode, error, t) {
102
+ if (errorCode === "SESSION_EXPIRED") {
103
+ return {
104
+ title: t("payment.checkout.expired.title"),
105
+ description: t("payment.checkout.expired.description"),
106
+ color: "#f59e0b"
107
+ };
108
+ }
109
+ if (errorCode === "EMPTY_LINE_ITEMS") {
110
+ return {
111
+ title: t("payment.checkout.emptyItems.title"),
112
+ description: t("payment.checkout.emptyItems.description"),
113
+ color: "#94a3b8"
114
+ };
115
+ }
116
+ return {
117
+ title: t("payment.checkout.error.title"),
118
+ description: error,
119
+ color: "#ef4444"
120
+ };
121
+ }
122
+ function ErrorContent({ error, errorCode = void 0 }) {
123
+ const { t } = useLocaleContext();
124
+ const theme = useTheme();
125
+ const { title, description } = getErrorConfig(errorCode, error, t);
126
+ const primaryColor = theme.palette.primary.main;
127
+ const appUrl = typeof window !== "undefined" ? window.blocklet?.appUrl : "/";
128
+ return /* @__PURE__ */ jsxs(Stack, { alignItems: "center", justifyContent: "center", sx: { flex: 1, textAlign: "center", px: 3 }, children: [
129
+ /* @__PURE__ */ jsx(GeometricDecoration, {}),
130
+ /* @__PURE__ */ jsx(
131
+ Typography,
132
+ {
133
+ component: "h1",
134
+ sx: {
135
+ fontWeight: 800,
136
+ fontSize: { xs: 36, md: 52 },
137
+ lineHeight: 1.05,
138
+ letterSpacing: "-0.03em",
139
+ color: "text.primary",
140
+ mb: 2
141
+ },
142
+ children: title
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsx(
146
+ Typography,
147
+ {
148
+ sx: {
149
+ color: "text.secondary",
150
+ fontSize: { xs: 15, md: 17 },
151
+ fontWeight: 300,
152
+ lineHeight: 1.7,
153
+ maxWidth: 420,
154
+ letterSpacing: "0.01em"
155
+ },
156
+ children: description
157
+ }
158
+ ),
159
+ appUrl && /* @__PURE__ */ jsx(
160
+ Button,
161
+ {
162
+ href: appUrl,
163
+ variant: "contained",
164
+ disableElevation: true,
165
+ startIcon: /* @__PURE__ */ jsx(ArrowBackIcon, { sx: { fontSize: "20px !important" } }),
166
+ sx: {
167
+ mt: 5,
168
+ minWidth: 240,
169
+ height: 56,
170
+ px: 6,
171
+ borderRadius: "9999px",
172
+ textTransform: "none",
173
+ fontWeight: 600,
174
+ fontSize: 16,
175
+ letterSpacing: "0.02em",
176
+ boxShadow: `0 8px 32px -4px ${alpha(primaryColor, 0.3)}`,
177
+ "&:hover": {
178
+ boxShadow: `0 12px 40px -4px ${alpha(primaryColor, 0.4)}`,
179
+ transform: "translateY(-1px)"
180
+ },
181
+ transition: "all 0.2s ease"
182
+ },
183
+ children: t("common.back")
184
+ }
185
+ )
186
+ ] });
187
+ }
188
+ export default function ErrorView({ error, errorCode = void 0, mode = "inline" }) {
189
+ const theme = useTheme();
190
+ const primaryColor = theme.palette.primary.main;
191
+ const isFullScreen = mode === "standalone";
192
+ const meshBg = {
193
+ bgcolor: (t) => t.palette.mode === "dark" ? "background.default" : "#f8faff",
194
+ backgroundImage: (t) => t.palette.mode === "dark" ? "none" : `radial-gradient(at 0% 0%, ${alpha(primaryColor, 0.06)} 0px, transparent 50%),
195
+ radial-gradient(at 100% 0%, ${alpha(primaryColor, 0.04)} 0px, transparent 50%),
196
+ radial-gradient(at 100% 100%, ${alpha(primaryColor, 0.06)} 0px, transparent 50%),
197
+ radial-gradient(at 0% 100%, rgba(203,213,225,0.3) 0px, transparent 50%)`
198
+ };
199
+ if (!isFullScreen) {
200
+ return /* @__PURE__ */ jsx(
201
+ Box,
202
+ {
203
+ sx: {
204
+ display: "flex",
205
+ width: "100%",
206
+ minHeight: { xs: 400, md: 520 },
207
+ maxWidth: 1120,
208
+ mx: "auto",
209
+ borderRadius: "16px",
210
+ overflow: "hidden",
211
+ boxShadow: 1,
212
+ border: 1,
213
+ borderColor: "divider",
214
+ ...meshBg
215
+ },
216
+ children: /* @__PURE__ */ jsx(
217
+ Box,
218
+ {
219
+ sx: {
220
+ flex: 1,
221
+ p: { xs: 4, md: 6 },
222
+ display: "flex",
223
+ flexDirection: "column",
224
+ justifyContent: "center",
225
+ alignItems: "center"
226
+ },
227
+ children: /* @__PURE__ */ jsx(ErrorContent, { error, errorCode })
228
+ }
229
+ )
230
+ }
231
+ );
232
+ }
233
+ return /* @__PURE__ */ jsxs(
234
+ Box,
235
+ {
236
+ sx: {
237
+ width: "100%",
238
+ height: "100vh",
239
+ minHeight: "100vh",
240
+ display: "flex",
241
+ flexDirection: "column",
242
+ position: "relative",
243
+ overflow: "hidden",
244
+ ...meshBg
245
+ },
246
+ children: [
247
+ /* @__PURE__ */ jsx(
248
+ Header,
249
+ {
250
+ sx: {
251
+ position: "absolute",
252
+ top: 20,
253
+ left: 0,
254
+ right: 0,
255
+ zIndex: 10,
256
+ background: "transparent",
257
+ "& .header-container": { height: "auto" }
258
+ },
259
+ hideNavMenu: true,
260
+ brand: null,
261
+ description: null,
262
+ addons: (buildIns) => buildIns.filter((addon) => ["locale-selector", "theme-mode-toggle", "session-user"].includes(addon.key))
263
+ }
264
+ ),
265
+ /* @__PURE__ */ jsx(ErrorContent, { error, errorCode })
266
+ ]
267
+ }
268
+ );
269
+ }
@@ -0,0 +1,5 @@
1
+ interface LoadingViewProps {
2
+ mode?: string;
3
+ }
4
+ export default function LoadingView({ mode }: LoadingViewProps): import("react").JSX.Element;
5
+ export {};
@@ -0,0 +1,158 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Box } from "@mui/material";
3
+ import { alpha, useTheme } from "@mui/material/styles";
4
+ import Header from "@blocklet/ui-react/lib/Header";
5
+ function PulsingDots() {
6
+ return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", gap: 2, mt: 4 }, children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx(
7
+ Box,
8
+ {
9
+ sx: {
10
+ width: 12,
11
+ height: 12,
12
+ borderRadius: "50%",
13
+ bgcolor: "primary.main",
14
+ opacity: 0.4,
15
+ animation: `pulse 1.4s ease-in-out ${i * 0.2}s infinite`,
16
+ "@keyframes pulse": {
17
+ "0%, 80%, 100%": { transform: "scale(0.6)", opacity: 0.3 },
18
+ "40%": { transform: "scale(1)", opacity: 0.7 }
19
+ }
20
+ }
21
+ },
22
+ i
23
+ )) });
24
+ }
25
+ function LoadingDecoration() {
26
+ return /* @__PURE__ */ jsxs(
27
+ Box,
28
+ {
29
+ sx: {
30
+ position: "relative",
31
+ width: { xs: 160, md: 200 },
32
+ height: { xs: 160, md: 200 }
33
+ },
34
+ children: [
35
+ /* @__PURE__ */ jsx(
36
+ Box,
37
+ {
38
+ sx: {
39
+ position: "absolute",
40
+ inset: 0,
41
+ borderRadius: "38% 62% 63% 37% / 41% 44% 56% 59%",
42
+ background: (t) => `linear-gradient(45deg, ${alpha(t.palette.primary.main, 0.1)}, ${alpha(t.palette.primary.main, 0.03)})`,
43
+ filter: "blur(1px)",
44
+ animation: "spin 20s linear infinite",
45
+ "@keyframes spin": { from: { transform: "rotate(0deg)" }, to: { transform: "rotate(360deg)" } }
46
+ }
47
+ }
48
+ ),
49
+ /* @__PURE__ */ jsx(
50
+ Box,
51
+ {
52
+ sx: {
53
+ position: "absolute",
54
+ inset: 0,
55
+ borderRadius: "38% 62% 63% 37% / 41% 44% 56% 59%",
56
+ background: (t) => `linear-gradient(135deg, ${alpha(t.palette.primary.main, 0.07)}, ${alpha(t.palette.primary.main, 0.01)})`,
57
+ filter: "blur(1px)",
58
+ transform: "scale(0.88)",
59
+ opacity: 0.6,
60
+ animation: "spinReverse 15s linear infinite",
61
+ "@keyframes spinReverse": {
62
+ from: { transform: "scale(0.88) rotate(0deg)" },
63
+ to: { transform: "scale(0.88) rotate(-360deg)" }
64
+ }
65
+ }
66
+ }
67
+ )
68
+ ]
69
+ }
70
+ );
71
+ }
72
+ export default function LoadingView({ mode = "inline" }) {
73
+ const isFullScreen = mode === "standalone";
74
+ const theme = useTheme();
75
+ const primaryColor = theme.palette.primary.main;
76
+ const bgSx = {
77
+ background: {
78
+ xs: "none",
79
+ md: `linear-gradient(160deg, ${alpha(primaryColor, 0.03)} 0%, ${alpha(primaryColor, 0.07)} 50%, ${alpha(primaryColor, 0.04)} 100%)`
80
+ },
81
+ bgcolor: (t) => t.palette.mode === "dark" ? "background.default" : "#f8faff"
82
+ };
83
+ const centerContent = /* @__PURE__ */ jsxs(
84
+ Box,
85
+ {
86
+ sx: {
87
+ display: "flex",
88
+ flexDirection: "column",
89
+ alignItems: "center",
90
+ justifyContent: "center",
91
+ flex: 1
92
+ },
93
+ children: [
94
+ /* @__PURE__ */ jsx(LoadingDecoration, {}),
95
+ /* @__PURE__ */ jsx(PulsingDots, {})
96
+ ]
97
+ }
98
+ );
99
+ if (!isFullScreen) {
100
+ return /* @__PURE__ */ jsx(
101
+ Box,
102
+ {
103
+ sx: {
104
+ display: "flex",
105
+ width: "100%",
106
+ minHeight: { xs: 400, md: 640 },
107
+ maxWidth: 1120,
108
+ mx: "auto",
109
+ borderRadius: "16px",
110
+ overflow: "hidden",
111
+ boxShadow: 1,
112
+ border: 1,
113
+ borderColor: "divider",
114
+ borderLeft: "4px solid",
115
+ borderLeftColor: "primary.main",
116
+ ...bgSx
117
+ },
118
+ children: centerContent
119
+ }
120
+ );
121
+ }
122
+ return /* @__PURE__ */ jsxs(
123
+ Box,
124
+ {
125
+ sx: {
126
+ width: "100%",
127
+ height: "100vh",
128
+ minHeight: "100vh",
129
+ display: "flex",
130
+ flexDirection: "column",
131
+ position: "relative",
132
+ overflow: "hidden",
133
+ ...bgSx
134
+ },
135
+ children: [
136
+ /* @__PURE__ */ jsx(
137
+ Header,
138
+ {
139
+ sx: {
140
+ position: "absolute",
141
+ top: 20,
142
+ left: 0,
143
+ right: 0,
144
+ zIndex: 10,
145
+ background: "transparent",
146
+ "& .header-container": { height: "auto" }
147
+ },
148
+ hideNavMenu: true,
149
+ brand: null,
150
+ description: null,
151
+ addons: (buildIns) => buildIns.filter((addon) => ["locale-selector", "theme-mode-toggle", "session-user"].includes(addon.key))
152
+ }
153
+ ),
154
+ centerContent
155
+ ]
156
+ }
157
+ );
158
+ }
@@ -0,0 +1,29 @@
1
+ import type { TCheckoutSessionExpanded } from '@blocklet/payment-types';
2
+ interface VendorInfo {
3
+ success: boolean;
4
+ status: 'delivered' | 'pending' | 'failed';
5
+ progress: number;
6
+ message: string;
7
+ appUrl?: string;
8
+ title?: string;
9
+ name?: string;
10
+ vendorType: string;
11
+ }
12
+ interface SuccessViewProps {
13
+ submit: {
14
+ vendorStatus: {
15
+ payment_status: string;
16
+ session_status: string;
17
+ vendors: VendorInfo[];
18
+ error: string | null;
19
+ isAllCompleted: boolean;
20
+ hasFailed: boolean;
21
+ } | null;
22
+ result: {
23
+ checkoutSession: TCheckoutSessionExpanded;
24
+ } | null;
25
+ };
26
+ session: TCheckoutSessionExpanded | null | undefined;
27
+ }
28
+ export default function SuccessView({ submit, session }: SuccessViewProps): import("react").JSX.Element;
29
+ export {};