@djangocfg/ext-payments 1.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.
Files changed (67) hide show
  1. package/README.md +206 -0
  2. package/dist/chunk-5KY6HVXF.js +2593 -0
  3. package/dist/hooks.cjs +2666 -0
  4. package/dist/hooks.d.cts +186 -0
  5. package/dist/hooks.d.ts +186 -0
  6. package/dist/hooks.js +1 -0
  7. package/dist/index.cjs +2590 -0
  8. package/dist/index.d.cts +1287 -0
  9. package/dist/index.d.ts +1287 -0
  10. package/dist/index.js +1 -0
  11. package/package.json +79 -0
  12. package/src/api/generated/ext_payments/_utils/fetchers/ext_payments__payments.ts +408 -0
  13. package/src/api/generated/ext_payments/_utils/fetchers/index.ts +28 -0
  14. package/src/api/generated/ext_payments/_utils/hooks/ext_payments__payments.ts +147 -0
  15. package/src/api/generated/ext_payments/_utils/hooks/index.ts +28 -0
  16. package/src/api/generated/ext_payments/_utils/schemas/Balance.schema.ts +23 -0
  17. package/src/api/generated/ext_payments/_utils/schemas/Currency.schema.ts +28 -0
  18. package/src/api/generated/ext_payments/_utils/schemas/PaginatedPaymentListList.schema.ts +24 -0
  19. package/src/api/generated/ext_payments/_utils/schemas/PaymentDetail.schema.ts +44 -0
  20. package/src/api/generated/ext_payments/_utils/schemas/PaymentList.schema.ts +28 -0
  21. package/src/api/generated/ext_payments/_utils/schemas/Transaction.schema.ts +28 -0
  22. package/src/api/generated/ext_payments/_utils/schemas/index.ts +24 -0
  23. package/src/api/generated/ext_payments/api-instance.ts +131 -0
  24. package/src/api/generated/ext_payments/client.ts +301 -0
  25. package/src/api/generated/ext_payments/enums.ts +64 -0
  26. package/src/api/generated/ext_payments/errors.ts +116 -0
  27. package/src/api/generated/ext_payments/ext_payments__payments/client.ts +118 -0
  28. package/src/api/generated/ext_payments/ext_payments__payments/index.ts +2 -0
  29. package/src/api/generated/ext_payments/ext_payments__payments/models.ts +135 -0
  30. package/src/api/generated/ext_payments/http.ts +103 -0
  31. package/src/api/generated/ext_payments/index.ts +273 -0
  32. package/src/api/generated/ext_payments/logger.ts +259 -0
  33. package/src/api/generated/ext_payments/retry.ts +175 -0
  34. package/src/api/generated/ext_payments/schema.json +850 -0
  35. package/src/api/generated/ext_payments/storage.ts +161 -0
  36. package/src/api/generated/ext_payments/validation-events.ts +133 -0
  37. package/src/api/index.ts +9 -0
  38. package/src/config.ts +20 -0
  39. package/src/contexts/BalancesContext.tsx +62 -0
  40. package/src/contexts/CurrenciesContext.tsx +63 -0
  41. package/src/contexts/OverviewContext.tsx +173 -0
  42. package/src/contexts/PaymentsContext.tsx +121 -0
  43. package/src/contexts/PaymentsExtensionProvider.tsx +55 -0
  44. package/src/contexts/README.md +201 -0
  45. package/src/contexts/RootPaymentsContext.tsx +65 -0
  46. package/src/contexts/index.ts +45 -0
  47. package/src/contexts/types.ts +40 -0
  48. package/src/hooks/index.ts +20 -0
  49. package/src/index.ts +36 -0
  50. package/src/layouts/PaymentsLayout/PaymentsLayout.tsx +92 -0
  51. package/src/layouts/PaymentsLayout/components/CreatePaymentDialog.tsx +291 -0
  52. package/src/layouts/PaymentsLayout/components/PaymentDetailsDialog.tsx +290 -0
  53. package/src/layouts/PaymentsLayout/components/index.ts +2 -0
  54. package/src/layouts/PaymentsLayout/events.ts +47 -0
  55. package/src/layouts/PaymentsLayout/index.ts +16 -0
  56. package/src/layouts/PaymentsLayout/types.ts +6 -0
  57. package/src/layouts/PaymentsLayout/views/overview/components/BalanceCard.tsx +128 -0
  58. package/src/layouts/PaymentsLayout/views/overview/components/RecentPayments.tsx +142 -0
  59. package/src/layouts/PaymentsLayout/views/overview/components/index.ts +2 -0
  60. package/src/layouts/PaymentsLayout/views/overview/index.tsx +20 -0
  61. package/src/layouts/PaymentsLayout/views/payments/components/PaymentsList.tsx +277 -0
  62. package/src/layouts/PaymentsLayout/views/payments/components/index.ts +1 -0
  63. package/src/layouts/PaymentsLayout/views/payments/index.tsx +17 -0
  64. package/src/layouts/PaymentsLayout/views/transactions/components/TransactionsList.tsx +273 -0
  65. package/src/layouts/PaymentsLayout/views/transactions/components/index.ts +1 -0
  66. package/src/layouts/PaymentsLayout/views/transactions/index.tsx +17 -0
  67. package/src/utils/logger.ts +9 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,2590 @@
