@windrun-huaiin/third-ui 30.1.0 → 31.0.1
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/README.md +109 -143
- package/dist/ai/ai-prompt-textarea.js +5 -5
- package/dist/ai/ai-prompt-textarea.mjs +5 -5
- package/dist/clerk/clerk-auth-appearance.d.ts +13 -0
- package/dist/clerk/clerk-auth-appearance.js +19 -0
- package/dist/clerk/clerk-auth-appearance.mjs +15 -0
- package/dist/clerk/clerk-auth-modal-appearance.d.ts +12 -0
- package/dist/clerk/clerk-auth-modal-appearance.js +17 -0
- package/dist/clerk/clerk-auth-modal-appearance.mjs +14 -0
- package/dist/clerk/clerk-page-context-generator.js +3 -3
- package/dist/clerk/clerk-page-context-generator.mjs +3 -3
- package/dist/clerk/clerk-page-generator.js +4 -4
- package/dist/clerk/clerk-page-generator.mjs +4 -4
- package/dist/clerk/clerk-user-client.js +2 -1
- package/dist/clerk/clerk-user-client.mjs +2 -1
- package/dist/clerk/fingerprint/fingerprint-client.d.ts +10 -10
- package/dist/clerk/fingerprint/fingerprint-client.js +20 -20
- package/dist/clerk/fingerprint/fingerprint-client.mjs +20 -20
- package/dist/clerk/fingerprint/fingerprint-provider.d.ts +3 -3
- package/dist/clerk/fingerprint/fingerprint-provider.js +8 -8
- package/dist/clerk/fingerprint/fingerprint-provider.mjs +8 -8
- package/dist/clerk/fingerprint/fingerprint-server.d.ts +12 -12
- package/dist/clerk/fingerprint/fingerprint-server.js +17 -17
- package/dist/clerk/fingerprint/fingerprint-server.mjs +17 -17
- package/dist/clerk/fingerprint/fingerprint-shared.d.ts +3 -3
- package/dist/clerk/fingerprint/fingerprint-shared.js +10 -10
- package/dist/clerk/fingerprint/fingerprint-shared.mjs +10 -10
- package/dist/clerk/fingerprint/types.d.ts +0 -1
- package/dist/clerk/fingerprint/use-fingerprint.js +7 -7
- package/dist/clerk/fingerprint/use-fingerprint.mjs +7 -7
- package/dist/clerk/signin-with-fingerprint-client.d.ts +2 -2
- package/dist/clerk/signin-with-fingerprint-client.js +7 -6
- package/dist/clerk/signin-with-fingerprint-client.mjs +7 -6
- package/dist/clerk/signup-button-with-fingerprint-client.js +6 -4
- package/dist/clerk/signup-button-with-fingerprint-client.mjs +6 -4
- package/dist/clerk/signup-with-fingerprint-client.d.ts +2 -2
- package/dist/clerk/signup-with-fingerprint-client.js +7 -6
- package/dist/clerk/signup-with-fingerprint-client.mjs +7 -6
- package/dist/fuma/heavy/mermaid.js +1 -1
- package/dist/fuma/heavy/mermaid.mjs +1 -1
- package/dist/fuma/mdx/fuma-github-info.d.ts +1 -2
- package/dist/fuma/mdx/fuma-github-info.js +3 -6
- package/dist/fuma/mdx/fuma-github-info.mjs +3 -6
- package/dist/fuma/site-x.js +0 -1
- package/dist/fuma/site-x.mjs +0 -1
- package/dist/main/calendar/calendar-date-range-input.js +1 -1
- package/dist/main/calendar/calendar-date-range-input.mjs +1 -1
- package/dist/main/credit/credit-overview-nav-client.d.ts +12 -0
- package/dist/main/credit/credit-overview-nav-client.js +65 -0
- package/dist/main/credit/credit-overview-nav-client.mjs +63 -0
- package/dist/main/credit/index.d.ts +2 -0
- package/dist/main/credit/index.js +2 -0
- package/dist/main/credit/index.mjs +1 -0
- package/dist/main/credit/types.d.ts +8 -8
- package/dist/main/money-price/index.d.ts +1 -1
- package/dist/main/money-price/money-price-button.js +10 -10
- package/dist/main/money-price/money-price-button.mjs +10 -10
- package/dist/main/money-price/money-price-config-util.d.ts +30 -30
- package/dist/main/money-price/money-price-config-util.js +48 -48
- package/dist/main/money-price/money-price-config-util.mjs +48 -48
- package/dist/main/money-price/money-price-interactive.js +30 -18
- package/dist/main/money-price/money-price-interactive.mjs +30 -18
- package/dist/main/money-price/money-price-types.d.ts +7 -1
- package/dist/main/money-price/money-price-types.js +2 -2
- package/dist/main/money-price/money-price-types.mjs +2 -2
- package/dist/main/money-price/server.d.ts +1 -1
- package/dist/main/pill-select/x-pill-select.js +2 -2
- package/dist/main/pill-select/x-pill-select.mjs +2 -2
- package/dist/main/server.d.ts +1 -1
- package/package.json +13 -7
- package/src/ai/ai-prompt-textarea.tsx +6 -6
- package/src/clerk/clerk-auth-appearance.ts +16 -0
- package/src/clerk/clerk-page-context-generator.tsx +3 -5
- package/src/clerk/clerk-page-generator.tsx +9 -8
- package/src/clerk/clerk-user-client.tsx +14 -5
- package/src/clerk/fingerprint/fingerprint-client.ts +20 -20
- package/src/clerk/fingerprint/fingerprint-provider.tsx +11 -11
- package/src/clerk/fingerprint/fingerprint-server.ts +17 -17
- package/src/clerk/fingerprint/fingerprint-shared.ts +10 -10
- package/src/clerk/fingerprint/types.ts +0 -1
- package/src/clerk/fingerprint/use-fingerprint.ts +7 -7
- package/src/clerk/signin-with-fingerprint-client.tsx +7 -7
- package/src/clerk/signup-button-with-fingerprint-client.tsx +7 -5
- package/src/clerk/signup-with-fingerprint-client.tsx +7 -7
- package/src/fuma/base/custom-home-layout.tsx +4 -4
- package/src/fuma/heavy/mermaid.tsx +1 -1
- package/src/fuma/mdx/fuma-github-info.tsx +3 -8
- package/src/fuma/site-x.tsx +0 -1
- package/src/main/calendar/calendar-date-range-input.tsx +1 -1
- package/src/main/credit/credit-overview-nav-client.tsx +95 -0
- package/src/main/credit/index.ts +5 -0
- package/src/main/credit/types.ts +8 -8
- package/src/main/gallery/gallery-mobile-swiper.tsx +0 -1
- package/src/main/gallery/gallery-server.tsx +2 -2
- package/src/main/money-price/index.ts +2 -0
- package/src/main/money-price/money-price-button.tsx +10 -10
- package/src/main/money-price/money-price-config-util.ts +49 -49
- package/src/main/money-price/money-price-interactive.tsx +40 -20
- package/src/main/money-price/money-price-types.ts +21 -14
- package/src/main/money-price/server.ts +2 -0
- package/src/main/pill-select/x-pill-select.tsx +2 -2
- package/src/main/server.ts +3 -1
- package/src/styles/third-ui.css +8 -0
|
@@ -5,7 +5,7 @@ import { useState, useEffect } from 'react';
|
|
|
5
5
|
import { ExternalLinkIcon, StarIcon } from '@windrun-huaiin/base-ui/icons';
|
|
6
6
|
|
|
7
7
|
// Loading state component
|
|
8
|
-
function GitHubInfoSkeleton({
|
|
8
|
+
function GitHubInfoSkeleton({ className }) {
|
|
9
9
|
return (jsxs("div", { className: `flex flex-col gap-1.5 p-2 rounded-lg text-sm text-fd-foreground/80 lg:flex-row lg:items-center animate-pulse ${className}`, children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("div", { className: "size-3.5 bg-fd-muted rounded" }), jsx("div", { className: "h-4 bg-fd-muted rounded w-20" })] }), jsx("div", { className: "h-3 bg-fd-muted rounded w-8" })] }));
|
|
10
10
|
}
|
|
11
11
|
// Error state component - graceful fallback
|
|
@@ -44,7 +44,7 @@ function humanizeNumber(num) {
|
|
|
44
44
|
* - 🎨 Three states: loading, success, error
|
|
45
45
|
* - 💯 Not affected by network issues causing page crashes
|
|
46
46
|
*/
|
|
47
|
-
function FumaGithubInfo({ owner, repo,
|
|
47
|
+
function FumaGithubInfo({ owner, repo, className }) {
|
|
48
48
|
const [data, setData] = useState(null);
|
|
49
49
|
const [loading, setLoading] = useState(true);
|
|
50
50
|
const [error, setError] = useState(null);
|
|
@@ -59,9 +59,6 @@ function FumaGithubInfo({ owner, repo, token, className }) {
|
|
|
59
59
|
const headers = new Headers({
|
|
60
60
|
'Accept': 'application/vnd.github.v3+json',
|
|
61
61
|
});
|
|
62
|
-
if (token) {
|
|
63
|
-
headers.set('Authorization', `Bearer ${token}`);
|
|
64
|
-
}
|
|
65
62
|
const response = yield fetch(`https://api.github.com/repos/${owner}/${repo}`, {
|
|
66
63
|
signal: controller.signal,
|
|
67
64
|
headers,
|
|
@@ -95,7 +92,7 @@ function FumaGithubInfo({ owner, repo, token, className }) {
|
|
|
95
92
|
}
|
|
96
93
|
});
|
|
97
94
|
fetchRepoData();
|
|
98
|
-
}, [owner, repo
|
|
95
|
+
}, [owner, repo]);
|
|
99
96
|
// Loading state
|
|
100
97
|
if (loading) {
|
|
101
98
|
return jsx(GitHubInfoSkeleton, { owner: owner, repo: repo, className: className });
|
package/dist/fuma/site-x.js
CHANGED
|
@@ -8,7 +8,6 @@ var utils = require('@windrun-huaiin/lib/utils');
|
|
|
8
8
|
function SiteX(_a) {
|
|
9
9
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
10
10
|
var { locale, type, namespace, tKey, className } = _a, props = tslib.__rest(_a, ["locale", "type", "namespace", "tKey", "className"]);
|
|
11
|
-
// 默认命名空间和key
|
|
12
11
|
let ns = namespace;
|
|
13
12
|
let key = tKey;
|
|
14
13
|
if (!ns) {
|
package/dist/fuma/site-x.mjs
CHANGED
|
@@ -6,7 +6,6 @@ import { cn } from '@windrun-huaiin/lib/utils';
|
|
|
6
6
|
function SiteX(_a) {
|
|
7
7
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8
8
|
var { locale, type, namespace, tKey, className } = _a, props = __rest(_a, ["locale", "type", "namespace", "tKey", "className"]);
|
|
9
|
-
// 默认命名空间和key
|
|
10
9
|
let ns = namespace;
|
|
11
10
|
let key = tKey;
|
|
12
11
|
if (!ns) {
|
|
@@ -9,7 +9,7 @@ var utils = require('@windrun-huaiin/lib/utils');
|
|
|
9
9
|
var usePressFeedback = require('../buttons/use-press-feedback.js');
|
|
10
10
|
var randomDateRangeDialog = require('./random-date-range-dialog.js');
|
|
11
11
|
|
|
12
|
-
const DEFAULT_PLACEHOLDER = '
|
|
12
|
+
const DEFAULT_PLACEHOLDER = 'Slide pick Date';
|
|
13
13
|
const DEFAULT_RANGE_DAYS = 7;
|
|
14
14
|
const CLEAR_PRESS_FEEDBACK_MS = 180;
|
|
15
15
|
function parseDateString(value) {
|
|
@@ -7,7 +7,7 @@ import { cn } from '@windrun-huaiin/lib/utils';
|
|
|
7
7
|
import { usePressFeedback, resolvePressFeedbackMode } from '../buttons/use-press-feedback.mjs';
|
|
8
8
|
import { RandomDateRangeDialog } from './random-date-range-dialog.mjs';
|
|
9
9
|
|
|
10
|
-
const DEFAULT_PLACEHOLDER = '
|
|
10
|
+
const DEFAULT_PLACEHOLDER = 'Slide pick Date';
|
|
11
11
|
const DEFAULT_RANGE_DAYS = 7;
|
|
12
12
|
const CLEAR_PRESS_FEEDBACK_MS = 180;
|
|
13
13
|
function parseDateString(value) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CreditOverviewTranslations } from './credit-overview-client';
|
|
2
|
+
import type { CreditOverviewData } from './types';
|
|
3
|
+
export interface CreditOverviewPayload {
|
|
4
|
+
data: CreditOverviewData;
|
|
5
|
+
totalLabel: string;
|
|
6
|
+
translations: CreditOverviewTranslations;
|
|
7
|
+
}
|
|
8
|
+
export interface CreditOverviewNavClientProps {
|
|
9
|
+
locale: string;
|
|
10
|
+
endpoint: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function CreditOverviewNavClient({ locale, endpoint, }: CreditOverviewNavClientProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var tslib = require('tslib');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var nextjs = require('@clerk/nextjs');
|
|
7
|
+
var React = require('react');
|
|
8
|
+
var creditNavButton = require('./credit-nav-button.js');
|
|
9
|
+
var creditOverviewClient = require('./credit-overview-client.js');
|
|
10
|
+
|
|
11
|
+
function buildCreditOverviewUrl(endpoint, locale) {
|
|
12
|
+
const url = new URL(endpoint, window.location.origin);
|
|
13
|
+
url.searchParams.set('locale', locale);
|
|
14
|
+
return url.toString();
|
|
15
|
+
}
|
|
16
|
+
function CreditOverviewNavClient({ locale, endpoint, }) {
|
|
17
|
+
const { isLoaded, isSignedIn, userId } = nextjs.useAuth();
|
|
18
|
+
const [payload, setPayload] = React.useState(null);
|
|
19
|
+
React.useEffect(() => {
|
|
20
|
+
if (!isLoaded) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (!isSignedIn) {
|
|
24
|
+
setPayload(null);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const controller = new AbortController();
|
|
28
|
+
function loadCreditOverview() {
|
|
29
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
try {
|
|
31
|
+
const response = yield fetch(buildCreditOverviewUrl(endpoint, locale), {
|
|
32
|
+
credentials: 'same-origin',
|
|
33
|
+
signal: controller.signal,
|
|
34
|
+
});
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
if (!controller.signal.aborted) {
|
|
37
|
+
setPayload(null);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const nextPayload = (yield response.json());
|
|
42
|
+
if (!controller.signal.aborted) {
|
|
43
|
+
setPayload(nextPayload);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (!controller.signal.aborted) {
|
|
48
|
+
setPayload(null);
|
|
49
|
+
console.warn('[CreditOverviewNavClient] Failed to load credit overview', error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
loadCreditOverview();
|
|
55
|
+
return () => {
|
|
56
|
+
controller.abort();
|
|
57
|
+
};
|
|
58
|
+
}, [endpoint, isLoaded, isSignedIn, locale, userId]);
|
|
59
|
+
if (!payload) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return (jsxRuntime.jsx(creditNavButton.CreditNavButton, { locale: locale, totalBalance: payload.data.totalBalance, totalLabel: payload.totalLabel, children: jsxRuntime.jsx(creditOverviewClient.CreditOverviewClient, { locale: locale, data: payload.data, translations: payload.translations }) }));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
exports.CreditOverviewNavClient = CreditOverviewNavClient;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { __awaiter } from 'tslib';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { useAuth } from '@clerk/nextjs';
|
|
5
|
+
import { useState, useEffect } from 'react';
|
|
6
|
+
import { CreditNavButton } from './credit-nav-button.mjs';
|
|
7
|
+
import { CreditOverviewClient } from './credit-overview-client.mjs';
|
|
8
|
+
|
|
9
|
+
function buildCreditOverviewUrl(endpoint, locale) {
|
|
10
|
+
const url = new URL(endpoint, window.location.origin);
|
|
11
|
+
url.searchParams.set('locale', locale);
|
|
12
|
+
return url.toString();
|
|
13
|
+
}
|
|
14
|
+
function CreditOverviewNavClient({ locale, endpoint, }) {
|
|
15
|
+
const { isLoaded, isSignedIn, userId } = useAuth();
|
|
16
|
+
const [payload, setPayload] = useState(null);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!isLoaded) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!isSignedIn) {
|
|
22
|
+
setPayload(null);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const controller = new AbortController();
|
|
26
|
+
function loadCreditOverview() {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
try {
|
|
29
|
+
const response = yield fetch(buildCreditOverviewUrl(endpoint, locale), {
|
|
30
|
+
credentials: 'same-origin',
|
|
31
|
+
signal: controller.signal,
|
|
32
|
+
});
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
if (!controller.signal.aborted) {
|
|
35
|
+
setPayload(null);
|
|
36
|
+
}
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const nextPayload = (yield response.json());
|
|
40
|
+
if (!controller.signal.aborted) {
|
|
41
|
+
setPayload(nextPayload);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (!controller.signal.aborted) {
|
|
46
|
+
setPayload(null);
|
|
47
|
+
console.warn('[CreditOverviewNavClient] Failed to load credit overview', error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
loadCreditOverview();
|
|
53
|
+
return () => {
|
|
54
|
+
controller.abort();
|
|
55
|
+
};
|
|
56
|
+
}, [endpoint, isLoaded, isSignedIn, locale, userId]);
|
|
57
|
+
if (!payload) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return (jsx(CreditNavButton, { locale: locale, totalBalance: payload.data.totalBalance, totalLabel: payload.totalLabel, children: jsx(CreditOverviewClient, { locale: locale, data: payload.data, translations: payload.translations }) }));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { CreditOverviewNavClient };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { CreditOverviewClient } from './credit-overview-client';
|
|
2
|
+
export { CreditOverviewNavClient } from './credit-overview-nav-client';
|
|
2
3
|
export { CreditNavButton } from './credit-nav-button';
|
|
3
4
|
export type { CreditOverviewTranslations } from './credit-overview-client';
|
|
5
|
+
export type { CreditOverviewNavClientProps, CreditOverviewPayload, } from './credit-overview-nav-client';
|
|
4
6
|
export type { CreditOverviewData, CreditBucket, CreditBucketStatus, SubscriptionInfo, } from './types';
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var creditOverviewClient = require('./credit-overview-client.js');
|
|
5
|
+
var creditOverviewNavClient = require('./credit-overview-nav-client.js');
|
|
5
6
|
var creditNavButton = require('./credit-nav-button.js');
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
exports.CreditOverviewClient = creditOverviewClient.CreditOverviewClient;
|
|
11
|
+
exports.CreditOverviewNavClient = creditOverviewNavClient.CreditOverviewNavClient;
|
|
10
12
|
exports.CreditNavButton = creditNavButton.CreditNavButton;
|
|
@@ -29,21 +29,21 @@ export interface CreditCTAConfig {
|
|
|
29
29
|
}
|
|
30
30
|
export type CreditBucketStatus = 'active' | 'expiringSoon' | 'expired';
|
|
31
31
|
export interface CreditBucket {
|
|
32
|
-
/**
|
|
32
|
+
/** Business-defined credit type identifier for translation mapping or analytics. */
|
|
33
33
|
kind: string;
|
|
34
|
-
/**
|
|
34
|
+
/** Display name override; otherwise the component uses the default translation for kind. */
|
|
35
35
|
label?: string;
|
|
36
|
-
/**
|
|
36
|
+
/** Current credit balance. */
|
|
37
37
|
balance: number;
|
|
38
|
-
/**
|
|
38
|
+
/** Credit limit for this credit type. */
|
|
39
39
|
limit: number;
|
|
40
|
-
/**
|
|
40
|
+
/** Optional status label for highlighting states such as expiration. */
|
|
41
41
|
status?: CreditBucketStatus;
|
|
42
|
-
/**
|
|
42
|
+
/** Credit expiration time as a local time string, used to derive component state. */
|
|
43
43
|
expiresAt?: string;
|
|
44
|
-
/**
|
|
44
|
+
/** Progress percentage from 0 to 100; computed from balance/limit when omitted. */
|
|
45
45
|
progressPercent?: number;
|
|
46
|
-
/**
|
|
46
|
+
/** Additional details, such as remaining days or usage limits. */
|
|
47
47
|
description?: string;
|
|
48
48
|
}
|
|
49
49
|
export interface SubscriptionInfo {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { MoneyPriceInteractive } from './money-price-interactive';
|
|
2
2
|
export { MoneyPriceButton } from './money-price-button';
|
|
3
|
-
export type { MoneyPriceConfig, MoneyPriceData, InitUserContext, MoneyPriceInteractiveProps, MoneyPriceButtonProps, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext, } from './money-price-types';
|
|
3
|
+
export type { MoneyPriceConfig, MoneyPriceData, MoneyPriceAnimeTone, MoneyPriceStrictDiffAnime, InitUserContext, MoneyPriceInteractiveProps, MoneyPriceButtonProps, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext, } from './money-price-types';
|
|
4
4
|
export { UserState } from './money-price-types';
|
|
@@ -26,9 +26,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
26
26
|
return billing === 'monthly' ? 2 : 4;
|
|
27
27
|
return 0;
|
|
28
28
|
};
|
|
29
|
-
//
|
|
29
|
+
// Button configuration for one-time mode.
|
|
30
30
|
const getOnetimeButtonConfig = () => {
|
|
31
|
-
//
|
|
31
|
+
// Anonymous users: show the sign-in button on every card.
|
|
32
32
|
if (!isAuthenticated) {
|
|
33
33
|
return {
|
|
34
34
|
text: texts.getStarted,
|
|
@@ -38,11 +38,11 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
if (subscriptionStatus === moneyPriceTypes.UserState.Anonymous) {
|
|
41
|
-
//
|
|
41
|
+
// Signed in but status unknown: treat as FreeUser.
|
|
42
42
|
console.warn('Clerk is authed OK but user is anonymous!');
|
|
43
43
|
return { text: '', disabled: true, hidden: true };
|
|
44
44
|
}
|
|
45
|
-
//
|
|
45
|
+
// Signed-in users: show the buy-credits button on every card in one-time mode.
|
|
46
46
|
return {
|
|
47
47
|
text: texts.buyCredits || texts.upgrade,
|
|
48
48
|
onClick: () => onAction(planKey, billingType),
|
|
@@ -50,9 +50,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
50
50
|
hidden: false
|
|
51
51
|
};
|
|
52
52
|
};
|
|
53
|
-
//
|
|
53
|
+
// Button configuration for subscription mode.
|
|
54
54
|
const getSubscriptionButtonConfig = () => {
|
|
55
|
-
//
|
|
55
|
+
// Anonymous users.
|
|
56
56
|
if (!isAuthenticated) {
|
|
57
57
|
const getButtonText = () => {
|
|
58
58
|
switch (planKey) {
|
|
@@ -73,7 +73,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
73
73
|
hidden: false
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
-
//
|
|
76
|
+
// Signed-in users.
|
|
77
77
|
switch (subscriptionStatus) {
|
|
78
78
|
case moneyPriceTypes.UserState.FreeUser: {
|
|
79
79
|
if (planTier === 'F1') {
|
|
@@ -91,7 +91,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
93
|
case moneyPriceTypes.UserState.ProUser: {
|
|
94
|
-
//
|
|
94
|
+
// Do not allow downgrades to Free.
|
|
95
95
|
if (planTier === 'F1') {
|
|
96
96
|
return { hidden: true };
|
|
97
97
|
}
|
|
@@ -169,12 +169,12 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
169
169
|
return { hidden: true };
|
|
170
170
|
}
|
|
171
171
|
default:
|
|
172
|
-
//
|
|
172
|
+
// Signed in but status unknown: treat as FreeUser.
|
|
173
173
|
console.warn('Clerk is authed OK but user is anonymous!');
|
|
174
174
|
return { text: '', disabled: true, hidden: true };
|
|
175
175
|
}
|
|
176
176
|
};
|
|
177
|
-
//
|
|
177
|
+
// Main button configuration function.
|
|
178
178
|
const getButtonConfig = () => {
|
|
179
179
|
if (billingType === 'onetime') {
|
|
180
180
|
return getOnetimeButtonConfig();
|
|
@@ -24,9 +24,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
24
24
|
return billing === 'monthly' ? 2 : 4;
|
|
25
25
|
return 0;
|
|
26
26
|
};
|
|
27
|
-
//
|
|
27
|
+
// Button configuration for one-time mode.
|
|
28
28
|
const getOnetimeButtonConfig = () => {
|
|
29
|
-
//
|
|
29
|
+
// Anonymous users: show the sign-in button on every card.
|
|
30
30
|
if (!isAuthenticated) {
|
|
31
31
|
return {
|
|
32
32
|
text: texts.getStarted,
|
|
@@ -36,11 +36,11 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
if (subscriptionStatus === UserState.Anonymous) {
|
|
39
|
-
//
|
|
39
|
+
// Signed in but status unknown: treat as FreeUser.
|
|
40
40
|
console.warn('Clerk is authed OK but user is anonymous!');
|
|
41
41
|
return { text: '', disabled: true, hidden: true };
|
|
42
42
|
}
|
|
43
|
-
//
|
|
43
|
+
// Signed-in users: show the buy-credits button on every card in one-time mode.
|
|
44
44
|
return {
|
|
45
45
|
text: texts.buyCredits || texts.upgrade,
|
|
46
46
|
onClick: () => onAction(planKey, billingType),
|
|
@@ -48,9 +48,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
48
48
|
hidden: false
|
|
49
49
|
};
|
|
50
50
|
};
|
|
51
|
-
//
|
|
51
|
+
// Button configuration for subscription mode.
|
|
52
52
|
const getSubscriptionButtonConfig = () => {
|
|
53
|
-
//
|
|
53
|
+
// Anonymous users.
|
|
54
54
|
if (!isAuthenticated) {
|
|
55
55
|
const getButtonText = () => {
|
|
56
56
|
switch (planKey) {
|
|
@@ -71,7 +71,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
71
71
|
hidden: false
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
-
//
|
|
74
|
+
// Signed-in users.
|
|
75
75
|
switch (subscriptionStatus) {
|
|
76
76
|
case UserState.FreeUser: {
|
|
77
77
|
if (planTier === 'F1') {
|
|
@@ -89,7 +89,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
case UserState.ProUser: {
|
|
92
|
-
//
|
|
92
|
+
// Do not allow downgrades to Free.
|
|
93
93
|
if (planTier === 'F1') {
|
|
94
94
|
return { hidden: true };
|
|
95
95
|
}
|
|
@@ -167,12 +167,12 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
|
|
|
167
167
|
return { hidden: true };
|
|
168
168
|
}
|
|
169
169
|
default:
|
|
170
|
-
//
|
|
170
|
+
// Signed in but status unknown: treat as FreeUser.
|
|
171
171
|
console.warn('Clerk is authed OK but user is anonymous!');
|
|
172
172
|
return { text: '', disabled: true, hidden: true };
|
|
173
173
|
}
|
|
174
174
|
};
|
|
175
|
-
//
|
|
175
|
+
// Main button configuration function.
|
|
176
176
|
const getButtonConfig = () => {
|
|
177
177
|
if (billingType === 'onetime') {
|
|
178
178
|
return getOnetimeButtonConfig();
|
|
@@ -1,52 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Money Price Configuration
|
|
3
|
-
*
|
|
3
|
+
* Pricing component configuration.
|
|
4
4
|
*/
|
|
5
5
|
import type { MoneyPriceConfig, PaymentProviderConfig, EnhancePricePlan } from './money-price-types';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Get the currently active payment provider configuration.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
9
|
+
* Security design:
|
|
10
|
+
* - The utility layer extracts the active provider configuration from the config.
|
|
11
|
+
* - Only the extracted result is returned; the full config structure is not exposed.
|
|
12
|
+
* - Application-level wrappers hide the config object from callers.
|
|
13
13
|
*
|
|
14
|
-
* @param config - MoneyPriceConfig
|
|
15
|
-
* @returns
|
|
14
|
+
* @param config - MoneyPriceConfig object provided by the application layer.
|
|
15
|
+
* @returns The currently active payment provider configuration.
|
|
16
16
|
*/
|
|
17
17
|
export declare function getActiveProviderConfigUtil(config: MoneyPriceConfig): PaymentProviderConfig;
|
|
18
18
|
export declare function getProductPricing(productKey: 'F1' | 'P2' | 'U3', billingType: string, provider: string, config: MoneyPriceConfig): EnhancePricePlan;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Get the credit amount for a price ID.
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
* -
|
|
24
|
-
* -
|
|
25
|
-
* -
|
|
22
|
+
* Security design:
|
|
23
|
+
* - The utility layer parses the config and extracts only the required data.
|
|
24
|
+
* - Only the query result is returned; the full config structure is not exposed.
|
|
25
|
+
* - Application-level wrappers hide the config object from callers.
|
|
26
26
|
*
|
|
27
|
-
* @param priceId -
|
|
28
|
-
* @param config - MoneyPriceConfig
|
|
29
|
-
* @returns
|
|
27
|
+
* @param priceId - Price ID to query.
|
|
28
|
+
* @param config - MoneyPriceConfig object provided by the application layer.
|
|
29
|
+
* @returns The matching credit amount, or null.
|
|
30
30
|
*/
|
|
31
31
|
export declare function getCreditsFromPriceIdUtil(priceId: string | undefined, config: MoneyPriceConfig): number | null;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* Get price configuration by query parameters.
|
|
34
34
|
*
|
|
35
|
-
*
|
|
36
|
-
* 1.
|
|
37
|
-
* 2.
|
|
38
|
-
* 3.
|
|
35
|
+
* Supported query modes:
|
|
36
|
+
* 1. Query directly by priceId.
|
|
37
|
+
* 2. Query by plan and billingType.
|
|
38
|
+
* 3. Query by plan.
|
|
39
39
|
*
|
|
40
|
-
*
|
|
41
|
-
* -
|
|
42
|
-
* -
|
|
43
|
-
* -
|
|
40
|
+
* Security design:
|
|
41
|
+
* - The utility layer parses the config and extracts only matching data.
|
|
42
|
+
* - Only the query result is returned; the full config structure is not exposed.
|
|
43
|
+
* - Application-level wrappers hide the config object from callers.
|
|
44
44
|
*
|
|
45
|
-
* @param priceId -
|
|
46
|
-
* @param plan -
|
|
47
|
-
* @param billingType -
|
|
48
|
-
* @param config - MoneyPriceConfig
|
|
49
|
-
* @returns
|
|
45
|
+
* @param priceId - Optional price ID to query.
|
|
46
|
+
* @param plan - Optional plan name, such as 'P2' or 'U3'.
|
|
47
|
+
* @param billingType - Optional billing type, such as 'monthly' or 'yearly'.
|
|
48
|
+
* @param config - MoneyPriceConfig object provided by the application layer.
|
|
49
|
+
* @returns The matching price config with derived metadata: priceName, description, and interval.
|
|
50
50
|
*/
|
|
51
51
|
export declare function getPriceConfigUtil(priceId: string | undefined, plan: string | undefined, billingType: string | undefined, config: MoneyPriceConfig): (EnhancePricePlan & {
|
|
52
52
|
priceName: string;
|