@carlonicora/nextjs-jsonapi 1.15.0 → 1.16.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 (271) hide show
  1. package/dist/{ApiResponseInterface-B4QdWh-y.d.mts → ApiResponseInterface-BvWIeLkq.d.ts} +2 -1
  2. package/dist/{ApiResponseInterface-QLDnxLA9.d.ts → ApiResponseInterface-CAbw0sv7.d.mts} +2 -1
  3. package/dist/{BlockNoteEditor-ITJLAOXC.mjs → BlockNoteEditor-HFX7Z5BQ.mjs} +5 -5
  4. package/dist/{BlockNoteEditor-FGXYUAWI.js → BlockNoteEditor-MBFDWP7X.js} +15 -15
  5. package/dist/{BlockNoteEditor-FGXYUAWI.js.map → BlockNoteEditor-MBFDWP7X.js.map} +1 -1
  6. package/dist/JsonApiRequest-45CLE65I.js +24 -0
  7. package/dist/{JsonApiRequest-FXZCYIER.js.map → JsonApiRequest-45CLE65I.js.map} +1 -1
  8. package/dist/{JsonApiRequest-HFWXMKMA.mjs → JsonApiRequest-6IPS3DZJ.mjs} +2 -2
  9. package/dist/{chunk-C6QXZGL7.js → chunk-2AZLCF6D.js} +1617 -158
  10. package/dist/chunk-2AZLCF6D.js.map +1 -0
  11. package/dist/{chunk-WAFOKMKT.mjs → chunk-5RAUCUAA.mjs} +3722 -396
  12. package/dist/chunk-5RAUCUAA.mjs.map +1 -0
  13. package/dist/{chunk-TGBXBUWM.mjs → chunk-BCKYJQ3K.mjs} +8 -1
  14. package/dist/chunk-BCKYJQ3K.mjs.map +1 -0
  15. package/dist/{chunk-JGVXZS7M.mjs → chunk-BCQSE3EU.mjs} +1588 -129
  16. package/dist/chunk-BCQSE3EU.mjs.map +1 -0
  17. package/dist/{chunk-FPZPD4JI.js → chunk-GPGJNTHP.js} +17 -10
  18. package/dist/chunk-GPGJNTHP.js.map +1 -0
  19. package/dist/{chunk-PK5DRSUD.js → chunk-ONB2DAIV.js} +4090 -764
  20. package/dist/chunk-ONB2DAIV.js.map +1 -0
  21. package/dist/{chunk-SJIVGCNM.mjs → chunk-POKIJ56Q.mjs} +7 -2
  22. package/dist/chunk-POKIJ56Q.mjs.map +1 -0
  23. package/dist/{chunk-6YD42BP6.js → chunk-R5QSSISB.js} +14 -9
  24. package/dist/chunk-R5QSSISB.js.map +1 -0
  25. package/dist/client/index.d.mts +5 -5
  26. package/dist/client/index.d.ts +5 -5
  27. package/dist/client/index.js +7 -5
  28. package/dist/client/index.js.map +1 -1
  29. package/dist/client/index.mjs +6 -4
  30. package/dist/components/index.d.mts +253 -9
  31. package/dist/components/index.d.ts +253 -9
  32. package/dist/components/index.js +83 -5
  33. package/dist/components/index.js.map +1 -1
  34. package/dist/components/index.mjs +82 -4
  35. package/dist/{config-eceYM5kN.d.ts → config-CWsTwnsK.d.mts} +7 -2
  36. package/dist/{config-C5tGGrYf.d.mts → config-DEaUbBqR.d.ts} +7 -2
  37. package/dist/{content.interface-TB2MfJGs.d.ts → content.interface-D_4b4RQt.d.ts} +1 -1
  38. package/dist/{content.interface-CxBBC7ec.d.mts → content.interface-Dk4UZcJM.d.mts} +1 -1
  39. package/dist/contexts/index.d.mts +2 -2
  40. package/dist/contexts/index.d.ts +2 -2
  41. package/dist/contexts/index.js +5 -5
  42. package/dist/contexts/index.mjs +4 -4
  43. package/dist/core/index.d.mts +521 -18
  44. package/dist/core/index.d.ts +521 -18
  45. package/dist/core/index.js +53 -3
  46. package/dist/core/index.js.map +1 -1
  47. package/dist/core/index.mjs +52 -2
  48. package/dist/index.d.mts +7 -7
  49. package/dist/index.d.ts +7 -7
  50. package/dist/index.js +56 -4
  51. package/dist/index.js.map +1 -1
  52. package/dist/index.mjs +55 -3
  53. package/dist/{notification.interface-lG6UpTpt.d.mts → notification.interface-BllkURRm.d.mts} +1 -2
  54. package/dist/{notification.interface-lG6UpTpt.d.ts → notification.interface-BllkURRm.d.ts} +1 -2
  55. package/dist/{s3.service-DP_hsssD.d.mts → s3.service-BEfGqho0.d.ts} +20 -2
  56. package/dist/{s3.service-Dq-PTUNa.d.ts → s3.service-DIQRYe93.d.mts} +20 -2
  57. package/dist/scripts/generate-web-module/generator.d.ts.map +1 -1
  58. package/dist/scripts/generate-web-module/generator.js +66 -0
  59. package/dist/scripts/generate-web-module/generator.js.map +1 -1
  60. package/dist/scripts/generate-web-module/templates/index.d.ts +8 -0
  61. package/dist/scripts/generate-web-module/templates/index.d.ts.map +1 -1
  62. package/dist/scripts/generate-web-module/templates/index.js +18 -1
  63. package/dist/scripts/generate-web-module/templates/index.js.map +1 -1
  64. package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.d.ts +7 -0
  65. package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.d.ts.map +1 -0
  66. package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.js +141 -0
  67. package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.js.map +1 -0
  68. package/dist/scripts/generate-web-module/templates/project/env.template.d.ts +7 -0
  69. package/dist/scripts/generate-web-module/templates/project/env.template.d.ts.map +1 -0
  70. package/dist/scripts/generate-web-module/templates/project/env.template.js +110 -0
  71. package/dist/scripts/generate-web-module/templates/project/env.template.js.map +1 -0
  72. package/dist/scripts/generate-web-module/templates/project/main-layout.template.d.ts +7 -0
  73. package/dist/scripts/generate-web-module/templates/project/main-layout.template.d.ts.map +1 -0
  74. package/dist/scripts/generate-web-module/templates/project/main-layout.template.js +101 -0
  75. package/dist/scripts/generate-web-module/templates/project/main-layout.template.js.map +1 -0
  76. package/dist/scripts/generate-web-module/templates/project/middleware-env.template.d.ts +7 -0
  77. package/dist/scripts/generate-web-module/templates/project/middleware-env.template.d.ts.map +1 -0
  78. package/dist/scripts/generate-web-module/templates/project/middleware-env.template.js +66 -0
  79. package/dist/scripts/generate-web-module/templates/project/middleware-env.template.js.map +1 -0
  80. package/dist/scripts/generate-web-module/templates/project/settings-container.template.d.ts +7 -0
  81. package/dist/scripts/generate-web-module/templates/project/settings-container.template.d.ts.map +1 -0
  82. package/dist/scripts/generate-web-module/templates/project/settings-container.template.js +257 -0
  83. package/dist/scripts/generate-web-module/templates/project/settings-container.template.js.map +1 -0
  84. package/dist/scripts/generate-web-module/templates/project/settings-context.template.d.ts +7 -0
  85. package/dist/scripts/generate-web-module/templates/project/settings-context.template.d.ts.map +1 -0
  86. package/dist/scripts/generate-web-module/templates/project/settings-context.template.js +124 -0
  87. package/dist/scripts/generate-web-module/templates/project/settings-context.template.js.map +1 -0
  88. package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.d.ts +7 -0
  89. package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.d.ts.map +1 -0
  90. package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.js +78 -0
  91. package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.js.map +1 -0
  92. package/dist/scripts/generate-web-module/templates/project/settings-page.template.d.ts +7 -0
  93. package/dist/scripts/generate-web-module/templates/project/settings-page.template.d.ts.map +1 -0
  94. package/dist/scripts/generate-web-module/templates/project/settings-page.template.js +75 -0
  95. package/dist/scripts/generate-web-module/templates/project/settings-page.template.js.map +1 -0
  96. package/dist/scripts/generate-web-module/types/template-data.interface.d.ts +1 -1
  97. package/dist/scripts/generate-web-module/types/template-data.interface.d.ts.map +1 -1
  98. package/dist/server/index.d.mts +4 -4
  99. package/dist/server/index.d.ts +4 -4
  100. package/dist/server/index.js +12 -12
  101. package/dist/server/index.mjs +2 -2
  102. package/dist/stripe-subscription.interface-C63L6hVg.d.mts +226 -0
  103. package/dist/stripe-subscription.interface-CUvNDvw5.d.ts +226 -0
  104. package/dist/{useSocket-Bua6MwLi.d.mts → useSocket-BpenBR2z.d.mts} +1 -1
  105. package/dist/{useSocket-D5dhUp4m.d.ts → useSocket-D-QYA0Sr.d.ts} +1 -1
  106. package/package.json +9 -1
  107. package/scripts/generate-web-module/generator.ts +83 -0
  108. package/scripts/generate-web-module/templates/index.ts +10 -0
  109. package/scripts/generate-web-module/templates/project/bootstrapper.template.ts +108 -0
  110. package/scripts/generate-web-module/templates/project/env.template.ts +77 -0
  111. package/scripts/generate-web-module/templates/project/main-layout.template.tsx +68 -0
  112. package/scripts/generate-web-module/templates/project/middleware-env.template.ts +33 -0
  113. package/scripts/generate-web-module/templates/project/settings-container.template.tsx +224 -0
  114. package/scripts/generate-web-module/templates/project/settings-context.template.tsx +91 -0
  115. package/scripts/generate-web-module/templates/project/settings-module-page.template.tsx +45 -0
  116. package/scripts/generate-web-module/templates/project/settings-page.template.tsx +42 -0
  117. package/scripts/generate-web-module/types/template-data.interface.ts +1 -1
  118. package/src/client/config.ts +9 -0
  119. package/src/components/index.ts +7 -0
  120. package/src/core/abstracts/AbstractService.ts +104 -0
  121. package/src/core/endpoint/EndpointCreator.ts +7 -4
  122. package/src/core/index.ts +12 -4
  123. package/src/core/interfaces/ApiResponseInterface.ts +1 -0
  124. package/src/core/registry/ModuleRegistry.ts +11 -2
  125. package/src/core/utils/translateResponse.ts +17 -0
  126. package/src/features/billing/components/cards/BillingUsageSummaryCard.tsx +97 -0
  127. package/src/features/billing/components/cards/CustomerInfoCard.tsx +112 -0
  128. package/src/features/billing/components/cards/InvoicesSummaryCard.tsx +114 -0
  129. package/src/features/billing/components/cards/PaymentMethodSummaryCard.tsx +119 -0
  130. package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +146 -0
  131. package/src/features/billing/components/cards/index.ts +5 -0
  132. package/src/features/billing/components/containers/BillingDashboardContainer.tsx +427 -0
  133. package/src/features/billing/components/containers/index.ts +1 -0
  134. package/src/features/billing/components/index.ts +6 -0
  135. package/src/features/billing/components/modals/BillingDetailModal.tsx +36 -0
  136. package/src/features/billing/components/modals/index.ts +1 -0
  137. package/src/features/billing/components/providers/StripeProvider.tsx +48 -0
  138. package/src/features/billing/components/providers/index.ts +1 -0
  139. package/src/features/billing/components/utils/currency.ts +49 -0
  140. package/src/features/billing/components/utils/date.ts +21 -0
  141. package/src/features/billing/components/utils/index.ts +2 -0
  142. package/src/features/billing/components/widgets/BillingAlertBanner.tsx +63 -0
  143. package/src/features/billing/components/widgets/index.ts +1 -0
  144. package/src/features/billing/data/Billing.ts +17 -0
  145. package/src/features/billing/data/billing.service.ts +58 -0
  146. package/src/features/billing/data/index.ts +5 -0
  147. package/src/features/billing/index.ts +3 -0
  148. package/src/features/billing/modules/billing.module.ts +9 -0
  149. package/src/features/billing/modules/index.ts +1 -0
  150. package/src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx +79 -0
  151. package/src/features/billing/stripe-customer/components/containers/index.ts +1 -0
  152. package/src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx +151 -0
  153. package/src/features/billing/stripe-customer/components/details/index.ts +1 -0
  154. package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +186 -0
  155. package/src/features/billing/stripe-customer/components/forms/index.ts +1 -0
  156. package/src/features/billing/stripe-customer/components/index.ts +4 -0
  157. package/src/features/billing/stripe-customer/components/lists/PaymentMethodsList.tsx +19 -0
  158. package/src/features/billing/stripe-customer/components/lists/index.ts +1 -0
  159. package/src/features/billing/stripe-customer/data/index.ts +5 -0
  160. package/src/features/billing/stripe-customer/data/payment-method.interface.ts +27 -0
  161. package/src/features/billing/stripe-customer/data/payment-method.ts +119 -0
  162. package/src/features/billing/stripe-customer/data/stripe-customer.interface.ts +16 -0
  163. package/src/features/billing/stripe-customer/data/stripe-customer.service.ts +128 -0
  164. package/src/features/billing/stripe-customer/data/stripe-customer.ts +71 -0
  165. package/src/features/billing/stripe-customer/index.ts +3 -0
  166. package/src/features/billing/stripe-customer/stripe-customer.module.ts +9 -0
  167. package/src/features/billing/stripe-customer/stripe-payment-method.module.ts +9 -0
  168. package/src/features/billing/stripe-invoice/components/containers/InvoicesContainer.tsx +66 -0
  169. package/src/features/billing/stripe-invoice/components/containers/index.ts +1 -0
  170. package/src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx +172 -0
  171. package/src/features/billing/stripe-invoice/components/details/index.ts +1 -0
  172. package/src/features/billing/stripe-invoice/components/index.ts +4 -0
  173. package/src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx +84 -0
  174. package/src/features/billing/stripe-invoice/components/lists/index.ts +1 -0
  175. package/src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx +41 -0
  176. package/src/features/billing/stripe-invoice/components/widgets/index.ts +1 -0
  177. package/src/features/billing/stripe-invoice/data/index.ts +3 -0
  178. package/src/features/billing/stripe-invoice/data/stripe-invoice.interface.ts +65 -0
  179. package/src/features/billing/stripe-invoice/data/stripe-invoice.service.ts +64 -0
  180. package/src/features/billing/stripe-invoice/data/stripe-invoice.ts +177 -0
  181. package/src/features/billing/stripe-invoice/index.ts +2 -0
  182. package/src/features/billing/stripe-invoice/stripe-invoice.module.ts +9 -0
  183. package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +304 -0
  184. package/src/features/billing/stripe-price/components/forms/index.ts +1 -0
  185. package/src/features/billing/stripe-price/components/index.ts +2 -0
  186. package/src/features/billing/stripe-price/components/lists/PricesList.tsx +283 -0
  187. package/src/features/billing/stripe-price/components/lists/index.ts +1 -0
  188. package/src/features/billing/stripe-price/data/index.ts +3 -0
  189. package/src/features/billing/stripe-price/data/stripe-price.interface.ts +48 -0
  190. package/src/features/billing/stripe-price/data/stripe-price.service.ts +123 -0
  191. package/src/features/billing/stripe-price/data/stripe-price.ts +156 -0
  192. package/src/features/billing/stripe-price/index.ts +2 -0
  193. package/src/features/billing/stripe-price/stripe-price.module.ts +9 -0
  194. package/src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx +86 -0
  195. package/src/features/billing/stripe-product/components/containers/index.ts +1 -0
  196. package/src/features/billing/stripe-product/components/forms/ProductEditor.tsx +100 -0
  197. package/src/features/billing/stripe-product/components/forms/index.ts +1 -0
  198. package/src/features/billing/stripe-product/components/index.ts +3 -0
  199. package/src/features/billing/stripe-product/components/lists/ProductsList.tsx +206 -0
  200. package/src/features/billing/stripe-product/components/lists/index.ts +1 -0
  201. package/src/features/billing/stripe-product/data/index.ts +3 -0
  202. package/src/features/billing/stripe-product/data/stripe-product.interface.ts +18 -0
  203. package/src/features/billing/stripe-product/data/stripe-product.service.ts +112 -0
  204. package/src/features/billing/stripe-product/data/stripe-product.ts +74 -0
  205. package/src/features/billing/stripe-product/index.ts +2 -0
  206. package/src/features/billing/stripe-product/stripe-product.module.ts +9 -0
  207. package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +304 -0
  208. package/src/features/billing/stripe-subscription/components/containers/index.ts +1 -0
  209. package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +223 -0
  210. package/src/features/billing/stripe-subscription/components/details/index.ts +1 -0
  211. package/src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx +116 -0
  212. package/src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx +331 -0
  213. package/src/features/billing/stripe-subscription/components/forms/index.ts +2 -0
  214. package/src/features/billing/stripe-subscription/components/index.ts +5 -0
  215. package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +104 -0
  216. package/src/features/billing/stripe-subscription/components/lists/index.ts +1 -0
  217. package/src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx +95 -0
  218. package/src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx +110 -0
  219. package/src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx +41 -0
  220. package/src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx +60 -0
  221. package/src/features/billing/stripe-subscription/components/widgets/index.ts +4 -0
  222. package/src/features/billing/stripe-subscription/data/index.ts +3 -0
  223. package/src/features/billing/stripe-subscription/data/stripe-subscription.interface.ts +66 -0
  224. package/src/features/billing/stripe-subscription/data/stripe-subscription.service.ts +193 -0
  225. package/src/features/billing/stripe-subscription/data/stripe-subscription.ts +135 -0
  226. package/src/features/billing/stripe-subscription/hooks/index.ts +1 -0
  227. package/src/features/billing/stripe-subscription/hooks/useConfirmSubscriptionPayment.ts +111 -0
  228. package/src/features/billing/stripe-subscription/index.ts +5 -0
  229. package/src/features/billing/stripe-subscription/stripe-subscription.module.ts +9 -0
  230. package/src/features/billing/stripe-usage/components/containers/UsageContainer.tsx +109 -0
  231. package/src/features/billing/stripe-usage/components/containers/index.ts +1 -0
  232. package/src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx +90 -0
  233. package/src/features/billing/stripe-usage/components/details/index.ts +1 -0
  234. package/src/features/billing/stripe-usage/components/index.ts +4 -0
  235. package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +72 -0
  236. package/src/features/billing/stripe-usage/components/lists/index.ts +1 -0
  237. package/src/features/billing/stripe-usage/components/widgets/UsageSummaryCards.tsx +19 -0
  238. package/src/features/billing/stripe-usage/components/widgets/index.ts +1 -0
  239. package/src/features/billing/stripe-usage/data/index.ts +3 -0
  240. package/src/features/billing/stripe-usage/data/stripe-usage.interface.ts +55 -0
  241. package/src/features/billing/stripe-usage/data/stripe-usage.service.ts +129 -0
  242. package/src/features/billing/stripe-usage/data/stripe-usage.ts +70 -0
  243. package/src/features/billing/stripe-usage/index.ts +2 -0
  244. package/src/features/billing/stripe-usage/stripe-usage.module.ts +9 -0
  245. package/src/features/company/components/forms/CompanyEditor.tsx +2 -2
  246. package/src/features/company/contexts/CompanyContext.tsx +2 -2
  247. package/src/features/feature/components/forms/FormFeatures.tsx +13 -106
  248. package/src/features/feature/data/feature.interface.ts +1 -1
  249. package/src/features/feature/data/feature.ts +4 -4
  250. package/src/features/index.ts +7 -0
  251. package/src/features/module/data/module.interface.ts +0 -1
  252. package/src/features/module/data/module.ts +0 -6
  253. package/src/features/user/components/lists/ContributorsList.tsx +2 -2
  254. package/src/features/user/components/widgets/UserAvatar.tsx +1 -1
  255. package/src/index.ts +1 -1
  256. package/src/shadcnui/custom/link.tsx +16 -6
  257. package/src/utils/blocknote-diff.util.ts +2 -1
  258. package/src/utils/blocknote-word-diff-renderer.util.ts +8 -7
  259. package/dist/AuthComponent-hxOPs9o8.d.mts +0 -11
  260. package/dist/AuthComponent-hxOPs9o8.d.ts +0 -11
  261. package/dist/JsonApiRequest-FXZCYIER.js +0 -24
  262. package/dist/chunk-6YD42BP6.js.map +0 -1
  263. package/dist/chunk-C6QXZGL7.js.map +0 -1
  264. package/dist/chunk-FPZPD4JI.js.map +0 -1
  265. package/dist/chunk-JGVXZS7M.mjs.map +0 -1
  266. package/dist/chunk-PK5DRSUD.js.map +0 -1
  267. package/dist/chunk-SJIVGCNM.mjs.map +0 -1
  268. package/dist/chunk-TGBXBUWM.mjs.map +0 -1
  269. package/dist/chunk-WAFOKMKT.mjs.map +0 -1
  270. /package/dist/{BlockNoteEditor-ITJLAOXC.mjs.map → BlockNoteEditor-HFX7Z5BQ.mjs.map} +0 -0
  271. /package/dist/{JsonApiRequest-HFWXMKMA.mjs.map → JsonApiRequest-6IPS3DZJ.mjs.map} +0 -0