1
+ 'use strict';
2
+
3
+ var consola = require('consola');
4
+ var pRetry = require('p-retry');
5
+ var zod = require('zod');
6
+ var api = require('@djangocfg/ext-base/api');
7
+ var react = require('react');
8
+ var useSWR = require('swr');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+ var uiNextjs = require('@djangocfg/ui-nextjs');
11
+ var lucideReact = require('lucide-react');
12
+ var reactHookForm = require('react-hook-form');
13
+ var zod$1 = require('@hookform/resolvers/zod');
14
+
15
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
+
17
+ var pRetry__default = /*#__PURE__*/_interopDefault(pRetry);
18
+ var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
19
+
20
+ var __defProp = Object.defineProperty;
21
+ var __export = (target, all) => {
22
+ for (var name in all)
23
+ __defProp(target, name, { get: all[name], enumerable: true });
24
+ };
25
+
26
+ // src/api/generated/ext_payments/ext_payments__payments/client.ts
27
+ var ExtPaymentsPayments = class {
28
+ client;
29
+ constructor(client) {
30
+ this.client = client;
31
+ }
32
+ /**
33
+ * Get user balance
34
+ *
35
+ * Get current user balance and transaction statistics
36
+ */
37
+ async balanceRetrieve() {
38
+ const response = await this.client.request("GET", "/cfg/payments/balance/");
39
+ return response;
40
+ }
41
+ /**
42
+ * Get available currencies
43
+ *
44
+ * Returns list of available currencies with token+network info
45
+ */
46
+ async currenciesList() {
47
+ const response = await this.client.request("GET", "/cfg/payments/currencies/");
48
+ return response;
49
+ }
50
+ /**
51
+ * ViewSet for payment operations. Endpoints: - GET /payments/ - List
52
+ * user's payments - GET /payments/{id}/ - Get payment details - POST
53
+ * /payments/create/ - Create new payment - GET /payments/{id}/status/ -
54
+ * Check payment status - POST /payments/{id}/confirm/ - Confirm payment
55
+ */
56
+ async paymentsList(...args) {
57
+ const isParamsObject = args.length === 1 && typeof args[0] === "object" && args[0] !== null && !Array.isArray(args[0]);
58
+ let params;
59
+ if (isParamsObject) {
60
+ params = args[0];
61
+ } else {
62
+ params = { page: args[0], page_size: args[1] };
63
+ }
64
+ const response = await this.client.request("GET", "/cfg/payments/payments/", { params });
65
+ return response;
66
+ }
67
+ /**
68
+ * ViewSet for payment operations. Endpoints: - GET /payments/ - List
69
+ * user's payments - GET /payments/{id}/ - Get payment details - POST
70
+ * /payments/create/ - Create new payment - GET /payments/{id}/status/ -
71
+ * Check payment status - POST /payments/{id}/confirm/ - Confirm payment
72
+ */
73
+ async paymentsRetrieve(id) {
74
+ const response = await this.client.request("GET", `/cfg/payments/payments/${id}/`);
75
+ return response;
76
+ }
77
+ /**
78
+ * POST /api/v1/payments/{id}/confirm/ Confirm payment (user clicked "I
79
+ * have paid"). Checks status with provider and creates transaction if
80
+ * completed.
81
+ */
82
+ async paymentsConfirmCreate(id) {
83
+ const response = await this.client.request("POST", `/cfg/payments/payments/${id}/confirm/`);
84
+ return response;
85
+ }
86
+ /**
87
+ * GET /api/v1/payments/{id}/status/?refresh=true Check payment status
88
+ * (with optional refresh from provider). Query params: - refresh: boolean
89
+ * (default: false) - Force refresh from provider
90
+ */
91
+ async paymentsStatusRetrieve(id) {
92
+ const response = await this.client.request("GET", `/cfg/payments/payments/${id}/status/`);
93
+ return response.results || response;
94
+ }
95
+ /**
96
+ * POST /api/v1/payments/create/ Create new payment. Request body: {
97
+ * "amount_usd": "100.00", "currency_code": "USDTTRC20", "description":
98
+ * "Optional description" }
99
+ */
100
+ async paymentsCreateCreate() {
101
+ const response = await this.client.request("POST", "/cfg/payments/payments/create/");
102
+ return response;
103
+ }
104
+ /**
105
+ * Get user transactions
106
+ *
107
+ * Get user transactions with pagination and filtering
108
+ */
109
+ async transactionsList(...args) {
110
+ const isParamsObject = args.length === 1 && typeof args[0] === "object" && args[0] !== null && !Array.isArray(args[0]);
111
+ let params;
112
+ if (isParamsObject) {
113
+ params = args[0];
114
+ } else {
115
+ params = { limit: args[0], offset: args[1], type: args[2] };
116
+ }
117
+ const response = await this.client.request("GET", "/cfg/payments/transactions/", { params });
118
+ return response;
119
+ }
120
+ };
121
+
122
+ // src/api/generated/ext_payments/ext_payments__payments/models.ts
123
+ var models_exports = {};
124
+
125
+ // src/api/generated/ext_payments/http.ts
126
+ var FetchAdapter = class {
127
+ async request(request) {
128
+ const { method, url, headers, body, params, formData } = request;
129
+ let finalUrl = url;
130
+ if (params) {
131
+ const searchParams = new URLSearchParams();
132
+ Object.entries(params).forEach(([key, value]) => {
133
+ if (value !== null && value !== void 0) {
134
+ searchParams.append(key, String(value));
135
+ }
136
+ });
137
+ const queryString = searchParams.toString();
138
+ if (queryString) {
139
+ finalUrl = url.includes("?") ? `${url}&${queryString}` : `${url}?${queryString}`;
140
+ }
141
+ }
142
+ const finalHeaders = { ...headers };
143
+ let requestBody;
144
+ if (formData) {
145
+ requestBody = formData;
146
+ } else if (body) {
147
+ finalHeaders["Content-Type"] = "application/json";
148
+ requestBody = JSON.stringify(body);
149
+ }
150
+ const response = await fetch(finalUrl, {
151
+ method,
152
+ headers: finalHeaders,
153
+ body: requestBody,
154
+ credentials: "include"
155
+ // Include Django session cookies
156
+ });
157
+ let data = null;
158
+ const contentType = response.headers.get("content-type");
159
+ if (response.status !== 204 && contentType?.includes("application/json")) {
160
+ data = await response.json();
161
+ } else if (response.status !== 204) {
162
+ data = await response.text();
163
+ }
164
+ const responseHeaders = {};
165
+ response.headers.forEach((value, key) => {
166
+ responseHeaders[key] = value;
167
+ });
168
+ return {
169
+ data,
170
+ status: response.status,
171
+ statusText: response.statusText,
172
+ headers: responseHeaders
173
+ };
174
+ }
175
+ };
176
+
177
+ // src/api/generated/ext_payments/errors.ts
178
+ var APIError = class extends Error {
179
+ constructor(statusCode, statusText, response, url, message) {
180
+ super(message || `HTTP ${statusCode}: ${statusText}`);
181
+ this.statusCode = statusCode;
182
+ this.statusText = statusText;
183
+ this.response = response;
184
+ this.url = url;
185
+ this.name = "APIError";
186
+ }
187
+ /**
188
+ * Get error details from response.
189
+ * DRF typically returns: { "detail": "Error message" } or { "field": ["error1", "error2"] }
190
+ */
191
+ get details() {
192
+ if (typeof this.response === "object" && this.response !== null) {
193
+ return this.response;
194
+ }
195
+ return null;
196
+ }
197
+ /**
198
+ * Get field-specific validation errors from DRF.
199
+ * Returns: { "field_name": ["error1", "error2"], ... }
200
+ */
201
+ get fieldErrors() {
202
+ const details = this.details;
203
+ if (!details) return null;
204
+ const fieldErrors = {};
205
+ for (const [key, value] of Object.entries(details)) {
206
+ if (Array.isArray(value)) {
207
+ fieldErrors[key] = value;
208
+ }
209
+ }
210
+ return Object.keys(fieldErrors).length > 0 ? fieldErrors : null;
211
+ }
212
+ /**
213
+ * Get single error message from DRF.
214
+ * Checks for "detail", "message", or first field error.
215
+ */
216
+ get errorMessage() {
217
+ const details = this.details;
218
+ if (!details) return this.message;
219
+ if (details.detail) {
220
+ return Array.isArray(details.detail) ? details.detail.join(", ") : String(details.detail);
221
+ }
222
+ if (details.message) {
223
+ return String(details.message);
224
+ }
225
+ const fieldErrors = this.fieldErrors;
226
+ if (fieldErrors) {
227
+ const firstField = Object.keys(fieldErrors)[0];
228
+ if (firstField) {
229
+ return `${firstField}: ${fieldErrors[firstField]?.join(", ")}`;
230
+ }
231
+ }
232
+ return this.message;
233
+ }
234
+ // Helper methods for common HTTP status codes
235
+ get isValidationError() {
236
+ return this.statusCode === 400;
237
+ }
238
+ get isAuthError() {
239
+ return this.statusCode === 401;
240
+ }
241
+ get isPermissionError() {
242
+ return this.statusCode === 403;
243
+ }
244
+ get isNotFoundError() {
245
+ return this.statusCode === 404;
246
+ }
247
+ get isServerError() {
248
+ return this.statusCode >= 500 && this.statusCode < 600;
249
+ }
250
+ };
251
+ var NetworkError = class extends Error {
252
+ constructor(message, url, originalError) {
253
+ super(message);
254
+ this.url = url;
255
+ this.originalError = originalError;
256
+ this.name = "NetworkError";
257
+ }
258
+ };
259
+ var DEFAULT_CONFIG = {
260
+ enabled: process.env.NODE_ENV !== "production",
261
+ logRequests: true,
262
+ logResponses: true,
263
+ logErrors: true,
264
+ logBodies: true,
265
+ logHeaders: false
266
+ };
267
+ var SENSITIVE_HEADERS = [
268
+ "authorization",
269
+ "cookie",
270
+ "set-cookie",
271
+ "x-api-key",
272
+ "x-csrf-token"
273
+ ];
274
+ var APILogger = class {
275
+ config;
276
+ consola;
277
+ constructor(config = {}) {
278
+ this.config = { ...DEFAULT_CONFIG, ...config };
279
+ this.consola = config.consola || consola.createConsola({
280
+ level: this.config.enabled ? 4 : 0
281
+ });
282
+ }
283
+ /**
284
+ * Enable logging
285
+ */
286
+ enable() {
287
+ this.config.enabled = true;
288
+ }
289
+ /**
290
+ * Disable logging
291
+ */
292
+ disable() {
293
+ this.config.enabled = false;
294
+ }
295
+ /**
296
+ * Update configuration
297
+ */
298
+ setConfig(config) {
299
+ this.config = { ...this.config, ...config };
300
+ }
301
+ /**
302
+ * Filter sensitive headers
303
+ */
304
+ filterHeaders(headers) {
305
+ if (!headers) return {};
306
+ const filtered = {};
307
+ Object.keys(headers).forEach((key) => {
308
+ const lowerKey = key.toLowerCase();
309
+ if (SENSITIVE_HEADERS.includes(lowerKey)) {
310
+ filtered[key] = "***";
311
+ } else {
312
+ filtered[key] = headers[key] || "";
313
+ }
314
+ });
315
+ return filtered;
316
+ }
317
+ /**
318
+ * Log request
319
+ */
320
+ logRequest(request) {
321
+ if (!this.config.enabled || !this.config.logRequests) return;
322
+ const { method, url, headers, body } = request;
323
+ this.consola.start(`${method} ${url}`);
324
+ if (this.config.logHeaders && headers) {
325
+ this.consola.debug("Headers:", this.filterHeaders(headers));
326
+ }
327
+ if (this.config.logBodies && body) {
328
+ this.consola.debug("Body:", body);
329
+ }
330
+ }
331
+ /**
332
+ * Log response
333
+ */
334
+ logResponse(request, response) {
335
+ if (!this.config.enabled || !this.config.logResponses) return;
336
+ const { method, url } = request;
337
+ const { status, statusText, data, duration } = response;
338
+ this.consola.success(
339
+ `${method} ${url} ${status} ${statusText} (${duration}ms)`
340
+ );
341
+ if (this.config.logBodies && data) {
342
+ this.consola.debug("Response:", data);
343
+ }
344
+ }
345
+ /**
346
+ * Log error
347
+ */
348
+ logError(request, error) {
349
+ if (!this.config.enabled || !this.config.logErrors) return;
350
+ const { method, url } = request;
351
+ const { message, statusCode, fieldErrors, duration } = error;
352
+ this.consola.error(
353
+ `${method} ${url} ${statusCode || "Network"} Error (${duration}ms)`
354
+ );
355
+ this.consola.error("Message:", message);
356
+ if (fieldErrors && Object.keys(fieldErrors).length > 0) {
357
+ this.consola.error("Field Errors:");
358
+ Object.entries(fieldErrors).forEach(([field, errors]) => {
359
+ errors.forEach((err) => {
360
+ this.consola.error(` \u2022 ${field}: ${err}`);
361
+ });
362
+ });
363
+ }
364
+ }
365
+ /**
366
+ * Log general info
367
+ */
368
+ info(message, ...args) {
369
+ if (!this.config.enabled) return;
370
+ this.consola.info(message, ...args);
371
+ }
372
+ /**
373
+ * Log warning
374
+ */
375
+ warn(message, ...args) {
376
+ if (!this.config.enabled) return;
377
+ this.consola.warn(message, ...args);
378
+ }
379
+ /**
380
+ * Log error
381
+ */
382
+ error(message, ...args) {
383
+ if (!this.config.enabled) return;
384
+ this.consola.error(message, ...args);
385
+ }
386
+ /**
387
+ * Log debug
388
+ */
389
+ debug(message, ...args) {
390
+ if (!this.config.enabled) return;
391
+ this.consola.debug(message, ...args);
392
+ }
393
+ /**
394
+ * Log success
395
+ */
396
+ success(message, ...args) {
397
+ if (!this.config.enabled) return;
398
+ this.consola.success(message, ...args);
399
+ }
400
+ /**
401
+ * Create a sub-logger with prefix
402
+ */
403
+ withTag(tag) {
404
+ return this.consola.withTag(tag);
405
+ }
406
+ };
407
+ new APILogger();
408
+ var DEFAULT_RETRY_CONFIG = {
409
+ retries: 3,
410
+ factor: 2,
411
+ minTimeout: 1e3,
412
+ maxTimeout: 6e4,
413
+ randomize: true,
414
+ onFailedAttempt: () => {
415
+ }
416
+ };
417
+ function shouldRetry(error) {
418
+ if (error instanceof NetworkError) {
419
+ return true;
420
+ }
421
+ if (error instanceof APIError) {
422
+ const status = error.statusCode;
423
+ if (status >= 500 && status < 600) {
424
+ return true;
425
+ }
426
+ if (status === 429) {
427
+ return true;
428
+ }
429
+ return false;
430
+ }
431
+ return true;
432
+ }
433
+ async function withRetry(fn, config) {
434
+ const finalConfig = { ...DEFAULT_RETRY_CONFIG, ...config };
435
+ return pRetry__default.default(
436
+ async () => {
437
+ try {
438
+ return await fn();
439
+ } catch (error) {
440
+ if (!shouldRetry(error)) {
441
+ throw new pRetry.AbortError(error);
442
+ }
443
+ throw error;
444
+ }
445
+ },
446
+ {
447
+ retries: finalConfig.retries,
448
+ factor: finalConfig.factor,
449
+ minTimeout: finalConfig.minTimeout,
450
+ maxTimeout: finalConfig.maxTimeout,
451
+ randomize: finalConfig.randomize,
452
+ onFailedAttempt: finalConfig.onFailedAttempt ? (error) => {
453
+ const pRetryError = error;
454
+ finalConfig.onFailedAttempt({
455
+ error: pRetryError,
456
+ attemptNumber: pRetryError.attemptNumber,
457
+ retriesLeft: pRetryError.retriesLeft
458
+ });
459
+ } : void 0
460
+ }
461
+ );
462
+ }
463
+
464
+ // src/api/generated/ext_payments/client.ts
465
+ var APIClient = class {
466
+ baseUrl;
467
+ httpClient;
468
+ logger = null;
469
+ retryConfig = null;
470
+ // Sub-clients
471
+ ext_payments_payments;
472
+ constructor(baseUrl, options) {
473
+ this.baseUrl = baseUrl.replace(/\/$/, "");
474
+ this.httpClient = options?.httpClient || new FetchAdapter();
475
+ if (options?.loggerConfig !== void 0) {
476
+ this.logger = new APILogger(options.loggerConfig);
477
+ }
478
+ if (options?.retryConfig !== void 0) {
479
+ this.retryConfig = options.retryConfig;
480
+ }
481
+ this.ext_payments_payments = new ExtPaymentsPayments(this);
482
+ }
483
+ /**
484
+ * Get CSRF token from cookies (for SessionAuthentication).
485
+ *
486
+ * Returns null if cookie doesn't exist (JWT-only auth).
487
+ */
488
+ getCsrfToken() {
489
+ const name = "csrftoken";
490
+ const value = `; ${document.cookie}`;
491
+ const parts = value.split(`; ${name}=`);
492
+ if (parts.length === 2) {
493
+ return parts.pop()?.split(";").shift() || null;
494
+ }
495
+ return null;
496
+ }
497
+ /**
498
+ * Make HTTP request with Django CSRF and session handling.
499
+ * Automatically retries on network errors and 5xx server errors.
500
+ */
501
+ async request(method, path, options) {
502
+ if (this.retryConfig) {
503
+ return withRetry(() => this._makeRequest(method, path, options), {
504
+ ...this.retryConfig,
505
+ onFailedAttempt: (info) => {
506
+ if (this.logger) {
507
+ this.logger.warn(
508
+ `Retry attempt ${info.attemptNumber}/${info.retriesLeft + info.attemptNumber} for ${method} ${path}: ${info.error.message}`
509
+ );
510
+ }
511
+ this.retryConfig?.onFailedAttempt?.(info);
512
+ }
513
+ });
514
+ }
515
+ return this._makeRequest(method, path, options);
516
+ }
517
+ /**
518
+ * Internal request method (without retry wrapper).
519
+ * Used by request() method with optional retry logic.
520
+ */
521
+ async _makeRequest(method, path, options) {
522
+ const url = this.baseUrl ? `${this.baseUrl}${path}` : path;
523
+ const startTime = Date.now();
524
+ const headers = {
525
+ ...options?.headers || {}
526
+ };
527
+ if (!options?.formData && !headers["Content-Type"]) {
528
+ headers["Content-Type"] = "application/json";
529
+ }
530
+ if (this.logger) {
531
+ this.logger.logRequest({
532
+ method,
533
+ url,
534
+ headers,
535
+ body: options?.formData || options?.body,
536
+ timestamp: startTime
537
+ });
538
+ }
539
+ try {
540
+ const response = await this.httpClient.request({
541
+ method,
542
+ url,
543
+ headers,
544
+ params: options?.params,
545
+ body: options?.body,
546
+ formData: options?.formData
547
+ });
548
+ const duration = Date.now() - startTime;
549
+ if (response.status >= 400) {
550
+ const error = new APIError(
551
+ response.status,
552
+ response.statusText,
553
+ response.data,
554
+ url
555
+ );
556
+ if (this.logger) {
557
+ this.logger.logError(
558
+ {
559
+ method,
560
+ url,
561
+ headers,
562
+ body: options?.formData || options?.body,
563
+ timestamp: startTime
564
+ },
565
+ {
566
+ message: error.message,
567
+ statusCode: response.status,
568
+ duration,
569
+ timestamp: Date.now()
570
+ }
571
+ );
572
+ }
573
+ throw error;
574
+ }
575
+ if (this.logger) {
576
+ this.logger.logResponse(
577
+ {
578
+ method,
579
+ url,
580
+ headers,
581
+ body: options?.formData || options?.body,
582
+ timestamp: startTime
583
+ },
584
+ {
585
+ status: response.status,
586
+ statusText: response.statusText,
587
+ data: response.data,
588
+ duration,
589
+ timestamp: Date.now()
590
+ }
591
+ );
592
+ }
593
+ return response.data;
594
+ } catch (error) {
595
+ const duration = Date.now() - startTime;
596
+ if (error instanceof APIError) {
597
+ throw error;
598
+ }
599
+ const isCORSError = error instanceof TypeError && (error.message.toLowerCase().includes("cors") || error.message.toLowerCase().includes("failed to fetch") || error.message.toLowerCase().includes("network request failed"));
600
+ if (this.logger) {
601
+ if (isCORSError) {
602
+ this.logger.error(`\u{1F6AB} CORS Error: ${method} ${url}`);
603
+ this.logger.error(` \u2192 ${error instanceof Error ? error.message : String(error)}`);
604
+ this.logger.error(` \u2192 Configure security_domains parameter on the server`);
605
+ } else {
606
+ this.logger.error(`\u26A0\uFE0F Network Error: ${method} ${url}`);
607
+ this.logger.error(` \u2192 ${error instanceof Error ? error.message : String(error)}`);
608
+ }
609
+ }
610
+ if (typeof window !== "undefined") {
611
+ try {
612
+ if (isCORSError) {
613
+ window.dispatchEvent(new CustomEvent("cors-error", {
614
+ detail: {
615
+ url,
616
+ method,
617
+ error: error instanceof Error ? error.message : String(error),
618
+ timestamp: /* @__PURE__ */ new Date()
619
+ },
620
+ bubbles: true,
621
+ cancelable: false
622
+ }));
623
+ } else {
624
+ window.dispatchEvent(new CustomEvent("network-error", {
625
+ detail: {
626
+ url,
627
+ method,
628
+ error: error instanceof Error ? error.message : String(error),
629
+ timestamp: /* @__PURE__ */ new Date()
630
+ },
631
+ bubbles: true,
632
+ cancelable: false
633
+ }));
634
+ }
635
+ } catch (eventError) {
636
+ }
637
+ }
638
+ const networkError = error instanceof Error ? new NetworkError(error.message, url, error) : new NetworkError("Unknown error", url);
639
+ if (this.logger) {
640
+ this.logger.logError(
641
+ {
642
+ method,
643
+ url,
644
+ headers,
645
+ body: options?.formData || options?.body,
646
+ timestamp: startTime
647
+ },
648
+ {
649
+ message: networkError.message,
650
+ duration,
651
+ timestamp: Date.now()
652
+ }
653
+ );
654
+ }
655
+ throw networkError;
656
+ }
657
+ }
658
+ };
659
+
660
+ // src/api/generated/ext_payments/storage.ts
661
+ var LocalStorageAdapter = class {
662
+ logger;
663
+ constructor(logger2) {
664
+ this.logger = logger2;
665
+ }
666
+ getItem(key) {
667
+ try {
668
+ if (typeof window !== "undefined" && window.localStorage) {
669
+ const value = localStorage.getItem(key);
670
+ this.logger?.debug(`LocalStorage.getItem("${key}"): ${value ? "found" : "not found"}`);
671
+ return value;
672
+ }
673
+ this.logger?.warn("LocalStorage not available: window.localStorage is undefined");
674
+ } catch (error) {
675
+ this.logger?.error("LocalStorage.getItem failed:", error);
676
+ }
677
+ return null;
678
+ }
679
+ setItem(key, value) {
680
+ try {
681
+ if (typeof window !== "undefined" && window.localStorage) {
682
+ localStorage.setItem(key, value);
683
+ this.logger?.debug(`LocalStorage.setItem("${key}"): success`);
684
+ } else {
685
+ this.logger?.warn("LocalStorage not available: window.localStorage is undefined");
686
+ }
687
+ } catch (error) {
688
+ this.logger?.error("LocalStorage.setItem failed:", error);
689
+ }
690
+ }
691
+ removeItem(key) {
692
+ try {
693
+ if (typeof window !== "undefined" && window.localStorage) {
694
+ localStorage.removeItem(key);
695
+ this.logger?.debug(`LocalStorage.removeItem("${key}"): success`);
696
+ } else {
697
+ this.logger?.warn("LocalStorage not available: window.localStorage is undefined");
698
+ }
699
+ } catch (error) {
700
+ this.logger?.error("LocalStorage.removeItem failed:", error);
701
+ }
702
+ }
703
+ };
704
+ var CookieStorageAdapter = class {
705
+ logger;
706
+ constructor(logger2) {
707
+ this.logger = logger2;
708
+ }
709
+ getItem(key) {
710
+ try {
711
+ if (typeof document === "undefined") {
712
+ this.logger?.warn("Cookies not available: document is undefined (SSR context?)");
713
+ return null;
714
+ }
715
+ const value = `; ${document.cookie}`;
716
+ const parts = value.split(`; ${key}=`);
717
+ if (parts.length === 2) {
718
+ const result = parts.pop()?.split(";").shift() || null;
719
+ this.logger?.debug(`CookieStorage.getItem("${key}"): ${result ? "found" : "not found"}`);
720
+ return result;
721
+ }
722
+ this.logger?.debug(`CookieStorage.getItem("${key}"): not found`);
723
+ } catch (error) {
724
+ this.logger?.error("CookieStorage.getItem failed:", error);
725
+ }
726
+ return null;
727
+ }
728
+ setItem(key, value) {
729
+ try {
730
+ if (typeof document !== "undefined") {
731
+ document.cookie = `${key}=${value}; path=/; max-age=31536000`;
732
+ this.logger?.debug(`CookieStorage.setItem("${key}"): success`);
733
+ } else {
734
+ this.logger?.warn("Cookies not available: document is undefined (SSR context?)");
735
+ }
736
+ } catch (error) {
737
+ this.logger?.error("CookieStorage.setItem failed:", error);
738
+ }
739
+ }
740
+ removeItem(key) {
741
+ try {
742
+ if (typeof document !== "undefined") {
743
+ document.cookie = `${key}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
744
+ this.logger?.debug(`CookieStorage.removeItem("${key}"): success`);
745
+ } else {
746
+ this.logger?.warn("Cookies not available: document is undefined (SSR context?)");
747
+ }
748
+ } catch (error) {
749
+ this.logger?.error("CookieStorage.removeItem failed:", error);
750
+ }
751
+ }
752
+ };
753
+ var MemoryStorageAdapter = class {
754
+ storage = /* @__PURE__ */ new Map();
755
+ logger;
756
+ constructor(logger2) {
757
+ this.logger = logger2;
758
+ }
759
+ getItem(key) {
760
+ const value = this.storage.get(key) || null;
761
+ this.logger?.debug(`MemoryStorage.getItem("${key}"): ${value ? "found" : "not found"}`);
762
+ return value;
763
+ }
764
+ setItem(key, value) {
765
+ this.storage.set(key, value);
766
+ this.logger?.debug(`MemoryStorage.setItem("${key}"): success`);
767
+ }
768
+ removeItem(key) {
769
+ this.storage.delete(key);
770
+ this.logger?.debug(`MemoryStorage.removeItem("${key}"): success`);
771
+ }
772
+ };
773
+
774
+ // src/api/generated/ext_payments/enums.ts
775
+ var enums_exports = {};
776
+ __export(enums_exports, {
777
+ PaymentDetailStatus: () => PaymentDetailStatus,
778
+ PaymentListStatus: () => PaymentListStatus,
779
+ TransactionTransactionType: () => TransactionTransactionType
780
+ });
781
+ var PaymentDetailStatus = /* @__PURE__ */ ((PaymentDetailStatus2) => {
782
+ PaymentDetailStatus2["PENDING"] = "pending";
783
+ PaymentDetailStatus2["CONFIRMING"] = "confirming";
784
+ PaymentDetailStatus2["CONFIRMED"] = "confirmed";
785
+ PaymentDetailStatus2["COMPLETED"] = "completed";
786
+ PaymentDetailStatus2["PARTIALLY_PAID"] = "partially_paid";
787
+ PaymentDetailStatus2["FAILED"] = "failed";
788
+ PaymentDetailStatus2["EXPIRED"] = "expired";
789
+ PaymentDetailStatus2["CANCELLED"] = "cancelled";
790
+ return PaymentDetailStatus2;
791
+ })(PaymentDetailStatus || {});
792
+ var PaymentListStatus = /* @__PURE__ */ ((PaymentListStatus2) => {
793
+ PaymentListStatus2["PENDING"] = "pending";
794
+ PaymentListStatus2["CONFIRMING"] = "confirming";
795
+ PaymentListStatus2["CONFIRMED"] = "confirmed";
796
+ PaymentListStatus2["COMPLETED"] = "completed";
797
+ PaymentListStatus2["PARTIALLY_PAID"] = "partially_paid";
798
+ PaymentListStatus2["FAILED"] = "failed";
799
+ PaymentListStatus2["EXPIRED"] = "expired";
800
+ PaymentListStatus2["CANCELLED"] = "cancelled";
801
+ return PaymentListStatus2;
802
+ })(PaymentListStatus || {});
803
+ var TransactionTransactionType = /* @__PURE__ */ ((TransactionTransactionType2) => {
804
+ TransactionTransactionType2["DEPOSIT"] = "deposit";
805
+ TransactionTransactionType2["WITHDRAWAL"] = "withdrawal";
806
+ TransactionTransactionType2["PAYMENT"] = "payment";
807
+ TransactionTransactionType2["REFUND"] = "refund";
808
+ TransactionTransactionType2["FEE"] = "fee";
809
+ TransactionTransactionType2["BONUS"] = "bonus";
810
+ TransactionTransactionType2["ADJUSTMENT"] = "adjustment";
811
+ return TransactionTransactionType2;
812
+ })(TransactionTransactionType || {});
813
+
814
+ // src/api/generated/ext_payments/_utils/schemas/index.ts
815
+ var schemas_exports = {};
816
+ __export(schemas_exports, {
817
+ BalanceSchema: () => BalanceSchema,
818
+ CurrencySchema: () => CurrencySchema,
819
+ PaginatedPaymentListListSchema: () => PaginatedPaymentListListSchema,
820
+ PaymentDetailSchema: () => PaymentDetailSchema,
821
+ PaymentListSchema: () => PaymentListSchema,
822
+ TransactionSchema: () => TransactionSchema
823
+ });
824
+ var BalanceSchema = zod.z.object({
825
+ balance_usd: zod.z.string(),
826
+ balance_display: zod.z.string(),
827
+ total_deposited: zod.z.string(),
828
+ total_withdrawn: zod.z.string(),
829
+ last_transaction_at: zod.z.iso.datetime().nullable()
830
+ });
831
+ var CurrencySchema = zod.z.object({
832
+ code: zod.z.string(),
833
+ name: zod.z.string(),
834
+ token: zod.z.string(),
835
+ network: zod.z.string().nullable(),
836
+ display_name: zod.z.string(),
837
+ symbol: zod.z.string(),
838
+ decimal_places: zod.z.int(),
839
+ is_active: zod.z.boolean(),
840
+ min_amount_usd: zod.z.string(),
841
+ sort_order: zod.z.int()
842
+ });
843
+ var PaymentListSchema = zod.z.object({
844
+ id: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
845
+ internal_payment_id: zod.z.string(),
846
+ amount_usd: zod.z.string(),
847
+ currency_code: zod.z.string(),
848
+ currency_token: zod.z.string(),
849
+ status: zod.z.nativeEnum(PaymentListStatus),
850
+ status_display: zod.z.string(),
851
+ created_at: zod.z.iso.datetime(),
852
+ completed_at: zod.z.iso.datetime().nullable()
853
+ });
854
+
855
+ // src/api/generated/ext_payments/_utils/schemas/PaginatedPaymentListList.schema.ts
856
+ var PaginatedPaymentListListSchema = zod.z.object({
857
+ count: zod.z.int(),
858
+ page: zod.z.int(),
859
+ pages: zod.z.int(),
860
+ page_size: zod.z.int(),
861
+ has_next: zod.z.boolean(),
862
+ has_previous: zod.z.boolean(),
863
+ next_page: zod.z.int().nullable().optional(),
864
+ previous_page: zod.z.int().nullable().optional(),
865
+ results: zod.z.array(PaymentListSchema)
866
+ });
867
+ var PaymentDetailSchema = zod.z.object({
868
+ id: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
869
+ internal_payment_id: zod.z.string(),
870
+ amount_usd: zod.z.string(),
871
+ currency_code: zod.z.string(),
872
+ currency_name: zod.z.string(),
873
+ currency_token: zod.z.string(),
874
+ currency_network: zod.z.string(),
875
+ pay_amount: zod.z.string().nullable(),
876
+ actual_amount: zod.z.string().nullable(),
877
+ actual_amount_usd: zod.z.string().nullable(),
878
+ status: zod.z.nativeEnum(PaymentDetailStatus),
879
+ status_display: zod.z.string(),
880
+ pay_address: zod.z.string().nullable(),
881
+ qr_code_url: zod.z.string().nullable(),
882
+ payment_url: zod.z.url().nullable(),
883
+ transaction_hash: zod.z.string().nullable(),
884
+ explorer_link: zod.z.string().nullable(),
885
+ confirmations_count: zod.z.int(),
886
+ expires_at: zod.z.iso.datetime().nullable(),
887
+ completed_at: zod.z.iso.datetime().nullable(),
888
+ created_at: zod.z.iso.datetime(),
889
+ is_completed: zod.z.boolean(),
890
+ is_failed: zod.z.boolean(),
891
+ is_expired: zod.z.boolean(),
892
+ description: zod.z.string()
893
+ });
894
+ var TransactionSchema = zod.z.object({
895
+ id: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
896
+ transaction_type: zod.z.nativeEnum(TransactionTransactionType),
897
+ type_display: zod.z.string(),
898
+ amount_usd: zod.z.string(),
899
+ amount_display: zod.z.string(),
900
+ balance_after: zod.z.string(),
901
+ payment_id: zod.z.string().nullable(),
902
+ description: zod.z.string(),
903
+ created_at: zod.z.iso.datetime()
904
+ });
905
+
906
+ // src/api/generated/ext_payments/validation-events.ts
907
+ function dispatchValidationError(detail) {
908
+ if (typeof window === "undefined") {
909
+ return;
910
+ }
911
+ try {
912
+ const event = new CustomEvent("zod-validation-error", {
913
+ detail,
914
+ bubbles: true,
915
+ cancelable: false
916
+ });
917
+ window.dispatchEvent(event);
918
+ } catch (error) {
919
+ console.warn("Failed to dispatch validation error event:", error);
920
+ }
921
+ }
922
+ function onValidationError(callback) {
923
+ if (typeof window === "undefined") {
924
+ return () => {
925
+ };
926
+ }
927
+ const handler = (event) => {
928
+ if (event instanceof CustomEvent) {
929
+ callback(event.detail);
930
+ }
931
+ };
932
+ window.addEventListener("zod-validation-error", handler);
933
+ return () => {
934
+ window.removeEventListener("zod-validation-error", handler);
935
+ };
936
+ }
937
+ function formatZodError(error) {
938
+ const issues = error.issues.map((issue, index) => {
939
+ const path = issue.path.join(".") || "root";
940
+ const parts = [`${index + 1}. ${path}: ${issue.message}`];
941
+ if ("expected" in issue && issue.expected) {
942
+ parts.push(` Expected: ${issue.expected}`);
943
+ }
944
+ if ("received" in issue && issue.received) {
945
+ parts.push(` Received: ${issue.received}`);
946
+ }
947
+ return parts.join("\n");
948
+ });
949
+ return issues.join("\n");
950
+ }
951
+
952
+ // src/api/generated/ext_payments/_utils/fetchers/index.ts
953
+ var fetchers_exports = {};
954
+ __export(fetchers_exports, {
955
+ createPaymentsPaymentsConfirmCreate: () => createPaymentsPaymentsConfirmCreate,
956
+ createPaymentsPaymentsCreateCreate: () => createPaymentsPaymentsCreateCreate,
957
+ getPaymentsBalanceRetrieve: () => getPaymentsBalanceRetrieve,
958
+ getPaymentsCurrenciesList: () => getPaymentsCurrenciesList,
959
+ getPaymentsPaymentsList: () => getPaymentsPaymentsList,
960
+ getPaymentsPaymentsRetrieve: () => getPaymentsPaymentsRetrieve,
961
+ getPaymentsPaymentsStatusRetrieve: () => getPaymentsPaymentsStatusRetrieve,
962
+ getPaymentsTransactionsList: () => getPaymentsTransactionsList
963
+ });
964
+
965
+ // src/api/generated/ext_payments/api-instance.ts
966
+ var globalAPI = null;
967
+ function getAPIInstance() {
968
+ if (!globalAPI) {
969
+ throw new Error(
970
+ 'API not configured. Call configureAPI() with your base URL before using fetchers or hooks.\n\nExample:\n import { configureAPI } from "./api-instance"\n configureAPI({ baseUrl: "https://api.example.com" })'
971
+ );
972
+ }
973
+ return globalAPI;
974
+ }
975
+ function isAPIConfigured() {
976
+ return globalAPI !== null;
977
+ }
978
+ function configureAPI(config) {
979
+ globalAPI = new API(config.baseUrl, config.options);
980
+ if (config.token) {
981
+ globalAPI.setToken(config.token, config.refreshToken);
982
+ }
983
+ return globalAPI;
984
+ }
985
+ function reconfigureAPI(updates) {
986
+ const instance = getAPIInstance();
987
+ if (updates.baseUrl) {
988
+ instance.setBaseUrl(updates.baseUrl);
989
+ }
990
+ if (updates.token) {
991
+ instance.setToken(updates.token, updates.refreshToken);
992
+ }
993
+ return instance;
994
+ }
995
+ function clearAPITokens() {
996
+ const instance = getAPIInstance();
997
+ instance.clearTokens();
998
+ }
999
+ function resetAPI() {
1000
+ if (globalAPI) {
1001
+ globalAPI.clearTokens();
1002
+ }
1003
+ globalAPI = null;
1004
+ }
1005
+
1006
+ // src/api/generated/ext_payments/_utils/fetchers/ext_payments__payments.ts
1007
+ async function getPaymentsBalanceRetrieve(client) {
1008
+ const api = client || getAPIInstance();
1009
+ const response = await api.ext_payments_payments.balanceRetrieve();
1010
+ try {
1011
+ return BalanceSchema.parse(response);
1012
+ } catch (error) {
1013
+ consola.consola.error("\u274C Zod Validation Failed");
1014
+ consola.consola.box(`getPaymentsBalanceRetrieve
1015
+ Path: /cfg/payments/balance/
1016
+ Method: GET`);
1017
+ if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
1018
+ consola.consola.error("Validation Issues:");
1019
+ error.issues.forEach((issue, index) => {
1020
+ consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
1021
+ consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
1022
+ if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
1023
+ if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
1024
+ });
1025
+ }
1026
+ consola.consola.error("Response data:", response);
1027
+ if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
1028
+ try {
1029
+ const event = new CustomEvent("zod-validation-error", {
1030
+ detail: {
1031
+ operation: "getPaymentsBalanceRetrieve",
1032
+ path: "/cfg/payments/balance/",
1033
+ method: "GET",
1034
+ error,
1035
+ response,
1036
+ timestamp: /* @__PURE__ */ new Date()
1037
+ },
1038
+ bubbles: true,
1039
+ cancelable: false
1040
+ });
1041
+ window.dispatchEvent(event);
1042
+ } catch (eventError) {
1043
+ consola.consola.warn("Failed to dispatch validation error event:", eventError);
1044
+ }
1045
+ }
1046
+ throw error;
1047
+ }
1048
+ }
1049
+ async function getPaymentsCurrenciesList(client) {
1050
+ const api = client || getAPIInstance();
1051
+ const response = await api.ext_payments_payments.currenciesList();
1052
+ return response;
1053
+ }
1054
+ async function getPaymentsPaymentsList(params, client) {
1055
+ const api = client || getAPIInstance();
1056
+ const response = await api.ext_payments_payments.paymentsList(params?.page, params?.page_size);
1057
+ try {
1058
+ return PaginatedPaymentListListSchema.parse(response);
1059
+ } catch (error) {
1060
+ consola.consola.error("\u274C Zod Validation Failed");
1061
+ consola.consola.box(`getPaymentsPaymentsList
1062
+ Path: /cfg/payments/payments/
1063
+ Method: GET`);
1064
+ if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
1065
+ consola.consola.error("Validation Issues:");
1066
+ error.issues.forEach((issue, index) => {
1067
+ consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
1068
+ consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
1069
+ if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
1070
+ if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
1071
+ });
1072
+ }
1073
+ consola.consola.error("Response data:", response);
1074
+ if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
1075
+ try {
1076
+ const event = new CustomEvent("zod-validation-error", {
1077
+ detail: {
1078
+ operation: "getPaymentsPaymentsList",
1079
+ path: "/cfg/payments/payments/",
1080
+ method: "GET",
1081
+ error,
1082
+ response,
1083
+ timestamp: /* @__PURE__ */ new Date()
1084
+ },
1085
+ bubbles: true,
1086
+ cancelable: false
1087
+ });
1088
+ window.dispatchEvent(event);
1089
+ } catch (eventError) {
1090
+ consola.consola.warn("Failed to dispatch validation error event:", eventError);
1091
+ }
1092
+ }
1093
+ throw error;
1094
+ }
1095
+ }
1096
+ async function getPaymentsPaymentsRetrieve(id, client) {
1097
+ const api = client || getAPIInstance();
1098
+ const response = await api.ext_payments_payments.paymentsRetrieve(id);
1099
+ try {
1100
+ return PaymentDetailSchema.parse(response);
1101
+ } catch (error) {
1102
+ consola.consola.error("\u274C Zod Validation Failed");
1103
+ consola.consola.box(`getPaymentsPaymentsRetrieve
1104
+ Path: /cfg/payments/payments/{id}/
1105
+ Method: GET`);
1106
+ if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
1107
+ consola.consola.error("Validation Issues:");
1108
+ error.issues.forEach((issue, index) => {
1109
+ consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
1110
+ consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
1111
+ if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
1112
+ if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
1113
+ });
1114
+ }
1115
+ consola.consola.error("Response data:", response);
1116
+ if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
1117
+ try {
1118
+ const event = new CustomEvent("zod-validation-error", {
1119
+ detail: {
1120
+ operation: "getPaymentsPaymentsRetrieve",
1121
+ path: "/cfg/payments/payments/{id}/",
1122
+ method: "GET",
1123
+ error,
1124
+ response,
1125
+ timestamp: /* @__PURE__ */ new Date()
1126
+ },
1127
+ bubbles: true,
1128
+ cancelable: false
1129
+ });
1130
+ window.dispatchEvent(event);
1131
+ } catch (eventError) {
1132
+ consola.consola.warn("Failed to dispatch validation error event:", eventError);
1133
+ }
1134
+ }
1135
+ throw error;
1136
+ }
1137
+ }
1138
+ async function createPaymentsPaymentsConfirmCreate(id, client) {
1139
+ const api = client || getAPIInstance();
1140
+ const response = await api.ext_payments_payments.paymentsConfirmCreate(id);
1141
+ try {
1142
+ return PaymentListSchema.parse(response);
1143
+ } catch (error) {
1144
+ consola.consola.error("\u274C Zod Validation Failed");
1145
+ consola.consola.box(`createPaymentsPaymentsConfirmCreate
1146
+ Path: /cfg/payments/payments/{id}/confirm/
1147
+ Method: POST`);
1148
+ if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
1149
+ consola.consola.error("Validation Issues:");
1150
+ error.issues.forEach((issue, index) => {
1151
+ consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
1152
+ consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
1153
+ if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
1154
+ if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
1155
+ });
1156
+ }
1157
+ consola.consola.error("Response data:", response);
1158
+ if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
1159
+ try {
1160
+ const event = new CustomEvent("zod-validation-error", {
1161
+ detail: {
1162
+ operation: "createPaymentsPaymentsConfirmCreate",
1163
+ path: "/cfg/payments/payments/{id}/confirm/",
1164
+ method: "POST",
1165
+ error,
1166
+ response,
1167
+ timestamp: /* @__PURE__ */ new Date()
1168
+ },
1169
+ bubbles: true,
1170
+ cancelable: false
1171
+ });
1172
+ window.dispatchEvent(event);
1173
+ } catch (eventError) {
1174
+ consola.consola.warn("Failed to dispatch validation error event:", eventError);
1175
+ }
1176
+ }
1177
+ throw error;
1178
+ }
1179
+ }
1180
+ async function getPaymentsPaymentsStatusRetrieve(id, client) {
1181
+ const api = client || getAPIInstance();
1182
+ const response = await api.ext_payments_payments.paymentsStatusRetrieve(id);
1183
+ try {
1184
+ return PaymentListSchema.parse(response);
1185
+ } catch (error) {
1186
+ consola.consola.error("\u274C Zod Validation Failed");
1187
+ consola.consola.box(`getPaymentsPaymentsStatusRetrieve
1188
+ Path: /cfg/payments/payments/{id}/status/
1189
+ Method: GET`);
1190
+ if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
1191
+ consola.consola.error("Validation Issues:");
1192
+ error.issues.forEach((issue, index) => {
1193
+ consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
1194
+ consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
1195
+ if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
1196
+ if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
1197
+ });
1198
+ }
1199
+ consola.consola.error("Response data:", response);
1200
+ if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
1201
+ try {
1202
+ const event = new CustomEvent("zod-validation-error", {
1203
+ detail: {
1204
+ operation: "getPaymentsPaymentsStatusRetrieve",
1205
+ path: "/cfg/payments/payments/{id}/status/",
1206
+ method: "GET",
1207
+ error,
1208
+ response,
1209
+ timestamp: /* @__PURE__ */ new Date()
1210
+ },
1211
+ bubbles: true,
1212
+ cancelable: false
1213
+ });
1214
+ window.dispatchEvent(event);
1215
+ } catch (eventError) {
1216
+ consola.consola.warn("Failed to dispatch validation error event:", eventError);
1217
+ }
1218
+ }
1219
+ throw error;
1220
+ }
1221
+ }
1222
+ async function createPaymentsPaymentsCreateCreate(client) {
1223
+ const api = client || getAPIInstance();
1224
+ const response = await api.ext_payments_payments.paymentsCreateCreate();
1225
+ try {
1226
+ return PaymentListSchema.parse(response);
1227
+ } catch (error) {
1228
+ consola.consola.error("\u274C Zod Validation Failed");
1229
+ consola.consola.box(`createPaymentsPaymentsCreateCreate
1230
+ Path: /cfg/payments/payments/create/
1231
+ Method: POST`);
1232
+ if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
1233
+ consola.consola.error("Validation Issues:");
1234
+ error.issues.forEach((issue, index) => {
1235
+ consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
1236
+ consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
1237
+ if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
1238
+ if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
1239
+ });
1240
+ }
1241
+ consola.consola.error("Response data:", response);
1242
+ if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
1243
+ try {
1244
+ const event = new CustomEvent("zod-validation-error", {
1245
+ detail: {
1246
+ operation: "createPaymentsPaymentsCreateCreate",
1247
+ path: "/cfg/payments/payments/create/",
1248
+ method: "POST",
1249
+ error,
1250
+ response,
1251
+ timestamp: /* @__PURE__ */ new Date()
1252
+ },
1253
+ bubbles: true,
1254
+ cancelable: false
1255
+ });
1256
+ window.dispatchEvent(event);
1257
+ } catch (eventError) {
1258
+ consola.consola.warn("Failed to dispatch validation error event:", eventError);
1259
+ }
1260
+ }
1261
+ throw error;
1262
+ }
1263
+ }
1264
+ async function getPaymentsTransactionsList(params, client) {
1265
+ const api = client || getAPIInstance();
1266
+ const response = await api.ext_payments_payments.transactionsList(params?.limit, params?.offset, params?.type);
1267
+ return response;
1268
+ }
1269
+
1270
+ // src/api/generated/ext_payments/index.ts
1271
+ var TOKEN_KEY = "auth_token";
1272
+ var REFRESH_TOKEN_KEY = "refresh_token";
1273
+ var API = class {
1274
+ baseUrl;
1275
+ _client;
1276
+ _token = null;
1277
+ _refreshToken = null;
1278
+ storage;
1279
+ options;
1280
+ // Sub-clients
1281
+ ext_payments_payments;
1282
+ constructor(baseUrl, options) {
1283
+ this.baseUrl = baseUrl;
1284
+ this.options = options;
1285
+ const logger2 = options?.loggerConfig ? new APILogger(options.loggerConfig) : void 0;
1286
+ this.storage = options?.storage || new LocalStorageAdapter(logger2);
1287
+ this._loadTokensFromStorage();
1288
+ this._client = new APIClient(this.baseUrl, {
1289
+ retryConfig: this.options?.retryConfig,
1290
+ loggerConfig: this.options?.loggerConfig
1291
+ });
1292
+ this._injectAuthHeader();
1293
+ this.ext_payments_payments = this._client.ext_payments_payments;
1294
+ }
1295
+ _loadTokensFromStorage() {
1296
+ this._token = this.storage.getItem(TOKEN_KEY);
1297
+ this._refreshToken = this.storage.getItem(REFRESH_TOKEN_KEY);
1298
+ }
1299
+ _reinitClients() {
1300
+ this._client = new APIClient(this.baseUrl, {
1301
+ retryConfig: this.options?.retryConfig,
1302
+ loggerConfig: this.options?.loggerConfig
1303
+ });
1304
+ this._injectAuthHeader();
1305
+ this.ext_payments_payments = this._client.ext_payments_payments;
1306
+ }
1307
+ _injectAuthHeader() {
1308
+ const originalRequest = this._client.request.bind(this._client);
1309
+ this._client.request = async (method, path, options) => {
1310
+ const token = this.getToken();
1311
+ const mergedOptions = {
1312
+ ...options,
1313
+ headers: {
1314
+ ...options?.headers || {},
1315
+ ...token ? { "Authorization": `Bearer ${token}` } : {}
1316
+ }
1317
+ };
1318
+ return originalRequest(method, path, mergedOptions);
1319
+ };
1320
+ }
1321
+ /**
1322
+ * Get current JWT token
1323
+ */
1324
+ getToken() {
1325
+ return this.storage.getItem(TOKEN_KEY);
1326
+ }
1327
+ /**
1328
+ * Get current refresh token
1329
+ */
1330
+ getRefreshToken() {
1331
+ return this.storage.getItem(REFRESH_TOKEN_KEY);
1332
+ }
1333
+ /**
1334
+ * Set JWT token and refresh token
1335
+ * @param token - JWT access token
1336
+ * @param refreshToken - JWT refresh token (optional)
1337
+ */
1338
+ setToken(token, refreshToken) {
1339
+ this._token = token;
1340
+ this.storage.setItem(TOKEN_KEY, token);
1341
+ if (refreshToken) {
1342
+ this._refreshToken = refreshToken;
1343
+ this.storage.setItem(REFRESH_TOKEN_KEY, refreshToken);
1344
+ }
1345
+ this._reinitClients();
1346
+ }
1347
+ /**
1348
+ * Clear all tokens
1349
+ */
1350
+ clearTokens() {
1351
+ this._token = null;
1352
+ this._refreshToken = null;
1353
+ this.storage.removeItem(TOKEN_KEY);
1354
+ this.storage.removeItem(REFRESH_TOKEN_KEY);
1355
+ this._reinitClients();
1356
+ }
1357
+ /**
1358
+ * Check if user is authenticated
1359
+ */
1360
+ isAuthenticated() {
1361
+ return !!this.getToken();
1362
+ }
1363
+ /**
1364
+ * Update base URL and reinitialize clients
1365
+ * @param url - New base URL
1366
+ */
1367
+ setBaseUrl(url) {
1368
+ this.baseUrl = url;
1369
+ this._reinitClients();
1370
+ }
1371
+ /**
1372
+ * Get current base URL
1373
+ */
1374
+ getBaseUrl() {
1375
+ return this.baseUrl;
1376
+ }
1377
+ /**
1378
+ * Get OpenAPI schema path
1379
+ * @returns Path to the OpenAPI schema JSON file
1380
+ *
1381
+ * Note: The OpenAPI schema is available in the schema.json file.
1382
+ * You can load it dynamically using:
1383
+ * ```typescript
1384
+ * const schema = await fetch('./schema.json').then(r => r.json());
1385
+ * // or using fs in Node.js:
1386
+ * // const schema = JSON.parse(fs.readFileSync('./schema.json', 'utf-8'));
1387
+ * ```
1388
+ */
1389
+ getSchemaPath() {
1390
+ return "./schema.json";
1391
+ }
1392
+ };
1393
+ var apiPayments = api.createExtensionAPI(API);
1394
+ function usePaymentsBalanceRetrieve(client) {
1395
+ return useSWR__default.default(
1396
+ "cfg-payments-balance",
1397
+ () => getPaymentsBalanceRetrieve(client)
1398
+ );
1399
+ }
1400
+ function usePaymentsCurrenciesList(client) {
1401
+ return useSWR__default.default(
1402
+ "cfg-payments-currencies",
1403
+ () => getPaymentsCurrenciesList(client)
1404
+ );
1405
+ }
1406
+ function usePaymentsPaymentsList(params, client) {
1407
+ return useSWR__default.default(
1408
+ params ? ["cfg-payments-payments", params] : "cfg-payments-payments",
1409
+ () => getPaymentsPaymentsList(params, client)
1410
+ );
1411
+ }
1412
+ function usePaymentsPaymentsRetrieve(id, client) {
1413
+ return useSWR__default.default(
1414
+ ["cfg-payments-payment", id],
1415
+ () => getPaymentsPaymentsRetrieve(id, client)
1416
+ );
1417
+ }
1418
+ function useCreatePaymentsPaymentsConfirmCreate() {
1419
+ const { mutate } = useSWR.useSWRConfig();
1420
+ return async (id, client) => {
1421
+ const result = await createPaymentsPaymentsConfirmCreate(id, client);
1422
+ mutate("cfg-payments-payments-confirm");
1423
+ return result;
1424
+ };
1425
+ }
1426
+ function useCreatePaymentsPaymentsCreateCreate() {
1427
+ const { mutate } = useSWR.useSWRConfig();
1428
+ return async (client) => {
1429
+ const result = await createPaymentsPaymentsCreateCreate(client);
1430
+ mutate("cfg-payments-payments");
1431
+ return result;
1432
+ };
1433
+ }
1434
+ function usePaymentsTransactionsList(params, client) {
1435
+ return useSWR__default.default(
1436
+ params ? ["cfg-payments-transactions", params] : "cfg-payments-transactions",
1437
+ () => getPaymentsTransactionsList(params, client)
1438
+ );
1439
+ }
1440
+ var PaymentsContext = react.createContext(void 0);
1441
+ function PaymentsProvider({ children }) {
1442
+ const {
1443
+ data: payments,
1444
+ error: paymentsError,
1445
+ isLoading: isLoadingPayments,
1446
+ mutate: mutatePayments
1447
+ } = usePaymentsPaymentsList({ page: 1, page_size: 1 }, apiPayments);
1448
+ const refreshPayments = async () => {
1449
+ await mutatePayments();
1450
+ };
1451
+ const createPaymentMutation = useCreatePaymentsPaymentsCreateCreate();
1452
+ const confirmPaymentMutation = useCreatePaymentsPaymentsConfirmCreate();
1453
+ const getPayment = async (id) => {
1454
+ return getPaymentsPaymentsRetrieve(id, apiPayments);
1455
+ };
1456
+ const createPayment = async () => {
1457
+ const result = await createPaymentMutation(apiPayments);
1458
+ await refreshPayments();
1459
+ return result;
1460
+ };
1461
+ const confirmPayment = async (id) => {
1462
+ const result = await confirmPaymentMutation(id, apiPayments);
1463
+ await refreshPayments();
1464
+ return result;
1465
+ };
1466
+ const checkPaymentStatus = async (id) => {
1467
+ return getPaymentsPaymentsStatusRetrieve(id, apiPayments);
1468
+ };
1469
+ const value = {
1470
+ payments,
1471
+ isLoadingPayments,
1472
+ paymentsError,
1473
+ refreshPayments,
1474
+ getPayment,
1475
+ createPayment,
1476
+ confirmPayment,
1477
+ checkPaymentStatus
1478
+ };
1479
+ return /* @__PURE__ */ jsxRuntime.jsx(PaymentsContext.Provider, { value, children });
1480
+ }
1481
+ function usePaymentsContext() {
1482
+ const context = react.useContext(PaymentsContext);
1483
+ if (!context) {
1484
+ throw new Error("usePaymentsContext must be used within PaymentsProvider");
1485
+ }
1486
+ return context;
1487
+ }
1488
+ react.createContext(void 0);
1489
+ react.createContext(void 0);
1490
+ var OverviewContext = react.createContext(void 0);
1491
+ function OverviewProvider({ children }) {
1492
+ const swrConfig = {
1493
+ revalidateOnFocus: false,
1494
+ revalidateOnReconnect: false,
1495
+ revalidateIfStale: false
1496
+ };
1497
+ const {
1498
+ data: balance,
1499
+ error: balanceError,
1500
+ isLoading: isLoadingBalance,
1501
+ mutate: mutateBalance
1502
+ } = usePaymentsBalanceRetrieve(apiPayments);
1503
+ const {
1504
+ data: payments,
1505
+ error: paymentsError,
1506
+ isLoading: isLoadingPayments,
1507
+ mutate: mutatePayments
1508
+ } = usePaymentsPaymentsList({}, apiPayments);
1509
+ const {
1510
+ data: transactions,
1511
+ error: transactionsError,
1512
+ isLoading: isLoadingTransactions,
1513
+ mutate: mutateTransactions
1514
+ } = usePaymentsTransactionsList({}, apiPayments);
1515
+ const createPaymentMutation = useCreatePaymentsPaymentsCreateCreate();
1516
+ const isLoadingOverview = isLoadingBalance || isLoadingPayments || isLoadingTransactions;
1517
+ const overviewError = balanceError || paymentsError || transactionsError;
1518
+ const refreshBalance = async () => {
1519
+ await mutateBalance();
1520
+ };
1521
+ const refreshPayments = async () => {
1522
+ await mutatePayments();
1523
+ };
1524
+ const refreshTransactions = async () => {
1525
+ await mutateTransactions();
1526
+ };
1527
+ const refreshOverview = async () => {
1528
+ await Promise.all([
1529
+ mutateBalance(),
1530
+ mutatePayments(),
1531
+ mutateTransactions()
1532
+ ]);
1533
+ };
1534
+ const createPayment = async () => {
1535
+ const result = await createPaymentMutation(apiPayments);
1536
+ await refreshOverview();
1537
+ return result;
1538
+ };
1539
+ const value = {
1540
+ balance,
1541
+ isLoadingBalance,
1542
+ balanceError,
1543
+ refreshBalance,
1544
+ payments,
1545
+ isLoadingPayments,
1546
+ paymentsError,
1547
+ refreshPayments,
1548
+ transactions,
1549
+ isLoadingTransactions,
1550
+ transactionsError,
1551
+ refreshTransactions,
1552
+ createPayment,
1553
+ isLoadingOverview,
1554
+ overviewError,
1555
+ refreshOverview
1556
+ };
1557
+ return /* @__PURE__ */ jsxRuntime.jsx(useSWR.SWRConfig, { value: swrConfig, children: /* @__PURE__ */ jsxRuntime.jsx(OverviewContext.Provider, { value, children }) });
1558
+ }
1559
+ function useOverviewContext() {
1560
+ const context = react.useContext(OverviewContext);
1561
+ if (!context) {
1562
+ throw new Error("useOverviewContext must be used within OverviewProvider");
1563
+ }
1564
+ return context;
1565
+ }
1566
+ var RootPaymentsContext = react.createContext(void 0);
1567
+ function RootPaymentsProvider({ children }) {
1568
+ const {
1569
+ data: currencies,
1570
+ error: currenciesError,
1571
+ isLoading: isLoadingCurrencies,
1572
+ mutate: mutateCurrencies
1573
+ } = usePaymentsCurrenciesList(apiPayments);
1574
+ const refreshCurrencies = async () => {
1575
+ await mutateCurrencies();
1576
+ };
1577
+ const value = {
1578
+ currencies,
1579
+ isLoadingCurrencies,
1580
+ currenciesError,
1581
+ refreshCurrencies
1582
+ };
1583
+ return /* @__PURE__ */ jsxRuntime.jsx(RootPaymentsContext.Provider, { value, children });
1584
+ }
1585
+ function useRootPaymentsContext() {
1586
+ const context = react.useContext(RootPaymentsContext);
1587
+ if (!context) {
1588
+ throw new Error("useRootPaymentsContext must be used within RootPaymentsProvider");
1589
+ }
1590
+ return context;
1591
+ }
1592
+
1593
+ // src/layouts/PaymentsLayout/events.ts
1594
+ var PAYMENT_EVENTS = {
1595
+ OPEN_CREATE_PAYMENT_DIALOG: "payments:open-create-payment",
1596
+ OPEN_PAYMENT_DETAILS_DIALOG: "payments:open-payment-details",
1597
+ CLOSE_DIALOG: "payments:close-dialog"
1598
+ };
1599
+ var openCreatePaymentDialog = () => {
1600
+ window.dispatchEvent(new Event(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG));
1601
+ };
1602
+ var openPaymentDetailsDialog = (id) => {
1603
+ window.dispatchEvent(
1604
+ new CustomEvent(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, {
1605
+ detail: { id }
1606
+ })
1607
+ );
1608
+ };
1609
+ var closePaymentsDialog = () => {
1610
+ window.dispatchEvent(new Event(PAYMENT_EVENTS.CLOSE_DIALOG));
1611
+ };
1612
+ var BalanceCard = () => {
1613
+ const {
1614
+ balance,
1615
+ isLoadingBalance,
1616
+ refreshBalance
1617
+ } = useOverviewContext();
1618
+ const formatCurrency = (amount) => {
1619
+ if (amount === null || amount === void 0) return "$0.00";
1620
+ return new Intl.NumberFormat("en-US", {
1621
+ style: "currency",
1622
+ currency: "USD",
1623
+ minimumFractionDigits: 2
1624
+ }).format(amount);
1625
+ };
1626
+ const formatDate = (dateStr) => {
1627
+ if (!dateStr) return "No transactions yet";
1628
+ try {
1629
+ return new Date(dateStr).toLocaleDateString("en-US", {
1630
+ year: "numeric",
1631
+ month: "short",
1632
+ day: "numeric"
1633
+ });
1634
+ } catch {
1635
+ return "Invalid date";
1636
+ }
1637
+ };
1638
+ if (isLoadingBalance) {
1639
+ return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
1640
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
1641
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1642
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { className: "h-5 w-5" }),
1643
+ "Account Balance"
1644
+ ] }),
1645
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-8 w-20" })
1646
+ ] }) }),
1647
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardContent, { className: "space-y-4", children: [
1648
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-10 w-32" }),
1649
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-4 w-48" })
1650
+ ] })
1651
+ ] });
1652
+ }
1653
+ const balanceData = balance?.balance || balance;
1654
+ const amountUsd = balanceData?.amount_usd ?? 0;
1655
+ const totalDeposited = balanceData?.total_deposited ?? 0;
1656
+ const totalWithdrawn = balanceData?.total_withdrawn ?? 0;
1657
+ const lastTransactionAt = balanceData?.last_transaction_at;
1658
+ const isEmpty = amountUsd === 0 && totalDeposited === 0;
1659
+ return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
1660
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
1661
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1662
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { className: "h-5 w-5" }),
1663
+ "Account Balance"
1664
+ ] }),
1665
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1666
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { variant: "ghost", size: "sm", onClick: refreshBalance, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4" }) }),
1667
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { size: "sm", onClick: () => openCreatePaymentDialog(), children: [
1668
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
1669
+ "Add Funds"
1670
+ ] })
1671
+ ] })
1672
+ ] }) }),
1673
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardContent, { className: "space-y-4", children: [
1674
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1675
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-4xl font-bold", children: formatCurrency(amountUsd) }),
1676
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mt-1", children: [
1677
+ "Available balance \u2022 Last updated ",
1678
+ formatDate(lastTransactionAt)
1679
+ ] })
1680
+ ] }),
1681
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4 pt-4 border-t", children: [
1682
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1683
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Total Deposited" }),
1684
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-semibold text-green-600", children: formatCurrency(totalDeposited) })
1685
+ ] }),
1686
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1687
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Total Withdrawn" }),
1688
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-semibold text-red-600", children: formatCurrency(totalWithdrawn) })
1689
+ ] })
1690
+ ] }),
1691
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1692
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: !isEmpty ? "default" : "secondary", children: !isEmpty ? "Active" : "New Account" }),
1693
+ isEmpty && /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: "outline", children: "Empty Balance" })
1694
+ ] })
1695
+ ] })
1696
+ ] });
1697
+ };
1698
+ var RecentPayments = () => {
1699
+ const { payments, isLoadingPayments } = useOverviewContext();
1700
+ const formatCurrency = (amount) => {
1701
+ if (amount === null || amount === void 0) return "$0.00";
1702
+ const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
1703
+ return new Intl.NumberFormat("en-US", {
1704
+ style: "currency",
1705
+ currency: "USD",
1706
+ minimumFractionDigits: 2
1707
+ }).format(numAmount);
1708
+ };
1709
+ const getRelativeTime = (date) => {
1710
+ if (!date) return "N/A";
1711
+ const now = /* @__PURE__ */ new Date();
1712
+ const target = new Date(date);
1713
+ const diffInSeconds = Math.floor((now.getTime() - target.getTime()) / 1e3);
1714
+ if (diffInSeconds < 60) return "Just now";
1715
+ if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
1716
+ if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
1717
+ return `${Math.floor(diffInSeconds / 86400)}d ago`;
1718
+ };
1719
+ const getStatusVariant = (status) => {
1720
+ switch (status?.toLowerCase()) {
1721
+ case "completed":
1722
+ case "success":
1723
+ return "default";
1724
+ case "pending":
1725
+ case "confirming":
1726
+ return "secondary";
1727
+ case "failed":
1728
+ case "error":
1729
+ case "expired":
1730
+ return "destructive";
1731
+ default:
1732
+ return "outline";
1733
+ }
1734
+ };
1735
+ if (isLoadingPayments) {
1736
+ return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
1737
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center gap-2", children: [
1738
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-5 w-5" }),
1739
+ "Recent Payments"
1740
+ ] }) }),
1741
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardContent, { className: "space-y-3", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-3 border rounded-sm", children: [
1742
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
1743
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-4 w-32" }),
1744
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-3 w-24" })
1745
+ ] }),
1746
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-6 w-16" })
1747
+ ] }, i)) })
1748
+ ] });
1749
+ }
1750
+ const recentPaymentsList = payments?.results?.slice(0, 5) || [];
1751
+ return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
1752
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
1753
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1754
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-5 w-5" }),
1755
+ "Recent Payments"
1756
+ ] }),
1757
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { variant: "ghost", size: "sm", children: [
1758
+ "View All",
1759
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 ml-2" })
1760
+ ] })
1761
+ ] }) }),
1762
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardContent, { children: recentPaymentsList.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
1763
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-12 w-12 mx-auto mb-4 opacity-50" }),
1764
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No recent payments" }),
1765
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm mt-2", children: "Create your first payment to get started" })
1766
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: recentPaymentsList.map((payment) => /* @__PURE__ */ jsxRuntime.jsxs(
1767
+ "div",
1768
+ {
1769
+ className: "flex items-center justify-between p-3 border rounded-sm hover:bg-accent cursor-pointer transition-colors",
1770
+ onClick: () => openPaymentDetailsDialog(String(payment.id)),
1771
+ children: [
1772
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
1773
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1774
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: formatCurrency(payment.amount_usd) }),
1775
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: getStatusVariant(payment.status), className: "text-xs", children: payment.status })
1776
+ ] }),
1777
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
1778
+ getRelativeTime(payment.created_at),
1779
+ " \u2022 ",
1780
+ payment.currency_code || "USD"
1781
+ ] })
1782
+ ] }),
1783
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 text-muted-foreground" })
1784
+ ]
1785
+ },
1786
+ payment.id
1787
+ )) }) })
1788
+ ] });
1789
+ };
1790
+ var OverviewView = () => {
1791
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 lg:grid-cols-2", children: [
1792
+ /* @__PURE__ */ jsxRuntime.jsx(BalanceCard, {}),
1793
+ /* @__PURE__ */ jsxRuntime.jsx(RecentPayments, {})
1794
+ ] }) });
1795
+ };
1796
+ var PaymentsList = () => {
1797
+ const pagination = uiNextjs.useDRFPagination(1, 20);
1798
+ const {
1799
+ data: payments,
1800
+ error,
1801
+ isLoading: isLoadingPayments,
1802
+ mutate: refreshPayments
1803
+ } = usePaymentsPaymentsList(pagination.params, apiPayments);
1804
+ const paymentsList = payments?.results || [];
1805
+ payments?.count || 0;
1806
+ const [searchTerm, setSearchTerm] = react.useState("");
1807
+ const [statusFilter, setStatusFilter] = react.useState("all");
1808
+ const formatCurrency = (amount) => {
1809
+ if (amount === null || amount === void 0) return "$0.00";
1810
+ const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
1811
+ return new Intl.NumberFormat("en-US", {
1812
+ style: "currency",
1813
+ currency: "USD",
1814
+ minimumFractionDigits: 2
1815
+ }).format(numAmount);
1816
+ };
1817
+ const getRelativeTime = (date) => {
1818
+ if (!date) return "N/A";
1819
+ const now = /* @__PURE__ */ new Date();
1820
+ const target = new Date(date);
1821
+ const diffInSeconds = Math.floor((now.getTime() - target.getTime()) / 1e3);
1822
+ if (diffInSeconds < 60) return "Just now";
1823
+ if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
1824
+ if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
1825
+ return `${Math.floor(diffInSeconds / 86400)}d ago`;
1826
+ };
1827
+ const getStatusVariant = (status) => {
1828
+ switch (status?.toLowerCase()) {
1829
+ case "completed":
1830
+ case "success":
1831
+ return "default";
1832
+ case "pending":
1833
+ case "confirming":
1834
+ return "secondary";
1835
+ case "failed":
1836
+ case "error":
1837
+ case "expired":
1838
+ return "destructive";
1839
+ default:
1840
+ return "outline";
1841
+ }
1842
+ };
1843
+ const handleSearch = (value) => {
1844
+ setSearchTerm(value);
1845
+ };
1846
+ const handleStatusFilter = (status) => {
1847
+ setStatusFilter(status);
1848
+ };
1849
+ const filteredPayments = paymentsList.filter((payment) => {
1850
+ const matchesSearch = searchTerm ? payment.id?.toLowerCase().includes(searchTerm.toLowerCase()) || payment.status?.toLowerCase().includes(searchTerm.toLowerCase()) || payment.currency_code?.toLowerCase().includes(searchTerm.toLowerCase()) : true;
1851
+ const matchesStatus = statusFilter !== "all" ? payment.status?.toLowerCase() === statusFilter.toLowerCase() : true;
1852
+ return matchesSearch && matchesStatus;
1853
+ });
1854
+ return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
1855
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
1856
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Payment History" }),
1857
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1858
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { variant: "outline", size: "sm", onClick: () => refreshPayments(), disabled: isLoadingPayments, children: [
1859
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: `h-4 w-4 mr-2 ${isLoadingPayments ? "animate-spin" : ""}` }),
1860
+ "Refresh"
1861
+ ] }),
1862
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { size: "sm", onClick: () => openCreatePaymentDialog(), children: [
1863
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
1864
+ "New Payment"
1865
+ ] })
1866
+ ] })
1867
+ ] }) }),
1868
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardContent, { className: "space-y-4", children: [
1869
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row gap-4", children: [
1870
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1", children: [
1871
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
1872
+ /* @__PURE__ */ jsxRuntime.jsx(
1873
+ uiNextjs.Input,
1874
+ {
1875
+ placeholder: "Search by ID, status, or currency...",
1876
+ value: searchTerm,
1877
+ onChange: (e) => handleSearch(e.target.value),
1878
+ className: "pl-10"
1879
+ }
1880
+ )
1881
+ ] }),
1882
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Select, { value: statusFilter, onValueChange: handleStatusFilter, children: [
1883
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.SelectTrigger, { className: "w-full sm:w-48", children: [
1884
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "h-4 w-4 mr-2" }),
1885
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectValue, { placeholder: "Filter by status" })
1886
+ ] }),
1887
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.SelectContent, { children: [
1888
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: "all", children: "All Statuses" }),
1889
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: "completed", children: "Completed" }),
1890
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: "pending", children: "Pending" }),
1891
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: "confirming", children: "Confirming" }),
1892
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: "failed", children: "Failed" }),
1893
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: "expired", children: "Expired" })
1894
+ ] })
1895
+ ] })
1896
+ ] }),
1897
+ isLoadingPayments ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border rounded-sm", children: [
1898
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
1899
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-4 w-32" }),
1900
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-3 w-24" })
1901
+ ] }),
1902
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-6 w-16" })
1903
+ ] }, i)) }) : filteredPayments.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-12", children: [
1904
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 mx-auto mb-4 bg-muted rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "w-8 h-8 text-muted-foreground" }) }),
1905
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-2", children: "No Payments Found" }),
1906
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-4", children: searchTerm || statusFilter !== "all" ? "No payments match your current filters" : "You haven't made any payments yet" }),
1907
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { onClick: () => openCreatePaymentDialog(), children: [
1908
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
1909
+ "Create Payment"
1910
+ ] })
1911
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1912
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Table, { children: [
1913
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.TableRow, { children: [
1914
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Date" }),
1915
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Amount" }),
1916
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Currency" }),
1917
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Status" }),
1918
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Provider" }),
1919
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Payment ID" }),
1920
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { className: "text-right", children: "Actions" })
1921
+ ] }) }),
1922
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableBody, { children: filteredPayments.map((payment) => /* @__PURE__ */ jsxRuntime.jsxs(
1923
+ uiNextjs.TableRow,
1924
+ {
1925
+ className: "cursor-pointer hover:bg-accent",
1926
+ onClick: () => openPaymentDetailsDialog(String(payment.id)),
1927
+ children: [
1928
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1929
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: payment.created_at ? new Date(payment.created_at).toLocaleDateString() : "N/A" }),
1930
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: getRelativeTime(payment.created_at) })
1931
+ ] }) }),
1932
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono font-semibold", children: formatCurrency(payment.amount_usd) }),
1933
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: "outline", children: payment.currency_code || "USD" }) }),
1934
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: getStatusVariant(payment.status), children: payment.status }) }),
1935
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "text-sm text-muted-foreground", children: "NowPayments" }),
1936
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono text-sm text-muted-foreground", children: payment.id ? `${payment.id.toString().slice(0, 8)}...` : "N/A" }),
1937
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(
1938
+ uiNextjs.Button,
1939
+ {
1940
+ variant: "ghost",
1941
+ size: "sm",
1942
+ onClick: (e) => {
1943
+ e.stopPropagation();
1944
+ openPaymentDetailsDialog(String(payment.id));
1945
+ },
1946
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4" })
1947
+ }
1948
+ ) })
1949
+ ]
1950
+ },
1951
+ payment.id
1952
+ )) })
1953
+ ] }) }),
1954
+ /* @__PURE__ */ jsxRuntime.jsx(
1955
+ uiNextjs.StaticPagination,
1956
+ {
1957
+ data: payments,
1958
+ onPageChange: pagination.setPage,
1959
+ className: "mt-4"
1960
+ }
1961
+ )
1962
+ ] })
1963
+ ] })
1964
+ ] });
1965
+ };
1966
+ var PaymentsView = () => {
1967
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsx(PaymentsList, {}) });
1968
+ };
1969
+ var TransactionsList = () => {
1970
+ const {
1971
+ transactions,
1972
+ isLoadingTransactions,
1973
+ refreshTransactions
1974
+ } = useOverviewContext();
1975
+ const [searchTerm, setSearchTerm] = react.useState("");
1976
+ const [typeFilter, setTypeFilter] = react.useState("all");
1977
+ const transactionsList = transactions?.results || transactions?.transactions || [];
1978
+ const formatCurrency = (amount) => {
1979
+ if (amount === null || amount === void 0) return "$0.00";
1980
+ return new Intl.NumberFormat("en-US", {
1981
+ style: "currency",
1982
+ currency: "USD",
1983
+ minimumFractionDigits: 2
1984
+ }).format(amount);
1985
+ };
1986
+ const formatDate = (date) => {
1987
+ if (!date) return "N/A";
1988
+ try {
1989
+ return new Date(date).toLocaleString("en-US", {
1990
+ year: "numeric",
1991
+ month: "short",
1992
+ day: "numeric",
1993
+ hour: "2-digit",
1994
+ minute: "2-digit"
1995
+ });
1996
+ } catch {
1997
+ return "Invalid date";
1998
+ }
1999
+ };
2000
+ const getRelativeTime = (date) => {
2001
+ if (!date) return "N/A";
2002
+ const now = /* @__PURE__ */ new Date();
2003
+ const target = new Date(date);
2004
+ const diffInSeconds = Math.floor((now.getTime() - target.getTime()) / 1e3);
2005
+ if (diffInSeconds < 60) return "Just now";
2006
+ if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
2007
+ if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
2008
+ return `${Math.floor(diffInSeconds / 86400)}d ago`;
2009
+ };
2010
+ const getTypeVariant = (type) => {
2011
+ switch (type?.toLowerCase()) {
2012
+ case "deposit":
2013
+ case "credit":
2014
+ return "default";
2015
+ case "withdrawal":
2016
+ case "debit":
2017
+ return "destructive";
2018
+ default:
2019
+ return "outline";
2020
+ }
2021
+ };
2022
+ const getTypeIcon = (type) => {
2023
+ const isDeposit = type?.toLowerCase() === "deposit" || type?.toLowerCase() === "credit";
2024
+ return isDeposit ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownLeft, { className: "h-4 w-4 text-green-600" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpRight, { className: "h-4 w-4 text-red-600" });
2025
+ };
2026
+ const handleSearch = async (value) => {
2027
+ setSearchTerm(value);
2028
+ await refreshTransactions();
2029
+ };
2030
+ const handleTypeFilter = async (type) => {
2031
+ setTypeFilter(type);
2032
+ await refreshTransactions();
2033
+ };
2034
+ const filteredTransactions = transactionsList.filter((transaction) => {
2035
+ const matchesSearch = searchTerm ? transaction.id?.toString().toLowerCase().includes(searchTerm.toLowerCase()) || transaction.description?.toLowerCase().includes(searchTerm.toLowerCase()) || transaction.type?.toLowerCase().includes(searchTerm.toLowerCase()) : true;
2036
+ const matchesType = typeFilter !== "all" ? transaction.type?.toLowerCase() === typeFilter.toLowerCase() : true;
2037
+ return matchesSearch && matchesType;
2038
+ });
2039
+ if (isLoadingTransactions) {
2040
+ return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
2041
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center gap-2", children: [
2042
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-5 w-5" }),
2043
+ "Transaction History"
2044
+ ] }) }),
2045
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardContent, { className: "space-y-3", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border rounded-sm", children: [
2046
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
2047
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-4 w-32" }),
2048
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-3 w-24" })
2049
+ ] }),
2050
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-6 w-16" })
2051
+ ] }, i)) })
2052
+ ] });
2053
+ }
2054
+ return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
2055
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
2056
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2057
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-5 w-5" }),
2058
+ "Transaction History"
2059
+ ] }),
2060
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { variant: "outline", size: "sm", onClick: refreshTransactions, disabled: isLoadingTransactions, children: [
2061
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: `h-4 w-4 mr-2 ${isLoadingTransactions ? "animate-spin" : ""}` }),
2062
+ "Refresh"
2063
+ ] })
2064
+ ] }) }),
2065
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardContent, { className: "space-y-4", children: [
2066
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row gap-4", children: [
2067
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1", children: [
2068
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
2069
+ /* @__PURE__ */ jsxRuntime.jsx(
2070
+ uiNextjs.Input,
2071
+ {
2072
+ placeholder: "Search by ID, description, or type...",
2073
+ value: searchTerm,
2074
+ onChange: (e) => handleSearch(e.target.value),
2075
+ className: "pl-10"
2076
+ }
2077
+ )
2078
+ ] }),
2079
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Select, { value: typeFilter, onValueChange: handleTypeFilter, children: [
2080
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.SelectTrigger, { className: "w-full sm:w-48", children: [
2081
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "h-4 w-4 mr-2" }),
2082
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectValue, { placeholder: "Filter by type" })
2083
+ ] }),
2084
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.SelectContent, { children: [
2085
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: "all", children: "All Types" }),
2086
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: "deposit", children: "Deposits" }),
2087
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: "withdrawal", children: "Withdrawals" })
2088
+ ] })
2089
+ ] })
2090
+ ] }),
2091
+ filteredTransactions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-12", children: [
2092
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 mx-auto mb-4 bg-muted rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "w-8 h-8 text-muted-foreground" }) }),
2093
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-2", children: "No Transactions Found" }),
2094
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: searchTerm || typeFilter !== "all" ? "No transactions match your current filters" : "You don't have any transactions yet" })
2095
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Table, { children: [
2096
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.TableRow, { children: [
2097
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Date & Time" }),
2098
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Type" }),
2099
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Amount" }),
2100
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Balance After" }),
2101
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Description" }),
2102
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Reference" })
2103
+ ] }) }),
2104
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableBody, { children: filteredTransactions.map((transaction, index) => {
2105
+ const isDeposit = transaction.type?.toLowerCase() === "deposit" || transaction.type?.toLowerCase() === "credit";
2106
+ return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.TableRow, { children: [
2107
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2108
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: formatDate(transaction.created_at || transaction.timestamp) }),
2109
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: getRelativeTime(transaction.created_at || transaction.timestamp) })
2110
+ ] }) }),
2111
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2112
+ getTypeIcon(transaction.type),
2113
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: getTypeVariant(transaction.type), children: transaction.type || "Unknown" })
2114
+ ] }) }),
2115
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono font-semibold", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: isDeposit ? "text-green-600" : "text-red-600", children: [
2116
+ isDeposit ? "+" : "-",
2117
+ formatCurrency(Math.abs(transaction.amount || transaction.amount_usd || 0))
2118
+ ] }) }),
2119
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono", children: formatCurrency(transaction.balance_after || 0) }),
2120
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "text-sm", children: transaction.description || transaction.note || "No description" }),
2121
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono text-sm text-muted-foreground", children: transaction.reference || transaction.payment_id ? `${(transaction.reference || transaction.payment_id).toString().slice(0, 8)}...` : "N/A" })
2122
+ ] }, transaction.id || index);
2123
+ }) })
2124
+ ] }) })
2125
+ ] })
2126
+ ] });
2127
+ };
2128
+ var TransactionsView = () => {
2129
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsx(TransactionsList, {}) });
2130
+ };
2131
+ var isDevelopment = process.env.NODE_ENV === "development";
2132
+ var logger = consola.createConsola({
2133
+ level: isDevelopment ? 4 : 1
2134
+ }).withTag("ext-payments");
2135
+ var paymentsLogger = logger;
2136
+ var PaymentCreateSchema = zod.z.object({
2137
+ amount_usd: zod.z.number().min(0.01, "Amount must be at least $0.01"),
2138
+ currency_code: zod.z.string().min(1, "Please select a currency")
2139
+ });
2140
+ var CreatePaymentDialog = () => {
2141
+ const [open, setOpen] = react.useState(false);
2142
+ const [isSubmitting, setIsSubmitting] = react.useState(false);
2143
+ const { createPayment } = usePaymentsContext();
2144
+ const { currencies, isLoadingCurrencies } = useRootPaymentsContext();
2145
+ const form = reactHookForm.useForm({
2146
+ resolver: zod$1.zodResolver(PaymentCreateSchema),
2147
+ defaultValues: {
2148
+ amount_usd: 10,
2149
+ currency_code: "USDT"
2150
+ }
2151
+ });
2152
+ const currenciesList = react.useMemo(() => {
2153
+ const data = currencies?.currencies || currencies?.results || currencies || [];
2154
+ return Array.isArray(data) ? data : [];
2155
+ }, [currencies]);
2156
+ const currencyOptions = react.useMemo(() => {
2157
+ return currenciesList.filter((curr) => curr.is_enabled !== false).map((curr) => ({
2158
+ code: curr.code || curr.currency_code || curr.symbol,
2159
+ name: curr.name || curr.code || curr.currency_code,
2160
+ usd_rate: curr.usd_rate || curr.rate || 1,
2161
+ network: curr.network || null
2162
+ }));
2163
+ }, [currenciesList]);
2164
+ const calculateCryptoAmount = react.useMemo(() => {
2165
+ const amountUsd = form.watch("amount_usd");
2166
+ const currencyCode = form.watch("currency_code");
2167
+ const currency = currencyOptions.find((c) => c.code === currencyCode);
2168
+ if (!currency || !currency.usd_rate || !amountUsd) {
2169
+ return null;
2170
+ }
2171
+ const cryptoAmount = amountUsd / currency.usd_rate;
2172
+ return {
2173
+ amount: cryptoAmount,
2174
+ currency: currency.code,
2175
+ rate: currency.usd_rate,
2176
+ network: currency.network
2177
+ };
2178
+ }, [form.watch("amount_usd"), form.watch("currency_code"), currencyOptions]);
2179
+ react.useEffect(() => {
2180
+ const handleOpen = () => setOpen(true);
2181
+ const handleClose2 = () => setOpen(false);
2182
+ window.addEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
2183
+ window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
2184
+ return () => {
2185
+ window.removeEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
2186
+ window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
2187
+ };
2188
+ }, []);
2189
+ const handleClose = () => {
2190
+ setOpen(false);
2191
+ form.reset();
2192
+ };
2193
+ react.useEffect(() => {
2194
+ if (currencyOptions.length > 0 && !form.getValues("currency_code")) {
2195
+ form.setValue("currency_code", currencyOptions[0].code);
2196
+ }
2197
+ }, [currencyOptions, form]);
2198
+ const handleSubmit = async (data) => {
2199
+ try {
2200
+ setIsSubmitting(true);
2201
+ const result = await createPayment();
2202
+ handleClose();
2203
+ closePaymentsDialog();
2204
+ const paymentData = result;
2205
+ const paymentId = paymentData?.payment?.id || paymentData?.id;
2206
+ if (paymentId) {
2207
+ openPaymentDetailsDialog(String(paymentId));
2208
+ }
2209
+ } catch (error) {
2210
+ paymentsLogger.error("Failed to create payment:", error);
2211
+ } finally {
2212
+ setIsSubmitting(false);
2213
+ }
2214
+ };
2215
+ return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-md", children: [
2216
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
2217
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Create Payment" }),
2218
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Create a new payment to add funds to your account." })
2219
+ ] }),
2220
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: form.handleSubmit(handleSubmit), className: "space-y-4", children: [
2221
+ /* @__PURE__ */ jsxRuntime.jsx(
2222
+ uiNextjs.FormField,
2223
+ {
2224
+ control: form.control,
2225
+ name: "amount_usd",
2226
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.FormItem, { children: [
2227
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormLabel, { children: "Amount (USD)" }),
2228
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
2229
+ uiNextjs.Input,
2230
+ {
2231
+ type: "number",
2232
+ step: "0.01",
2233
+ min: "0.01",
2234
+ placeholder: "10.00",
2235
+ ...field,
2236
+ onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
2237
+ }
2238
+ ) }),
2239
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormDescription, { children: "The amount you want to pay in USD." }),
2240
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormMessage, {})
2241
+ ] })
2242
+ }
2243
+ ),
2244
+ /* @__PURE__ */ jsxRuntime.jsx(
2245
+ uiNextjs.FormField,
2246
+ {
2247
+ control: form.control,
2248
+ name: "currency_code",
2249
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.FormItem, { children: [
2250
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormLabel, { children: "Currency" }),
2251
+ /* @__PURE__ */ jsxRuntime.jsxs(
2252
+ uiNextjs.Select,
2253
+ {
2254
+ onValueChange: field.onChange,
2255
+ defaultValue: field.value,
2256
+ disabled: isLoadingCurrencies,
2257
+ children: [
2258
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectValue, { placeholder: "Select currency..." }) }) }),
2259
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectContent, { children: currencyOptions.map((curr) => /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: curr.code, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2260
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TokenIcon, { symbol: curr.code, size: 16 }),
2261
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: curr.code }),
2262
+ curr.network && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
2263
+ "(",
2264
+ curr.network,
2265
+ ")"
2266
+ ] })
2267
+ ] }) }, curr.code)) })
2268
+ ]
2269
+ }
2270
+ ),
2271
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormDescription, { children: "The cryptocurrency to use for payment." }),
2272
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormMessage, {})
2273
+ ] })
2274
+ }
2275
+ ),
2276
+ calculateCryptoAmount && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-sm bg-muted p-4 space-y-3", children: [
2277
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2278
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "You will send" }),
2279
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2280
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TokenIcon, { symbol: calculateCryptoAmount.currency, size: 16 }),
2281
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono font-semibold", children: [
2282
+ calculateCryptoAmount.amount.toFixed(8),
2283
+ " ",
2284
+ calculateCryptoAmount.currency
2285
+ ] })
2286
+ ] })
2287
+ ] }),
2288
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2289
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "You will receive" }),
2290
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-lg font-bold", children: [
2291
+ "$",
2292
+ form.watch("amount_usd")?.toFixed(2),
2293
+ " USD"
2294
+ ] })
2295
+ ] }),
2296
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
2297
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Rate" }),
2298
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
2299
+ "1 ",
2300
+ calculateCryptoAmount.currency,
2301
+ " = $",
2302
+ calculateCryptoAmount.rate?.toFixed(2)
2303
+ ] })
2304
+ ] }),
2305
+ calculateCryptoAmount.network && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t pt-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2306
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Network" }),
2307
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: calculateCryptoAmount.network })
2308
+ ] }) })
2309
+ ] }),
2310
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogFooter, { children: [
2311
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { type: "button", variant: "outline", onClick: handleClose, disabled: isSubmitting, children: "Cancel" }),
2312
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { type: "submit", disabled: isSubmitting || currencyOptions.length === 0, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2313
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4 mr-2 animate-spin" }),
2314
+ "Creating..."
2315
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2316
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
2317
+ "Create Payment"
2318
+ ] }) })
2319
+ ] })
2320
+ ] }) })
2321
+ ] }) });
2322
+ };
2323
+ var PaymentDetailsDialog = () => {
2324
+ const [open, setOpen] = react.useState(false);
2325
+ const [paymentId, setPaymentId] = react.useState(null);
2326
+ const [timeLeft, setTimeLeft] = react.useState("");
2327
+ const shouldFetch = open && !!paymentId;
2328
+ const { data: payment, isLoading, error, mutate } = usePaymentsPaymentsRetrieve(
2329
+ shouldFetch ? paymentId : "",
2330
+ apiPayments
2331
+ );
2332
+ react.useEffect(() => {
2333
+ const handleOpen = (event) => {
2334
+ const customEvent = event;
2335
+ setPaymentId(customEvent.detail.id);
2336
+ setOpen(true);
2337
+ };
2338
+ const handleClose2 = () => {
2339
+ setOpen(false);
2340
+ setPaymentId(null);
2341
+ };
2342
+ window.addEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
2343
+ window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
2344
+ return () => {
2345
+ window.removeEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
2346
+ window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
2347
+ };
2348
+ }, []);
2349
+ const handleClose = () => {
2350
+ setOpen(false);
2351
+ setPaymentId(null);
2352
+ };
2353
+ react.useEffect(() => {
2354
+ if (!payment?.expires_at) return;
2355
+ const updateTimeLeft = () => {
2356
+ const now = (/* @__PURE__ */ new Date()).getTime();
2357
+ const expires = new Date(payment.expires_at).getTime();
2358
+ const diff = expires - now;
2359
+ if (diff <= 0) {
2360
+ setTimeLeft("Expired");
2361
+ return;
2362
+ }
2363
+ const hours = Math.floor(diff / (1e3 * 60 * 60));
2364
+ const minutes = Math.floor(diff % (1e3 * 60 * 60) / (1e3 * 60));
2365
+ const seconds = Math.floor(diff % (1e3 * 60) / 1e3);
2366
+ setTimeLeft(`${hours}h ${minutes}m ${seconds}s`);
2367
+ };
2368
+ updateTimeLeft();
2369
+ const interval = setInterval(updateTimeLeft, 1e3);
2370
+ return () => clearInterval(interval);
2371
+ }, [payment?.expires_at]);
2372
+ const getStatusInfo = () => {
2373
+ switch (payment?.status?.toLowerCase()) {
2374
+ case "pending":
2375
+ return { icon: lucideReact.Clock, color: "text-yellow-500", bg: "bg-yellow-500/10" };
2376
+ case "completed":
2377
+ case "success":
2378
+ return { icon: lucideReact.CheckCircle2, color: "text-green-500", bg: "bg-green-500/10" };
2379
+ case "failed":
2380
+ case "error":
2381
+ return { icon: lucideReact.XCircle, color: "text-red-500", bg: "bg-red-500/10" };
2382
+ case "expired":
2383
+ return { icon: lucideReact.AlertCircle, color: "text-gray-500", bg: "bg-gray-500/10" };
2384
+ case "confirming":
2385
+ return { icon: lucideReact.RefreshCw, color: "text-blue-500", bg: "bg-blue-500/10" };
2386
+ default:
2387
+ return { icon: lucideReact.Clock, color: "text-gray-500", bg: "bg-gray-500/10" };
2388
+ }
2389
+ };
2390
+ if (!open) return null;
2391
+ if (isLoading) {
2392
+ return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-lg", children: [
2393
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
2394
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Payment Details" }),
2395
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Loading payment information..." })
2396
+ ] }),
2397
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-8 w-8 animate-spin text-muted-foreground" }) })
2398
+ ] }) });
2399
+ }
2400
+ if (shouldFetch && !isLoading && (error || !payment)) {
2401
+ return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-lg", children: [
2402
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
2403
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Payment Details" }),
2404
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Failed to load payment information" })
2405
+ ] }),
2406
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
2407
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "h-12 w-12 text-destructive" }),
2408
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: error ? `Error: ${error}` : "Payment not found" }),
2409
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { onClick: () => mutate(), children: "Try Again" })
2410
+ ] })
2411
+ ] }) });
2412
+ }
2413
+ const statusInfo = getStatusInfo();
2414
+ const StatusIcon = statusInfo.icon;
2415
+ const qrCodeUrl = payment.pay_address ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}` : null;
2416
+ return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-lg", children: [
2417
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
2418
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Payment Details" }),
2419
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Send cryptocurrency to complete your payment" })
2420
+ ] }),
2421
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
2422
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-3 p-4 rounded-sm ${statusInfo.bg}`, children: [
2423
+ /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { className: `h-5 w-5 ${statusInfo.color}` }),
2424
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
2425
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-semibold capitalize", children: payment.status }),
2426
+ payment.status === "pending" && timeLeft && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-muted-foreground", children: [
2427
+ "Expires in ",
2428
+ timeLeft
2429
+ ] })
2430
+ ] })
2431
+ ] }),
2432
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2433
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 bg-muted rounded-sm", children: [
2434
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Amount to send" }),
2435
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2436
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TokenIcon, { symbol: String(payment.currency_code || "BTC"), size: 20 }),
2437
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono font-bold text-lg", children: [
2438
+ payment.pay_amount || "0.00000000",
2439
+ " ",
2440
+ payment.currency_code
2441
+ ] })
2442
+ ] })
2443
+ ] }),
2444
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
2445
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Equivalent to" }),
2446
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-lg", children: [
2447
+ "$",
2448
+ parseFloat(payment.amount_usd || "0").toFixed(2),
2449
+ " USD"
2450
+ ] })
2451
+ ] }),
2452
+ payment.internal_payment_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
2453
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Payment Order #" }),
2454
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-medium", children: payment.internal_payment_id })
2455
+ ] }),
2456
+ payment.currency_network && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
2457
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Network" }),
2458
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: payment.currency_network })
2459
+ ] })
2460
+ ] }),
2461
+ qrCodeUrl && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center p-6 bg-white rounded-sm", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: qrCodeUrl, alt: "Payment QR Code", className: "w-48 h-48" }) }),
2462
+ payment.pay_address && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
2463
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Payment Address" }),
2464
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2465
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.pay_address }),
2466
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CopyButton, { value: payment.pay_address, variant: "outline" })
2467
+ ] })
2468
+ ] }),
2469
+ payment.transaction_hash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
2470
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
2471
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.transaction_hash })
2472
+ ] }),
2473
+ payment.payment_url && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsxs(
2474
+ uiNextjs.Button,
2475
+ {
2476
+ variant: "outline",
2477
+ className: "w-full",
2478
+ onClick: () => window.open(payment.payment_url, "_blank"),
2479
+ children: [
2480
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 mr-2" }),
2481
+ "Open in Payment Provider"
2482
+ ]
2483
+ }
2484
+ ),
2485
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t space-y-2 text-xs text-muted-foreground", children: [
2486
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
2487
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Payment ID" }),
2488
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: payment.id })
2489
+ ] }),
2490
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
2491
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Created" }),
2492
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: new Date(payment.created_at).toLocaleString() })
2493
+ ] }),
2494
+ payment.confirmations_count !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
2495
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Confirmations" }),
2496
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: payment.confirmations_count })
2497
+ ] })
2498
+ ] })
2499
+ ] }),
2500
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogFooter, { children: [
2501
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { variant: "outline", onClick: handleClose, children: "Close" }),
2502
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { onClick: () => mutate(), variant: "ghost", size: "sm", children: [
2503
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4 mr-2" }),
2504
+ "Refresh"
2505
+ ] })
2506
+ ] })
2507
+ ] }) });
2508
+ };
2509
+ var PaymentsLayout = () => {
2510
+ return /* @__PURE__ */ jsxRuntime.jsx(RootPaymentsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full p-6 space-y-6", children: [
2511
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2512
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "Payments" }),
2513
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "Manage your payments, balance, and transaction history" })
2514
+ ] }),
2515
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Tabs, { defaultValue: "overview", className: "space-y-6", children: [
2516
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.TabsList, { className: "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground", children: [
2517
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.TabsTrigger, { value: "overview", className: "inline-flex items-center gap-2 px-3 py-1.5", children: [
2518
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { className: "h-4 w-4" }),
2519
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "Overview" })
2520
+ ] }),
2521
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.TabsTrigger, { value: "payments", className: "inline-flex items-center gap-2 px-3 py-1.5", children: [
2522
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCard, { className: "h-4 w-4" }),
2523
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "Payments" })
2524
+ ] }),
2525
+ /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.TabsTrigger, { value: "transactions", className: "inline-flex items-center gap-2 px-3 py-1.5", children: [
2526
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-4 w-4" }),
2527
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "Transactions" })
2528
+ ] })
2529
+ ] }),
2530
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TabsContent, { value: "overview", className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsx(OverviewProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(PaymentsProvider, { children: [
2531
+ /* @__PURE__ */ jsxRuntime.jsx(OverviewView, {}),
2532
+ /* @__PURE__ */ jsxRuntime.jsx(CreatePaymentDialog, {})
2533
+ ] }) }) }),
2534
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TabsContent, { value: "payments", className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsxs(PaymentsProvider, { children: [
2535
+ /* @__PURE__ */ jsxRuntime.jsx(PaymentsView, {}),
2536
+ /* @__PURE__ */ jsxRuntime.jsx(CreatePaymentDialog, {})
2537
+ ] }) }),
2538
+ /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TabsContent, { value: "transactions", className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsx(OverviewProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(TransactionsView, {}) }) })
2539
+ ] }),
2540
+ /* @__PURE__ */ jsxRuntime.jsx(PaymentDetailsDialog, {})
2541
+ ] }) });
2542
+ };
2543
+
2544
+ exports.API = API;
2545
+ exports.APIClient = APIClient;
2546
+ exports.APIError = APIError;
2547
+ exports.APILogger = APILogger;
2548
+ exports.BalanceSchema = BalanceSchema;
2549
+ exports.CookieStorageAdapter = CookieStorageAdapter;
2550
+ exports.CurrencySchema = CurrencySchema;
2551
+ exports.DEFAULT_RETRY_CONFIG = DEFAULT_RETRY_CONFIG;
2552
+ exports.Enums = enums_exports;
2553
+ exports.ExtPaymentsPaymentsTypes = models_exports;
2554
+ exports.FetchAdapter = FetchAdapter;
2555
+ exports.Fetchers = fetchers_exports;
2556
+ exports.LocalStorageAdapter = LocalStorageAdapter;
2557
+ exports.MemoryStorageAdapter = MemoryStorageAdapter;
2558
+ exports.NetworkError = NetworkError;
2559
+ exports.PAYMENT_EVENTS = PAYMENT_EVENTS;
2560
+ exports.PaginatedPaymentListListSchema = PaginatedPaymentListListSchema;
2561
+ exports.PaymentDetailSchema = PaymentDetailSchema;
2562
+ exports.PaymentListSchema = PaymentListSchema;
2563
+ exports.PaymentsLayout = PaymentsLayout;
2564
+ exports.REFRESH_TOKEN_KEY = REFRESH_TOKEN_KEY;
2565
+ exports.Schemas = schemas_exports;
2566
+ exports.TOKEN_KEY = TOKEN_KEY;
2567
+ exports.TransactionSchema = TransactionSchema;
2568
+ exports.apiPayments = apiPayments;
2569
+ exports.clearAPITokens = clearAPITokens;
2570
+ exports.closePaymentsDialog = closePaymentsDialog;
2571
+ exports.configureAPI = configureAPI;
2572
+ exports.createPaymentsPaymentsConfirmCreate = createPaymentsPaymentsConfirmCreate;
2573
+ exports.createPaymentsPaymentsCreateCreate = createPaymentsPaymentsCreateCreate;
2574
+ exports.dispatchValidationError = dispatchValidationError;
2575
+ exports.formatZodError = formatZodError;
2576
+ exports.getAPIInstance = getAPIInstance;
2577
+ exports.getPaymentsBalanceRetrieve = getPaymentsBalanceRetrieve;
2578
+ exports.getPaymentsCurrenciesList = getPaymentsCurrenciesList;
2579
+ exports.getPaymentsPaymentsList = getPaymentsPaymentsList;
2580
+ exports.getPaymentsPaymentsRetrieve = getPaymentsPaymentsRetrieve;
2581
+ exports.getPaymentsPaymentsStatusRetrieve = getPaymentsPaymentsStatusRetrieve;
2582
+ exports.getPaymentsTransactionsList = getPaymentsTransactionsList;
2583
+ exports.isAPIConfigured = isAPIConfigured;
2584
+ exports.onValidationError = onValidationError;
2585
+ exports.openCreatePaymentDialog = openCreatePaymentDialog;
2586
+ exports.openPaymentDetailsDialog = openPaymentDetailsDialog;
2587
+ exports.reconfigureAPI = reconfigureAPI;
2588
+ exports.resetAPI = resetAPI;
2589
+ exports.shouldRetry = shouldRetry;
2590
+ exports.withRetry = withRetry;