@blocklet/payment-react 1.20.21 → 1.21.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.
package/es/locales/en.js CHANGED
@@ -185,7 +185,17 @@ export default flat({
185
185
  progress: "Progress {progress}%",
186
186
  delivered: "Installation completed",
187
187
  failed: "Processing failed",
188
- failedMsg: "An exception occurred during installation. We will automatically process a refund for you. We apologize for the inconvenience. Thank you for your understanding!"
188
+ failedMsg: "An exception occurred during installation. We will automatically process a refund for you. We apologize for the inconvenience. Thank you for your understanding!",
189
+ launcher: {
190
+ processing: "Installing {name}",
191
+ completed: "{name} installed successfully",
192
+ failed: "Failed to install {name}"
193
+ },
194
+ didnames: {
195
+ processing: "Domain ({domain}) registering",
196
+ completed: "Domain ({domain}) registered successfully",
197
+ failed: "Domain ({domain}) registered failed"
198
+ }
189
199
  },
190
200
  confirm: {
191
201
  withStake: "By confirming, you allow {payee} to charge your account for future payments and, if necessary, slash your stake. You can cancel your subscription or withdraw your stake at any time.",
package/es/locales/zh.js CHANGED
@@ -185,7 +185,17 @@ export default flat({
185
185
  progress: "\u8FDB\u5EA6 {progress}%",
186
186
  delivered: "\u5B89\u88C5\u6210\u529F",
187
187
  failed: "\u5B89\u88C5\u5931\u8D25",
188
- failedMsg: "\u5F88\u62B1\u6B49\uFF0C\u5B89\u88C5\u8FC7\u7A0B\u4E2D\u9047\u5230\u4E86\u4E00\u4E9B\u95EE\u9898\u3002\u6211\u4EEC\u6B63\u5728\u5904\u7406\u8FD9\u4E2A\u95EE\u9898\uFF0C\u7A0D\u540E\u4F1A\u81EA\u52A8\u4E3A\u60A8\u9000\u6B3E\u3002\u611F\u8C22\u60A8\u7684\u8010\u5FC3\u7B49\u5F85\uFF01"
188
+ failedMsg: "\u5F88\u62B1\u6B49\uFF0C\u5B89\u88C5\u8FC7\u7A0B\u4E2D\u9047\u5230\u4E86\u4E00\u4E9B\u95EE\u9898\u3002\u6211\u4EEC\u6B63\u5728\u5904\u7406\u8FD9\u4E2A\u95EE\u9898\uFF0C\u7A0D\u540E\u4F1A\u81EA\u52A8\u4E3A\u60A8\u9000\u6B3E\u3002\u611F\u8C22\u60A8\u7684\u8010\u5FC3\u7B49\u5F85\uFF01",
189
+ launcher: {
190
+ processing: "\u6B63\u5728\u5B89\u88C5 {name}",
191
+ completed: "\u5B89\u88C5 {name} \u6210\u529F",
192
+ failed: "\u5B89\u88C5 {name} \u5931\u8D25"
193
+ },
194
+ didnames: {
195
+ processing: "\u6B63\u5728\u6CE8\u518C {domain}",
196
+ completed: "\u6CE8\u518C {domain} \u6210\u529F",
197
+ failed: "\u6CE8\u518C {domain} \u5931\u8D25"
198
+ }
189
199
  },
190
200
  confirm: {
191
201
  withStake: "\u786E\u8BA4\u8BA2\u9605\uFF0C\u5373\u8868\u793A\u60A8\u6388\u6743 {payee} \u4ECE\u60A8\u7684\u8D26\u6237\u6263\u53D6\u672A\u6765\u6B3E\u9879\uFF0C\u5E76\u5728\u5FC5\u8981\u65F6\u7F5A\u6CA1\u8D28\u62BC\u3002\u60A8\u53EF\u968F\u65F6\u53D6\u6D88\u8BA2\u9605\u6216\u64A4\u9500\u8D28\u62BC\u3002",
@@ -304,7 +304,9 @@ function PaymentInner({
304
304
  {
305
305
  mode,
306
306
  pageInfo: state.checkoutSession.metadata?.page_info,
307
- hasVendor: state.checkoutSession.metadata?.page_info?.hasVendor || state.checkoutSession.line_items.some((item) => item.price?.product?.vendor_config?.length > 0),
307
+ vendorCount: state.checkoutSession.line_items.reduce((total, item) => {
308
+ return total + (item.price?.product?.vendor_config?.length || 0);
309
+ }, 0),
308
310
  sessionId: state.checkoutSession.id,
309
311
  payee: getStatementDescriptor(state.checkoutSession.line_items),
310
312
  action: state.checkoutSession.mode,
@@ -1,3 +1,4 @@
1
+ export declare function VendorPlaceholder(): import("react").JSX.Element;
1
2
  interface VendorStatus {
2
3
  success: boolean;
3
4
  name?: string;
@@ -7,6 +8,7 @@ interface VendorStatus {
7
8
  message: string;
8
9
  appUrl?: string;
9
10
  title?: string;
11
+ vendorType: string;
10
12
  }
11
13
  export declare function VendorProgressItem({ vendor }: {
12
14
  vendor: VendorStatus;
@@ -1,7 +1,37 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
3
- import { Box, LinearProgress, Typography } from "@mui/material";
3
+ import { Box, LinearProgress, Skeleton, Typography } from "@mui/material";
4
4
  import { useCallback, useEffect, useRef, useState } from "react";
5
+ import { Check } from "@mui/icons-material";
6
+ export function VendorPlaceholder() {
7
+ return /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
8
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }, children: [
9
+ /* @__PURE__ */ jsx(Skeleton, { variant: "rounded", height: 16, width: 150 }),
10
+ /* @__PURE__ */ jsx(Skeleton, { variant: "rounded", height: 16, width: 50 })
11
+ ] }),
12
+ /* @__PURE__ */ jsx(Skeleton, { variant: "rounded", height: 8, width: "100%" })
13
+ ] });
14
+ }
15
+ const getVendorLabel = (vendor, isFailed, t) => {
16
+ const name = vendor.name || vendor.title;
17
+ const isCompleted = vendor.status === "delivered";
18
+ if (vendor.vendorType === "didnames") {
19
+ if (isFailed) {
20
+ return t("payment.checkout.vendor.didnames.failed", { name });
21
+ }
22
+ if (isCompleted) {
23
+ return t("payment.checkout.vendor.didnames.completed", { name });
24
+ }
25
+ return t("payment.checkout.vendor.didnames.processing", { name });
26
+ }
27
+ if (isFailed) {
28
+ return t("payment.checkout.vendor.launcher.failed", { name });
29
+ }
30
+ if (isCompleted) {
31
+ return t("payment.checkout.vendor.launcher.completed", { name });
32
+ }
33
+ return t("payment.checkout.vendor.launcher.processing", { name });
34
+ };
5
35
  export function VendorProgressItem({ vendor }) {
6
36
  const { t } = useLocaleContext();
7
37
  const [displayProgress, setDisplayProgress] = useState(0);
@@ -29,7 +59,7 @@ export function VendorProgressItem({ vendor }) {
29
59
  newProgress = Math.min(startProgress + elapsed / 1e3, 99);
30
60
  }
31
61
  newProgress = Math.round(newProgress);
32
- setDisplayProgress((pre) => pre > newProgress ? pre : newProgress);
62
+ setDisplayProgress((pre) => Math.min(pre > newProgress ? pre : newProgress, 100));
33
63
  if (realProgress === 100) {
34
64
  return;
35
65
  }
@@ -52,11 +82,11 @@ export function VendorProgressItem({ vendor }) {
52
82
  }, [startAnimation]);
53
83
  const isCompleted = displayProgress >= 100;
54
84
  const isFailed = vendor.status === "failed";
55
- const nameText = vendor.name || vendor.title;
85
+ const nameText = getVendorLabel(vendor, isFailed, t);
56
86
  if (isFailed) {
57
87
  return /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
58
88
  /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }, children: [
59
- /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary" }, children: nameText ? `${nameText} - ${t("payment.checkout.vendor.failed")}` : t("payment.checkout.vendor.failed") }),
89
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary" }, children: nameText }),
60
90
  /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "error.main", fontWeight: 500 }, children: t("payment.checkout.vendor.progress", { progress: 0 }) })
61
91
  ] }),
