@windrun-huaiin/third-ui 31.3.7 → 31.4.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/dist/main/credit/credit-nav-button.d.ts +3 -2
- package/dist/main/credit/credit-nav-button.js +7 -9
- package/dist/main/credit/credit-nav-button.mjs +5 -7
- package/dist/main/credit/credit-overview-nav-client.d.ts +7 -2
- package/dist/main/credit/credit-overview-nav-client.js +2 -2
- package/dist/main/credit/credit-overview-nav-client.mjs +2 -2
- package/dist/main/credit/index.d.ts +1 -1
- package/dist/main/credit/types.d.ts +1 -0
- package/dist/main/money-price/index.d.ts +2 -0
- package/dist/main/money-price/index.js +4 -0
- package/dist/main/money-price/index.mjs +1 -0
- package/dist/main/money-price/money-price-interactive.d.ts +1 -1
- package/dist/main/money-price/money-price-interactive.js +7 -5
- package/dist/main/money-price/money-price-interactive.mjs +7 -5
- package/dist/main/money-price/money-price-types.d.ts +2 -0
- package/dist/main/money-price/money-price.d.ts +1 -1
- package/dist/main/money-price/money-price.js +2 -2
- package/dist/main/money-price/money-price.mjs +2 -2
- package/dist/main/money-price/pricing-modal.d.ts +33 -0
- package/dist/main/money-price/pricing-modal.js +109 -0
- package/dist/main/money-price/pricing-modal.mjs +105 -0
- package/package.json +3 -3
- package/src/main/credit/credit-nav-button.tsx +15 -56
- package/src/main/credit/credit-overview-nav-client.tsx +8 -1
- package/src/main/credit/index.ts +1 -0
- package/src/main/credit/types.ts +1 -0
- package/src/main/money-price/index.ts +10 -0
- package/src/main/money-price/money-price-interactive.tsx +41 -31
- package/src/main/money-price/money-price-types.ts +2 -0
- package/src/main/money-price/money-price.tsx +2 -0
- package/src/main/money-price/pricing-modal.tsx +283 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { MoneyPriceData } from '../money-price/money-price-types';
|
|
2
|
-
import type { CreditPricingContext, PricingModalMode } from './types';
|
|
2
|
+
import type { CreditPricingContext, MobileBillingSwitchBehavior, PricingModalMode } from './types';
|
|
3
3
|
interface CreditNavButtonProps {
|
|
4
4
|
locale: string;
|
|
5
5
|
totalBalance: number;
|
|
6
6
|
totalLabel: string;
|
|
7
|
+
mobileBillingSwitchBehavior?: MobileBillingSwitchBehavior;
|
|
7
8
|
children: React.ReactNode;
|
|
8
9
|
}
|
|
9
|
-
export declare function CreditNavButton({ locale, totalBalance, totalLabel, children, }: CreditNavButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function CreditNavButton({ locale, totalBalance, totalLabel, mobileBillingSwitchBehavior, children, }: CreditNavButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
10
11
|
interface CreditNavPopoverContextValue {
|
|
11
12
|
close: () => void;
|
|
12
13
|
isMobile: boolean;
|
|
@@ -4,20 +4,18 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var utils = require('@windrun-huaiin/lib/utils');
|
|
6
6
|
var icons = require('@windrun-huaiin/base-ui/icons');
|
|
7
|
-
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
8
7
|
var ui = require('@windrun-huaiin/base-ui/ui');
|
|
9
8
|
var React = require('react');
|
|
10
|
-
var moneyPriceInteractive = require('../money-price/money-price-interactive.js');
|
|
11
9
|
var moneyPriceConfigUtil = require('../money-price/money-price-config-util.js');
|
|
12
|
-
var
|
|
10
|
+
var pricingModal = require('../money-price/pricing-modal.js');
|
|
13
11
|
|
|
14
|
-
function CreditNavButton({ locale, totalBalance, totalLabel, children, }) {
|
|
12
|
+
function CreditNavButton({ locale, totalBalance, totalLabel, mobileBillingSwitchBehavior, children, }) {
|
|
15
13
|
const [open, setOpen] = React.useState(false);
|
|
16
14
|
const [isMobile, setIsMobile] = React.useState(false);
|
|
17
15
|
const triggerRef = React.useRef(null);
|
|
18
16
|
const contentRef = React.useRef(null);
|
|
19
17
|
const closeMenu = React.useCallback(() => setOpen(false), []);
|
|
20
|
-
const [pricingModal, setPricingModal] = React.useState({
|
|
18
|
+
const [pricingModal$1, setPricingModal] = React.useState({
|
|
21
19
|
open: false,
|
|
22
20
|
mode: 'subscription',
|
|
23
21
|
});
|
|
@@ -108,13 +106,13 @@ function CreditNavButton({ locale, totalBalance, totalLabel, children, }) {
|
|
|
108
106
|
openPricingModal,
|
|
109
107
|
closePricingModal,
|
|
110
108
|
}), [closeMenu, isMobile, openPricingModal, closePricingModal]);
|
|
111
|
-
const isOnetimeModal = pricingModal.mode === 'onetime';
|
|
109
|
+
const isOnetimeModal = pricingModal$1.mode === 'onetime';
|
|
112
110
|
const modalInitialBillingType = React.useMemo(() => {
|
|
113
111
|
var _a, _b;
|
|
114
112
|
if (isOnetimeModal) {
|
|
115
113
|
return 'onetime';
|
|
116
114
|
}
|
|
117
|
-
const pricingContext = pricingModal.pricingContext;
|
|
115
|
+
const pricingContext = pricingModal$1.pricingContext;
|
|
118
116
|
const priceId = (_b = (_a = pricingContext === null || pricingContext === void 0 ? void 0 : pricingContext.initUserContext) === null || _a === void 0 ? void 0 : _a.xSubscription) === null || _b === void 0 ? void 0 : _b.priceId;
|
|
119
117
|
if (!pricingContext || !priceId) {
|
|
120
118
|
return undefined;
|
|
@@ -129,8 +127,8 @@ function CreditNavButton({ locale, totalBalance, totalLabel, children, }) {
|
|
|
129
127
|
}
|
|
130
128
|
}
|
|
131
129
|
return undefined;
|
|
132
|
-
}, [isOnetimeModal, pricingModal.pricingContext]);
|
|
133
|
-
return (jsxRuntime.jsxs(CreditNavPopoverContext.Provider, { value: contextValue, children: [jsxRuntime.jsxs(ui.DropdownMenu, { modal: false, open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", "aria-label": `${formattedBalance} ${totalLabel}`, className: utils.cn('group relative mx-2 sm:mx-1 inline-flex items-center gap-2 overflow-hidden rounded-full border border-slate-200 bg-white pl-2 pr-4 py-1.5 text-sm font-semibold text-slate-700 shadow-sm transition-all duration-200 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100', 'hover:-translate-y-0.5 hover:scale-[1.02] hover:border-transparent hover:text-white hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-slate-400 dark:focus-visible:ring-slate-500'), ref: triggerRef, children: [jsxRuntime.jsx("span", { className: "pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-200 group-hover:opacity-100 group-focus-visible:opacity-100 bg-linear-to-bl from-indigo-200/60 via-indigo-400/90 to-purple-200/50 dark:from-indigo-300/20 dark:via-slate-400 dark:to-slate-500/50", "aria-hidden": "true" }), jsxRuntime.jsx("span", { className: "relative z-10 flex h-6 w-6 items-center justify-center rounded-full bg-slate-100 text-slate-600 transition-transform duration-200 group-hover:scale-110 group-hover:bg-white/20 group-hover:text-white dark:bg-slate-800 dark:text-slate-200 dark:group-hover:bg-white/20 dark:group-hover:text-white", children: jsxRuntime.jsx(icons.GemIcon, { className: "h-3.5 w-3.5" }) }), jsxRuntime.jsxs("span", { className: "relative z-10 flex items-center", children: [jsxRuntime.jsx("span", { className: "text-base font-semibold leading-none", children: formattedBalance }), jsxRuntime.jsx("span", { className: "sr-only", children: ` ${totalLabel}` })] })] }) }), jsxRuntime.jsx(ui.DropdownMenuContent, { forceMount: true, sideOffset: 12, align: "end", className: "z-50 border-0 bg-transparent p-0 shadow-none mx-4 sm:mx-2 md:mx-1", children: jsxRuntime.jsx("div", { className: "w-[90vw] max-w-[90vw] max-h-[80vh] overflow-y-auto overflow-x-hidden rounded-3xl bg-transparent sm:w-[410px] sm:max-h-[90vh] sm:max-w-[95vw]", ref: contentRef, children: children }) })] }), pricingModal.modalMoneyPriceData && pricingModal.pricingContext ? (jsxRuntime.jsx(
|
|
130
|
+
}, [isOnetimeModal, pricingModal$1.pricingContext]);
|
|
131
|
+
return (jsxRuntime.jsxs(CreditNavPopoverContext.Provider, { value: contextValue, children: [jsxRuntime.jsxs(ui.DropdownMenu, { modal: false, open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", "aria-label": `${formattedBalance} ${totalLabel}`, className: utils.cn('group relative mx-2 sm:mx-1 inline-flex items-center gap-2 overflow-hidden rounded-full border border-slate-200 bg-white pl-2 pr-4 py-1.5 text-sm font-semibold text-slate-700 shadow-sm transition-all duration-200 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100', 'hover:-translate-y-0.5 hover:scale-[1.02] hover:border-transparent hover:text-white hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-slate-400 dark:focus-visible:ring-slate-500'), ref: triggerRef, children: [jsxRuntime.jsx("span", { className: "pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-200 group-hover:opacity-100 group-focus-visible:opacity-100 bg-linear-to-bl from-indigo-200/60 via-indigo-400/90 to-purple-200/50 dark:from-indigo-300/20 dark:via-slate-400 dark:to-slate-500/50", "aria-hidden": "true" }), jsxRuntime.jsx("span", { className: "relative z-10 flex h-6 w-6 items-center justify-center rounded-full bg-slate-100 text-slate-600 transition-transform duration-200 group-hover:scale-110 group-hover:bg-white/20 group-hover:text-white dark:bg-slate-800 dark:text-slate-200 dark:group-hover:bg-white/20 dark:group-hover:text-white", children: jsxRuntime.jsx(icons.GemIcon, { className: "h-3.5 w-3.5" }) }), jsxRuntime.jsxs("span", { className: "relative z-10 flex items-center", children: [jsxRuntime.jsx("span", { className: "text-base font-semibold leading-none", children: formattedBalance }), jsxRuntime.jsx("span", { className: "sr-only", children: ` ${totalLabel}` })] })] }) }), jsxRuntime.jsx(ui.DropdownMenuContent, { forceMount: true, sideOffset: 12, align: "end", className: "z-50 border-0 bg-transparent p-0 shadow-none mx-4 sm:mx-2 md:mx-1", children: jsxRuntime.jsx("div", { className: "w-[90vw] max-w-[90vw] max-h-[80vh] overflow-y-auto overflow-x-hidden rounded-3xl bg-transparent sm:w-[410px] sm:max-h-[90vh] sm:max-w-[95vw]", ref: contentRef, children: children }) })] }), pricingModal$1.modalMoneyPriceData && pricingModal$1.pricingContext ? (jsxRuntime.jsx(pricingModal.PricingModal, { open: pricingModal$1.open, onOpenChange: (open) => setPricingModal((prev) => (Object.assign(Object.assign({}, prev), { open }))), data: pricingModal$1.modalMoneyPriceData, config: pricingModal$1.pricingContext.moneyPriceConfig, checkoutApiEndpoint: pricingModal$1.pricingContext.checkoutApiEndpoint, customerPortalApiEndpoint: pricingModal$1.pricingContext.customerPortalApiEndpoint, mobileBillingSwitchBehavior: mobileBillingSwitchBehavior, enableSubscriptionUpgrade: pricingModal$1.pricingContext.enableSubscriptionUpgrade, billingType: modalInitialBillingType, initUserContext: pricingModal$1.pricingContext.initUserContext })) : null] }));
|
|
134
132
|
}
|
|
135
133
|
const CreditNavPopoverContext = React.createContext(null);
|
|
136
134
|
function useCreditNavPopover() {
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
4
|
-
import { GemIcon
|
|
5
|
-
import {
|
|
6
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle } from '@windrun-huaiin/base-ui/ui';
|
|
4
|
+
import { GemIcon } from '@windrun-huaiin/base-ui/icons';
|
|
5
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent } from '@windrun-huaiin/base-ui/ui';
|
|
7
6
|
import { createContext, useState, useRef, useCallback, useMemo, useEffect, useContext } from 'react';
|
|
8
|
-
import { MoneyPriceInteractive } from '../money-price/money-price-interactive.mjs';
|
|
9
7
|
import { getActiveProviderConfigUtil } from '../money-price/money-price-config-util.mjs';
|
|
10
|
-
import {
|
|
8
|
+
import { PricingModal } from '../money-price/pricing-modal.mjs';
|
|
11
9
|
|
|
12
|
-
function CreditNavButton({ locale, totalBalance, totalLabel, children, }) {
|
|
10
|
+
function CreditNavButton({ locale, totalBalance, totalLabel, mobileBillingSwitchBehavior, children, }) {
|
|
13
11
|
const [open, setOpen] = useState(false);
|
|
14
12
|
const [isMobile, setIsMobile] = useState(false);
|
|
15
13
|
const triggerRef = useRef(null);
|
|
@@ -128,7 +126,7 @@ function CreditNavButton({ locale, totalBalance, totalLabel, children, }) {
|
|
|
128
126
|
}
|
|
129
127
|
return undefined;
|
|
130
128
|
}, [isOnetimeModal, pricingModal.pricingContext]);
|
|
131
|
-
return (jsxs(CreditNavPopoverContext.Provider, { value: contextValue, children: [jsxs(DropdownMenu, { modal: false, open: open, onOpenChange: setOpen, children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs("button", { type: "button", "aria-label": `${formattedBalance} ${totalLabel}`, className: cn('group relative mx-2 sm:mx-1 inline-flex items-center gap-2 overflow-hidden rounded-full border border-slate-200 bg-white pl-2 pr-4 py-1.5 text-sm font-semibold text-slate-700 shadow-sm transition-all duration-200 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100', 'hover:-translate-y-0.5 hover:scale-[1.02] hover:border-transparent hover:text-white hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-slate-400 dark:focus-visible:ring-slate-500'), ref: triggerRef, children: [jsx("span", { className: "pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-200 group-hover:opacity-100 group-focus-visible:opacity-100 bg-linear-to-bl from-indigo-200/60 via-indigo-400/90 to-purple-200/50 dark:from-indigo-300/20 dark:via-slate-400 dark:to-slate-500/50", "aria-hidden": "true" }), jsx("span", { className: "relative z-10 flex h-6 w-6 items-center justify-center rounded-full bg-slate-100 text-slate-600 transition-transform duration-200 group-hover:scale-110 group-hover:bg-white/20 group-hover:text-white dark:bg-slate-800 dark:text-slate-200 dark:group-hover:bg-white/20 dark:group-hover:text-white", children: jsx(GemIcon, { className: "h-3.5 w-3.5" }) }), jsxs("span", { className: "relative z-10 flex items-center", children: [jsx("span", { className: "text-base font-semibold leading-none", children: formattedBalance }), jsx("span", { className: "sr-only", children: ` ${totalLabel}` })] })] }) }), jsx(DropdownMenuContent, { forceMount: true, sideOffset: 12, align: "end", className: "z-50 border-0 bg-transparent p-0 shadow-none mx-4 sm:mx-2 md:mx-1", children: jsx("div", { className: "w-[90vw] max-w-[90vw] max-h-[80vh] overflow-y-auto overflow-x-hidden rounded-3xl bg-transparent sm:w-[410px] sm:max-h-[90vh] sm:max-w-[95vw]", ref: contentRef, children: children }) })] }), pricingModal.modalMoneyPriceData && pricingModal.pricingContext ? (jsx(
|
|
129
|
+
return (jsxs(CreditNavPopoverContext.Provider, { value: contextValue, children: [jsxs(DropdownMenu, { modal: false, open: open, onOpenChange: setOpen, children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs("button", { type: "button", "aria-label": `${formattedBalance} ${totalLabel}`, className: cn('group relative mx-2 sm:mx-1 inline-flex items-center gap-2 overflow-hidden rounded-full border border-slate-200 bg-white pl-2 pr-4 py-1.5 text-sm font-semibold text-slate-700 shadow-sm transition-all duration-200 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100', 'hover:-translate-y-0.5 hover:scale-[1.02] hover:border-transparent hover:text-white hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-slate-400 dark:focus-visible:ring-slate-500'), ref: triggerRef, children: [jsx("span", { className: "pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-200 group-hover:opacity-100 group-focus-visible:opacity-100 bg-linear-to-bl from-indigo-200/60 via-indigo-400/90 to-purple-200/50 dark:from-indigo-300/20 dark:via-slate-400 dark:to-slate-500/50", "aria-hidden": "true" }), jsx("span", { className: "relative z-10 flex h-6 w-6 items-center justify-center rounded-full bg-slate-100 text-slate-600 transition-transform duration-200 group-hover:scale-110 group-hover:bg-white/20 group-hover:text-white dark:bg-slate-800 dark:text-slate-200 dark:group-hover:bg-white/20 dark:group-hover:text-white", children: jsx(GemIcon, { className: "h-3.5 w-3.5" }) }), jsxs("span", { className: "relative z-10 flex items-center", children: [jsx("span", { className: "text-base font-semibold leading-none", children: formattedBalance }), jsx("span", { className: "sr-only", children: ` ${totalLabel}` })] })] }) }), jsx(DropdownMenuContent, { forceMount: true, sideOffset: 12, align: "end", className: "z-50 border-0 bg-transparent p-0 shadow-none mx-4 sm:mx-2 md:mx-1", children: jsx("div", { className: "w-[90vw] max-w-[90vw] max-h-[80vh] overflow-y-auto overflow-x-hidden rounded-3xl bg-transparent sm:w-[410px] sm:max-h-[90vh] sm:max-w-[95vw]", ref: contentRef, children: children }) })] }), pricingModal.modalMoneyPriceData && pricingModal.pricingContext ? (jsx(PricingModal, { open: pricingModal.open, onOpenChange: (open) => setPricingModal((prev) => (Object.assign(Object.assign({}, prev), { open }))), data: pricingModal.modalMoneyPriceData, config: pricingModal.pricingContext.moneyPriceConfig, checkoutApiEndpoint: pricingModal.pricingContext.checkoutApiEndpoint, customerPortalApiEndpoint: pricingModal.pricingContext.customerPortalApiEndpoint, mobileBillingSwitchBehavior: mobileBillingSwitchBehavior, enableSubscriptionUpgrade: pricingModal.pricingContext.enableSubscriptionUpgrade, billingType: modalInitialBillingType, initUserContext: pricingModal.pricingContext.initUserContext })) : null] }));
|
|
132
130
|
}
|
|
133
131
|
const CreditNavPopoverContext = createContext(null);
|
|
134
132
|
function useCreditNavPopover() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CreditOverviewTranslations } from './credit-overview-client';
|
|
2
|
-
import type { CreditOverviewData } from './types';
|
|
2
|
+
import type { CreditOverviewData, MobileBillingSwitchBehavior } from './types';
|
|
3
3
|
export declare const DEFAULT_CREDIT_OVERVIEW_REFRESH_EVENT = "windrun-huaiin:credit-overview:refresh";
|
|
4
4
|
export interface CreditOverviewPayload {
|
|
5
5
|
data: CreditOverviewData;
|
|
@@ -14,6 +14,11 @@ export interface CreditOverviewNavClientProps {
|
|
|
14
14
|
* Defaults are handled by the API/payload builder when omitted.
|
|
15
15
|
*/
|
|
16
16
|
enabledBillingTypes?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* Mobile behavior for the pricing modal billing switch.
|
|
19
|
+
* Default: 'sticky'.
|
|
20
|
+
*/
|
|
21
|
+
mobileBillingSwitchBehavior?: MobileBillingSwitchBehavior;
|
|
17
22
|
/**
|
|
18
23
|
* Browser event names that should trigger credit overview reload.
|
|
19
24
|
* Business apps can dispatch these events after credit balance changes.
|
|
@@ -29,4 +34,4 @@ export interface CreditOverviewNavClientProps {
|
|
|
29
34
|
refreshDebounceMs?: number;
|
|
30
35
|
}
|
|
31
36
|
export declare function dispatchCreditOverviewRefresh(eventName?: string): void;
|
|
32
|
-
export declare function CreditOverviewNavClient({ locale, endpoint, enabledBillingTypes, refreshEvents, refreshDebounceMs, }: CreditOverviewNavClientProps): import("react/jsx-runtime").JSX.Element | null;
|
|
37
|
+
export declare function CreditOverviewNavClient({ locale, endpoint, enabledBillingTypes, mobileBillingSwitchBehavior, refreshEvents, refreshDebounceMs, }: CreditOverviewNavClientProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -43,7 +43,7 @@ function dispatchCreditOverviewRefresh(eventName = DEFAULT_CREDIT_OVERVIEW_REFRE
|
|
|
43
43
|
}
|
|
44
44
|
window.dispatchEvent(new CustomEvent(eventName));
|
|
45
45
|
}
|
|
46
|
-
function CreditOverviewNavClient({ locale, endpoint, enabledBillingTypes, refreshEvents, refreshDebounceMs = 300, }) {
|
|
46
|
+
function CreditOverviewNavClient({ locale, endpoint, enabledBillingTypes, mobileBillingSwitchBehavior, refreshEvents, refreshDebounceMs = 300, }) {
|
|
47
47
|
const { isLoaded, isSignedIn, userId } = nextjs.useAuth();
|
|
48
48
|
const [payload, setPayload] = React.useState(null);
|
|
49
49
|
const abortControllerRef = React.useRef(null);
|
|
@@ -135,7 +135,7 @@ function CreditOverviewNavClient({ locale, endpoint, enabledBillingTypes, refres
|
|
|
135
135
|
if (!payload) {
|
|
136
136
|
return null;
|
|
137
137
|
}
|
|
138
|
-
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 }) }));
|
|
138
|
+
return (jsxRuntime.jsx(creditNavButton.CreditNavButton, { locale: locale, totalBalance: payload.data.totalBalance, totalLabel: payload.totalLabel, mobileBillingSwitchBehavior: mobileBillingSwitchBehavior, children: jsxRuntime.jsx(creditOverviewClient.CreditOverviewClient, { locale: locale, data: payload.data, translations: payload.translations }) }));
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
exports.CreditOverviewNavClient = CreditOverviewNavClient;
|
|
@@ -41,7 +41,7 @@ function dispatchCreditOverviewRefresh(eventName = DEFAULT_CREDIT_OVERVIEW_REFRE
|
|
|
41
41
|
}
|
|
42
42
|
window.dispatchEvent(new CustomEvent(eventName));
|
|
43
43
|
}
|
|
44
|
-
function CreditOverviewNavClient({ locale, endpoint, enabledBillingTypes, refreshEvents, refreshDebounceMs = 300, }) {
|
|
44
|
+
function CreditOverviewNavClient({ locale, endpoint, enabledBillingTypes, mobileBillingSwitchBehavior, refreshEvents, refreshDebounceMs = 300, }) {
|
|
45
45
|
const { isLoaded, isSignedIn, userId } = useAuth();
|
|
46
46
|
const [payload, setPayload] = useState(null);
|
|
47
47
|
const abortControllerRef = useRef(null);
|
|
@@ -133,7 +133,7 @@ function CreditOverviewNavClient({ locale, endpoint, enabledBillingTypes, refres
|
|
|
133
133
|
if (!payload) {
|
|
134
134
|
return null;
|
|
135
135
|
}
|
|
136
|
-
return (jsx(CreditNavButton, { locale: locale, totalBalance: payload.data.totalBalance, totalLabel: payload.totalLabel, children: jsx(CreditOverviewClient, { locale: locale, data: payload.data, translations: payload.translations }) }));
|
|
136
|
+
return (jsx(CreditNavButton, { locale: locale, totalBalance: payload.data.totalBalance, totalLabel: payload.totalLabel, mobileBillingSwitchBehavior: mobileBillingSwitchBehavior, children: jsx(CreditOverviewClient, { locale: locale, data: payload.data, translations: payload.translations }) }));
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
export { CreditOverviewNavClient, DEFAULT_CREDIT_OVERVIEW_REFRESH_EVENT, dispatchCreditOverviewRefresh };
|
|
@@ -3,4 +3,4 @@ export { CreditOverviewNavClient, DEFAULT_CREDIT_OVERVIEW_REFRESH_EVENT, dispatc
|
|
|
3
3
|
export { CreditNavButton } from './credit-nav-button';
|
|
4
4
|
export type { CreditOverviewTranslations } from './credit-overview-client';
|
|
5
5
|
export type { CreditOverviewNavClientProps, CreditOverviewPayload, } from './credit-overview-nav-client';
|
|
6
|
-
export type { CreditOverviewData, CreditBucket, CreditBucketStatus, SubscriptionInfo, } from './types';
|
|
6
|
+
export type { CreditOverviewData, CreditBucket, CreditBucketStatus, MobileBillingSwitchBehavior, SubscriptionInfo, } from './types';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { InitUserContext, MoneyPriceConfig, MoneyPriceData } from '../money-price/money-price-types';
|
|
2
2
|
export type PricingModalMode = 'subscription' | 'onetime';
|
|
3
|
+
export type MobileBillingSwitchBehavior = 'sticky' | 'static';
|
|
3
4
|
export type CreditActionConfig = CreditModalAction | CreditRedirectAction | CreditAuthAction | CreditCustomAction;
|
|
4
5
|
export interface CreditModalAction {
|
|
5
6
|
kind: 'modal';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { MoneyPriceInteractive } from './money-price-interactive';
|
|
2
2
|
export { MoneyPriceButton } from './money-price-button';
|
|
3
|
+
export { PricingModal, PricingModalProvider, usePricingModal, } from './pricing-modal';
|
|
3
4
|
export type { MoneyPriceConfig, MoneyPriceData, MoneyPriceAnimeTone, MoneyPriceStrictDiffAnime, InitUserContext, MoneyPriceInteractiveProps, MoneyPriceButtonProps, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext, } from './money-price-types';
|
|
5
|
+
export type { OpenPricingModalOptions, PricingModalProps, PricingModalProviderProps, } from './pricing-modal';
|
|
4
6
|
export { UserState } from './money-price-types';
|
|
@@ -3,12 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
var moneyPriceInteractive = require('./money-price-interactive.js');
|
|
5
5
|
var moneyPriceButton = require('./money-price-button.js');
|
|
6
|
+
var pricingModal = require('./pricing-modal.js');
|
|
6
7
|
var moneyPriceTypes = require('./money-price-types.js');
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
exports.MoneyPriceInteractive = moneyPriceInteractive.MoneyPriceInteractive;
|
|
11
12
|
exports.MoneyPriceButton = moneyPriceButton.MoneyPriceButton;
|
|
13
|
+
exports.PricingModal = pricingModal.PricingModal;
|
|
14
|
+
exports.PricingModalProvider = pricingModal.PricingModalProvider;
|
|
15
|
+
exports.usePricingModal = pricingModal.usePricingModal;
|
|
12
16
|
Object.defineProperty(exports, "UserState", {
|
|
13
17
|
enumerable: true,
|
|
14
18
|
get: function () { return moneyPriceTypes.UserState; }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
export { MoneyPriceInteractive } from './money-price-interactive.mjs';
|
|
3
3
|
export { MoneyPriceButton } from './money-price-button.mjs';
|
|
4
|
+
export { PricingModal, PricingModalProvider, usePricingModal } from './pricing-modal.mjs';
|
|
4
5
|
export { UserState } from './money-price-types.mjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { type MoneyPriceInteractiveProps } from './money-price-types';
|
|
2
|
-
export declare function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal, enabledBillingTypes, enableSubscriptionUpgrade, initialBillingType, disableAutoDetectBilling, initUserContext, isInitLoading, }: MoneyPriceInteractiveProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal, enabledBillingTypes, mobileBillingSwitchBehavior, enableSubscriptionUpgrade, initialBillingType, disableAutoDetectBilling, initUserContext, isInitLoading, }: MoneyPriceInteractiveProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -17,7 +17,7 @@ require('animejs');
|
|
|
17
17
|
require('../anime/anime-404-page.js');
|
|
18
18
|
|
|
19
19
|
const PLAN_KEYS = ['F1', 'P2', 'U3'];
|
|
20
|
-
function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, enabledBillingTypes, enableSubscriptionUpgrade = true, initialBillingType, disableAutoDetectBilling = false, initUserContext, isInitLoading = false, }) {
|
|
20
|
+
function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, enabledBillingTypes, mobileBillingSwitchBehavior = 'static', enableSubscriptionUpgrade = true, initialBillingType, disableAutoDetectBilling = false, initUserContext, isInitLoading = false, }) {
|
|
21
21
|
var _a, _b, _c, _d, _e, _f;
|
|
22
22
|
const { redirectToSignIn, redirectToSignUp, user: clerkUser, openSignUp } = nextjs.useClerk();
|
|
23
23
|
const router = navigation.useRouter();
|
|
@@ -37,6 +37,7 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
|
|
|
37
37
|
return acc;
|
|
38
38
|
}, {});
|
|
39
39
|
}, [billingOptions]);
|
|
40
|
+
const showBillingSwitch = billingOptions.length > 1;
|
|
40
41
|
const defaultBilling = React.useMemo(() => {
|
|
41
42
|
var _a;
|
|
42
43
|
const defaultKey = data.billingSwitch.defaultKey;
|
|
@@ -309,15 +310,16 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
|
|
|
309
310
|
return null;
|
|
310
311
|
return selectedBillingOption.discountText.replace('{percent}', String(discountPercent));
|
|
311
312
|
}, [selectedBillingOption, providerConfig, billingType]);
|
|
312
|
-
// Configure the mobile
|
|
313
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className:
|
|
313
|
+
// Configure the mobile behavior for BillingTypeButton.
|
|
314
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showBillingSwitch ? (jsxRuntime.jsx("div", { className: utils.cn('mb-6 flex justify-center', mobileBillingSwitchBehavior === 'sticky' &&
|
|
315
|
+
'max-md:sticky max-md:top-2 max-md:z-30 max-md:py-2 max-md:bg-transparent'), children: jsxRuntime.jsx("div", { className: "inline-flex max-w-[calc(100vw-2rem)] bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-700 rounded-full px-2 py-2 sm:px-3 sm:py-3 shadow-sm", "data-billing-switch": true, children: billingOptions.map(option => {
|
|
314
316
|
const isActive = option.key === billingType;
|
|
315
317
|
const buttonClasses = isActive
|
|
316
318
|
? utils.cn('text-white rounded-full shadow-sm', lib.themeButtonGradientClass, lib.themeButtonGradientHoverClass)
|
|
317
319
|
: 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full';
|
|
318
320
|
const showBadge = option.key === billingType && !!discountBadgeText;
|
|
319
|
-
return (jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center mx-1", children: [showBadge && (jsxRuntime.jsx("span", { className: "absolute z-10 left-1/2 -translate-x-1/2 -top-3 sm:-top-4 translate-y-[-50%] px-3 py-0.5 text-[0.625rem] sm:text-xs rounded-md bg-yellow-100 text-yellow-800 font-semibold shadow-sm whitespace-nowrap", children: discountBadgeText })), jsxRuntime.jsx("button", { className: utils.cn('text-sm md:text-base font-medium transition relative text-center z-10 px-2 sm:px-4 py-2 min-w-[100px] sm:min-w-[120px]', buttonClasses), type: "button", "data-billing-button": option.key, onClick: () => setUserSelectedBillingType(option.key), children: option.name })] }, option.key));
|
|
320
|
-
}) }) }), jsxRuntime.jsx("div", { className: "w-full", children: jsxRuntime.jsx("div", { className: "flex flex-wrap justify-center gap-5 md:gap-6 xl:gap-8 w-full max-w-6xl mx-auto", children: currentPlans.map((plan) => {
|
|
321
|
+
return (jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center mx-1", children: [showBadge && (jsxRuntime.jsx("span", { className: "absolute z-10 left-1/2 -translate-x-1/2 -top-3 sm:-top-4 translate-y-[-50%] px-3 py-0.5 text-[0.625rem] sm:text-xs rounded-md bg-yellow-100 text-yellow-800 font-semibold shadow-sm whitespace-nowrap", children: discountBadgeText })), jsxRuntime.jsx("button", { className: utils.cn('text-sm md:text-base font-medium transition relative text-center z-10 px-2 sm:px-4 py-2 min-w-[88px] min-[360px]:min-w-[100px] sm:min-w-[120px]', buttonClasses), type: "button", "data-billing-button": option.key, onClick: () => setUserSelectedBillingType(option.key), children: option.name })] }, option.key));
|
|
322
|
+
}) }) })) : null, jsxRuntime.jsx("div", { className: "w-full", children: jsxRuntime.jsx("div", { className: "flex flex-wrap justify-center gap-5 md:gap-6 xl:gap-8 w-full max-w-6xl mx-auto", children: currentPlans.map((plan) => {
|
|
321
323
|
var _a, _b;
|
|
322
324
|
const planKey = plan.key;
|
|
323
325
|
if (!PLAN_KEYS.includes(planKey)) {
|
|
@@ -15,7 +15,7 @@ import 'animejs';
|
|
|
15
15
|
import '../anime/anime-404-page.mjs';
|
|
16
16
|
|
|
17
17
|
const PLAN_KEYS = ['F1', 'P2', 'U3'];
|
|
18
|
-
function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, enabledBillingTypes, enableSubscriptionUpgrade = true, initialBillingType, disableAutoDetectBilling = false, initUserContext, isInitLoading = false, }) {
|
|
18
|
+
function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, enabledBillingTypes, mobileBillingSwitchBehavior = 'static', enableSubscriptionUpgrade = true, initialBillingType, disableAutoDetectBilling = false, initUserContext, isInitLoading = false, }) {
|
|
19
19
|
var _a, _b, _c, _d, _e, _f;
|
|
20
20
|
const { redirectToSignIn, redirectToSignUp, user: clerkUser, openSignUp } = useClerk();
|
|
21
21
|
const router = useRouter();
|
|
@@ -35,6 +35,7 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
|
|
|
35
35
|
return acc;
|
|
36
36
|
}, {});
|
|
37
37
|
}, [billingOptions]);
|
|
38
|
+
const showBillingSwitch = billingOptions.length > 1;
|
|
38
39
|
const defaultBilling = useMemo(() => {
|
|
39
40
|
var _a;
|
|
40
41
|
const defaultKey = data.billingSwitch.defaultKey;
|
|
@@ -307,15 +308,16 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
|
|
|
307
308
|
return null;
|
|
308
309
|
return selectedBillingOption.discountText.replace('{percent}', String(discountPercent));
|
|
309
310
|
}, [selectedBillingOption, providerConfig, billingType]);
|
|
310
|
-
// Configure the mobile
|
|
311
|
-
return (jsxs(Fragment, { children: [jsx("div", { className:
|
|
311
|
+
// Configure the mobile behavior for BillingTypeButton.
|
|
312
|
+
return (jsxs(Fragment, { children: [showBillingSwitch ? (jsx("div", { className: cn('mb-6 flex justify-center', mobileBillingSwitchBehavior === 'sticky' &&
|
|
313
|
+
'max-md:sticky max-md:top-2 max-md:z-30 max-md:py-2 max-md:bg-transparent'), children: jsx("div", { className: "inline-flex max-w-[calc(100vw-2rem)] bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-700 rounded-full px-2 py-2 sm:px-3 sm:py-3 shadow-sm", "data-billing-switch": true, children: billingOptions.map(option => {
|
|
312
314
|
const isActive = option.key === billingType;
|
|
313
315
|
const buttonClasses = isActive
|
|
314
316
|
? cn('text-white rounded-full shadow-sm', themeButtonGradientClass, themeButtonGradientHoverClass)
|
|
315
317
|
: 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full';
|
|
316
318
|
const showBadge = option.key === billingType && !!discountBadgeText;
|
|
317
|
-
return (jsxs("div", { className: "relative flex items-center justify-center mx-1", children: [showBadge && (jsx("span", { className: "absolute z-10 left-1/2 -translate-x-1/2 -top-3 sm:-top-4 translate-y-[-50%] px-3 py-0.5 text-[0.625rem] sm:text-xs rounded-md bg-yellow-100 text-yellow-800 font-semibold shadow-sm whitespace-nowrap", children: discountBadgeText })), jsx("button", { className: cn('text-sm md:text-base font-medium transition relative text-center z-10 px-2 sm:px-4 py-2 min-w-[100px] sm:min-w-[120px]', buttonClasses), type: "button", "data-billing-button": option.key, onClick: () => setUserSelectedBillingType(option.key), children: option.name })] }, option.key));
|
|
318
|
-
}) }) }), jsx("div", { className: "w-full", children: jsx("div", { className: "flex flex-wrap justify-center gap-5 md:gap-6 xl:gap-8 w-full max-w-6xl mx-auto", children: currentPlans.map((plan) => {
|
|
319
|
+
return (jsxs("div", { className: "relative flex items-center justify-center mx-1", children: [showBadge && (jsx("span", { className: "absolute z-10 left-1/2 -translate-x-1/2 -top-3 sm:-top-4 translate-y-[-50%] px-3 py-0.5 text-[0.625rem] sm:text-xs rounded-md bg-yellow-100 text-yellow-800 font-semibold shadow-sm whitespace-nowrap", children: discountBadgeText })), jsx("button", { className: cn('text-sm md:text-base font-medium transition relative text-center z-10 px-2 sm:px-4 py-2 min-w-[88px] min-[360px]:min-w-[100px] sm:min-w-[120px]', buttonClasses), type: "button", "data-billing-button": option.key, onClick: () => setUserSelectedBillingType(option.key), children: option.name })] }, option.key));
|
|
320
|
+
}) }) })) : null, jsx("div", { className: "w-full", children: jsx("div", { className: "flex flex-wrap justify-center gap-5 md:gap-6 xl:gap-8 w-full max-w-6xl mx-auto", children: currentPlans.map((plan) => {
|
|
319
321
|
var _a, _b;
|
|
320
322
|
const planKey = plan.key;
|
|
321
323
|
if (!PLAN_KEYS.includes(planKey)) {
|
|
@@ -81,6 +81,7 @@ export interface MoneyPriceProps {
|
|
|
81
81
|
enableClerkModal?: boolean;
|
|
82
82
|
sectionClassName?: string;
|
|
83
83
|
enabledBillingTypes?: string[];
|
|
84
|
+
mobileBillingSwitchBehavior?: 'sticky' | 'static';
|
|
84
85
|
enableSubscriptionUpgrade?: boolean;
|
|
85
86
|
initUserContext?: InitUserContext;
|
|
86
87
|
initialBillingType?: string;
|
|
@@ -92,6 +93,7 @@ export interface MoneyPriceInteractiveProps {
|
|
|
92
93
|
customerPortalApiEndpoint?: string;
|
|
93
94
|
enableClerkModal?: boolean;
|
|
94
95
|
enabledBillingTypes?: string[];
|
|
96
|
+
mobileBillingSwitchBehavior?: 'sticky' | 'static';
|
|
95
97
|
enableSubscriptionUpgrade?: boolean;
|
|
96
98
|
initialBillingType?: string;
|
|
97
99
|
disableAutoDetectBilling?: boolean;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { MoneyPriceProps } from './money-price-types';
|
|
2
|
-
export declare function MoneyPrice({ locale, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal, sectionClassName, enabledBillingTypes, enableSubscriptionUpgrade, initUserContext, initialBillingType, }: MoneyPriceProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
2
|
+
export declare function MoneyPrice({ locale, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal, sectionClassName, enabledBillingTypes, mobileBillingSwitchBehavior, enableSubscriptionUpgrade, initUserContext, initialBillingType, }: MoneyPriceProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -7,13 +7,13 @@ var moneyPriceInteractive = require('./money-price-interactive.js');
|
|
|
7
7
|
var moneyPriceData = require('./money-price-data.js');
|
|
8
8
|
|
|
9
9
|
function MoneyPrice(_a) {
|
|
10
|
-
return tslib.__awaiter(this, arguments, void 0, function* ({ locale, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, sectionClassName, enabledBillingTypes, enableSubscriptionUpgrade = true, initUserContext, initialBillingType, }) {
|
|
10
|
+
return tslib.__awaiter(this, arguments, void 0, function* ({ locale, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, sectionClassName, enabledBillingTypes, mobileBillingSwitchBehavior, enableSubscriptionUpgrade = true, initUserContext, initialBillingType, }) {
|
|
11
11
|
const data = yield moneyPriceData.buildMoneyPriceData({
|
|
12
12
|
locale,
|
|
13
13
|
currency: config.display.currency,
|
|
14
14
|
enabledBillingTypes,
|
|
15
15
|
});
|
|
16
|
-
return (jsxRuntime.jsxs("section", { id: "money-pricing", className: utils.cn("px-4 py-4 md:px-16 md:py-8 mx-auto max-w-7xl scroll-mt-10", sectionClassName), children: [jsxRuntime.jsx("h2", { className: "text-3xl md:text-4xl font-bold text-center mb-3", children: data.title }), jsxRuntime.jsx("p", { className: "text-center text-gray-600 dark:text-gray-400 mb-4 text-base md:text-lg mx-auto", children: data.subtitle }), jsxRuntime.jsx(moneyPriceInteractive.MoneyPriceInteractive, { data: data, config: config, checkoutApiEndpoint: checkoutApiEndpoint, customerPortalApiEndpoint: customerPortalApiEndpoint, enableClerkModal: enableClerkModal, enabledBillingTypes: enabledBillingTypes, enableSubscriptionUpgrade: enableSubscriptionUpgrade, initUserContext: initUserContext, initialBillingType: initialBillingType })] }));
|
|
16
|
+
return (jsxRuntime.jsxs("section", { id: "money-pricing", className: utils.cn("px-4 py-4 md:px-16 md:py-8 mx-auto max-w-7xl scroll-mt-10", sectionClassName), children: [jsxRuntime.jsx("h2", { className: "text-3xl md:text-4xl font-bold text-center mb-3", children: data.title }), jsxRuntime.jsx("p", { className: "text-center text-gray-600 dark:text-gray-400 mb-4 text-base md:text-lg mx-auto", children: data.subtitle }), jsxRuntime.jsx(moneyPriceInteractive.MoneyPriceInteractive, { data: data, config: config, checkoutApiEndpoint: checkoutApiEndpoint, customerPortalApiEndpoint: customerPortalApiEndpoint, enableClerkModal: enableClerkModal, enabledBillingTypes: enabledBillingTypes, mobileBillingSwitchBehavior: mobileBillingSwitchBehavior, enableSubscriptionUpgrade: enableSubscriptionUpgrade, initUserContext: initUserContext, initialBillingType: initialBillingType })] }));
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -5,13 +5,13 @@ import { MoneyPriceInteractive } from './money-price-interactive.mjs';
|
|
|
5
5
|
import { buildMoneyPriceData } from './money-price-data.mjs';
|
|
6
6
|
|
|
7
7
|
function MoneyPrice(_a) {
|
|
8
|
-
return __awaiter(this, arguments, void 0, function* ({ locale, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, sectionClassName, enabledBillingTypes, enableSubscriptionUpgrade = true, initUserContext, initialBillingType, }) {
|
|
8
|
+
return __awaiter(this, arguments, void 0, function* ({ locale, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, sectionClassName, enabledBillingTypes, mobileBillingSwitchBehavior, enableSubscriptionUpgrade = true, initUserContext, initialBillingType, }) {
|
|
9
9
|
const data = yield buildMoneyPriceData({
|
|
10
10
|
locale,
|
|
11
11
|
currency: config.display.currency,
|
|
12
12
|
enabledBillingTypes,
|
|
13
13
|
});
|
|
14
|
-
return (jsxs("section", { id: "money-pricing", className: cn("px-4 py-4 md:px-16 md:py-8 mx-auto max-w-7xl scroll-mt-10", sectionClassName), children: [jsx("h2", { className: "text-3xl md:text-4xl font-bold text-center mb-3", children: data.title }), jsx("p", { className: "text-center text-gray-600 dark:text-gray-400 mb-4 text-base md:text-lg mx-auto", children: data.subtitle }), jsx(MoneyPriceInteractive, { data: data, config: config, checkoutApiEndpoint: checkoutApiEndpoint, customerPortalApiEndpoint: customerPortalApiEndpoint, enableClerkModal: enableClerkModal, enabledBillingTypes: enabledBillingTypes, enableSubscriptionUpgrade: enableSubscriptionUpgrade, initUserContext: initUserContext, initialBillingType: initialBillingType })] }));
|
|
14
|
+
return (jsxs("section", { id: "money-pricing", className: cn("px-4 py-4 md:px-16 md:py-8 mx-auto max-w-7xl scroll-mt-10", sectionClassName), children: [jsx("h2", { className: "text-3xl md:text-4xl font-bold text-center mb-3", children: data.title }), jsx("p", { className: "text-center text-gray-600 dark:text-gray-400 mb-4 text-base md:text-lg mx-auto", children: data.subtitle }), jsx(MoneyPriceInteractive, { data: data, config: config, checkoutApiEndpoint: checkoutApiEndpoint, customerPortalApiEndpoint: customerPortalApiEndpoint, enableClerkModal: enableClerkModal, enabledBillingTypes: enabledBillingTypes, mobileBillingSwitchBehavior: mobileBillingSwitchBehavior, enableSubscriptionUpgrade: enableSubscriptionUpgrade, initUserContext: initUserContext, initialBillingType: initialBillingType })] }));
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { InitUserContext, MoneyPriceConfig, MoneyPriceData } from './money-price-types';
|
|
3
|
+
export interface OpenPricingModalOptions {
|
|
4
|
+
billingType?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PricingModalProps {
|
|
7
|
+
open: boolean;
|
|
8
|
+
onOpenChange: (open: boolean) => void;
|
|
9
|
+
data: MoneyPriceData;
|
|
10
|
+
config: MoneyPriceConfig;
|
|
11
|
+
billingType?: string;
|
|
12
|
+
checkoutApiEndpoint?: string;
|
|
13
|
+
customerPortalApiEndpoint?: string;
|
|
14
|
+
enableClerkModal?: boolean;
|
|
15
|
+
enabledBillingTypes?: string[];
|
|
16
|
+
mobileBillingSwitchBehavior?: 'sticky' | 'static';
|
|
17
|
+
enableSubscriptionUpgrade?: boolean;
|
|
18
|
+
initUserContext?: InitUserContext;
|
|
19
|
+
isInitLoading?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface PricingModalProviderProps extends Omit<PricingModalProps, 'open' | 'onOpenChange' | 'billingType'> {
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
pricingContextEndpoint?: string;
|
|
24
|
+
}
|
|
25
|
+
interface PricingModalContextValue {
|
|
26
|
+
openPricingModal: (options?: OpenPricingModalOptions) => void;
|
|
27
|
+
closePricingModal: () => void;
|
|
28
|
+
isPricingModalOpen: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare function PricingModal({ open, onOpenChange, data, config, billingType, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal, enabledBillingTypes, mobileBillingSwitchBehavior, enableSubscriptionUpgrade, initUserContext, isInitLoading, }: PricingModalProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare function PricingModalProvider({ children, pricingContextEndpoint, initUserContext: initUserContextProp, isInitLoading: isInitLoadingProp, ...modalProps }: PricingModalProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export declare function usePricingModal(): PricingModalContextValue;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var tslib = require('tslib');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var icons = require('@windrun-huaiin/base-ui/icons');
|
|
7
|
+
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
8
|
+
var ui = require('@windrun-huaiin/base-ui/ui');
|
|
9
|
+
var utils = require('@windrun-huaiin/lib/utils');
|
|
10
|
+
var React = require('react');
|
|
11
|
+
var dialogStyles = require('../alert-dialog/dialog-styles.js');
|
|
12
|
+
var moneyPriceInteractive = require('./money-price-interactive.js');
|
|
13
|
+
|
|
14
|
+
const emptyInitUserContext = {
|
|
15
|
+
fingerprintId: null,
|
|
16
|
+
xUser: null,
|
|
17
|
+
xCredit: null,
|
|
18
|
+
xSubscription: null,
|
|
19
|
+
isClerkAuthenticated: false,
|
|
20
|
+
};
|
|
21
|
+
const PricingModalContext = React.createContext(null);
|
|
22
|
+
function normalizeEnabledBillingTypes(data, enabledBillingTypes) {
|
|
23
|
+
const availableKeys = data.billingSwitch.options.map((option) => option.key);
|
|
24
|
+
const configuredKeys = (enabledBillingTypes === null || enabledBillingTypes === void 0 ? void 0 : enabledBillingTypes.length) ? enabledBillingTypes : availableKeys;
|
|
25
|
+
return Array.from(new Set(configuredKeys
|
|
26
|
+
.map((billingType) => billingType.trim())
|
|
27
|
+
.filter((billingType) => availableKeys.includes(billingType))));
|
|
28
|
+
}
|
|
29
|
+
function resolveBillingType({ data, enabledBillingTypes, requestedBillingType, }) {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
const enabledKeys = normalizeEnabledBillingTypes(data, enabledBillingTypes);
|
|
32
|
+
if (requestedBillingType && enabledKeys.includes(requestedBillingType)) {
|
|
33
|
+
return requestedBillingType;
|
|
34
|
+
}
|
|
35
|
+
if (enabledKeys.includes(data.billingSwitch.defaultKey)) {
|
|
36
|
+
return data.billingSwitch.defaultKey;
|
|
37
|
+
}
|
|
38
|
+
return (_a = enabledKeys[0]) !== null && _a !== void 0 ? _a : (_b = data.billingSwitch.options[0]) === null || _b === void 0 ? void 0 : _b.key;
|
|
39
|
+
}
|
|
40
|
+
function PricingModal({ open, onOpenChange, data, config, billingType, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, enabledBillingTypes, mobileBillingSwitchBehavior, enableSubscriptionUpgrade = true, initUserContext, isInitLoading = false, }) {
|
|
41
|
+
const resolvedBillingType = React.useMemo(() => resolveBillingType({
|
|
42
|
+
data,
|
|
43
|
+
enabledBillingTypes,
|
|
44
|
+
requestedBillingType: billingType,
|
|
45
|
+
}), [billingType, data, enabledBillingTypes]);
|
|
46
|
+
return (jsxRuntime.jsx(ui.AlertDialog, { open: open, onOpenChange: onOpenChange, children: open ? (jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn('mt-5 sm:mt-6 md:mt-10 lg:mt-15 w-[95vw] max-w-[1200px] overflow-hidden border border-slate-200 p-0 shadow-[0_32px_90px_rgba(15,23,42,0.25)] ring-1 ring-black/5 dark:border-white/12 dark:shadow-[0_40px_120px_rgba(0,0,0,0.6)] dark:ring-white/10', lib.themeMainBgColor), overlayClassName: dialogStyles.dialogThemedOverlayClass, children: [jsxRuntime.jsxs(ui.AlertDialogHeader, { className: "flex flex-row items-center justify-between border-b border-slate-200 px-6 pt-4 pb-1 dark:border-slate-800", children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: "flex flex-wrap items-baseline gap-3 text-slate-900 dark:text-white", children: [jsxRuntime.jsx("span", { className: "text-2xl font-semibold leading-tight", children: data.title }), data.subtitle ? (jsxRuntime.jsx("span", { className: "text-sm font-medium text-slate-500 dark:text-slate-300", children: data.subtitle })) : null] }) }), jsxRuntime.jsx("button", { type: "button", className: "rounded-full p-2 text-gray-400 transition hover:bg-gray-400 hover:text-gray-400 dark:text-white/80 dark:hover:bg-white/80 dark:hover:text-white/80", onClick: () => onOpenChange(false), children: jsxRuntime.jsx(icons.XIcon, { className: "h-6 w-6" }) })] }), jsxRuntime.jsx("div", { className: "max-h-[60vh] overflow-y-auto px-4 pt-2 pb-6 sm:max-h-[80vh]", children: jsxRuntime.jsx("div", { className: "mx-auto w-full", children: jsxRuntime.jsx(moneyPriceInteractive.MoneyPriceInteractive, { data: data, config: config, checkoutApiEndpoint: checkoutApiEndpoint, customerPortalApiEndpoint: customerPortalApiEndpoint, enableClerkModal: enableClerkModal, enabledBillingTypes: enabledBillingTypes, mobileBillingSwitchBehavior: mobileBillingSwitchBehavior, enableSubscriptionUpgrade: enableSubscriptionUpgrade, initialBillingType: resolvedBillingType, disableAutoDetectBilling: resolvedBillingType === 'onetime', initUserContext: initUserContext, isInitLoading: isInitLoading }, resolvedBillingType !== null && resolvedBillingType !== void 0 ? resolvedBillingType : 'default') }) })] })) : null }));
|
|
47
|
+
}
|
|
48
|
+
function PricingModalProvider(_a) {
|
|
49
|
+
var { children, pricingContextEndpoint, initUserContext: initUserContextProp, isInitLoading: isInitLoadingProp = false } = _a, modalProps = tslib.__rest(_a, ["children", "pricingContextEndpoint", "initUserContext", "isInitLoading"]);
|
|
50
|
+
const [open, setOpen] = React.useState(false);
|
|
51
|
+
const [requestedBillingType, setRequestedBillingType] = React.useState();
|
|
52
|
+
const [loadedInitUserContext, setLoadedInitUserContext] = React.useState(initUserContextProp !== null && initUserContextProp !== void 0 ? initUserContextProp : emptyInitUserContext);
|
|
53
|
+
const [isContextLoading, setIsContextLoading] = React.useState(false);
|
|
54
|
+
const loadedContextRef = React.useRef(!!initUserContextProp);
|
|
55
|
+
React.useEffect(() => {
|
|
56
|
+
if (initUserContextProp) {
|
|
57
|
+
loadedContextRef.current = true;
|
|
58
|
+
setLoadedInitUserContext(initUserContextProp);
|
|
59
|
+
}
|
|
60
|
+
}, [initUserContextProp]);
|
|
61
|
+
const loadPricingContext = React.useCallback(() => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
if (!pricingContextEndpoint || loadedContextRef.current) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
setIsContextLoading(true);
|
|
66
|
+
try {
|
|
67
|
+
const response = yield fetch(pricingContextEndpoint, {
|
|
68
|
+
credentials: 'same-origin',
|
|
69
|
+
});
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const nextContext = (yield response.json());
|
|
74
|
+
loadedContextRef.current = true;
|
|
75
|
+
setLoadedInitUserContext(nextContext);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.warn('[PricingModalProvider] Failed to load pricing context', error);
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
setIsContextLoading(false);
|
|
82
|
+
}
|
|
83
|
+
}), [pricingContextEndpoint]);
|
|
84
|
+
const openPricingModal = React.useCallback((options) => {
|
|
85
|
+
setRequestedBillingType(options === null || options === void 0 ? void 0 : options.billingType);
|
|
86
|
+
setOpen(true);
|
|
87
|
+
void loadPricingContext();
|
|
88
|
+
}, [loadPricingContext]);
|
|
89
|
+
const closePricingModal = React.useCallback(() => {
|
|
90
|
+
setOpen(false);
|
|
91
|
+
}, []);
|
|
92
|
+
const contextValue = React.useMemo(() => ({
|
|
93
|
+
openPricingModal,
|
|
94
|
+
closePricingModal,
|
|
95
|
+
isPricingModalOpen: open,
|
|
96
|
+
}), [closePricingModal, open, openPricingModal]);
|
|
97
|
+
return (jsxRuntime.jsxs(PricingModalContext.Provider, { value: contextValue, children: [children, jsxRuntime.jsx(PricingModal, Object.assign({}, modalProps, { open: open, onOpenChange: setOpen, billingType: requestedBillingType, initUserContext: initUserContextProp !== null && initUserContextProp !== void 0 ? initUserContextProp : loadedInitUserContext, isInitLoading: isInitLoadingProp || isContextLoading }))] }));
|
|
98
|
+
}
|
|
99
|
+
function usePricingModal() {
|
|
100
|
+
const context = React.useContext(PricingModalContext);
|
|
101
|
+
if (!context) {
|
|
102
|
+
throw new Error('usePricingModal must be used within PricingModalProvider.');
|
|
103
|
+
}
|
|
104
|
+
return context;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
exports.PricingModal = PricingModal;
|
|
108
|
+
exports.PricingModalProvider = PricingModalProvider;
|
|
109
|
+
exports.usePricingModal = usePricingModal;
|