@carlonicora/nextjs-jsonapi 5.5.0 → 5.7.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.
Files changed (152) hide show
  1. package/dist/{BlockNoteEditor-GVQCKRMU.mjs → BlockNoteEditor-R3WXUFHX.mjs} +4 -4
  2. package/dist/{BlockNoteEditor-THBJH2UR.js → BlockNoteEditor-ZHXXFWUJ.js} +19 -19
  3. package/dist/{BlockNoteEditor-THBJH2UR.js.map → BlockNoteEditor-ZHXXFWUJ.js.map} +1 -1
  4. package/dist/{BlockNoteViewer-U6E3DS4F.mjs → BlockNoteViewer-BVVN6D3T.mjs} +2 -2
  5. package/dist/{BlockNoteViewer-VZOVKTFO.js → BlockNoteViewer-SD3ZFIXD.js} +3 -3
  6. package/dist/{BlockNoteViewer-VZOVKTFO.js.map → BlockNoteViewer-SD3ZFIXD.js.map} +1 -1
  7. package/dist/billing/index.d.mts +197 -46
  8. package/dist/billing/index.d.ts +197 -46
  9. package/dist/billing/index.js +1166 -589
  10. package/dist/billing/index.js.map +1 -1
  11. package/dist/billing/index.mjs +803 -226
  12. package/dist/billing/index.mjs.map +1 -1
  13. package/dist/{chunk-WPYT4UKJ.js → chunk-2TXE57LE.js} +3 -3
  14. package/dist/{chunk-WPYT4UKJ.js.map → chunk-2TXE57LE.js.map} +1 -1
  15. package/dist/{chunk-G6UE6MEP.js → chunk-5TH2DSAH.js} +901 -204
  16. package/dist/chunk-5TH2DSAH.js.map +1 -0
  17. package/dist/{chunk-X5WIUUNG.mjs → chunk-CFB6FHIY.mjs} +3342 -2377
  18. package/dist/chunk-CFB6FHIY.mjs.map +1 -0
  19. package/dist/{chunk-VC5A3AUZ.mjs → chunk-FK26NX3S.mjs} +701 -4
  20. package/dist/chunk-FK26NX3S.mjs.map +1 -0
  21. package/dist/{chunk-YDYVJM4I.js → chunk-IJME5SAM.js} +4 -4
  22. package/dist/{chunk-YDYVJM4I.js.map → chunk-IJME5SAM.js.map} +1 -1
  23. package/dist/{chunk-W7F5BDSV.mjs → chunk-OKCV4GPJ.mjs} +2 -2
  24. package/dist/{chunk-3CGROPF3.mjs → chunk-RGQYFSJF.mjs} +2 -2
  25. package/dist/{chunk-6SQYXUVP.mjs → chunk-WCHLCOZG.mjs} +2 -2
  26. package/dist/{chunk-S4YJ5WCW.js → chunk-XOSC3FFP.js} +8 -8
  27. package/dist/{chunk-S4YJ5WCW.js.map → chunk-XOSC3FFP.js.map} +1 -1
  28. package/dist/{chunk-TY5FYP3G.js → chunk-ZCOPOO7T.js} +2024 -1059
  29. package/dist/chunk-ZCOPOO7T.js.map +1 -0
  30. package/dist/client/index.js +4 -4
  31. package/dist/client/index.mjs +3 -3
  32. package/dist/components/index.js +4 -4
  33. package/dist/components/index.mjs +3 -3
  34. package/dist/contexts/index.js +4 -4
  35. package/dist/contexts/index.mjs +3 -3
  36. package/dist/core/index.d.mts +248 -3
  37. package/dist/core/index.d.ts +248 -3
  38. package/dist/core/index.js +42 -2
  39. package/dist/core/index.js.map +1 -1
  40. package/dist/core/index.mjs +41 -1
  41. package/dist/{stripe-promotion-code.interface-ClZ7DxS9.d.mts → currency-DT_dveBx.d.mts} +137 -1
  42. package/dist/{stripe-promotion-code.interface-C3qqh3mi.d.ts → currency-pK9eRYRC.d.ts} +137 -1
  43. package/dist/email-automations/index.js +92 -92
  44. package/dist/email-automations/index.mjs +3 -3
  45. package/dist/features/analytics/index.js +121 -121
  46. package/dist/features/analytics/index.mjs +4 -4
  47. package/dist/features/analytics/server.js +4 -4
  48. package/dist/features/analytics/server.mjs +2 -2
  49. package/dist/features/blog/index.js +150 -150
  50. package/dist/features/blog/index.mjs +3 -3
  51. package/dist/features/blog/server.js +16 -16
  52. package/dist/features/blog/server.mjs +1 -1
  53. package/dist/features/help/index.js +37 -37
  54. package/dist/features/help/index.mjs +3 -3
  55. package/dist/features/tokenusage/index.js +124 -124
  56. package/dist/features/tokenusage/index.mjs +4 -4
  57. package/dist/index.d.mts +2 -2
  58. package/dist/index.d.ts +2 -2
  59. package/dist/index.js +43 -3
  60. package/dist/index.js.map +1 -1
  61. package/dist/index.mjs +42 -2
  62. package/dist/server/index.js +3 -3
  63. package/dist/server/index.mjs +2 -2
  64. package/messages/en.json +125 -3
  65. package/messages/it.json +125 -3
  66. package/package.json +1 -1
  67. package/scripts/validate-messages.mjs +1 -0
  68. package/src/billing/index.ts +1 -0
  69. package/src/client/index.ts +4 -0
  70. package/src/core/index.ts +4 -0
  71. package/src/core/registry/ModuleRegistry.ts +3 -0
  72. package/src/features/billing/components/cards/InvoicesSummaryCard.tsx +3 -2
  73. package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +4 -3
  74. package/src/features/billing/components/containers/BillingDashboardContainer.tsx +22 -5
  75. package/src/features/billing/components/utils/__tests__/discount.spec.ts +59 -0
  76. package/src/features/billing/components/utils/__tests__/url.spec.ts +32 -0
  77. package/src/features/billing/components/utils/discount.ts +38 -0
  78. package/src/features/billing/components/utils/index.ts +2 -0
  79. package/src/features/billing/components/utils/url.ts +12 -0
  80. package/src/features/billing/contexts/CouponContext.tsx +209 -0
  81. package/src/features/billing/contexts/index.ts +1 -0
  82. package/src/features/billing/i18n-keys.ts +79 -0
  83. package/src/features/billing/stripe-coupon/components/containers/CouponContainer.tsx +38 -0
  84. package/src/features/billing/stripe-coupon/components/containers/index.ts +1 -0
  85. package/src/features/billing/stripe-coupon/components/details/CouponDetails.tsx +72 -0
  86. package/src/features/billing/stripe-coupon/components/details/index.ts +1 -0
  87. package/src/features/billing/stripe-coupon/components/forms/CouponCodeEditor.tsx +80 -0
  88. package/src/features/billing/stripe-coupon/components/forms/CouponCodeFields.tsx +214 -0
  89. package/src/features/billing/stripe-coupon/components/forms/CouponEditor.tsx +425 -0
  90. package/src/features/billing/stripe-coupon/components/forms/CouponRefresher.tsx +45 -0
  91. package/src/features/billing/stripe-coupon/components/forms/index.ts +6 -0
  92. package/src/features/billing/stripe-coupon/components/index.ts +5 -0
  93. package/src/features/billing/stripe-coupon/components/lists/CouponCodesList.tsx +61 -0
  94. package/src/features/billing/stripe-coupon/components/lists/CouponsList.tsx +67 -0
  95. package/src/features/billing/stripe-coupon/components/lists/index.ts +2 -0
  96. package/src/features/billing/stripe-coupon/components/widgets/CouponCodeActions.tsx +81 -0
  97. package/src/features/billing/stripe-coupon/components/widgets/index.ts +1 -0
  98. package/src/features/billing/stripe-coupon/data/__tests__/stripe-coupon-models.spec.ts +114 -0
  99. package/src/features/billing/stripe-coupon/data/index.ts +10 -0
  100. package/src/features/billing/stripe-coupon/data/stripe-coupon-code.fields.ts +8 -0
  101. package/src/features/billing/stripe-coupon/data/stripe-coupon-code.interface.ts +44 -0
  102. package/src/features/billing/stripe-coupon/data/stripe-coupon-code.service.ts +92 -0
  103. package/src/features/billing/stripe-coupon/data/stripe-coupon-code.ts +132 -0
  104. package/src/features/billing/stripe-coupon/data/stripe-coupon-offer.interface.ts +17 -0
  105. package/src/features/billing/stripe-coupon/data/stripe-coupon-offer.ts +70 -0
  106. package/src/features/billing/stripe-coupon/data/stripe-coupon.fields.ts +7 -0
  107. package/src/features/billing/stripe-coupon/data/stripe-coupon.interface.ts +55 -0
  108. package/src/features/billing/stripe-coupon/data/stripe-coupon.service.ts +93 -0
  109. package/src/features/billing/stripe-coupon/data/stripe-coupon.ts +167 -0
  110. package/src/features/billing/stripe-coupon/hooks/useStripeCouponCodeTableStructure.tsx +161 -0
  111. package/src/features/billing/stripe-coupon/hooks/useStripeCouponTableStructure.tsx +113 -0
  112. package/src/features/billing/stripe-coupon/index.ts +5 -0
  113. package/src/features/billing/stripe-coupon/stripe-coupon-code.module.ts +15 -0
  114. package/src/features/billing/stripe-coupon/stripe-coupon-offer.module.ts +10 -0
  115. package/src/features/billing/stripe-coupon/stripe-coupon.module.ts +25 -0
  116. package/src/features/billing/stripe-coupon/utils/__tests__/coupon-places.spec.ts +19 -0
  117. package/src/features/billing/stripe-coupon/utils/__tests__/to-promotion-code-result.spec.ts +41 -0
  118. package/src/features/billing/stripe-coupon/utils/coupon-places.ts +23 -0
  119. package/src/features/billing/stripe-coupon/utils/format-coupon-discount.ts +36 -0
  120. package/src/features/billing/stripe-coupon/utils/index.ts +3 -0
  121. package/src/features/billing/stripe-coupon/utils/to-promotion-code-result.ts +23 -0
  122. package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +24 -8
  123. package/src/features/billing/stripe-product/components/containers/ProductsListContainer.tsx +21 -6
  124. package/src/features/billing/stripe-promotion-code/components/PromoCodeInput.tsx +60 -19
  125. package/src/features/billing/stripe-promotion-code/data/stripe-promotion-code.interface.ts +2 -0
  126. package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +24 -5
  127. package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +21 -2
  128. package/src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx +1 -1
  129. package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +1 -1
  130. package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +60 -49
  131. package/src/features/billing/stripe-subscription/components/wizards/__tests__/review-card.spec.ts +34 -0
  132. package/src/features/billing/stripe-subscription/components/wizards/review-card.ts +24 -0
  133. package/src/features/billing/stripe-subscription/data/__tests__/stripe-subscription.discount.spec.ts +67 -0
  134. package/src/features/billing/stripe-subscription/data/stripe-subscription.interface.ts +14 -0
  135. package/src/features/billing/stripe-subscription/data/stripe-subscription.service.ts +39 -0
  136. package/src/features/billing/stripe-subscription/data/stripe-subscription.ts +21 -0
  137. package/src/features/billing/stripe-subscription/hooks/__tests__/wizard-payment.spec.ts +48 -0
  138. package/src/features/billing/stripe-subscription/hooks/__tests__/wizard-promotion.spec.ts +132 -0
  139. package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +138 -12
  140. package/src/features/billing/stripe-subscription/hooks/wizard-payment.ts +30 -0
  141. package/src/features/billing/stripe-subscription/hooks/wizard-promotion.ts +61 -0
  142. package/src/features/user/contexts/CurrentUserContext.tsx +25 -0
  143. package/src/features/user/contexts/__tests__/CurrentUserContext.spec.tsx +121 -2
  144. package/dist/chunk-G6UE6MEP.js.map +0 -1
  145. package/dist/chunk-TY5FYP3G.js.map +0 -1
  146. package/dist/chunk-VC5A3AUZ.mjs.map +0 -1
  147. package/dist/chunk-X5WIUUNG.mjs.map +0 -1
  148. /package/dist/{BlockNoteEditor-GVQCKRMU.mjs.map → BlockNoteEditor-R3WXUFHX.mjs.map} +0 -0
  149. /package/dist/{BlockNoteViewer-U6E3DS4F.mjs.map → BlockNoteViewer-BVVN6D3T.mjs.map} +0 -0
  150. /package/dist/{chunk-W7F5BDSV.mjs.map → chunk-OKCV4GPJ.mjs.map} +0 -0
  151. /package/dist/{chunk-3CGROPF3.mjs.map → chunk-RGQYFSJF.mjs.map} +0 -0
  152. /package/dist/{chunk-6SQYXUVP.mjs.map → chunk-WCHLCOZG.mjs.map} +0 -0
