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