@nozle-js/react 0.4.0 → 0.5.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/index.cjs +2773 -902
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +602 -123
- package/dist/index.d.ts +602 -123
- package/dist/index.js +2740 -898
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,157 +1,636 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
1
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { Stripe } from '@stripe/stripe-js';
|
|
5
|
-
|
|
6
|
-
interface EntitlementsResponse {
|
|
7
|
-
plan_slug: string;
|
|
8
|
-
subscription_status: string;
|
|
9
|
-
features: Record<string, {
|
|
10
|
-
enabled: boolean;
|
|
11
|
-
}>;
|
|
12
|
-
limits: Record<string, {
|
|
13
|
-
limit: number;
|
|
14
|
-
used: number;
|
|
15
|
-
source?: string;
|
|
16
|
-
}>;
|
|
17
|
-
}
|
|
18
|
-
interface BillingState {
|
|
19
|
-
entitlements: EntitlementsResponse | null;
|
|
20
|
-
credits: null;
|
|
21
|
-
usage: Record<string, {
|
|
22
|
-
used: number;
|
|
23
|
-
limit: number;
|
|
24
|
-
remaining: number;
|
|
25
|
-
}>;
|
|
26
|
-
connectionState: "connecting" | "connected" | "disconnected";
|
|
27
|
-
error: Error | null;
|
|
28
|
-
}
|
|
29
|
-
interface UseCanResult {
|
|
3
|
+
|
|
4
|
+
interface CanResult {
|
|
30
5
|
allowed: boolean;
|
|
31
|
-
|
|
32
|
-
|
|
6
|
+
remaining: number | null;
|
|
7
|
+
limit: number | null;
|
|
8
|
+
used: number;
|
|
9
|
+
error?: string | null;
|
|
33
10
|
}
|
|
34
|
-
interface
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
} | null;
|
|
40
|
-
isLoading: boolean;
|
|
41
|
-
error: Error | null;
|
|
11
|
+
interface NozleClient {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
baseUrl: string;
|
|
14
|
+
fetch(path: string, init?: RequestInit): Promise<Response>;
|
|
15
|
+
can(customerId: string, feature: string): Promise<CanResult>;
|
|
42
16
|
}
|
|
43
|
-
interface
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
isLoading: boolean;
|
|
49
|
-
error: Error | null;
|
|
17
|
+
interface BillingContextValue {
|
|
18
|
+
client: NozleClient | null;
|
|
19
|
+
workspaceId: string;
|
|
20
|
+
centrifugoUrl: string;
|
|
21
|
+
centrifugoToken: string | null;
|
|
50
22
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
23
|
+
declare const BillingContext: React.Context<BillingContextValue>;
|
|
24
|
+
interface BillingProviderProps {
|
|
25
|
+
apiKey: string;
|
|
26
|
+
baseUrl?: string;
|
|
27
|
+
workspaceId?: string;
|
|
28
|
+
centrifugoUrl?: string;
|
|
29
|
+
children: ReactNode;
|
|
56
30
|
}
|
|
31
|
+
declare function BillingProvider({ apiKey, baseUrl, workspaceId, centrifugoUrl, children, }: BillingProviderProps): React.ReactElement;
|
|
32
|
+
declare function useBillingContext(): BillingContextValue;
|
|
33
|
+
declare function useNozleClient(): NozleClient;
|
|
57
34
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
updateUsage(metric: string, used: number, limit: number, remaining: number): void;
|
|
72
|
-
fetchUsage(feature: string): Promise<void>;
|
|
73
|
-
fetchCheckoutSecret(planCode: string, successUrl?: string): Promise<CheckoutResult>;
|
|
74
|
-
fetchPlans(): Promise<Array<{
|
|
75
|
-
code: string;
|
|
76
|
-
name: string;
|
|
77
|
-
amount_cents: number;
|
|
78
|
-
amount_currency: string;
|
|
79
|
-
interval: string;
|
|
80
|
-
}>>;
|
|
81
|
-
handleEvent(event: {
|
|
82
|
-
type: string;
|
|
83
|
-
[key: string]: unknown;
|
|
84
|
-
}): void;
|
|
35
|
+
/**
|
|
36
|
+
* useCan hook — check whether a customer can use a feature.
|
|
37
|
+
* SDK-03: Calls client.can() for initial state, then subscribes to Centrifugo
|
|
38
|
+
* workspace:{id}:entitlements channel for live updates.
|
|
39
|
+
*
|
|
40
|
+
* CONTEXT.md hard requirement: NO setInterval polling — Centrifugo WebSocket only.
|
|
41
|
+
*/
|
|
42
|
+
interface CanState {
|
|
43
|
+
allowed: boolean;
|
|
44
|
+
remaining: number | null;
|
|
45
|
+
limit: number | null;
|
|
46
|
+
loading: boolean;
|
|
47
|
+
error: string | null;
|
|
85
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Check whether a customer is entitled to a feature.
|
|
51
|
+
* Subscribes to Centrifugo workspace:{workspaceId}:entitlements channel for live updates.
|
|
52
|
+
* No polling — WebSocket only per CONTEXT.md locked decision.
|
|
53
|
+
*
|
|
54
|
+
* @param customerId - Customer ID to check entitlement for
|
|
55
|
+
* @param featureKey - Feature key to check
|
|
56
|
+
* @returns CanState with allowed, remaining, limit, loading, error
|
|
57
|
+
*/
|
|
58
|
+
declare function useCan(customerId: string, featureKey: string): CanState;
|
|
86
59
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
60
|
+
/**
|
|
61
|
+
* useUsage hook — fetch usage data for a customer metric.
|
|
62
|
+
* Calls GET /api/v1/usage/:customerId/:metricKey via client's fetch wrapper.
|
|
63
|
+
*/
|
|
64
|
+
interface UsageState {
|
|
65
|
+
value: number | null;
|
|
66
|
+
loading: boolean;
|
|
67
|
+
error: string | null;
|
|
90
68
|
}
|
|
91
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Fetch usage for a customer metric.
|
|
71
|
+
*
|
|
72
|
+
* @param customerId - Customer ID to fetch usage for
|
|
73
|
+
* @param metricKey - Metric key to fetch
|
|
74
|
+
* @returns UsageState with value, loading, error
|
|
75
|
+
*/
|
|
76
|
+
declare function useUsage(customerId: string, metricKey: string): UsageState;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* useCredits hook — fetch credit balance for a customer.
|
|
80
|
+
* Calls GET /api/v1/credits/:customerId/balance via client's fetch wrapper.
|
|
81
|
+
*/
|
|
82
|
+
interface CreditsState {
|
|
83
|
+
balance: number | null;
|
|
84
|
+
loading: boolean;
|
|
85
|
+
error: string | null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Fetch credit balance for a customer.
|
|
89
|
+
*
|
|
90
|
+
* @param customerId - Customer ID to fetch credit balance for
|
|
91
|
+
* @returns CreditsState with balance, loading, error
|
|
92
|
+
*/
|
|
93
|
+
declare function useCredits(customerId: string): CreditsState;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* BillingPortalProvider — Context wrapper for embeddable SDK components.
|
|
97
|
+
* UI-01: Wraps children and exposes a React context with { customerId, apiKey }.
|
|
98
|
+
* Components inside can consume this via the useBillingPortal() hook.
|
|
99
|
+
*
|
|
100
|
+
* Internally renders BillingProvider so all billing hooks work inside.
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
interface BillingPortalContextValue {
|
|
104
|
+
customerId: string;
|
|
92
105
|
apiKey: string;
|
|
106
|
+
}
|
|
107
|
+
declare function useBillingPortal(): BillingPortalContextValue;
|
|
108
|
+
interface BillingPortalProviderProps {
|
|
93
109
|
customerId: string;
|
|
94
|
-
|
|
95
|
-
wsUrl?: string;
|
|
96
|
-
stripeKey?: string;
|
|
97
|
-
features?: string[];
|
|
110
|
+
apiKey: string;
|
|
98
111
|
children: ReactNode;
|
|
99
112
|
}
|
|
100
|
-
|
|
101
|
-
|
|
113
|
+
/**
|
|
114
|
+
* BillingPortalProvider wraps your embedded billing UI and provides
|
|
115
|
+
* { customerId, apiKey } context to all nested SDK components.
|
|
116
|
+
*
|
|
117
|
+
* Usage:
|
|
118
|
+
* ```tsx
|
|
119
|
+
* <BillingPortalProvider customerId="cus_xxx" apiKey="bsr_pk_xxx">
|
|
120
|
+
* <PricingTable plans={plans} />
|
|
121
|
+
* <FeatureGate feature="analytics" />
|
|
122
|
+
* </BillingPortalProvider>
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
declare function BillingPortalProvider({ customerId, apiKey, children, }: BillingPortalProviderProps): React.ReactElement;
|
|
102
126
|
|
|
103
|
-
|
|
127
|
+
/**
|
|
128
|
+
* PlanCard — Individual pricing plan card component.
|
|
129
|
+
* UI-01: Shows plan name, price, interval, features list, and CTA button.
|
|
130
|
+
* Uses CSS variable theming with --nozle-* namespace.
|
|
131
|
+
*/
|
|
104
132
|
|
|
105
|
-
|
|
133
|
+
interface Plan {
|
|
134
|
+
id: string;
|
|
135
|
+
name: string;
|
|
136
|
+
monthlyPrice: number;
|
|
137
|
+
annualPrice: number;
|
|
138
|
+
features: string[];
|
|
139
|
+
description?: string;
|
|
140
|
+
}
|
|
141
|
+
interface PlanCardProps extends Plan {
|
|
142
|
+
isAnnual: boolean;
|
|
143
|
+
isCurrent: boolean;
|
|
144
|
+
onSelect?: () => void;
|
|
145
|
+
children?: ReactNode;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* PlanCard renders a single pricing plan.
|
|
149
|
+
* Highlighted with aria-current="true" when isCurrent=true.
|
|
150
|
+
*/
|
|
151
|
+
declare function PlanCard({ id, name, monthlyPrice, annualPrice, features, description, isAnnual, isCurrent, onSelect, }: PlanCardProps): React.ReactElement;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* PricingTable — Renders plan cards with monthly/annual toggle.
|
|
155
|
+
* UI-01: Responsive grid, monthly/annual toggle, highlights currentPlanId.
|
|
156
|
+
* Uses CSS variable theming with --nozle-* namespace.
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
interface PricingTableProps {
|
|
160
|
+
plans: Plan[];
|
|
161
|
+
currentPlanId?: string;
|
|
162
|
+
onSelect?: (planId: string) => void;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* PricingTable renders plan cards in a responsive grid with monthly/annual toggle.
|
|
166
|
+
* The current plan is highlighted with aria-current="true" and border-primary class.
|
|
167
|
+
*
|
|
168
|
+
* Usage:
|
|
169
|
+
* ```tsx
|
|
170
|
+
* <PricingTable
|
|
171
|
+
* plans={plans}
|
|
172
|
+
* currentPlanId="pro"
|
|
173
|
+
* onSelect={(planId) => handleUpgrade(planId)}
|
|
174
|
+
* />
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
declare function PricingTable({ plans, currentPlanId, onSelect, }: PricingTableProps): React.ReactElement;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* PlanComparison — Side-by-side feature comparison table.
|
|
181
|
+
* UI-01: Renders shadcn-style table with plan names as headers and features as rows.
|
|
182
|
+
* Check/cross icons for boolean values. Uses CSS variable theming.
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
interface ComparisonFeature {
|
|
186
|
+
key: string;
|
|
187
|
+
label: string;
|
|
188
|
+
values: Record<string, string | boolean>;
|
|
189
|
+
}
|
|
190
|
+
interface PlanComparisonProps {
|
|
191
|
+
plans: Plan[];
|
|
192
|
+
features: ComparisonFeature[];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* PlanComparison renders a side-by-side feature comparison table.
|
|
196
|
+
*
|
|
197
|
+
* Usage:
|
|
198
|
+
* ```tsx
|
|
199
|
+
* <PlanComparison
|
|
200
|
+
* plans={plans}
|
|
201
|
+
* features={[
|
|
202
|
+
* { key: 'api_calls', label: 'API Calls', values: { starter: '10K', pro: '100K' } },
|
|
203
|
+
* { key: 'analytics', label: 'Analytics', values: { starter: false, pro: true } },
|
|
204
|
+
* ]}
|
|
205
|
+
* />
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
declare function PlanComparison({ plans, features, }: PlanComparisonProps): React.ReactElement;
|
|
106
209
|
|
|
107
|
-
|
|
210
|
+
/**
|
|
211
|
+
* CheckoutButton — Initiates checkout for a plan.
|
|
212
|
+
* UI-02: Calls POST /api/v1/checkout, detects processor type from the response,
|
|
213
|
+
* and branches to the appropriate payment flow:
|
|
214
|
+
* - Stripe hosted checkout: redirect to url
|
|
215
|
+
* - Stripe embedded Elements: emit clientSecret via onStripeClientSecret callback
|
|
216
|
+
* - Razorpay: inject Razorpay.js and open the checkout modal
|
|
217
|
+
* - Legacy (no type): redirect to url for backwards compatibility
|
|
218
|
+
* Uses CSS variable theming with --nozle-* namespace.
|
|
219
|
+
*/
|
|
108
220
|
|
|
221
|
+
interface CheckoutButtonProps {
|
|
222
|
+
planId: string;
|
|
223
|
+
label?: string;
|
|
224
|
+
apiBaseUrl?: string;
|
|
225
|
+
className?: string;
|
|
226
|
+
style?: React.CSSProperties;
|
|
227
|
+
onError?: (error: Error) => void;
|
|
228
|
+
/** Required for Razorpay checkout path — the Razorpay publishable key (key_id). */
|
|
229
|
+
razorpayKeyId?: string;
|
|
230
|
+
/** Called with the Stripe Payment Intent / Checkout Session client secret
|
|
231
|
+
* when the BFF returns type:'stripe' without a hosted url.
|
|
232
|
+
* The host app is responsible for mounting Stripe Elements. */
|
|
233
|
+
onStripeClientSecret?: (clientSecret: string) => void;
|
|
234
|
+
/** Called with the Razorpay payment ID after a successful Razorpay payment. */
|
|
235
|
+
onSuccess?: (paymentId: string) => void;
|
|
236
|
+
}
|
|
237
|
+
interface RazorpayOptions {
|
|
238
|
+
key: string;
|
|
239
|
+
order_id: string;
|
|
240
|
+
name?: string;
|
|
241
|
+
description?: string;
|
|
242
|
+
handler: (response: {
|
|
243
|
+
razorpay_payment_id: string;
|
|
244
|
+
}) => void;
|
|
245
|
+
modal?: {
|
|
246
|
+
ondismiss?: () => void;
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
declare global {
|
|
250
|
+
interface Window {
|
|
251
|
+
Razorpay: new (opts: RazorpayOptions) => {
|
|
252
|
+
open(): void;
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* CheckoutButton initiates a checkout session and routes to the appropriate
|
|
258
|
+
* payment processor path.
|
|
259
|
+
*
|
|
260
|
+
* Must be used inside a BillingPortalProvider.
|
|
261
|
+
*/
|
|
262
|
+
declare function CheckoutButton({ planId, label, apiBaseUrl, className, style, onError, razorpayKeyId, onStripeClientSecret, onSuccess, }: CheckoutButtonProps): React.ReactElement;
|
|
263
|
+
|
|
264
|
+
interface CheckoutProps {
|
|
265
|
+
/** Stripe PaymentIntent client secret */
|
|
266
|
+
clientSecret: string;
|
|
267
|
+
/** Stripe publishable key */
|
|
268
|
+
publishableKey: string;
|
|
269
|
+
/** Optional Stripe Connect account ID */
|
|
270
|
+
stripeAccount?: string;
|
|
271
|
+
/** Custom label for the submit button (default: "Pay now") */
|
|
272
|
+
submitLabel?: string;
|
|
273
|
+
/** Called with the paymentIntentId when payment succeeds without redirect */
|
|
274
|
+
onSuccess?: (paymentIntentId: string) => void;
|
|
275
|
+
/** Called with the error when payment fails */
|
|
276
|
+
onError?: (error: Error) => void;
|
|
277
|
+
/** Called when the PaymentElement becomes interactive */
|
|
278
|
+
onReady?: () => void;
|
|
279
|
+
/** Additional CSS class for the outer wrapper */
|
|
280
|
+
className?: string;
|
|
281
|
+
/** Inline styles for the outer wrapper */
|
|
282
|
+
style?: React.CSSProperties;
|
|
283
|
+
}
|
|
109
284
|
interface UseCheckoutResult {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
285
|
+
/** Trigger payment confirmation programmatically */
|
|
286
|
+
confirmPayment: () => Promise<void>;
|
|
287
|
+
/** True while a payment confirmation is in-flight */
|
|
288
|
+
isProcessing: boolean;
|
|
289
|
+
/** Last payment error, or null if no error */
|
|
114
290
|
error: Error | null;
|
|
115
291
|
}
|
|
116
292
|
declare function useCheckout(): UseCheckoutResult;
|
|
293
|
+
declare function Checkout({ clientSecret, publishableKey, stripeAccount, submitLabel, onSuccess, onError, onReady, className, style, }: CheckoutProps): react_jsx_runtime.JSX.Element;
|
|
117
294
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
295
|
+
/**
|
|
296
|
+
* UpgradeButton — Opens UpgradeModal on click.
|
|
297
|
+
* UI-02: Triggers plan upgrade flow with proration preview.
|
|
298
|
+
* Uses CSS variable theming with --nozle-* namespace.
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
interface UpgradeButtonProps {
|
|
302
|
+
targetPlanId: string;
|
|
303
|
+
label?: string;
|
|
304
|
+
apiBaseUrl?: string;
|
|
305
|
+
className?: string;
|
|
306
|
+
style?: React.CSSProperties;
|
|
307
|
+
onUpgraded?: () => void;
|
|
122
308
|
}
|
|
123
|
-
|
|
309
|
+
/**
|
|
310
|
+
* UpgradeButton opens an UpgradeModal with live proration preview.
|
|
311
|
+
* Must be used inside a BillingPortalProvider.
|
|
312
|
+
*/
|
|
313
|
+
declare function UpgradeButton({ targetPlanId, label, apiBaseUrl, className, style, onUpgraded, }: UpgradeButtonProps): React.ReactElement;
|
|
124
314
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
315
|
+
/**
|
|
316
|
+
* CreditTopUpButton — Opens a dialog for purchasing credits.
|
|
317
|
+
* UI-02: Allows customers to top up their credit balance.
|
|
318
|
+
* Uses CSS variable theming with --nozle-* namespace.
|
|
319
|
+
*/
|
|
320
|
+
|
|
321
|
+
interface CreditTopUpButtonProps {
|
|
322
|
+
label?: string;
|
|
323
|
+
apiBaseUrl?: string;
|
|
324
|
+
className?: string;
|
|
325
|
+
style?: React.CSSProperties;
|
|
326
|
+
onSuccess?: (amount: number) => void;
|
|
327
|
+
onError?: (error: Error) => void;
|
|
131
328
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
329
|
+
/**
|
|
330
|
+
* CreditTopUpButton opens a dialog to purchase credits.
|
|
331
|
+
* Must be used inside a BillingPortalProvider.
|
|
332
|
+
*/
|
|
333
|
+
declare function CreditTopUpButton({ label, apiBaseUrl, className, style, onSuccess, onError, }: CreditTopUpButtonProps): React.ReactElement;
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* UpgradeModal — Shows live proration preview before confirming plan upgrade.
|
|
337
|
+
* UI-02: Fetches proration preview from POST /api/v1/subscriptions/preview.
|
|
338
|
+
* Shows credit, debit, net, and next billing date before confirming.
|
|
339
|
+
* Uses CSS variable theming with --nozle-* namespace.
|
|
340
|
+
*/
|
|
136
341
|
|
|
137
|
-
interface
|
|
138
|
-
|
|
139
|
-
|
|
342
|
+
interface ProrationPreview {
|
|
343
|
+
credit: number;
|
|
344
|
+
debit: number;
|
|
345
|
+
net: number;
|
|
346
|
+
nextBillingDate: string;
|
|
140
347
|
}
|
|
141
|
-
interface
|
|
142
|
-
|
|
348
|
+
interface UpgradeModalProps {
|
|
349
|
+
isOpen: boolean;
|
|
350
|
+
targetPlanId: string;
|
|
351
|
+
customerId: string;
|
|
352
|
+
apiBaseUrl?: string;
|
|
353
|
+
apiKey?: string;
|
|
354
|
+
onConfirm?: () => void;
|
|
355
|
+
onCancel?: () => void;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* UpgradeModal shows proration preview from POST /api/v1/subscriptions/preview
|
|
359
|
+
* before the customer confirms a plan upgrade.
|
|
360
|
+
*/
|
|
361
|
+
declare function UpgradeModal({ isOpen, targetPlanId, customerId, apiBaseUrl, apiKey, onConfirm, onCancel, }: UpgradeModalProps): React.ReactElement | null;
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* FeatureGate — Renders children if customer has access to a feature.
|
|
365
|
+
* UI-03: Uses useCan hook; renders fallback when allowed=false.
|
|
366
|
+
* Renders null while loading to avoid layout shift.
|
|
367
|
+
*/
|
|
368
|
+
|
|
369
|
+
interface FeatureGateProps {
|
|
370
|
+
/** Customer ID to check entitlement for */
|
|
371
|
+
customerId: string;
|
|
372
|
+
/** Feature key to check */
|
|
373
|
+
feature: string;
|
|
374
|
+
/** Rendered when customer does not have access. Defaults to null. */
|
|
375
|
+
fallback?: ReactNode;
|
|
376
|
+
/** Content to show when customer has access */
|
|
377
|
+
children: ReactNode;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* FeatureGate renders children only when the customer is entitled to the feature.
|
|
381
|
+
* Returns null while the entitlement check is loading.
|
|
382
|
+
*
|
|
383
|
+
* Usage:
|
|
384
|
+
* ```tsx
|
|
385
|
+
* <FeatureGate customerId="cus_123" feature="analytics" fallback={<UpgradePrompt />}>
|
|
386
|
+
* <AnalyticsDashboard />
|
|
387
|
+
* </FeatureGate>
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
declare function FeatureGate({ customerId, feature, fallback, children, }: FeatureGateProps): React.ReactElement | null;
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* UsageGate — Renders children if usage is below limit.
|
|
394
|
+
* UI-03: Renders fallback when usage >= limit.
|
|
395
|
+
* Pure render logic — caller provides usage and limit values.
|
|
396
|
+
*/
|
|
397
|
+
|
|
398
|
+
interface UsageGateProps {
|
|
399
|
+
/** Current usage value */
|
|
400
|
+
usage: number;
|
|
401
|
+
/** Usage limit */
|
|
402
|
+
limit: number;
|
|
403
|
+
/** Rendered when usage is at or above limit. Defaults to null. */
|
|
404
|
+
fallback?: ReactNode;
|
|
405
|
+
/** Content to show when usage is below limit */
|
|
406
|
+
children: ReactNode;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* UsageGate renders children only when current usage is below the limit.
|
|
410
|
+
* When usage >= limit, renders fallback.
|
|
411
|
+
*
|
|
412
|
+
* Usage:
|
|
413
|
+
* ```tsx
|
|
414
|
+
* <UsageGate usage={currentUsage} limit={plan.apiCallLimit} fallback={<UpgradePrompt />}>
|
|
415
|
+
* <ApiCallButton />
|
|
416
|
+
* </UsageGate>
|
|
417
|
+
* ```
|
|
418
|
+
*/
|
|
419
|
+
declare function UsageGate({ usage, limit, fallback, children, }: UsageGateProps): React.ReactElement;
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* PlanGate — Renders children if customer's plan is in the allowed list.
|
|
423
|
+
* UI-03: Pure render logic — caller provides currentPlan and allowedPlans.
|
|
424
|
+
* Renders fallback when customer is not on an allowed plan tier.
|
|
425
|
+
*/
|
|
426
|
+
|
|
427
|
+
interface PlanGateProps {
|
|
428
|
+
/** The customer's current plan identifier */
|
|
429
|
+
currentPlan: string;
|
|
430
|
+
/** List of plan identifiers that are allowed to see the children */
|
|
431
|
+
allowedPlans: string[];
|
|
432
|
+
/** Rendered when customer is not on an allowed plan. Defaults to null. */
|
|
433
|
+
fallback?: ReactNode;
|
|
434
|
+
/** Content to show when customer is on an allowed plan */
|
|
435
|
+
children: ReactNode;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* PlanGate renders children only when the customer's currentPlan is in allowedPlans.
|
|
439
|
+
* When not on an allowed plan, renders fallback.
|
|
440
|
+
*
|
|
441
|
+
* Usage:
|
|
442
|
+
* ```tsx
|
|
443
|
+
* <PlanGate
|
|
444
|
+
* currentPlan={customer.plan}
|
|
445
|
+
* allowedPlans={['pro', 'enterprise']}
|
|
446
|
+
* fallback={<UpgradePrompt planName="Pro" />}
|
|
447
|
+
* >
|
|
448
|
+
* <ProFeature />
|
|
449
|
+
* </PlanGate>
|
|
450
|
+
* ```
|
|
451
|
+
*/
|
|
452
|
+
declare function PlanGate({ currentPlan, allowedPlans, fallback, children, }: PlanGateProps): React.ReactElement;
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* UpgradePrompt — Reusable upgrade message component.
|
|
456
|
+
* UI-03: Shows plan name + upgrade button; used as default fallback for LockedOverlay.
|
|
457
|
+
* Uses CSS variable theming with --nozle-* namespace.
|
|
458
|
+
*/
|
|
459
|
+
|
|
460
|
+
interface UpgradePromptProps {
|
|
461
|
+
text?: string;
|
|
462
|
+
planName?: string;
|
|
463
|
+
onUpgrade?: () => void;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* UpgradePrompt renders an upgrade call-to-action with a message and button.
|
|
467
|
+
* Used as default fallback in LockedOverlay and gate components.
|
|
468
|
+
*/
|
|
469
|
+
declare function UpgradePrompt({ text, planName, onUpgrade, }: UpgradePromptProps): React.ReactElement;
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* LockedOverlay — Wraps children with a blur filter + upgrade CTA overlay when locked.
|
|
473
|
+
* UI-03: Applies CSS blur(4px) to children with an upgrade prompt overlay.
|
|
474
|
+
* Uses CSS variable theming with --nozle-* namespace.
|
|
475
|
+
*/
|
|
476
|
+
|
|
477
|
+
interface LockedOverlayProps {
|
|
478
|
+
/** Whether to apply the locked blur + overlay state */
|
|
479
|
+
locked: boolean;
|
|
480
|
+
/** Text to show in the upgrade prompt */
|
|
481
|
+
upgradeText?: string;
|
|
482
|
+
/** Plan name to show in the upgrade prompt */
|
|
483
|
+
upgradePlanName?: string;
|
|
484
|
+
/** Called when the upgrade button is clicked */
|
|
485
|
+
onUpgrade?: () => void;
|
|
486
|
+
/** Content to blur when locked */
|
|
487
|
+
children: ReactNode;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* LockedOverlay wraps children in a relative container.
|
|
491
|
+
* When locked=true:
|
|
492
|
+
* - Children receive CSS blur(4px) and pointer-events: none
|
|
493
|
+
* - An upgrade CTA overlay is positioned on top
|
|
494
|
+
*
|
|
495
|
+
* When locked=false, children render normally without any overlay.
|
|
496
|
+
*
|
|
497
|
+
* Usage:
|
|
498
|
+
* ```tsx
|
|
499
|
+
* <LockedOverlay locked={!canAccessFeature} upgradeText="Upgrade to Pro" onUpgrade={openUpgradeModal}>
|
|
500
|
+
* <FeatureContent />
|
|
501
|
+
* </LockedOverlay>
|
|
502
|
+
* ```
|
|
503
|
+
*/
|
|
504
|
+
declare function LockedOverlay({ locked, upgradeText, upgradePlanName, onUpgrade, children, }: LockedOverlayProps): React.ReactElement;
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* UsageMeter — embeddable usage progress bar with automatic color thresholds.
|
|
508
|
+
* Uses --nozle-* CSS variables for theming (customer-facing portal layer).
|
|
509
|
+
*
|
|
510
|
+
* Color thresholds:
|
|
511
|
+
* < 80% → primary (normal)
|
|
512
|
+
* 80-94% → warning (amber)
|
|
513
|
+
* ≥ 95% → destructive (red)
|
|
514
|
+
*/
|
|
515
|
+
declare function getUsageMeterColor(percentage: number): string;
|
|
516
|
+
interface UsageMeterProps {
|
|
517
|
+
used: number;
|
|
518
|
+
limit: number;
|
|
519
|
+
label?: string;
|
|
520
|
+
showText?: boolean;
|
|
521
|
+
}
|
|
522
|
+
declare function UsageMeter({ used, limit, label, showText, }: UsageMeterProps): react_jsx_runtime.JSX.Element;
|
|
523
|
+
|
|
524
|
+
interface UsageDashboardFeature {
|
|
525
|
+
key: string;
|
|
526
|
+
label: string;
|
|
527
|
+
used: number;
|
|
528
|
+
limit: number;
|
|
529
|
+
}
|
|
530
|
+
interface UsageDashboardProps {
|
|
531
|
+
features?: UsageDashboardFeature[];
|
|
532
|
+
loading?: boolean;
|
|
143
533
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
534
|
+
declare function UsageDashboard({ features, loading, }: UsageDashboardProps): react_jsx_runtime.JSX.Element;
|
|
535
|
+
|
|
536
|
+
interface UsageAlertFeature {
|
|
537
|
+
key: string;
|
|
538
|
+
label: string;
|
|
539
|
+
percentage: number;
|
|
540
|
+
}
|
|
541
|
+
interface UsageAlertProps {
|
|
542
|
+
features: UsageAlertFeature[];
|
|
543
|
+
threshold?: number;
|
|
544
|
+
upgradeHref?: string;
|
|
545
|
+
}
|
|
546
|
+
declare function UsageAlert({ features, threshold, upgradeHref, }: UsageAlertProps): react_jsx_runtime.JSX.Element | null;
|
|
547
|
+
|
|
548
|
+
interface CreditBalanceProps {
|
|
549
|
+
customerId: string;
|
|
550
|
+
currency?: string;
|
|
551
|
+
}
|
|
552
|
+
declare function CreditBalance({ customerId, currency, }: CreditBalanceProps): react_jsx_runtime.JSX.Element;
|
|
553
|
+
|
|
554
|
+
interface CreditTransaction {
|
|
555
|
+
id: string;
|
|
556
|
+
amount: number;
|
|
557
|
+
type: string;
|
|
558
|
+
description: string;
|
|
559
|
+
createdAt: string;
|
|
560
|
+
}
|
|
561
|
+
interface CreditHistoryProps {
|
|
562
|
+
customerId: string;
|
|
563
|
+
viewAllHref?: string;
|
|
564
|
+
}
|
|
565
|
+
declare function CreditHistory({ customerId, viewAllHref, }: CreditHistoryProps): react_jsx_runtime.JSX.Element;
|
|
566
|
+
|
|
567
|
+
interface PlanBadgeProps {
|
|
568
|
+
plan: string;
|
|
569
|
+
tier?: "free" | "starter" | "pro" | "enterprise";
|
|
570
|
+
}
|
|
571
|
+
declare function PlanBadge({ plan, tier }: PlanBadgeProps): react_jsx_runtime.JSX.Element;
|
|
572
|
+
|
|
573
|
+
interface BillingPortalProps {
|
|
574
|
+
customerId: string;
|
|
575
|
+
usageFeatures?: UsageDashboardFeature[];
|
|
576
|
+
usageLoading?: boolean;
|
|
577
|
+
onChangePlan?: () => void;
|
|
578
|
+
subscriptionId?: string;
|
|
579
|
+
onCancelled?: () => void;
|
|
149
580
|
}
|
|
581
|
+
declare function BillingPortal({ customerId, usageFeatures, usageLoading, onChangePlan, }: BillingPortalProps): react_jsx_runtime.JSX.Element;
|
|
150
582
|
|
|
151
|
-
|
|
583
|
+
interface CurrentPlanData {
|
|
584
|
+
id: string;
|
|
585
|
+
planName: string;
|
|
586
|
+
interval: string;
|
|
587
|
+
status: string;
|
|
588
|
+
nextBillingDate?: string;
|
|
589
|
+
tier?: "free" | "starter" | "pro" | "enterprise";
|
|
590
|
+
}
|
|
591
|
+
interface CurrentPlanProps {
|
|
592
|
+
customerId: string;
|
|
593
|
+
onChangePlan?: () => void;
|
|
594
|
+
changePlanHref?: string;
|
|
595
|
+
}
|
|
596
|
+
declare function CurrentPlan({ customerId, onChangePlan, changePlanHref, }: CurrentPlanProps): react_jsx_runtime.JSX.Element;
|
|
152
597
|
|
|
153
|
-
|
|
598
|
+
interface Invoice {
|
|
599
|
+
id: string;
|
|
600
|
+
number: string;
|
|
601
|
+
date: string;
|
|
602
|
+
amount: number;
|
|
603
|
+
currency: string;
|
|
604
|
+
status: "draft" | "open" | "paid" | "void" | "uncollectible";
|
|
605
|
+
pdf_url?: string;
|
|
606
|
+
}
|
|
607
|
+
interface InvoiceListProps {
|
|
608
|
+
customerId: string;
|
|
609
|
+
}
|
|
610
|
+
declare function InvoiceList({ customerId }: InvoiceListProps): react_jsx_runtime.JSX.Element;
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* PaymentMethodDisplay — shows saved payment method details.
|
|
614
|
+
* Displays last4, brand, expiry. "Update Payment Method" button opens checkout.
|
|
615
|
+
*/
|
|
616
|
+
interface PaymentMethod {
|
|
617
|
+
last4: string;
|
|
618
|
+
brand: string;
|
|
619
|
+
expMonth: number;
|
|
620
|
+
expYear: number;
|
|
621
|
+
}
|
|
622
|
+
interface PaymentMethodDisplayProps {
|
|
623
|
+
paymentMethod?: PaymentMethod;
|
|
624
|
+
onUpdatePaymentMethod?: () => void;
|
|
625
|
+
updateHref?: string;
|
|
626
|
+
}
|
|
627
|
+
declare function PaymentMethodDisplay({ paymentMethod, onUpdatePaymentMethod, updateHref, }: PaymentMethodDisplayProps): react_jsx_runtime.JSX.Element;
|
|
154
628
|
|
|
155
|
-
declare
|
|
629
|
+
declare const CANCEL_REASONS: readonly ["Too expensive", "Missing features", "Switching to competitor", "Not using it enough", "Other"];
|
|
630
|
+
interface CancelSubscriptionButtonProps {
|
|
631
|
+
subscriptionId: string;
|
|
632
|
+
onCancelled?: () => void;
|
|
633
|
+
}
|
|
634
|
+
declare function CancelSubscriptionButton({ subscriptionId, onCancelled, }: CancelSubscriptionButtonProps): react_jsx_runtime.JSX.Element;
|
|
156
635
|
|
|
157
|
-
export { BillingProvider, type
|
|
636
|
+
export { BillingContext, type BillingContextValue, BillingPortal, type BillingPortalContextValue, type BillingPortalProps, BillingPortalProvider, type BillingPortalProviderProps, BillingProvider, type BillingProviderProps, CANCEL_REASONS, type CanState, CancelSubscriptionButton, type CancelSubscriptionButtonProps, Checkout, CheckoutButton, type CheckoutButtonProps, type CheckoutProps, type ComparisonFeature, CreditBalance, type CreditBalanceProps, CreditHistory, type CreditHistoryProps, CreditTopUpButton, type CreditTopUpButtonProps, type CreditTransaction, type CreditsState, CurrentPlan, type CurrentPlanData, type CurrentPlanProps, FeatureGate, type FeatureGateProps, type Invoice, InvoiceList, type InvoiceListProps, LockedOverlay, type LockedOverlayProps, type NozleClient, type PaymentMethod, PaymentMethodDisplay, type PaymentMethodDisplayProps, type Plan, PlanBadge, type PlanBadgeProps, PlanCard, type PlanCardProps, PlanComparison, type PlanComparisonProps, PlanGate, type PlanGateProps, PricingTable, type PricingTableProps, type ProrationPreview, UpgradeButton, type UpgradeButtonProps, UpgradeModal, type UpgradeModalProps, UpgradePrompt, type UpgradePromptProps, UsageAlert, type UsageAlertFeature, type UsageAlertProps, UsageDashboard, type UsageDashboardFeature, type UsageDashboardProps, UsageGate, type UsageGateProps, UsageMeter, type UsageMeterProps, type UsageState, type UseCheckoutResult, getUsageMeterColor, useBillingContext, useBillingPortal, useCan, useCheckout, useCredits, useNozleClient, useUsage };
|