@@ -1,7 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { j as StripeSubscriptionInterface, P as PaymentMethodInterface, S as StripeCustomerInterface, a as StripeInvoiceInterface, M as MeterInterface, o as MeterSummaryInterface, d as StripePriceInterface, f as StripePriceInput, g as StripeProductInterface, h as StripeProductInput, I as InvoiceStatus, b as ProrationPreviewInterface, i as SubscriptionStatus, q as PromotionCodeValidationResult, n as StripeUsageInterface } from '../stripe-promotion-code.interface-ClZ7DxS9.mjs';
3
+ import { k as StripeSubscriptionInterface, P as PaymentMethodInterface, S as StripeCustomerInterface, a as StripeInvoiceInterface, M as MeterInterface, p as MeterSummaryInterface, F as BillingFormatOptions, r as PromotionCodeValidationResult, u as StripeCouponInterface, x as StripeCouponInput, y as StripeCouponRenameInput, A as StripeCouponCodeInput, z as StripeCouponCodeInterface, B as StripeCouponCodeFlagsInput, d as StripePriceInterface, f as StripePriceInput, g as StripeProductInterface, h as StripeProductInput, I as InvoiceStatus, b as ProrationPreviewInterface, i as SubscriptionStatus, o as StripeUsageInterface } from '../currency-DT_dveBx.mjs';
4
+ export { G as BillingTranslator, D as formatCurrency, E as formatFixed, C as formatInterval } from '../currency-DT_dveBx.mjs';
4
5
  import { J as JsonApiHydratedDataInterface } from '../ApiDataInterface-BcZeXy5X.mjs';
