@windrun-huaiin/third-ui 20.0.0 → 21.0.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/LICENSE +1 -1
- package/dist/clerk/clerk-page-generator.d.ts +0 -8
- package/dist/clerk/fingerprint/fingerprint-provider.js +58 -49
- package/dist/clerk/fingerprint/fingerprint-provider.mjs +58 -49
- package/dist/fuma/fuma-page-genarator.d.ts +2 -2
- package/dist/fuma/fuma-page-genarator.js +21 -8
- package/dist/fuma/fuma-page-genarator.mjs +21 -8
- package/dist/fuma/llm-copy-handler.js +3 -2
- package/dist/fuma/llm-copy-handler.mjs +3 -2
- package/dist/fuma/mdx/index.d.ts +1 -0
- package/dist/fuma/mdx/index.js +3 -0
- package/dist/fuma/mdx/index.mjs +1 -0
- package/dist/fuma/mdx/math.d.ts +17 -0
- package/dist/fuma/mdx/math.js +60 -0
- package/dist/fuma/mdx/math.mjs +57 -0
- package/dist/fuma/mdx/zia-card.js +1 -1
- package/dist/fuma/mdx/zia-card.mjs +1 -1
- package/dist/main/{ads-alert-dialog.d.ts → alert-dialog/ads-alert-dialog.d.ts} +1 -1
- package/dist/main/alert-dialog/ads-alert-dialog.js +24 -0
- package/dist/main/alert-dialog/ads-alert-dialog.mjs +22 -0
- package/dist/main/alert-dialog/confirm-dialog.d.ts +15 -0
- package/dist/main/alert-dialog/confirm-dialog.js +40 -0
- package/dist/main/alert-dialog/confirm-dialog.mjs +38 -0
- package/dist/main/alert-dialog/dialog-styles.d.ts +14 -0
- package/dist/main/alert-dialog/dialog-styles.js +35 -0
- package/dist/main/alert-dialog/dialog-styles.mjs +20 -0
- package/dist/main/alert-dialog/high-priority-confirm-dialog.d.ts +12 -0
- package/dist/main/alert-dialog/high-priority-confirm-dialog.js +23 -0
- package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +21 -0
- package/dist/main/alert-dialog/index.d.ts +4 -0
- package/dist/main/alert-dialog/info-dialog.d.ts +13 -0
- package/dist/main/alert-dialog/info-dialog.js +50 -0
- package/dist/main/alert-dialog/info-dialog.mjs +48 -0
- package/dist/main/index.d.ts +1 -1
- package/dist/main/index.js +7 -1
- package/dist/main/index.mjs +4 -1
- package/package.json +4 -4
- package/src/clerk/clerk-page-generator.tsx +0 -9
- package/src/clerk/fingerprint/fingerprint-provider.tsx +155 -62
- package/src/fuma/fuma-page-genarator.tsx +26 -9
- package/src/fuma/llm-copy-handler.ts +3 -3
- package/src/fuma/mdx/index.ts +1 -0
- package/src/fuma/mdx/math.tsx +130 -0
- package/src/fuma/mdx/zia-card.tsx +1 -0
- package/src/main/{ads-alert-dialog.tsx → alert-dialog/ads-alert-dialog.tsx} +46 -29
- package/src/main/alert-dialog/confirm-dialog.tsx +131 -0
- package/src/main/alert-dialog/dialog-styles.ts +73 -0
- package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +94 -0
- package/src/main/alert-dialog/index.ts +7 -0
- package/src/main/alert-dialog/info-dialog.tsx +139 -0
- package/src/main/index.ts +1 -1
- package/src/main/language-detector.tsx +0 -8
- package/dist/main/ads-alert-dialog.js +0 -21
- package/dist/main/ads-alert-dialog.mjs +0 -19
package/LICENSE
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* MIT License
|
|
4
|
-
* Copyright (c) 2026 D8ger
|
|
5
|
-
*
|
|
6
|
-
* This source code is licensed under the MIT license found in the
|
|
7
|
-
* LICENSE file in the root directory of this source tree.
|
|
8
|
-
*/
|
|
9
1
|
export declare function createSignInPage(): () => import("react/jsx-runtime").JSX.Element;
|
|
10
2
|
export declare function createSignUpPage(): () => import("react/jsx-runtime").JSX.Element;
|
|
11
3
|
export declare function createWaitlistPage(): () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,6 +6,7 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
6
6
|
var icons = require('@windrun-huaiin/base-ui/icons');
|
|
7
7
|
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
8
8
|
var utils = require('@windrun-huaiin/lib/utils');
|
|
9
|
+
var nextIntl = require('next-intl');
|
|
9
10
|
var React = require('react');
|
|
10
11
|
var useFingerprint = require('./use-fingerprint.js');
|
|
11
12
|
var ui = require('@windrun-huaiin/base-ui/ui');
|
|
@@ -14,6 +15,10 @@ var fingerprintDebug = require('./fingerprint-debug.js');
|
|
|
14
15
|
var fingerprintShared = require('./fingerprint-shared.js');
|
|
15
16
|
|
|
16
17
|
const FingerprintContext = React.createContext(undefined);
|
|
18
|
+
function useFingerprintStatusTranslations() {
|
|
19
|
+
const messages = nextIntl.useMessages();
|
|
20
|
+
return messages.fingerprint;
|
|
21
|
+
}
|
|
17
22
|
/**
|
|
18
23
|
* Fingerprint Provider Component
|
|
19
24
|
* 为应用提供fingerprint和匿名用户管理功能
|
|
@@ -53,6 +58,7 @@ function withFingerprint(Component, config) {
|
|
|
53
58
|
* 组件:显示用户状态和积分信息(用于调试)
|
|
54
59
|
*/
|
|
55
60
|
function FingerprintStatus() {
|
|
61
|
+
const translations = useFingerprintStatusTranslations();
|
|
56
62
|
const { fingerprintId, xUser, xCredit, xSubscription, error, clearError, } = useFingerprintContext();
|
|
57
63
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
58
64
|
const [panelMode, setPanelMode] = React.useState('info');
|
|
@@ -92,7 +98,7 @@ function FingerprintStatus() {
|
|
|
92
98
|
return [
|
|
93
99
|
{
|
|
94
100
|
key: 'paid',
|
|
95
|
-
label:
|
|
101
|
+
label: translations.creditBuckets.paid,
|
|
96
102
|
icon: jsxRuntime.jsx(icons.Settings2Icon, { className: "size-4 text-green-500 dark:text-green-300" }),
|
|
97
103
|
balance: xCredit.balancePaid,
|
|
98
104
|
total: xCredit.totalPaidLimit,
|
|
@@ -101,7 +107,7 @@ function FingerprintStatus() {
|
|
|
101
107
|
},
|
|
102
108
|
{
|
|
103
109
|
key: 'oneTimePaid',
|
|
104
|
-
label:
|
|
110
|
+
label: translations.creditBuckets.oneTimePaid,
|
|
105
111
|
icon: jsxRuntime.jsx(icons.CoinsIcon, { className: "size-4 text-amber-500 dark:text-amber-300" }),
|
|
106
112
|
balance: xCredit.balanceOneTimePaid,
|
|
107
113
|
total: xCredit.totalOneTimePaidLimit,
|
|
@@ -110,7 +116,7 @@ function FingerprintStatus() {
|
|
|
110
116
|
},
|
|
111
117
|
{
|
|
112
118
|
key: 'free',
|
|
113
|
-
label:
|
|
119
|
+
label: translations.creditBuckets.free,
|
|
114
120
|
icon: jsxRuntime.jsx(icons.GiftIcon, { className: "size-4 text-purple-500 dark:text-purple-300" }),
|
|
115
121
|
balance: xCredit.balanceFree,
|
|
116
122
|
total: xCredit.totalFreeLimit,
|
|
@@ -118,15 +124,15 @@ function FingerprintStatus() {
|
|
|
118
124
|
end: xCredit.freeEnd,
|
|
119
125
|
},
|
|
120
126
|
];
|
|
121
|
-
}, [xCredit]);
|
|
127
|
+
}, [translations.creditBuckets.free, translations.creditBuckets.oneTimePaid, translations.creditBuckets.paid, xCredit]);
|
|
122
128
|
const subscriptionStatus = React.useMemo(() => {
|
|
123
129
|
var _a, _b;
|
|
124
130
|
if (!xSubscription) {
|
|
125
131
|
return {
|
|
126
|
-
status:
|
|
132
|
+
status: translations.placeholders.subscriptionStatusNever,
|
|
127
133
|
priceName: '--',
|
|
128
134
|
creditsAllocated: '--',
|
|
129
|
-
period:
|
|
135
|
+
period: translations.placeholders.subscriptionPeriodUnavailable,
|
|
130
136
|
};
|
|
131
137
|
}
|
|
132
138
|
return {
|
|
@@ -135,9 +141,9 @@ function FingerprintStatus() {
|
|
|
135
141
|
creditsAllocated: typeof xSubscription.creditsAllocated === 'number'
|
|
136
142
|
? formatNumber(xSubscription.creditsAllocated)
|
|
137
143
|
: '--',
|
|
138
|
-
period: formatRangeText(xSubscription.subPeriodStart, xSubscription.subPeriodEnd),
|
|
144
|
+
period: formatRangeText(xSubscription.subPeriodStart, xSubscription.subPeriodEnd, translations),
|
|
139
145
|
};
|
|
140
|
-
}, [xSubscription]);
|
|
146
|
+
}, [translations.placeholders.subscriptionPeriodUnavailable, translations.placeholders.subscriptionStatusNever, xSubscription]);
|
|
141
147
|
const userStatus = (xUser === null || xUser === void 0 ? void 0 : xUser.status) || '--';
|
|
142
148
|
const totalCredits = formatNumber(xCredit === null || xCredit === void 0 ? void 0 : xCredit.totalBalance);
|
|
143
149
|
const subStatus = subscriptionStatus.status;
|
|
@@ -145,22 +151,22 @@ function FingerprintStatus() {
|
|
|
145
151
|
const runContextParallelInitTest = () => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
146
152
|
const debugFingerprintId = activeDebugFingerprintId !== null && activeDebugFingerprintId !== void 0 ? activeDebugFingerprintId : fingerprintDebug.getOrCreateDebugFingerprintOverride();
|
|
147
153
|
if (!debugFingerprintId) {
|
|
148
|
-
setTestResult(
|
|
154
|
+
setTestResult(translations.messages.testFingerprintNotReady);
|
|
149
155
|
return;
|
|
150
156
|
}
|
|
151
157
|
setActiveDebugFingerprintId(debugFingerprintId);
|
|
152
158
|
setIsRunningTest(true);
|
|
153
|
-
setTestResult(
|
|
159
|
+
setTestResult(tpl(translations.messages.runningFrontendPreventionTest, { fingerprintId: debugFingerprintId }));
|
|
154
160
|
try {
|
|
155
161
|
yield Promise.all([
|
|
156
162
|
initializeDebugAnonymousUser(debugFingerprintId),
|
|
157
163
|
initializeDebugAnonymousUser(debugFingerprintId),
|
|
158
164
|
initializeDebugAnonymousUser(debugFingerprintId),
|
|
159
165
|
]);
|
|
160
|
-
setTestResult(
|
|
166
|
+
setTestResult(tpl(translations.messages.frontendPreventionTestFinished, { fingerprintId: debugFingerprintId }));
|
|
161
167
|
}
|
|
162
168
|
catch (testError) {
|
|
163
|
-
setTestResult(
|
|
169
|
+
setTestResult(tpl(translations.messages.frontendPreventionTestFailed, { error: formatErrorMessage(testError, translations) }));
|
|
164
170
|
}
|
|
165
171
|
finally {
|
|
166
172
|
setIsRunningTest(false);
|
|
@@ -180,7 +186,7 @@ function FingerprintStatus() {
|
|
|
180
186
|
});
|
|
181
187
|
if (!response.ok) {
|
|
182
188
|
const errorData = yield response.json().catch(() => ({}));
|
|
183
|
-
throw new Error(errorData.error ||
|
|
189
|
+
throw new Error(errorData.error || translations.messages.failedToInitializeAnonymousUser);
|
|
184
190
|
}
|
|
185
191
|
yield response.json().catch(() => ({}));
|
|
186
192
|
}
|
|
@@ -191,12 +197,12 @@ function FingerprintStatus() {
|
|
|
191
197
|
const runRawParallelPostTest = () => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
192
198
|
const normalizedFingerprintId = activeDebugFingerprintId !== null && activeDebugFingerprintId !== void 0 ? activeDebugFingerprintId : fingerprintDebug.getOrCreateDebugFingerprintOverride();
|
|
193
199
|
if (!normalizedFingerprintId) {
|
|
194
|
-
setTestResult(
|
|
200
|
+
setTestResult(translations.messages.testFingerprintNotReady);
|
|
195
201
|
return;
|
|
196
202
|
}
|
|
197
203
|
setActiveDebugFingerprintId(normalizedFingerprintId);
|
|
198
204
|
setIsRunningTest(true);
|
|
199
|
-
setTestResult(
|
|
205
|
+
setTestResult(tpl(translations.messages.runningBackendIdempotencyTest, { fingerprintId: normalizedFingerprintId }));
|
|
200
206
|
try {
|
|
201
207
|
const fingerprintHeaders = yield fingerprintClient.createFingerprintHeaders();
|
|
202
208
|
const requests = Array.from({ length: 3 }, () => fetch('/api/user/anonymous/init', {
|
|
@@ -227,16 +233,16 @@ function FingerprintStatus() {
|
|
|
227
233
|
.filter((payload) => !payload.ok)
|
|
228
234
|
.map((payload) => `${payload.status}${payload.error ? `:${payload.error}` : ''}`);
|
|
229
235
|
setTestResult([
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
failedStatuses.length > 0 ?
|
|
236
|
+
translations.messages.backendIdempotencyTestDone,
|
|
237
|
+
tpl(translations.messages.createdCount, { count: createdUserIds.length }),
|
|
238
|
+
tpl(translations.messages.reusedCount, { count: reusedUserIds.length }),
|
|
239
|
+
tpl(translations.messages.failedCount, { count: failedStatuses.length }),
|
|
240
|
+
tpl(translations.messages.createdUserIds, { value: createdUserIds.join(', ') }),
|
|
241
|
+
failedStatuses.length > 0 ? tpl(translations.messages.failedStatuses, { value: failedStatuses.join(', ') }) : null,
|
|
236
242
|
].filter(Boolean).join('\n'));
|
|
237
243
|
}
|
|
238
244
|
catch (testError) {
|
|
239
|
-
setTestResult(
|
|
245
|
+
setTestResult(tpl(translations.messages.backendIdempotencyTestFailed, { error: formatErrorMessage(testError, translations) }));
|
|
240
246
|
}
|
|
241
247
|
finally {
|
|
242
248
|
setIsRunningTest(false);
|
|
@@ -245,31 +251,31 @@ function FingerprintStatus() {
|
|
|
245
251
|
const regenerateTestFingerprint = () => {
|
|
246
252
|
const nextFingerprintId = fingerprintDebug.regenerateDebugFingerprintOverride();
|
|
247
253
|
setActiveDebugFingerprintId(nextFingerprintId);
|
|
248
|
-
setTestResult(
|
|
254
|
+
setTestResult(tpl(translations.messages.generatedTestFingerprintOverride, { fingerprintId: nextFingerprintId }));
|
|
249
255
|
};
|
|
250
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!isOpen && (jsxRuntime.jsx("button", { onClick: handleToggle, type: "button", "aria-label":
|
|
256
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!isOpen && (jsxRuntime.jsx("button", { onClick: handleToggle, type: "button", "aria-label": translations.panel.toggleAriaLabel, className: utils.cn('fixed left-2 top-2 md:left-2 md:top-3 z-10000 inline-flex size-8 md:size-11 items-center justify-center rounded-full', lib.themeButtonGradientClass, lib.themeButtonGradientHoverClass, 'text-white rounded-full shadow-lg hover:shadow-xl transition-all duration-300'), children: jsxRuntime.jsx(icons.LightbulbIcon, { className: "size-6 text-white" }) })), isOpen && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { onClick: handleBackdropClick, className: "fixed inset-0 z-9998 bg-black/60 backdrop-blur-sm" }), jsxRuntime.jsxs("div", { ref: modalRef, className: utils.cn('fixed inset-3 z-9999 mx-auto w-[min(95vw,520px)] overflow-y-auto rounded-2xl border', 'border-slate-200/70 bg-white/95 p-4 shadow-2xl backdrop-blur-sm', 'font-sans text-sm text-slate-700 dark:border-white/12 dark:bg-slate-950/95 dark:text-slate-200', 'sm:inset-auto md:left-2 sm:top-1 md:right-auto sm:w-[min(520px,95vw)] sm:p-5'), children: [jsxRuntime.jsx("header", { className: "mb-4", children: jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [jsxRuntime.jsxs("div", { className: utils.cn("flex items-center gap-2 text-base font-bold tracking-wider", lib.themeIconColor), children: [jsxRuntime.jsx(icons.ShieldUserIcon, { className: "size-4" }), translations.panel.title] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsxs("button", { type: "button", onClick: () => setPanelMode((prev) => prev === 'info' ? 'test' : 'info'), className: utils.cn('inline-flex items-center gap-2 rounded-full border px-2 py-1 text-[11px] font-semibold shadow-sm transition-all duration-200', panelMode === 'test'
|
|
251
257
|
? utils.cn('border-transparent text-white', lib.themeButtonGradientClass, lib.themeButtonGradientHoverClass)
|
|
252
|
-
: themedGhostButtonClass), "aria-pressed": panelMode === 'test', children: [jsxRuntime.jsx("span", { children:
|
|
258
|
+
: themedGhostButtonClass), "aria-pressed": panelMode === 'test', children: [jsxRuntime.jsx("span", { children: translations.panel.testModeLabel }), jsxRuntime.jsx("span", { className: utils.cn('relative inline-flex h-5 w-9 items-center rounded-full transition-colors', panelMode === 'test'
|
|
253
259
|
? 'bg-white/25'
|
|
254
|
-
: 'bg-slate-300 dark:bg-slate-700'), children: jsxRuntime.jsx("span", { className: utils.cn('inline-block size-4 rounded-full shadow-sm transition-transform', panelMode === 'test' ? 'bg-white' : 'bg-white dark:bg-slate-100', panelMode === 'test' ? 'translate-x-4' : 'translate-x-0.5') }) })] }), jsxRuntime.jsx("button", { type: "button", "aria-label":
|
|
255
|
-
{ label:
|
|
256
|
-
{ label:
|
|
257
|
-
{ label:
|
|
258
|
-
{ label:
|
|
259
|
-
{ label:
|
|
260
|
-
{ label:
|
|
261
|
-
{ label:
|
|
262
|
-
] }), jsxRuntime.jsxs("div", { className: "space-y-2 rounded-xl border border-slate-200/70 bg-white/80 p-4 shadow-sm dark:border-white/12 dark:bg-slate-900/50", children: [jsxRuntime.jsx(PanelHeader, { icon: jsxRuntime.jsx(icons.GemIcon, { className: "size-4" }), title:
|
|
260
|
+
: 'bg-slate-300 dark:bg-slate-700'), children: jsxRuntime.jsx("span", { className: utils.cn('inline-block size-4 rounded-full shadow-sm transition-transform', panelMode === 'test' ? 'bg-white' : 'bg-white dark:bg-slate-100', panelMode === 'test' ? 'translate-x-4' : 'translate-x-0.5') }) })] }), jsxRuntime.jsx("button", { type: "button", "aria-label": translations.panel.closeAriaLabel, className: "rounded-full p-2 text-slate-500 transition hover:bg-slate-100 hover:text-slate-700 dark:text-slate-300 dark:hover:bg-white/10 dark:hover:text-white", onClick: () => setIsOpen(false), children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] })] }) }), jsxRuntime.jsxs("section", { className: "space-y-1", children: [panelMode === 'info' ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(PanelSection, { icon: jsxRuntime.jsx(icons.FingerprintIcon, { className: "size-4" }), title: translations.sections.user, rightInfo: jsxRuntime.jsx(StatusTag, { value: userStatus, translations: translations }), items: [
|
|
261
|
+
{ label: translations.labels.userId, value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.userId) || '' }) },
|
|
262
|
+
{ label: translations.labels.nickName, value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.userName) || '' }) },
|
|
263
|
+
{ label: translations.labels.fingerprintId, value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.fingerprintId) || fingerprintId || '' }) },
|
|
264
|
+
{ label: translations.labels.clerkUserId, value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.clerkUserId) || '' }) },
|
|
265
|
+
{ label: translations.labels.email, value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.email) || '' }) },
|
|
266
|
+
{ label: translations.labels.stripeCusId, value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.stripeCusId) || '' }) },
|
|
267
|
+
{ label: translations.labels.createdAt, value: (xUser === null || xUser === void 0 ? void 0 : xUser.createdAt) || '--' },
|
|
268
|
+
] }), jsxRuntime.jsxs("div", { className: "space-y-2 rounded-xl border border-slate-200/70 bg-white/80 p-4 shadow-sm dark:border-white/12 dark:bg-slate-900/50", children: [jsxRuntime.jsx(PanelHeader, { icon: jsxRuntime.jsx(icons.GemIcon, { className: "size-4" }), title: translations.sections.creditsInfo, rightInfo: jsxRuntime.jsx("span", { className: utils.cn("font-semibold", lib.themeIconColor), children: totalCredits }) }), jsxRuntime.jsx("div", { className: "space-y-3", children: creditBuckets.length > 0 ? (creditBuckets.map((bucket) => {
|
|
263
269
|
const percent = Math.round(computeProgress(bucket.balance, bucket.total) * 100);
|
|
264
|
-
return (jsxRuntime.jsxs("div", { className: "rounded-lg border border-slate-200/70 bg-white/70 p-3 dark:border-white/10 dark:bg-slate-900/40", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-xs font-medium text-slate-600 dark:text-slate-300", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [bucket.icon, jsxRuntime.jsx("span", { children: bucket.label })] }), jsxRuntime.jsxs("span", { className: "font-semibold text-slate-700 dark:text-slate-100", children: [formatNumber(bucket.balance), " / ", formatNumber(bucket.total)] })] }), jsxRuntime.jsx("div", { className: "mt-2 h-1.5 w-full rounded-full bg-slate-200 dark:bg-slate-800", children: jsxRuntime.jsx("div", { className: "h-full rounded-full bg-linear-to-r from-purple-500 via-pink-500 to-rose-400 transition-[width]", style: { width: `${percent}%` } }) }), jsxRuntime.jsxs("div", { className: "mt-2 flex items-center justify-between text-[11px] text-slate-500 dark:text-slate-400", children: [jsxRuntime.jsx("span", { children: formatRangeText(bucket.start, bucket.end) }), jsxRuntime.jsxs("span", { children: [percent, "%"] })] })] }, bucket.key));
|
|
265
|
-
})) : (jsxRuntime.jsx(EmptyPlaceholder, { label:
|
|
266
|
-
{ label:
|
|
267
|
-
{ label:
|
|
268
|
-
{ label:
|
|
269
|
-
{ label:
|
|
270
|
-
{ label:
|
|
271
|
-
{ label:
|
|
272
|
-
] })] })) : (jsxRuntime.jsxs("div", { className: "space-y-3 rounded-xl border border-slate-200/70 bg-white/85 p-4 shadow-sm dark:border-white/12 dark:bg-slate-900/45", children: [jsxRuntime.jsx(PanelHeader, { icon: jsxRuntime.jsx(icons.DatabaseZapIcon, { className: "size-4" }), title:
|
|
270
|
+
return (jsxRuntime.jsxs("div", { className: "rounded-lg border border-slate-200/70 bg-white/70 p-3 dark:border-white/10 dark:bg-slate-900/40", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-xs font-medium text-slate-600 dark:text-slate-300", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [bucket.icon, jsxRuntime.jsx("span", { children: bucket.label })] }), jsxRuntime.jsxs("span", { className: "font-semibold text-slate-700 dark:text-slate-100", children: [formatNumber(bucket.balance), " / ", formatNumber(bucket.total)] })] }), jsxRuntime.jsx("div", { className: "mt-2 h-1.5 w-full rounded-full bg-slate-200 dark:bg-slate-800", children: jsxRuntime.jsx("div", { className: "h-full rounded-full bg-linear-to-r from-purple-500 via-pink-500 to-rose-400 transition-[width]", style: { width: `${percent}%` } }) }), jsxRuntime.jsxs("div", { className: "mt-2 flex items-center justify-between text-[11px] text-slate-500 dark:text-slate-400", children: [jsxRuntime.jsx("span", { children: formatRangeText(bucket.start, bucket.end, translations) }), jsxRuntime.jsxs("span", { children: [percent, "%"] })] })] }, bucket.key));
|
|
271
|
+
})) : (jsxRuntime.jsx(EmptyPlaceholder, { label: translations.placeholders.noCreditsYet, icon: jsxRuntime.jsx(icons.DatabaseZapIcon, { className: "size-4" }) })) })] }), jsxRuntime.jsx(PanelSection, { icon: jsxRuntime.jsx(icons.BellIcon, { className: "size-4" }), title: translations.sections.subscription, rightInfo: jsxRuntime.jsx(StatusTag, { value: subStatus, translations: translations }), items: [
|
|
272
|
+
{ label: translations.labels.plan, value: subscriptionStatus.priceName },
|
|
273
|
+
{ label: translations.labels.period, value: subscriptionStatus.period },
|
|
274
|
+
{ label: translations.labels.allocated, value: subscriptionStatus.creditsAllocated },
|
|
275
|
+
{ label: translations.labels.subId, value: jsxRuntime.jsx(ui.CopyableText, { text: (xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.paySubscriptionId) || '' }) },
|
|
276
|
+
{ label: translations.labels.orderId, value: jsxRuntime.jsx(ui.CopyableText, { text: (xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.orderId) || '' }) },
|
|
277
|
+
{ label: translations.labels.priceId, value: jsxRuntime.jsx(ui.CopyableText, { text: (xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.priceId) || '' }) },
|
|
278
|
+
] })] })) : (jsxRuntime.jsxs("div", { className: "space-y-3 rounded-xl border border-slate-200/70 bg-white/85 p-4 shadow-sm dark:border-white/12 dark:bg-slate-900/45", children: [jsxRuntime.jsx(PanelHeader, { icon: jsxRuntime.jsx(icons.DatabaseZapIcon, { className: "size-4" }), title: translations.sections.concurrentBaseInfo, rightInfo: jsxRuntime.jsx(StatusTag, { value: isRunningTest ? translations.status.pending : translations.status.idle, translations: translations }) }), jsxRuntime.jsxs("div", { className: "space-y-2 text-xs text-slate-500 dark:text-slate-300", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxRuntime.jsx("span", { className: "text-slate-400 dark:text-slate-500", children: translations.labels.realBrowser }), jsxRuntime.jsx(ui.CopyableText, { text: fingerprintId || '' })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsx("span", { className: "text-slate-400 dark:text-slate-500", children: translations.labels.testOverride }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 py-1", children: [jsxRuntime.jsx("div", { className: "min-w-0 flex-1 rounded-lg border border-slate-200 bg-white px-3 py-2 font-mono text-[0.5rem] sm:text-[0.625rem] md:text-xs leading-tight text-slate-700 dark:border-white/10 dark:bg-slate-950 dark:text-slate-100", children: jsxRuntime.jsx(ui.CopyableText, { text: activeDebugFingerprintId || '' }) }), jsxRuntime.jsx("button", { type: "button", disabled: isRunningTest, onClick: regenerateTestFingerprint, "aria-label": translations.actions.generateNewTestFingerprintAriaLabel, className: "inline-flex size-9 items-center justify-center rounded-lg border border-slate-200 bg-slate-50 text-slate-700 transition hover:border-slate-300 hover:bg-slate-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/10 dark:bg-slate-950 dark:text-slate-100 dark:hover:bg-slate-900", children: jsxRuntime.jsx(icons.RefreshCcwIcon, { className: "size-4" }) })] })] })] }), jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: [jsxRuntime.jsx("button", { type: "button", disabled: isRunningTest, onClick: runContextParallelInitTest, className: utils.cn('shrink-0 rounded-full border px-3 py-2 text-xs font-semibold transition-all duration-200 disabled:cursor-not-allowed disabled:opacity-50', themedGhostButtonClass), children: translations.actions.frontendPreventionTest }), jsxRuntime.jsx("button", { type: "button", disabled: isRunningTest, onClick: runRawParallelPostTest, className: utils.cn('shrink-0 rounded-full border px-3 py-2 text-xs font-semibold text-white shadow-sm transition-all duration-200 disabled:cursor-not-allowed disabled:opacity-50', 'border-transparent', lib.themeButtonGradientClass, lib.themeButtonGradientHoverClass), children: translations.actions.backendIdempotencyTest })] }), jsxRuntime.jsx("div", { className: "rounded-lg border border-dashed border-slate-200 bg-slate-50/80 p-3 dark:border-white/10 dark:bg-slate-950/50", children: jsxRuntime.jsx("pre", { className: "overflow-x-auto whitespace-pre-wrap break-all font-mono text-[11px] leading-5 text-slate-600 dark:text-slate-300", children: testResult || translations.placeholders.noTestExecutedYet }) })] })), error && (jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3 rounded-xl border border-amber-200 bg-amber-50 p-3 text-xs text-amber-600 shadow-sm dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-200", children: [jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [jsxRuntime.jsx(icons.XIcon, { className: "mt-0.5 size-4 shrink-0" }), jsxRuntime.jsx("span", { children: error })] }), jsxRuntime.jsx("button", { type: "button", "aria-label": translations.actions.dismissErrorAriaLabel, onClick: clearError, className: "shrink-0 rounded-full p-1 text-amber-500 transition hover:bg-amber-100 hover:text-amber-700 dark:text-amber-200 dark:hover:bg-amber-500/10 dark:hover:text-amber-100", children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }))] })] })] }))] }));
|
|
273
279
|
}
|
|
274
280
|
/* ==================== 新增辅助组件 ==================== */
|
|
275
281
|
// 标题行:左侧图标+标题,右侧信息(右对齐)
|
|
@@ -296,11 +302,11 @@ function computeProgress(balance, total) {
|
|
|
296
302
|
return 0;
|
|
297
303
|
return Math.min(Math.max(ratio, 0), 1);
|
|
298
304
|
}
|
|
299
|
-
function formatRangeText(start, end) {
|
|
305
|
+
function formatRangeText(start, end, translations) {
|
|
300
306
|
const safeStart = start && start.trim() ? start : '';
|
|
301
307
|
const safeEnd = end && end.trim() ? end : '';
|
|
302
308
|
if (!safeStart && !safeEnd) {
|
|
303
|
-
return
|
|
309
|
+
return translations.placeholders.noRecords;
|
|
304
310
|
}
|
|
305
311
|
if (!safeStart) {
|
|
306
312
|
return safeEnd;
|
|
@@ -310,9 +316,9 @@ function formatRangeText(start, end) {
|
|
|
310
316
|
}
|
|
311
317
|
return `${safeStart} - ${safeEnd}`;
|
|
312
318
|
}
|
|
313
|
-
function StatusTag({ value }) {
|
|
319
|
+
function StatusTag({ value, translations, }) {
|
|
314
320
|
if (!value)
|
|
315
|
-
return jsxRuntime.jsx("span", { className: "text-slate-400", children:
|
|
321
|
+
return jsxRuntime.jsx("span", { className: "text-slate-400", children: translations.placeholders.none });
|
|
316
322
|
const normalized = value.toLowerCase();
|
|
317
323
|
const colorMap = {
|
|
318
324
|
// 绿色:正常/活跃
|
|
@@ -335,14 +341,17 @@ function StatusTag({ value }) {
|
|
|
335
341
|
const badgeClass = colorMap[normalized] || defaultColor;
|
|
336
342
|
return (jsxRuntime.jsx("span", { className: utils.cn('inline-block rounded-full px-2 py-0.5 text-xs capitalize font-medium', badgeClass), children: value }));
|
|
337
343
|
}
|
|
338
|
-
function formatErrorMessage(error) {
|
|
344
|
+
function formatErrorMessage(error, translations) {
|
|
339
345
|
if (error instanceof Error) {
|
|
340
346
|
return error.message;
|
|
341
347
|
}
|
|
342
348
|
if (typeof error === 'string') {
|
|
343
349
|
return error;
|
|
344
350
|
}
|
|
345
|
-
return
|
|
351
|
+
return translations.placeholders.unknownError;
|
|
352
|
+
}
|
|
353
|
+
function tpl(template, values) {
|
|
354
|
+
return template.replace(/\{(\w+)\}/g, (_, key) => { var _a; return String((_a = values[key]) !== null && _a !== void 0 ? _a : ''); });
|
|
346
355
|
}
|
|
347
356
|
|
|
348
357
|
exports.FingerprintProvider = FingerprintProvider;
|