62
92
  /* @__PURE__ */ jsx(
@@ -77,17 +107,23 @@ export function VendorProgressItem({ vendor }) {
77
107
  )
78
108
  ] });
79
109
  }
80
- const statusText = isCompleted ? t("payment.checkout.vendor.delivered") : t("payment.checkout.vendor.processing");
110
+ if (!vendor.name && !vendor.title) {
111
+ return /* @__PURE__ */ jsx(VendorPlaceholder, {});
112
+ }
81
113
  return /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
82
114
  /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }, children: [
83
- /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary" }, children: nameText ? `${nameText} - ${statusText}` : statusText }),
84
- /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary", fontWeight: 500 }, children: t("payment.checkout.vendor.progress", { progress: displayProgress }) })
115
+ /* @__PURE__ */ jsxs(Typography, { variant: "body2", sx: { color: "text.secondary", display: "flex", alignItems: "center" }, children: [
116
+ nameText,
117
+ " ",
118
+ isCompleted ? /* @__PURE__ */ jsx(Check, { sx: { color: "success.main", ml: 0.5 }, fontSize: "small" }) : null
119
+ ] }),
120
+ isCompleted ? null : /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary", fontWeight: 500 }, children: t("payment.checkout.vendor.progress", { progress: displayProgress }) })
85
121
  ] }),