6
+ import { FieldValues, UseFormReturn } from 'react-hook-form';
7
+ import { z } from 'zod';
5
8
  import '../feature.interface-CXb1-vNq.mjs';
6
9
 
7
10
  type SubscriptionSummaryCardProps = {
@@ -61,45 +64,6 @@ declare function StripeProvider({ children }: {
61
64
  }): React.JSX.Element;
62
65
  declare function isStripeConfigured(): boolean;
63
66
 
64
- /** A message translator, as returned by `useTranslations()`. */
65
- type BillingTranslator = (key: string, values?: Record<string, any>) => string;
66
- /**
67
- * What the billing formatters need from the caller's React context. The
68
- * formatters are plain functions and cannot call hooks, so a component reads
69
- * `useI18nLocale()` and `useTranslations()` and passes both here.
70
- *
71
- * Both are optional so existing callers keep their output: without a `locale`
72
- * the formatters use "en-US", without `t` they return the English literals they
73
- * always returned.
74
- */
75
- type BillingFormatOptions = {
76
- /** BCP 47 locale for `Intl` (the app's active locale, from `useI18nLocale()`). */
77
- locale?: string;
78
- /** Translator for the words the formatters emit. */
79
- t?: BillingTranslator;
80
- };
81
-
82
- /**
83
- * Format price recurring interval for display
84
- * @param price - Stripe price object
85
- * @param options - `t` translates the interval words; without it the output is English
86
- * @returns Formatted interval string (e.g., "/month", "/year", "/2 weeks", "one-time")
87
- */
88
- declare function formatInterval(price: StripePriceInterface, options?: BillingFormatOptions): string;
89
- /**
90
- * Format currency amount from cents to localized currency string
91
- * @param amount - Amount in cents
92
- * @param currency - Currency code (e.g., "USD", "EUR", "GBP")
93
- * @param options - `locale` drives number formatting; defaults to "en-US"
94
- * @returns Formatted currency string (e.g., "$9.99", "€9,99")
95
- */
96
- declare function formatCurrency(amount: number | undefined, currency: string, options?: BillingFormatOptions): string;
97
- /**
98
- * `value.toFixed(digits)` with the locale's decimal separator ("12.5" in English,
99
- * "12,5" in Italian). No grouping, so English output matches `toFixed` exactly.
100
- */
101
- declare function formatFixed(value: number, locale: string | undefined, digits: number): string;
102
-
103
67
  /**
104
68
  * Format a date to a localized date string
105
69
  * @param date - Date object or ISO string
@@ -112,6 +76,22 @@ declare function formatDate(date: Date | string | undefined, options?: BillingFo
112
76
  /** The active locale and translator, ready to pass to the billing formatters. */
113
77
  declare function useBillingFormatOptions(): Required<BillingFormatOptions>;
114
78
 
79
+ /** A discount as the billing screens apply it: a percentage, or an amount in minor units. */
80
+ type BillingDiscount = {
81
+ discountType: "percent_off" | "amount_off";
82
+ discountValue: number;
83
+ currency?: string;
84
+ };
85
+ /** The discount a valid promotion code (typed or automatic) gives, or null. */
86
+ declare function promotionCodeDiscount(code: PromotionCodeValidationResult | null | undefined): BillingDiscount | null;
87
+ /** The discount a subscription already carries in Stripe, or null. */
88
+ declare function subscriptionDiscount(subscription: StripeSubscriptionInterface | null | undefined): BillingDiscount | null;
89
+ /**
90
+ * The amount after the discount, in the same minor units; null when there is no
91
+ * discount or nothing to discount. An amount discount never goes below zero.
92
+ */
93
+ declare function applyDiscount(amount: number | undefined, discount: BillingDiscount | null): number | null;
94
+
115
95
  type BillingAlertBannerProps = {
116
96
  subscription: StripeSubscriptionInterface;
117
97
  onUpdatePayment?: () => void;
@@ -119,6 +99,34 @@ type BillingAlertBannerProps = {
119
99
  };
120
100
  declare function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }: BillingAlertBannerProps): React.JSX.Element | null;
121
101
 
