@djangocfg/ext-payments 1.0.13 → 1.0.17
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/config.cjs +5 -8
- package/dist/config.js +5 -8
- package/dist/hooks.cjs +1 -1
- package/dist/hooks.js +1 -1
- package/dist/index.cjs +1085 -1107
- package/dist/index.d.cts +480 -41
- package/dist/index.d.ts +480 -41
- package/dist/index.js +1037 -1093
- package/package.json +13 -16
- package/src/api/generated/ext_payments/CLAUDE.md +7 -3
- package/src/api/generated/ext_payments/_utils/fetchers/ext_payments__payments.ts +237 -5
- package/src/api/generated/ext_payments/_utils/hooks/ext_payments__payments.ts +71 -3
- package/src/api/generated/ext_payments/_utils/schemas/PaginatedWithdrawalListList.schema.ts +24 -0
- package/src/api/generated/ext_payments/_utils/schemas/PaymentCreateRequest.schema.ts +21 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCreateRequest.schema.ts +21 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalDetail.schema.ts +42 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalList.schema.ts +29 -0
- package/src/api/generated/ext_payments/_utils/schemas/index.ts +5 -0
- package/src/api/generated/ext_payments/enums.ts +36 -0
- package/src/api/generated/ext_payments/ext_payments__payments/client.ts +58 -5
- package/src/api/generated/ext_payments/ext_payments__payments/models.ts +141 -0
- package/src/api/generated/ext_payments/schema.json +579 -3
- package/src/components/ActivityItem.tsx +118 -0
- package/src/components/ActivityList.tsx +93 -0
- package/src/components/AddFundsSheet.tsx +258 -0
- package/src/components/BalanceHero.tsx +102 -0
- package/src/components/PaymentSheet.tsx +290 -0
- package/src/components/ResponsiveSheet.tsx +151 -0
- package/src/components/WithdrawSheet.tsx +329 -0
- package/src/components/index.ts +18 -0
- package/src/contexts/WalletContext.tsx +355 -0
- package/src/contexts/index.ts +12 -45
- package/src/index.ts +6 -18
- package/src/contexts/BalancesContext.tsx +0 -63
- package/src/contexts/CurrenciesContext.tsx +0 -64
- package/src/contexts/OverviewContext.tsx +0 -173
- package/src/contexts/PaymentsContext.tsx +0 -122
- package/src/contexts/PaymentsExtensionProvider.tsx +0 -56
- package/src/contexts/README.md +0 -201
- package/src/contexts/RootPaymentsContext.tsx +0 -66
- package/src/contexts/types.ts +0 -40
- package/src/hooks/index.ts +0 -20
- package/src/layouts/PaymentsLayout/PaymentsLayout.tsx +0 -90
- package/src/layouts/PaymentsLayout/components/CreatePaymentDialog.tsx +0 -274
- package/src/layouts/PaymentsLayout/components/PaymentDetailsDialog.tsx +0 -287
- package/src/layouts/PaymentsLayout/components/index.ts +0 -2
- package/src/layouts/PaymentsLayout/events.ts +0 -47
- package/src/layouts/PaymentsLayout/index.ts +0 -16
- package/src/layouts/PaymentsLayout/types.ts +0 -6
- package/src/layouts/PaymentsLayout/views/overview/components/BalanceCard.tsx +0 -121
- package/src/layouts/PaymentsLayout/views/overview/components/RecentPayments.tsx +0 -139
- package/src/layouts/PaymentsLayout/views/overview/components/index.ts +0 -2
- package/src/layouts/PaymentsLayout/views/overview/index.tsx +0 -21
- package/src/layouts/PaymentsLayout/views/payments/components/PaymentsList.tsx +0 -279
- package/src/layouts/PaymentsLayout/views/payments/components/index.ts +0 -1
- package/src/layouts/PaymentsLayout/views/payments/index.tsx +0 -18
- package/src/layouts/PaymentsLayout/views/transactions/components/TransactionsList.tsx +0 -260
- package/src/layouts/PaymentsLayout/views/transactions/components/index.ts +0 -1
- package/src/layouts/PaymentsLayout/views/transactions/index.tsx +0 -18
package/dist/index.js
CHANGED
|
@@ -2,15 +2,16 @@ import { createConsola, consola } from 'consola';
|
|
|
2
2
|
import pRetry, { AbortError } from 'p-retry';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { initializeExtensionAPI, createExtensionAPI } from '@djangocfg/ext-base/api';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
5
|
+
import { Plus, ArrowUpRight, RefreshCw, AlertCircle, XCircle, CheckCircle2, Loader2, Clock, ArrowDownLeft, History, ChevronRight, ExternalLink } from 'lucide-react';
|
|
6
|
+
import { Skeleton, Button, TokenIcon, ResponsiveSheet, ResponsiveSheetContent, ResponsiveSheetHeader, ResponsiveSheetTitle, ResponsiveSheetDescription, Form, FormField, FormItem, FormLabel, FormControl, Input, FormMessage, Combobox, Alert, AlertDescription, CopyButton, useIsMobile, Drawer, Dialog, DrawerContent, DialogContent, DrawerHeader, DialogHeader, DrawerTitle, DialogTitle, DrawerDescription, DialogDescription, DrawerFooter, DialogFooter } from '@djangocfg/ui-core';
|
|
7
|
+
import { cn } from '@djangocfg/ui-core/lib';
|
|
8
|
+
import * as React2 from 'react';
|
|
9
|
+
import { createContext, useState, useMemo, useCallback, useEffect, useContext } from 'react';
|
|
10
|
+
import useSWR2 from 'swr';
|
|
11
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
12
|
+
import moment2 from 'moment';
|
|
10
13
|
import { useForm } from 'react-hook-form';
|
|
11
14
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
12
|
-
import moment from 'moment';
|
|
13
|
-
import { useDRFPagination, StaticPagination } from '@djangocfg/ui-nextjs/components';
|
|
14
15
|
import { createExtensionConfig } from '@djangocfg/ext-base';
|
|
15
16
|
|
|
16
17
|
var __defProp = Object.defineProperty;
|
|
@@ -89,12 +90,12 @@ var ExtPaymentsPayments = class {
|
|
|
89
90
|
return response.results || response;
|
|
90
91
|
}
|
|
91
92
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
93
|
+
* Create payment
|
|
94
|
+
*
|
|
95
|
+
* Create a new payment with specified amount and currency
|
|
95
96
|
*/
|
|
96
|
-
async paymentsCreateCreate() {
|
|
97
|
-
const response = await this.client.request("POST", "/cfg/payments/payments/create/");
|
|
97
|
+
async paymentsCreateCreate(data) {
|
|
98
|
+
const response = await this.client.request("POST", "/cfg/payments/payments/create/", { body: data });
|
|
98
99
|
return response;
|
|
99
100
|
}
|
|
100
101
|
/**
|
|
@@ -113,6 +114,51 @@ var ExtPaymentsPayments = class {
|
|
|
113
114
|
const response = await this.client.request("GET", "/cfg/payments/transactions/", { params });
|
|
114
115
|
return response;
|
|
115
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* ViewSet for withdrawal operations. Endpoints: - GET /withdrawals/ - List
|
|
119
|
+
* user's withdrawal requests - GET /withdrawals/{id}/ - Get withdrawal
|
|
120
|
+
* details - POST /withdrawals/create/ - Create withdrawal request - POST
|
|
121
|
+
* /withdrawals/{id}/cancel/ - Cancel pending withdrawal
|
|
122
|
+
*/
|
|
123
|
+
async withdrawalsList(...args) {
|
|
124
|
+
const isParamsObject = args.length === 1 && typeof args[0] === "object" && args[0] !== null && !Array.isArray(args[0]);
|
|
125
|
+
let params;
|
|
126
|
+
if (isParamsObject) {
|
|
127
|
+
params = args[0];
|
|
128
|
+
} else {
|
|
129
|
+
params = { page: args[0], page_size: args[1] };
|
|
130
|
+
}
|
|
131
|
+
const response = await this.client.request("GET", "/cfg/payments/withdrawals/", { params });
|
|
132
|
+
return response;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* ViewSet for withdrawal operations. Endpoints: - GET /withdrawals/ - List
|
|
136
|
+
* user's withdrawal requests - GET /withdrawals/{id}/ - Get withdrawal
|
|
137
|
+
* details - POST /withdrawals/create/ - Create withdrawal request - POST
|
|
138
|
+
* /withdrawals/{id}/cancel/ - Cancel pending withdrawal
|
|
139
|
+
*/
|
|
140
|
+
async withdrawalsRetrieve(id) {
|
|
141
|
+
const response = await this.client.request("GET", `/cfg/payments/withdrawals/${id}/`);
|
|
142
|
+
return response;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Cancel withdrawal request
|
|
146
|
+
*
|
|
147
|
+
* Cancel a pending withdrawal request
|
|
148
|
+
*/
|
|
149
|
+
async withdrawalsCancelCreate(id) {
|
|
150
|
+
const response = await this.client.request("POST", `/cfg/payments/withdrawals/${id}/cancel/`);
|
|
151
|
+
return response;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Create withdrawal request
|
|
155
|
+
*
|
|
156
|
+
* Create a new withdrawal request (requires admin approval)
|
|
157
|
+
*/
|
|
158
|
+
async withdrawalsCreateCreate(data) {
|
|
159
|
+
const response = await this.client.request("POST", "/cfg/payments/withdrawals/create/", { body: data });
|
|
160
|
+
return response;
|
|
161
|
+
}
|
|
116
162
|
};
|
|
117
163
|
|
|
118
164
|
// src/api/generated/ext_payments/ext_payments__payments/models.ts
|
|
@@ -675,8 +721,8 @@ var APIClient = class {
|
|
|
675
721
|
// src/api/generated/ext_payments/storage.ts
|
|
676
722
|
var LocalStorageAdapter = class {
|
|
677
723
|
logger;
|
|
678
|
-
constructor(
|
|
679
|
-
this.logger =
|
|
724
|
+
constructor(logger) {
|
|
725
|
+
this.logger = logger;
|
|
680
726
|
}
|
|
681
727
|
getItem(key) {
|
|
682
728
|
try {
|
|
@@ -718,8 +764,8 @@ var LocalStorageAdapter = class {
|
|
|
718
764
|
};
|
|
719
765
|
var CookieStorageAdapter = class {
|
|
720
766
|
logger;
|
|
721
|
-
constructor(
|
|
722
|
-
this.logger =
|
|
767
|
+
constructor(logger) {
|
|
768
|
+
this.logger = logger;
|
|
723
769
|
}
|
|
724
770
|
getItem(key) {
|
|
725
771
|
try {
|
|
@@ -768,8 +814,8 @@ var CookieStorageAdapter = class {
|
|
|
768
814
|
var MemoryStorageAdapter = class {
|
|
769
815
|
storage = /* @__PURE__ */ new Map();
|
|
770
816
|
logger;
|
|
771
|
-
constructor(
|
|
772
|
-
this.logger =
|
|
817
|
+
constructor(logger) {
|
|
818
|
+
this.logger = logger;
|
|
773
819
|
}
|
|
774
820
|
getItem(key) {
|
|
775
821
|
const value = this.storage.get(key) || null;
|
|
@@ -791,7 +837,9 @@ var enums_exports = {};
|
|
|
791
837
|
__export(enums_exports, {
|
|
792
838
|
PaymentDetailStatus: () => PaymentDetailStatus,
|
|
793
839
|
PaymentListStatus: () => PaymentListStatus,
|
|
794
|
-
TransactionTransactionType: () => TransactionTransactionType
|
|
840
|
+
TransactionTransactionType: () => TransactionTransactionType,
|
|
841
|
+
WithdrawalDetailStatus: () => WithdrawalDetailStatus,
|
|
842
|
+
WithdrawalListStatus: () => WithdrawalListStatus
|
|
795
843
|
});
|
|
796
844
|
var PaymentDetailStatus = /* @__PURE__ */ ((PaymentDetailStatus2) => {
|
|
797
845
|
PaymentDetailStatus2["PENDING"] = "pending";
|
|
@@ -825,6 +873,24 @@ var TransactionTransactionType = /* @__PURE__ */ ((TransactionTransactionType2)
|
|
|
825
873
|
TransactionTransactionType2["ADJUSTMENT"] = "adjustment";
|
|
826
874
|
return TransactionTransactionType2;
|
|
827
875
|
})(TransactionTransactionType || {});
|
|
876
|
+
var WithdrawalDetailStatus = /* @__PURE__ */ ((WithdrawalDetailStatus2) => {
|
|
877
|
+
WithdrawalDetailStatus2["PENDING"] = "pending";
|
|
878
|
+
WithdrawalDetailStatus2["APPROVED"] = "approved";
|
|
879
|
+
WithdrawalDetailStatus2["PROCESSING"] = "processing";
|
|
880
|
+
WithdrawalDetailStatus2["COMPLETED"] = "completed";
|
|
881
|
+
WithdrawalDetailStatus2["REJECTED"] = "rejected";
|
|
882
|
+
WithdrawalDetailStatus2["CANCELLED"] = "cancelled";
|
|
883
|
+
return WithdrawalDetailStatus2;
|
|
884
|
+
})(WithdrawalDetailStatus || {});
|
|
885
|
+
var WithdrawalListStatus = /* @__PURE__ */ ((WithdrawalListStatus2) => {
|
|
886
|
+
WithdrawalListStatus2["PENDING"] = "pending";
|
|
887
|
+
WithdrawalListStatus2["APPROVED"] = "approved";
|
|
888
|
+
WithdrawalListStatus2["PROCESSING"] = "processing";
|
|
889
|
+
WithdrawalListStatus2["COMPLETED"] = "completed";
|
|
890
|
+
WithdrawalListStatus2["REJECTED"] = "rejected";
|
|
891
|
+
WithdrawalListStatus2["CANCELLED"] = "cancelled";
|
|
892
|
+
return WithdrawalListStatus2;
|
|
893
|
+
})(WithdrawalListStatus || {});
|
|
828
894
|
|
|
829
895
|
// src/api/generated/ext_payments/_utils/schemas/index.ts
|
|
830
896
|
var schemas_exports = {};
|
|
@@ -832,9 +898,14 @@ __export(schemas_exports, {
|
|
|
832
898
|
BalanceSchema: () => BalanceSchema,
|
|
833
899
|
CurrencySchema: () => CurrencySchema,
|
|
834
900
|
PaginatedPaymentListListSchema: () => PaginatedPaymentListListSchema,
|
|
901
|
+
PaginatedWithdrawalListListSchema: () => PaginatedWithdrawalListListSchema,
|
|
902
|
+
PaymentCreateRequestSchema: () => PaymentCreateRequestSchema,
|
|
835
903
|
PaymentDetailSchema: () => PaymentDetailSchema,
|
|
836
904
|
PaymentListSchema: () => PaymentListSchema,
|
|
837
|
-
TransactionSchema: () => TransactionSchema
|
|
905
|
+
TransactionSchema: () => TransactionSchema,
|
|
906
|
+
WithdrawalCreateRequestSchema: () => WithdrawalCreateRequestSchema,
|
|
907
|
+
WithdrawalDetailSchema: () => WithdrawalDetailSchema,
|
|
908
|
+
WithdrawalListSchema: () => WithdrawalListSchema
|
|
838
909
|
});
|
|
839
910
|
var BalanceSchema = z.object({
|
|
840
911
|
balance_usd: z.string(),
|
|
@@ -879,6 +950,36 @@ var PaginatedPaymentListListSchema = z.object({
|
|
|
879
950
|
previous_page: z.int().nullable().optional(),
|
|
880
951
|
results: z.array(PaymentListSchema)
|
|
881
952
|
});
|
|
953
|
+
var WithdrawalListSchema = z.object({
|
|
954
|
+
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),
|
|
955
|
+
internal_withdrawal_id: z.string(),
|
|
956
|
+
amount_usd: z.string(),
|
|
957
|
+
final_amount_usd: z.string(),
|
|
958
|
+
currency_code: z.string(),
|
|
959
|
+
currency_token: z.string(),
|
|
960
|
+
status: z.nativeEnum(WithdrawalListStatus),
|
|
961
|
+
status_display: z.string(),
|
|
962
|
+
created_at: z.iso.datetime(),
|
|
963
|
+
completed_at: z.iso.datetime().nullable()
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
// src/api/generated/ext_payments/_utils/schemas/PaginatedWithdrawalListList.schema.ts
|
|
967
|
+
var PaginatedWithdrawalListListSchema = z.object({
|
|
968
|
+
count: z.int(),
|
|
969
|
+
page: z.int(),
|
|
970
|
+
pages: z.int(),
|
|
971
|
+
page_size: z.int(),
|
|
972
|
+
has_next: z.boolean(),
|
|
973
|
+
has_previous: z.boolean(),
|
|
974
|
+
next_page: z.int().nullable().optional(),
|
|
975
|
+
previous_page: z.int().nullable().optional(),
|
|
976
|
+
results: z.array(WithdrawalListSchema)
|
|
977
|
+
});
|
|
978
|
+
var PaymentCreateRequestSchema = z.object({
|
|
979
|
+
amount_usd: z.string(),
|
|
980
|
+
currency_code: z.string().min(1).max(20),
|
|
981
|
+
description: z.string().max(500).optional()
|
|
982
|
+
});
|
|
882
983
|
var PaymentDetailSchema = z.object({
|
|
883
984
|
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),
|
|
884
985
|
internal_payment_id: z.string(),
|
|
@@ -917,6 +1018,36 @@ var TransactionSchema = z.object({
|
|
|
917
1018
|
description: z.string(),
|
|
918
1019
|
created_at: z.iso.datetime()
|
|
919
1020
|
});
|
|
1021
|
+
var WithdrawalCreateRequestSchema = z.object({
|
|
1022
|
+
amount_usd: z.string(),
|
|
1023
|
+
currency_code: z.string().min(1).max(20),
|
|
1024
|
+
wallet_address: z.string().min(1).max(255)
|
|
1025
|
+
});
|
|
1026
|
+
var WithdrawalDetailSchema = z.object({
|
|
1027
|
+
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),
|
|
1028
|
+
internal_withdrawal_id: z.string(),
|
|
1029
|
+
amount_usd: z.string(),
|
|
1030
|
+
currency_code: z.string(),
|
|
1031
|
+
currency_name: z.string(),
|
|
1032
|
+
currency_token: z.string(),
|
|
1033
|
+
currency_network: z.string(),
|
|
1034
|
+
wallet_address: z.string(),
|
|
1035
|
+
network_fee_usd: z.string(),
|
|
1036
|
+
service_fee_usd: z.string(),
|
|
1037
|
+
total_fee_usd: z.string(),
|
|
1038
|
+
final_amount_usd: z.string(),
|
|
1039
|
+
crypto_amount: z.string().nullable(),
|
|
1040
|
+
status: z.nativeEnum(WithdrawalDetailStatus),
|
|
1041
|
+
status_display: z.string(),
|
|
1042
|
+
transaction_hash: z.string().nullable(),
|
|
1043
|
+
explorer_link: z.string().nullable(),
|
|
1044
|
+
admin_notes: z.string(),
|
|
1045
|
+
created_at: z.iso.datetime(),
|
|
1046
|
+
approved_at: z.iso.datetime().nullable(),
|
|
1047
|
+
completed_at: z.iso.datetime().nullable(),
|
|
1048
|
+
rejected_at: z.iso.datetime().nullable(),
|
|
1049
|
+
cancelled_at: z.iso.datetime().nullable()
|
|
1050
|
+
});
|
|
920
1051
|
|
|
921
1052
|
// src/api/generated/ext_payments/validation-events.ts
|
|
922
1053
|
function dispatchValidationError(detail) {
|
|
@@ -969,12 +1100,16 @@ var fetchers_exports = {};
|
|
|
969
1100
|
__export(fetchers_exports, {
|
|
970
1101
|
createPaymentsPaymentsConfirmCreate: () => createPaymentsPaymentsConfirmCreate,
|
|
971
1102
|
createPaymentsPaymentsCreateCreate: () => createPaymentsPaymentsCreateCreate,
|
|
1103
|
+
createPaymentsWithdrawalsCancelCreate: () => createPaymentsWithdrawalsCancelCreate,
|
|
1104
|
+
createPaymentsWithdrawalsCreateCreate: () => createPaymentsWithdrawalsCreateCreate,
|
|
972
1105
|
getPaymentsBalanceRetrieve: () => getPaymentsBalanceRetrieve,
|
|
973
1106
|
getPaymentsCurrenciesList: () => getPaymentsCurrenciesList,
|
|
974
1107
|
getPaymentsPaymentsList: () => getPaymentsPaymentsList,
|
|
975
1108
|
getPaymentsPaymentsRetrieve: () => getPaymentsPaymentsRetrieve,
|
|
976
1109
|
getPaymentsPaymentsStatusRetrieve: () => getPaymentsPaymentsStatusRetrieve,
|
|
977
|
-
getPaymentsTransactionsList: () => getPaymentsTransactionsList
|
|
1110
|
+
getPaymentsTransactionsList: () => getPaymentsTransactionsList,
|
|
1111
|
+
getPaymentsWithdrawalsList: () => getPaymentsWithdrawalsList,
|
|
1112
|
+
getPaymentsWithdrawalsRetrieve: () => getPaymentsWithdrawalsRetrieve
|
|
978
1113
|
});
|
|
979
1114
|
|
|
980
1115
|
// src/api/generated/ext_payments/api-instance.ts
|
|
@@ -1247,11 +1382,11 @@ Method: GET`);
|
|
|
1247
1382
|
throw error;
|
|
1248
1383
|
}
|
|
1249
1384
|
}
|
|
1250
|
-
async function createPaymentsPaymentsCreateCreate(client) {
|
|
1385
|
+
async function createPaymentsPaymentsCreateCreate(data, client) {
|
|
1251
1386
|
const api = client || getAPIInstance();
|
|
1252
|
-
const response = await api.ext_payments_payments.paymentsCreateCreate();
|
|
1387
|
+
const response = await api.ext_payments_payments.paymentsCreateCreate(data);
|
|
1253
1388
|
try {
|
|
1254
|
-
return
|
|
1389
|
+
return PaymentDetailSchema.parse(response);
|
|
1255
1390
|
} catch (error) {
|
|
1256
1391
|
consola.error("\u274C Zod Validation Failed");
|
|
1257
1392
|
consola.box(`createPaymentsPaymentsCreateCreate
|
|
@@ -1294,6 +1429,174 @@ async function getPaymentsTransactionsList(params, client) {
|
|
|
1294
1429
|
const response = await api.ext_payments_payments.transactionsList(params?.limit, params?.offset, params?.type);
|
|
1295
1430
|
return response;
|
|
1296
1431
|
}
|
|
1432
|
+
async function getPaymentsWithdrawalsList(params, client) {
|
|
1433
|
+
const api = client || getAPIInstance();
|
|
1434
|
+
const response = await api.ext_payments_payments.withdrawalsList(params?.page, params?.page_size);
|
|
1435
|
+
try {
|
|
1436
|
+
return PaginatedWithdrawalListListSchema.parse(response);
|
|
1437
|
+
} catch (error) {
|
|
1438
|
+
consola.error("\u274C Zod Validation Failed");
|
|
1439
|
+
consola.box(`getPaymentsWithdrawalsList
|
|
1440
|
+
Path: /cfg/payments/withdrawals/
|
|
1441
|
+
Method: GET`);
|
|
1442
|
+
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1443
|
+
consola.error("Validation Issues:");
|
|
1444
|
+
error.issues.forEach((issue, index) => {
|
|
1445
|
+
consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1446
|
+
consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1447
|
+
if (issue.expected) consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1448
|
+
if (issue.received) consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
consola.error("Response data:", response);
|
|
1452
|
+
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1453
|
+
try {
|
|
1454
|
+
const event = new CustomEvent("zod-validation-error", {
|
|
1455
|
+
detail: {
|
|
1456
|
+
operation: "getPaymentsWithdrawalsList",
|
|
1457
|
+
path: "/cfg/payments/withdrawals/",
|
|
1458
|
+
method: "GET",
|
|
1459
|
+
error,
|
|
1460
|
+
response,
|
|
1461
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1462
|
+
},
|
|
1463
|
+
bubbles: true,
|
|
1464
|
+
cancelable: false
|
|
1465
|
+
});
|
|
1466
|
+
window.dispatchEvent(event);
|
|
1467
|
+
} catch (eventError) {
|
|
1468
|
+
consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
throw error;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
async function getPaymentsWithdrawalsRetrieve(id, client) {
|
|
1475
|
+
const api = client || getAPIInstance();
|
|
1476
|
+
const response = await api.ext_payments_payments.withdrawalsRetrieve(id);
|
|
1477
|
+
try {
|
|
1478
|
+
return WithdrawalDetailSchema.parse(response);
|
|
1479
|
+
} catch (error) {
|
|
1480
|
+
consola.error("\u274C Zod Validation Failed");
|
|
1481
|
+
consola.box(`getPaymentsWithdrawalsRetrieve
|
|
1482
|
+
Path: /cfg/payments/withdrawals/{id}/
|
|
1483
|
+
Method: GET`);
|
|
1484
|
+
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1485
|
+
consola.error("Validation Issues:");
|
|
1486
|
+
error.issues.forEach((issue, index) => {
|
|
1487
|
+
consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1488
|
+
consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1489
|
+
if (issue.expected) consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1490
|
+
if (issue.received) consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
consola.error("Response data:", response);
|
|
1494
|
+
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1495
|
+
try {
|
|
1496
|
+
const event = new CustomEvent("zod-validation-error", {
|
|
1497
|
+
detail: {
|
|
1498
|
+
operation: "getPaymentsWithdrawalsRetrieve",
|
|
1499
|
+
path: "/cfg/payments/withdrawals/{id}/",
|
|
1500
|
+
method: "GET",
|
|
1501
|
+
error,
|
|
1502
|
+
response,
|
|
1503
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1504
|
+
},
|
|
1505
|
+
bubbles: true,
|
|
1506
|
+
cancelable: false
|
|
1507
|
+
});
|
|
1508
|
+
window.dispatchEvent(event);
|
|
1509
|
+
} catch (eventError) {
|
|
1510
|
+
consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
throw error;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
async function createPaymentsWithdrawalsCancelCreate(id, client) {
|
|
1517
|
+
const api = client || getAPIInstance();
|
|
1518
|
+
const response = await api.ext_payments_payments.withdrawalsCancelCreate(id);
|
|
1519
|
+
try {
|
|
1520
|
+
return WithdrawalDetailSchema.parse(response);
|
|
1521
|
+
} catch (error) {
|
|
1522
|
+
consola.error("\u274C Zod Validation Failed");
|
|
1523
|
+
consola.box(`createPaymentsWithdrawalsCancelCreate
|
|
1524
|
+
Path: /cfg/payments/withdrawals/{id}/cancel/
|
|
1525
|
+
Method: POST`);
|
|
1526
|
+
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1527
|
+
consola.error("Validation Issues:");
|
|
1528
|
+
error.issues.forEach((issue, index) => {
|
|
1529
|
+
consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1530
|
+
consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1531
|
+
if (issue.expected) consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1532
|
+
if (issue.received) consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
consola.error("Response data:", response);
|
|
1536
|
+
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1537
|
+
try {
|
|
1538
|
+
const event = new CustomEvent("zod-validation-error", {
|
|
1539
|
+
detail: {
|
|
1540
|
+
operation: "createPaymentsWithdrawalsCancelCreate",
|
|
1541
|
+
path: "/cfg/payments/withdrawals/{id}/cancel/",
|
|
1542
|
+
method: "POST",
|
|
1543
|
+
error,
|
|
1544
|
+
response,
|
|
1545
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1546
|
+
},
|
|
1547
|
+
bubbles: true,
|
|
1548
|
+
cancelable: false
|
|
1549
|
+
});
|
|
1550
|
+
window.dispatchEvent(event);
|
|
1551
|
+
} catch (eventError) {
|
|
1552
|
+
consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
throw error;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
async function createPaymentsWithdrawalsCreateCreate(data, client) {
|
|
1559
|
+
const api = client || getAPIInstance();
|
|
1560
|
+
const response = await api.ext_payments_payments.withdrawalsCreateCreate(data);
|
|
1561
|
+
try {
|
|
1562
|
+
return WithdrawalDetailSchema.parse(response);
|
|
1563
|
+
} catch (error) {
|
|
1564
|
+
consola.error("\u274C Zod Validation Failed");
|
|
1565
|
+
consola.box(`createPaymentsWithdrawalsCreateCreate
|
|
1566
|
+
Path: /cfg/payments/withdrawals/create/
|
|
1567
|
+
Method: POST`);
|
|
1568
|
+
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1569
|
+
consola.error("Validation Issues:");
|
|
1570
|
+
error.issues.forEach((issue, index) => {
|
|
1571
|
+
consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1572
|
+
consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1573
|
+
if (issue.expected) consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1574
|
+
if (issue.received) consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
consola.error("Response data:", response);
|
|
1578
|
+
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1579
|
+
try {
|
|
1580
|
+
const event = new CustomEvent("zod-validation-error", {
|
|
1581
|
+
detail: {
|
|
1582
|
+
operation: "createPaymentsWithdrawalsCreateCreate",
|
|
1583
|
+
path: "/cfg/payments/withdrawals/create/",
|
|
1584
|
+
method: "POST",
|
|
1585
|
+
error,
|
|
1586
|
+
response,
|
|
1587
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1588
|
+
},
|
|
1589
|
+
bubbles: true,
|
|
1590
|
+
cancelable: false
|
|
1591
|
+
});
|
|
1592
|
+
window.dispatchEvent(event);
|
|
1593
|
+
} catch (eventError) {
|
|
1594
|
+
consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
throw error;
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1297
1600
|
|
|
1298
1601
|
// src/api/generated/ext_payments/index.ts
|
|
1299
1602
|
var TOKEN_KEY = "auth_token";
|
|
@@ -1310,8 +1613,8 @@ var API = class {
|
|
|
1310
1613
|
constructor(baseUrl, options) {
|
|
1311
1614
|
this.baseUrl = baseUrl;
|
|
1312
1615
|
this.options = options;
|
|
1313
|
-
const
|
|
1314
|
-
this.storage = options?.storage || new LocalStorageAdapter(
|
|
1616
|
+
const logger = options?.loggerConfig ? new APILogger(options.loggerConfig) : void 0;
|
|
1617
|
+
this.storage = options?.storage || new LocalStorageAdapter(logger);
|
|
1315
1618
|
this._loadTokensFromStorage();
|
|
1316
1619
|
this._client = new APIClient(this.baseUrl, {
|
|
1317
1620
|
retryConfig: this.options?.retryConfig,
|
|
@@ -1422,333 +1725,296 @@ var API = class {
|
|
|
1422
1725
|
};
|
|
1423
1726
|
initializeExtensionAPI(configureAPI);
|
|
1424
1727
|
var apiPayments = createExtensionAPI(API);
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
() => getPaymentsBalanceRetrieve(client)
|
|
1429
|
-
);
|
|
1430
|
-
}
|
|
1431
|
-
function usePaymentsCurrenciesList(client) {
|
|
1432
|
-
return useSWR(
|
|
1433
|
-
"cfg-payments-currencies",
|
|
1434
|
-
() => getPaymentsCurrenciesList(client)
|
|
1435
|
-
);
|
|
1436
|
-
}
|
|
1437
|
-
function usePaymentsPaymentsList(params, client) {
|
|
1438
|
-
return useSWR(
|
|
1439
|
-
params ? ["cfg-payments-payments", params] : "cfg-payments-payments",
|
|
1440
|
-
() => getPaymentsPaymentsList(params, client)
|
|
1441
|
-
);
|
|
1442
|
-
}
|
|
1443
|
-
function usePaymentsPaymentsRetrieve(id, client) {
|
|
1444
|
-
return useSWR(
|
|
1445
|
-
["cfg-payments-payment", id],
|
|
1446
|
-
() => getPaymentsPaymentsRetrieve(id, client)
|
|
1447
|
-
);
|
|
1448
|
-
}
|
|
1449
|
-
function useCreatePaymentsPaymentsConfirmCreate() {
|
|
1450
|
-
const { mutate } = useSWRConfig();
|
|
1451
|
-
return async (id, client) => {
|
|
1452
|
-
const result = await createPaymentsPaymentsConfirmCreate(id, client);
|
|
1453
|
-
mutate("cfg-payments-payments-confirm");
|
|
1454
|
-
return result;
|
|
1455
|
-
};
|
|
1456
|
-
}
|
|
1457
|
-
function useCreatePaymentsPaymentsCreateCreate() {
|
|
1458
|
-
const { mutate } = useSWRConfig();
|
|
1459
|
-
return async (client) => {
|
|
1460
|
-
const result = await createPaymentsPaymentsCreateCreate(client);
|
|
1461
|
-
mutate("cfg-payments-payments");
|
|
1462
|
-
return result;
|
|
1463
|
-
};
|
|
1464
|
-
}
|
|
1465
|
-
function usePaymentsTransactionsList(params, client) {
|
|
1466
|
-
return useSWR(
|
|
1467
|
-
params ? ["cfg-payments-transactions", params] : "cfg-payments-transactions",
|
|
1468
|
-
() => getPaymentsTransactionsList(params, client)
|
|
1469
|
-
);
|
|
1470
|
-
}
|
|
1471
|
-
var PaymentsContext = createContext(void 0);
|
|
1472
|
-
function PaymentsProvider({ children }) {
|
|
1473
|
-
const {
|
|
1474
|
-
data: payments,
|
|
1475
|
-
error: paymentsError,
|
|
1476
|
-
isLoading: isLoadingPayments,
|
|
1477
|
-
mutate: mutatePayments
|
|
1478
|
-
} = usePaymentsPaymentsList({ page: 1, page_size: 1 }, apiPayments);
|
|
1479
|
-
const refreshPayments = async () => {
|
|
1480
|
-
await mutatePayments();
|
|
1481
|
-
};
|
|
1482
|
-
const createPaymentMutation = useCreatePaymentsPaymentsCreateCreate();
|
|
1483
|
-
const confirmPaymentMutation = useCreatePaymentsPaymentsConfirmCreate();
|
|
1484
|
-
const getPayment = async (id) => {
|
|
1485
|
-
return getPaymentsPaymentsRetrieve(id, apiPayments);
|
|
1486
|
-
};
|
|
1487
|
-
const createPayment = async () => {
|
|
1488
|
-
const result = await createPaymentMutation(apiPayments);
|
|
1489
|
-
await refreshPayments();
|
|
1490
|
-
return result;
|
|
1491
|
-
};
|
|
1492
|
-
const confirmPayment = async (id) => {
|
|
1493
|
-
const result = await confirmPaymentMutation(id, apiPayments);
|
|
1494
|
-
await refreshPayments();
|
|
1495
|
-
return result;
|
|
1496
|
-
};
|
|
1497
|
-
const checkPaymentStatus = async (id) => {
|
|
1498
|
-
return getPaymentsPaymentsStatusRetrieve(id, apiPayments);
|
|
1499
|
-
};
|
|
1500
|
-
const value = {
|
|
1501
|
-
payments,
|
|
1502
|
-
isLoadingPayments,
|
|
1503
|
-
paymentsError,
|
|
1504
|
-
refreshPayments,
|
|
1505
|
-
getPayment,
|
|
1506
|
-
createPayment,
|
|
1507
|
-
confirmPayment,
|
|
1508
|
-
checkPaymentStatus
|
|
1509
|
-
};
|
|
1510
|
-
return /* @__PURE__ */ jsx(PaymentsContext.Provider, { value, children });
|
|
1511
|
-
}
|
|
1512
|
-
function usePaymentsContext() {
|
|
1513
|
-
const context = useContext(PaymentsContext);
|
|
1728
|
+
var WalletContext = createContext(void 0);
|
|
1729
|
+
function useWallet() {
|
|
1730
|
+
const context = useContext(WalletContext);
|
|
1514
1731
|
if (!context) {
|
|
1515
|
-
throw new Error("
|
|
1732
|
+
throw new Error("useWallet must be used within WalletProvider");
|
|
1516
1733
|
}
|
|
1517
1734
|
return context;
|
|
1518
1735
|
}
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
isLoadingBalance,
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1736
|
+
function BalanceHero({ onAddFunds, onWithdraw, className }) {
|
|
1737
|
+
const { balance, balanceAmount, isLoadingBalance, refreshWallet } = useWallet();
|
|
1738
|
+
const formattedBalance = new Intl.NumberFormat("en-US", {
|
|
1739
|
+
style: "currency",
|
|
1740
|
+
currency: "USD",
|
|
1741
|
+
minimumFractionDigits: 2,
|
|
1742
|
+
maximumFractionDigits: 2
|
|
1743
|
+
}).format(balanceAmount);
|
|
1744
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center py-16 px-4", className), children: [
|
|
1745
|
+
/* @__PURE__ */ jsx("div", { className: "text-center mb-6", children: isLoadingBalance ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1746
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-48 mx-auto mb-2" }),
|
|
1747
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24 mx-auto" })
|
|
1748
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1749
|
+
/* @__PURE__ */ jsx("h1", { className: "text-5xl font-bold tracking-tight tabular-nums", children: formattedBalance }),
|
|
1750
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1", children: "Available Balance" })
|
|
1751
|
+
] }) }),
|
|
1752
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1753
|
+
/* @__PURE__ */ jsxs(
|
|
1754
|
+
Button,
|
|
1755
|
+
{
|
|
1756
|
+
size: "lg",
|
|
1757
|
+
onClick: onAddFunds,
|
|
1758
|
+
className: "rounded-full px-6",
|
|
1759
|
+
children: [
|
|
1760
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-5 w-5 mr-2" }),
|
|
1761
|
+
"Add Funds"
|
|
1762
|
+
]
|
|
1763
|
+
}
|
|
1764
|
+
),
|
|
1765
|
+
/* @__PURE__ */ jsxs(
|
|
1766
|
+
Button,
|
|
1767
|
+
{
|
|
1768
|
+
size: "lg",
|
|
1769
|
+
variant: "outline",
|
|
1770
|
+
onClick: onWithdraw,
|
|
1771
|
+
className: "rounded-full px-6",
|
|
1772
|
+
children: [
|
|
1773
|
+
/* @__PURE__ */ jsx(ArrowUpRight, { className: "h-5 w-5 mr-2" }),
|
|
1774
|
+
"Withdraw"
|
|
1775
|
+
]
|
|
1776
|
+
}
|
|
1777
|
+
),
|
|
1778
|
+
/* @__PURE__ */ jsx(
|
|
1779
|
+
Button,
|
|
1780
|
+
{
|
|
1781
|
+
size: "icon",
|
|
1782
|
+
variant: "ghost",
|
|
1783
|
+
onClick: () => refreshWallet(),
|
|
1784
|
+
className: "rounded-full",
|
|
1785
|
+
children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" })
|
|
1786
|
+
}
|
|
1787
|
+
)
|
|
1788
|
+
] }),
|
|
1789
|
+
balance && !isLoadingBalance && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-6 mt-6 text-sm text-muted-foreground", children: [
|
|
1790
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1791
|
+
/* @__PURE__ */ jsxs("span", { className: "block font-medium text-foreground", children: [
|
|
1792
|
+
"$",
|
|
1793
|
+
parseFloat(balance.total_deposited || "0").toFixed(2)
|
|
1794
|
+
] }),
|
|
1795
|
+
/* @__PURE__ */ jsx("span", { children: "Total Deposited" })
|
|
1796
|
+
] }),
|
|
1797
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 w-px bg-border" }),
|
|
1798
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1799
|
+
/* @__PURE__ */ jsxs("span", { className: "block font-medium text-foreground", children: [
|
|
1800
|
+
"$",
|
|
1801
|
+
parseFloat(balance.total_withdrawn || "0").toFixed(2)
|
|
1802
|
+
] }),
|
|
1803
|
+
/* @__PURE__ */ jsx("span", { children: "Total Withdrawn" })
|
|
1804
|
+
] })
|
|
1805
|
+
] })
|
|
1806
|
+
] });
|
|
1589
1807
|
}
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1808
|
+
var statusConfig = {
|
|
1809
|
+
pending: {
|
|
1810
|
+
icon: Clock,
|
|
1811
|
+
color: "text-yellow-500",
|
|
1812
|
+
bg: "bg-yellow-500/10"
|
|
1813
|
+
},
|
|
1814
|
+
confirming: {
|
|
1815
|
+
icon: Loader2,
|
|
1816
|
+
color: "text-blue-500",
|
|
1817
|
+
bg: "bg-blue-500/10",
|
|
1818
|
+
animate: true
|
|
1819
|
+
},
|
|
1820
|
+
completed: {
|
|
1821
|
+
icon: CheckCircle2,
|
|
1822
|
+
color: "text-green-500",
|
|
1823
|
+
bg: "bg-green-500/10"
|
|
1824
|
+
},
|
|
1825
|
+
failed: {
|
|
1826
|
+
icon: XCircle,
|
|
1827
|
+
color: "text-red-500",
|
|
1828
|
+
bg: "bg-red-500/10"
|
|
1829
|
+
},
|
|
1830
|
+
expired: {
|
|
1831
|
+
icon: AlertCircle,
|
|
1832
|
+
color: "text-muted-foreground",
|
|
1833
|
+
bg: "bg-muted"
|
|
1594
1834
|
}
|
|
1595
|
-
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
const
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1835
|
+
};
|
|
1836
|
+
function ActivityItem({ item, onClick }) {
|
|
1837
|
+
const config = statusConfig[item.status];
|
|
1838
|
+
const StatusIcon = config.icon;
|
|
1839
|
+
const isPositive = item.type === "payment" || item.type === "deposit";
|
|
1840
|
+
const DirectionIcon = isPositive ? ArrowDownLeft : ArrowUpRight;
|
|
1841
|
+
const relativeTime = moment2(item.createdAt).fromNow();
|
|
1842
|
+
return /* @__PURE__ */ jsxs(
|
|
1843
|
+
"button",
|
|
1844
|
+
{
|
|
1845
|
+
onClick,
|
|
1846
|
+
className: cn(
|
|
1847
|
+
"w-full flex items-center gap-4 p-4 rounded-xl",
|
|
1848
|
+
"cursor-pointer",
|
|
1849
|
+
"hover:bg-accent active:bg-accent/80 transition-colors",
|
|
1850
|
+
"text-left"
|
|
1851
|
+
),
|
|
1852
|
+
children: [
|
|
1853
|
+
/* @__PURE__ */ jsx("div", { className: cn(
|
|
1854
|
+
"flex items-center justify-center w-10 h-10 rounded-full",
|
|
1855
|
+
isPositive ? "bg-green-500/10" : "bg-red-500/10"
|
|
1856
|
+
), children: item.currency ? /* @__PURE__ */ jsx(TokenIcon, { symbol: item.currency, size: 24 }) : /* @__PURE__ */ jsx(DirectionIcon, { className: cn(
|
|
1857
|
+
"h-5 w-5",
|
|
1858
|
+
isPositive ? "text-green-500" : "text-red-500"
|
|
1859
|
+
) }) }),
|
|
1860
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
1861
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx("span", { className: "font-medium truncate", children: item.description }) }),
|
|
1862
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
1863
|
+
/* @__PURE__ */ jsx("span", { children: relativeTime }),
|
|
1864
|
+
item.status !== "completed" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1865
|
+
/* @__PURE__ */ jsx("span", { children: "\xB7" }),
|
|
1866
|
+
/* @__PURE__ */ jsxs("span", { className: cn("flex items-center gap-1", config.color), children: [
|
|
1867
|
+
/* @__PURE__ */ jsx(StatusIcon, { className: cn("h-3 w-3", config.animate && "animate-spin") }),
|
|
1868
|
+
item.statusDisplay
|
|
1869
|
+
] })
|
|
1870
|
+
] })
|
|
1871
|
+
] })
|
|
1872
|
+
] }),
|
|
1873
|
+
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
1874
|
+
/* @__PURE__ */ jsx("span", { className: cn(
|
|
1875
|
+
"font-semibold tabular-nums",
|
|
1876
|
+
isPositive ? "text-green-600 dark:text-green-400" : "text-foreground"
|
|
1877
|
+
), children: item.amountDisplay }),
|
|
1878
|
+
item.status === "completed" && /* @__PURE__ */ jsx(CheckCircle2, { className: "h-4 w-4 text-green-500 ml-2 inline-block" })
|
|
1879
|
+
] })
|
|
1880
|
+
]
|
|
1881
|
+
}
|
|
1882
|
+
);
|
|
1615
1883
|
}
|
|
1616
|
-
function
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1884
|
+
function ActivityList({
|
|
1885
|
+
onItemClick,
|
|
1886
|
+
onViewAll,
|
|
1887
|
+
limit = 10,
|
|
1888
|
+
className
|
|
1889
|
+
}) {
|
|
1890
|
+
const { activity, isLoadingActivity, hasMoreActivity } = useWallet();
|
|
1891
|
+
const displayedActivity = limit ? activity.slice(0, limit) : activity;
|
|
1892
|
+
if (isLoadingActivity) {
|
|
1893
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
|
|
1894
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-between px-4 py-2", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-32" }) }),
|
|
1895
|
+
[1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 p-4", children: [
|
|
1896
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-10 rounded-full" }),
|
|
1897
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
|
|
1898
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-32" }),
|
|
1899
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" })
|
|
1900
|
+
] }),
|
|
1901
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-16" })
|
|
1902
|
+
] }, i))
|
|
1903
|
+
] });
|
|
1620
1904
|
}
|
|
1621
|
-
|
|
1905
|
+
if (activity.length === 0) {
|
|
1906
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("text-center py-12", className), children: [
|
|
1907
|
+
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center justify-center w-16 h-16 rounded-full bg-muted mb-4", children: /* @__PURE__ */ jsx(History, { className: "h-8 w-8 text-muted-foreground" }) }),
|
|
1908
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold mb-1", children: "No Activity Yet" }),
|
|
1909
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Your transactions will appear here" })
|
|
1910
|
+
] });
|
|
1911
|
+
}
|
|
1912
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("pt-6", className), children: [
|
|
1913
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-2", children: [
|
|
1914
|
+
/* @__PURE__ */ jsx("h2", { className: "font-semibold text-lg", children: "Recent Activity" }),
|
|
1915
|
+
hasMoreActivity && onViewAll && /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: onViewAll, className: "text-primary", children: [
|
|
1916
|
+
"View All",
|
|
1917
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 ml-1" })
|
|
1918
|
+
] })
|
|
1919
|
+
] }),
|
|
1920
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-border/50", children: displayedActivity.map((item) => /* @__PURE__ */ jsx(
|
|
1921
|
+
ActivityItem,
|
|
1922
|
+
{
|
|
1923
|
+
item,
|
|
1924
|
+
onClick: () => onItemClick?.(item)
|
|
1925
|
+
},
|
|
1926
|
+
item.id
|
|
1927
|
+
)) })
|
|
1928
|
+
] });
|
|
1622
1929
|
}
|
|
1623
|
-
var
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
}).withTag("ext-payments");
|
|
1627
|
-
var paymentsLogger = logger;
|
|
1628
|
-
|
|
1629
|
-
// src/layouts/PaymentsLayout/events.ts
|
|
1630
|
-
var PAYMENT_EVENTS = {
|
|
1631
|
-
OPEN_CREATE_PAYMENT_DIALOG: "payments:open-create-payment",
|
|
1632
|
-
OPEN_PAYMENT_DETAILS_DIALOG: "payments:open-payment-details",
|
|
1633
|
-
CLOSE_DIALOG: "payments:close-dialog"
|
|
1634
|
-
};
|
|
1635
|
-
var openCreatePaymentDialog = () => {
|
|
1636
|
-
window.dispatchEvent(new Event(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG));
|
|
1637
|
-
};
|
|
1638
|
-
var openPaymentDetailsDialog = (id) => {
|
|
1639
|
-
window.dispatchEvent(
|
|
1640
|
-
new CustomEvent(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, {
|
|
1641
|
-
detail: { id }
|
|
1642
|
-
})
|
|
1643
|
-
);
|
|
1644
|
-
};
|
|
1645
|
-
var closePaymentsDialog = () => {
|
|
1646
|
-
window.dispatchEvent(new Event(PAYMENT_EVENTS.CLOSE_DIALOG));
|
|
1647
|
-
};
|
|
1648
|
-
var PaymentCreateSchema = z.object({
|
|
1649
|
-
amount_usd: z.number().min(0.01, "Amount must be at least $0.01"),
|
|
1650
|
-
currency_code: z.string().min(1, "Please select a currency")
|
|
1930
|
+
var AddFundsSchema = z.object({
|
|
1931
|
+
amount: z.number().min(1, "Minimum $1.00"),
|
|
1932
|
+
currency: z.string().min(1, "Select a currency")
|
|
1651
1933
|
});
|
|
1652
|
-
|
|
1653
|
-
const
|
|
1934
|
+
function AddFundsSheet({ open, onOpenChange, onSuccess }) {
|
|
1935
|
+
const { currencies, isLoadingCurrencies, addFunds } = useWallet();
|
|
1654
1936
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
1655
|
-
const
|
|
1656
|
-
const { currencies, isLoadingCurrencies } = useRootPaymentsContext();
|
|
1937
|
+
const [error, setError] = useState(null);
|
|
1657
1938
|
const form = useForm({
|
|
1658
|
-
resolver: zodResolver(
|
|
1939
|
+
resolver: zodResolver(AddFundsSchema),
|
|
1659
1940
|
defaultValues: {
|
|
1660
|
-
|
|
1661
|
-
|
|
1941
|
+
amount: 100,
|
|
1942
|
+
currency: ""
|
|
1662
1943
|
}
|
|
1663
1944
|
});
|
|
1664
|
-
const currenciesList = useMemo(() => {
|
|
1665
|
-
const data = currencies?.currencies || currencies?.results || currencies || [];
|
|
1666
|
-
return Array.isArray(data) ? data : [];
|
|
1667
|
-
}, [currencies]);
|
|
1668
1945
|
const currencyOptions = useMemo(() => {
|
|
1669
|
-
return
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
network:
|
|
1946
|
+
return currencies.map((c) => ({
|
|
1947
|
+
value: c.code,
|
|
1948
|
+
label: c.network ? `${c.code} (${c.network})` : c.code,
|
|
1949
|
+
rate: c.rate,
|
|
1950
|
+
network: c.network
|
|
1674
1951
|
}));
|
|
1675
|
-
}, [
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
if (!currency || !currency.usd_rate || !amountUsd) {
|
|
1681
|
-
return null;
|
|
1682
|
-
}
|
|
1683
|
-
const cryptoAmount = amountUsd / currency.usd_rate;
|
|
1684
|
-
return {
|
|
1685
|
-
amount: cryptoAmount,
|
|
1686
|
-
currency: currency.code,
|
|
1687
|
-
rate: currency.usd_rate,
|
|
1688
|
-
network: currency.network
|
|
1689
|
-
};
|
|
1690
|
-
}, [form.watch("amount_usd"), form.watch("currency_code"), currencyOptions]);
|
|
1691
|
-
useEffect(() => {
|
|
1692
|
-
const handleOpen = () => setOpen(true);
|
|
1693
|
-
const handleClose2 = () => setOpen(false);
|
|
1694
|
-
window.addEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
|
|
1695
|
-
window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1696
|
-
return () => {
|
|
1697
|
-
window.removeEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
|
|
1698
|
-
window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1699
|
-
};
|
|
1700
|
-
}, []);
|
|
1701
|
-
const handleClose = () => {
|
|
1702
|
-
setOpen(false);
|
|
1703
|
-
form.reset();
|
|
1704
|
-
};
|
|
1705
|
-
useEffect(() => {
|
|
1706
|
-
if (currencyOptions.length > 0 && !form.getValues("currency_code")) {
|
|
1707
|
-
form.setValue("currency_code", currencyOptions[0].code);
|
|
1952
|
+
}, [currencies]);
|
|
1953
|
+
useMemo(() => {
|
|
1954
|
+
if (currencyOptions.length > 0 && !form.getValues("currency")) {
|
|
1955
|
+
const usdt = currencyOptions.find((c) => c.value.includes("USDT"));
|
|
1956
|
+
form.setValue("currency", usdt?.value || currencyOptions[0].value);
|
|
1708
1957
|
}
|
|
1709
1958
|
}, [currencyOptions, form]);
|
|
1710
|
-
const
|
|
1959
|
+
const selectedCurrency = currencyOptions.find((c) => c.value === form.watch("currency"));
|
|
1960
|
+
const cryptoAmount = useMemo(() => {
|
|
1961
|
+
const amount = form.watch("amount");
|
|
1962
|
+
if (!selectedCurrency?.rate || !amount) return null;
|
|
1963
|
+
return amount / selectedCurrency.rate;
|
|
1964
|
+
}, [form.watch("amount"), selectedCurrency]);
|
|
1965
|
+
const handleSubmit = useCallback(async (data) => {
|
|
1711
1966
|
try {
|
|
1712
1967
|
setIsSubmitting(true);
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
} catch (
|
|
1722
|
-
|
|
1968
|
+
setError(null);
|
|
1969
|
+
const result = await addFunds({
|
|
1970
|
+
amount_usd: String(data.amount),
|
|
1971
|
+
currency_code: data.currency
|
|
1972
|
+
});
|
|
1973
|
+
form.reset();
|
|
1974
|
+
onOpenChange(false);
|
|
1975
|
+
onSuccess?.(result);
|
|
1976
|
+
} catch (err) {
|
|
1977
|
+
const message = err?.response?.data?.message || err?.response?.data?.detail || err?.message || "Failed to create payment";
|
|
1978
|
+
setError(message);
|
|
1723
1979
|
} finally {
|
|
1724
1980
|
setIsSubmitting(false);
|
|
1725
1981
|
}
|
|
1726
|
-
};
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1982
|
+
}, [addFunds, form, onOpenChange, onSuccess]);
|
|
1983
|
+
const handleOpenChange = useCallback((open2) => {
|
|
1984
|
+
if (!open2) {
|
|
1985
|
+
setError(null);
|
|
1986
|
+
form.reset();
|
|
1987
|
+
}
|
|
1988
|
+
onOpenChange(open2);
|
|
1989
|
+
}, [form, onOpenChange]);
|
|
1990
|
+
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-md", children: [
|
|
1991
|
+
/* @__PURE__ */ jsxs(ResponsiveSheetHeader, { children: [
|
|
1992
|
+
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { children: "Add Funds" }),
|
|
1993
|
+
/* @__PURE__ */ jsx(ResponsiveSheetDescription, { children: "Add funds to your wallet using cryptocurrency" })
|
|
1731
1994
|
] }),
|
|
1732
|
-
/* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { onSubmit: form.handleSubmit(handleSubmit), className: "space-y-4", children: [
|
|
1995
|
+
/* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { onSubmit: form.handleSubmit(handleSubmit), className: "space-y-6 p-4 sm:p-0 sm:mt-4", children: [
|
|
1733
1996
|
/* @__PURE__ */ jsx(
|
|
1734
1997
|
FormField,
|
|
1735
1998
|
{
|
|
1736
1999
|
control: form.control,
|
|
1737
|
-
name: "
|
|
2000
|
+
name: "amount",
|
|
1738
2001
|
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
1739
2002
|
/* @__PURE__ */ jsx(FormLabel, { children: "Amount (USD)" }),
|
|
1740
|
-
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
2003
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
2004
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-muted-foreground text-lg", children: "$" }),
|
|
2005
|
+
/* @__PURE__ */ jsx(
|
|
2006
|
+
Input,
|
|
2007
|
+
{
|
|
2008
|
+
type: "number",
|
|
2009
|
+
step: "0.01",
|
|
2010
|
+
min: "1",
|
|
2011
|
+
placeholder: "100.00",
|
|
2012
|
+
className: "pl-8 text-2xl h-14 font-semibold",
|
|
2013
|
+
...field,
|
|
2014
|
+
onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
|
|
2015
|
+
}
|
|
2016
|
+
)
|
|
2017
|
+
] }) }),
|
|
1752
2018
|
/* @__PURE__ */ jsx(FormMessage, {})
|
|
1753
2019
|
] })
|
|
1754
2020
|
}
|
|
@@ -1757,122 +2023,344 @@ var CreatePaymentDialog = () => {
|
|
|
1757
2023
|
FormField,
|
|
1758
2024
|
{
|
|
1759
2025
|
control: form.control,
|
|
1760
|
-
name: "
|
|
2026
|
+
name: "currency",
|
|
1761
2027
|
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
1762
|
-
/* @__PURE__ */ jsx(FormLabel, { children: "
|
|
1763
|
-
/* @__PURE__ */
|
|
1764
|
-
|
|
2028
|
+
/* @__PURE__ */ jsx(FormLabel, { children: "Pay with" }),
|
|
2029
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
|
|
2030
|
+
Combobox,
|
|
1765
2031
|
{
|
|
2032
|
+
options: currencyOptions,
|
|
2033
|
+
value: field.value,
|
|
1766
2034
|
onValueChange: field.onChange,
|
|
1767
|
-
|
|
2035
|
+
placeholder: "Select currency...",
|
|
2036
|
+
searchPlaceholder: "Search...",
|
|
1768
2037
|
disabled: isLoadingCurrencies,
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
/* @__PURE__ */ jsx(
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
] })
|
|
1779
|
-
] }) }, curr.code)) })
|
|
1780
|
-
]
|
|
2038
|
+
className: "h-14",
|
|
2039
|
+
renderOption: (option) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1", children: [
|
|
2040
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2041
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2042
|
+
] }),
|
|
2043
|
+
renderValue: (option) => option && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2044
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2045
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2046
|
+
] })
|
|
1781
2047
|
}
|
|
1782
|
-
),
|
|
1783
|
-
/* @__PURE__ */ jsx(FormDescription, { children: "The cryptocurrency to use for payment." }),
|
|
2048
|
+
) }),
|
|
1784
2049
|
/* @__PURE__ */ jsx(FormMessage, {})
|
|
1785
2050
|
] })
|
|
1786
2051
|
}
|
|
1787
2052
|
),
|
|
1788
|
-
|
|
2053
|
+
cryptoAmount !== null && selectedCurrency && /* @__PURE__ */ jsxs("div", { className: "bg-muted rounded-xl p-4 space-y-2", children: [
|
|
1789
2054
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1790
|
-
/* @__PURE__ */ jsx("span", { className: "text-
|
|
2055
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "You will send" }),
|
|
1791
2056
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1792
|
-
/* @__PURE__ */ jsx(TokenIcon, { symbol:
|
|
2057
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: selectedCurrency.value, size: 20 }),
|
|
1793
2058
|
/* @__PURE__ */ jsxs("span", { className: "font-mono font-semibold", children: [
|
|
1794
|
-
|
|
2059
|
+
cryptoAmount.toFixed(8),
|
|
1795
2060
|
" ",
|
|
1796
|
-
|
|
2061
|
+
selectedCurrency.value
|
|
1797
2062
|
] })
|
|
1798
2063
|
] })
|
|
1799
2064
|
] }),
|
|
1800
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1801
|
-
/* @__PURE__ */ jsx("span", {
|
|
1802
|
-
/* @__PURE__ */ jsxs("span", {
|
|
2065
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm text-muted-foreground", children: [
|
|
2066
|
+
/* @__PURE__ */ jsx("span", { children: "Rate" }),
|
|
2067
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
2068
|
+
"1 ",
|
|
2069
|
+
selectedCurrency.value,
|
|
2070
|
+
" = $",
|
|
2071
|
+
selectedCurrency.rate.toFixed(2)
|
|
2072
|
+
] })
|
|
2073
|
+
] })
|
|
2074
|
+
] }),
|
|
2075
|
+
error && /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx(AlertDescription, { children: error }) }),
|
|
2076
|
+
/* @__PURE__ */ jsx(
|
|
2077
|
+
Button,
|
|
2078
|
+
{
|
|
2079
|
+
type: "submit",
|
|
2080
|
+
size: "lg",
|
|
2081
|
+
className: "w-full h-14 text-lg rounded-xl",
|
|
2082
|
+
disabled: isSubmitting || currencyOptions.length === 0,
|
|
2083
|
+
children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2084
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: "h-5 w-5 mr-2 animate-spin" }),
|
|
2085
|
+
"Creating..."
|
|
2086
|
+
] }) : "Continue"
|
|
2087
|
+
}
|
|
2088
|
+
)
|
|
2089
|
+
] }) })
|
|
2090
|
+
] }) });
|
|
2091
|
+
}
|
|
2092
|
+
var WithdrawSchema = z.object({
|
|
2093
|
+
amount: z.number().min(10, "Minimum $10.00"),
|
|
2094
|
+
currency: z.string().min(1, "Select a currency"),
|
|
2095
|
+
wallet_address: z.string().min(26, "Invalid wallet address")
|
|
2096
|
+
});
|
|
2097
|
+
var SERVICE_FEE_PERCENT = 0.01;
|
|
2098
|
+
var NETWORK_FEE_USD = 1;
|
|
2099
|
+
function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
2100
|
+
const { currencies, isLoadingCurrencies, withdraw, balanceAmount } = useWallet();
|
|
2101
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
2102
|
+
const [error, setError] = useState(null);
|
|
2103
|
+
const form = useForm({
|
|
2104
|
+
resolver: zodResolver(WithdrawSchema),
|
|
2105
|
+
defaultValues: {
|
|
2106
|
+
amount: 10,
|
|
2107
|
+
currency: "",
|
|
2108
|
+
wallet_address: ""
|
|
2109
|
+
}
|
|
2110
|
+
});
|
|
2111
|
+
const currencyOptions = useMemo(() => {
|
|
2112
|
+
return currencies.map((c) => ({
|
|
2113
|
+
value: c.code,
|
|
2114
|
+
label: c.network ? `${c.code} (${c.network})` : c.code,
|
|
2115
|
+
rate: c.rate,
|
|
2116
|
+
network: c.network
|
|
2117
|
+
}));
|
|
2118
|
+
}, [currencies]);
|
|
2119
|
+
useMemo(() => {
|
|
2120
|
+
if (currencyOptions.length > 0 && !form.getValues("currency")) {
|
|
2121
|
+
const usdt = currencyOptions.find((c) => c.value.includes("USDT"));
|
|
2122
|
+
form.setValue("currency", usdt?.value || currencyOptions[0].value);
|
|
2123
|
+
}
|
|
2124
|
+
}, [currencyOptions, form]);
|
|
2125
|
+
const selectedCurrency = currencyOptions.find((c) => c.value === form.watch("currency"));
|
|
2126
|
+
const amount = form.watch("amount") || 0;
|
|
2127
|
+
const feeBreakdown = useMemo(() => {
|
|
2128
|
+
const serviceFee = amount * SERVICE_FEE_PERCENT;
|
|
2129
|
+
const networkFee = NETWORK_FEE_USD;
|
|
2130
|
+
const totalFee = serviceFee + networkFee;
|
|
2131
|
+
const finalAmount = Math.max(0, amount - totalFee);
|
|
2132
|
+
const cryptoAmount = selectedCurrency?.rate ? finalAmount / selectedCurrency.rate : null;
|
|
2133
|
+
return {
|
|
2134
|
+
serviceFee,
|
|
2135
|
+
networkFee,
|
|
2136
|
+
totalFee,
|
|
2137
|
+
finalAmount,
|
|
2138
|
+
cryptoAmount
|
|
2139
|
+
};
|
|
2140
|
+
}, [amount, selectedCurrency]);
|
|
2141
|
+
const insufficientBalance = amount > balanceAmount;
|
|
2142
|
+
const handleSubmit = useCallback(async (data) => {
|
|
2143
|
+
try {
|
|
2144
|
+
setIsSubmitting(true);
|
|
2145
|
+
setError(null);
|
|
2146
|
+
const result = await withdraw({
|
|
2147
|
+
amount_usd: String(data.amount),
|
|
2148
|
+
currency_code: data.currency,
|
|
2149
|
+
wallet_address: data.wallet_address
|
|
2150
|
+
});
|
|
2151
|
+
form.reset();
|
|
2152
|
+
onOpenChange(false);
|
|
2153
|
+
onSuccess?.(result);
|
|
2154
|
+
} catch (err) {
|
|
2155
|
+
const message = err?.response?.data?.error || err?.response?.data?.message || err?.response?.data?.detail || err?.message || "Failed to create withdrawal request";
|
|
2156
|
+
setError(message);
|
|
2157
|
+
} finally {
|
|
2158
|
+
setIsSubmitting(false);
|
|
2159
|
+
}
|
|
2160
|
+
}, [withdraw, form, onOpenChange, onSuccess]);
|
|
2161
|
+
const handleOpenChange = useCallback((open2) => {
|
|
2162
|
+
if (!open2) {
|
|
2163
|
+
setError(null);
|
|
2164
|
+
form.reset();
|
|
2165
|
+
}
|
|
2166
|
+
onOpenChange(open2);
|
|
2167
|
+
}, [form, onOpenChange]);
|
|
2168
|
+
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-md", children: [
|
|
2169
|
+
/* @__PURE__ */ jsxs(ResponsiveSheetHeader, { children: [
|
|
2170
|
+
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { children: "Withdraw" }),
|
|
2171
|
+
/* @__PURE__ */ jsx(ResponsiveSheetDescription, { children: "Withdraw funds to your cryptocurrency wallet" })
|
|
2172
|
+
] }),
|
|
2173
|
+
/* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { onSubmit: form.handleSubmit(handleSubmit), className: "space-y-6 p-4 sm:p-0 sm:mt-4", children: [
|
|
2174
|
+
/* @__PURE__ */ jsx(
|
|
2175
|
+
FormField,
|
|
2176
|
+
{
|
|
2177
|
+
control: form.control,
|
|
2178
|
+
name: "amount",
|
|
2179
|
+
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
2180
|
+
/* @__PURE__ */ jsx(FormLabel, { children: "Amount (USD)" }),
|
|
2181
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
2182
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-muted-foreground text-lg", children: "$" }),
|
|
2183
|
+
/* @__PURE__ */ jsx(
|
|
2184
|
+
Input,
|
|
2185
|
+
{
|
|
2186
|
+
type: "number",
|
|
2187
|
+
step: "0.01",
|
|
2188
|
+
min: "10",
|
|
2189
|
+
placeholder: "10.00",
|
|
2190
|
+
className: "pl-8 text-2xl h-14 font-semibold",
|
|
2191
|
+
...field,
|
|
2192
|
+
onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
|
|
2193
|
+
}
|
|
2194
|
+
)
|
|
2195
|
+
] }) }),
|
|
2196
|
+
/* @__PURE__ */ jsx(FormMessage, {}),
|
|
2197
|
+
insufficientBalance && /* @__PURE__ */ jsxs("p", { className: "text-sm text-destructive mt-1", children: [
|
|
2198
|
+
"Insufficient balance (Available: $",
|
|
2199
|
+
balanceAmount.toFixed(2),
|
|
2200
|
+
")"
|
|
2201
|
+
] })
|
|
2202
|
+
] })
|
|
2203
|
+
}
|
|
2204
|
+
),
|
|
2205
|
+
/* @__PURE__ */ jsx(
|
|
2206
|
+
FormField,
|
|
2207
|
+
{
|
|
2208
|
+
control: form.control,
|
|
2209
|
+
name: "currency",
|
|
2210
|
+
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
2211
|
+
/* @__PURE__ */ jsx(FormLabel, { children: "Withdraw as" }),
|
|
2212
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
|
|
2213
|
+
Combobox,
|
|
2214
|
+
{
|
|
2215
|
+
options: currencyOptions,
|
|
2216
|
+
value: field.value,
|
|
2217
|
+
onValueChange: field.onChange,
|
|
2218
|
+
placeholder: "Select currency...",
|
|
2219
|
+
searchPlaceholder: "Search...",
|
|
2220
|
+
disabled: isLoadingCurrencies,
|
|
2221
|
+
className: "h-14",
|
|
2222
|
+
renderOption: (option) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1", children: [
|
|
2223
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2224
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2225
|
+
] }),
|
|
2226
|
+
renderValue: (option) => option && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2227
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2228
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2229
|
+
] })
|
|
2230
|
+
}
|
|
2231
|
+
) }),
|
|
2232
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
2233
|
+
] })
|
|
2234
|
+
}
|
|
2235
|
+
),
|
|
2236
|
+
/* @__PURE__ */ jsx(
|
|
2237
|
+
FormField,
|
|
2238
|
+
{
|
|
2239
|
+
control: form.control,
|
|
2240
|
+
name: "wallet_address",
|
|
2241
|
+
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
2242
|
+
/* @__PURE__ */ jsx(FormLabel, { children: "Wallet Address" }),
|
|
2243
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
|
|
2244
|
+
Input,
|
|
2245
|
+
{
|
|
2246
|
+
placeholder: "Enter your wallet address",
|
|
2247
|
+
className: "font-mono text-sm",
|
|
2248
|
+
...field
|
|
2249
|
+
}
|
|
2250
|
+
) }),
|
|
2251
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
2252
|
+
] })
|
|
2253
|
+
}
|
|
2254
|
+
),
|
|
2255
|
+
amount >= 10 && selectedCurrency && /* @__PURE__ */ jsxs("div", { className: "bg-muted rounded-xl p-4 space-y-2", children: [
|
|
2256
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2257
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Amount" }),
|
|
2258
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1803
2259
|
"$",
|
|
1804
|
-
|
|
1805
|
-
" USD"
|
|
2260
|
+
amount.toFixed(2)
|
|
1806
2261
|
] })
|
|
1807
2262
|
] }),
|
|
1808
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-
|
|
1809
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "
|
|
1810
|
-
/* @__PURE__ */ jsxs("span", { className: "
|
|
1811
|
-
"
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
2263
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2264
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Service fee (1%)" }),
|
|
2265
|
+
/* @__PURE__ */ jsxs("span", { className: "text-destructive", children: [
|
|
2266
|
+
"-$",
|
|
2267
|
+
feeBreakdown.serviceFee.toFixed(2)
|
|
2268
|
+
] })
|
|
2269
|
+
] }),
|
|
2270
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2271
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Network fee" }),
|
|
2272
|
+
/* @__PURE__ */ jsxs("span", { className: "text-destructive", children: [
|
|
2273
|
+
"-$",
|
|
2274
|
+
feeBreakdown.networkFee.toFixed(2)
|
|
1815
2275
|
] })
|
|
1816
2276
|
] }),
|
|
1817
|
-
|
|
1818
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
1819
|
-
/* @__PURE__ */
|
|
2277
|
+
/* @__PURE__ */ jsx("div", { className: "border-t pt-2 mt-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2278
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "You will receive" }),
|
|
2279
|
+
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
2280
|
+
/* @__PURE__ */ jsxs("div", { className: "font-semibold", children: [
|
|
2281
|
+
"$",
|
|
2282
|
+
feeBreakdown.finalAmount.toFixed(2)
|
|
2283
|
+
] }),
|
|
2284
|
+
feeBreakdown.cryptoAmount !== null && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
2285
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: selectedCurrency.value, size: 16 }),
|
|
2286
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: feeBreakdown.cryptoAmount.toFixed(8) })
|
|
2287
|
+
] })
|
|
2288
|
+
] })
|
|
1820
2289
|
] }) })
|
|
1821
2290
|
] }),
|
|
1822
|
-
/* @__PURE__ */ jsxs(
|
|
1823
|
-
/* @__PURE__ */ jsx(
|
|
1824
|
-
/* @__PURE__ */ jsx(
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
2291
|
+
/* @__PURE__ */ jsxs(Alert, { children: [
|
|
2292
|
+
/* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
|
|
2293
|
+
/* @__PURE__ */ jsx(AlertDescription, { children: "Withdrawal requests require admin approval. Processing may take 24-48 hours." })
|
|
2294
|
+
] }),
|
|
2295
|
+
error && /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx(AlertDescription, { children: error }) }),
|
|
2296
|
+
/* @__PURE__ */ jsx(
|
|
2297
|
+
Button,
|
|
2298
|
+
{
|
|
2299
|
+
type: "submit",
|
|
2300
|
+
size: "lg",
|
|
2301
|
+
className: "w-full h-14 text-lg rounded-xl",
|
|
2302
|
+
disabled: isSubmitting || currencyOptions.length === 0 || insufficientBalance || feeBreakdown.finalAmount <= 0,
|
|
2303
|
+
children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2304
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: "h-5 w-5 mr-2 animate-spin" }),
|
|
2305
|
+
"Submitting..."
|
|
2306
|
+
] }) : "Request Withdrawal"
|
|
2307
|
+
}
|
|
2308
|
+
)
|
|
1832
2309
|
] }) })
|
|
1833
2310
|
] }) });
|
|
2311
|
+
}
|
|
2312
|
+
var statusConfig2 = {
|
|
2313
|
+
pending: {
|
|
2314
|
+
icon: Clock,
|
|
2315
|
+
color: "text-yellow-500",
|
|
2316
|
+
bg: "bg-yellow-500/10",
|
|
2317
|
+
label: "Waiting for payment"
|
|
2318
|
+
},
|
|
2319
|
+
confirming: {
|
|
2320
|
+
icon: RefreshCw,
|
|
2321
|
+
color: "text-blue-500",
|
|
2322
|
+
bg: "bg-blue-500/10",
|
|
2323
|
+
label: "Confirming",
|
|
2324
|
+
animate: true
|
|
2325
|
+
},
|
|
2326
|
+
completed: {
|
|
2327
|
+
icon: CheckCircle2,
|
|
2328
|
+
color: "text-green-500",
|
|
2329
|
+
bg: "bg-green-500/10",
|
|
2330
|
+
label: "Completed"
|
|
2331
|
+
},
|
|
2332
|
+
failed: {
|
|
2333
|
+
icon: XCircle,
|
|
2334
|
+
color: "text-red-500",
|
|
2335
|
+
bg: "bg-red-500/10",
|
|
2336
|
+
label: "Failed"
|
|
2337
|
+
},
|
|
2338
|
+
expired: {
|
|
2339
|
+
icon: AlertCircle,
|
|
2340
|
+
color: "text-muted-foreground",
|
|
2341
|
+
bg: "bg-muted",
|
|
2342
|
+
label: "Expired"
|
|
2343
|
+
}
|
|
1834
2344
|
};
|
|
1835
|
-
|
|
1836
|
-
const
|
|
1837
|
-
const [paymentId, setPaymentId] = useState(null);
|
|
2345
|
+
function PaymentSheet({ paymentId, open, onOpenChange }) {
|
|
2346
|
+
const { getPaymentDetails } = useWallet();
|
|
1838
2347
|
const [timeLeft, setTimeLeft] = useState("");
|
|
1839
|
-
const
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
2348
|
+
const { data: payment, isLoading, error, mutate } = useSWR2(
|
|
2349
|
+
open && paymentId ? ["payment-details", paymentId] : null,
|
|
2350
|
+
() => getPaymentDetails(paymentId),
|
|
2351
|
+
{ refreshInterval: 1e4 }
|
|
1843
2352
|
);
|
|
1844
|
-
useEffect(() => {
|
|
1845
|
-
const handleOpen = (event) => {
|
|
1846
|
-
const customEvent = event;
|
|
1847
|
-
setPaymentId(customEvent.detail.id);
|
|
1848
|
-
setOpen(true);
|
|
1849
|
-
};
|
|
1850
|
-
const handleClose2 = () => {
|
|
1851
|
-
setOpen(false);
|
|
1852
|
-
setPaymentId(null);
|
|
1853
|
-
};
|
|
1854
|
-
window.addEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
|
|
1855
|
-
window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1856
|
-
return () => {
|
|
1857
|
-
window.removeEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
|
|
1858
|
-
window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1859
|
-
};
|
|
1860
|
-
}, []);
|
|
1861
|
-
const handleClose = () => {
|
|
1862
|
-
setOpen(false);
|
|
1863
|
-
setPaymentId(null);
|
|
1864
|
-
};
|
|
1865
2353
|
useEffect(() => {
|
|
1866
2354
|
if (!payment?.expires_at) return;
|
|
1867
2355
|
const updateTimeLeft = () => {
|
|
1868
|
-
const now =
|
|
1869
|
-
const expires =
|
|
2356
|
+
const now = moment2();
|
|
2357
|
+
const expires = moment2.utc(payment.expires_at);
|
|
1870
2358
|
const diff = expires.diff(now);
|
|
1871
2359
|
if (diff <= 0) {
|
|
1872
2360
|
setTimeLeft("Expired");
|
|
1873
2361
|
return;
|
|
1874
2362
|
}
|
|
1875
|
-
const duration =
|
|
2363
|
+
const duration = moment2.duration(diff);
|
|
1876
2364
|
const hours = Math.floor(duration.asHours());
|
|
1877
2365
|
const minutes = duration.minutes();
|
|
1878
2366
|
const seconds = duration.seconds();
|
|
@@ -1882,713 +2370,172 @@ var PaymentDetailsDialog = () => {
|
|
|
1882
2370
|
const interval = setInterval(updateTimeLeft, 1e3);
|
|
1883
2371
|
return () => clearInterval(interval);
|
|
1884
2372
|
}, [payment?.expires_at]);
|
|
1885
|
-
const
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: "Payment Details" }),
|
|
1908
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: "Loading payment information..." })
|
|
1909
|
-
] }),
|
|
1910
|
-
/* @__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" }) })
|
|
1911
|
-
] }) });
|
|
1912
|
-
}
|
|
1913
|
-
if (shouldFetch && !isLoading && (error || !payment)) {
|
|
1914
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-lg", children: [
|
|
1915
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
1916
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: "Payment Details" }),
|
|
1917
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: "Failed to load payment information" })
|
|
2373
|
+
const status = useMemo(() => {
|
|
2374
|
+
const s = payment?.status?.toLowerCase();
|
|
2375
|
+
if (s === "completed" || s === "success" || s === "finished") return "completed";
|
|
2376
|
+
if (s === "confirming" || s === "partially_paid") return "confirming";
|
|
2377
|
+
if (s === "expired") return "expired";
|
|
2378
|
+
if (s === "failed" || s === "error" || s === "cancelled") return "failed";
|
|
2379
|
+
return "pending";
|
|
2380
|
+
}, [payment?.status]);
|
|
2381
|
+
const config = statusConfig2[status];
|
|
2382
|
+
const StatusIcon = config.icon;
|
|
2383
|
+
const qrCodeUrl = payment?.pay_address ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}` : null;
|
|
2384
|
+
const isPending = status === "pending";
|
|
2385
|
+
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-lg", children: [
|
|
2386
|
+
/* @__PURE__ */ jsxs(ResponsiveSheetHeader, { children: [
|
|
2387
|
+
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { children: "Payment Details" }),
|
|
2388
|
+
/* @__PURE__ */ jsx(ResponsiveSheetDescription, { children: isPending ? "Send cryptocurrency to complete payment" : "Payment information" })
|
|
2389
|
+
] }),
|
|
2390
|
+
/* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-0 sm:mt-4 overflow-y-auto max-h-[70vh]", children: [
|
|
2391
|
+
isLoading && /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
2392
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-48 w-48 rounded-xl" }) }),
|
|
2393
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-full" }),
|
|
2394
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-24 w-full" })
|
|
1918
2395
|
] }),
|
|
1919
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-12
|
|
1920
|
-
/* @__PURE__ */ jsx(XCircle, { className: "h-12 w-12 text-destructive" }),
|
|
1921
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children:
|
|
2396
|
+
error && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-12", children: [
|
|
2397
|
+
/* @__PURE__ */ jsx(XCircle, { className: "h-12 w-12 text-destructive mb-4" }),
|
|
2398
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Failed to load payment" }),
|
|
1922
2399
|
/* @__PURE__ */ jsx(Button, { onClick: () => mutate(), children: "Try Again" })
|
|
1923
|
-
] })
|
|
1924
|
-
] }) });
|
|
1925
|
-
}
|
|
1926
|
-
const statusInfo = getStatusInfo();
|
|
1927
|
-
const StatusIcon = statusInfo.icon;
|
|
1928
|
-
const qrCodeUrl = payment.pay_address ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}` : null;
|
|
1929
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-lg", children: [
|
|
1930
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
1931
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: "Payment Details" }),
|
|
1932
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: "Send cryptocurrency to complete your payment" })
|
|
1933
|
-
] }),
|
|
1934
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
1935
|
-
/* @__PURE__ */ jsxs("div", { className: `flex items-center gap-3 p-4 rounded-sm ${statusInfo.bg}`, children: [
|
|
1936
|
-
/* @__PURE__ */ jsx(StatusIcon, { className: `h-5 w-5 ${statusInfo.color}` }),
|
|
1937
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
1938
|
-
/* @__PURE__ */ jsx("div", { className: "font-semibold capitalize", children: payment.status }),
|
|
1939
|
-
payment.status === "pending" && timeLeft && /* @__PURE__ */ jsxs("div", { className: "text-sm text-muted-foreground", children: [
|
|
1940
|
-
"Expires in ",
|
|
1941
|
-
timeLeft
|
|
1942
|
-
] })
|
|
1943
|
-
] })
|
|
1944
2400
|
] }),
|
|
1945
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-
|
|
1946
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center
|
|
1947
|
-
/* @__PURE__ */ jsx(
|
|
1948
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
1949
|
-
/* @__PURE__ */ jsx(
|
|
1950
|
-
/* @__PURE__ */ jsxs("
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
payment.currency_code
|
|
2401
|
+
payment && !isLoading && /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
2402
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3 p-4 rounded-xl", config.bg), children: [
|
|
2403
|
+
/* @__PURE__ */ jsx(StatusIcon, { className: cn("h-6 w-6", config.color, config.animate && "animate-spin") }),
|
|
2404
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
2405
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold", children: config.label }),
|
|
2406
|
+
isPending && timeLeft && /* @__PURE__ */ jsxs("div", { className: "text-sm text-muted-foreground", children: [
|
|
2407
|
+
"Expires in ",
|
|
2408
|
+
timeLeft
|
|
1954
2409
|
] })
|
|
1955
2410
|
] })
|
|
1956
2411
|
] }),
|
|
1957
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
1958
|
-
/* @__PURE__ */
|
|
1959
|
-
|
|
1960
|
-
"$",
|
|
1961
|
-
parseFloat(payment.amount_usd || "0").toFixed(2),
|
|
1962
|
-
" USD"
|
|
1963
|
-
] })
|
|
1964
|
-
] }),
|
|
1965
|
-
payment.internal_payment_id && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
1966
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Payment Order #" }),
|
|
1967
|
-
/* @__PURE__ */ jsx("span", { className: "font-mono font-medium", children: payment.internal_payment_id })
|
|
1968
|
-
] }),
|
|
1969
|
-
payment.currency_network && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
1970
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Network" }),
|
|
1971
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: payment.currency_network })
|
|
1972
|
-
] })
|
|
1973
|
-
] }),
|
|
1974
|
-
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" }) }),
|
|
1975
|
-
payment.pay_address && payment.status === "pending" && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1976
|
-
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Payment Address" }),
|
|
1977
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1978
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.pay_address }),
|
|
1979
|
-
/* @__PURE__ */ jsx(CopyButton, { value: payment.pay_address, variant: "outline" })
|
|
1980
|
-
] })
|
|
1981
|
-
] }),
|
|
1982
|
-
payment.transaction_hash && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1983
|
-
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
|
|
1984
|
-
/* @__PURE__ */ jsx("div", { className: "p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.transaction_hash })
|
|
1985
|
-
] }),
|
|
1986
|
-
payment.payment_url && payment.status === "pending" && /* @__PURE__ */ jsxs(
|
|
1987
|
-
Button,
|
|
1988
|
-
{
|
|
1989
|
-
variant: "outline",
|
|
1990
|
-
className: "w-full",
|
|
1991
|
-
onClick: () => window.open(payment.payment_url, "_blank"),
|
|
1992
|
-
children: [
|
|
1993
|
-
/* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4 mr-2" }),
|
|
1994
|
-
"Open in Payment Provider"
|
|
1995
|
-
]
|
|
1996
|
-
}
|
|
1997
|
-
),
|
|
1998
|
-
/* @__PURE__ */ jsxs("div", { className: "pt-4 border-t space-y-2 text-xs text-muted-foreground", children: [
|
|
1999
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
2000
|
-
/* @__PURE__ */ jsx("span", { children: "Payment ID" }),
|
|
2001
|
-
/* @__PURE__ */ jsx("span", { className: "font-mono", children: payment.id })
|
|
2002
|
-
] }),
|
|
2003
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
2004
|
-
/* @__PURE__ */ jsx("span", { children: "Created" }),
|
|
2005
|
-
/* @__PURE__ */ jsx("span", { children: moment.utc(payment.created_at).local().format("MMM D, YYYY HH:mm") })
|
|
2006
|
-
] }),
|
|
2007
|
-
payment.confirmations_count !== void 0 && /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
2008
|
-
/* @__PURE__ */ jsx("span", { children: "Confirmations" }),
|
|
2009
|
-
/* @__PURE__ */ jsx("span", { children: payment.confirmations_count })
|
|
2010
|
-
] })
|
|
2011
|
-
] })
|
|
2012
|
-
] }),
|
|
2013
|
-
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
2014
|
-
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleClose, children: "Close" }),
|
|
2015
|
-
/* @__PURE__ */ jsxs(Button, { onClick: () => mutate(), variant: "ghost", size: "sm", children: [
|
|
2016
|
-
/* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4 mr-2" }),
|
|
2017
|
-
"Refresh"
|
|
2018
|
-
] })
|
|
2019
|
-
] })
|
|
2020
|
-
] }) });
|
|
2021
|
-
};
|
|
2022
|
-
var BalanceCard = () => {
|
|
2023
|
-
const {
|
|
2024
|
-
balance,
|
|
2025
|
-
isLoadingBalance,
|
|
2026
|
-
refreshBalance
|
|
2027
|
-
} = useOverviewContext();
|
|
2028
|
-
const formatCurrency = (amount) => {
|
|
2029
|
-
if (amount === null || amount === void 0) return "$0.00";
|
|
2030
|
-
return new Intl.NumberFormat("en-US", {
|
|
2031
|
-
style: "currency",
|
|
2032
|
-
currency: "USD",
|
|
2033
|
-
minimumFractionDigits: 2
|
|
2034
|
-
}).format(amount);
|
|
2035
|
-
};
|
|
2036
|
-
const formatDate = (dateStr) => {
|
|
2037
|
-
if (!dateStr) return "No transactions yet";
|
|
2038
|
-
try {
|
|
2039
|
-
return moment.utc(dateStr).local().format("MMM D, YYYY");
|
|
2040
|
-
} catch {
|
|
2041
|
-
return "Invalid date";
|
|
2042
|
-
}
|
|
2043
|
-
};
|
|
2044
|
-
if (isLoadingBalance) {
|
|
2045
|
-
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
2046
|
-
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center justify-between", children: [
|
|
2047
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2048
|
-
/* @__PURE__ */ jsx(Wallet, { className: "h-5 w-5" }),
|
|
2049
|
-
"Account Balance"
|
|
2050
|
-
] }),
|
|
2051
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-20" })
|
|
2052
|
-
] }) }),
|
|
2053
|
-
/* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
|
|
2054
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-32" }),
|
|
2055
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-48" })
|
|
2056
|
-
] })
|
|
2057
|
-
] });
|
|
2058
|
-
}
|
|
2059
|
-
const balanceData = balance?.balance || balance;
|
|
2060
|
-
const amountUsd = balanceData?.amount_usd ?? 0;
|
|
2061
|
-
const totalDeposited = balanceData?.total_deposited ?? 0;
|
|
2062
|
-
const totalWithdrawn = balanceData?.total_withdrawn ?? 0;
|
|
2063
|
-
const lastTransactionAt = balanceData?.last_transaction_at;
|
|
2064
|
-
const isEmpty = amountUsd === 0 && totalDeposited === 0;
|
|
2065
|
-
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
2066
|
-
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center justify-between", children: [
|
|
2067
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2068
|
-
/* @__PURE__ */ jsx(Wallet, { className: "h-5 w-5" }),
|
|
2069
|
-
"Account Balance"
|
|
2070
|
-
] }),
|
|
2071
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2072
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: refreshBalance, children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" }) }),
|
|
2073
|
-
/* @__PURE__ */ jsxs(Button, { size: "sm", onClick: () => openCreatePaymentDialog(), children: [
|
|
2074
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4 mr-2" }),
|
|
2075
|
-
"Add Funds"
|
|
2076
|
-
] })
|
|
2077
|
-
] })
|
|
2078
|
-
] }) }),
|
|
2079
|
-
/* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
|
|
2080
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2081
|
-
/* @__PURE__ */ jsx("div", { className: "text-4xl font-bold", children: formatCurrency(amountUsd) }),
|
|
2082
|
-
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground mt-1", children: [
|
|
2083
|
-
"Available balance \u2022 Last updated ",
|
|
2084
|
-
formatDate(lastTransactionAt)
|
|
2085
|
-
] })
|
|
2086
|
-
] }),
|
|
2087
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4 pt-4 border-t", children: [
|
|
2088
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2089
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Total Deposited" }),
|
|
2090
|
-
/* @__PURE__ */ jsx("p", { className: "text-lg font-semibold text-green-600", children: formatCurrency(totalDeposited) })
|
|
2091
|
-
] }),
|
|
2092
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2093
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Total Withdrawn" }),
|
|
2094
|
-
/* @__PURE__ */ jsx("p", { className: "text-lg font-semibold text-red-600", children: formatCurrency(totalWithdrawn) })
|
|
2095
|
-
] })
|
|
2096
|
-
] }),
|
|
2097
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2098
|
-
/* @__PURE__ */ jsx(Badge, { variant: !isEmpty ? "default" : "secondary", children: !isEmpty ? "Active" : "New Account" }),
|
|
2099
|
-
isEmpty && /* @__PURE__ */ jsx(Badge, { variant: "outline", children: "Empty Balance" })
|
|
2100
|
-
] })
|
|
2101
|
-
] })
|
|
2102
|
-
] });
|
|
2103
|
-
};
|
|
2104
|
-
var RecentPayments = () => {
|
|
2105
|
-
const { payments, isLoadingPayments } = useOverviewContext();
|
|
2106
|
-
const formatCurrency = (amount) => {
|
|
2107
|
-
if (amount === null || amount === void 0) return "$0.00";
|
|
2108
|
-
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
2109
|
-
return new Intl.NumberFormat("en-US", {
|
|
2110
|
-
style: "currency",
|
|
2111
|
-
currency: "USD",
|
|
2112
|
-
minimumFractionDigits: 2
|
|
2113
|
-
}).format(numAmount);
|
|
2114
|
-
};
|
|
2115
|
-
const getRelativeTime = (date) => {
|
|
2116
|
-
if (!date) return "N/A";
|
|
2117
|
-
const m = moment.utc(date).local();
|
|
2118
|
-
const now = moment();
|
|
2119
|
-
const diffInSeconds = now.diff(m, "seconds");
|
|
2120
|
-
if (diffInSeconds < 60) return "Just now";
|
|
2121
|
-
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
2122
|
-
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
2123
|
-
return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
2124
|
-
};
|
|
2125
|
-
const getStatusVariant = (status) => {
|
|
2126
|
-
switch (status?.toLowerCase()) {
|
|
2127
|
-
case "completed":
|
|
2128
|
-
case "success":
|
|
2129
|
-
return "default";
|
|
2130
|
-
case "pending":
|
|
2131
|
-
case "confirming":
|
|
2132
|
-
return "secondary";
|
|
2133
|
-
case "failed":
|
|
2134
|
-
case "error":
|
|
2135
|
-
case "expired":
|
|
2136
|
-
return "destructive";
|
|
2137
|
-
default:
|
|
2138
|
-
return "outline";
|
|
2139
|
-
}
|
|
2140
|
-
};
|
|
2141
|
-
if (isLoadingPayments) {
|
|
2142
|
-
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
2143
|
-
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2", children: [
|
|
2144
|
-
/* @__PURE__ */ jsx(History, { className: "h-5 w-5" }),
|
|
2145
|
-
"Recent Payments"
|
|
2146
|
-
] }) }),
|
|
2147
|
-
/* @__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: [
|
|
2148
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2149
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-32" }),
|
|
2150
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" })
|
|
2151
|
-
] }),
|
|
2152
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-16" })
|
|
2153
|
-
] }, i)) })
|
|
2154
|
-
] });
|
|
2155
|
-
}
|
|
2156
|
-
const recentPaymentsList = payments?.results?.slice(0, 5) || [];
|
|
2157
|
-
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
2158
|
-
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center justify-between", children: [
|
|
2159
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2160
|
-
/* @__PURE__ */ jsx(History, { className: "h-5 w-5" }),
|
|
2161
|
-
"Recent Payments"
|
|
2162
|
-
] }),
|
|
2163
|
-
/* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", children: [
|
|
2164
|
-
"View All",
|
|
2165
|
-
/* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4 ml-2" })
|
|
2166
|
-
] })
|
|
2167
|
-
] }) }),
|
|
2168
|
-
/* @__PURE__ */ jsx(CardContent, { children: recentPaymentsList.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
2169
|
-
/* @__PURE__ */ jsx(History, { className: "h-12 w-12 mx-auto mb-4 opacity-50" }),
|
|
2170
|
-
/* @__PURE__ */ jsx("p", { children: "No recent payments" }),
|
|
2171
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm mt-2", children: "Create your first payment to get started" })
|
|
2172
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: recentPaymentsList.map((payment) => /* @__PURE__ */ jsxs(
|
|
2173
|
-
"div",
|
|
2174
|
-
{
|
|
2175
|
-
className: "flex items-center justify-between p-3 border rounded-sm hover:bg-accent cursor-pointer transition-colors",
|
|
2176
|
-
onClick: () => openPaymentDetailsDialog(String(payment.id)),
|
|
2177
|
-
children: [
|
|
2178
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
2412
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-muted rounded-xl p-4 space-y-3", children: [
|
|
2413
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2414
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Amount to send" }),
|
|
2179
2415
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2180
|
-
/* @__PURE__ */ jsx(
|
|
2181
|
-
/* @__PURE__ */
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
payment.currency_code || "USD"
|
|
2416
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: payment.currency_code, size: 24 }),
|
|
2417
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono font-bold text-lg", children: [
|
|
2418
|
+
payment.pay_amount,
|
|
2419
|
+
" ",
|
|
2420
|
+
payment.currency_code
|
|
2421
|
+
] })
|
|
2187
2422
|
] })
|
|
2188
2423
|
] }),
|
|
2189
|
-
/* @__PURE__ */
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
}
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
};
|
|
2202
|
-
var PaymentsList = () => {
|
|
2203
|
-
const pagination = useDRFPagination(1, 20);
|
|
2204
|
-
const {
|
|
2205
|
-
data: payments,
|
|
2206
|
-
error,
|
|
2207
|
-
isLoading: isLoadingPayments,
|
|
2208
|
-
mutate: refreshPayments
|
|
2209
|
-
} = usePaymentsPaymentsList(pagination.params, apiPayments);
|
|
2210
|
-
const paymentsList = payments?.results || [];
|
|
2211
|
-
payments?.count || 0;
|
|
2212
|
-
const [searchTerm, setSearchTerm] = useState("");
|
|
2213
|
-
const [statusFilter, setStatusFilter] = useState("all");
|
|
2214
|
-
const formatCurrency = (amount) => {
|
|
2215
|
-
if (amount === null || amount === void 0) return "$0.00";
|
|
2216
|
-
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
2217
|
-
return new Intl.NumberFormat("en-US", {
|
|
2218
|
-
style: "currency",
|
|
2219
|
-
currency: "USD",
|
|
2220
|
-
minimumFractionDigits: 2
|
|
2221
|
-
}).format(numAmount);
|
|
2222
|
-
};
|
|
2223
|
-
const getRelativeTime = (date) => {
|
|
2224
|
-
if (!date) return "N/A";
|
|
2225
|
-
const m = moment.utc(date).local();
|
|
2226
|
-
const now = moment();
|
|
2227
|
-
const diffInSeconds = now.diff(m, "seconds");
|
|
2228
|
-
if (diffInSeconds < 60) return "Just now";
|
|
2229
|
-
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
2230
|
-
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
2231
|
-
return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
2232
|
-
};
|
|
2233
|
-
const formatDate = (date) => {
|
|
2234
|
-
if (!date) return "N/A";
|
|
2235
|
-
return moment.utc(date).local().format("MMM D, YYYY");
|
|
2236
|
-
};
|
|
2237
|
-
const getStatusVariant = (status) => {
|
|
2238
|
-
switch (status?.toLowerCase()) {
|
|
2239
|
-
case "completed":
|
|
2240
|
-
case "success":
|
|
2241
|
-
return "default";
|
|
2242
|
-
case "pending":
|
|
2243
|
-
case "confirming":
|
|
2244
|
-
return "secondary";
|
|
2245
|
-
case "failed":
|
|
2246
|
-
case "error":
|
|
2247
|
-
case "expired":
|
|
2248
|
-
return "destructive";
|
|
2249
|
-
default:
|
|
2250
|
-
return "outline";
|
|
2251
|
-
}
|
|
2252
|
-
};
|
|
2253
|
-
const handleSearch = (value) => {
|
|
2254
|
-
setSearchTerm(value);
|
|
2255
|
-
};
|
|
2256
|
-
const handleStatusFilter = (status) => {
|
|
2257
|
-
setStatusFilter(status);
|
|
2258
|
-
};
|
|
2259
|
-
const truncateId = (id) => {
|
|
2260
|
-
if (!id) return "N/A";
|
|
2261
|
-
const str = id.toString();
|
|
2262
|
-
return str.length > 8 ? `${str.slice(0, 8)}...` : str;
|
|
2263
|
-
};
|
|
2264
|
-
const filteredPayments = paymentsList.filter((payment) => {
|
|
2265
|
-
const matchesSearch = searchTerm ? payment.id?.toLowerCase().includes(searchTerm.toLowerCase()) || payment.status?.toLowerCase().includes(searchTerm.toLowerCase()) || payment.currency_code?.toLowerCase().includes(searchTerm.toLowerCase()) : true;
|
|
2266
|
-
const matchesStatus = statusFilter !== "all" ? payment.status?.toLowerCase() === statusFilter.toLowerCase() : true;
|
|
2267
|
-
return matchesSearch && matchesStatus;
|
|
2268
|
-
}).map((payment) => ({
|
|
2269
|
-
...payment,
|
|
2270
|
-
formattedDate: formatDate(payment.created_at),
|
|
2271
|
-
relativeTime: getRelativeTime(payment.created_at),
|
|
2272
|
-
truncatedId: truncateId(payment.id)
|
|
2273
|
-
}));
|
|
2274
|
-
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
2275
|
-
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center justify-between", children: [
|
|
2276
|
-
/* @__PURE__ */ jsx("span", { children: "Payment History" }),
|
|
2277
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2278
|
-
/* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: () => refreshPayments(), disabled: isLoadingPayments, children: [
|
|
2279
|
-
/* @__PURE__ */ jsx(RefreshCw, { className: `h-4 w-4 mr-2 ${isLoadingPayments ? "animate-spin" : ""}` }),
|
|
2280
|
-
"Refresh"
|
|
2424
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2425
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Equivalent" }),
|
|
2426
|
+
/* @__PURE__ */ jsxs("span", { className: "font-semibold", children: [
|
|
2427
|
+
"$",
|
|
2428
|
+
parseFloat(payment.amount_usd).toFixed(2),
|
|
2429
|
+
" USD"
|
|
2430
|
+
] })
|
|
2431
|
+
] }),
|
|
2432
|
+
payment.currency_network && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm pt-2 border-t", children: [
|
|
2433
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Network" }),
|
|
2434
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: payment.currency_network })
|
|
2435
|
+
] })
|
|
2281
2436
|
] }),
|
|
2282
|
-
/* @__PURE__ */
|
|
2283
|
-
|
|
2284
|
-
"
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2291
|
-
/* @__PURE__ */ jsx(
|
|
2292
|
-
/* @__PURE__ */ jsx(
|
|
2293
|
-
Input,
|
|
2294
|
-
{
|
|
2295
|
-
placeholder: "Search by ID, status, or currency...",
|
|
2296
|
-
value: searchTerm,
|
|
2297
|
-
onChange: (e) => handleSearch(e.target.value),
|
|
2298
|
-
className: "pl-10"
|
|
2299
|
-
}
|
|
2300
|
-
)
|
|
2437
|
+
qrCodeUrl && isPending && /* @__PURE__ */ jsx("div", { className: "flex justify-center p-6 bg-white rounded-xl", children: /* @__PURE__ */ jsx("img", { src: qrCodeUrl, alt: "Payment QR Code", className: "w-48 h-48" }) }),
|
|
2438
|
+
payment.pay_address && isPending && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2439
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Payment Address" }),
|
|
2440
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2441
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 p-3 bg-muted rounded-xl font-mono text-sm break-all", children: payment.pay_address }),
|
|
2442
|
+
/* @__PURE__ */ jsx(CopyButton, { value: payment.pay_address, variant: "outline", className: "shrink-0" })
|
|
2443
|
+
] })
|
|
2444
|
+
] }),
|
|
2445
|
+
payment.transaction_hash && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2446
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
|
|
2447
|
+
/* @__PURE__ */ jsx("div", { className: "p-3 bg-muted rounded-xl font-mono text-sm break-all", children: payment.transaction_hash })
|
|
2301
2448
|
] }),
|
|
2302
|
-
/* @__PURE__ */ jsxs(
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2449
|
+
payment.payment_url && isPending && /* @__PURE__ */ jsxs(
|
|
2450
|
+
Button,
|
|
2451
|
+
{
|
|
2452
|
+
variant: "outline",
|
|
2453
|
+
className: "w-full",
|
|
2454
|
+
onClick: () => window.open(payment.payment_url, "_blank"),
|
|
2455
|
+
children: [
|
|
2456
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4 mr-2" }),
|
|
2457
|
+
"Open in Payment Provider"
|
|
2458
|
+
]
|
|
2459
|
+
}
|
|
2460
|
+
),
|
|
2461
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2 text-xs text-muted-foreground pt-4 border-t", children: [
|
|
2462
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
2463
|
+
/* @__PURE__ */ jsx("span", { children: "Payment ID" }),
|
|
2464
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: payment.id })
|
|
2465
|
+
] }),
|
|
2466
|
+
payment.internal_payment_id && /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
2467
|
+
/* @__PURE__ */ jsx("span", { children: "Order #" }),
|
|
2468
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: payment.internal_payment_id })
|
|
2306
2469
|
] }),
|
|
2307
|
-
/* @__PURE__ */ jsxs(
|
|
2308
|
-
/* @__PURE__ */ jsx(
|
|
2309
|
-
/* @__PURE__ */ jsx(
|
|
2310
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "pending", children: "Pending" }),
|
|
2311
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "confirming", children: "Confirming" }),
|
|
2312
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "failed", children: "Failed" }),
|
|
2313
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "expired", children: "Expired" })
|
|
2470
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
2471
|
+
/* @__PURE__ */ jsx("span", { children: "Created" }),
|
|
2472
|
+
/* @__PURE__ */ jsx("span", { children: moment2.utc(payment.created_at).local().format("MMM D, YYYY HH:mm") })
|
|
2314
2473
|
] })
|
|
2315
|
-
] })
|
|
2316
|
-
] }),
|
|
2317
|
-
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: [
|
|
2318
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2319
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-32" }),
|
|
2320
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" })
|
|
2321
2474
|
] }),
|
|
2322
|
-
/* @__PURE__ */
|
|
2323
|
-
|
|
2324
|
-
/* @__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" }) }),
|
|
2325
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-2", children: "No Payments Found" }),
|
|
2326
|
-
/* @__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" }),
|
|
2327
|
-
/* @__PURE__ */ jsxs(Button, { onClick: () => openCreatePaymentDialog(), children: [
|
|
2328
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4 mr-2" }),
|
|
2329
|
-
"Create Payment"
|
|
2330
|
-
] })
|
|
2331
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2332
|
-
/* @__PURE__ */ jsx("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
2333
|
-
/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
2334
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Date" }),
|
|
2335
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Amount" }),
|
|
2336
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Currency" }),
|
|
2337
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Status" }),
|
|
2338
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Provider" }),
|
|
2339
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Payment ID" }),
|
|
2340
|
-
/* @__PURE__ */ jsx(TableHead, { className: "text-right", children: "Actions" })
|
|
2341
|
-
] }) }),
|
|
2342
|
-
/* @__PURE__ */ jsx(TableBody, { children: filteredPayments.map((payment) => /* @__PURE__ */ jsxs(
|
|
2343
|
-
TableRow,
|
|
2344
|
-
{
|
|
2345
|
-
className: "cursor-pointer hover:bg-accent",
|
|
2346
|
-
onClick: () => openPaymentDetailsDialog(String(payment.id)),
|
|
2347
|
-
children: [
|
|
2348
|
-
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsxs("div", { children: [
|
|
2349
|
-
/* @__PURE__ */ jsx("div", { className: "font-medium", children: payment.formattedDate }),
|
|
2350
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: payment.relativeTime })
|
|
2351
|
-
] }) }),
|
|
2352
|
-
/* @__PURE__ */ jsx(TableCell, { className: "font-mono font-semibold", children: formatCurrency(payment.amount_usd) }),
|
|
2353
|
-
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Badge, { variant: "outline", children: payment.currency_code || "USD" }) }),
|
|
2354
|
-
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Badge, { variant: getStatusVariant(payment.status), children: payment.status }) }),
|
|
2355
|
-
/* @__PURE__ */ jsx(TableCell, { className: "text-sm text-muted-foreground", children: "NowPayments" }),
|
|
2356
|
-
/* @__PURE__ */ jsx(TableCell, { className: "font-mono text-sm text-muted-foreground", children: payment.truncatedId }),
|
|
2357
|
-
/* @__PURE__ */ jsx(TableCell, { className: "text-right", children: /* @__PURE__ */ jsx(
|
|
2358
|
-
Button,
|
|
2359
|
-
{
|
|
2360
|
-
variant: "ghost",
|
|
2361
|
-
size: "sm",
|
|
2362
|
-
onClick: (e) => {
|
|
2363
|
-
e.stopPropagation();
|
|
2364
|
-
openPaymentDetailsDialog(String(payment.id));
|
|
2365
|
-
},
|
|
2366
|
-
children: /* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4" })
|
|
2367
|
-
}
|
|
2368
|
-
) })
|
|
2369
|
-
]
|
|
2370
|
-
},
|
|
2371
|
-
payment.id
|
|
2372
|
-
)) })
|
|
2373
|
-
] }) }),
|
|
2374
|
-
/* @__PURE__ */ jsx(
|
|
2375
|
-
StaticPagination,
|
|
2475
|
+
/* @__PURE__ */ jsxs(
|
|
2476
|
+
Button,
|
|
2376
2477
|
{
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2478
|
+
variant: "ghost",
|
|
2479
|
+
className: "w-full",
|
|
2480
|
+
onClick: () => mutate(),
|
|
2481
|
+
children: [
|
|
2482
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4 mr-2" }),
|
|
2483
|
+
"Refresh Status"
|
|
2484
|
+
]
|
|
2380
2485
|
}
|
|
2381
2486
|
)
|
|
2382
2487
|
] })
|
|
2383
2488
|
] })
|
|
2384
|
-
] });
|
|
2385
|
-
};
|
|
2386
|
-
var PaymentsView = () => {
|
|
2387
|
-
return /* @__PURE__ */ jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsx(PaymentsList, {}) });
|
|
2388
|
-
};
|
|
2389
|
-
var TransactionsList = () => {
|
|
2390
|
-
const {
|
|
2391
|
-
transactions,
|
|
2392
|
-
isLoadingTransactions,
|
|
2393
|
-
refreshTransactions
|
|
2394
|
-
} = useOverviewContext();
|
|
2395
|
-
const [searchTerm, setSearchTerm] = useState("");
|
|
2396
|
-
const [typeFilter, setTypeFilter] = useState("all");
|
|
2397
|
-
const transactionsList = transactions?.results || transactions?.transactions || [];
|
|
2398
|
-
const formatCurrency = (amount) => {
|
|
2399
|
-
if (amount === null || amount === void 0) return "$0.00";
|
|
2400
|
-
return new Intl.NumberFormat("en-US", {
|
|
2401
|
-
style: "currency",
|
|
2402
|
-
currency: "USD",
|
|
2403
|
-
minimumFractionDigits: 2
|
|
2404
|
-
}).format(amount);
|
|
2405
|
-
};
|
|
2406
|
-
const formatDate = (date) => {
|
|
2407
|
-
if (!date) return "N/A";
|
|
2408
|
-
try {
|
|
2409
|
-
return moment.utc(date).local().format("MMM D, YYYY hh:mm A");
|
|
2410
|
-
} catch {
|
|
2411
|
-
return "Invalid date";
|
|
2412
|
-
}
|
|
2413
|
-
};
|
|
2414
|
-
const getRelativeTime = (date) => {
|
|
2415
|
-
if (!date) return "N/A";
|
|
2416
|
-
const m = moment.utc(date).local();
|
|
2417
|
-
const now = moment();
|
|
2418
|
-
const diffInSeconds = now.diff(m, "seconds");
|
|
2419
|
-
if (diffInSeconds < 60) return "Just now";
|
|
2420
|
-
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
2421
|
-
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
2422
|
-
return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
2423
|
-
};
|
|
2424
|
-
const getTypeVariant = (type) => {
|
|
2425
|
-
switch (type?.toLowerCase()) {
|
|
2426
|
-
case "deposit":
|
|
2427
|
-
case "credit":
|
|
2428
|
-
return "default";
|
|
2429
|
-
case "withdrawal":
|
|
2430
|
-
case "debit":
|
|
2431
|
-
return "destructive";
|
|
2432
|
-
default:
|
|
2433
|
-
return "outline";
|
|
2434
|
-
}
|
|
2435
|
-
};
|
|
2436
|
-
const getTypeIcon = (type) => {
|
|
2437
|
-
const isDeposit = type?.toLowerCase() === "deposit" || type?.toLowerCase() === "credit";
|
|
2438
|
-
return isDeposit ? /* @__PURE__ */ jsx(ArrowDownLeft, { className: "h-4 w-4 text-green-600" }) : /* @__PURE__ */ jsx(ArrowUpRight, { className: "h-4 w-4 text-red-600" });
|
|
2439
|
-
};
|
|
2440
|
-
const handleSearch = async (value) => {
|
|
2441
|
-
setSearchTerm(value);
|
|
2442
|
-
await refreshTransactions();
|
|
2443
|
-
};
|
|
2444
|
-
const handleTypeFilter = async (type) => {
|
|
2445
|
-
setTypeFilter(type);
|
|
2446
|
-
await refreshTransactions();
|
|
2447
|
-
};
|
|
2448
|
-
const truncateId = (id) => {
|
|
2449
|
-
if (!id) return "N/A";
|
|
2450
|
-
const str = id.toString();
|
|
2451
|
-
return str.length > 8 ? `${str.slice(0, 8)}...` : str;
|
|
2452
|
-
};
|
|
2453
|
-
const filteredTransactions = transactionsList.filter((transaction) => {
|
|
2454
|
-
const matchesSearch = searchTerm ? transaction.id?.toString().toLowerCase().includes(searchTerm.toLowerCase()) || transaction.description?.toLowerCase().includes(searchTerm.toLowerCase()) || transaction.type?.toLowerCase().includes(searchTerm.toLowerCase()) : true;
|
|
2455
|
-
const matchesType = typeFilter !== "all" ? transaction.type?.toLowerCase() === typeFilter.toLowerCase() : true;
|
|
2456
|
-
return matchesSearch && matchesType;
|
|
2457
|
-
}).map((transaction) => ({
|
|
2458
|
-
...transaction,
|
|
2459
|
-
isDeposit: transaction.type?.toLowerCase() === "deposit" || transaction.type?.toLowerCase() === "credit",
|
|
2460
|
-
formattedDate: formatDate(transaction.created_at || transaction.timestamp),
|
|
2461
|
-
relativeTime: getRelativeTime(transaction.created_at || transaction.timestamp),
|
|
2462
|
-
truncatedRef: truncateId(transaction.reference || transaction.payment_id)
|
|
2463
|
-
}));
|
|
2464
|
-
if (isLoadingTransactions) {
|
|
2465
|
-
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
2466
|
-
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2", children: [
|
|
2467
|
-
/* @__PURE__ */ jsx(History, { className: "h-5 w-5" }),
|
|
2468
|
-
"Transaction History"
|
|
2469
|
-
] }) }),
|
|
2470
|
-
/* @__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: [
|
|
2471
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2472
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-32" }),
|
|
2473
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" })
|
|
2474
|
-
] }),
|
|
2475
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-16" })
|
|
2476
|
-
] }, i)) })
|
|
2477
|
-
] });
|
|
2478
|
-
}
|
|
2479
|
-
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
2480
|
-
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center justify-between", children: [
|
|
2481
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2482
|
-
/* @__PURE__ */ jsx(History, { className: "h-5 w-5" }),
|
|
2483
|
-
"Transaction History"
|
|
2484
|
-
] }),
|
|
2485
|
-
/* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: refreshTransactions, disabled: isLoadingTransactions, children: [
|
|
2486
|
-
/* @__PURE__ */ jsx(RefreshCw, { className: `h-4 w-4 mr-2 ${isLoadingTransactions ? "animate-spin" : ""}` }),
|
|
2487
|
-
"Refresh"
|
|
2488
|
-
] })
|
|
2489
|
-
] }) }),
|
|
2490
|
-
/* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
|
|
2491
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row gap-4", children: [
|
|
2492
|
-
/* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
|
|
2493
|
-
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
|
|
2494
|
-
/* @__PURE__ */ jsx(
|
|
2495
|
-
Input,
|
|
2496
|
-
{
|
|
2497
|
-
placeholder: "Search by ID, description, or type...",
|
|
2498
|
-
value: searchTerm,
|
|
2499
|
-
onChange: (e) => handleSearch(e.target.value),
|
|
2500
|
-
className: "pl-10"
|
|
2501
|
-
}
|
|
2502
|
-
)
|
|
2503
|
-
] }),
|
|
2504
|
-
/* @__PURE__ */ jsxs(Select, { value: typeFilter, onValueChange: handleTypeFilter, children: [
|
|
2505
|
-
/* @__PURE__ */ jsxs(SelectTrigger, { className: "w-full sm:w-48", children: [
|
|
2506
|
-
/* @__PURE__ */ jsx(Filter, { className: "h-4 w-4 mr-2" }),
|
|
2507
|
-
/* @__PURE__ */ jsx(SelectValue, { placeholder: "Filter by type" })
|
|
2508
|
-
] }),
|
|
2509
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
2510
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "all", children: "All Types" }),
|
|
2511
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "deposit", children: "Deposits" }),
|
|
2512
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "withdrawal", children: "Withdrawals" })
|
|
2513
|
-
] })
|
|
2514
|
-
] })
|
|
2515
|
-
] }),
|
|
2516
|
-
filteredTransactions.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-12", children: [
|
|
2517
|
-
/* @__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" }) }),
|
|
2518
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-2", children: "No Transactions Found" }),
|
|
2519
|
-
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: searchTerm || typeFilter !== "all" ? "No transactions match your current filters" : "You don't have any transactions yet" })
|
|
2520
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
2521
|
-
/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
2522
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Date & Time" }),
|
|
2523
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Type" }),
|
|
2524
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Amount" }),
|
|
2525
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Balance After" }),
|
|
2526
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Description" }),
|
|
2527
|
-
/* @__PURE__ */ jsx(TableHead, { children: "Reference" })
|
|
2528
|
-
] }) }),
|
|
2529
|
-
/* @__PURE__ */ jsx(TableBody, { children: filteredTransactions.map((transaction, index) => /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
2530
|
-
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsxs("div", { children: [
|
|
2531
|
-
/* @__PURE__ */ jsx("div", { className: "font-medium", children: transaction.formattedDate }),
|
|
2532
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: transaction.relativeTime })
|
|
2533
|
-
] }) }),
|
|
2534
|
-
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2535
|
-
getTypeIcon(transaction.type),
|
|
2536
|
-
/* @__PURE__ */ jsx(Badge, { variant: getTypeVariant(transaction.type), children: transaction.type || "Unknown" })
|
|
2537
|
-
] }) }),
|
|
2538
|
-
/* @__PURE__ */ jsx(TableCell, { className: "font-mono font-semibold", children: /* @__PURE__ */ jsxs("span", { className: transaction.isDeposit ? "text-green-600" : "text-red-600", children: [
|
|
2539
|
-
transaction.isDeposit ? "+" : "-",
|
|
2540
|
-
formatCurrency(Math.abs(transaction.amount || transaction.amount_usd || 0))
|
|
2541
|
-
] }) }),
|
|
2542
|
-
/* @__PURE__ */ jsx(TableCell, { className: "font-mono", children: formatCurrency(transaction.balance_after || 0) }),
|
|
2543
|
-
/* @__PURE__ */ jsx(TableCell, { className: "text-sm", children: transaction.description || transaction.note || "No description" }),
|
|
2544
|
-
/* @__PURE__ */ jsx(TableCell, { className: "font-mono text-sm text-muted-foreground", children: transaction.truncatedRef })
|
|
2545
|
-
] }, transaction.id || index)) })
|
|
2546
|
-
] }) })
|
|
2547
|
-
] })
|
|
2548
|
-
] });
|
|
2549
|
-
};
|
|
2550
|
-
var TransactionsView = () => {
|
|
2551
|
-
return /* @__PURE__ */ jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsx(TransactionsList, {}) });
|
|
2552
|
-
};
|
|
2553
|
-
var PaymentsLayout = () => {
|
|
2554
|
-
return /* @__PURE__ */ jsx(RootPaymentsProvider, { children: /* @__PURE__ */ jsxs("div", { className: "h-full p-6 space-y-6", children: [
|
|
2555
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2556
|
-
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "Payments" }),
|
|
2557
|
-
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "Manage your payments, balance, and transaction history" })
|
|
2558
|
-
] }),
|
|
2559
|
-
/* @__PURE__ */ jsxs(Tabs, { defaultValue: "overview", className: "space-y-6", children: [
|
|
2560
|
-
/* @__PURE__ */ jsxs(TabsList, { className: "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground", children: [
|
|
2561
|
-
/* @__PURE__ */ jsxs(TabsTrigger, { value: "overview", className: "inline-flex items-center gap-2 px-3 py-1.5", children: [
|
|
2562
|
-
/* @__PURE__ */ jsx(Wallet, { className: "h-4 w-4" }),
|
|
2563
|
-
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Overview" })
|
|
2564
|
-
] }),
|
|
2565
|
-
/* @__PURE__ */ jsxs(TabsTrigger, { value: "payments", className: "inline-flex items-center gap-2 px-3 py-1.5", children: [
|
|
2566
|
-
/* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
|
|
2567
|
-
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Payments" })
|
|
2568
|
-
] }),
|
|
2569
|
-
/* @__PURE__ */ jsxs(TabsTrigger, { value: "transactions", className: "inline-flex items-center gap-2 px-3 py-1.5", children: [
|
|
2570
|
-
/* @__PURE__ */ jsx(History, { className: "h-4 w-4" }),
|
|
2571
|
-
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Transactions" })
|
|
2572
|
-
] })
|
|
2573
|
-
] }),
|
|
2574
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "overview", className: "space-y-6", children: /* @__PURE__ */ jsx(OverviewProvider, { children: /* @__PURE__ */ jsxs(PaymentsProvider, { children: [
|
|
2575
|
-
/* @__PURE__ */ jsx(OverviewView, {}),
|
|
2576
|
-
/* @__PURE__ */ jsx(CreatePaymentDialog, {})
|
|
2577
|
-
] }) }) }),
|
|
2578
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "payments", className: "space-y-6", children: /* @__PURE__ */ jsxs(PaymentsProvider, { children: [
|
|
2579
|
-
/* @__PURE__ */ jsx(PaymentsView, {}),
|
|
2580
|
-
/* @__PURE__ */ jsx(CreatePaymentDialog, {})
|
|
2581
|
-
] }) }),
|
|
2582
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "transactions", className: "space-y-6", children: /* @__PURE__ */ jsx(OverviewProvider, { children: /* @__PURE__ */ jsx(TransactionsView, {}) }) })
|
|
2583
|
-
] }),
|
|
2584
|
-
/* @__PURE__ */ jsx(PaymentDetailsDialog, {})
|
|
2585
2489
|
] }) });
|
|
2586
|
-
}
|
|
2490
|
+
}
|
|
2491
|
+
var ResponsiveSheetContext = React2.createContext({ isMobile: false });
|
|
2492
|
+
function ResponsiveSheet4({ open, onOpenChange, children }) {
|
|
2493
|
+
const isMobile = useIsMobile();
|
|
2494
|
+
if (isMobile) {
|
|
2495
|
+
return /* @__PURE__ */ jsx(ResponsiveSheetContext.Provider, { value: { isMobile: true }, children: /* @__PURE__ */ jsx(Drawer, { open, onOpenChange, children }) });
|
|
2496
|
+
}
|
|
2497
|
+
return /* @__PURE__ */ jsx(ResponsiveSheetContext.Provider, { value: { isMobile: false }, children: /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children }) });
|
|
2498
|
+
}
|
|
2499
|
+
function ResponsiveSheetContent4({ children, className }) {
|
|
2500
|
+
const { isMobile } = React2.useContext(ResponsiveSheetContext);
|
|
2501
|
+
if (isMobile) {
|
|
2502
|
+
return /* @__PURE__ */ jsx(DrawerContent, { className, children });
|
|
2503
|
+
}
|
|
2504
|
+
return /* @__PURE__ */ jsx(DialogContent, { className, children });
|
|
2505
|
+
}
|
|
2506
|
+
function ResponsiveSheetHeader4({ children, className }) {
|
|
2507
|
+
const { isMobile } = React2.useContext(ResponsiveSheetContext);
|
|
2508
|
+
if (isMobile) {
|
|
2509
|
+
return /* @__PURE__ */ jsx(DrawerHeader, { className, children });
|
|
2510
|
+
}
|
|
2511
|
+
return /* @__PURE__ */ jsx(DialogHeader, { className, children });
|
|
2512
|
+
}
|
|
2513
|
+
function ResponsiveSheetTitle4({ children, className }) {
|
|
2514
|
+
const { isMobile } = React2.useContext(ResponsiveSheetContext);
|
|
2515
|
+
if (isMobile) {
|
|
2516
|
+
return /* @__PURE__ */ jsx(DrawerTitle, { className, children });
|
|
2517
|
+
}
|
|
2518
|
+
return /* @__PURE__ */ jsx(DialogTitle, { className, children });
|
|
2519
|
+
}
|
|
2520
|
+
function ResponsiveSheetDescription4({ children, className }) {
|
|
2521
|
+
const { isMobile } = React2.useContext(ResponsiveSheetContext);
|
|
2522
|
+
if (isMobile) {
|
|
2523
|
+
return /* @__PURE__ */ jsx(DrawerDescription, { className, children });
|
|
2524
|
+
}
|
|
2525
|
+
return /* @__PURE__ */ jsx(DialogDescription, { className, children });
|
|
2526
|
+
}
|
|
2527
|
+
function ResponsiveSheetFooter({ children, className }) {
|
|
2528
|
+
const { isMobile } = React2.useContext(ResponsiveSheetContext);
|
|
2529
|
+
if (isMobile) {
|
|
2530
|
+
return /* @__PURE__ */ jsx(DrawerFooter, { className, children });
|
|
2531
|
+
}
|
|
2532
|
+
return /* @__PURE__ */ jsx(DialogFooter, { className, children });
|
|
2533
|
+
}
|
|
2587
2534
|
|
|
2588
2535
|
// package.json
|
|
2589
2536
|
var package_default = {
|
|
2590
2537
|
name: "@djangocfg/ext-payments",
|
|
2591
|
-
version: "1.0.
|
|
2538
|
+
version: "1.0.17",
|
|
2592
2539
|
description: "Payments system extension for DjangoCFG",
|
|
2593
2540
|
keywords: [
|
|
2594
2541
|
"django",
|
|
@@ -2625,11 +2572,6 @@ var package_default = {
|
|
|
2625
2572
|
import: "./dist/index.js",
|
|
2626
2573
|
require: "./dist/index.cjs"
|
|
2627
2574
|
},
|
|
2628
|
-
"./hooks": {
|
|
2629
|
-
types: "./dist/hooks.d.ts",
|
|
2630
|
-
import: "./dist/hooks.js",
|
|
2631
|
-
require: "./dist/hooks.cjs"
|
|
2632
|
-
},
|
|
2633
2575
|
"./config": {
|
|
2634
2576
|
types: "./dist/config.d.ts",
|
|
2635
2577
|
import: "./dist/config.js",
|
|
@@ -2657,8 +2599,10 @@ var package_default = {
|
|
|
2657
2599
|
"p-retry": "^7.0.0",
|
|
2658
2600
|
react: "^19",
|
|
2659
2601
|
swr: "^2.3.7",
|
|
2660
|
-
zod: "^4.
|
|
2661
|
-
moment: "^2.30.1"
|
|
2602
|
+
zod: "^4.3.4",
|
|
2603
|
+
moment: "^2.30.1",
|
|
2604
|
+
"react-hook-form": "^7.69.0",
|
|
2605
|
+
"@hookform/resolvers": "^5.2.2"
|
|
2662
2606
|
},
|
|
2663
2607
|
devDependencies: {
|
|
2664
2608
|
"@djangocfg/api": "workspace:*",
|
|
@@ -2731,4 +2675,4 @@ export default function CryptoCheckout() {
|
|
|
2731
2675
|
]
|
|
2732
2676
|
});
|
|
2733
2677
|
|
|
2734
|
-
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,
|
|
2678
|
+
export { API, APIClient, APIError, APILogger, ActivityItem, ActivityList, AddFundsSheet, BalanceHero, BalanceSchema, CookieStorageAdapter, CurrencySchema, DEFAULT_RETRY_CONFIG, enums_exports as Enums, models_exports as ExtPaymentsPaymentsTypes, FetchAdapter, fetchers_exports as Fetchers, LocalStorageAdapter, MemoryStorageAdapter, NetworkError, PaginatedPaymentListListSchema, PaginatedWithdrawalListListSchema, PaymentCreateRequestSchema, PaymentDetailSchema, PaymentListSchema, PaymentSheet, REFRESH_TOKEN_KEY, ResponsiveSheet4 as ResponsiveSheet, ResponsiveSheetContent4 as ResponsiveSheetContent, ResponsiveSheetDescription4 as ResponsiveSheetDescription, ResponsiveSheetFooter, ResponsiveSheetHeader4 as ResponsiveSheetHeader, ResponsiveSheetTitle4 as ResponsiveSheetTitle, schemas_exports as Schemas, TOKEN_KEY, TransactionSchema, WithdrawSheet, WithdrawalCreateRequestSchema, WithdrawalDetailSchema, WithdrawalListSchema, apiPayments, clearAPITokens, configureAPI, createPaymentsPaymentsConfirmCreate, createPaymentsPaymentsCreateCreate, createPaymentsWithdrawalsCancelCreate, createPaymentsWithdrawalsCreateCreate, dispatchValidationError, extensionConfig, formatZodError, getAPIInstance, getPaymentsBalanceRetrieve, getPaymentsCurrenciesList, getPaymentsPaymentsList, getPaymentsPaymentsRetrieve, getPaymentsPaymentsStatusRetrieve, getPaymentsTransactionsList, getPaymentsWithdrawalsList, getPaymentsWithdrawalsRetrieve, isAPIConfigured, onValidationError, reconfigureAPI, resetAPI, shouldRetry, withRetry };
|