@growflowstudio/growflowbilling-admin-core 2.0.0 → 2.1.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.d.mts +104 -1
- package/dist/index.d.ts +104 -1
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +57 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,15 @@ import * as react from 'react';
|
|
|
2
2
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
3
3
|
|
|
4
4
|
type AdminPlanPricingModel = 'flat' | 'tiered' | 'per_unit' | 'usage_based';
|
|
5
|
+
/**
|
|
6
|
+
* Per-feature UI visibility for a plan.
|
|
7
|
+
*
|
|
8
|
+
* - ``visible``: feature is listed in the public plan card and accessible.
|
|
9
|
+
* - ``teaser``: feature is listed but shown as locked with an upgrade CTA.
|
|
10
|
+
* - ``hidden``: feature exists on the plan but is not shown in the UI
|
|
11
|
+
* (used for sunset / admin-only flags).
|
|
12
|
+
*/
|
|
13
|
+
type Visibility = 'visible' | 'teaser' | 'hidden';
|
|
5
14
|
interface AdminPlan {
|
|
6
15
|
id: string;
|
|
7
16
|
client_id: string;
|
|
@@ -16,11 +25,14 @@ interface AdminPlan {
|
|
|
16
25
|
stripe_price_id_yearly: string | null;
|
|
17
26
|
limits: Record<string, number> | null;
|
|
18
27
|
features: string[] | null;
|
|
28
|
+
/** Per-feature UI visibility override. Empty/null means "all visible". */
|
|
29
|
+
ui_visibility?: Record<string, Visibility> | null;
|
|
19
30
|
trial_days: number;
|
|
20
31
|
is_active: boolean;
|
|
21
32
|
contact_sales: boolean;
|
|
22
33
|
color: string;
|
|
23
34
|
sort_order: number;
|
|
35
|
+
environment?: 'test' | 'live';
|
|
24
36
|
created_at: string;
|
|
25
37
|
updated_at: string;
|
|
26
38
|
}
|
|
@@ -34,6 +46,7 @@ interface AdminPlanCreate {
|
|
|
34
46
|
currency?: string;
|
|
35
47
|
limits?: Record<string, number>;
|
|
36
48
|
features?: string[];
|
|
49
|
+
ui_visibility?: Record<string, Visibility>;
|
|
37
50
|
trial_days?: number;
|
|
38
51
|
is_active?: boolean;
|
|
39
52
|
contact_sales?: boolean;
|
|
@@ -48,6 +61,7 @@ interface AdminPlanUpdate {
|
|
|
48
61
|
price_yearly?: number;
|
|
49
62
|
limits?: Record<string, number>;
|
|
50
63
|
features?: string[];
|
|
64
|
+
ui_visibility?: Record<string, Visibility>;
|
|
51
65
|
trial_days?: number;
|
|
52
66
|
is_active?: boolean;
|
|
53
67
|
contact_sales?: boolean;
|
|
@@ -74,6 +88,7 @@ interface AdminSubscription {
|
|
|
74
88
|
trial_end: string | null;
|
|
75
89
|
canceled_at: string | null;
|
|
76
90
|
cancel_at: string | null;
|
|
91
|
+
environment?: 'test' | 'live';
|
|
77
92
|
created_at: string;
|
|
78
93
|
updated_at: string;
|
|
79
94
|
}
|
|
@@ -145,6 +160,7 @@ interface AdminInvoice {
|
|
|
145
160
|
subscription_id: string | null;
|
|
146
161
|
invoice_pdf: string | null;
|
|
147
162
|
hosted_invoice_url: string | null;
|
|
163
|
+
environment?: 'test' | 'live';
|
|
148
164
|
lines: AdminInvoiceLineItem[];
|
|
149
165
|
}
|
|
150
166
|
interface AdminInvoiceLineItem {
|
|
@@ -173,6 +189,7 @@ interface AdminProduct {
|
|
|
173
189
|
category: string | null;
|
|
174
190
|
is_active: boolean;
|
|
175
191
|
extra_data: ProductExtraData | null;
|
|
192
|
+
environment?: 'test' | 'live';
|
|
176
193
|
created_at: string | null;
|
|
177
194
|
updated_at: string | null;
|
|
178
195
|
}
|
|
@@ -241,6 +258,66 @@ interface AdminFeatureFilters {
|
|
|
241
258
|
category?: string;
|
|
242
259
|
}
|
|
243
260
|
|
|
261
|
+
interface ConnectAccount {
|
|
262
|
+
id: string;
|
|
263
|
+
email: string;
|
|
264
|
+
country: string;
|
|
265
|
+
business_type: string;
|
|
266
|
+
charges_enabled: boolean;
|
|
267
|
+
payouts_enabled: boolean;
|
|
268
|
+
details_submitted: boolean;
|
|
269
|
+
created_at: string;
|
|
270
|
+
metadata: Record<string, string>;
|
|
271
|
+
}
|
|
272
|
+
interface ConnectAccountLink {
|
|
273
|
+
url: string;
|
|
274
|
+
expires_at: string;
|
|
275
|
+
}
|
|
276
|
+
interface ConnectLoginLink {
|
|
277
|
+
url: string;
|
|
278
|
+
created: string;
|
|
279
|
+
}
|
|
280
|
+
interface ConnectTransfer {
|
|
281
|
+
id: string;
|
|
282
|
+
amount: number;
|
|
283
|
+
currency: string;
|
|
284
|
+
destination: string;
|
|
285
|
+
description?: string;
|
|
286
|
+
created_at: string;
|
|
287
|
+
}
|
|
288
|
+
interface ConnectBalanceAmount {
|
|
289
|
+
amount: number;
|
|
290
|
+
currency: string;
|
|
291
|
+
}
|
|
292
|
+
interface ConnectBalance {
|
|
293
|
+
available: ConnectBalanceAmount[];
|
|
294
|
+
pending: ConnectBalanceAmount[];
|
|
295
|
+
}
|
|
296
|
+
interface ConnectAccountsPage {
|
|
297
|
+
data: ConnectAccount[];
|
|
298
|
+
has_more: boolean;
|
|
299
|
+
}
|
|
300
|
+
interface ConnectTransfersPage {
|
|
301
|
+
data: ConnectTransfer[];
|
|
302
|
+
has_more: boolean;
|
|
303
|
+
}
|
|
304
|
+
interface CreateConnectAccountInput {
|
|
305
|
+
email: string;
|
|
306
|
+
country?: string;
|
|
307
|
+
business_type?: string;
|
|
308
|
+
metadata?: Record<string, string>;
|
|
309
|
+
}
|
|
310
|
+
interface CreateOnboardingLinkInput {
|
|
311
|
+
refresh_url: string;
|
|
312
|
+
return_url: string;
|
|
313
|
+
}
|
|
314
|
+
interface CreateTransferInput {
|
|
315
|
+
amount_cents: number;
|
|
316
|
+
currency?: string;
|
|
317
|
+
description?: string;
|
|
318
|
+
metadata?: Record<string, string>;
|
|
319
|
+
}
|
|
320
|
+
|
|
244
321
|
/**
|
|
245
322
|
* A generic fetcher function that consumer projects provide.
|
|
246
323
|
* It handles auth tokens, refresh, and base URL internally.
|
|
@@ -313,6 +390,20 @@ declare class BillingAdminApiClient {
|
|
|
313
390
|
getClientInfo(): Promise<{
|
|
314
391
|
client_id: string | null;
|
|
315
392
|
}>;
|
|
393
|
+
getConnectAccounts(params?: {
|
|
394
|
+
limit?: number;
|
|
395
|
+
starting_after?: string;
|
|
396
|
+
}): Promise<ConnectAccountsPage>;
|
|
397
|
+
getConnectAccount(accountId: string): Promise<ConnectAccount>;
|
|
398
|
+
createConnectAccount(data: CreateConnectAccountInput): Promise<ConnectAccount>;
|
|
399
|
+
createOnboardingLink(accountId: string, data: CreateOnboardingLinkInput): Promise<ConnectAccountLink>;
|
|
400
|
+
createLoginLink(accountId: string): Promise<ConnectLoginLink>;
|
|
401
|
+
getConnectAccountBalance(accountId: string): Promise<ConnectBalance>;
|
|
402
|
+
createTransfer(accountId: string, data: CreateTransferInput): Promise<ConnectTransfer>;
|
|
403
|
+
listTransfers(accountId: string, params?: {
|
|
404
|
+
limit?: number;
|
|
405
|
+
starting_after?: string;
|
|
406
|
+
}): Promise<ConnectTransfersPage>;
|
|
316
407
|
}
|
|
317
408
|
/**
|
|
318
409
|
* Factory function to create a BillingAdminApiClient instance.
|
|
@@ -334,6 +425,18 @@ declare function useDialogState<T = undefined>(): {
|
|
|
334
425
|
setData: react.Dispatch<react.SetStateAction<T | undefined>>;
|
|
335
426
|
};
|
|
336
427
|
|
|
428
|
+
interface CursorPaginationState {
|
|
429
|
+
cursor: string | undefined;
|
|
430
|
+
goToNext: (lastItemId: string) => void;
|
|
431
|
+
goToFirst: () => void;
|
|
432
|
+
hasCursor: boolean;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Hook for managing cursor-based pagination state.
|
|
436
|
+
* Encapsulates the cursor value and navigation callbacks.
|
|
437
|
+
*/
|
|
438
|
+
declare function useCursorPagination(): CursorPaginationState;
|
|
439
|
+
|
|
337
440
|
declare function useAdminPlans(params?: {
|
|
338
441
|
is_active?: boolean;
|
|
339
442
|
}): _tanstack_react_query.UseQueryResult<PaginatedResponse<AdminPlan>, Error>;
|
|
@@ -444,4 +547,4 @@ declare function validateSlug(slug: string): string | null;
|
|
|
444
547
|
*/
|
|
445
548
|
declare function validateRequired(value: string, fieldName: string): string | null;
|
|
446
549
|
|
|
447
|
-
export { type AdminFeature, type AdminFeatureCreate, type AdminFeatureFilters, type AdminFeatureListResponse, type AdminFeatureUpdate, type AdminInvoice, type AdminInvoiceLineItem, type AdminInvoiceStatus, type AdminPayment, type AdminPaymentRefund, type AdminPaymentStatus, type AdminPlan, type AdminPlanCreate, type AdminPlanPricingModel, type AdminPlanUpdate, type AdminProduct, type AdminProductCreate, type AdminProductUpdate, type AdminSubscription, type AdminSubscriptionCreate, type AdminSubscriptionStatus, BillingAdminApiClient, type BillingAdminClientConfig, BillingAdminClientContext, type CursorPaginatedResponse, type Fetcher, type JsonArray, type JsonObject, type JsonPrimitive, type JsonValue, type PaginatedResponse, type ProductExtraData, type RecurringInterval, type RefundStatus, createBillingAdminClient, formatCurrency, formatCurrencyFromCents, formatDate, formatPrice, formatTimestamp, invoiceStatusColors, invoiceStatusLabels, paymentStatusColors, paymentStatusLabels, subscriptionStatusColors, subscriptionStatusLabels, truncateId, useAdminFeatures, useAdminInvoices, useAdminPayments, useAdminPlans, useAdminProducts, useAdminSubscriptions, useAvailableFeatures, useBillingAdminClient, useCancelSubscription, useChangeSubscriptionPlan, useCreateFeature, useCreatePlan, useCreateProduct, useCreateSubscription, useDeleteFeature, useDeletePlan, useDeleteProduct, useDialogState, useRefundPayment, useSendInvoice, useSyncPlanToStripe, useSyncProductToStripe, useUpdateFeature, useUpdatePlan, useUpdateProduct, useVoidInvoice, validateRequired, validateSlug };
|
|
550
|
+
export { type AdminFeature, type AdminFeatureCreate, type AdminFeatureFilters, type AdminFeatureListResponse, type AdminFeatureUpdate, type AdminInvoice, type AdminInvoiceLineItem, type AdminInvoiceStatus, type AdminPayment, type AdminPaymentRefund, type AdminPaymentStatus, type AdminPlan, type AdminPlanCreate, type AdminPlanPricingModel, type AdminPlanUpdate, type AdminProduct, type AdminProductCreate, type AdminProductUpdate, type AdminSubscription, type AdminSubscriptionCreate, type AdminSubscriptionStatus, BillingAdminApiClient, type BillingAdminClientConfig, BillingAdminClientContext, type CursorPaginatedResponse, type CursorPaginationState, type Fetcher, type JsonArray, type JsonObject, type JsonPrimitive, type JsonValue, type PaginatedResponse, type ProductExtraData, type RecurringInterval, type RefundStatus, type Visibility, createBillingAdminClient, formatCurrency, formatCurrencyFromCents, formatDate, formatPrice, formatTimestamp, invoiceStatusColors, invoiceStatusLabels, paymentStatusColors, paymentStatusLabels, subscriptionStatusColors, subscriptionStatusLabels, truncateId, useAdminFeatures, useAdminInvoices, useAdminPayments, useAdminPlans, useAdminProducts, useAdminSubscriptions, useAvailableFeatures, useBillingAdminClient, useCancelSubscription, useChangeSubscriptionPlan, useCreateFeature, useCreatePlan, useCreateProduct, useCreateSubscription, useCursorPagination, useDeleteFeature, useDeletePlan, useDeleteProduct, useDialogState, useRefundPayment, useSendInvoice, useSyncPlanToStripe, useSyncProductToStripe, useUpdateFeature, useUpdatePlan, useUpdateProduct, useVoidInvoice, validateRequired, validateSlug };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,15 @@ import * as react from 'react';
|
|
|
2
2
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
3
3
|
|
|
4
4
|
type AdminPlanPricingModel = 'flat' | 'tiered' | 'per_unit' | 'usage_based';
|
|
5
|
+
/**
|
|
6
|
+
* Per-feature UI visibility for a plan.
|
|
7
|
+
*
|
|
8
|
+
* - ``visible``: feature is listed in the public plan card and accessible.
|
|
9
|
+
* - ``teaser``: feature is listed but shown as locked with an upgrade CTA.
|
|
10
|
+
* - ``hidden``: feature exists on the plan but is not shown in the UI
|
|
11
|
+
* (used for sunset / admin-only flags).
|
|
12
|
+
*/
|
|
13
|
+
type Visibility = 'visible' | 'teaser' | 'hidden';
|
|
5
14
|
interface AdminPlan {
|
|
6
15
|
id: string;
|
|
7
16
|
client_id: string;
|
|
@@ -16,11 +25,14 @@ interface AdminPlan {
|
|
|
16
25
|
stripe_price_id_yearly: string | null;
|
|
17
26
|
limits: Record<string, number> | null;
|
|
18
27
|
features: string[] | null;
|
|
28
|
+
/** Per-feature UI visibility override. Empty/null means "all visible". */
|
|
29
|
+
ui_visibility?: Record<string, Visibility> | null;
|
|
19
30
|
trial_days: number;
|
|
20
31
|
is_active: boolean;
|
|
21
32
|
contact_sales: boolean;
|
|
22
33
|
color: string;
|
|
23
34
|
sort_order: number;
|
|
35
|
+
environment?: 'test' | 'live';
|
|
24
36
|
created_at: string;
|
|
25
37
|
updated_at: string;
|
|
26
38
|
}
|
|
@@ -34,6 +46,7 @@ interface AdminPlanCreate {
|
|
|
34
46
|
currency?: string;
|
|
35
47
|
limits?: Record<string, number>;
|
|
36
48
|
features?: string[];
|
|
49
|
+
ui_visibility?: Record<string, Visibility>;
|
|
37
50
|
trial_days?: number;
|
|
38
51
|
is_active?: boolean;
|
|
39
52
|
contact_sales?: boolean;
|
|
@@ -48,6 +61,7 @@ interface AdminPlanUpdate {
|
|
|
48
61
|
price_yearly?: number;
|
|
49
62
|
limits?: Record<string, number>;
|
|
50
63
|
features?: string[];
|
|
64
|
+
ui_visibility?: Record<string, Visibility>;
|
|
51
65
|
trial_days?: number;
|
|
52
66
|
is_active?: boolean;
|
|
53
67
|
contact_sales?: boolean;
|
|
@@ -74,6 +88,7 @@ interface AdminSubscription {
|
|
|
74
88
|
trial_end: string | null;
|
|
75
89
|
canceled_at: string | null;
|
|
76
90
|
cancel_at: string | null;
|
|
91
|
+
environment?: 'test' | 'live';
|
|
77
92
|
created_at: string;
|
|
78
93
|
updated_at: string;
|
|
79
94
|
}
|
|
@@ -145,6 +160,7 @@ interface AdminInvoice {
|
|
|
145
160
|
subscription_id: string | null;
|
|
146
161
|
invoice_pdf: string | null;
|
|
147
162
|
hosted_invoice_url: string | null;
|
|
163
|
+
environment?: 'test' | 'live';
|
|
148
164
|
lines: AdminInvoiceLineItem[];
|
|
149
165
|
}
|
|
150
166
|
interface AdminInvoiceLineItem {
|
|
@@ -173,6 +189,7 @@ interface AdminProduct {
|
|
|
173
189
|
category: string | null;
|
|
174
190
|
is_active: boolean;
|
|
175
191
|
extra_data: ProductExtraData | null;
|
|
192
|
+
environment?: 'test' | 'live';
|
|
176
193
|
created_at: string | null;
|
|
177
194
|
updated_at: string | null;
|
|
178
195
|
}
|
|
@@ -241,6 +258,66 @@ interface AdminFeatureFilters {
|
|
|
241
258
|
category?: string;
|
|
242
259
|
}
|
|
243
260
|
|
|
261
|
+
interface ConnectAccount {
|
|
262
|
+
id: string;
|
|
263
|
+
email: string;
|
|
264
|
+
country: string;
|
|
265
|
+
business_type: string;
|
|
266
|
+
charges_enabled: boolean;
|
|
267
|
+
payouts_enabled: boolean;
|
|
268
|
+
details_submitted: boolean;
|
|
269
|
+
created_at: string;
|
|
270
|
+
metadata: Record<string, string>;
|
|
271
|
+
}
|
|
272
|
+
interface ConnectAccountLink {
|
|
273
|
+
url: string;
|
|
274
|
+
expires_at: string;
|
|
275
|
+
}
|
|
276
|
+
interface ConnectLoginLink {
|
|
277
|
+
url: string;
|
|
278
|
+
created: string;
|
|
279
|
+
}
|
|
280
|
+
interface ConnectTransfer {
|
|
281
|
+
id: string;
|
|
282
|
+
amount: number;
|
|
283
|
+
currency: string;
|
|
284
|
+
destination: string;
|
|
285
|
+
description?: string;
|
|
286
|
+
created_at: string;
|
|
287
|
+
}
|
|
288
|
+
interface ConnectBalanceAmount {
|
|
289
|
+
amount: number;
|
|
290
|
+
currency: string;
|
|
291
|
+
}
|
|
292
|
+
interface ConnectBalance {
|
|
293
|
+
available: ConnectBalanceAmount[];
|
|
294
|
+
pending: ConnectBalanceAmount[];
|
|
295
|
+
}
|
|
296
|
+
interface ConnectAccountsPage {
|
|
297
|
+
data: ConnectAccount[];
|
|
298
|
+
has_more: boolean;
|
|
299
|
+
}
|
|
300
|
+
interface ConnectTransfersPage {
|
|
301
|
+
data: ConnectTransfer[];
|
|
302
|
+
has_more: boolean;
|
|
303
|
+
}
|
|
304
|
+
interface CreateConnectAccountInput {
|
|
305
|
+
email: string;
|
|
306
|
+
country?: string;
|
|
307
|
+
business_type?: string;
|
|
308
|
+
metadata?: Record<string, string>;
|
|
309
|
+
}
|
|
310
|
+
interface CreateOnboardingLinkInput {
|
|
311
|
+
refresh_url: string;
|
|
312
|
+
return_url: string;
|
|
313
|
+
}
|
|
314
|
+
interface CreateTransferInput {
|
|
315
|
+
amount_cents: number;
|
|
316
|
+
currency?: string;
|
|
317
|
+
description?: string;
|
|
318
|
+
metadata?: Record<string, string>;
|
|
319
|
+
}
|
|
320
|
+
|
|
244
321
|
/**
|
|
245
322
|
* A generic fetcher function that consumer projects provide.
|
|
246
323
|
* It handles auth tokens, refresh, and base URL internally.
|
|
@@ -313,6 +390,20 @@ declare class BillingAdminApiClient {
|
|
|
313
390
|
getClientInfo(): Promise<{
|
|
314
391
|
client_id: string | null;
|
|
315
392
|
}>;
|
|
393
|
+
getConnectAccounts(params?: {
|
|
394
|
+
limit?: number;
|
|
395
|
+
starting_after?: string;
|
|
396
|
+
}): Promise<ConnectAccountsPage>;
|
|
397
|
+
getConnectAccount(accountId: string): Promise<ConnectAccount>;
|
|
398
|
+
createConnectAccount(data: CreateConnectAccountInput): Promise<ConnectAccount>;
|
|
399
|
+
createOnboardingLink(accountId: string, data: CreateOnboardingLinkInput): Promise<ConnectAccountLink>;
|
|
400
|
+
createLoginLink(accountId: string): Promise<ConnectLoginLink>;
|
|
401
|
+
getConnectAccountBalance(accountId: string): Promise<ConnectBalance>;
|
|
402
|
+
createTransfer(accountId: string, data: CreateTransferInput): Promise<ConnectTransfer>;
|
|
403
|
+
listTransfers(accountId: string, params?: {
|
|
404
|
+
limit?: number;
|
|
405
|
+
starting_after?: string;
|
|
406
|
+
}): Promise<ConnectTransfersPage>;
|
|
316
407
|
}
|
|
317
408
|
/**
|
|
318
409
|
* Factory function to create a BillingAdminApiClient instance.
|
|
@@ -334,6 +425,18 @@ declare function useDialogState<T = undefined>(): {
|
|
|
334
425
|
setData: react.Dispatch<react.SetStateAction<T | undefined>>;
|
|
335
426
|
};
|
|
336
427
|
|
|
428
|
+
interface CursorPaginationState {
|
|
429
|
+
cursor: string | undefined;
|
|
430
|
+
goToNext: (lastItemId: string) => void;
|
|
431
|
+
goToFirst: () => void;
|
|
432
|
+
hasCursor: boolean;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Hook for managing cursor-based pagination state.
|
|
436
|
+
* Encapsulates the cursor value and navigation callbacks.
|
|
437
|
+
*/
|
|
438
|
+
declare function useCursorPagination(): CursorPaginationState;
|
|
439
|
+
|
|
337
440
|
declare function useAdminPlans(params?: {
|
|
338
441
|
is_active?: boolean;
|
|
339
442
|
}): _tanstack_react_query.UseQueryResult<PaginatedResponse<AdminPlan>, Error>;
|
|
@@ -444,4 +547,4 @@ declare function validateSlug(slug: string): string | null;
|
|
|
444
547
|
*/
|
|
445
548
|
declare function validateRequired(value: string, fieldName: string): string | null;
|
|
446
549
|
|
|
447
|
-
export { type AdminFeature, type AdminFeatureCreate, type AdminFeatureFilters, type AdminFeatureListResponse, type AdminFeatureUpdate, type AdminInvoice, type AdminInvoiceLineItem, type AdminInvoiceStatus, type AdminPayment, type AdminPaymentRefund, type AdminPaymentStatus, type AdminPlan, type AdminPlanCreate, type AdminPlanPricingModel, type AdminPlanUpdate, type AdminProduct, type AdminProductCreate, type AdminProductUpdate, type AdminSubscription, type AdminSubscriptionCreate, type AdminSubscriptionStatus, BillingAdminApiClient, type BillingAdminClientConfig, BillingAdminClientContext, type CursorPaginatedResponse, type Fetcher, type JsonArray, type JsonObject, type JsonPrimitive, type JsonValue, type PaginatedResponse, type ProductExtraData, type RecurringInterval, type RefundStatus, createBillingAdminClient, formatCurrency, formatCurrencyFromCents, formatDate, formatPrice, formatTimestamp, invoiceStatusColors, invoiceStatusLabels, paymentStatusColors, paymentStatusLabels, subscriptionStatusColors, subscriptionStatusLabels, truncateId, useAdminFeatures, useAdminInvoices, useAdminPayments, useAdminPlans, useAdminProducts, useAdminSubscriptions, useAvailableFeatures, useBillingAdminClient, useCancelSubscription, useChangeSubscriptionPlan, useCreateFeature, useCreatePlan, useCreateProduct, useCreateSubscription, useDeleteFeature, useDeletePlan, useDeleteProduct, useDialogState, useRefundPayment, useSendInvoice, useSyncPlanToStripe, useSyncProductToStripe, useUpdateFeature, useUpdatePlan, useUpdateProduct, useVoidInvoice, validateRequired, validateSlug };
|
|
550
|
+
export { type AdminFeature, type AdminFeatureCreate, type AdminFeatureFilters, type AdminFeatureListResponse, type AdminFeatureUpdate, type AdminInvoice, type AdminInvoiceLineItem, type AdminInvoiceStatus, type AdminPayment, type AdminPaymentRefund, type AdminPaymentStatus, type AdminPlan, type AdminPlanCreate, type AdminPlanPricingModel, type AdminPlanUpdate, type AdminProduct, type AdminProductCreate, type AdminProductUpdate, type AdminSubscription, type AdminSubscriptionCreate, type AdminSubscriptionStatus, BillingAdminApiClient, type BillingAdminClientConfig, BillingAdminClientContext, type CursorPaginatedResponse, type CursorPaginationState, type Fetcher, type JsonArray, type JsonObject, type JsonPrimitive, type JsonValue, type PaginatedResponse, type ProductExtraData, type RecurringInterval, type RefundStatus, type Visibility, createBillingAdminClient, formatCurrency, formatCurrencyFromCents, formatDate, formatPrice, formatTimestamp, invoiceStatusColors, invoiceStatusLabels, paymentStatusColors, paymentStatusLabels, subscriptionStatusColors, subscriptionStatusLabels, truncateId, useAdminFeatures, useAdminInvoices, useAdminPayments, useAdminPlans, useAdminProducts, useAdminSubscriptions, useAvailableFeatures, useBillingAdminClient, useCancelSubscription, useChangeSubscriptionPlan, useCreateFeature, useCreatePlan, useCreateProduct, useCreateSubscription, useCursorPagination, useDeleteFeature, useDeletePlan, useDeleteProduct, useDialogState, useRefundPayment, useSendInvoice, useSyncPlanToStripe, useSyncProductToStripe, useUpdateFeature, useUpdatePlan, useUpdateProduct, useVoidInvoice, validateRequired, validateSlug };
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,7 @@ __export(index_exports, {
|
|
|
49
49
|
useCreatePlan: () => useCreatePlan,
|
|
50
50
|
useCreateProduct: () => useCreateProduct,
|
|
51
51
|
useCreateSubscription: () => useCreateSubscription,
|
|
52
|
+
useCursorPagination: () => useCursorPagination,
|
|
52
53
|
useDeleteFeature: () => useDeleteFeature,
|
|
53
54
|
useDeletePlan: () => useDeletePlan,
|
|
54
55
|
useDeleteProduct: () => useDeleteProduct,
|
|
@@ -241,6 +242,44 @@ var BillingAdminApiClient = class {
|
|
|
241
242
|
async getClientInfo() {
|
|
242
243
|
return this.fetcher(this.url("/client-info"));
|
|
243
244
|
}
|
|
245
|
+
// --- Connect Accounts ---
|
|
246
|
+
async getConnectAccounts(params) {
|
|
247
|
+
const query = buildQuery({ limit: params?.limit, starting_after: params?.starting_after });
|
|
248
|
+
return this.fetcher(this.url(`/connect/accounts${query}`));
|
|
249
|
+
}
|
|
250
|
+
async getConnectAccount(accountId) {
|
|
251
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}`));
|
|
252
|
+
}
|
|
253
|
+
async createConnectAccount(data) {
|
|
254
|
+
return this.fetcher(this.url("/connect/accounts"), {
|
|
255
|
+
method: "POST",
|
|
256
|
+
body: JSON.stringify(data)
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
async createOnboardingLink(accountId, data) {
|
|
260
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/onboarding-link`), {
|
|
261
|
+
method: "POST",
|
|
262
|
+
body: JSON.stringify(data)
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
async createLoginLink(accountId) {
|
|
266
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/login-link`), {
|
|
267
|
+
method: "POST"
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
async getConnectAccountBalance(accountId) {
|
|
271
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/balance`));
|
|
272
|
+
}
|
|
273
|
+
async createTransfer(accountId, data) {
|
|
274
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/transfers`), {
|
|
275
|
+
method: "POST",
|
|
276
|
+
body: JSON.stringify(data)
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
async listTransfers(accountId, params) {
|
|
280
|
+
const query = buildQuery({ limit: params?.limit, starting_after: params?.starting_after });
|
|
281
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/transfers${query}`));
|
|
282
|
+
}
|
|
244
283
|
};
|
|
245
284
|
function createBillingAdminClient(config) {
|
|
246
285
|
return new BillingAdminApiClient(config);
|
|
@@ -289,6 +328,24 @@ function useDialogState() {
|
|
|
289
328
|
};
|
|
290
329
|
}
|
|
291
330
|
|
|
331
|
+
// src/hooks/useCursorPagination.ts
|
|
332
|
+
var import_react3 = require("react");
|
|
333
|
+
function useCursorPagination() {
|
|
334
|
+
const [cursor, setCursor] = (0, import_react3.useState)();
|
|
335
|
+
const goToNext = (0, import_react3.useCallback)((lastItemId) => {
|
|
336
|
+
setCursor(lastItemId);
|
|
337
|
+
}, []);
|
|
338
|
+
const goToFirst = (0, import_react3.useCallback)(() => {
|
|
339
|
+
setCursor(void 0);
|
|
340
|
+
}, []);
|
|
341
|
+
return {
|
|
342
|
+
cursor,
|
|
343
|
+
goToNext,
|
|
344
|
+
goToFirst,
|
|
345
|
+
hasCursor: cursor !== void 0
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
292
349
|
// src/hooks/usePlans.ts
|
|
293
350
|
var import_react_query = require("@tanstack/react-query");
|
|
294
351
|
var PLANS_KEY = "billing-admin-plans";
|
|
@@ -676,6 +733,7 @@ function validateRequired(value, fieldName) {
|
|
|
676
733
|
useCreatePlan,
|
|
677
734
|
useCreateProduct,
|
|
678
735
|
useCreateSubscription,
|
|
736
|
+
useCursorPagination,
|
|
679
737
|
useDeleteFeature,
|
|
680
738
|
useDeletePlan,
|
|
681
739
|
useDeleteProduct,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/api/client.ts","../src/hooks/context.ts","../src/hooks/useDialogState.ts","../src/hooks/usePlans.ts","../src/hooks/useSubscriptions.ts","../src/hooks/usePayments.ts","../src/hooks/useInvoices.ts","../src/hooks/useProducts.ts","../src/hooks/useFeatures.ts","../src/utils/formatters.ts","../src/utils/status.ts","../src/utils/validators.ts"],"sourcesContent":["// Types\nexport type {\n AdminPlan,\n AdminPlanCreate,\n AdminPlanUpdate,\n AdminPlanPricingModel,\n} from './types/plan';\n\nexport type {\n AdminSubscription,\n AdminSubscriptionCreate,\n AdminSubscriptionStatus,\n} from './types/subscription';\n\nexport type {\n AdminPayment,\n AdminPaymentRefund,\n AdminPaymentStatus,\n} from './types/payment';\n\nexport type {\n AdminInvoice,\n AdminInvoiceLineItem,\n AdminInvoiceStatus,\n} from './types/invoice';\n\nexport type {\n AdminProduct,\n AdminProductCreate,\n AdminProductUpdate,\n ProductExtraData,\n} from './types/product';\n\nexport type {\n AdminFeature,\n AdminFeatureCreate,\n AdminFeatureUpdate,\n AdminFeatureListResponse,\n AdminFeatureFilters,\n} from './types/feature';\n\nexport type {\n PaginatedResponse,\n CursorPaginatedResponse,\n JsonValue,\n JsonObject,\n JsonArray,\n JsonPrimitive,\n RecurringInterval,\n RefundStatus,\n} from './types/common';\n\n// API Client\nexport { BillingAdminApiClient, createBillingAdminClient } from './api/client';\nexport type { BillingAdminClientConfig, Fetcher } from './api/client';\n\n// React Hooks\nexport { BillingAdminClientContext, useBillingAdminClient } from './hooks/context';\nexport { useDialogState } from './hooks/useDialogState';\nexport { useAdminPlans, useCreatePlan, useUpdatePlan, useDeletePlan, useSyncPlanToStripe } from './hooks/usePlans';\nexport { useAdminSubscriptions, useCreateSubscription, useCancelSubscription, useChangeSubscriptionPlan } from './hooks/useSubscriptions';\nexport { useAdminPayments, useRefundPayment } from './hooks/usePayments';\nexport { useAdminInvoices, useSendInvoice, useVoidInvoice } from './hooks/useInvoices';\nexport { useAdminProducts, useCreateProduct, useUpdateProduct, useDeleteProduct, useSyncProductToStripe } from './hooks/useProducts';\nexport { useAdminFeatures, useAvailableFeatures, useCreateFeature, useUpdateFeature, useDeleteFeature } from './hooks/useFeatures';\n\n// Utilities\nexport {\n formatCurrency,\n formatCurrencyFromCents,\n formatPrice,\n formatDate,\n formatTimestamp,\n truncateId,\n} from './utils/formatters';\n\nexport {\n subscriptionStatusColors,\n subscriptionStatusLabels,\n paymentStatusColors,\n paymentStatusLabels,\n invoiceStatusColors,\n invoiceStatusLabels,\n} from './utils/status';\n\nexport {\n validateSlug,\n validateRequired,\n} from './utils/validators';\n","import type { AdminPlan, AdminPlanCreate, AdminPlanUpdate } from '../types/plan';\nimport type { AdminSubscription, AdminSubscriptionCreate, AdminSubscriptionStatus } from '../types/subscription';\nimport type { AdminPayment, AdminPaymentRefund, AdminPaymentStatus } from '../types/payment';\nimport type { AdminInvoice } from '../types/invoice';\nimport type { AdminProduct, AdminProductCreate, AdminProductUpdate } from '../types/product';\nimport type { AdminFeature, AdminFeatureCreate, AdminFeatureUpdate, AdminFeatureListResponse, AdminFeatureFilters } from '../types/feature';\nimport type { PaginatedResponse, CursorPaginatedResponse } from '../types/common';\n\n/**\n * A generic fetcher function that consumer projects provide.\n * It handles auth tokens, refresh, and base URL internally.\n */\nexport type Fetcher = <T>(url: string, options?: RequestInit) => Promise<T>;\n\nexport interface BillingAdminClientConfig {\n /** Base path for billing admin API (e.g., '/api/v1/billing-admin') */\n basePath: string;\n /** HTTP fetcher function provided by the host application */\n fetcher: Fetcher;\n}\n\nfunction buildQuery(params: Record<string, string | number | boolean | undefined>): string {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, String(value));\n }\n }\n const query = searchParams.toString();\n return query ? `?${query}` : '';\n}\n\nexport class BillingAdminApiClient {\n private basePath: string;\n private fetcher: Fetcher;\n\n constructor(config: BillingAdminClientConfig) {\n this.basePath = config.basePath;\n this.fetcher = config.fetcher;\n }\n\n private url(path: string): string {\n return `${this.basePath}${path}`;\n }\n\n // --- Plans ---\n\n async getPlans(params?: { is_active?: boolean }): Promise<PaginatedResponse<AdminPlan>> {\n const query = buildQuery({ is_active: params?.is_active });\n return this.fetcher(this.url(`/plans${query}`));\n }\n\n async getPlan(planId: string): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}`));\n }\n\n async createPlan(data: AdminPlanCreate): Promise<AdminPlan> {\n return this.fetcher(this.url('/plans'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updatePlan(planId: string, data: AdminPlanUpdate): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deletePlan(planId: string): Promise<void> {\n return this.fetcher(this.url(`/plans/${planId}`), { method: 'DELETE' });\n }\n\n async syncPlanToStripe(planId: string): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}/sync-stripe`), { method: 'POST' });\n }\n\n // --- Subscriptions ---\n\n async getSubscriptions(params?: {\n status?: AdminSubscriptionStatus;\n search?: string;\n limit?: number;\n offset?: number;\n }): Promise<PaginatedResponse<AdminSubscription>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n limit: params?.limit,\n offset: params?.offset,\n });\n return this.fetcher(this.url(`/subscriptions${query}`));\n }\n\n async getSubscription(subscriptionId: string): Promise<AdminSubscription> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}`));\n }\n\n async cancelSubscription(subscriptionId: string, atPeriodEnd: boolean = true): Promise<AdminSubscription> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}/cancel`), {\n method: 'POST',\n body: JSON.stringify({ at_period_end: atPeriodEnd }),\n });\n }\n\n async createSubscription(data: AdminSubscriptionCreate): Promise<AdminSubscription> {\n return this.fetcher(this.url('/subscriptions'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async changeSubscriptionPlan(subscriptionId: string, newPlanSlug: string): Promise<void> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}/change-plan`), {\n method: 'POST',\n body: JSON.stringify({ new_plan_slug: newPlanSlug }),\n });\n }\n\n // --- Payments ---\n\n async getPayments(params?: {\n status?: AdminPaymentStatus | string;\n search?: string;\n limit?: number;\n starting_after?: string;\n }): Promise<CursorPaginatedResponse<AdminPayment>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n limit: params?.limit,\n starting_after: params?.starting_after,\n });\n return this.fetcher(this.url(`/payments${query}`));\n }\n\n async getPayment(paymentId: string): Promise<AdminPayment> {\n return this.fetcher(this.url(`/payments/${paymentId}`));\n }\n\n async refundPayment(paymentId: string, params?: {\n amount?: number;\n reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer';\n }): Promise<AdminPaymentRefund> {\n return this.fetcher(this.url(`/payments/${paymentId}/refund`), {\n method: 'POST',\n body: JSON.stringify(params || {}),\n });\n }\n\n // --- Invoices ---\n\n async getInvoices(params?: {\n status?: string;\n search?: string;\n store_id?: string;\n limit?: number;\n starting_after?: string;\n }): Promise<CursorPaginatedResponse<AdminInvoice>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n store_id: params?.store_id,\n limit: params?.limit,\n starting_after: params?.starting_after,\n });\n return this.fetcher(this.url(`/invoices${query}`));\n }\n\n async getInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}`));\n }\n\n async sendInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}/send`), { method: 'POST' });\n }\n\n async voidInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}/void`), { method: 'POST' });\n }\n\n // --- Products ---\n\n async getProducts(params?: { is_active?: boolean }): Promise<PaginatedResponse<AdminProduct>> {\n const query = buildQuery({ is_active: params?.is_active });\n return this.fetcher(this.url(`/products${query}`));\n }\n\n async getProduct(productId: string): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}`));\n }\n\n async createProduct(data: AdminProductCreate): Promise<AdminProduct> {\n return this.fetcher(this.url('/products'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updateProduct(productId: string, data: AdminProductUpdate): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deleteProduct(productId: string): Promise<void> {\n return this.fetcher(this.url(`/products/${productId}`), { method: 'DELETE' });\n }\n\n async syncProductToStripe(productId: string): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}/sync-stripe`), { method: 'POST' });\n }\n\n // --- Features ---\n\n async getFeatures(params?: AdminFeatureFilters): Promise<AdminFeatureListResponse> {\n const query = buildQuery({\n available_only: params?.available_only,\n category: params?.category,\n });\n return this.fetcher(this.url(`/features${query}`));\n }\n\n async getAvailableFeatures(category?: string): Promise<AdminFeatureListResponse> {\n const query = buildQuery({ category });\n return this.fetcher(this.url(`/features/available${query}`));\n }\n\n async getFeature(featureId: string): Promise<AdminFeature> {\n return this.fetcher(this.url(`/features/${featureId}`));\n }\n\n async createFeature(data: AdminFeatureCreate): Promise<AdminFeature> {\n return this.fetcher(this.url('/features'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updateFeature(featureId: string, data: AdminFeatureUpdate): Promise<AdminFeature> {\n return this.fetcher(this.url(`/features/${featureId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deleteFeature(featureId: string): Promise<void> {\n return this.fetcher(this.url(`/features/${featureId}`), { method: 'DELETE' });\n }\n\n // --- Client Info ---\n\n async getClientInfo(): Promise<{ client_id: string | null }> {\n return this.fetcher(this.url('/client-info'));\n }\n}\n\n/**\n * Factory function to create a BillingAdminApiClient instance.\n */\nexport function createBillingAdminClient(config: BillingAdminClientConfig): BillingAdminApiClient {\n return new BillingAdminApiClient(config);\n}\n","import { createContext, useContext } from 'react';\nimport type { BillingAdminApiClient } from '../api/client';\n\nexport const BillingAdminClientContext = createContext<BillingAdminApiClient | null>(null);\n\nexport function useBillingAdminClient(): BillingAdminApiClient {\n const client = useContext(BillingAdminClientContext);\n if (!client) {\n throw new Error(\n 'useBillingAdminClient must be used within a BillingAdminProvider. ' +\n 'Wrap your component tree with <BillingAdminProvider config={{...}}>.'\n );\n }\n return client;\n}\n","import { useState, useCallback } from 'react';\n\n/**\n * Generic hook for managing dialog state with optional associated data.\n */\nexport function useDialogState<T = undefined>() {\n const [isOpen, setIsOpen] = useState(false);\n const [data, setData] = useState<T | undefined>(undefined);\n\n const open = useCallback((initialData?: T) => {\n setData(initialData);\n setIsOpen(true);\n }, []);\n\n const close = useCallback(() => {\n setIsOpen(false);\n setTimeout(() => setData(undefined), 150);\n }, []);\n\n const toggle = useCallback(() => {\n if (isOpen) {\n close();\n } else {\n open();\n }\n }, [isOpen, open, close]);\n\n return {\n isOpen,\n data,\n open,\n close,\n toggle,\n setData,\n };\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminPlanCreate, AdminPlanUpdate } from '../types/plan';\n\nconst PLANS_KEY = 'billing-admin-plans';\n\nexport function useAdminPlans(params?: { is_active?: boolean }) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PLANS_KEY, params],\n queryFn: () => client.getPlans(params),\n });\n}\n\nexport function useCreatePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminPlanCreate) => client.createPlan(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useUpdatePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminPlanUpdate }) =>\n client.updatePlan(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useDeletePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deletePlan(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useSyncPlanToStripe() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.syncPlanToStripe(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminSubscriptionStatus, AdminSubscriptionCreate } from '../types/subscription';\n\nconst SUBSCRIPTIONS_KEY = 'billing-admin-subscriptions';\n\nexport function useAdminSubscriptions(params?: {\n status?: AdminSubscriptionStatus;\n search?: string;\n limit?: number;\n offset?: number;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [SUBSCRIPTIONS_KEY, params],\n queryFn: () => client.getSubscriptions(params),\n });\n}\n\nexport function useCreateSubscription() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminSubscriptionCreate) => client.createSubscription(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n\nexport function useCancelSubscription() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, atPeriodEnd }: { id: string; atPeriodEnd: boolean }) =>\n client.cancelSubscription(id, atPeriodEnd),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n\nexport function useChangeSubscriptionPlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, newPlanSlug }: { id: string; newPlanSlug: string }) =>\n client.changeSubscriptionPlan(id, newPlanSlug),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\n\nconst PAYMENTS_KEY = 'billing-admin-payments';\n\nexport function useAdminPayments(params?: {\n status?: string;\n search?: string;\n limit?: number;\n starting_after?: string;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PAYMENTS_KEY, params],\n queryFn: () => client.getPayments(params),\n });\n}\n\nexport function useRefundPayment() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, amount, reason }: {\n id: string;\n amount?: number;\n reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer';\n }) => client.refundPayment(id, { amount, reason }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PAYMENTS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\n\nconst INVOICES_KEY = 'billing-admin-invoices';\n\nexport function useAdminInvoices(params?: {\n status?: string;\n search?: string;\n store_id?: string;\n limit?: number;\n starting_after?: string;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [INVOICES_KEY, params],\n queryFn: () => client.getInvoices(params),\n });\n}\n\nexport function useSendInvoice() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.sendInvoice(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });\n },\n });\n}\n\nexport function useVoidInvoice() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.voidInvoice(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminProductCreate, AdminProductUpdate } from '../types/product';\n\nconst PRODUCTS_KEY = 'billing-admin-products';\n\nexport function useAdminProducts(params?: { is_active?: boolean }) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PRODUCTS_KEY, params],\n queryFn: () => client.getProducts(params),\n });\n}\n\nexport function useCreateProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminProductCreate) => client.createProduct(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useUpdateProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminProductUpdate }) =>\n client.updateProduct(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useDeleteProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deleteProduct(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useSyncProductToStripe() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.syncProductToStripe(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminFeatureFilters, AdminFeatureCreate, AdminFeatureUpdate } from '../types/feature';\n\nexport function useAdminFeatures(params?: AdminFeatureFilters) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: ['billing-admin', 'features', params],\n queryFn: () => client.getFeatures(params),\n });\n}\n\nexport function useAvailableFeatures(category?: string) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: ['billing-admin', 'features', 'available', category],\n queryFn: () => client.getAvailableFeatures(category),\n });\n}\n\nexport function useCreateFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminFeatureCreate) => client.createFeature(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n\nexport function useUpdateFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminFeatureUpdate }) => client.updateFeature(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n\nexport function useDeleteFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deleteFeature(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n","/**\n * Format a currency amount using Intl.NumberFormat.\n */\nexport function formatCurrency(amount: number, currency: string = 'EUR', locale: string = 'it-IT'): string {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency.toUpperCase(),\n }).format(amount);\n}\n\n/**\n * Format amount in cents to currency string.\n */\nexport function formatCurrencyFromCents(amountCents: number, currency: string = 'EUR', locale: string = 'it-IT'): string {\n return formatCurrency(amountCents / 100, currency, locale);\n}\n\n/**\n * Format a price, returning \"Contattaci\" for null values.\n */\nexport function formatPrice(price: number | null, currency: string = 'EUR', locale: string = 'it-IT'): string {\n if (price === null) return 'Contattaci';\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency.toUpperCase(),\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }).format(price);\n}\n\n/**\n * Format a date string or Date object.\n */\nexport function formatDate(date: Date | string | undefined | null, locale: string = 'it-IT'): string {\n if (!date) return 'N/A';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (isNaN(d.getTime())) return 'N/A';\n return new Intl.DateTimeFormat(locale, {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n }).format(d);\n}\n\n/**\n * Format a Unix timestamp (seconds) to date string.\n */\nexport function formatTimestamp(timestamp: number | null, includeTime: boolean = false, locale: string = 'it-IT'): string {\n if (!timestamp) return '-';\n const date = new Date(timestamp * 1000);\n if (includeTime) {\n return date.toLocaleDateString(locale, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n }\n return date.toLocaleDateString(locale, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n });\n}\n\n/**\n * Truncate long IDs for display.\n */\nexport function truncateId(id: string, maxLength: number = 20): string {\n if (id.length <= maxLength) return id;\n return `${id.slice(0, 10)}...${id.slice(-6)}`;\n}\n","import type { AdminSubscriptionStatus } from '../types/subscription';\nimport type { AdminPaymentStatus } from '../types/payment';\nimport type { AdminInvoiceStatus } from '../types/invoice';\n\n// --- Subscription Status ---\n\nexport const subscriptionStatusColors: Record<AdminSubscriptionStatus, string> = {\n active: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n trialing: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n past_due: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n canceled: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n unpaid: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n incomplete: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400',\n};\n\nexport const subscriptionStatusLabels: Record<AdminSubscriptionStatus, string> = {\n active: 'Attivo',\n trialing: 'In Prova',\n past_due: 'Scaduto',\n canceled: 'Cancellato',\n unpaid: 'Non Pagato',\n incomplete: 'Incompleto',\n};\n\n// --- Payment Status ---\n\nexport const paymentStatusColors: Record<AdminPaymentStatus, string> = {\n succeeded: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n pending: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n failed: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n canceled: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n requires_payment_method: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n};\n\nexport const paymentStatusLabels: Record<AdminPaymentStatus, string> = {\n succeeded: 'Completato',\n pending: 'In Attesa',\n failed: 'Fallito',\n canceled: 'Annullato',\n requires_payment_method: 'Richiede Pagamento',\n};\n\n// --- Invoice Status ---\n\nexport const invoiceStatusColors: Record<AdminInvoiceStatus, string> = {\n draft: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n open: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n paid: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n void: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n uncollectible: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n};\n\nexport const invoiceStatusLabels: Record<AdminInvoiceStatus, string> = {\n draft: 'Bozza',\n open: 'Aperta',\n paid: 'Pagata',\n void: 'Annullata',\n uncollectible: 'Non Riscuotibile',\n};\n","/**\n * Validate a plan slug format.\n */\nexport function validateSlug(slug: string): string | null {\n if (!slug.trim()) {\n return 'Lo slug è obbligatorio';\n }\n if (!/^[a-z0-9-]+$/.test(slug)) {\n return 'Lo slug può contenere solo lettere minuscole, numeri e trattini';\n }\n return null;\n}\n\n/**\n * Validate required string field.\n */\nexport function validateRequired(value: string, fieldName: string): string | null {\n if (!value.trim()) {\n return `${fieldName} è obbligatorio`;\n }\n return null;\n}\n"],"mappings":"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","names":["import_react","import_react_query","import_react_query","import_react_query","import_react_query","import_react_query"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/api/client.ts","../src/hooks/context.ts","../src/hooks/useDialogState.ts","../src/hooks/useCursorPagination.ts","../src/hooks/usePlans.ts","../src/hooks/useSubscriptions.ts","../src/hooks/usePayments.ts","../src/hooks/useInvoices.ts","../src/hooks/useProducts.ts","../src/hooks/useFeatures.ts","../src/utils/formatters.ts","../src/utils/status.ts","../src/utils/validators.ts"],"sourcesContent":["// Types\nexport type {\n AdminPlan,\n AdminPlanCreate,\n AdminPlanUpdate,\n AdminPlanPricingModel,\n Visibility,\n} from './types/plan';\n\nexport type {\n AdminSubscription,\n AdminSubscriptionCreate,\n AdminSubscriptionStatus,\n} from './types/subscription';\n\nexport type {\n AdminPayment,\n AdminPaymentRefund,\n AdminPaymentStatus,\n} from './types/payment';\n\nexport type {\n AdminInvoice,\n AdminInvoiceLineItem,\n AdminInvoiceStatus,\n} from './types/invoice';\n\nexport type {\n AdminProduct,\n AdminProductCreate,\n AdminProductUpdate,\n ProductExtraData,\n} from './types/product';\n\nexport type {\n AdminFeature,\n AdminFeatureCreate,\n AdminFeatureUpdate,\n AdminFeatureListResponse,\n AdminFeatureFilters,\n} from './types/feature';\n\nexport type {\n PaginatedResponse,\n CursorPaginatedResponse,\n JsonValue,\n JsonObject,\n JsonArray,\n JsonPrimitive,\n RecurringInterval,\n RefundStatus,\n} from './types/common';\n\n// API Client\nexport { BillingAdminApiClient, createBillingAdminClient } from './api/client';\nexport type { BillingAdminClientConfig, Fetcher } from './api/client';\n\n// React Hooks\nexport { BillingAdminClientContext, useBillingAdminClient } from './hooks/context';\nexport { useDialogState } from './hooks/useDialogState';\nexport { useCursorPagination } from './hooks/useCursorPagination';\nexport type { CursorPaginationState } from './hooks/useCursorPagination';\nexport { useAdminPlans, useCreatePlan, useUpdatePlan, useDeletePlan, useSyncPlanToStripe } from './hooks/usePlans';\nexport { useAdminSubscriptions, useCreateSubscription, useCancelSubscription, useChangeSubscriptionPlan } from './hooks/useSubscriptions';\nexport { useAdminPayments, useRefundPayment } from './hooks/usePayments';\nexport { useAdminInvoices, useSendInvoice, useVoidInvoice } from './hooks/useInvoices';\nexport { useAdminProducts, useCreateProduct, useUpdateProduct, useDeleteProduct, useSyncProductToStripe } from './hooks/useProducts';\nexport { useAdminFeatures, useAvailableFeatures, useCreateFeature, useUpdateFeature, useDeleteFeature } from './hooks/useFeatures';\n\n// Utilities\nexport {\n formatCurrency,\n formatCurrencyFromCents,\n formatPrice,\n formatDate,\n formatTimestamp,\n truncateId,\n} from './utils/formatters';\n\nexport {\n subscriptionStatusColors,\n subscriptionStatusLabels,\n paymentStatusColors,\n paymentStatusLabels,\n invoiceStatusColors,\n invoiceStatusLabels,\n} from './utils/status';\n\nexport {\n validateSlug,\n validateRequired,\n} from './utils/validators';\n","import type { AdminPlan, AdminPlanCreate, AdminPlanUpdate } from '../types/plan';\nimport type {\n ConnectAccount,\n ConnectAccountLink,\n ConnectLoginLink,\n ConnectTransfer,\n ConnectBalance,\n ConnectAccountsPage,\n ConnectTransfersPage,\n CreateConnectAccountInput,\n CreateOnboardingLinkInput,\n CreateTransferInput,\n} from '../types/connect';\nimport type { AdminSubscription, AdminSubscriptionCreate, AdminSubscriptionStatus } from '../types/subscription';\nimport type { AdminPayment, AdminPaymentRefund, AdminPaymentStatus } from '../types/payment';\nimport type { AdminInvoice } from '../types/invoice';\nimport type { AdminProduct, AdminProductCreate, AdminProductUpdate } from '../types/product';\nimport type { AdminFeature, AdminFeatureCreate, AdminFeatureUpdate, AdminFeatureListResponse, AdminFeatureFilters } from '../types/feature';\nimport type { PaginatedResponse, CursorPaginatedResponse } from '../types/common';\n\n/**\n * A generic fetcher function that consumer projects provide.\n * It handles auth tokens, refresh, and base URL internally.\n */\nexport type Fetcher = <T>(url: string, options?: RequestInit) => Promise<T>;\n\nexport interface BillingAdminClientConfig {\n /** Base path for billing admin API (e.g., '/api/v1/billing-admin') */\n basePath: string;\n /** HTTP fetcher function provided by the host application */\n fetcher: Fetcher;\n}\n\nfunction buildQuery(params: Record<string, string | number | boolean | undefined>): string {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, String(value));\n }\n }\n const query = searchParams.toString();\n return query ? `?${query}` : '';\n}\n\nexport class BillingAdminApiClient {\n private basePath: string;\n private fetcher: Fetcher;\n\n constructor(config: BillingAdminClientConfig) {\n this.basePath = config.basePath;\n this.fetcher = config.fetcher;\n }\n\n private url(path: string): string {\n return `${this.basePath}${path}`;\n }\n\n // --- Plans ---\n\n async getPlans(params?: { is_active?: boolean }): Promise<PaginatedResponse<AdminPlan>> {\n const query = buildQuery({ is_active: params?.is_active });\n return this.fetcher(this.url(`/plans${query}`));\n }\n\n async getPlan(planId: string): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}`));\n }\n\n async createPlan(data: AdminPlanCreate): Promise<AdminPlan> {\n return this.fetcher(this.url('/plans'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updatePlan(planId: string, data: AdminPlanUpdate): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deletePlan(planId: string): Promise<void> {\n return this.fetcher(this.url(`/plans/${planId}`), { method: 'DELETE' });\n }\n\n async syncPlanToStripe(planId: string): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}/sync-stripe`), { method: 'POST' });\n }\n\n // --- Subscriptions ---\n\n async getSubscriptions(params?: {\n status?: AdminSubscriptionStatus;\n search?: string;\n limit?: number;\n offset?: number;\n }): Promise<PaginatedResponse<AdminSubscription>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n limit: params?.limit,\n offset: params?.offset,\n });\n return this.fetcher(this.url(`/subscriptions${query}`));\n }\n\n async getSubscription(subscriptionId: string): Promise<AdminSubscription> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}`));\n }\n\n async cancelSubscription(subscriptionId: string, atPeriodEnd: boolean = true): Promise<AdminSubscription> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}/cancel`), {\n method: 'POST',\n body: JSON.stringify({ at_period_end: atPeriodEnd }),\n });\n }\n\n async createSubscription(data: AdminSubscriptionCreate): Promise<AdminSubscription> {\n return this.fetcher(this.url('/subscriptions'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async changeSubscriptionPlan(subscriptionId: string, newPlanSlug: string): Promise<void> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}/change-plan`), {\n method: 'POST',\n body: JSON.stringify({ new_plan_slug: newPlanSlug }),\n });\n }\n\n // --- Payments ---\n\n async getPayments(params?: {\n status?: AdminPaymentStatus | string;\n search?: string;\n limit?: number;\n starting_after?: string;\n }): Promise<CursorPaginatedResponse<AdminPayment>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n limit: params?.limit,\n starting_after: params?.starting_after,\n });\n return this.fetcher(this.url(`/payments${query}`));\n }\n\n async getPayment(paymentId: string): Promise<AdminPayment> {\n return this.fetcher(this.url(`/payments/${paymentId}`));\n }\n\n async refundPayment(paymentId: string, params?: {\n amount?: number;\n reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer';\n }): Promise<AdminPaymentRefund> {\n return this.fetcher(this.url(`/payments/${paymentId}/refund`), {\n method: 'POST',\n body: JSON.stringify(params || {}),\n });\n }\n\n // --- Invoices ---\n\n async getInvoices(params?: {\n status?: string;\n search?: string;\n store_id?: string;\n limit?: number;\n starting_after?: string;\n }): Promise<CursorPaginatedResponse<AdminInvoice>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n store_id: params?.store_id,\n limit: params?.limit,\n starting_after: params?.starting_after,\n });\n return this.fetcher(this.url(`/invoices${query}`));\n }\n\n async getInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}`));\n }\n\n async sendInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}/send`), { method: 'POST' });\n }\n\n async voidInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}/void`), { method: 'POST' });\n }\n\n // --- Products ---\n\n async getProducts(params?: { is_active?: boolean }): Promise<PaginatedResponse<AdminProduct>> {\n const query = buildQuery({ is_active: params?.is_active });\n return this.fetcher(this.url(`/products${query}`));\n }\n\n async getProduct(productId: string): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}`));\n }\n\n async createProduct(data: AdminProductCreate): Promise<AdminProduct> {\n return this.fetcher(this.url('/products'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updateProduct(productId: string, data: AdminProductUpdate): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deleteProduct(productId: string): Promise<void> {\n return this.fetcher(this.url(`/products/${productId}`), { method: 'DELETE' });\n }\n\n async syncProductToStripe(productId: string): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}/sync-stripe`), { method: 'POST' });\n }\n\n // --- Features ---\n\n async getFeatures(params?: AdminFeatureFilters): Promise<AdminFeatureListResponse> {\n const query = buildQuery({\n available_only: params?.available_only,\n category: params?.category,\n });\n return this.fetcher(this.url(`/features${query}`));\n }\n\n async getAvailableFeatures(category?: string): Promise<AdminFeatureListResponse> {\n const query = buildQuery({ category });\n return this.fetcher(this.url(`/features/available${query}`));\n }\n\n async getFeature(featureId: string): Promise<AdminFeature> {\n return this.fetcher(this.url(`/features/${featureId}`));\n }\n\n async createFeature(data: AdminFeatureCreate): Promise<AdminFeature> {\n return this.fetcher(this.url('/features'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updateFeature(featureId: string, data: AdminFeatureUpdate): Promise<AdminFeature> {\n return this.fetcher(this.url(`/features/${featureId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deleteFeature(featureId: string): Promise<void> {\n return this.fetcher(this.url(`/features/${featureId}`), { method: 'DELETE' });\n }\n\n // --- Client Info ---\n\n async getClientInfo(): Promise<{ client_id: string | null }> {\n return this.fetcher(this.url('/client-info'));\n }\n\n // --- Connect Accounts ---\n\n async getConnectAccounts(params?: {\n limit?: number;\n starting_after?: string;\n }): Promise<ConnectAccountsPage> {\n const query = buildQuery({ limit: params?.limit, starting_after: params?.starting_after });\n return this.fetcher(this.url(`/connect/accounts${query}`));\n }\n\n async getConnectAccount(accountId: string): Promise<ConnectAccount> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}`));\n }\n\n async createConnectAccount(data: CreateConnectAccountInput): Promise<ConnectAccount> {\n return this.fetcher(this.url('/connect/accounts'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async createOnboardingLink(\n accountId: string,\n data: CreateOnboardingLinkInput,\n ): Promise<ConnectAccountLink> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}/onboarding-link`), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async createLoginLink(accountId: string): Promise<ConnectLoginLink> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}/login-link`), {\n method: 'POST',\n });\n }\n\n async getConnectAccountBalance(accountId: string): Promise<ConnectBalance> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}/balance`));\n }\n\n async createTransfer(accountId: string, data: CreateTransferInput): Promise<ConnectTransfer> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}/transfers`), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async listTransfers(\n accountId: string,\n params?: { limit?: number; starting_after?: string },\n ): Promise<ConnectTransfersPage> {\n const query = buildQuery({ limit: params?.limit, starting_after: params?.starting_after });\n return this.fetcher(this.url(`/connect/accounts/${accountId}/transfers${query}`));\n }\n}\n\n/**\n * Factory function to create a BillingAdminApiClient instance.\n */\nexport function createBillingAdminClient(config: BillingAdminClientConfig): BillingAdminApiClient {\n return new BillingAdminApiClient(config);\n}\n","import { createContext, useContext } from 'react';\nimport type { BillingAdminApiClient } from '../api/client';\n\nexport const BillingAdminClientContext = createContext<BillingAdminApiClient | null>(null);\n\nexport function useBillingAdminClient(): BillingAdminApiClient {\n const client = useContext(BillingAdminClientContext);\n if (!client) {\n throw new Error(\n 'useBillingAdminClient must be used within a BillingAdminProvider. ' +\n 'Wrap your component tree with <BillingAdminProvider config={{...}}>.'\n );\n }\n return client;\n}\n","import { useState, useCallback } from 'react';\n\n/**\n * Generic hook for managing dialog state with optional associated data.\n */\nexport function useDialogState<T = undefined>() {\n const [isOpen, setIsOpen] = useState(false);\n const [data, setData] = useState<T | undefined>(undefined);\n\n const open = useCallback((initialData?: T) => {\n setData(initialData);\n setIsOpen(true);\n }, []);\n\n const close = useCallback(() => {\n setIsOpen(false);\n setTimeout(() => setData(undefined), 150);\n }, []);\n\n const toggle = useCallback(() => {\n if (isOpen) {\n close();\n } else {\n open();\n }\n }, [isOpen, open, close]);\n\n return {\n isOpen,\n data,\n open,\n close,\n toggle,\n setData,\n };\n}\n","import { useState, useCallback } from 'react';\n\nexport interface CursorPaginationState {\n cursor: string | undefined;\n goToNext: (lastItemId: string) => void;\n goToFirst: () => void;\n hasCursor: boolean;\n}\n\n/**\n * Hook for managing cursor-based pagination state.\n * Encapsulates the cursor value and navigation callbacks.\n */\nexport function useCursorPagination(): CursorPaginationState {\n const [cursor, setCursor] = useState<string | undefined>();\n\n const goToNext = useCallback((lastItemId: string) => {\n setCursor(lastItemId);\n }, []);\n\n const goToFirst = useCallback(() => {\n setCursor(undefined);\n }, []);\n\n return {\n cursor,\n goToNext,\n goToFirst,\n hasCursor: cursor !== undefined,\n };\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminPlanCreate, AdminPlanUpdate } from '../types/plan';\n\nconst PLANS_KEY = 'billing-admin-plans';\n\nexport function useAdminPlans(params?: { is_active?: boolean }) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PLANS_KEY, params],\n queryFn: () => client.getPlans(params),\n });\n}\n\nexport function useCreatePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminPlanCreate) => client.createPlan(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useUpdatePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminPlanUpdate }) =>\n client.updatePlan(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useDeletePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deletePlan(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useSyncPlanToStripe() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.syncPlanToStripe(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminSubscriptionStatus, AdminSubscriptionCreate } from '../types/subscription';\n\nconst SUBSCRIPTIONS_KEY = 'billing-admin-subscriptions';\n\nexport function useAdminSubscriptions(params?: {\n status?: AdminSubscriptionStatus;\n search?: string;\n limit?: number;\n offset?: number;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [SUBSCRIPTIONS_KEY, params],\n queryFn: () => client.getSubscriptions(params),\n });\n}\n\nexport function useCreateSubscription() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminSubscriptionCreate) => client.createSubscription(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n\nexport function useCancelSubscription() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, atPeriodEnd }: { id: string; atPeriodEnd: boolean }) =>\n client.cancelSubscription(id, atPeriodEnd),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n\nexport function useChangeSubscriptionPlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, newPlanSlug }: { id: string; newPlanSlug: string }) =>\n client.changeSubscriptionPlan(id, newPlanSlug),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\n\nconst PAYMENTS_KEY = 'billing-admin-payments';\n\nexport function useAdminPayments(params?: {\n status?: string;\n search?: string;\n limit?: number;\n starting_after?: string;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PAYMENTS_KEY, params],\n queryFn: () => client.getPayments(params),\n });\n}\n\nexport function useRefundPayment() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, amount, reason }: {\n id: string;\n amount?: number;\n reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer';\n }) => client.refundPayment(id, { amount, reason }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PAYMENTS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\n\nconst INVOICES_KEY = 'billing-admin-invoices';\n\nexport function useAdminInvoices(params?: {\n status?: string;\n search?: string;\n store_id?: string;\n limit?: number;\n starting_after?: string;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [INVOICES_KEY, params],\n queryFn: () => client.getInvoices(params),\n });\n}\n\nexport function useSendInvoice() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.sendInvoice(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });\n },\n });\n}\n\nexport function useVoidInvoice() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.voidInvoice(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminProductCreate, AdminProductUpdate } from '../types/product';\n\nconst PRODUCTS_KEY = 'billing-admin-products';\n\nexport function useAdminProducts(params?: { is_active?: boolean }) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PRODUCTS_KEY, params],\n queryFn: () => client.getProducts(params),\n });\n}\n\nexport function useCreateProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminProductCreate) => client.createProduct(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useUpdateProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminProductUpdate }) =>\n client.updateProduct(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useDeleteProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deleteProduct(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useSyncProductToStripe() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.syncProductToStripe(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminFeatureFilters, AdminFeatureCreate, AdminFeatureUpdate } from '../types/feature';\n\nexport function useAdminFeatures(params?: AdminFeatureFilters) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: ['billing-admin', 'features', params],\n queryFn: () => client.getFeatures(params),\n });\n}\n\nexport function useAvailableFeatures(category?: string) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: ['billing-admin', 'features', 'available', category],\n queryFn: () => client.getAvailableFeatures(category),\n });\n}\n\nexport function useCreateFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminFeatureCreate) => client.createFeature(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n\nexport function useUpdateFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminFeatureUpdate }) => client.updateFeature(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n\nexport function useDeleteFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deleteFeature(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n","/**\n * Format a currency amount using Intl.NumberFormat.\n */\nexport function formatCurrency(amount: number, currency: string = 'EUR', locale: string = 'it-IT'): string {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency.toUpperCase(),\n }).format(amount);\n}\n\n/**\n * Format amount in cents to currency string.\n */\nexport function formatCurrencyFromCents(amountCents: number, currency: string = 'EUR', locale: string = 'it-IT'): string {\n return formatCurrency(amountCents / 100, currency, locale);\n}\n\n/**\n * Format a price, returning \"Contattaci\" for null values.\n */\nexport function formatPrice(price: number | null, currency: string = 'EUR', locale: string = 'it-IT'): string {\n if (price === null) return 'Contattaci';\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency.toUpperCase(),\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }).format(price);\n}\n\n/**\n * Format a date string or Date object.\n */\nexport function formatDate(date: Date | string | undefined | null, locale: string = 'it-IT'): string {\n if (!date) return 'N/A';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (isNaN(d.getTime())) return 'N/A';\n return new Intl.DateTimeFormat(locale, {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n }).format(d);\n}\n\n/**\n * Format a Unix timestamp (seconds) to date string.\n */\nexport function formatTimestamp(timestamp: number | null, includeTime: boolean = false, locale: string = 'it-IT'): string {\n if (!timestamp) return '-';\n const date = new Date(timestamp * 1000);\n if (includeTime) {\n return date.toLocaleDateString(locale, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n }\n return date.toLocaleDateString(locale, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n });\n}\n\n/**\n * Truncate long IDs for display.\n */\nexport function truncateId(id: string, maxLength: number = 20): string {\n if (id.length <= maxLength) return id;\n return `${id.slice(0, 10)}...${id.slice(-6)}`;\n}\n","import type { AdminSubscriptionStatus } from '../types/subscription';\nimport type { AdminPaymentStatus } from '../types/payment';\nimport type { AdminInvoiceStatus } from '../types/invoice';\n\n// --- Subscription Status ---\n\nexport const subscriptionStatusColors: Record<AdminSubscriptionStatus, string> = {\n active: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n trialing: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n past_due: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n canceled: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n unpaid: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n incomplete: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400',\n};\n\nexport const subscriptionStatusLabels: Record<AdminSubscriptionStatus, string> = {\n active: 'Attivo',\n trialing: 'In Prova',\n past_due: 'Scaduto',\n canceled: 'Cancellato',\n unpaid: 'Non Pagato',\n incomplete: 'Incompleto',\n};\n\n// --- Payment Status ---\n\nexport const paymentStatusColors: Record<AdminPaymentStatus, string> = {\n succeeded: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n pending: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n failed: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n canceled: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n requires_payment_method: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n};\n\nexport const paymentStatusLabels: Record<AdminPaymentStatus, string> = {\n succeeded: 'Completato',\n pending: 'In Attesa',\n failed: 'Fallito',\n canceled: 'Annullato',\n requires_payment_method: 'Richiede Pagamento',\n};\n\n// --- Invoice Status ---\n\nexport const invoiceStatusColors: Record<AdminInvoiceStatus, string> = {\n draft: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n open: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n paid: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n void: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n uncollectible: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n};\n\nexport const invoiceStatusLabels: Record<AdminInvoiceStatus, string> = {\n draft: 'Bozza',\n open: 'Aperta',\n paid: 'Pagata',\n void: 'Annullata',\n uncollectible: 'Non Riscuotibile',\n};\n","/**\n * Validate a plan slug format.\n */\nexport function validateSlug(slug: string): string | null {\n if (!slug.trim()) {\n return 'Lo slug è obbligatorio';\n }\n if (!/^[a-z0-9-]+$/.test(slug)) {\n return 'Lo slug può contenere solo lettere minuscole, numeri e trattini';\n }\n return null;\n}\n\n/**\n * Validate required string field.\n */\nexport function validateRequired(value: string, fieldName: string): string | null {\n if (!value.trim()) {\n return `${fieldName} è obbligatorio`;\n }\n return null;\n}\n"],"mappings":"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","names":["import_react","import_react","import_react_query","import_react_query","import_react_query","import_react_query","import_react_query"]}
|
package/dist/index.mjs
CHANGED
|
@@ -173,6 +173,44 @@ var BillingAdminApiClient = class {
|
|
|
173
173
|
async getClientInfo() {
|
|
174
174
|
return this.fetcher(this.url("/client-info"));
|
|
175
175
|
}
|
|
176
|
+
// --- Connect Accounts ---
|
|
177
|
+
async getConnectAccounts(params) {
|
|
178
|
+
const query = buildQuery({ limit: params?.limit, starting_after: params?.starting_after });
|
|
179
|
+
return this.fetcher(this.url(`/connect/accounts${query}`));
|
|
180
|
+
}
|
|
181
|
+
async getConnectAccount(accountId) {
|
|
182
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}`));
|
|
183
|
+
}
|
|
184
|
+
async createConnectAccount(data) {
|
|
185
|
+
return this.fetcher(this.url("/connect/accounts"), {
|
|
186
|
+
method: "POST",
|
|
187
|
+
body: JSON.stringify(data)
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
async createOnboardingLink(accountId, data) {
|
|
191
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/onboarding-link`), {
|
|
192
|
+
method: "POST",
|
|
193
|
+
body: JSON.stringify(data)
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
async createLoginLink(accountId) {
|
|
197
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/login-link`), {
|
|
198
|
+
method: "POST"
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
async getConnectAccountBalance(accountId) {
|
|
202
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/balance`));
|
|
203
|
+
}
|
|
204
|
+
async createTransfer(accountId, data) {
|
|
205
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/transfers`), {
|
|
206
|
+
method: "POST",
|
|
207
|
+
body: JSON.stringify(data)
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
async listTransfers(accountId, params) {
|
|
211
|
+
const query = buildQuery({ limit: params?.limit, starting_after: params?.starting_after });
|
|
212
|
+
return this.fetcher(this.url(`/connect/accounts/${accountId}/transfers${query}`));
|
|
213
|
+
}
|
|
176
214
|
};
|
|
177
215
|
function createBillingAdminClient(config) {
|
|
178
216
|
return new BillingAdminApiClient(config);
|
|
@@ -221,6 +259,24 @@ function useDialogState() {
|
|
|
221
259
|
};
|
|
222
260
|
}
|
|
223
261
|
|
|
262
|
+
// src/hooks/useCursorPagination.ts
|
|
263
|
+
import { useState as useState2, useCallback as useCallback2 } from "react";
|
|
264
|
+
function useCursorPagination() {
|
|
265
|
+
const [cursor, setCursor] = useState2();
|
|
266
|
+
const goToNext = useCallback2((lastItemId) => {
|
|
267
|
+
setCursor(lastItemId);
|
|
268
|
+
}, []);
|
|
269
|
+
const goToFirst = useCallback2(() => {
|
|
270
|
+
setCursor(void 0);
|
|
271
|
+
}, []);
|
|
272
|
+
return {
|
|
273
|
+
cursor,
|
|
274
|
+
goToNext,
|
|
275
|
+
goToFirst,
|
|
276
|
+
hasCursor: cursor !== void 0
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
|
|
224
280
|
// src/hooks/usePlans.ts
|
|
225
281
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
226
282
|
var PLANS_KEY = "billing-admin-plans";
|
|
@@ -607,6 +663,7 @@ export {
|
|
|
607
663
|
useCreatePlan,
|
|
608
664
|
useCreateProduct,
|
|
609
665
|
useCreateSubscription,
|
|
666
|
+
useCursorPagination,
|
|
610
667
|
useDeleteFeature,
|
|
611
668
|
useDeletePlan,
|
|
612
669
|
useDeleteProduct,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/client.ts","../src/hooks/context.ts","../src/hooks/useDialogState.ts","../src/hooks/usePlans.ts","../src/hooks/useSubscriptions.ts","../src/hooks/usePayments.ts","../src/hooks/useInvoices.ts","../src/hooks/useProducts.ts","../src/hooks/useFeatures.ts","../src/utils/formatters.ts","../src/utils/status.ts","../src/utils/validators.ts"],"sourcesContent":["import type { AdminPlan, AdminPlanCreate, AdminPlanUpdate } from '../types/plan';\nimport type { AdminSubscription, AdminSubscriptionCreate, AdminSubscriptionStatus } from '../types/subscription';\nimport type { AdminPayment, AdminPaymentRefund, AdminPaymentStatus } from '../types/payment';\nimport type { AdminInvoice } from '../types/invoice';\nimport type { AdminProduct, AdminProductCreate, AdminProductUpdate } from '../types/product';\nimport type { AdminFeature, AdminFeatureCreate, AdminFeatureUpdate, AdminFeatureListResponse, AdminFeatureFilters } from '../types/feature';\nimport type { PaginatedResponse, CursorPaginatedResponse } from '../types/common';\n\n/**\n * A generic fetcher function that consumer projects provide.\n * It handles auth tokens, refresh, and base URL internally.\n */\nexport type Fetcher = <T>(url: string, options?: RequestInit) => Promise<T>;\n\nexport interface BillingAdminClientConfig {\n /** Base path for billing admin API (e.g., '/api/v1/billing-admin') */\n basePath: string;\n /** HTTP fetcher function provided by the host application */\n fetcher: Fetcher;\n}\n\nfunction buildQuery(params: Record<string, string | number | boolean | undefined>): string {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, String(value));\n }\n }\n const query = searchParams.toString();\n return query ? `?${query}` : '';\n}\n\nexport class BillingAdminApiClient {\n private basePath: string;\n private fetcher: Fetcher;\n\n constructor(config: BillingAdminClientConfig) {\n this.basePath = config.basePath;\n this.fetcher = config.fetcher;\n }\n\n private url(path: string): string {\n return `${this.basePath}${path}`;\n }\n\n // --- Plans ---\n\n async getPlans(params?: { is_active?: boolean }): Promise<PaginatedResponse<AdminPlan>> {\n const query = buildQuery({ is_active: params?.is_active });\n return this.fetcher(this.url(`/plans${query}`));\n }\n\n async getPlan(planId: string): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}`));\n }\n\n async createPlan(data: AdminPlanCreate): Promise<AdminPlan> {\n return this.fetcher(this.url('/plans'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updatePlan(planId: string, data: AdminPlanUpdate): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deletePlan(planId: string): Promise<void> {\n return this.fetcher(this.url(`/plans/${planId}`), { method: 'DELETE' });\n }\n\n async syncPlanToStripe(planId: string): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}/sync-stripe`), { method: 'POST' });\n }\n\n // --- Subscriptions ---\n\n async getSubscriptions(params?: {\n status?: AdminSubscriptionStatus;\n search?: string;\n limit?: number;\n offset?: number;\n }): Promise<PaginatedResponse<AdminSubscription>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n limit: params?.limit,\n offset: params?.offset,\n });\n return this.fetcher(this.url(`/subscriptions${query}`));\n }\n\n async getSubscription(subscriptionId: string): Promise<AdminSubscription> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}`));\n }\n\n async cancelSubscription(subscriptionId: string, atPeriodEnd: boolean = true): Promise<AdminSubscription> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}/cancel`), {\n method: 'POST',\n body: JSON.stringify({ at_period_end: atPeriodEnd }),\n });\n }\n\n async createSubscription(data: AdminSubscriptionCreate): Promise<AdminSubscription> {\n return this.fetcher(this.url('/subscriptions'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async changeSubscriptionPlan(subscriptionId: string, newPlanSlug: string): Promise<void> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}/change-plan`), {\n method: 'POST',\n body: JSON.stringify({ new_plan_slug: newPlanSlug }),\n });\n }\n\n // --- Payments ---\n\n async getPayments(params?: {\n status?: AdminPaymentStatus | string;\n search?: string;\n limit?: number;\n starting_after?: string;\n }): Promise<CursorPaginatedResponse<AdminPayment>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n limit: params?.limit,\n starting_after: params?.starting_after,\n });\n return this.fetcher(this.url(`/payments${query}`));\n }\n\n async getPayment(paymentId: string): Promise<AdminPayment> {\n return this.fetcher(this.url(`/payments/${paymentId}`));\n }\n\n async refundPayment(paymentId: string, params?: {\n amount?: number;\n reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer';\n }): Promise<AdminPaymentRefund> {\n return this.fetcher(this.url(`/payments/${paymentId}/refund`), {\n method: 'POST',\n body: JSON.stringify(params || {}),\n });\n }\n\n // --- Invoices ---\n\n async getInvoices(params?: {\n status?: string;\n search?: string;\n store_id?: string;\n limit?: number;\n starting_after?: string;\n }): Promise<CursorPaginatedResponse<AdminInvoice>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n store_id: params?.store_id,\n limit: params?.limit,\n starting_after: params?.starting_after,\n });\n return this.fetcher(this.url(`/invoices${query}`));\n }\n\n async getInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}`));\n }\n\n async sendInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}/send`), { method: 'POST' });\n }\n\n async voidInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}/void`), { method: 'POST' });\n }\n\n // --- Products ---\n\n async getProducts(params?: { is_active?: boolean }): Promise<PaginatedResponse<AdminProduct>> {\n const query = buildQuery({ is_active: params?.is_active });\n return this.fetcher(this.url(`/products${query}`));\n }\n\n async getProduct(productId: string): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}`));\n }\n\n async createProduct(data: AdminProductCreate): Promise<AdminProduct> {\n return this.fetcher(this.url('/products'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updateProduct(productId: string, data: AdminProductUpdate): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deleteProduct(productId: string): Promise<void> {\n return this.fetcher(this.url(`/products/${productId}`), { method: 'DELETE' });\n }\n\n async syncProductToStripe(productId: string): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}/sync-stripe`), { method: 'POST' });\n }\n\n // --- Features ---\n\n async getFeatures(params?: AdminFeatureFilters): Promise<AdminFeatureListResponse> {\n const query = buildQuery({\n available_only: params?.available_only,\n category: params?.category,\n });\n return this.fetcher(this.url(`/features${query}`));\n }\n\n async getAvailableFeatures(category?: string): Promise<AdminFeatureListResponse> {\n const query = buildQuery({ category });\n return this.fetcher(this.url(`/features/available${query}`));\n }\n\n async getFeature(featureId: string): Promise<AdminFeature> {\n return this.fetcher(this.url(`/features/${featureId}`));\n }\n\n async createFeature(data: AdminFeatureCreate): Promise<AdminFeature> {\n return this.fetcher(this.url('/features'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updateFeature(featureId: string, data: AdminFeatureUpdate): Promise<AdminFeature> {\n return this.fetcher(this.url(`/features/${featureId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deleteFeature(featureId: string): Promise<void> {\n return this.fetcher(this.url(`/features/${featureId}`), { method: 'DELETE' });\n }\n\n // --- Client Info ---\n\n async getClientInfo(): Promise<{ client_id: string | null }> {\n return this.fetcher(this.url('/client-info'));\n }\n}\n\n/**\n * Factory function to create a BillingAdminApiClient instance.\n */\nexport function createBillingAdminClient(config: BillingAdminClientConfig): BillingAdminApiClient {\n return new BillingAdminApiClient(config);\n}\n","import { createContext, useContext } from 'react';\nimport type { BillingAdminApiClient } from '../api/client';\n\nexport const BillingAdminClientContext = createContext<BillingAdminApiClient | null>(null);\n\nexport function useBillingAdminClient(): BillingAdminApiClient {\n const client = useContext(BillingAdminClientContext);\n if (!client) {\n throw new Error(\n 'useBillingAdminClient must be used within a BillingAdminProvider. ' +\n 'Wrap your component tree with <BillingAdminProvider config={{...}}>.'\n );\n }\n return client;\n}\n","import { useState, useCallback } from 'react';\n\n/**\n * Generic hook for managing dialog state with optional associated data.\n */\nexport function useDialogState<T = undefined>() {\n const [isOpen, setIsOpen] = useState(false);\n const [data, setData] = useState<T | undefined>(undefined);\n\n const open = useCallback((initialData?: T) => {\n setData(initialData);\n setIsOpen(true);\n }, []);\n\n const close = useCallback(() => {\n setIsOpen(false);\n setTimeout(() => setData(undefined), 150);\n }, []);\n\n const toggle = useCallback(() => {\n if (isOpen) {\n close();\n } else {\n open();\n }\n }, [isOpen, open, close]);\n\n return {\n isOpen,\n data,\n open,\n close,\n toggle,\n setData,\n };\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminPlanCreate, AdminPlanUpdate } from '../types/plan';\n\nconst PLANS_KEY = 'billing-admin-plans';\n\nexport function useAdminPlans(params?: { is_active?: boolean }) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PLANS_KEY, params],\n queryFn: () => client.getPlans(params),\n });\n}\n\nexport function useCreatePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminPlanCreate) => client.createPlan(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useUpdatePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminPlanUpdate }) =>\n client.updatePlan(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useDeletePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deletePlan(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useSyncPlanToStripe() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.syncPlanToStripe(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminSubscriptionStatus, AdminSubscriptionCreate } from '../types/subscription';\n\nconst SUBSCRIPTIONS_KEY = 'billing-admin-subscriptions';\n\nexport function useAdminSubscriptions(params?: {\n status?: AdminSubscriptionStatus;\n search?: string;\n limit?: number;\n offset?: number;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [SUBSCRIPTIONS_KEY, params],\n queryFn: () => client.getSubscriptions(params),\n });\n}\n\nexport function useCreateSubscription() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminSubscriptionCreate) => client.createSubscription(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n\nexport function useCancelSubscription() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, atPeriodEnd }: { id: string; atPeriodEnd: boolean }) =>\n client.cancelSubscription(id, atPeriodEnd),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n\nexport function useChangeSubscriptionPlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, newPlanSlug }: { id: string; newPlanSlug: string }) =>\n client.changeSubscriptionPlan(id, newPlanSlug),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\n\nconst PAYMENTS_KEY = 'billing-admin-payments';\n\nexport function useAdminPayments(params?: {\n status?: string;\n search?: string;\n limit?: number;\n starting_after?: string;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PAYMENTS_KEY, params],\n queryFn: () => client.getPayments(params),\n });\n}\n\nexport function useRefundPayment() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, amount, reason }: {\n id: string;\n amount?: number;\n reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer';\n }) => client.refundPayment(id, { amount, reason }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PAYMENTS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\n\nconst INVOICES_KEY = 'billing-admin-invoices';\n\nexport function useAdminInvoices(params?: {\n status?: string;\n search?: string;\n store_id?: string;\n limit?: number;\n starting_after?: string;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [INVOICES_KEY, params],\n queryFn: () => client.getInvoices(params),\n });\n}\n\nexport function useSendInvoice() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.sendInvoice(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });\n },\n });\n}\n\nexport function useVoidInvoice() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.voidInvoice(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminProductCreate, AdminProductUpdate } from '../types/product';\n\nconst PRODUCTS_KEY = 'billing-admin-products';\n\nexport function useAdminProducts(params?: { is_active?: boolean }) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PRODUCTS_KEY, params],\n queryFn: () => client.getProducts(params),\n });\n}\n\nexport function useCreateProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminProductCreate) => client.createProduct(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useUpdateProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminProductUpdate }) =>\n client.updateProduct(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useDeleteProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deleteProduct(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useSyncProductToStripe() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.syncProductToStripe(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminFeatureFilters, AdminFeatureCreate, AdminFeatureUpdate } from '../types/feature';\n\nexport function useAdminFeatures(params?: AdminFeatureFilters) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: ['billing-admin', 'features', params],\n queryFn: () => client.getFeatures(params),\n });\n}\n\nexport function useAvailableFeatures(category?: string) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: ['billing-admin', 'features', 'available', category],\n queryFn: () => client.getAvailableFeatures(category),\n });\n}\n\nexport function useCreateFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminFeatureCreate) => client.createFeature(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n\nexport function useUpdateFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminFeatureUpdate }) => client.updateFeature(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n\nexport function useDeleteFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deleteFeature(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n","/**\n * Format a currency amount using Intl.NumberFormat.\n */\nexport function formatCurrency(amount: number, currency: string = 'EUR', locale: string = 'it-IT'): string {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency.toUpperCase(),\n }).format(amount);\n}\n\n/**\n * Format amount in cents to currency string.\n */\nexport function formatCurrencyFromCents(amountCents: number, currency: string = 'EUR', locale: string = 'it-IT'): string {\n return formatCurrency(amountCents / 100, currency, locale);\n}\n\n/**\n * Format a price, returning \"Contattaci\" for null values.\n */\nexport function formatPrice(price: number | null, currency: string = 'EUR', locale: string = 'it-IT'): string {\n if (price === null) return 'Contattaci';\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency.toUpperCase(),\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }).format(price);\n}\n\n/**\n * Format a date string or Date object.\n */\nexport function formatDate(date: Date | string | undefined | null, locale: string = 'it-IT'): string {\n if (!date) return 'N/A';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (isNaN(d.getTime())) return 'N/A';\n return new Intl.DateTimeFormat(locale, {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n }).format(d);\n}\n\n/**\n * Format a Unix timestamp (seconds) to date string.\n */\nexport function formatTimestamp(timestamp: number | null, includeTime: boolean = false, locale: string = 'it-IT'): string {\n if (!timestamp) return '-';\n const date = new Date(timestamp * 1000);\n if (includeTime) {\n return date.toLocaleDateString(locale, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n }\n return date.toLocaleDateString(locale, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n });\n}\n\n/**\n * Truncate long IDs for display.\n */\nexport function truncateId(id: string, maxLength: number = 20): string {\n if (id.length <= maxLength) return id;\n return `${id.slice(0, 10)}...${id.slice(-6)}`;\n}\n","import type { AdminSubscriptionStatus } from '../types/subscription';\nimport type { AdminPaymentStatus } from '../types/payment';\nimport type { AdminInvoiceStatus } from '../types/invoice';\n\n// --- Subscription Status ---\n\nexport const subscriptionStatusColors: Record<AdminSubscriptionStatus, string> = {\n active: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n trialing: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n past_due: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n canceled: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n unpaid: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n incomplete: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400',\n};\n\nexport const subscriptionStatusLabels: Record<AdminSubscriptionStatus, string> = {\n active: 'Attivo',\n trialing: 'In Prova',\n past_due: 'Scaduto',\n canceled: 'Cancellato',\n unpaid: 'Non Pagato',\n incomplete: 'Incompleto',\n};\n\n// --- Payment Status ---\n\nexport const paymentStatusColors: Record<AdminPaymentStatus, string> = {\n succeeded: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n pending: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n failed: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n canceled: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n requires_payment_method: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n};\n\nexport const paymentStatusLabels: Record<AdminPaymentStatus, string> = {\n succeeded: 'Completato',\n pending: 'In Attesa',\n failed: 'Fallito',\n canceled: 'Annullato',\n requires_payment_method: 'Richiede Pagamento',\n};\n\n// --- Invoice Status ---\n\nexport const invoiceStatusColors: Record<AdminInvoiceStatus, string> = {\n draft: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n open: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n paid: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n void: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n uncollectible: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n};\n\nexport const invoiceStatusLabels: Record<AdminInvoiceStatus, string> = {\n draft: 'Bozza',\n open: 'Aperta',\n paid: 'Pagata',\n void: 'Annullata',\n uncollectible: 'Non Riscuotibile',\n};\n","/**\n * Validate a plan slug format.\n */\nexport function validateSlug(slug: string): string | null {\n if (!slug.trim()) {\n return 'Lo slug è obbligatorio';\n }\n if (!/^[a-z0-9-]+$/.test(slug)) {\n return 'Lo slug può contenere solo lettere minuscole, numeri e trattini';\n }\n return null;\n}\n\n/**\n * Validate required string field.\n */\nexport function validateRequired(value: string, fieldName: string): string | null {\n if (!value.trim()) {\n return `${fieldName} è obbligatorio`;\n }\n return null;\n}\n"],"mappings":"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","names":["useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation","useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation","useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation","useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation","useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation"]}
|
|
1
|
+
{"version":3,"sources":["../src/api/client.ts","../src/hooks/context.ts","../src/hooks/useDialogState.ts","../src/hooks/useCursorPagination.ts","../src/hooks/usePlans.ts","../src/hooks/useSubscriptions.ts","../src/hooks/usePayments.ts","../src/hooks/useInvoices.ts","../src/hooks/useProducts.ts","../src/hooks/useFeatures.ts","../src/utils/formatters.ts","../src/utils/status.ts","../src/utils/validators.ts"],"sourcesContent":["import type { AdminPlan, AdminPlanCreate, AdminPlanUpdate } from '../types/plan';\nimport type {\n ConnectAccount,\n ConnectAccountLink,\n ConnectLoginLink,\n ConnectTransfer,\n ConnectBalance,\n ConnectAccountsPage,\n ConnectTransfersPage,\n CreateConnectAccountInput,\n CreateOnboardingLinkInput,\n CreateTransferInput,\n} from '../types/connect';\nimport type { AdminSubscription, AdminSubscriptionCreate, AdminSubscriptionStatus } from '../types/subscription';\nimport type { AdminPayment, AdminPaymentRefund, AdminPaymentStatus } from '../types/payment';\nimport type { AdminInvoice } from '../types/invoice';\nimport type { AdminProduct, AdminProductCreate, AdminProductUpdate } from '../types/product';\nimport type { AdminFeature, AdminFeatureCreate, AdminFeatureUpdate, AdminFeatureListResponse, AdminFeatureFilters } from '../types/feature';\nimport type { PaginatedResponse, CursorPaginatedResponse } from '../types/common';\n\n/**\n * A generic fetcher function that consumer projects provide.\n * It handles auth tokens, refresh, and base URL internally.\n */\nexport type Fetcher = <T>(url: string, options?: RequestInit) => Promise<T>;\n\nexport interface BillingAdminClientConfig {\n /** Base path for billing admin API (e.g., '/api/v1/billing-admin') */\n basePath: string;\n /** HTTP fetcher function provided by the host application */\n fetcher: Fetcher;\n}\n\nfunction buildQuery(params: Record<string, string | number | boolean | undefined>): string {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, String(value));\n }\n }\n const query = searchParams.toString();\n return query ? `?${query}` : '';\n}\n\nexport class BillingAdminApiClient {\n private basePath: string;\n private fetcher: Fetcher;\n\n constructor(config: BillingAdminClientConfig) {\n this.basePath = config.basePath;\n this.fetcher = config.fetcher;\n }\n\n private url(path: string): string {\n return `${this.basePath}${path}`;\n }\n\n // --- Plans ---\n\n async getPlans(params?: { is_active?: boolean }): Promise<PaginatedResponse<AdminPlan>> {\n const query = buildQuery({ is_active: params?.is_active });\n return this.fetcher(this.url(`/plans${query}`));\n }\n\n async getPlan(planId: string): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}`));\n }\n\n async createPlan(data: AdminPlanCreate): Promise<AdminPlan> {\n return this.fetcher(this.url('/plans'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updatePlan(planId: string, data: AdminPlanUpdate): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deletePlan(planId: string): Promise<void> {\n return this.fetcher(this.url(`/plans/${planId}`), { method: 'DELETE' });\n }\n\n async syncPlanToStripe(planId: string): Promise<AdminPlan> {\n return this.fetcher(this.url(`/plans/${planId}/sync-stripe`), { method: 'POST' });\n }\n\n // --- Subscriptions ---\n\n async getSubscriptions(params?: {\n status?: AdminSubscriptionStatus;\n search?: string;\n limit?: number;\n offset?: number;\n }): Promise<PaginatedResponse<AdminSubscription>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n limit: params?.limit,\n offset: params?.offset,\n });\n return this.fetcher(this.url(`/subscriptions${query}`));\n }\n\n async getSubscription(subscriptionId: string): Promise<AdminSubscription> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}`));\n }\n\n async cancelSubscription(subscriptionId: string, atPeriodEnd: boolean = true): Promise<AdminSubscription> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}/cancel`), {\n method: 'POST',\n body: JSON.stringify({ at_period_end: atPeriodEnd }),\n });\n }\n\n async createSubscription(data: AdminSubscriptionCreate): Promise<AdminSubscription> {\n return this.fetcher(this.url('/subscriptions'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async changeSubscriptionPlan(subscriptionId: string, newPlanSlug: string): Promise<void> {\n return this.fetcher(this.url(`/subscriptions/${subscriptionId}/change-plan`), {\n method: 'POST',\n body: JSON.stringify({ new_plan_slug: newPlanSlug }),\n });\n }\n\n // --- Payments ---\n\n async getPayments(params?: {\n status?: AdminPaymentStatus | string;\n search?: string;\n limit?: number;\n starting_after?: string;\n }): Promise<CursorPaginatedResponse<AdminPayment>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n limit: params?.limit,\n starting_after: params?.starting_after,\n });\n return this.fetcher(this.url(`/payments${query}`));\n }\n\n async getPayment(paymentId: string): Promise<AdminPayment> {\n return this.fetcher(this.url(`/payments/${paymentId}`));\n }\n\n async refundPayment(paymentId: string, params?: {\n amount?: number;\n reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer';\n }): Promise<AdminPaymentRefund> {\n return this.fetcher(this.url(`/payments/${paymentId}/refund`), {\n method: 'POST',\n body: JSON.stringify(params || {}),\n });\n }\n\n // --- Invoices ---\n\n async getInvoices(params?: {\n status?: string;\n search?: string;\n store_id?: string;\n limit?: number;\n starting_after?: string;\n }): Promise<CursorPaginatedResponse<AdminInvoice>> {\n const query = buildQuery({\n status: params?.status,\n search: params?.search,\n store_id: params?.store_id,\n limit: params?.limit,\n starting_after: params?.starting_after,\n });\n return this.fetcher(this.url(`/invoices${query}`));\n }\n\n async getInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}`));\n }\n\n async sendInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}/send`), { method: 'POST' });\n }\n\n async voidInvoice(invoiceId: string): Promise<AdminInvoice> {\n return this.fetcher(this.url(`/invoices/${invoiceId}/void`), { method: 'POST' });\n }\n\n // --- Products ---\n\n async getProducts(params?: { is_active?: boolean }): Promise<PaginatedResponse<AdminProduct>> {\n const query = buildQuery({ is_active: params?.is_active });\n return this.fetcher(this.url(`/products${query}`));\n }\n\n async getProduct(productId: string): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}`));\n }\n\n async createProduct(data: AdminProductCreate): Promise<AdminProduct> {\n return this.fetcher(this.url('/products'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updateProduct(productId: string, data: AdminProductUpdate): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deleteProduct(productId: string): Promise<void> {\n return this.fetcher(this.url(`/products/${productId}`), { method: 'DELETE' });\n }\n\n async syncProductToStripe(productId: string): Promise<AdminProduct> {\n return this.fetcher(this.url(`/products/${productId}/sync-stripe`), { method: 'POST' });\n }\n\n // --- Features ---\n\n async getFeatures(params?: AdminFeatureFilters): Promise<AdminFeatureListResponse> {\n const query = buildQuery({\n available_only: params?.available_only,\n category: params?.category,\n });\n return this.fetcher(this.url(`/features${query}`));\n }\n\n async getAvailableFeatures(category?: string): Promise<AdminFeatureListResponse> {\n const query = buildQuery({ category });\n return this.fetcher(this.url(`/features/available${query}`));\n }\n\n async getFeature(featureId: string): Promise<AdminFeature> {\n return this.fetcher(this.url(`/features/${featureId}`));\n }\n\n async createFeature(data: AdminFeatureCreate): Promise<AdminFeature> {\n return this.fetcher(this.url('/features'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async updateFeature(featureId: string, data: AdminFeatureUpdate): Promise<AdminFeature> {\n return this.fetcher(this.url(`/features/${featureId}`), {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async deleteFeature(featureId: string): Promise<void> {\n return this.fetcher(this.url(`/features/${featureId}`), { method: 'DELETE' });\n }\n\n // --- Client Info ---\n\n async getClientInfo(): Promise<{ client_id: string | null }> {\n return this.fetcher(this.url('/client-info'));\n }\n\n // --- Connect Accounts ---\n\n async getConnectAccounts(params?: {\n limit?: number;\n starting_after?: string;\n }): Promise<ConnectAccountsPage> {\n const query = buildQuery({ limit: params?.limit, starting_after: params?.starting_after });\n return this.fetcher(this.url(`/connect/accounts${query}`));\n }\n\n async getConnectAccount(accountId: string): Promise<ConnectAccount> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}`));\n }\n\n async createConnectAccount(data: CreateConnectAccountInput): Promise<ConnectAccount> {\n return this.fetcher(this.url('/connect/accounts'), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async createOnboardingLink(\n accountId: string,\n data: CreateOnboardingLinkInput,\n ): Promise<ConnectAccountLink> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}/onboarding-link`), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async createLoginLink(accountId: string): Promise<ConnectLoginLink> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}/login-link`), {\n method: 'POST',\n });\n }\n\n async getConnectAccountBalance(accountId: string): Promise<ConnectBalance> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}/balance`));\n }\n\n async createTransfer(accountId: string, data: CreateTransferInput): Promise<ConnectTransfer> {\n return this.fetcher(this.url(`/connect/accounts/${accountId}/transfers`), {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async listTransfers(\n accountId: string,\n params?: { limit?: number; starting_after?: string },\n ): Promise<ConnectTransfersPage> {\n const query = buildQuery({ limit: params?.limit, starting_after: params?.starting_after });\n return this.fetcher(this.url(`/connect/accounts/${accountId}/transfers${query}`));\n }\n}\n\n/**\n * Factory function to create a BillingAdminApiClient instance.\n */\nexport function createBillingAdminClient(config: BillingAdminClientConfig): BillingAdminApiClient {\n return new BillingAdminApiClient(config);\n}\n","import { createContext, useContext } from 'react';\nimport type { BillingAdminApiClient } from '../api/client';\n\nexport const BillingAdminClientContext = createContext<BillingAdminApiClient | null>(null);\n\nexport function useBillingAdminClient(): BillingAdminApiClient {\n const client = useContext(BillingAdminClientContext);\n if (!client) {\n throw new Error(\n 'useBillingAdminClient must be used within a BillingAdminProvider. ' +\n 'Wrap your component tree with <BillingAdminProvider config={{...}}>.'\n );\n }\n return client;\n}\n","import { useState, useCallback } from 'react';\n\n/**\n * Generic hook for managing dialog state with optional associated data.\n */\nexport function useDialogState<T = undefined>() {\n const [isOpen, setIsOpen] = useState(false);\n const [data, setData] = useState<T | undefined>(undefined);\n\n const open = useCallback((initialData?: T) => {\n setData(initialData);\n setIsOpen(true);\n }, []);\n\n const close = useCallback(() => {\n setIsOpen(false);\n setTimeout(() => setData(undefined), 150);\n }, []);\n\n const toggle = useCallback(() => {\n if (isOpen) {\n close();\n } else {\n open();\n }\n }, [isOpen, open, close]);\n\n return {\n isOpen,\n data,\n open,\n close,\n toggle,\n setData,\n };\n}\n","import { useState, useCallback } from 'react';\n\nexport interface CursorPaginationState {\n cursor: string | undefined;\n goToNext: (lastItemId: string) => void;\n goToFirst: () => void;\n hasCursor: boolean;\n}\n\n/**\n * Hook for managing cursor-based pagination state.\n * Encapsulates the cursor value and navigation callbacks.\n */\nexport function useCursorPagination(): CursorPaginationState {\n const [cursor, setCursor] = useState<string | undefined>();\n\n const goToNext = useCallback((lastItemId: string) => {\n setCursor(lastItemId);\n }, []);\n\n const goToFirst = useCallback(() => {\n setCursor(undefined);\n }, []);\n\n return {\n cursor,\n goToNext,\n goToFirst,\n hasCursor: cursor !== undefined,\n };\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminPlanCreate, AdminPlanUpdate } from '../types/plan';\n\nconst PLANS_KEY = 'billing-admin-plans';\n\nexport function useAdminPlans(params?: { is_active?: boolean }) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PLANS_KEY, params],\n queryFn: () => client.getPlans(params),\n });\n}\n\nexport function useCreatePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminPlanCreate) => client.createPlan(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useUpdatePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminPlanUpdate }) =>\n client.updatePlan(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useDeletePlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deletePlan(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n\nexport function useSyncPlanToStripe() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.syncPlanToStripe(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminSubscriptionStatus, AdminSubscriptionCreate } from '../types/subscription';\n\nconst SUBSCRIPTIONS_KEY = 'billing-admin-subscriptions';\n\nexport function useAdminSubscriptions(params?: {\n status?: AdminSubscriptionStatus;\n search?: string;\n limit?: number;\n offset?: number;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [SUBSCRIPTIONS_KEY, params],\n queryFn: () => client.getSubscriptions(params),\n });\n}\n\nexport function useCreateSubscription() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminSubscriptionCreate) => client.createSubscription(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n\nexport function useCancelSubscription() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, atPeriodEnd }: { id: string; atPeriodEnd: boolean }) =>\n client.cancelSubscription(id, atPeriodEnd),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n\nexport function useChangeSubscriptionPlan() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, newPlanSlug }: { id: string; newPlanSlug: string }) =>\n client.changeSubscriptionPlan(id, newPlanSlug),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\n\nconst PAYMENTS_KEY = 'billing-admin-payments';\n\nexport function useAdminPayments(params?: {\n status?: string;\n search?: string;\n limit?: number;\n starting_after?: string;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PAYMENTS_KEY, params],\n queryFn: () => client.getPayments(params),\n });\n}\n\nexport function useRefundPayment() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, amount, reason }: {\n id: string;\n amount?: number;\n reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer';\n }) => client.refundPayment(id, { amount, reason }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PAYMENTS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\n\nconst INVOICES_KEY = 'billing-admin-invoices';\n\nexport function useAdminInvoices(params?: {\n status?: string;\n search?: string;\n store_id?: string;\n limit?: number;\n starting_after?: string;\n}) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [INVOICES_KEY, params],\n queryFn: () => client.getInvoices(params),\n });\n}\n\nexport function useSendInvoice() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.sendInvoice(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });\n },\n });\n}\n\nexport function useVoidInvoice() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.voidInvoice(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminProductCreate, AdminProductUpdate } from '../types/product';\n\nconst PRODUCTS_KEY = 'billing-admin-products';\n\nexport function useAdminProducts(params?: { is_active?: boolean }) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: [PRODUCTS_KEY, params],\n queryFn: () => client.getProducts(params),\n });\n}\n\nexport function useCreateProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminProductCreate) => client.createProduct(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useUpdateProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminProductUpdate }) =>\n client.updateProduct(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useDeleteProduct() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deleteProduct(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n\nexport function useSyncProductToStripe() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.syncProductToStripe(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });\n },\n });\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useBillingAdminClient } from './context';\nimport type { AdminFeatureFilters, AdminFeatureCreate, AdminFeatureUpdate } from '../types/feature';\n\nexport function useAdminFeatures(params?: AdminFeatureFilters) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: ['billing-admin', 'features', params],\n queryFn: () => client.getFeatures(params),\n });\n}\n\nexport function useAvailableFeatures(category?: string) {\n const client = useBillingAdminClient();\n return useQuery({\n queryKey: ['billing-admin', 'features', 'available', category],\n queryFn: () => client.getAvailableFeatures(category),\n });\n}\n\nexport function useCreateFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: AdminFeatureCreate) => client.createFeature(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n\nexport function useUpdateFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data }: { id: string; data: AdminFeatureUpdate }) => client.updateFeature(id, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n\nexport function useDeleteFeature() {\n const client = useBillingAdminClient();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => client.deleteFeature(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['billing-admin', 'features'] });\n },\n });\n}\n","/**\n * Format a currency amount using Intl.NumberFormat.\n */\nexport function formatCurrency(amount: number, currency: string = 'EUR', locale: string = 'it-IT'): string {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency.toUpperCase(),\n }).format(amount);\n}\n\n/**\n * Format amount in cents to currency string.\n */\nexport function formatCurrencyFromCents(amountCents: number, currency: string = 'EUR', locale: string = 'it-IT'): string {\n return formatCurrency(amountCents / 100, currency, locale);\n}\n\n/**\n * Format a price, returning \"Contattaci\" for null values.\n */\nexport function formatPrice(price: number | null, currency: string = 'EUR', locale: string = 'it-IT'): string {\n if (price === null) return 'Contattaci';\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency.toUpperCase(),\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }).format(price);\n}\n\n/**\n * Format a date string or Date object.\n */\nexport function formatDate(date: Date | string | undefined | null, locale: string = 'it-IT'): string {\n if (!date) return 'N/A';\n const d = typeof date === 'string' ? new Date(date) : date;\n if (isNaN(d.getTime())) return 'N/A';\n return new Intl.DateTimeFormat(locale, {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n }).format(d);\n}\n\n/**\n * Format a Unix timestamp (seconds) to date string.\n */\nexport function formatTimestamp(timestamp: number | null, includeTime: boolean = false, locale: string = 'it-IT'): string {\n if (!timestamp) return '-';\n const date = new Date(timestamp * 1000);\n if (includeTime) {\n return date.toLocaleDateString(locale, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n }\n return date.toLocaleDateString(locale, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n });\n}\n\n/**\n * Truncate long IDs for display.\n */\nexport function truncateId(id: string, maxLength: number = 20): string {\n if (id.length <= maxLength) return id;\n return `${id.slice(0, 10)}...${id.slice(-6)}`;\n}\n","import type { AdminSubscriptionStatus } from '../types/subscription';\nimport type { AdminPaymentStatus } from '../types/payment';\nimport type { AdminInvoiceStatus } from '../types/invoice';\n\n// --- Subscription Status ---\n\nexport const subscriptionStatusColors: Record<AdminSubscriptionStatus, string> = {\n active: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n trialing: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n past_due: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n canceled: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n unpaid: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n incomplete: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400',\n};\n\nexport const subscriptionStatusLabels: Record<AdminSubscriptionStatus, string> = {\n active: 'Attivo',\n trialing: 'In Prova',\n past_due: 'Scaduto',\n canceled: 'Cancellato',\n unpaid: 'Non Pagato',\n incomplete: 'Incompleto',\n};\n\n// --- Payment Status ---\n\nexport const paymentStatusColors: Record<AdminPaymentStatus, string> = {\n succeeded: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n pending: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n failed: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n canceled: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n requires_payment_method: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n};\n\nexport const paymentStatusLabels: Record<AdminPaymentStatus, string> = {\n succeeded: 'Completato',\n pending: 'In Attesa',\n failed: 'Fallito',\n canceled: 'Annullato',\n requires_payment_method: 'Richiede Pagamento',\n};\n\n// --- Invoice Status ---\n\nexport const invoiceStatusColors: Record<AdminInvoiceStatus, string> = {\n draft: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',\n open: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n paid: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n void: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n uncollectible: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n};\n\nexport const invoiceStatusLabels: Record<AdminInvoiceStatus, string> = {\n draft: 'Bozza',\n open: 'Aperta',\n paid: 'Pagata',\n void: 'Annullata',\n uncollectible: 'Non Riscuotibile',\n};\n","/**\n * Validate a plan slug format.\n */\nexport function validateSlug(slug: string): string | null {\n if (!slug.trim()) {\n return 'Lo slug è obbligatorio';\n }\n if (!/^[a-z0-9-]+$/.test(slug)) {\n return 'Lo slug può contenere solo lettere minuscole, numeri e trattini';\n }\n return null;\n}\n\n/**\n * Validate required string field.\n */\nexport function validateRequired(value: string, fieldName: string): string | null {\n if (!value.trim()) {\n return `${fieldName} è obbligatorio`;\n }\n return null;\n}\n"],"mappings":"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","names":["useState","useCallback","useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation","useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation","useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation","useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation","useQuery","useMutation","useQueryClient","useQuery","useQueryClient","useMutation"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@growflowstudio/growflowbilling-admin-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Headless billing admin core - types, API client, React Query hooks, and utilities for GrowFlow Billing",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|