102
+ interface CouponContextType {
103
+ coupon: StripeCouponInterface | undefined;
104
+ setCoupon: (value: StripeCouponInterface | undefined) => void;
105
+ reloadCoupon: () => Promise<void>;
106
+ createCoupon: (input: StripeCouponInput) => Promise<StripeCouponInterface>;
107
+ renameCoupon: (input: StripeCouponRenameInput) => Promise<StripeCouponInterface>;
108
+ refreshCounts: (id?: string) => Promise<void>;
109
+ createCode: (input: StripeCouponCodeInput) => Promise<StripeCouponCodeInterface>;
110
+ updateCodeFlags: (input: StripeCouponCodeFlagsInput) => Promise<StripeCouponCodeInterface>;
111
+ /** Bumped by every mutation. Mounted lists re-fetch on it. */
112
+ catalogueVersion: number;
113
+ refreshCatalogue: () => void;
114
+ }
115
+ type CouponProviderProps = {
116
+ children: ReactNode;
117
+ dehydratedCoupon?: JsonApiHydratedDataInterface;
118
+ /**
119
+ * Publish breadcrumbs + title into SharedProvider. Pass `false` when this
120
+ * provider is mounted INSIDE another entity's page (the Codes tab of the
121
+ * products page mounts CouponProvider that way): SharedProvider replaces its
122
+ * value for the subtree rather than merging (SharedContext.tsx:35-37), so a
123
+ * nested provider that publishes chrome would blank the host page's title.
124
+ */
125
+ publishChrome?: boolean;
126
+ };
127
+ declare const CouponProvider: ({ children, dehydratedCoupon, publishChrome }: CouponProviderProps) => React.JSX.Element;
128
+ declare const useCouponContext: () => CouponContextType;
129
+
122
130
  interface PriceContextType {
123
131
  price: StripePriceInterface | undefined;
124
132
  setPrice: (value: StripePriceInterface | undefined) => void;
@@ -202,8 +210,13 @@ type PaymentMethodFormProps = {
202
210
  onSuccess: () => void;
203
211
  onCancel: () => void;
204
212
  isLoading?: boolean;
213
+ /**
214
+ * Always make the new card the customer's default and hide the checkbox. The
215
+ * subscription wizard needs this: the next attempt must charge the card just added.
216
+ */
217
+ alwaysSetDefault?: boolean;
205
218
  };
206
- declare function PaymentMethodForm({ onSuccess, onCancel, isLoading }: PaymentMethodFormProps): React.JSX.Element;
219
+ declare function PaymentMethodForm({ onSuccess, onCancel, isLoading, alwaysSetDefault, }: PaymentMethodFormProps): React.JSX.Element;
207
220
 
208
221
  type PaymentMethodsListProps = {
209
222
  paymentMethods: PaymentMethodInterface[];
@@ -302,15 +315,19 @@ declare function PricesList({ productId, fullWidth }: PricesListProps): React.JS
302
315
  declare function ProductContainer(): React.JSX.Element | null;
303
316
 
304
317
  /**
305
- * Page container for the administrative product list.
318
+ * Page container for the administrative products page: two tabs, Products and
319
+ * Codes, with `sectionKey`s so the URL keeps the tab (`?section=codes`).
306
320
  *
307
321
  * Client component by necessity: `module={Modules.StripeProduct}` is a registry
308
322
  * entry carrying an icon component and methods, which a Server Component cannot
309
323
  * pass across the boundary. Routes mount this container instead — the same
310
324
  * shape as every other list page.
311
325
  *
312
- * No `forceHeader`: ContentListTable draws its own header row with the title
313
- * and the create action, exactly as the company and user list pages do.
326
+ * No `fullWidth`, on the page or the lists: the page keeps its title bar and
327
+ * each ContentListTable keeps its own bordered card in the tab (see ProductContainer). CouponProvider
328
+ * is nested with `publishChrome={false}`: SharedProvider REPLACES its value for
329
+ * the subtree (SharedContext.tsx:35-37), so a nested provider publishing chrome
330
+ * would blank the products page's own title.
314
331
  */
315
332
  declare function ProductsListContainer(): React.JSX.Element;
316
333
 
@@ -350,11 +367,145 @@ type ProductsListProps = {
350
367
  };
351
368
  declare function ProductsList({ fullWidth }?: ProductsListProps): React.JSX.Element;
352
369
 
370
+ declare function CouponContainer(): React.JSX.Element | null;
371
+
372
+ declare function CouponDetails(): React.JSX.Element | null;
373
+
374
+ /**
375
+ * What a number or decimal `<FormInput>` holds: "" until something is typed, a
376
+ * number from `type="number"` (`+""` is 0 when cleared, NaN on garbage), a
377
+ * string from `type="decimal"` (may use a comma as the separator).
378
+ *
379
+ * The schemas below validate this raw value and never transform it, so the
380
+ * form's values have one type before and after validation. The `parse*`
381
+ * functions turn it into the number that is sent, on submit.
382
+ */
383
+ type RawNumber = string | number | null | undefined;
384
+ /**
385
+ * Optional whole number of at least 1. 0, "" and NaN all mean "not set": every
386
+ * limit here has a floor of 1.
387
+ */
388
+ declare function parseOptionalPositiveInt(value: RawNumber): number | undefined;
389
+ /**
390
+ * Optional decimal in MAJOR units. Converted to minor units on submit, exactly
391
+ * as PriceEditor does (`Math.round(value * 100)`).
392
+ */
393
+ declare function parseOptionalDecimal(value: RawNumber): number | undefined;
394
+ declare const optionalPositiveInt: () => z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
395
+ declare const optionalDecimal: () => z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
396
+ /**
397
+ * Optional point in time from `<FormDateTime allowEmpty>`, which writes "" when
398
+ * the value is cleared (FormDateTime.tsx:136, :241).
399
+ */
400
+ declare const optionalDate: () => z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodDate, z.ZodLiteral<"">]>>>;
401
+ /** Mirrors StripeCouponCodePostAttributesDTO. */
402
+ declare const couponCodeSchema: (t: (key: string) => string) => z.ZodObject<{
403
+ code: z.ZodOptional<z.ZodString>;
404
+ firstTimeTransaction: z.ZodBoolean;
405
+ minimumAmount: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
406
+ minimumAmountCurrency: z.ZodString;
407
+ stripeCustomerId: z.ZodOptional<z.ZodString>;
408
+ expiresAt: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodDate, z.ZodLiteral<"">]>>>;
409
+ maxRedemptions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
410
+ automatic: z.ZodBoolean;
411
+ }, z.core.$strip>;
412
+ type CouponCodeFormValues = z.infer<ReturnType<typeof couponCodeSchema>>;
413
+ /**
414
+ * Every text/number input starts as "" (never undefined): FormInput spreads
415
+ * `field.value` onto a Base UI input, and undefined → value flips it from
416
+ * uncontrolled to controlled (console warning). The parse functions map ""
417
+ * to undefined, so empty fields are still sent as absent.
418
+ */
419
+ declare const couponCodeDefaults: () => CouponCodeFormValues;
420
+ /** Form values → the code attributes the models serialise. Unset fields are left out. */
421
+ declare const toCouponCodeInput: (values: CouponCodeFormValues) => Omit<StripeCouponCodeInput, "id" | "couponId">;
422
+ declare const couponCurrencyOptions: {
423
+ id: string;
424
+ text: string;
425
+ }[];
426
+ type CouponCodeFieldsProps<T extends FieldValues> = {
427
+ form: UseFormReturn<T>;
428
+ /** "" for CouponCodeEditor, "firstCode." when nested inside CouponEditor. */
429
+ prefix?: string;
430
+ };
431
+ /** The fields of a customer-facing code, shared by CouponEditor (first code) and CouponCodeEditor. */
432
+ declare function CouponCodeFields<T extends FieldValues>({ form, prefix }: CouponCodeFieldsProps<T>): React.JSX.Element;
433
+
434
+ type CouponRefresherProps = {
435
+ coupon: StripeCouponInterface;
436
+ };
437
+ /**
438
+ * Re-reads the coupon and its codes from Stripe and writes the usage counts to
439
+ * our copy. Counts go stale only for subscriptions made outside our endpoints
440
+ * (the Stripe dashboard); this button fixes that.
441
+ */
442
+ declare function CouponRefresher({ coupon }: CouponRefresherProps): React.JSX.Element;
443
+
444
+ type CouponEditorProps = {
445
+ coupon?: StripeCouponInterface;
446
+ propagateChanges?: (coupon: StripeCouponInterface) => void;
447
+ onSuccess?: () => void | Promise<void>;
448
+ trigger?: ReactNode;
449
+ forceShow?: boolean;
450
+ onClose?: () => void;
451
+ dialogOpen?: boolean;
452
+ onDialogOpenChange?: (open: boolean) => void;
453
+ };
454
+ declare function CouponEditor(props: CouponEditorProps): React.JSX.Element;
455
+
456
+ type CouponCodeEditorProps = {
457
+ couponId: string;
458
+ onSuccess?: () => void | Promise<void>;
459
+ trigger?: ReactNode;
460
+ forceShow?: boolean;
461
+ onClose?: () => void;
462
+ dialogOpen?: boolean;
463
+ onDialogOpenChange?: (open: boolean) => void;
464
+ };
465
+ declare function CouponCodeEditor(props: CouponCodeEditorProps): React.JSX.Element;
466
+
467
+ type CouponsListProps = {
468
+ /**
469
+ * Pass this whenever the list is the page's own content inside a
470
+ * `RoundPageContainer fullWidth`. Without it ContentListTable wraps itself in
471
+ * `rounded-md border`, drawing a second bordered card inside the page's
472
+ * rounded shell.
473
+ */
474
+ fullWidth?: boolean;
475
+ };
476
+ declare function CouponsList({ fullWidth }?: CouponsListProps): React.JSX.Element;
477
+
478
+ type CouponCodesListProps = {
479
+ couponId: string;
480
+ };
481
+ declare function CouponCodesList({ couponId }: CouponCodesListProps): React.JSX.Element;
482
+
483
+ type CouponCodeStatus = "active" | "inactive" | "expired" | "used_up";
484
+
485
+ type CouponCodeActionsProps = {
486
+ code: StripeCouponCodeInterface;
487
+ status: CouponCodeStatus;
488
+ };
489
+ /**
490
+ * Row controls of a code: the "Apply automatically" switch and the deactivate /
491
+ * reactivate button. The button sits behind ConfirmDialog, which is controlled
492
+ * and trigger-less by design — the caller owns the trigger button, so none of
493
+ * Base UI's trigger-composition pitfalls apply (no asChild, no nested <button>).
494
+ */
495
+ declare function CouponCodeActions({ code, status }: CouponCodeActionsProps): React.JSX.Element;
496
+
353
497
  type SubscriptionsContainerProps = {
354
498
  onOpenWizard?: (subscription?: StripeSubscriptionInterface) => void;
355
499
  hasActiveRecurringSubscription?: boolean;
500
+ /**
501
+ * The list a parent already holds (the billing dashboard). When given, the container
502
+ * shows it instead of loading its own, and a change asks the parent to refresh through
503
+ * `onSubscriptionsChange`, so the dialog and the cards behind it never disagree.
504
+ */
505
+ subscriptions?: StripeSubscriptionInterface[];
506
+ onSubscriptionsChange?: () => void;
356
507
  };
