@djangocfg/ext-payments 1.0.1 → 1.0.3

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