@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 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,
@@ -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.0.0",
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",