357
- declare function SubscriptionsContainer({ onOpenWizard, hasActiveRecurringSubscription }: SubscriptionsContainerProps): React.JSX.Element;
508
+ declare function SubscriptionsContainer({ onOpenWizard, hasActiveRecurringSubscription, subscriptions: parentSubscriptions, onSubscriptionsChange, }: SubscriptionsContainerProps): React.JSX.Element;
358
509
 
359
510
  type SubscriptionDetailsProps = {
360
511
  subscription: StripeSubscriptionInterface;
@@ -525,4 +676,4 @@ type PromoCodeInputProps = {
525
676
  };
526
677
  declare function PromoCodeInput({ appliedCode, isValidating, error, onApply, onRemove, disabled, }: PromoCodeInputProps): React.JSX.Element;
527
678
 
528
- export { BillingAlertBanner, BillingDashboardContainer, BillingDetailModal, type BillingFormatOptions, type BillingInterval, type BillingTranslator, BillingUsageSummaryCard, CancelSubscriptionDialog, CustomerInfoCard, IntervalToggle, type IntervalToggleProps, InvoiceDetails, InvoiceStatusBadge, InvoicesContainer, InvoicesList, InvoicesSummaryCard, PaymentMethodCard, PaymentMethodEditor, PaymentMethodForm, PaymentMethodSummaryCard, PaymentMethodsContainer, PaymentMethodsList, PriceArchiver, PriceContainer, type PriceContextType, PriceDetails, PriceEditor, type PriceEditorProps, PriceProvider, type PriceProviderProps, PricesList, PricingCard, type PricingCardProps, ProductArchiver, ProductContainer, type ProductContextType, ProductDetails, ProductEditor, type ProductEditorProps, ProductPricingList, type ProductPricingListProps, ProductPricingRow, type ProductPricingRowProps, ProductProvider, type ProductProviderProps, ProductsList, ProductsListContainer, PromoCodeInput, ProrationPreview, StripeProvider, SubscriptionConfirmation, SubscriptionDetails, SubscriptionStatusBadge, SubscriptionSummaryCard, SubscriptionWizard, type SubscriptionWizardProps, SubscriptionsContainer, SubscriptionsList, UsageContainer, UsageHistoryTable, UsageSummaryCard, UsageSummaryCards, WizardProgressIndicator, WizardStepPaymentMethod, WizardStepPlanSelection, WizardStepReview, formatCurrency, formatDate, formatFixed, formatInterval, isStripeConfigured, priceLabel, useBillingFormatOptions, usePriceContext, useProductContext };
679
+ export { BillingAlertBanner, BillingDashboardContainer, BillingDetailModal, type BillingDiscount, BillingFormatOptions, type BillingInterval, BillingUsageSummaryCard, CancelSubscriptionDialog, CouponCodeActions, CouponCodeEditor, type CouponCodeEditorProps, CouponCodeFields, type CouponCodeFormValues, CouponCodesList, CouponContainer, type CouponContextType, CouponDetails, CouponEditor, type CouponEditorProps, CouponProvider, type CouponProviderProps, CouponRefresher, CouponsList, CustomerInfoCard, IntervalToggle, type IntervalToggleProps, InvoiceDetails, InvoiceStatusBadge, InvoicesContainer, InvoicesList, InvoicesSummaryCard, PaymentMethodCard, PaymentMethodEditor, PaymentMethodForm, PaymentMethodSummaryCard, PaymentMethodsContainer, PaymentMethodsList, PriceArchiver, PriceContainer, type PriceContextType, PriceDetails, PriceEditor, type PriceEditorProps, PriceProvider, type PriceProviderProps, PricesList, PricingCard, type PricingCardProps, ProductArchiver, ProductContainer, type ProductContextType, ProductDetails, ProductEditor, type ProductEditorProps, ProductPricingList, type ProductPricingListProps, ProductPricingRow, type ProductPricingRowProps, ProductProvider, type ProductProviderProps, ProductsList, ProductsListContainer, PromoCodeInput, ProrationPreview, StripeProvider, SubscriptionConfirmation, SubscriptionDetails, SubscriptionStatusBadge, SubscriptionSummaryCard, SubscriptionWizard, type SubscriptionWizardProps, SubscriptionsContainer, SubscriptionsList, UsageContainer, UsageHistoryTable, UsageSummaryCard, UsageSummaryCards, WizardProgressIndicator, WizardStepPaymentMethod, WizardStepPlanSelection, WizardStepReview, applyDiscount, couponCodeDefaults, couponCodeSchema, couponCurrencyOptions, formatDate, isStripeConfigured, optionalDate, optionalDecimal, optionalPositiveInt, parseOptionalDecimal, parseOptionalPositiveInt, priceLabel, promotionCodeDiscount, subscriptionDiscount, toCouponCodeInput, useBillingFormatOptions, useCouponContext, usePriceContext, useProductContext };
@@ -1,7 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { j as StripeSubscriptionInterface, P as PaymentMethodInterface, S as StripeCustomerInterface, a as StripeInvoiceInterface, M as MeterInterface, o as MeterSummaryInterface, d as StripePriceInterface, f as StripePriceInput, g as StripeProductInterface, h as StripeProductInput, I as InvoiceStatus, b as ProrationPreviewInterface, i as SubscriptionStatus, q as PromotionCodeValidationResult, n as StripeUsageInterface } from '../stripe-promotion-code.interface-C3qqh3mi.js';
3
+ import { k as StripeSubscriptionInterface, P as PaymentMethodInterface, S as StripeCustomerInterface, a as StripeInvoiceInterface, M as MeterInterface, p as MeterSummaryInterface, F as BillingFormatOptions, r as PromotionCodeValidationResult, u as StripeCouponInterface, x as StripeCouponInput, y as StripeCouponRenameInput, A as StripeCouponCodeInput, z as StripeCouponCodeInterface, B as StripeCouponCodeFlagsInput, d as StripePriceInterface, f as StripePriceInput, g as StripeProductInterface, h as StripeProductInput, I as InvoiceStatus, b as ProrationPreviewInterface, i as SubscriptionStatus, o as StripeUsageInterface } from '../currency-pK9eRYRC.js';
4
+ export { G as BillingTranslator, D as formatCurrency, E as formatFixed, C as formatInterval } from '../currency-pK9eRYRC.js';
4
5
  import { J as JsonApiHydratedDataInterface } from '../ApiDataInterface-BcZeXy5X.js';
6
+ import { FieldValues, UseFormReturn } from 'react-hook-form';
7
+ import { z } from 'zod';
5
8
  import '../feature.interface-BO25VLlx.js';
6
9
 
7
10
  type SubscriptionSummaryCardProps = {
@@ -61,45 +64,6 @@ declare function StripeProvider({ children }: {
61
64
  }): React.JSX.Element;
62
65
  declare function isStripeConfigured(): boolean;
63
66
 
64
- /** A message translator, as returned by `useTranslations()`. */
65
- type BillingTranslator = (key: string, values?: Record<string, any>) => string;
66
- /**
67
- * What the billing formatters need from the caller's React context. The
68
- * formatters are plain functions and cannot call hooks, so a component reads
69
- * `useI18nLocale()` and `useTranslations()` and passes both here.
70
- *
71
- * Both are optional so existing callers keep their output: without a `locale`
72
- * the formatters use "en-US", without `t` they return the English literals they
73
- * always returned.
74
- */
75
- type BillingFormatOptions = {
76
- /** BCP 47 locale for `Intl` (the app's active locale, from `useI18nLocale()`). */
77
- locale?: string;
78
- /** Translator for the words the formatters emit. */
79
- t?: BillingTranslator;
80
- };
81
-
82
- /**
83
- * Format price recurring interval for display
84
- * @param price - Stripe price object
85
- * @param options - `t` translates the interval words; without it the output is English
86
- * @returns Formatted interval string (e.g., "/month", "/year", "/2 weeks", "one-time")
87
- */
88
- declare function formatInterval(price: StripePriceInterface, options?: BillingFormatOptions): string;
89
- /**
90
- * Format currency amount from cents to localized currency string
91
- * @param amount - Amount in cents
92
- * @param currency - Currency code (e.g., "USD", "EUR", "GBP")
93
- * @param options - `locale` drives number formatting; defaults to "en-US"
94
- * @returns Formatted currency string (e.g., "$9.99", "€9,99")
95
- */
96
- declare function formatCurrency(amount: number | undefined, currency: string, options?: BillingFormatOptions): string;
97
- /**
98
- * `value.toFixed(digits)` with the locale's decimal separator ("12.5" in English,
99
- * "12,5" in Italian). No grouping, so English output matches `toFixed` exactly.
100
- */
101
- declare function formatFixed(value: number, locale: string | undefined, digits: number): string;
102
-
103
67
  /**
104
68
  * Format a date to a localized date string
105
69
  * @param date - Date object or ISO string
@@ -112,6 +76,22 @@ declare function formatDate(date: Date | string | undefined, options?: BillingFo
112
76
  /** The active locale and translator, ready to pass to the billing formatters. */
113
77
  declare function useBillingFormatOptions(): Required<BillingFormatOptions>;
114
78
 
79
+ /** A discount as the billing screens apply it: a percentage, or an amount in minor units. */
80
+ type BillingDiscount = {
81
+ discountType: "percent_off" | "amount_off";
82
+ discountValue: number;
83
+ currency?: string;
84
+ };
85
+ /** The discount a valid promotion code (typed or automatic) gives, or null. */
86
+ declare function promotionCodeDiscount(code: PromotionCodeValidationResult | null | undefined): BillingDiscount | null;
87
+ /** The discount a subscription already carries in Stripe, or null. */
88
+ declare function subscriptionDiscount(subscription: StripeSubscriptionInterface | null | undefined): BillingDiscount | null;
89
+ /**
90
+ * The amount after the discount, in the same minor units; null when there is no
91
+ * discount or nothing to discount. An amount discount never goes below zero.
92
+ */
93
+ declare function applyDiscount(amount: number | undefined, discount: BillingDiscount | null): number | null;
94
+
115
95
  type BillingAlertBannerProps = {
116
96
  subscription: StripeSubscriptionInterface;
117
97
  onUpdatePayment?: () => void;
@@ -119,6 +99,34 @@ type BillingAlertBannerProps = {
119
99
  };
120
100
  declare function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }: BillingAlertBannerProps): React.JSX.Element | null;
121
101
 
102
+ interface CouponContextType {
103
+ coupon: StripeCouponInterface | undefined;
104
+ setCoupon: (value: StripeCouponInterface | undefined) => void;
105
+ reloadCoupon: () => Promise<void>;
106
+ createCoupon: (input: StripeCouponInput) => Promise<StripeCouponInterface>;
107
+ renameCoupon: (input: StripeCouponRenameInput) => Promise<StripeCouponInterface>;
108
+ refreshCounts: (id?: string) => Promise<void>;
109
+ createCode: (input: StripeCouponCodeInput) => Promise<StripeCouponCodeInterface>;
110
+ updateCodeFlags: (input: StripeCouponCodeFlagsInput) => Promise<StripeCouponCodeInterface>;
111
+ /** Bumped by every mutation. Mounted lists re-fetch on it. */
112
+ catalogueVersion: number;
113
+ refreshCatalogue: () => void;
114
+ }
115
+ type CouponProviderProps = {
116
+ children: ReactNode;
117
+ dehydratedCoupon?: JsonApiHydratedDataInterface;
118
+ /**
119
+ * Publish breadcrumbs + title into SharedProvider. Pass `false` when this
120
+ * provider is mounted INSIDE another entity's page (the Codes tab of the
121
+ * products page mounts CouponProvider that way): SharedProvider replaces its
122
+ * value for the subtree rather than merging (SharedContext.tsx:35-37), so a
123
+ * nested provider that publishes chrome would blank the host page's title.
124
+ */
125
+ publishChrome?: boolean;
126
+ };
127
+ declare const CouponProvider: ({ children, dehydratedCoupon, publishChrome }: CouponProviderProps) => React.JSX.Element;
128
+ declare const useCouponContext: () => CouponContextType;
129
+
122
130
  interface PriceContextType {
123
131
  price: StripePriceInterface | undefined;
124
132
  setPrice: (value: StripePriceInterface | undefined) => void;
@@ -202,8 +210,13 @@ type PaymentMethodFormProps = {
202
210
  onSuccess: () => void;
203
211
  onCancel: () => void;
204
212
  isLoading?: boolean;
213
+ /**
214
+ * Always make the new card the customer's default and hide the checkbox. The
215
+ * subscription wizard needs this: the next attempt must charge the card just added.
216
+ */
217
+ alwaysSetDefault?: boolean;
205
218
  };
206
- declare function PaymentMethodForm({ onSuccess, onCancel, isLoading }: PaymentMethodFormProps): React.JSX.Element;
219
+ declare function PaymentMethodForm({ onSuccess, onCancel, isLoading, alwaysSetDefault, }: PaymentMethodFormProps): React.JSX.Element;
207
220
 
208
221
  type PaymentMethodsListProps = {
209
222
  paymentMethods: PaymentMethodInterface[];
@@ -302,15 +315,19 @@ declare function PricesList({ productId, fullWidth }: PricesListProps): React.JS
302
315
  declare function ProductContainer(): React.JSX.Element | null;
303
316
 
304
317
  /**
305
- * Page container for the administrative product list.
318
+ * Page container for the administrative products page: two tabs, Products and
319
+ * Codes, with `sectionKey`s so the URL keeps the tab (`?section=codes`).
306
320
  *
307
321
  * Client component by necessity: `module={Modules.StripeProduct}` is a registry
308
322
  * entry carrying an icon component and methods, which a Server Component cannot
309
323
  * pass across the boundary. Routes mount this container instead — the same
310
324
  * shape as every other list page.
311
325
  *
312
- * No `forceHeader`: ContentListTable draws its own header row with the title
313
- * and the create action, exactly as the company and user list pages do.
326
+ * No `fullWidth`, on the page or the lists: the page keeps its title bar and
327
+ * each ContentListTable keeps its own bordered card in the tab (see ProductContainer). CouponProvider
328
+ * is nested with `publishChrome={false}`: SharedProvider REPLACES its value for
329
+ * the subtree (SharedContext.tsx:35-37), so a nested provider publishing chrome
330
+ * would blank the products page's own title.
314
331
  */
315
332
  declare function ProductsListContainer(): React.JSX.Element;
316
333
 
@@ -350,11 +367,145 @@ type ProductsListProps = {
350
367
  };
351
368
  declare function ProductsList({ fullWidth }?: ProductsListProps): React.JSX.Element;
352
369
 
370
+ declare function CouponContainer(): React.JSX.Element | null;
371
+
372
+ declare function CouponDetails(): React.JSX.Element | null;
373
+
374
+ /**
375
+ * What a number or decimal `<FormInput>` holds: "" until something is typed, a
376
+ * number from `type="number"` (`+""` is 0 when cleared, NaN on garbage), a
377
+ * string from `type="decimal"` (may use a comma as the separator).
378
+ *
379
+ * The schemas below validate this raw value and never transform it, so the
380
+ * form's values have one type before and after validation. The `parse*`
381
+ * functions turn it into the number that is sent, on submit.
382
+ */
383
+ type RawNumber = string | number | null | undefined;
384
+ /**
385
+ * Optional whole number of at least 1. 0, "" and NaN all mean "not set": every
386
+ * limit here has a floor of 1.
387
+ */
388
+ declare function parseOptionalPositiveInt(value: RawNumber): number | undefined;
389
+ /**
390
+ * Optional decimal in MAJOR units. Converted to minor units on submit, exactly
391
+ * as PriceEditor does (`Math.round(value * 100)`).
392
+ */
393
+ declare function parseOptionalDecimal(value: RawNumber): number | undefined;
394
+ declare const optionalPositiveInt: () => z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
395
+ declare const optionalDecimal: () => z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
396
+ /**
397
+ * Optional point in time from `<FormDateTime allowEmpty>`, which writes "" when
398
+ * the value is cleared (FormDateTime.tsx:136, :241).
399
+ */
400
+ declare const optionalDate: () => z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodDate, z.ZodLiteral<"">]>>>;
401
+ /** Mirrors StripeCouponCodePostAttributesDTO. */
402
+ declare const couponCodeSchema: (t: (key: string) => string) => z.ZodObject<{
403
+ code: z.ZodOptional<z.ZodString>;
404
+ firstTimeTransaction: z.ZodBoolean;
405
+ minimumAmount: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
406
+ minimumAmountCurrency: z.ZodString;
407
+ stripeCustomerId: z.ZodOptional<z.ZodString>;
408
+ expiresAt: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodDate, z.ZodLiteral<"">]>>>;
409
+ maxRedemptions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
410
+ automatic: z.ZodBoolean;
411
+ }, z.core.$strip>;
412
+ type CouponCodeFormValues = z.infer<ReturnType<typeof couponCodeSchema>>;
413
+ /**
414
+ * Every text/number input starts as "" (never undefined): FormInput spreads
415
+ * `field.value` onto a Base UI input, and undefined → value flips it from
416
+ * uncontrolled to controlled (console warning). The parse functions map ""
417
+ * to undefined, so empty fields are still sent as absent.
418
+ */
419
+ declare const couponCodeDefaults: () => CouponCodeFormValues;
420
+ /** Form values → the code attributes the models serialise. Unset fields are left out. */
421
+ declare const toCouponCodeInput: (values: CouponCodeFormValues) => Omit<StripeCouponCodeInput, "id" | "couponId">;
422
+ declare const couponCurrencyOptions: {
423
+ id: string;
424
+ text: string;
425
+ }[];
426
+ type CouponCodeFieldsProps<T extends FieldValues> = {
427
+ form: UseFormReturn<T>;
428
+ /** "" for CouponCodeEditor, "firstCode." when nested inside CouponEditor. */
429
+ prefix?: string;
430
+ };
431
+ /** The fields of a customer-facing code, shared by CouponEditor (first code) and CouponCodeEditor. */
432
+ declare function CouponCodeFields<T extends FieldValues>({ form, prefix }: CouponCodeFieldsProps<T>): React.JSX.Element;
433
+
434
+ type CouponRefresherProps = {
435
+ coupon: StripeCouponInterface;
436
+ };
437
+ /**
438
+ * Re-reads the coupon and its codes from Stripe and writes the usage counts to
439
+ * our copy. Counts go stale only for subscriptions made outside our endpoints
440
+ * (the Stripe dashboard); this button fixes that.
441
+ */
442
+ declare function CouponRefresher({ coupon }: CouponRefresherProps): React.JSX.Element;
443
+
444
+ type CouponEditorProps = {
445
+ coupon?: StripeCouponInterface;
446
+ propagateChanges?: (coupon: StripeCouponInterface) => void;
447
+ onSuccess?: () => void | Promise<void>;
448
+ trigger?: ReactNode;
449
+ forceShow?: boolean;
450
+ onClose?: () => void;
451
+ dialogOpen?: boolean;
452
+ onDialogOpenChange?: (open: boolean) => void;
453
+ };
454
+ declare function CouponEditor(props: CouponEditorProps): React.JSX.Element;
455
+
456
+ type CouponCodeEditorProps = {
457
+ couponId: string;
458
+ onSuccess?: () => void | Promise<void>;
459
+ trigger?: ReactNode;
460
+ forceShow?: boolean;
461
+ onClose?: () => void;
462
+ dialogOpen?: boolean;
463
+ onDialogOpenChange?: (open: boolean) => void;
464
+ };
465
+ declare function CouponCodeEditor(props: CouponCodeEditorProps): React.JSX.Element;
466
+
467
+ type CouponsListProps = {
468
+ /**
469
+ * Pass this whenever the list is the page's own content inside a
470
+ * `RoundPageContainer fullWidth`. Without it ContentListTable wraps itself in
471
+ * `rounded-md border`, drawing a second bordered card inside the page's
472
+ * rounded shell.
473
+ */
474
+ fullWidth?: boolean;
475
+ };
476
+ declare function CouponsList({ fullWidth }?: CouponsListProps): React.JSX.Element;
477
+
478
+ type CouponCodesListProps = {
479
+ couponId: string;
480
+ };
481
+ declare function CouponCodesList({ couponId }: CouponCodesListProps): React.JSX.Element;
482
+
483
+ type CouponCodeStatus = "active" | "inactive" | "expired" | "used_up";
484
+
485
+ type CouponCodeActionsProps = {
486
+ code: StripeCouponCodeInterface;
487
+ status: CouponCodeStatus;
488
+ };
489
+ /**
490
+ * Row controls of a code: the "Apply automatically" switch and the deactivate /
491
+ * reactivate button. The button sits behind ConfirmDialog, which is controlled
492
+ * and trigger-less by design — the caller owns the trigger button, so none of
493
+ * Base UI's trigger-composition pitfalls apply (no asChild, no nested <button>).
494
+ */
495
+ declare function CouponCodeActions({ code, status }: CouponCodeActionsProps): React.JSX.Element;
496
+
353
497
  type SubscriptionsContainerProps = {
354
498
  onOpenWizard?: (subscription?: StripeSubscriptionInterface) => void;
355
499
  hasActiveRecurringSubscription?: boolean;
500
+ /**
501
+ * The list a parent already holds (the billing dashboard). When given, the container
502
+ * shows it instead of loading its own, and a change asks the parent to refresh through
503
+ * `onSubscriptionsChange`, so the dialog and the cards behind it never disagree.
504
+ */
505
+ subscriptions?: StripeSubscriptionInterface[];
506
+ onSubscriptionsChange?: () => void;
356
507
  };
357
- declare function SubscriptionsContainer({ onOpenWizard, hasActiveRecurringSubscription }: SubscriptionsContainerProps): React.JSX.Element;
508
+ declare function SubscriptionsContainer({ onOpenWizard, hasActiveRecurringSubscription, subscriptions: parentSubscriptions, onSubscriptionsChange, }: SubscriptionsContainerProps): React.JSX.Element;
358
509
 
359
510
  type SubscriptionDetailsProps = {
360
511
  subscription: StripeSubscriptionInterface;
@@ -525,4 +676,4 @@ type PromoCodeInputProps = {
525
676
  };
526
677
  declare function PromoCodeInput({ appliedCode, isValidating, error, onApply, onRemove, disabled, }: PromoCodeInputProps): React.JSX.Element;
527
678
 
528
- export { BillingAlertBanner, BillingDashboardContainer, BillingDetailModal, type BillingFormatOptions, type BillingInterval, type BillingTranslator, BillingUsageSummaryCard, CancelSubscriptionDialog, CustomerInfoCard, IntervalToggle, type IntervalToggleProps, InvoiceDetails, InvoiceStatusBadge, InvoicesContainer, InvoicesList, InvoicesSummaryCard, PaymentMethodCard, PaymentMethodEditor, PaymentMethodForm, PaymentMethodSummaryCard, PaymentMethodsContainer, PaymentMethodsList, PriceArchiver, PriceContainer, type PriceContextType, PriceDetails, PriceEditor, type PriceEditorProps, PriceProvider, type PriceProviderProps, PricesList, PricingCard, type PricingCardProps, ProductArchiver, ProductContainer, type ProductContextType, ProductDetails, ProductEditor, type ProductEditorProps, ProductPricingList, type ProductPricingListProps, ProductPricingRow, type ProductPricingRowProps, ProductProvider, type ProductProviderProps, ProductsList, ProductsListContainer, PromoCodeInput, ProrationPreview, StripeProvider, SubscriptionConfirmation, SubscriptionDetails, SubscriptionStatusBadge, SubscriptionSummaryCard, SubscriptionWizard, type SubscriptionWizardProps, SubscriptionsContainer, SubscriptionsList, UsageContainer, UsageHistoryTable, UsageSummaryCard, UsageSummaryCards, WizardProgressIndicator, WizardStepPaymentMethod, WizardStepPlanSelection, WizardStepReview, formatCurrency, formatDate, formatFixed, formatInterval, isStripeConfigured, priceLabel, useBillingFormatOptions, usePriceContext, useProductContext };
679
+ export { BillingAlertBanner, BillingDashboardContainer, BillingDetailModal, type BillingDiscount, BillingFormatOptions, type BillingInterval, BillingUsageSummaryCard, CancelSubscriptionDialog, CouponCodeActions, CouponCodeEditor, type CouponCodeEditorProps, CouponCodeFields, type CouponCodeFormValues, CouponCodesList, CouponContainer, type CouponContextType, CouponDetails, CouponEditor, type CouponEditorProps, CouponProvider, type CouponProviderProps, CouponRefresher, CouponsList, CustomerInfoCard, IntervalToggle, type IntervalToggleProps, InvoiceDetails, InvoiceStatusBadge, InvoicesContainer, InvoicesList, InvoicesSummaryCard, PaymentMethodCard, PaymentMethodEditor, PaymentMethodForm, PaymentMethodSummaryCard, PaymentMethodsContainer, PaymentMethodsList, PriceArchiver, PriceContainer, type PriceContextType, PriceDetails, PriceEditor, type PriceEditorProps, PriceProvider, type PriceProviderProps, PricesList, PricingCard, type PricingCardProps, ProductArchiver, ProductContainer, type ProductContextType, ProductDetails, ProductEditor, type ProductEditorProps, ProductPricingList, type ProductPricingListProps, ProductPricingRow, type ProductPricingRowProps, ProductProvider, type ProductProviderProps, ProductsList, ProductsListContainer, PromoCodeInput, ProrationPreview, StripeProvider, SubscriptionConfirmation, SubscriptionDetails, SubscriptionStatusBadge, SubscriptionSummaryCard, SubscriptionWizard, type SubscriptionWizardProps, SubscriptionsContainer, SubscriptionsList, UsageContainer, UsageHistoryTable, UsageSummaryCard, UsageSummaryCards, WizardProgressIndicator, WizardStepPaymentMethod, WizardStepPlanSelection, WizardStepReview, applyDiscount, couponCodeDefaults, couponCodeSchema, couponCurrencyOptions, formatDate, isStripeConfigured, optionalDate, optionalDecimal, optionalPositiveInt, parseOptionalDecimal, parseOptionalPositiveInt, priceLabel, promotionCodeDiscount, subscriptionDiscount, toCouponCodeInput, useBillingFormatOptions, useCouponContext, usePriceContext, useProductContext };