@@ -0,0 +1,58 @@
1
+ import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from "../../../core";
2
+
3
+ // Import from new sub-modules for backwards compatibility re-exports
4
+ import { MeterInterface, MeterSummaryInterface } from "../stripe-usage/data/stripe-usage.interface";
5
+
6
+ /**
7
+ * Legacy billing service - only contains meter methods
8
+ * @deprecated Use StripeUsageService for meter methods, StripeInvoiceService for invoices,
9
+ * StripeCustomerService for payment methods
10
+ */
11
+ export class BillingService extends AbstractService {
12
+ // ============================================================================
13
+ // Meter Methods (kept here for backwards compatibility)
14
+ // ============================================================================
15
+
16
+ /**
17
+ * List all available usage meters
18
+ * @deprecated Use StripeUsageService.listMeters() instead
19
+ */
20
+ static async listMeters(params?: { next?: NextRef; prev?: PreviousRef }): Promise<MeterInterface[]> {
21
+ const endpoint = new EndpointCreator({
22
+ endpoint: Modules.StripeUsage,
23
+ childEndpoint: "meters",
24
+ });
25
+
26
+ return this.callApi({
27
+ type: Modules.StripeUsage,
28
+ method: HttpMethod.GET,
29
+ endpoint: endpoint.generate(),
30
+ next: params?.next,
31
+ previous: params?.prev,
32
+ });
33
+ }
34
+
35
+ /**
36
+ * Get meter summaries for a specific time period
37
+ * @deprecated Use StripeUsageService.getMeterSummaries() instead
38
+ */
39
+ static async getMeterSummaries(params: {
40
+ meterId: string;
41
+ startTime: Date;
42
+ endTime: Date;
43
+ }): Promise<MeterSummaryInterface[]> {
44
+ const endpoint = new EndpointCreator({
45
+ endpoint: Modules.StripeUsage,
46
+ childEndpoint: `meters/${params.meterId}/summaries`,
47
+ });
48
+
49
+ endpoint.addAdditionalParam("startTime", params.startTime.toISOString());
50
+ endpoint.addAdditionalParam("endTime", params.endTime.toISOString());
51
+
52
+ return this.callApi({
53
+ type: Modules.StripeUsage,
54
+ method: HttpMethod.GET,
55
+ endpoint: endpoint.generate(),
56
+ });
57
+ }
58
+ }
@@ -0,0 +1,5 @@
1
+ // Services
2
+ export { BillingService } from "./billing.service";
3
+
4
+ // Data classes
5
+ export { Billing } from "./Billing";
@@ -0,0 +1,3 @@
1
+ export * from "./components";
2
+ export * from "./data";
3
+ export * from "./modules";
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../../permissions";
2
+ import { Billing } from "../data/Billing";
3
+
4
+ export const BillingModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "billing",
7
+ model: Billing,
8
+ moduleId: "3266b307-5a9a-46f9-b78d-631f672f8735",
9
+ });
@@ -0,0 +1 @@
1
+ export { BillingModule } from "./billing.module";
@@ -0,0 +1,79 @@
1
+ "use client";
2
+
3
+ import { CreditCard } from "lucide-react";
4
+ import { useEffect, useState } from "react";
5
+ import { Button } from "../../../../../shadcnui";
6
+ import { PaymentMethodInterface, StripeCustomerService } from "../../data";
7
+ import { PaymentMethodEditor } from "../forms/PaymentMethodEditor";
8
+ import { PaymentMethodsList } from "../lists/PaymentMethodsList";
9
+
10
+ export function PaymentMethodsContainer() {
11
+ const [paymentMethods, setPaymentMethods] = useState<PaymentMethodInterface[]>([]);
12
+ const [loading, setLoading] = useState<boolean>(true);
13
+ const [showAddPaymentMethod, setShowAddPaymentMethod] = useState<boolean>(false);
14
+
15
+ const loadPaymentMethods = async () => {
16
+ setLoading(true);
17
+ try {
18
+ const fetchedPaymentMethods = await StripeCustomerService.listPaymentMethods();
19
+ setPaymentMethods(fetchedPaymentMethods);
20
+ } catch (error) {
21
+ console.error("[PaymentMethodsContainer] Failed to load payment methods:", error);
22
+ } finally {
23
+ setLoading(false);
24
+ }
25
+ };
26
+
27
+ useEffect(() => {
28
+ loadPaymentMethods();
29
+ }, []);
30
+
31
+ if (loading) {
32
+ return (
33
+ <div className="flex h-64 items-center justify-center">
34
+ <p className="text-muted-foreground">Loading payment methods...</p>
35
+ </div>
36
+ );
37
+ }
38
+
39
+ return (
40
+ <div className="flex w-full flex-col gap-y-6">
41
+ {/* Header */}
42
+ <div className="flex items-center justify-between">
43
+ <div className="flex items-center gap-x-3">
44
+ <CreditCard className="h-8 w-8" />
45
+ <h1 className="text-3xl font-bold">Payment Methods</h1>
46
+ </div>
47
+ <Button onClick={() => setShowAddPaymentMethod(true)}>Add Payment Method</Button>
48
+ </div>
49
+
50
+ {/* Empty State */}
51
+ {paymentMethods.length === 0 && (
52
+ <div className="flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 bg-muted/50 p-12">
53
+ <CreditCard className="h-16 w-16 text-muted-foreground" />
54
+ <div className="text-center">
55
+ <h3 className="mb-2 text-xl font-semibold">No payment methods</h3>
56
+ <p className="mb-4 text-muted-foreground">
57
+ Add a payment method to enable subscriptions and secure checkout.
58
+ </p>
59
+ <Button onClick={() => setShowAddPaymentMethod(true)}>Add Your First Card</Button>
60
+ </div>
61
+ </div>
62
+ )}
63
+
64
+ {/* Payment Methods List */}
65
+ {paymentMethods.length > 0 && (
66
+ <PaymentMethodsList paymentMethods={paymentMethods} onUpdate={loadPaymentMethods} />
67
+ )}
68
+
69
+ {/* Add Payment Method Modal */}
70
+ {showAddPaymentMethod && (
71
+ <PaymentMethodEditor
72
+ open={showAddPaymentMethod}
73
+ onOpenChange={setShowAddPaymentMethod}
74
+ onSuccess={loadPaymentMethods}
75
+ />
76
+ )}
77
+ </div>
78
+ );
79
+ }
@@ -0,0 +1 @@
1
+ export * from "./PaymentMethodsContainer";
@@ -0,0 +1,151 @@
1
+ "use client";
2
+
3
+ import { MoreVertical } from "lucide-react";
4
+ import { useEffect, useState } from "react";
5
+ import {
6
+ AlertDialog,
7
+ AlertDialogAction,
8
+ AlertDialogCancel,
9
+ AlertDialogContent,
10
+ AlertDialogDescription,
11
+ AlertDialogFooter,
12
+ AlertDialogHeader,
13
+ AlertDialogTitle,
14
+ Badge,
15
+ Button,
16
+ Card,
17
+ CardContent,
18
+ CardHeader,
19
+ DropdownMenu,
20
+ DropdownMenuContent,
21
+ DropdownMenuItem,
22
+ DropdownMenuTrigger,
23
+ } from "../../../../../shadcnui";
24
+ import { PaymentMethodInterface, StripeCustomerInterface, StripeCustomerService } from "../../data";
25
+
26
+ type PaymentMethodCardProps = {
27
+ paymentMethod: PaymentMethodInterface;
28
+ onUpdate: () => void;
29
+ };
30
+
31
+ // Card brand icons mapping
32
+ const brandIcons: Record<string, string> = {
33
+ visa: "💳",
34
+ mastercard: "💳",
35
+ amex: "💳",
36
+ discover: "💳",
37
+ };
38
+
39
+ export function PaymentMethodCard({ paymentMethod, onUpdate }: PaymentMethodCardProps) {
40
+ const [loading, setLoading] = useState<boolean>(false);
41
+ const [customer, setCustomer] = useState<StripeCustomerInterface | null>(null);
42
+ const [showRemoveDialog, setShowRemoveDialog] = useState<boolean>(false);
43
+
44
+ // Load customer to check default payment method
45
+ useEffect(() => {
46
+ const loadCustomer = async () => {
47
+ try {
48
+ const fetchedCustomer = await StripeCustomerService.getCustomer();
49
+ setCustomer(fetchedCustomer);
50
+ } catch (error) {
51
+ console.error("[PaymentMethodCard] Failed to load customer:", error);
52
+ }
53
+ };
54
+
55
+ loadCustomer();
56
+ }, []);
57
+
58
+ const isDefault = customer?.defaultPaymentMethodId === paymentMethod.id;
59
+ const brand = paymentMethod.card?.brand || "card";
60
+ const last4 = paymentMethod.card?.last4 || "****";
61
+ const expMonth = paymentMethod.card?.expMonth || 0;
62
+ const expYear = paymentMethod.card?.expYear || 0;
63
+ const brandIcon = brandIcons[brand.toLowerCase()] || "💳";
64
+
65
+ const handleSetDefault = async () => {
66
+ setLoading(true);
67
+ try {
68
+ await StripeCustomerService.setDefaultPaymentMethod({ paymentMethodId: paymentMethod.id });
69
+ onUpdate();
70
+ } catch (error) {
71
+ console.error("[PaymentMethodCard] Failed to set as default:", error);
72
+ } finally {
73
+ setLoading(false);
74
+ }
75
+ };
76
+
77
+ const handleRemove = async () => {
78
+ setLoading(true);
79
+ try {
80
+ await StripeCustomerService.removePaymentMethod({ paymentMethodId: paymentMethod.id });
81
+ setShowRemoveDialog(false);
82
+ onUpdate();
83
+ } catch (error) {
84
+ console.error("[PaymentMethodCard] Failed to remove:", error);
85
+ setLoading(false);
86
+ }
87
+ };
88
+
89
+ return (
90
+ <>
91
+ <Card className="relative">
92
+ {/* Default Badge */}
93
+ {isDefault && (
94
+ <Badge className="absolute right-2 top-2 bg-green-100 text-green-800 hover:bg-green-100">Default</Badge>
95
+ )}
96
+
97
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
98
+ <div className="flex items-center gap-x-2">
99
+ <span className="text-2xl">{brandIcon}</span>
100
+ <span className="text-sm font-medium capitalize">{brand}</span>
101
+ </div>
102
+ <DropdownMenu>
103
+ <DropdownMenuTrigger asChild>
104
+ <Button variant="ghost" size="sm" disabled={loading} className="h-8 w-8 p-0">
105
+ <MoreVertical className="h-4 w-4" />
106
+ </Button>
107
+ </DropdownMenuTrigger>
108
+ <DropdownMenuContent align="end">
109
+ {!isDefault && (
110
+ <DropdownMenuItem onClick={handleSetDefault} disabled={loading}>
111
+ Set as Default
112
+ </DropdownMenuItem>
113
+ )}
114
+ <DropdownMenuItem onClick={() => setShowRemoveDialog(true)} disabled={loading} className="text-red-600">
115
+ Remove
116
+ </DropdownMenuItem>
117
+ </DropdownMenuContent>
118
+ </DropdownMenu>
119
+ </CardHeader>
120
+
121
+ <CardContent>
122
+ <div className="flex flex-col gap-y-1">
123
+ <p className="text-lg font-semibold">•••• {last4}</p>
124
+ <p className="text-sm text-muted-foreground">
125
+ Expires {String(expMonth).padStart(2, "0")}/{expYear}
126
+ </p>
127
+ </div>
128
+ </CardContent>
129
+ </Card>
130
+
131
+ {/* Remove Confirmation Dialog */}
132
+ <AlertDialog open={showRemoveDialog} onOpenChange={setShowRemoveDialog}>
133
+ <AlertDialogContent>
134
+ <AlertDialogHeader>
135
+ <AlertDialogTitle>Remove Payment Method</AlertDialogTitle>
136
+ <AlertDialogDescription>
137
+ Are you sure you want to remove this payment method? This action cannot be undone.
138
+ {isDefault && " This is your default payment method."}
139
+ </AlertDialogDescription>
140
+ </AlertDialogHeader>
141
+ <AlertDialogFooter>
142
+ <AlertDialogCancel disabled={loading}>Cancel</AlertDialogCancel>
143
+ <AlertDialogAction onClick={handleRemove} disabled={loading} className="bg-red-600 hover:bg-red-700">
144
+ {loading ? "Removing..." : "Remove"}
145
+ </AlertDialogAction>
146
+ </AlertDialogFooter>
147
+ </AlertDialogContent>
148
+ </AlertDialog>
149
+ </>
150
+ );
151
+ }
@@ -0,0 +1 @@
1
+ export * from "./PaymentMethodCard";
@@ -0,0 +1,186 @@
1
+ "use client";
2
+
3
+ import { CardElement, useElements, useStripe } from "@stripe/react-stripe-js";
4
+ import { useEffect, useState } from "react";
5
+ import {
6
+ Alert,
7
+ AlertDescription,
8
+ Button,
9
+ Checkbox,
10
+ Dialog,
11
+ DialogContent,
12
+ DialogDescription,
13
+ DialogHeader,
14
+ DialogTitle,
15
+ Label,
16
+ } from "../../../../../shadcnui";
17
+ import { StripeCustomerService } from "../../data";
18
+
19
+ type PaymentMethodEditorProps = {
20
+ open: boolean;
21
+ onOpenChange: (open: boolean) => void;
22
+ onSuccess: () => void;
23
+ };
24
+
25
+ export function PaymentMethodEditor({ open, onOpenChange, onSuccess }: PaymentMethodEditorProps) {
26
+ const stripe = useStripe();
27
+ const elements = useElements();
28
+
29
+ const [setupIntent, setSetupIntent] = useState<{ clientSecret: string } | null>(null);
30
+ const [loading, setLoading] = useState<boolean>(true);
31
+ const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
32
+ const [error, setError] = useState<string | null>(null);
33
+ const [setAsDefault, setSetAsDefault] = useState<boolean>(true);
34
+
35
+ // Fetch setup intent on component mount
36
+ useEffect(() => {
37
+ const fetchSetupIntent = async () => {
38
+ setLoading(true);
39
+ try {
40
+ const intent = await StripeCustomerService.createSetupIntent();
41
+ setSetupIntent(intent);
42
+ } catch (err) {
43
+ console.error("[PaymentMethodEditor] Failed to create setup intent:", err);
44
+ setError("Failed to initialize payment form. Please try again.");
45
+ } finally {
46
+ setLoading(false);
47
+ }
48
+ };
49
+
50
+ if (open) {
51
+ fetchSetupIntent();
52
+ }
53
+ }, [open]);
54
+
55
+ const handleSubmit = async (e: React.FormEvent) => {
56
+ e.preventDefault();
57
+
58
+ if (!stripe || !elements || !setupIntent) {
59
+ return;
60
+ }
61
+
62
+ setIsSubmitting(true);
63
+ setError(null);
64
+
65
+ try {
66
+ const cardElement = elements.getElement(CardElement);
67
+ if (!cardElement) {
68
+ throw new Error("Card element not found");
69
+ }
70
+
71
+ // Confirm card setup with Stripe
72
+ const { error: stripeError, setupIntent: confirmedSetupIntent } = await stripe.confirmCardSetup(
73
+ setupIntent.clientSecret,
74
+ {
75
+ payment_method: {
76
+ card: cardElement,
77
+ },
78
+ },
79
+ );
80
+
81
+ if (stripeError) {
82
+ console.error("[PaymentMethodEditor] Stripe error:", stripeError);
83
+ setError(stripeError.message || "Failed to add payment method. Please check your card details.");
84
+ setIsSubmitting(false);
85
+ return;
86
+ }
87
+
88
+ // Set as default if checkbox is checked
89
+ if (setAsDefault && confirmedSetupIntent?.payment_method) {
90
+ await StripeCustomerService.setDefaultPaymentMethod({
91
+ paymentMethodId:
92
+ typeof confirmedSetupIntent.payment_method === "string"
93
+ ? confirmedSetupIntent.payment_method
94
+ : confirmedSetupIntent.payment_method.id,
95
+ });
96
+ }
97
+
98
+ onSuccess();
99
+ onOpenChange(false);
100
+ } catch (err: any) {
101
+ console.error("[PaymentMethodEditor] Error:", err);
102
+ setError(err.message || "An unexpected error occurred. Please try again.");
103
+ } finally {
104
+ setIsSubmitting(false);
105
+ }
106
+ };
107
+
108
+ return (
109
+ <Dialog open={open} onOpenChange={onOpenChange}>
110
+ <DialogContent className="max-w-md">
111
+ <DialogHeader>
112
+ <DialogTitle>Add Payment Method</DialogTitle>
113
+ <DialogDescription>
114
+ Add a new payment method to your account. Your card information is securely processed by Stripe.
115
+ </DialogDescription>
116
+ </DialogHeader>
117
+
118
+ {loading && (
119
+ <div className="flex items-center justify-center py-8">
120
+ <p className="text-muted-foreground">Loading payment form...</p>
121
+ </div>
122
+ )}
123
+
124
+ {!loading && setupIntent && (
125
+ <form onSubmit={handleSubmit} className="flex flex-col gap-y-4">
126
+ {/* Card Element */}
127
+ <div className="rounded-md border border-gray-300 p-3">
128
+ <CardElement
129
+ options={{
130
+ style: {
131
+ base: {
132
+ fontSize: "16px",
133
+ color: "#424770",
134
+ "::placeholder": {
135
+ color: "#aab7c4",
136
+ },
137
+ },
138
+ invalid: {
139
+ color: "#9e2146",
140
+ },
141
+ },
142
+ }}
143
+ />
144
+ </div>
145
+
146
+ {/* Set as Default Checkbox */}
147
+ <div className="flex items-center gap-x-2">
148
+ <Checkbox
149
+ id="setAsDefault"
150
+ checked={setAsDefault}
151
+ onCheckedChange={(checked) => setSetAsDefault(!!checked)}
152
+ />
153
+ <Label htmlFor="setAsDefault" className="text-sm font-normal">
154
+ Set as default payment method
155
+ </Label>
156
+ </div>
157
+
158
+ {/* Error Alert */}
159
+ {error && (
160
+ <Alert variant="destructive" className="bg-red-50 border-red-200">
161
+ <AlertDescription>{error}</AlertDescription>
162
+ </Alert>
163
+ )}
164
+
165
+ {/* Action Buttons */}
166
+ <div className="flex justify-end gap-x-2">
167
+ <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={isSubmitting}>
168
+ Cancel
169
+ </Button>
170
+ <Button type="submit" disabled={!stripe || isSubmitting}>
171
+ {isSubmitting ? "Processing..." : "Add Card"}
172
+ </Button>
173
+ </div>
174
+ </form>
175
+ )}
176
+
177
+ {/* Error State */}
178
+ {!loading && !setupIntent && error && (
179
+ <Alert variant="destructive" className="bg-red-50 border-red-200">
180
+ <AlertDescription>{error}</AlertDescription>
181
+ </Alert>
182
+ )}
183
+ </DialogContent>
184
+ </Dialog>
185
+ );
186
+ }
@@ -0,0 +1 @@
1
+ export * from "./PaymentMethodEditor";
@@ -0,0 +1,4 @@
1
+ export * from "./containers";
2
+ export * from "./details";
3
+ export * from "./forms";
4
+ export * from "./lists";
@@ -0,0 +1,19 @@
1
+ "use client";
2
+
3
+ import { PaymentMethodInterface } from "../../data";
4
+ import { PaymentMethodCard } from "../details/PaymentMethodCard";
5
+
6
+ type PaymentMethodsListProps = {
7
+ paymentMethods: PaymentMethodInterface[];
8
+ onUpdate: () => void;
9
+ };
10
+
11
+ export function PaymentMethodsList({ paymentMethods, onUpdate }: PaymentMethodsListProps) {
12
+ return (
13
+ <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
14
+ {paymentMethods.map((paymentMethod) => (
15
+ <PaymentMethodCard key={paymentMethod.id} paymentMethod={paymentMethod} onUpdate={onUpdate} />
16
+ ))}
17
+ </div>
18
+ );
19
+ }
@@ -0,0 +1 @@
1
+ export * from "./PaymentMethodsList";
@@ -0,0 +1,5 @@
1
+ export * from "./payment-method";
2
+ export * from "./payment-method.interface";
3
+ export * from "./stripe-customer";
4
+ export * from "./stripe-customer.interface";
5
+ export * from "./stripe-customer.service";
@@ -0,0 +1,27 @@
1
+ // ============================================================================
2
+ // Payment Method Interfaces
3
+ // ============================================================================
4
+
5
+ export interface PaymentMethodInterface {
6
+ id: string;
7
+ type: string;
8
+ card?: {
9
+ brand: string;
10
+ last4: string;
11
+ expMonth: number;
12
+ expYear: number;
13
+ };
14
+ billingDetails?: {
15
+ name?: string;
16
+ email?: string;
17
+ phone?: string;
18
+ address?: {
19
+ city?: string;
20
+ country?: string;
21
+ line1?: string;
22
+ line2?: string;
23
+ postalCode?: string;
24
+ state?: string;
25
+ };
26
+ };
27
+ }