@growflowstudio/growflowbilling-admin-core 2.0.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/LICENSE +21 -0
- package/dist/index.d.mts +447 -0
- package/dist/index.d.ts +447 -0
- package/dist/index.js +694 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +625 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +65 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
BillingAdminApiClient: () => BillingAdminApiClient,
|
|
24
|
+
BillingAdminClientContext: () => BillingAdminClientContext,
|
|
25
|
+
createBillingAdminClient: () => createBillingAdminClient,
|
|
26
|
+
formatCurrency: () => formatCurrency,
|
|
27
|
+
formatCurrencyFromCents: () => formatCurrencyFromCents,
|
|
28
|
+
formatDate: () => formatDate,
|
|
29
|
+
formatPrice: () => formatPrice,
|
|
30
|
+
formatTimestamp: () => formatTimestamp,
|
|
31
|
+
invoiceStatusColors: () => invoiceStatusColors,
|
|
32
|
+
invoiceStatusLabels: () => invoiceStatusLabels,
|
|
33
|
+
paymentStatusColors: () => paymentStatusColors,
|
|
34
|
+
paymentStatusLabels: () => paymentStatusLabels,
|
|
35
|
+
subscriptionStatusColors: () => subscriptionStatusColors,
|
|
36
|
+
subscriptionStatusLabels: () => subscriptionStatusLabels,
|
|
37
|
+
truncateId: () => truncateId,
|
|
38
|
+
useAdminFeatures: () => useAdminFeatures,
|
|
39
|
+
useAdminInvoices: () => useAdminInvoices,
|
|
40
|
+
useAdminPayments: () => useAdminPayments,
|
|
41
|
+
useAdminPlans: () => useAdminPlans,
|
|
42
|
+
useAdminProducts: () => useAdminProducts,
|
|
43
|
+
useAdminSubscriptions: () => useAdminSubscriptions,
|
|
44
|
+
useAvailableFeatures: () => useAvailableFeatures,
|
|
45
|
+
useBillingAdminClient: () => useBillingAdminClient,
|
|
46
|
+
useCancelSubscription: () => useCancelSubscription,
|
|
47
|
+
useChangeSubscriptionPlan: () => useChangeSubscriptionPlan,
|
|
48
|
+
useCreateFeature: () => useCreateFeature,
|
|
49
|
+
useCreatePlan: () => useCreatePlan,
|
|
50
|
+
useCreateProduct: () => useCreateProduct,
|
|
51
|
+
useCreateSubscription: () => useCreateSubscription,
|
|
52
|
+
useDeleteFeature: () => useDeleteFeature,
|
|
53
|
+
useDeletePlan: () => useDeletePlan,
|
|
54
|
+
useDeleteProduct: () => useDeleteProduct,
|
|
55
|
+
useDialogState: () => useDialogState,
|
|
56
|
+
useRefundPayment: () => useRefundPayment,
|
|
57
|
+
useSendInvoice: () => useSendInvoice,
|
|
58
|
+
useSyncPlanToStripe: () => useSyncPlanToStripe,
|
|
59
|
+
useSyncProductToStripe: () => useSyncProductToStripe,
|
|
60
|
+
useUpdateFeature: () => useUpdateFeature,
|
|
61
|
+
useUpdatePlan: () => useUpdatePlan,
|
|
62
|
+
useUpdateProduct: () => useUpdateProduct,
|
|
63
|
+
useVoidInvoice: () => useVoidInvoice,
|
|
64
|
+
validateRequired: () => validateRequired,
|
|
65
|
+
validateSlug: () => validateSlug
|
|
66
|
+
});
|
|
67
|
+
module.exports = __toCommonJS(index_exports);
|
|
68
|
+
|
|
69
|
+
// src/api/client.ts
|
|
70
|
+
function buildQuery(params) {
|
|
71
|
+
const searchParams = new URLSearchParams();
|
|
72
|
+
for (const [key, value] of Object.entries(params)) {
|
|
73
|
+
if (value !== void 0) {
|
|
74
|
+
searchParams.set(key, String(value));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const query = searchParams.toString();
|
|
78
|
+
return query ? `?${query}` : "";
|
|
79
|
+
}
|
|
80
|
+
var BillingAdminApiClient = class {
|
|
81
|
+
constructor(config) {
|
|
82
|
+
this.basePath = config.basePath;
|
|
83
|
+
this.fetcher = config.fetcher;
|
|
84
|
+
}
|
|
85
|
+
url(path) {
|
|
86
|
+
return `${this.basePath}${path}`;
|
|
87
|
+
}
|
|
88
|
+
// --- Plans ---
|
|
89
|
+
async getPlans(params) {
|
|
90
|
+
const query = buildQuery({ is_active: params?.is_active });
|
|
91
|
+
return this.fetcher(this.url(`/plans${query}`));
|
|
92
|
+
}
|
|
93
|
+
async getPlan(planId) {
|
|
94
|
+
return this.fetcher(this.url(`/plans/${planId}`));
|
|
95
|
+
}
|
|
96
|
+
async createPlan(data) {
|
|
97
|
+
return this.fetcher(this.url("/plans"), {
|
|
98
|
+
method: "POST",
|
|
99
|
+
body: JSON.stringify(data)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async updatePlan(planId, data) {
|
|
103
|
+
return this.fetcher(this.url(`/plans/${planId}`), {
|
|
104
|
+
method: "PATCH",
|
|
105
|
+
body: JSON.stringify(data)
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async deletePlan(planId) {
|
|
109
|
+
return this.fetcher(this.url(`/plans/${planId}`), { method: "DELETE" });
|
|
110
|
+
}
|
|
111
|
+
async syncPlanToStripe(planId) {
|
|
112
|
+
return this.fetcher(this.url(`/plans/${planId}/sync-stripe`), { method: "POST" });
|
|
113
|
+
}
|
|
114
|
+
// --- Subscriptions ---
|
|
115
|
+
async getSubscriptions(params) {
|
|
116
|
+
const query = buildQuery({
|
|
117
|
+
status: params?.status,
|
|
118
|
+
search: params?.search,
|
|
119
|
+
limit: params?.limit,
|
|
120
|
+
offset: params?.offset
|
|
121
|
+
});
|
|
122
|
+
return this.fetcher(this.url(`/subscriptions${query}`));
|
|
123
|
+
}
|
|
124
|
+
async getSubscription(subscriptionId) {
|
|
125
|
+
return this.fetcher(this.url(`/subscriptions/${subscriptionId}`));
|
|
126
|
+
}
|
|
127
|
+
async cancelSubscription(subscriptionId, atPeriodEnd = true) {
|
|
128
|
+
return this.fetcher(this.url(`/subscriptions/${subscriptionId}/cancel`), {
|
|
129
|
+
method: "POST",
|
|
130
|
+
body: JSON.stringify({ at_period_end: atPeriodEnd })
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
async createSubscription(data) {
|
|
134
|
+
return this.fetcher(this.url("/subscriptions"), {
|
|
135
|
+
method: "POST",
|
|
136
|
+
body: JSON.stringify(data)
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async changeSubscriptionPlan(subscriptionId, newPlanSlug) {
|
|
140
|
+
return this.fetcher(this.url(`/subscriptions/${subscriptionId}/change-plan`), {
|
|
141
|
+
method: "POST",
|
|
142
|
+
body: JSON.stringify({ new_plan_slug: newPlanSlug })
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// --- Payments ---
|
|
146
|
+
async getPayments(params) {
|
|
147
|
+
const query = buildQuery({
|
|
148
|
+
status: params?.status,
|
|
149
|
+
search: params?.search,
|
|
150
|
+
limit: params?.limit,
|
|
151
|
+
starting_after: params?.starting_after
|
|
152
|
+
});
|
|
153
|
+
return this.fetcher(this.url(`/payments${query}`));
|
|
154
|
+
}
|
|
155
|
+
async getPayment(paymentId) {
|
|
156
|
+
return this.fetcher(this.url(`/payments/${paymentId}`));
|
|
157
|
+
}
|
|
158
|
+
async refundPayment(paymentId, params) {
|
|
159
|
+
return this.fetcher(this.url(`/payments/${paymentId}/refund`), {
|
|
160
|
+
method: "POST",
|
|
161
|
+
body: JSON.stringify(params || {})
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
// --- Invoices ---
|
|
165
|
+
async getInvoices(params) {
|
|
166
|
+
const query = buildQuery({
|
|
167
|
+
status: params?.status,
|
|
168
|
+
search: params?.search,
|
|
169
|
+
store_id: params?.store_id,
|
|
170
|
+
limit: params?.limit,
|
|
171
|
+
starting_after: params?.starting_after
|
|
172
|
+
});
|
|
173
|
+
return this.fetcher(this.url(`/invoices${query}`));
|
|
174
|
+
}
|
|
175
|
+
async getInvoice(invoiceId) {
|
|
176
|
+
return this.fetcher(this.url(`/invoices/${invoiceId}`));
|
|
177
|
+
}
|
|
178
|
+
async sendInvoice(invoiceId) {
|
|
179
|
+
return this.fetcher(this.url(`/invoices/${invoiceId}/send`), { method: "POST" });
|
|
180
|
+
}
|
|
181
|
+
async voidInvoice(invoiceId) {
|
|
182
|
+
return this.fetcher(this.url(`/invoices/${invoiceId}/void`), { method: "POST" });
|
|
183
|
+
}
|
|
184
|
+
// --- Products ---
|
|
185
|
+
async getProducts(params) {
|
|
186
|
+
const query = buildQuery({ is_active: params?.is_active });
|
|
187
|
+
return this.fetcher(this.url(`/products${query}`));
|
|
188
|
+
}
|
|
189
|
+
async getProduct(productId) {
|
|
190
|
+
return this.fetcher(this.url(`/products/${productId}`));
|
|
191
|
+
}
|
|
192
|
+
async createProduct(data) {
|
|
193
|
+
return this.fetcher(this.url("/products"), {
|
|
194
|
+
method: "POST",
|
|
195
|
+
body: JSON.stringify(data)
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async updateProduct(productId, data) {
|
|
199
|
+
return this.fetcher(this.url(`/products/${productId}`), {
|
|
200
|
+
method: "PATCH",
|
|
201
|
+
body: JSON.stringify(data)
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
async deleteProduct(productId) {
|
|
205
|
+
return this.fetcher(this.url(`/products/${productId}`), { method: "DELETE" });
|
|
206
|
+
}
|
|
207
|
+
async syncProductToStripe(productId) {
|
|
208
|
+
return this.fetcher(this.url(`/products/${productId}/sync-stripe`), { method: "POST" });
|
|
209
|
+
}
|
|
210
|
+
// --- Features ---
|
|
211
|
+
async getFeatures(params) {
|
|
212
|
+
const query = buildQuery({
|
|
213
|
+
available_only: params?.available_only,
|
|
214
|
+
category: params?.category
|
|
215
|
+
});
|
|
216
|
+
return this.fetcher(this.url(`/features${query}`));
|
|
217
|
+
}
|
|
218
|
+
async getAvailableFeatures(category) {
|
|
219
|
+
const query = buildQuery({ category });
|
|
220
|
+
return this.fetcher(this.url(`/features/available${query}`));
|
|
221
|
+
}
|
|
222
|
+
async getFeature(featureId) {
|
|
223
|
+
return this.fetcher(this.url(`/features/${featureId}`));
|
|
224
|
+
}
|
|
225
|
+
async createFeature(data) {
|
|
226
|
+
return this.fetcher(this.url("/features"), {
|
|
227
|
+
method: "POST",
|
|
228
|
+
body: JSON.stringify(data)
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
async updateFeature(featureId, data) {
|
|
232
|
+
return this.fetcher(this.url(`/features/${featureId}`), {
|
|
233
|
+
method: "PATCH",
|
|
234
|
+
body: JSON.stringify(data)
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
async deleteFeature(featureId) {
|
|
238
|
+
return this.fetcher(this.url(`/features/${featureId}`), { method: "DELETE" });
|
|
239
|
+
}
|
|
240
|
+
// --- Client Info ---
|
|
241
|
+
async getClientInfo() {
|
|
242
|
+
return this.fetcher(this.url("/client-info"));
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
function createBillingAdminClient(config) {
|
|
246
|
+
return new BillingAdminApiClient(config);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// src/hooks/context.ts
|
|
250
|
+
var import_react = require("react");
|
|
251
|
+
var BillingAdminClientContext = (0, import_react.createContext)(null);
|
|
252
|
+
function useBillingAdminClient() {
|
|
253
|
+
const client = (0, import_react.useContext)(BillingAdminClientContext);
|
|
254
|
+
if (!client) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
"useBillingAdminClient must be used within a BillingAdminProvider. Wrap your component tree with <BillingAdminProvider config={{...}}>."
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
return client;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/hooks/useDialogState.ts
|
|
263
|
+
var import_react2 = require("react");
|
|
264
|
+
function useDialogState() {
|
|
265
|
+
const [isOpen, setIsOpen] = (0, import_react2.useState)(false);
|
|
266
|
+
const [data, setData] = (0, import_react2.useState)(void 0);
|
|
267
|
+
const open = (0, import_react2.useCallback)((initialData) => {
|
|
268
|
+
setData(initialData);
|
|
269
|
+
setIsOpen(true);
|
|
270
|
+
}, []);
|
|
271
|
+
const close = (0, import_react2.useCallback)(() => {
|
|
272
|
+
setIsOpen(false);
|
|
273
|
+
setTimeout(() => setData(void 0), 150);
|
|
274
|
+
}, []);
|
|
275
|
+
const toggle = (0, import_react2.useCallback)(() => {
|
|
276
|
+
if (isOpen) {
|
|
277
|
+
close();
|
|
278
|
+
} else {
|
|
279
|
+
open();
|
|
280
|
+
}
|
|
281
|
+
}, [isOpen, open, close]);
|
|
282
|
+
return {
|
|
283
|
+
isOpen,
|
|
284
|
+
data,
|
|
285
|
+
open,
|
|
286
|
+
close,
|
|
287
|
+
toggle,
|
|
288
|
+
setData
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// src/hooks/usePlans.ts
|
|
293
|
+
var import_react_query = require("@tanstack/react-query");
|
|
294
|
+
var PLANS_KEY = "billing-admin-plans";
|
|
295
|
+
function useAdminPlans(params) {
|
|
296
|
+
const client = useBillingAdminClient();
|
|
297
|
+
return (0, import_react_query.useQuery)({
|
|
298
|
+
queryKey: [PLANS_KEY, params],
|
|
299
|
+
queryFn: () => client.getPlans(params)
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
function useCreatePlan() {
|
|
303
|
+
const client = useBillingAdminClient();
|
|
304
|
+
const queryClient = (0, import_react_query.useQueryClient)();
|
|
305
|
+
return (0, import_react_query.useMutation)({
|
|
306
|
+
mutationFn: (data) => client.createPlan(data),
|
|
307
|
+
onSuccess: () => {
|
|
308
|
+
queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
function useUpdatePlan() {
|
|
313
|
+
const client = useBillingAdminClient();
|
|
314
|
+
const queryClient = (0, import_react_query.useQueryClient)();
|
|
315
|
+
return (0, import_react_query.useMutation)({
|
|
316
|
+
mutationFn: ({ id, data }) => client.updatePlan(id, data),
|
|
317
|
+
onSuccess: () => {
|
|
318
|
+
queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
function useDeletePlan() {
|
|
323
|
+
const client = useBillingAdminClient();
|
|
324
|
+
const queryClient = (0, import_react_query.useQueryClient)();
|
|
325
|
+
return (0, import_react_query.useMutation)({
|
|
326
|
+
mutationFn: (id) => client.deletePlan(id),
|
|
327
|
+
onSuccess: () => {
|
|
328
|
+
queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
function useSyncPlanToStripe() {
|
|
333
|
+
const client = useBillingAdminClient();
|
|
334
|
+
const queryClient = (0, import_react_query.useQueryClient)();
|
|
335
|
+
return (0, import_react_query.useMutation)({
|
|
336
|
+
mutationFn: (id) => client.syncPlanToStripe(id),
|
|
337
|
+
onSuccess: () => {
|
|
338
|
+
queryClient.invalidateQueries({ queryKey: [PLANS_KEY] });
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// src/hooks/useSubscriptions.ts
|
|
344
|
+
var import_react_query2 = require("@tanstack/react-query");
|
|
345
|
+
var SUBSCRIPTIONS_KEY = "billing-admin-subscriptions";
|
|
346
|
+
function useAdminSubscriptions(params) {
|
|
347
|
+
const client = useBillingAdminClient();
|
|
348
|
+
return (0, import_react_query2.useQuery)({
|
|
349
|
+
queryKey: [SUBSCRIPTIONS_KEY, params],
|
|
350
|
+
queryFn: () => client.getSubscriptions(params)
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
function useCreateSubscription() {
|
|
354
|
+
const client = useBillingAdminClient();
|
|
355
|
+
const queryClient = (0, import_react_query2.useQueryClient)();
|
|
356
|
+
return (0, import_react_query2.useMutation)({
|
|
357
|
+
mutationFn: (data) => client.createSubscription(data),
|
|
358
|
+
onSuccess: () => {
|
|
359
|
+
queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
function useCancelSubscription() {
|
|
364
|
+
const client = useBillingAdminClient();
|
|
365
|
+
const queryClient = (0, import_react_query2.useQueryClient)();
|
|
366
|
+
return (0, import_react_query2.useMutation)({
|
|
367
|
+
mutationFn: ({ id, atPeriodEnd }) => client.cancelSubscription(id, atPeriodEnd),
|
|
368
|
+
onSuccess: () => {
|
|
369
|
+
queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
function useChangeSubscriptionPlan() {
|
|
374
|
+
const client = useBillingAdminClient();
|
|
375
|
+
const queryClient = (0, import_react_query2.useQueryClient)();
|
|
376
|
+
return (0, import_react_query2.useMutation)({
|
|
377
|
+
mutationFn: ({ id, newPlanSlug }) => client.changeSubscriptionPlan(id, newPlanSlug),
|
|
378
|
+
onSuccess: () => {
|
|
379
|
+
queryClient.invalidateQueries({ queryKey: [SUBSCRIPTIONS_KEY] });
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// src/hooks/usePayments.ts
|
|
385
|
+
var import_react_query3 = require("@tanstack/react-query");
|
|
386
|
+
var PAYMENTS_KEY = "billing-admin-payments";
|
|
387
|
+
function useAdminPayments(params) {
|
|
388
|
+
const client = useBillingAdminClient();
|
|
389
|
+
return (0, import_react_query3.useQuery)({
|
|
390
|
+
queryKey: [PAYMENTS_KEY, params],
|
|
391
|
+
queryFn: () => client.getPayments(params)
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
function useRefundPayment() {
|
|
395
|
+
const client = useBillingAdminClient();
|
|
396
|
+
const queryClient = (0, import_react_query3.useQueryClient)();
|
|
397
|
+
return (0, import_react_query3.useMutation)({
|
|
398
|
+
mutationFn: ({ id, amount, reason }) => client.refundPayment(id, { amount, reason }),
|
|
399
|
+
onSuccess: () => {
|
|
400
|
+
queryClient.invalidateQueries({ queryKey: [PAYMENTS_KEY] });
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// src/hooks/useInvoices.ts
|
|
406
|
+
var import_react_query4 = require("@tanstack/react-query");
|
|
407
|
+
var INVOICES_KEY = "billing-admin-invoices";
|
|
408
|
+
function useAdminInvoices(params) {
|
|
409
|
+
const client = useBillingAdminClient();
|
|
410
|
+
return (0, import_react_query4.useQuery)({
|
|
411
|
+
queryKey: [INVOICES_KEY, params],
|
|
412
|
+
queryFn: () => client.getInvoices(params)
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
function useSendInvoice() {
|
|
416
|
+
const client = useBillingAdminClient();
|
|
417
|
+
const queryClient = (0, import_react_query4.useQueryClient)();
|
|
418
|
+
return (0, import_react_query4.useMutation)({
|
|
419
|
+
mutationFn: (id) => client.sendInvoice(id),
|
|
420
|
+
onSuccess: () => {
|
|
421
|
+
queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
function useVoidInvoice() {
|
|
426
|
+
const client = useBillingAdminClient();
|
|
427
|
+
const queryClient = (0, import_react_query4.useQueryClient)();
|
|
428
|
+
return (0, import_react_query4.useMutation)({
|
|
429
|
+
mutationFn: (id) => client.voidInvoice(id),
|
|
430
|
+
onSuccess: () => {
|
|
431
|
+
queryClient.invalidateQueries({ queryKey: [INVOICES_KEY] });
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// src/hooks/useProducts.ts
|
|
437
|
+
var import_react_query5 = require("@tanstack/react-query");
|
|
438
|
+
var PRODUCTS_KEY = "billing-admin-products";
|
|
439
|
+
function useAdminProducts(params) {
|
|
440
|
+
const client = useBillingAdminClient();
|
|
441
|
+
return (0, import_react_query5.useQuery)({
|
|
442
|
+
queryKey: [PRODUCTS_KEY, params],
|
|
443
|
+
queryFn: () => client.getProducts(params)
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
function useCreateProduct() {
|
|
447
|
+
const client = useBillingAdminClient();
|
|
448
|
+
const queryClient = (0, import_react_query5.useQueryClient)();
|
|
449
|
+
return (0, import_react_query5.useMutation)({
|
|
450
|
+
mutationFn: (data) => client.createProduct(data),
|
|
451
|
+
onSuccess: () => {
|
|
452
|
+
queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
function useUpdateProduct() {
|
|
457
|
+
const client = useBillingAdminClient();
|
|
458
|
+
const queryClient = (0, import_react_query5.useQueryClient)();
|
|
459
|
+
return (0, import_react_query5.useMutation)({
|
|
460
|
+
mutationFn: ({ id, data }) => client.updateProduct(id, data),
|
|
461
|
+
onSuccess: () => {
|
|
462
|
+
queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
function useDeleteProduct() {
|
|
467
|
+
const client = useBillingAdminClient();
|
|
468
|
+
const queryClient = (0, import_react_query5.useQueryClient)();
|
|
469
|
+
return (0, import_react_query5.useMutation)({
|
|
470
|
+
mutationFn: (id) => client.deleteProduct(id),
|
|
471
|
+
onSuccess: () => {
|
|
472
|
+
queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function useSyncProductToStripe() {
|
|
477
|
+
const client = useBillingAdminClient();
|
|
478
|
+
const queryClient = (0, import_react_query5.useQueryClient)();
|
|
479
|
+
return (0, import_react_query5.useMutation)({
|
|
480
|
+
mutationFn: (id) => client.syncProductToStripe(id),
|
|
481
|
+
onSuccess: () => {
|
|
482
|
+
queryClient.invalidateQueries({ queryKey: [PRODUCTS_KEY] });
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// src/hooks/useFeatures.ts
|
|
488
|
+
var import_react_query6 = require("@tanstack/react-query");
|
|
489
|
+
function useAdminFeatures(params) {
|
|
490
|
+
const client = useBillingAdminClient();
|
|
491
|
+
return (0, import_react_query6.useQuery)({
|
|
492
|
+
queryKey: ["billing-admin", "features", params],
|
|
493
|
+
queryFn: () => client.getFeatures(params)
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
function useAvailableFeatures(category) {
|
|
497
|
+
const client = useBillingAdminClient();
|
|
498
|
+
return (0, import_react_query6.useQuery)({
|
|
499
|
+
queryKey: ["billing-admin", "features", "available", category],
|
|
500
|
+
queryFn: () => client.getAvailableFeatures(category)
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
function useCreateFeature() {
|
|
504
|
+
const client = useBillingAdminClient();
|
|
505
|
+
const queryClient = (0, import_react_query6.useQueryClient)();
|
|
506
|
+
return (0, import_react_query6.useMutation)({
|
|
507
|
+
mutationFn: (data) => client.createFeature(data),
|
|
508
|
+
onSuccess: () => {
|
|
509
|
+
queryClient.invalidateQueries({ queryKey: ["billing-admin", "features"] });
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
function useUpdateFeature() {
|
|
514
|
+
const client = useBillingAdminClient();
|
|
515
|
+
const queryClient = (0, import_react_query6.useQueryClient)();
|
|
516
|
+
return (0, import_react_query6.useMutation)({
|
|
517
|
+
mutationFn: ({ id, data }) => client.updateFeature(id, data),
|
|
518
|
+
onSuccess: () => {
|
|
519
|
+
queryClient.invalidateQueries({ queryKey: ["billing-admin", "features"] });
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
function useDeleteFeature() {
|
|
524
|
+
const client = useBillingAdminClient();
|
|
525
|
+
const queryClient = (0, import_react_query6.useQueryClient)();
|
|
526
|
+
return (0, import_react_query6.useMutation)({
|
|
527
|
+
mutationFn: (id) => client.deleteFeature(id),
|
|
528
|
+
onSuccess: () => {
|
|
529
|
+
queryClient.invalidateQueries({ queryKey: ["billing-admin", "features"] });
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// src/utils/formatters.ts
|
|
535
|
+
function formatCurrency(amount, currency = "EUR", locale = "it-IT") {
|
|
536
|
+
return new Intl.NumberFormat(locale, {
|
|
537
|
+
style: "currency",
|
|
538
|
+
currency: currency.toUpperCase()
|
|
539
|
+
}).format(amount);
|
|
540
|
+
}
|
|
541
|
+
function formatCurrencyFromCents(amountCents, currency = "EUR", locale = "it-IT") {
|
|
542
|
+
return formatCurrency(amountCents / 100, currency, locale);
|
|
543
|
+
}
|
|
544
|
+
function formatPrice(price, currency = "EUR", locale = "it-IT") {
|
|
545
|
+
if (price === null) return "Contattaci";
|
|
546
|
+
return new Intl.NumberFormat(locale, {
|
|
547
|
+
style: "currency",
|
|
548
|
+
currency: currency.toUpperCase(),
|
|
549
|
+
minimumFractionDigits: 0,
|
|
550
|
+
maximumFractionDigits: 0
|
|
551
|
+
}).format(price);
|
|
552
|
+
}
|
|
553
|
+
function formatDate(date, locale = "it-IT") {
|
|
554
|
+
if (!date) return "N/A";
|
|
555
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
556
|
+
if (isNaN(d.getTime())) return "N/A";
|
|
557
|
+
return new Intl.DateTimeFormat(locale, {
|
|
558
|
+
day: "numeric",
|
|
559
|
+
month: "short",
|
|
560
|
+
year: "numeric"
|
|
561
|
+
}).format(d);
|
|
562
|
+
}
|
|
563
|
+
function formatTimestamp(timestamp, includeTime = false, locale = "it-IT") {
|
|
564
|
+
if (!timestamp) return "-";
|
|
565
|
+
const date = new Date(timestamp * 1e3);
|
|
566
|
+
if (includeTime) {
|
|
567
|
+
return date.toLocaleDateString(locale, {
|
|
568
|
+
day: "2-digit",
|
|
569
|
+
month: "short",
|
|
570
|
+
year: "numeric",
|
|
571
|
+
hour: "2-digit",
|
|
572
|
+
minute: "2-digit"
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
return date.toLocaleDateString(locale, {
|
|
576
|
+
day: "2-digit",
|
|
577
|
+
month: "short",
|
|
578
|
+
year: "numeric"
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
function truncateId(id, maxLength = 20) {
|
|
582
|
+
if (id.length <= maxLength) return id;
|
|
583
|
+
return `${id.slice(0, 10)}...${id.slice(-6)}`;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// src/utils/status.ts
|
|
587
|
+
var subscriptionStatusColors = {
|
|
588
|
+
active: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
|
|
589
|
+
trialing: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400",
|
|
590
|
+
past_due: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400",
|
|
591
|
+
canceled: "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400",
|
|
592
|
+
unpaid: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400",
|
|
593
|
+
incomplete: "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400"
|
|
594
|
+
};
|
|
595
|
+
var subscriptionStatusLabels = {
|
|
596
|
+
active: "Attivo",
|
|
597
|
+
trialing: "In Prova",
|
|
598
|
+
past_due: "Scaduto",
|
|
599
|
+
canceled: "Cancellato",
|
|
600
|
+
unpaid: "Non Pagato",
|
|
601
|
+
incomplete: "Incompleto"
|
|
602
|
+
};
|
|
603
|
+
var paymentStatusColors = {
|
|
604
|
+
succeeded: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
|
|
605
|
+
pending: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400",
|
|
606
|
+
failed: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400",
|
|
607
|
+
canceled: "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400",
|
|
608
|
+
requires_payment_method: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
|
|
609
|
+
};
|
|
610
|
+
var paymentStatusLabels = {
|
|
611
|
+
succeeded: "Completato",
|
|
612
|
+
pending: "In Attesa",
|
|
613
|
+
failed: "Fallito",
|
|
614
|
+
canceled: "Annullato",
|
|
615
|
+
requires_payment_method: "Richiede Pagamento"
|
|
616
|
+
};
|
|
617
|
+
var invoiceStatusColors = {
|
|
618
|
+
draft: "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400",
|
|
619
|
+
open: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400",
|
|
620
|
+
paid: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
|
|
621
|
+
void: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400",
|
|
622
|
+
uncollectible: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
|
|
623
|
+
};
|
|
624
|
+
var invoiceStatusLabels = {
|
|
625
|
+
draft: "Bozza",
|
|
626
|
+
open: "Aperta",
|
|
627
|
+
paid: "Pagata",
|
|
628
|
+
void: "Annullata",
|
|
629
|
+
uncollectible: "Non Riscuotibile"
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
// src/utils/validators.ts
|
|
633
|
+
function validateSlug(slug) {
|
|
634
|
+
if (!slug.trim()) {
|
|
635
|
+
return "Lo slug \xE8 obbligatorio";
|
|
636
|
+
}
|
|
637
|
+
if (!/^[a-z0-9-]+$/.test(slug)) {
|
|
638
|
+
return "Lo slug pu\xF2 contenere solo lettere minuscole, numeri e trattini";
|
|
639
|
+
}
|
|
640
|
+
return null;
|
|
641
|
+
}
|
|
642
|
+
function validateRequired(value, fieldName) {
|
|
643
|
+
if (!value.trim()) {
|
|
644
|
+
return `${fieldName} \xE8 obbligatorio`;
|
|
645
|
+
}
|
|
646
|
+
return null;
|
|
647
|
+
}
|
|
648
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
649
|
+
0 && (module.exports = {
|
|
650
|
+
BillingAdminApiClient,
|
|
651
|
+
BillingAdminClientContext,
|
|
652
|
+
createBillingAdminClient,
|
|
653
|
+
formatCurrency,
|
|
654
|
+
formatCurrencyFromCents,
|
|
655
|
+
formatDate,
|
|
656
|
+
formatPrice,
|
|
657
|
+
formatTimestamp,
|
|
658
|
+
invoiceStatusColors,
|
|
659
|
+
invoiceStatusLabels,
|
|
660
|
+
paymentStatusColors,
|
|
661
|
+
paymentStatusLabels,
|
|
662
|
+
subscriptionStatusColors,
|
|
663
|
+
subscriptionStatusLabels,
|
|
664
|
+
truncateId,
|
|
665
|
+
useAdminFeatures,
|
|
666
|
+
useAdminInvoices,
|
|
667
|
+
useAdminPayments,
|
|
668
|
+
useAdminPlans,
|
|
669
|
+
useAdminProducts,
|
|
670
|
+
useAdminSubscriptions,
|
|
671
|
+
useAvailableFeatures,
|
|
672
|
+
useBillingAdminClient,
|
|
673
|
+
useCancelSubscription,
|
|
674
|
+
useChangeSubscriptionPlan,
|
|
675
|
+
useCreateFeature,
|
|
676
|
+
useCreatePlan,
|
|
677
|
+
useCreateProduct,
|
|
678
|
+
useCreateSubscription,
|
|
679
|
+
useDeleteFeature,
|
|
680
|
+
useDeletePlan,
|
|
681
|
+
useDeleteProduct,
|
|
682
|
+
useDialogState,
|
|
683
|
+
useRefundPayment,
|
|
684
|
+
useSendInvoice,
|
|
685
|
+
useSyncPlanToStripe,
|
|
686
|
+
useSyncProductToStripe,
|
|
687
|
+
useUpdateFeature,
|
|
688
|
+
useUpdatePlan,
|
|
689
|
+
useUpdateProduct,
|
|
690
|
+
useVoidInvoice,
|
|
691
|
+
validateRequired,
|
|
692
|
+
validateSlug
|
|
693
|
+
});
|
|
694
|
+
//# sourceMappingURL=index.js.map
|