86
122
  /* @__PURE__ */ jsx(
87
123
  LinearProgress,
88
124
  {
89
125
  variant: "determinate",
90
- value: Math.min(displayProgress, 100),
126
+ value: displayProgress || 0,
91
127
  sx: {
92
128
  height: 8,
93
129
  borderRadius: 4,
@@ -1,7 +1,7 @@
1
1
  type Props = {
2
2
  mode: string;
3
3
  pageInfo?: any;
4
- hasVendor?: boolean;
4
+ vendorCount?: number;
5
5
  sessionId?: string;
6
6
  message: string;
7
7
  action: string;
@@ -10,5 +10,5 @@ type Props = {
10
10
  subscriptionId?: string;
11
11
  subscriptions?: any[];
12
12
  };
13
- export default function PaymentSuccess({ mode, pageInfo, hasVendor, sessionId, message, action, payee, invoiceId, subscriptionId, subscriptions, }: Props): import("react").JSX.Element;
13
+ export default function PaymentSuccess({ mode, pageInfo, vendorCount, sessionId, message, action, payee, invoiceId, subscriptionId, subscriptions, }: Props): import("react").JSX.Element;
14
14
  export {};
@@ -5,11 +5,11 @@ import { useEffect, useRef, useState } from "react";
5
5
  import { joinURL } from "ufo";
6
6
  import { Button } from "@arcblock/ux";
7
7
  import { usePaymentContext } from "../contexts/payment.js";
8
- import { VendorProgressItem } from "./progress-item.js";
8
+ import { VendorPlaceholder, VendorProgressItem } from "./progress-item.js";
9
9
  export default function PaymentSuccess({
10
10
  mode,
11
11
  pageInfo = {},
12
- hasVendor = false,
12
+ vendorCount = 0,
13
13
  sessionId = "",
14
14
  message,
15
15
  action,
@@ -26,7 +26,7 @@ export default function PaymentSuccess({
26
26
  const timerRef = useRef(Date.now());
27
27
  let next = null;
28
28
  useEffect(() => {
29
- if (!hasVendor || !sessionId) return void 0;
29
+ if (vendorCount === 0 || !sessionId) return void 0;
30
30
  const fetchVendorStatus = async (interval2) => {
31
31
  try {
32
32
  const response = await api.get(joinURL(prefix, `/api/vendors/order/${sessionId}/status`), {});
@@ -50,9 +50,22 @@ export default function PaymentSuccess({
50
50
  fetchVendorStatus(interval);
51
51
  }, 5e3);
52
52
  return () => clearInterval(interval);
53
- }, [hasVendor, api, prefix, sessionId]);
53
+ }, [vendorCount, api, prefix, sessionId]);
54
+ const renderPlaceholders = () => {
55
+ const placeholders = [];
56
+ for (let i = 0; i < vendorCount; i++) {
57
+ placeholders.push(/* @__PURE__ */ jsx(VendorPlaceholder, {}, `placeholder-${i}`));
58
+ }
59
+ return placeholders;
60
+ };
61
+ const renderVendors = () => {
62
+ if (!vendorStatus) return renderPlaceholders();
63
+ return vendorStatus.vendors?.map((vendor, index) => {
64
+ return /* @__PURE__ */ jsx(VendorProgressItem, { vendor }, vendor.title || `vendor-${index}`);
65
+ });
66
+ };
54
67
  const renderVendorProgress = () => {
55
- if (!hasVendor || !vendorStatus) return null;
68
+ if (vendorCount === 0) return null;
56
69
  return /* @__PURE__ */ jsxs(
57
70
  Paper,
58
71
  {
@@ -68,7 +81,7 @@ export default function PaymentSuccess({
68
81
  gap: 2
69
82
  },
70
83
  children: [
71
- vendorStatus.vendors?.map((vendor, index) => /* @__PURE__ */ jsx(VendorProgressItem, { vendor }, vendor.title || `vendor-${index}`)),
84
+ renderVendors(),
72
85
  hasFailed ? /* @__PURE__ */ jsx(Typography, { variant: "h6", sx: { color: "warning.main", mb: 1 }, children: t("payment.checkout.vendor.failedMsg") }) : null,
73
86
  pageInfo?.success_message?.[locale] && isAllCompleted ? /* @__PURE__ */ jsx(Typography, { variant: "h6", sx: { color: "text.primary", mb: 1 }, children: pageInfo?.success_message?.[locale] }) : null
74
87
  ]
package/lib/locales/en.js CHANGED
@@ -192,7 +192,17 @@ module.exports = (0, _flat.default)({
192
192
  progress: "Progress {progress}%",
193
193
  delivered: "Installation completed",
194
194
  failed: "Processing failed",
195
- failedMsg: "An exception occurred during installation. We will automatically process a refund for you. We apologize for the inconvenience. Thank you for your understanding!"
195
+ failedMsg: "An exception occurred during installation. We will automatically process a refund for you. We apologize for the inconvenience. Thank you for your understanding!",
196
+ launcher: {
197
+ processing: "Installing {name}",
198
+ completed: "{name} installed successfully",
199
+ failed: "Failed to install {name}"
200
+ },
201
+ didnames: {
202
+ processing: "Domain ({domain}) registering",
203
+ completed: "Domain ({domain}) registered successfully",
204
+ failed: "Domain ({domain}) registered failed"
205
+ }
196
206
  },
197
207
  confirm: {
198
208
  withStake: "By confirming, you allow {payee} to charge your account for future payments and, if necessary, slash your stake. You can cancel your subscription or withdraw your stake at any time.",
package/lib/locales/zh.js CHANGED
@@ -192,7 +192,17 @@ module.exports = (0, _flat.default)({
192
192
  progress: "\u8FDB\u5EA6 {progress}%",
193
193
  delivered: "\u5B89\u88C5\u6210\u529F",
194
194
  failed: "\u5B89\u88C5\u5931\u8D25",
195
- failedMsg: "\u5F88\u62B1\u6B49\uFF0C\u5B89\u88C5\u8FC7\u7A0B\u4E2D\u9047\u5230\u4E86\u4E00\u4E9B\u95EE\u9898\u3002\u6211\u4EEC\u6B63\u5728\u5904\u7406\u8FD9\u4E2A\u95EE\u9898\uFF0C\u7A0D\u540E\u4F1A\u81EA\u52A8\u4E3A\u60A8\u9000\u6B3E\u3002\u611F\u8C22\u60A8\u7684\u8010\u5FC3\u7B49\u5F85\uFF01"
195
+ failedMsg: "\u5F88\u62B1\u6B49\uFF0C\u5B89\u88C5\u8FC7\u7A0B\u4E2D\u9047\u5230\u4E86\u4E00\u4E9B\u95EE\u9898\u3002\u6211\u4EEC\u6B63\u5728\u5904\u7406\u8FD9\u4E2A\u95EE\u9898\uFF0C\u7A0D\u540E\u4F1A\u81EA\u52A8\u4E3A\u60A8\u9000\u6B3E\u3002\u611F\u8C22\u60A8\u7684\u8010\u5FC3\u7B49\u5F85\uFF01",
196
+ launcher: {
197
+ processing: "\u6B63\u5728\u5B89\u88C5 {name}",
198
+ completed: "\u5B89\u88C5 {name} \u6210\u529F",
199
+ failed: "\u5B89\u88C5 {name} \u5931\u8D25"
200
+ },
201
+ didnames: {
202
+ processing: "\u6B63\u5728\u6CE8\u518C {domain}",
203
+ completed: "\u6CE8\u518C {domain} \u6210\u529F",
204
+ failed: "\u6CE8\u518C {domain} \u5931\u8D25"
205
+ }
196
206
  },
197
207
  confirm: {
198
208
  withStake: "\u786E\u8BA4\u8BA2\u9605\uFF0C\u5373\u8868\u793A\u60A8\u6388\u6743 {payee} \u4ECE\u60A8\u7684\u8D26\u6237\u6263\u53D6\u672A\u6765\u6B3E\u9879\uFF0C\u5E76\u5728\u5FC5\u8981\u65F6\u7F5A\u6CA1\u8D28\u62BC\u3002\u60A8\u53EF\u968F\u65F6\u53D6\u6D88\u8BA2\u9605\u6216\u64A4\u9500\u8D28\u62BC\u3002",
@@ -360,7 +360,9 @@ function PaymentInner({
360
360
  children: [completed && /* @__PURE__ */(0, _jsxRuntime.jsx)(_success.default, {
361
361
  mode,
362
362
  pageInfo: state.checkoutSession.metadata?.page_info,
363
- hasVendor: state.checkoutSession.metadata?.page_info?.hasVendor || state.checkoutSession.line_items.some(item => item.price?.product?.vendor_config?.length > 0),
363
+ vendorCount: state.checkoutSession.line_items.reduce((total, item) => {
364
+ return total + (item.price?.product?.vendor_config?.length || 0);
365
+ }, 0),
364
366
  sessionId: state.checkoutSession.id,
365
367
  payee: (0, _util2.getStatementDescriptor)(state.checkoutSession.line_items),
366
368
  action: state.checkoutSession.mode,
@@ -1,3 +1,4 @@
1
+ export declare function VendorPlaceholder(): import("react").JSX.Element;
1
2
  interface VendorStatus {
2
3
  success: boolean;
3
4
  name?: string;
@@ -7,6 +8,7 @@ interface VendorStatus {
7
8
  message: string;
8
9
  appUrl?: string;
9
10
  title?: string;
11
+ vendorType: string;
10
12
  }
11
13
  export declare function VendorProgressItem({ vendor }: {
12
14
  vendor: VendorStatus;
@@ -3,11 +3,73 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.VendorPlaceholder = VendorPlaceholder;
6
7
  exports.VendorProgressItem = VendorProgressItem;
7
8
  var _jsxRuntime = require("react/jsx-runtime");
8
9
  var _context = require("@arcblock/ux/lib/Locale/context");
9
10
  var _material = require("@mui/material");
10
11
  var _react = require("react");
12
+ var _iconsMaterial = require("@mui/icons-material");
13
+ function VendorPlaceholder() {
14
+ return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
15
+ sx: {
16
+ mb: 2
17
+ },
18
+ children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
19
+ sx: {
20
+ display: "flex",
21
+ justifyContent: "space-between",
22
+ alignItems: "center",
23
+ mb: 1
24
+ },
25
+ children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Skeleton, {
26
+ variant: "rounded",
27
+ height: 16,
28
+ width: 150
29
+ }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Skeleton, {
30
+ variant: "rounded",
31
+ height: 16,
32
+ width: 50
33
+ })]
34
+ }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Skeleton, {
35
+ variant: "rounded",
36
+ height: 8,
37
+ width: "100%"
38
+ })]
39
+ });
40
+ }
41
+ const getVendorLabel = (vendor, isFailed, t) => {
42
+ const name = vendor.name || vendor.title;
43
+ const isCompleted = vendor.status === "delivered";
44
+ if (vendor.vendorType === "didnames") {
45
+ if (isFailed) {
46
+ return t("payment.checkout.vendor.didnames.failed", {
47
+ name
48
+ });
49
+ }
50
+ if (isCompleted) {
51
+ return t("payment.checkout.vendor.didnames.completed", {
52
+ name
53
+ });
54
+ }
55
+ return t("payment.checkout.vendor.didnames.processing", {
56
+ name
57
+ });
58
+ }
59
+ if (isFailed) {
60
+ return t("payment.checkout.vendor.launcher.failed", {
61
+ name
62
+ });
63
+ }
64
+ if (isCompleted) {
65
+ return t("payment.checkout.vendor.launcher.completed", {
66
+ name
67
+ });
68
+ }
69
+ return t("payment.checkout.vendor.launcher.processing", {
70
+ name
71
+ });
72
+ };
11
73
  function VendorProgressItem({
12
74
  vendor
13
75
  }) {
@@ -39,7 +101,7 @@ function VendorProgressItem({
39
101
  newProgress = Math.min(startProgress + elapsed / 1e3, 99);
40
102
  }
41
103
  newProgress = Math.round(newProgress);
42
- setDisplayProgress(pre => pre > newProgress ? pre : newProgress);
104
+ setDisplayProgress(pre => Math.min(pre > newProgress ? pre : newProgress, 100));
43
105
  if (realProgress === 100) {
44
106
  return;
45
107
  }
@@ -62,7 +124,7 @@ function VendorProgressItem({
62
124
  }, [startAnimation]);
63
125
  const isCompleted = displayProgress >= 100;
64
126
  const isFailed = vendor.status === "failed";
65
- const nameText = vendor.name || vendor.title;
127
+ const nameText = getVendorLabel(vendor, isFailed, t);
66
128
  if (isFailed) {
67
129
  return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
68
130
  sx: {
@@ -80,7 +142,7 @@ function VendorProgressItem({
80
142
  sx: {
81
143
  color: "text.secondary"
82
144
  },
83
- children: nameText ? `${nameText} - ${t("payment.checkout.vendor.failed")}` : t("payment.checkout.vendor.failed")
145
+ children: nameText
84
146
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
85
147
  variant: "body2",
86
148
  sx: {
@@ -106,7 +168,9 @@ function VendorProgressItem({
106
168
  })]
107
169
  });
108
170
  }
109
- const statusText = isCompleted ? t("payment.checkout.vendor.delivered") : t("payment.checkout.vendor.processing");
171
+ if (!vendor.name && !vendor.title) {
172
+ return /* @__PURE__ */(0, _jsxRuntime.jsx)(VendorPlaceholder, {});
173
+ }
110
174
  return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
111
175
  sx: {
112
176
  mb: 2
@@ -118,13 +182,21 @@ function VendorProgressItem({
118
182
  alignItems: "center",
119
183
  mb: 1
120
184
  },
121
- children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
185
+ children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Typography, {
122
186
  variant: "body2",
123
187
  sx: {
124
- color: "text.secondary"
188
+ color: "text.secondary",
189
+ display: "flex",
190
+ alignItems: "center"
125
191
  },
126
- children: nameText ? `${nameText} - ${statusText}` : statusText
127
- }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
192
+ children: [nameText, " ", isCompleted ? /* @__PURE__ */(0, _jsxRuntime.jsx)(_iconsMaterial.Check, {
193
+ sx: {
194
+ color: "success.main",
195
+ ml: 0.5
196
+ },
197
+ fontSize: "small"
198
+ }) : null]
199
+ }), isCompleted ? null : /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
128
200
  variant: "body2",
129
201
  sx: {
130
202
  color: "text.secondary",
@@ -136,7 +208,7 @@ function VendorProgressItem({
136
208
  })]
137
209
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.LinearProgress, {
138
210
  variant: "determinate",
139
- value: Math.min(displayProgress, 100),
211
+ value: displayProgress || 0,
140
212
  sx: {
141
213
  height: 8,
142
214
  borderRadius: 4,
@@ -1,7 +1,7 @@
1
1
  type Props = {
2
2
  mode: string;
3
3
  pageInfo?: any;
4
- hasVendor?: boolean;
4
+ vendorCount?: number;
5
5
  sessionId?: string;
6
6
  message: string;
7
7
  action: string;
@@ -10,5 +10,5 @@ type Props = {
10
10
  subscriptionId?: string;
11
11
  subscriptions?: any[];
12
12
  };
13
- export default function PaymentSuccess({ mode, pageInfo, hasVendor, sessionId, message, action, payee, invoiceId, subscriptionId, subscriptions, }: Props): import("react").JSX.Element;
13
+ export default function PaymentSuccess({ mode, pageInfo, vendorCount, sessionId, message, action, payee, invoiceId, subscriptionId, subscriptions, }: Props): import("react").JSX.Element;
14
14
  export {};
@@ -15,7 +15,7 @@ var _progressItem = require("./progress-item");
15
15
  function PaymentSuccess({
16
16
  mode,
17
17
  pageInfo = {},
18
- hasVendor = false,
18
+ vendorCount = 0,
19
19
  sessionId = "",
20
20
  message,
21
21
  action,
@@ -38,7 +38,7 @@ function PaymentSuccess({
38
38
  const timerRef = (0, _react.useRef)(Date.now());
39
39
  let next = null;
40
40
  (0, _react.useEffect)(() => {
41
- if (!hasVendor || !sessionId) return void 0;
41
+ if (vendorCount === 0 || !sessionId) return void 0;
42
42
  const fetchVendorStatus = async interval2 => {
43
43
  try {
44
44
  const response = await api.get((0, _ufo.joinURL)(prefix, `/api/vendors/order/${sessionId}/status`), {});
@@ -60,9 +60,24 @@ function PaymentSuccess({
60
60
  fetchVendorStatus(interval);
61
61
  }, 5e3);
62
62
  return () => clearInterval(interval);
63
- }, [hasVendor, api, prefix, sessionId]);
63
+ }, [vendorCount, api, prefix, sessionId]);
64
+ const renderPlaceholders = () => {
65
+ const placeholders = [];
66
+ for (let i = 0; i < vendorCount; i++) {
67
+ placeholders.push(/* @__PURE__ */(0, _jsxRuntime.jsx)(_progressItem.VendorPlaceholder, {}, `placeholder-${i}`));
68
+ }
69
+ return placeholders;
70
+ };
71
+ const renderVendors = () => {
72
+ if (!vendorStatus) return renderPlaceholders();
73
+ return vendorStatus.vendors?.map((vendor, index) => {
74
+ return /* @__PURE__ */(0, _jsxRuntime.jsx)(_progressItem.VendorProgressItem, {
75
+ vendor
76
+ }, vendor.title || `vendor-${index}`);
77
+ });
78
+ };
64
79
  const renderVendorProgress = () => {
65
- if (!hasVendor || !vendorStatus) return null;
80
+ if (vendorCount === 0) return null;
66
81
  return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Paper, {
67
82
  elevation: 0,
68
83
  sx: {
@@ -75,9 +90,7 @@ function PaymentSuccess({
75
90
  flexDirection: "column",
76
91
  gap: 2
77
92
  },
78
- children: [vendorStatus.vendors?.map((vendor, index) => /* @__PURE__ */(0, _jsxRuntime.jsx)(_progressItem.VendorProgressItem, {
79
- vendor
80
- }, vendor.title || `vendor-${index}`)), hasFailed ? /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
93
+ children: [renderVendors(), hasFailed ? /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
81
94
  variant: "h6",
82
95
  sx: {
83
96
  color: "warning.main",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/payment-react",
3
- "version": "1.20.21",
3
+ "version": "1.21.0",
4
4
  "description": "Reusable react components for payment kit v2",
5
5
  "keywords": [
6
6
  "react",
@@ -54,16 +54,16 @@
54
54
  }
55
55
  },
56
56
  "dependencies": {
57
- "@arcblock/did-connect-react": "^3.1.41",
58
- "@arcblock/ux": "^3.1.41",
59
- "@arcblock/ws": "^1.25.3",
60
- "@blocklet/theme": "^3.1.41",
61
- "@blocklet/ui-react": "^3.1.41",
57
+ "@arcblock/did-connect-react": "^3.1.43",
58
+ "@arcblock/ux": "^3.1.43",
59
+ "@arcblock/ws": "^1.25.4",
60
+ "@blocklet/theme": "^3.1.43",
61
+ "@blocklet/ui-react": "^3.1.43",
62
62
  "@mui/icons-material": "^7.1.2",
63
63
  "@mui/lab": "7.0.0-beta.14",
64
64
  "@mui/material": "^7.1.2",
65
65
  "@mui/system": "^7.1.1",
66
- "@ocap/util": "^1.25.3",
66
+ "@ocap/util": "^1.25.4",
67
67
  "@stripe/react-stripe-js": "^2.9.0",
68
68
  "@stripe/stripe-js": "^2.4.0",
69
69
  "@vitejs/plugin-legacy": "^7.0.0",
@@ -94,7 +94,7 @@
94
94
  "@babel/core": "^7.27.4",
95
95
  "@babel/preset-env": "^7.27.2",
96
96
  "@babel/preset-react": "^7.27.1",
97
- "@blocklet/payment-types": "1.20.21",
97
+ "@blocklet/payment-types": "1.21.0",
98
98
  "@storybook/addon-essentials": "^7.6.20",
99
99
  "@storybook/addon-interactions": "^7.6.20",
100
100
  "@storybook/addon-links": "^7.6.20",
@@ -125,5 +125,5 @@
125
125
  "vite-plugin-babel": "^1.3.1",
126
126
  "vite-plugin-node-polyfills": "^0.23.0"
127
127
  },
128
- "gitHead": "43b26f9e7373a99000f6a14762fdab860a562967"
128
+ "gitHead": "d133aa0e8c6681dd77bafe024c1e1dafb1addf0d"
129
129
  }
@@ -190,6 +190,16 @@ export default flat({
190
190
  failed: 'Processing failed',
191
191
  failedMsg:
192
192
  'An exception occurred during installation. We will automatically process a refund for you. We apologize for the inconvenience. Thank you for your understanding!',
193
+ launcher: {
194
+ processing: 'Installing {name}',
195
+ completed: '{name} installed successfully',
196
+ failed: 'Failed to install {name}',
197
+ },
198
+ didnames: {
199
+ processing: 'Domain ({domain}) registering',
200
+ completed: 'Domain ({domain}) registered successfully',
201
+ failed: 'Domain ({domain}) registered failed',
202
+ },
193
203
  },
194
204
  confirm: {
195
205
  withStake:
@@ -188,6 +188,16 @@ export default flat({
188
188
  delivered: '安装成功',
189
189
  failed: '安装失败',
190
190
  failedMsg: '很抱歉,安装过程中遇到了一些问题。我们正在处理这个问题,稍后会自动为您退款。感谢您的耐心等待!',
191
+ launcher: {
192
+ processing: '正在安装 {name}',
193
+ completed: '安装 {name} 成功',
194
+ failed: '安装 {name} 失败',
195
+ },
196
+ didnames: {
197
+ processing: '正在注册 {domain}',
198
+ completed: '注册 {domain} 成功',
199
+ failed: '注册 {domain} 失败',
200
+ },
191
201
  },
192
202
  confirm: {
193
203
  withStake:
@@ -361,10 +361,9 @@ function PaymentInner({
361
361
  <PaymentSuccess
362
362
  mode={mode}
363
363
  pageInfo={state.checkoutSession.metadata?.page_info}
364
- hasVendor={
365
- state.checkoutSession.metadata?.page_info?.hasVendor ||
366
- state.checkoutSession.line_items.some((item: any) => item.price?.product?.vendor_config?.length > 0)
367
- }
364
+ vendorCount={state.checkoutSession.line_items.reduce((total: number, item: any) => {
365
+ return total + (item.price?.product?.vendor_config?.length || 0);
366
+ }, 0)}
368
367
  sessionId={state.checkoutSession.id}
369
368
  payee={getStatementDescriptor(state.checkoutSession.line_items)}
370
369
  action={state.checkoutSession.mode}
@@ -1,6 +1,19 @@
1
1
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
2
- import { Box, LinearProgress, Typography } from '@mui/material';
2
+ import { Box, LinearProgress, Skeleton, Typography } from '@mui/material';
3
3
  import { useCallback, useEffect, useRef, useState } from 'react';
4
+ import { Check } from '@mui/icons-material';
5
+
6
+ export function VendorPlaceholder() {
7
+ return (
8
+ <Box sx={{ mb: 2 }}>
9
+ <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
10
+ <Skeleton variant="rounded" height={16} width={150} />
11
+ <Skeleton variant="rounded" height={16} width={50} />
12
+ </Box>
13
+ <Skeleton variant="rounded" height={8} width="100%" />
14
+ </Box>
15
+ );
16
+ }
4
17
 
5
18
  interface VendorStatus {
6
19
  success: boolean;
@@ -11,8 +24,33 @@ interface VendorStatus {
11
24
  message: string;
12
25
  appUrl?: string;
13
26
  title?: string;
27
+ vendorType: string;
14
28
  }
15
29
 
30
+ const getVendorLabel = (vendor: VendorStatus, isFailed: boolean, t: any) => {
31
+ const name = vendor.name || vendor.title;
32
+ const isCompleted = vendor.status === 'delivered';
33
+
34
+ if (vendor.vendorType === 'didnames') {
35
+ if (isFailed) {
36
+ return t('payment.checkout.vendor.didnames.failed', { name });
37
+ }
38
+ if (isCompleted) {
39
+ return t('payment.checkout.vendor.didnames.completed', { name });
40
+ }
41
+ return t('payment.checkout.vendor.didnames.processing', { name });
42
+ }
43
+
44
+ // Default to launcher type
45
+ if (isFailed) {
46
+ return t('payment.checkout.vendor.launcher.failed', { name });
47
+ }
48
+ if (isCompleted) {
49
+ return t('payment.checkout.vendor.launcher.completed', { name });
50
+ }
51
+ return t('payment.checkout.vendor.launcher.processing', { name });
52
+ };
53
+
16
54
  export function VendorProgressItem({ vendor }: { vendor: VendorStatus }) {
17
55
  const { t } = useLocaleContext();
18
56
  const [displayProgress, setDisplayProgress] = useState(0);
@@ -49,7 +87,7 @@ export function VendorProgressItem({ vendor }: { vendor: VendorStatus }) {
49
87
 
50
88
  // Ensure progress is an integer
51
89
  newProgress = Math.round(newProgress);
52
- setDisplayProgress((pre) => (pre > newProgress ? pre : newProgress));
90
+ setDisplayProgress((pre) => Math.min(pre > newProgress ? pre : newProgress, 100));
53
91
 
54
92
  // Stop animation immediately when 100%
55
93
  if (realProgress === 100) {
@@ -80,7 +118,7 @@ export function VendorProgressItem({ vendor }: { vendor: VendorStatus }) {
80
118
  const isCompleted = displayProgress >= 100;
81
119
  const isFailed = vendor.status === 'failed';
82
120
 
83
- const nameText = vendor.name || vendor.title;
121
+ const nameText = getVendorLabel(vendor, isFailed, t);
84
122
 
85
123
  // 如果是失败状态,显示错误 UI
86
124
  if (isFailed) {
@@ -88,7 +126,7 @@ export function VendorProgressItem({ vendor }: { vendor: VendorStatus }) {
88
126
  <Box sx={{ mb: 2 }}>
89
127
  <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
90
128
  <Typography variant="body2" sx={{ color: 'text.secondary' }}>
91
- {nameText ? `${nameText} - ${t('payment.checkout.vendor.failed')}` : t('payment.checkout.vendor.failed')}
129
+ {nameText}
92
130
  </Typography>
93
131
  <Typography variant="body2" sx={{ color: 'error.main', fontWeight: 500 }}>
94
132
  {t('payment.checkout.vendor.progress', { progress: 0 })}
@@ -111,20 +149,25 @@ export function VendorProgressItem({ vendor }: { vendor: VendorStatus }) {
111
149
  );
112
150
  }
113
151
 
114
- const statusText = isCompleted ? t('payment.checkout.vendor.delivered') : t('payment.checkout.vendor.processing');
152
+ if (!vendor.name && !vendor.title) {
153
+ return <VendorPlaceholder />;
154
+ }
155
+
115
156
  return (
116
157
  <Box sx={{ mb: 2 }}>
117
158
  <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
118
- <Typography variant="body2" sx={{ color: 'text.secondary' }}>
119
- {nameText ? `${nameText} - ${statusText}` : statusText}
120
- </Typography>
121
- <Typography variant="body2" sx={{ color: 'text.secondary', fontWeight: 500 }}>
122
- {t('payment.checkout.vendor.progress', { progress: displayProgress })}
159
+ <Typography variant="body2" sx={{ color: 'text.secondary', display: 'flex', alignItems: 'center' }}>
160
+ {nameText} {isCompleted ? <Check sx={{ color: 'success.main', ml: 0.5 }} fontSize="small" /> : null}
123
161
  </Typography>
162
+ {isCompleted ? null : (
163
+ <Typography variant="body2" sx={{ color: 'text.secondary', fontWeight: 500 }}>
164
+ {t('payment.checkout.vendor.progress', { progress: displayProgress })}
165
+ </Typography>
166
+ )}
124
167
  </Box>
125
168
  <LinearProgress
126
169
  variant="determinate"
127
- value={Math.min(displayProgress, 100)}
170
+ value={displayProgress || 0}
128
171
  sx={{
129
172
  height: 8,
130
173
  borderRadius: 4,
@@ -5,12 +5,12 @@ import { joinURL } from 'ufo';
5
5
 
6
6
  import { Button } from '@arcblock/ux';
7
7
  import { usePaymentContext } from '../contexts/payment';
8
- import { VendorProgressItem } from './progress-item';
8
+ import { VendorPlaceholder, VendorProgressItem } from './progress-item';
9
9
 
10
10
  type Props = {
11
11
  mode: string;
12
12
  pageInfo?: any;
13
- hasVendor?: boolean;
13
+ vendorCount?: number;
14
14
  sessionId?: string;
15
15
  message: string;
16
16
  action: string;
@@ -27,6 +27,9 @@ interface VendorStatus {
27
27
  message: string;
28
28
  appUrl?: string;
29
29
  title?: string;
30
+ name?: string;
31
+ key?: string;
32
+ vendorType: string;
30
33
  }
31
34
 
32
35
  interface VendorResponse {
@@ -39,7 +42,7 @@ interface VendorResponse {
39
42
  export default function PaymentSuccess({
40
43
  mode,
41
44
  pageInfo = {},
42
- hasVendor = false,
45
+ vendorCount = 0,
43
46
  sessionId = '',
44
47
  message,
45
48
  action,
@@ -56,9 +59,9 @@ export default function PaymentSuccess({
56
59
  const timerRef = useRef(Date.now());
57
60
  let next: any = null;
58
61
 
59
- // Fetch vendor status when hasVendor is true
62
+ // Fetch vendor status when vendorCount > 0
60
63
  useEffect(() => {
61
- if (!hasVendor || !sessionId) return undefined;
64
+ if (vendorCount === 0 || !sessionId) return undefined;
62
65
 
63
66
  const fetchVendorStatus = async (interval?: NodeJS.Timeout) => {
64
67
  try {
@@ -89,11 +92,26 @@ export default function PaymentSuccess({
89
92
  }, 5000);
90
93
 
91
94
  return () => clearInterval(interval);
92
- }, [hasVendor, api, prefix, sessionId]);
95
+ }, [vendorCount, api, prefix, sessionId]);
96
+
97
+ const renderPlaceholders = () => {
98
+ const placeholders = [];
99
+ for (let i = 0; i < vendorCount; i++) {
100
+ placeholders.push(<VendorPlaceholder key={`placeholder-${i}`} />);
101
+ }
102
+ return placeholders;
103
+ };
104
+
105
+ const renderVendors = () => {
106
+ if (!vendorStatus) return renderPlaceholders();
107
+ return vendorStatus.vendors?.map((vendor, index) => {
108
+ return <VendorProgressItem key={vendor.title || `vendor-${index}`} vendor={vendor} />;
109
+ });
110
+ };
93
111
 
94
112
  // Render vendor progress component
95
113
  const renderVendorProgress = () => {
96
- if (!hasVendor || !vendorStatus) return null;
114
+ if (vendorCount === 0) return null;
97
115
 
98
116
  return (
99
117
  <Paper
@@ -108,9 +126,7 @@ export default function PaymentSuccess({
108
126
  flexDirection: 'column',
109
127
  gap: 2,
110
128
  }}>
111
- {vendorStatus.vendors?.map((vendor, index) => (
112
- <VendorProgressItem key={vendor.title || `vendor-${index}`} vendor={vendor} />
113
- ))}
129
+ {renderVendors()}
114
130
  {hasFailed ? (
115
131
  <Typography variant="h6" sx={{ color: 'warning.main', mb: 1 }}>
116
132
  {t('payment.checkout.vendor.failedMsg')}