@djangocfg/ext-payments 1.0.14 → 1.0.19
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/index.cjs +1906 -1043
- package/dist/index.d.cts +644 -59
- package/dist/index.d.ts +644 -59
- package/dist/index.js +1886 -1040
- package/package.json +13 -16
- package/src/WalletPage.tsx +100 -0
- package/src/api/generated/ext_payments/CLAUDE.md +10 -4
- package/src/api/generated/ext_payments/_utils/fetchers/ext_payments__payments.ts +268 -5
- package/src/api/generated/ext_payments/_utils/hooks/ext_payments__payments.ts +102 -3
- package/src/api/generated/ext_payments/_utils/schemas/Balance.schema.ts +1 -1
- 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/PaymentCreateResponse.schema.ts +22 -0
- package/src/api/generated/ext_payments/_utils/schemas/PaymentDetail.schema.ts +3 -3
- package/src/api/generated/ext_payments/_utils/schemas/PaymentList.schema.ts +2 -2
- package/src/api/generated/ext_payments/_utils/schemas/Transaction.schema.ts +1 -1
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCancelResponse.schema.ts +22 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCreateRequest.schema.ts +21 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCreateResponse.schema.ts +22 -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 +8 -0
- package/src/api/generated/ext_payments/client.ts +1 -1
- package/src/api/generated/ext_payments/enums.ts +36 -0
- package/src/api/generated/ext_payments/ext_payments__payments/client.ts +104 -6
- package/src/api/generated/ext_payments/ext_payments__payments/models.ts +168 -8
- package/src/api/generated/ext_payments/index.ts +1 -1
- package/src/api/generated/ext_payments/schema.json +752 -42
- package/src/components/ActivityItem.tsx +118 -0
- package/src/components/ActivityList.tsx +93 -0
- package/src/components/AddFundsSheet.tsx +342 -0
- package/src/components/BalanceHero.tsx +102 -0
- package/src/components/CurrencyCombobox.tsx +49 -0
- package/src/components/PaymentSheet.tsx +352 -0
- package/src/components/WithdrawSheet.tsx +355 -0
- package/src/components/WithdrawalSheet.tsx +332 -0
- package/src/components/index.ts +11 -0
- package/src/config.ts +1 -0
- package/src/contexts/WalletContext.tsx +356 -0
- package/src/contexts/index.ts +13 -42
- package/src/contexts/types.ts +43 -37
- package/src/hooks/index.ts +3 -20
- package/src/hooks/useCurrencyOptions.ts +79 -0
- package/src/hooks/useEstimate.ts +113 -0
- package/src/hooks/useWithdrawalEstimate.ts +117 -0
- package/src/index.ts +9 -18
- package/src/types/index.ts +78 -0
- package/src/utils/errors.ts +36 -0
- package/src/utils/format.ts +65 -0
- package/src/utils/index.ts +3 -0
- 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/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.cjs
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var api = require('@djangocfg/ext-base/api');
|
|
3
5
|
var consola = require('consola');
|
|
4
6
|
var pRetry = require('p-retry');
|
|
5
7
|
var zod = require('zod');
|
|
6
|
-
var api = require('@djangocfg/ext-base/api');
|
|
7
|
-
var lucideReact = require('lucide-react');
|
|
8
|
-
var uiCore = require('@djangocfg/ui-core');
|
|
9
|
-
var react = require('react');
|
|
10
8
|
var useSWR = require('swr');
|
|
11
9
|
var jsxRuntime = require('react/jsx-runtime');
|
|
10
|
+
var lucideReact = require('lucide-react');
|
|
11
|
+
var uiCore = require('@djangocfg/ui-core');
|
|
12
|
+
var lib = require('@djangocfg/ui-core/lib');
|
|
13
|
+
var moment3 = require('moment');
|
|
12
14
|
var reactHookForm = require('react-hook-form');
|
|
13
15
|
var zod$1 = require('@hookform/resolvers/zod');
|
|
14
|
-
var moment = require('moment');
|
|
15
|
-
var components = require('@djangocfg/ui-nextjs/components');
|
|
16
16
|
var extBase = require('@djangocfg/ext-base');
|
|
17
17
|
|
|
18
18
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
19
|
|
|
20
20
|
var pRetry__default = /*#__PURE__*/_interopDefault(pRetry);
|
|
21
21
|
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
|
|
22
|
-
var
|
|
22
|
+
var moment3__default = /*#__PURE__*/_interopDefault(moment3);
|
|
23
23
|
|
|
24
24
|
var __defProp = Object.defineProperty;
|
|
25
25
|
var __export = (target, all) => {
|
|
@@ -45,12 +45,47 @@ var ExtPaymentsPayments = class {
|
|
|
45
45
|
/**
|
|
46
46
|
* Get available currencies
|
|
47
47
|
*
|
|
48
|
-
* Returns list of available currencies with token+network info
|
|
48
|
+
* Returns list of available currencies with token+network info, popular
|
|
49
|
+
* first
|
|
49
50
|
*/
|
|
50
51
|
async currenciesList() {
|
|
51
52
|
const response = await this.client.request("GET", "/cfg/payments/currencies/");
|
|
52
53
|
return response;
|
|
53
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Get currency estimate
|
|
57
|
+
*
|
|
58
|
+
* Get estimated crypto amount for a given USD amount, including min amount
|
|
59
|
+
*/
|
|
60
|
+
async currenciesEstimateRetrieve(...args) {
|
|
61
|
+
const code = args[0];
|
|
62
|
+
const isParamsObject = args.length === 2 && typeof args[1] === "object" && args[1] !== null && !Array.isArray(args[1]);
|
|
63
|
+
let params;
|
|
64
|
+
if (isParamsObject) {
|
|
65
|
+
params = args[1];
|
|
66
|
+
} else {
|
|
67
|
+
params = { amount: args[1] };
|
|
68
|
+
}
|
|
69
|
+
const response = await this.client.request("GET", `/cfg/payments/currencies/${code}/estimate/`, { params });
|
|
70
|
+
return response;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get withdrawal estimate
|
|
74
|
+
*
|
|
75
|
+
* Get estimated crypto amount for withdrawal with fee breakdown
|
|
76
|
+
*/
|
|
77
|
+
async currenciesWithdrawalEstimateRetrieve(...args) {
|
|
78
|
+
const code = args[0];
|
|
79
|
+
const isParamsObject = args.length === 2 && typeof args[1] === "object" && args[1] !== null && !Array.isArray(args[1]);
|
|
80
|
+
let params;
|
|
81
|
+
if (isParamsObject) {
|
|
82
|
+
params = args[1];
|
|
83
|
+
} else {
|
|
84
|
+
params = { amount: args[1] };
|
|
85
|
+
}
|
|
86
|
+
const response = await this.client.request("GET", `/cfg/payments/currencies/${code}/withdrawal-estimate/`, { params });
|
|
87
|
+
return response;
|
|
88
|
+
}
|
|
54
89
|
/**
|
|
55
90
|
* ViewSet for payment operations. Endpoints: - GET /payments/ - List
|
|
56
91
|
* user's payments - GET /payments/{id}/ - Get payment details - POST
|
|
@@ -97,12 +132,12 @@ var ExtPaymentsPayments = class {
|
|
|
97
132
|
return response.results || response;
|
|
98
133
|
}
|
|
99
134
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
135
|
+
* Create payment
|
|
136
|
+
*
|
|
137
|
+
* Create a new payment with specified amount and currency
|
|
103
138
|
*/
|
|
104
|
-
async paymentsCreateCreate() {
|
|
105
|
-
const response = await this.client.request("POST", "/cfg/payments/payments/create/");
|
|
139
|
+
async paymentsCreateCreate(data) {
|
|
140
|
+
const response = await this.client.request("POST", "/cfg/payments/payments/create/", { body: data });
|
|
106
141
|
return response;
|
|
107
142
|
}
|
|
108
143
|
/**
|
|
@@ -121,6 +156,51 @@ var ExtPaymentsPayments = class {
|
|
|
121
156
|
const response = await this.client.request("GET", "/cfg/payments/transactions/", { params });
|
|
122
157
|
return response;
|
|
123
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* ViewSet for withdrawal operations. Endpoints: - GET /withdrawals/ - List
|
|
161
|
+
* user's withdrawal requests - GET /withdrawals/{id}/ - Get withdrawal
|
|
162
|
+
* details - POST /withdrawals/create/ - Create withdrawal request - POST
|
|
163
|
+
* /withdrawals/{id}/cancel/ - Cancel pending withdrawal
|
|
164
|
+
*/
|
|
165
|
+
async withdrawalsList(...args) {
|
|
166
|
+
const isParamsObject = args.length === 1 && typeof args[0] === "object" && args[0] !== null && !Array.isArray(args[0]);
|
|
167
|
+
let params;
|
|
168
|
+
if (isParamsObject) {
|
|
169
|
+
params = args[0];
|
|
170
|
+
} else {
|
|
171
|
+
params = { page: args[0], page_size: args[1] };
|
|
172
|
+
}
|
|
173
|
+
const response = await this.client.request("GET", "/cfg/payments/withdrawals/", { params });
|
|
174
|
+
return response;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* ViewSet for withdrawal operations. Endpoints: - GET /withdrawals/ - List
|
|
178
|
+
* user's withdrawal requests - GET /withdrawals/{id}/ - Get withdrawal
|
|
179
|
+
* details - POST /withdrawals/create/ - Create withdrawal request - POST
|
|
180
|
+
* /withdrawals/{id}/cancel/ - Cancel pending withdrawal
|
|
181
|
+
*/
|
|
182
|
+
async withdrawalsRetrieve(id) {
|
|
183
|
+
const response = await this.client.request("GET", `/cfg/payments/withdrawals/${id}/`);
|
|
184
|
+
return response;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Cancel withdrawal request
|
|
188
|
+
*
|
|
189
|
+
* Cancel a pending withdrawal request
|
|
190
|
+
*/
|
|
191
|
+
async withdrawalsCancelCreate(id) {
|
|
192
|
+
const response = await this.client.request("POST", `/cfg/payments/withdrawals/${id}/cancel/`);
|
|
193
|
+
return response;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Create withdrawal request
|
|
197
|
+
*
|
|
198
|
+
* Create a new withdrawal request (requires admin approval)
|
|
199
|
+
*/
|
|
200
|
+
async withdrawalsCreateCreate(data) {
|
|
201
|
+
const response = await this.client.request("POST", "/cfg/payments/withdrawals/create/", { body: data });
|
|
202
|
+
return response;
|
|
203
|
+
}
|
|
124
204
|
};
|
|
125
205
|
|
|
126
206
|
// src/api/generated/ext_payments/ext_payments__payments/models.ts
|
|
@@ -799,7 +879,9 @@ var enums_exports = {};
|
|
|
799
879
|
__export(enums_exports, {
|
|
800
880
|
PaymentDetailStatus: () => PaymentDetailStatus,
|
|
801
881
|
PaymentListStatus: () => PaymentListStatus,
|
|
802
|
-
TransactionTransactionType: () => TransactionTransactionType
|
|
882
|
+
TransactionTransactionType: () => TransactionTransactionType,
|
|
883
|
+
WithdrawalDetailStatus: () => WithdrawalDetailStatus,
|
|
884
|
+
WithdrawalListStatus: () => WithdrawalListStatus
|
|
803
885
|
});
|
|
804
886
|
var PaymentDetailStatus = /* @__PURE__ */ ((PaymentDetailStatus2) => {
|
|
805
887
|
PaymentDetailStatus2["PENDING"] = "pending";
|
|
@@ -833,6 +915,24 @@ var TransactionTransactionType = /* @__PURE__ */ ((TransactionTransactionType2)
|
|
|
833
915
|
TransactionTransactionType2["ADJUSTMENT"] = "adjustment";
|
|
834
916
|
return TransactionTransactionType2;
|
|
835
917
|
})(TransactionTransactionType || {});
|
|
918
|
+
var WithdrawalDetailStatus = /* @__PURE__ */ ((WithdrawalDetailStatus2) => {
|
|
919
|
+
WithdrawalDetailStatus2["PENDING"] = "pending";
|
|
920
|
+
WithdrawalDetailStatus2["APPROVED"] = "approved";
|
|
921
|
+
WithdrawalDetailStatus2["PROCESSING"] = "processing";
|
|
922
|
+
WithdrawalDetailStatus2["COMPLETED"] = "completed";
|
|
923
|
+
WithdrawalDetailStatus2["REJECTED"] = "rejected";
|
|
924
|
+
WithdrawalDetailStatus2["CANCELLED"] = "cancelled";
|
|
925
|
+
return WithdrawalDetailStatus2;
|
|
926
|
+
})(WithdrawalDetailStatus || {});
|
|
927
|
+
var WithdrawalListStatus = /* @__PURE__ */ ((WithdrawalListStatus2) => {
|
|
928
|
+
WithdrawalListStatus2["PENDING"] = "pending";
|
|
929
|
+
WithdrawalListStatus2["APPROVED"] = "approved";
|
|
930
|
+
WithdrawalListStatus2["PROCESSING"] = "processing";
|
|
931
|
+
WithdrawalListStatus2["COMPLETED"] = "completed";
|
|
932
|
+
WithdrawalListStatus2["REJECTED"] = "rejected";
|
|
933
|
+
WithdrawalListStatus2["CANCELLED"] = "cancelled";
|
|
934
|
+
return WithdrawalListStatus2;
|
|
935
|
+
})(WithdrawalListStatus || {});
|
|
836
936
|
|
|
837
937
|
// src/api/generated/ext_payments/_utils/schemas/index.ts
|
|
838
938
|
var schemas_exports = {};
|
|
@@ -840,16 +940,24 @@ __export(schemas_exports, {
|
|
|
840
940
|
BalanceSchema: () => BalanceSchema,
|
|
841
941
|
CurrencySchema: () => CurrencySchema,
|
|
842
942
|
PaginatedPaymentListListSchema: () => PaginatedPaymentListListSchema,
|
|
943
|
+
PaginatedWithdrawalListListSchema: () => PaginatedWithdrawalListListSchema,
|
|
944
|
+
PaymentCreateRequestSchema: () => PaymentCreateRequestSchema,
|
|
945
|
+
PaymentCreateResponseSchema: () => PaymentCreateResponseSchema,
|
|
843
946
|
PaymentDetailSchema: () => PaymentDetailSchema,
|
|
844
947
|
PaymentListSchema: () => PaymentListSchema,
|
|
845
|
-
TransactionSchema: () => TransactionSchema
|
|
948
|
+
TransactionSchema: () => TransactionSchema,
|
|
949
|
+
WithdrawalCancelResponseSchema: () => WithdrawalCancelResponseSchema,
|
|
950
|
+
WithdrawalCreateRequestSchema: () => WithdrawalCreateRequestSchema,
|
|
951
|
+
WithdrawalCreateResponseSchema: () => WithdrawalCreateResponseSchema,
|
|
952
|
+
WithdrawalDetailSchema: () => WithdrawalDetailSchema,
|
|
953
|
+
WithdrawalListSchema: () => WithdrawalListSchema
|
|
846
954
|
});
|
|
847
955
|
var BalanceSchema = zod.z.object({
|
|
848
956
|
balance_usd: zod.z.string(),
|
|
849
957
|
balance_display: zod.z.string(),
|
|
850
958
|
total_deposited: zod.z.string(),
|
|
851
959
|
total_withdrawn: zod.z.string(),
|
|
852
|
-
last_transaction_at: zod.z.
|
|
960
|
+
last_transaction_at: zod.z.string().datetime({ offset: true }).nullable()
|
|
853
961
|
});
|
|
854
962
|
var CurrencySchema = zod.z.object({
|
|
855
963
|
code: zod.z.string(),
|
|
@@ -871,8 +979,8 @@ var PaymentListSchema = zod.z.object({
|
|
|
871
979
|
currency_token: zod.z.string(),
|
|
872
980
|
status: zod.z.nativeEnum(PaymentListStatus),
|
|
873
981
|
status_display: zod.z.string(),
|
|
874
|
-
created_at: zod.z.
|
|
875
|
-
completed_at: zod.z.
|
|
982
|
+
created_at: zod.z.string().datetime({ offset: true }),
|
|
983
|
+
completed_at: zod.z.string().datetime({ offset: true }).nullable()
|
|
876
984
|
});
|
|
877
985
|
|
|
878
986
|
// src/api/generated/ext_payments/_utils/schemas/PaginatedPaymentListList.schema.ts
|
|
@@ -887,6 +995,36 @@ var PaginatedPaymentListListSchema = zod.z.object({
|
|
|
887
995
|
previous_page: zod.z.int().nullable().optional(),
|
|
888
996
|
results: zod.z.array(PaymentListSchema)
|
|
889
997
|
});
|
|
998
|
+
var WithdrawalListSchema = zod.z.object({
|
|
999
|
+
id: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
1000
|
+
internal_withdrawal_id: zod.z.string(),
|
|
1001
|
+
amount_usd: zod.z.string(),
|
|
1002
|
+
final_amount_usd: zod.z.string(),
|
|
1003
|
+
currency_code: zod.z.string(),
|
|
1004
|
+
currency_token: zod.z.string(),
|
|
1005
|
+
status: zod.z.nativeEnum(WithdrawalListStatus),
|
|
1006
|
+
status_display: zod.z.string(),
|
|
1007
|
+
created_at: zod.z.string().datetime({ offset: true }),
|
|
1008
|
+
completed_at: zod.z.string().datetime({ offset: true }).nullable()
|
|
1009
|
+
});
|
|
1010
|
+
|
|
1011
|
+
// src/api/generated/ext_payments/_utils/schemas/PaginatedWithdrawalListList.schema.ts
|
|
1012
|
+
var PaginatedWithdrawalListListSchema = zod.z.object({
|
|
1013
|
+
count: zod.z.int(),
|
|
1014
|
+
page: zod.z.int(),
|
|
1015
|
+
pages: zod.z.int(),
|
|
1016
|
+
page_size: zod.z.int(),
|
|
1017
|
+
has_next: zod.z.boolean(),
|
|
1018
|
+
has_previous: zod.z.boolean(),
|
|
1019
|
+
next_page: zod.z.int().nullable().optional(),
|
|
1020
|
+
previous_page: zod.z.int().nullable().optional(),
|
|
1021
|
+
results: zod.z.array(WithdrawalListSchema)
|
|
1022
|
+
});
|
|
1023
|
+
var PaymentCreateRequestSchema = zod.z.object({
|
|
1024
|
+
amount_usd: zod.z.string(),
|
|
1025
|
+
currency_code: zod.z.string().min(1).max(20),
|
|
1026
|
+
description: zod.z.string().max(500).optional()
|
|
1027
|
+
});
|
|
890
1028
|
var PaymentDetailSchema = zod.z.object({
|
|
891
1029
|
id: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
892
1030
|
internal_payment_id: zod.z.string(),
|
|
@@ -906,14 +1044,21 @@ var PaymentDetailSchema = zod.z.object({
|
|
|
906
1044
|
transaction_hash: zod.z.string().nullable(),
|
|
907
1045
|
explorer_link: zod.z.string().nullable(),
|
|
908
1046
|
confirmations_count: zod.z.int(),
|
|
909
|
-
expires_at: zod.z.
|
|
910
|
-
completed_at: zod.z.
|
|
911
|
-
created_at: zod.z.
|
|
1047
|
+
expires_at: zod.z.string().datetime({ offset: true }).nullable(),
|
|
1048
|
+
completed_at: zod.z.string().datetime({ offset: true }).nullable(),
|
|
1049
|
+
created_at: zod.z.string().datetime({ offset: true }),
|
|
912
1050
|
is_completed: zod.z.boolean(),
|
|
913
1051
|
is_failed: zod.z.boolean(),
|
|
914
1052
|
is_expired: zod.z.boolean(),
|
|
915
1053
|
description: zod.z.string()
|
|
916
1054
|
});
|
|
1055
|
+
|
|
1056
|
+
// src/api/generated/ext_payments/_utils/schemas/PaymentCreateResponse.schema.ts
|
|
1057
|
+
var PaymentCreateResponseSchema = zod.z.object({
|
|
1058
|
+
success: zod.z.boolean(),
|
|
1059
|
+
payment: PaymentDetailSchema,
|
|
1060
|
+
qr_code_url: zod.z.union([zod.z.url(), zod.z.literal("")]).nullable()
|
|
1061
|
+
});
|
|
917
1062
|
var TransactionSchema = zod.z.object({
|
|
918
1063
|
id: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
919
1064
|
transaction_type: zod.z.nativeEnum(TransactionTransactionType),
|
|
@@ -923,7 +1068,49 @@ var TransactionSchema = zod.z.object({
|
|
|
923
1068
|
balance_after: zod.z.string(),
|
|
924
1069
|
payment_id: zod.z.string().nullable(),
|
|
925
1070
|
description: zod.z.string(),
|
|
926
|
-
created_at: zod.z.
|
|
1071
|
+
created_at: zod.z.string().datetime({ offset: true })
|
|
1072
|
+
});
|
|
1073
|
+
var WithdrawalDetailSchema = zod.z.object({
|
|
1074
|
+
id: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
1075
|
+
internal_withdrawal_id: zod.z.string(),
|
|
1076
|
+
amount_usd: zod.z.string(),
|
|
1077
|
+
currency_code: zod.z.string(),
|
|
1078
|
+
currency_name: zod.z.string(),
|
|
1079
|
+
currency_token: zod.z.string(),
|
|
1080
|
+
currency_network: zod.z.string(),
|
|
1081
|
+
wallet_address: zod.z.string(),
|
|
1082
|
+
network_fee_usd: zod.z.string(),
|
|
1083
|
+
service_fee_usd: zod.z.string(),
|
|
1084
|
+
total_fee_usd: zod.z.string(),
|
|
1085
|
+
final_amount_usd: zod.z.string(),
|
|
1086
|
+
crypto_amount: zod.z.string().nullable(),
|
|
1087
|
+
status: zod.z.nativeEnum(WithdrawalDetailStatus),
|
|
1088
|
+
status_display: zod.z.string(),
|
|
1089
|
+
transaction_hash: zod.z.string().nullable(),
|
|
1090
|
+
explorer_link: zod.z.string().nullable(),
|
|
1091
|
+
admin_notes: zod.z.string(),
|
|
1092
|
+
created_at: zod.z.string().datetime({ offset: true }),
|
|
1093
|
+
approved_at: zod.z.string().datetime({ offset: true }).nullable(),
|
|
1094
|
+
completed_at: zod.z.string().datetime({ offset: true }).nullable(),
|
|
1095
|
+
rejected_at: zod.z.string().datetime({ offset: true }).nullable(),
|
|
1096
|
+
cancelled_at: zod.z.string().datetime({ offset: true }).nullable()
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
// src/api/generated/ext_payments/_utils/schemas/WithdrawalCancelResponse.schema.ts
|
|
1100
|
+
var WithdrawalCancelResponseSchema = zod.z.object({
|
|
1101
|
+
success: zod.z.boolean(),
|
|
1102
|
+
withdrawal: WithdrawalDetailSchema,
|
|
1103
|
+
message: zod.z.string()
|
|
1104
|
+
});
|
|
1105
|
+
var WithdrawalCreateRequestSchema = zod.z.object({
|
|
1106
|
+
amount_usd: zod.z.string(),
|
|
1107
|
+
currency_code: zod.z.string().min(1).max(20),
|
|
1108
|
+
wallet_address: zod.z.string().min(1).max(255)
|
|
1109
|
+
});
|
|
1110
|
+
var WithdrawalCreateResponseSchema = zod.z.object({
|
|
1111
|
+
success: zod.z.boolean(),
|
|
1112
|
+
withdrawal: WithdrawalDetailSchema,
|
|
1113
|
+
message: zod.z.string()
|
|
927
1114
|
});
|
|
928
1115
|
|
|
929
1116
|
// src/api/generated/ext_payments/validation-events.ts
|
|
@@ -977,12 +1164,18 @@ var fetchers_exports = {};
|
|
|
977
1164
|
__export(fetchers_exports, {
|
|
978
1165
|
createPaymentsPaymentsConfirmCreate: () => createPaymentsPaymentsConfirmCreate,
|
|
979
1166
|
createPaymentsPaymentsCreateCreate: () => createPaymentsPaymentsCreateCreate,
|
|
1167
|
+
createPaymentsWithdrawalsCancelCreate: () => createPaymentsWithdrawalsCancelCreate,
|
|
1168
|
+
createPaymentsWithdrawalsCreateCreate: () => createPaymentsWithdrawalsCreateCreate,
|
|
980
1169
|
getPaymentsBalanceRetrieve: () => getPaymentsBalanceRetrieve,
|
|
1170
|
+
getPaymentsCurrenciesEstimateRetrieve: () => getPaymentsCurrenciesEstimateRetrieve,
|
|
981
1171
|
getPaymentsCurrenciesList: () => getPaymentsCurrenciesList,
|
|
1172
|
+
getPaymentsCurrenciesWithdrawalEstimateRetrieve: () => getPaymentsCurrenciesWithdrawalEstimateRetrieve,
|
|
982
1173
|
getPaymentsPaymentsList: () => getPaymentsPaymentsList,
|
|
983
1174
|
getPaymentsPaymentsRetrieve: () => getPaymentsPaymentsRetrieve,
|
|
984
1175
|
getPaymentsPaymentsStatusRetrieve: () => getPaymentsPaymentsStatusRetrieve,
|
|
985
|
-
getPaymentsTransactionsList: () => getPaymentsTransactionsList
|
|
1176
|
+
getPaymentsTransactionsList: () => getPaymentsTransactionsList,
|
|
1177
|
+
getPaymentsWithdrawalsList: () => getPaymentsWithdrawalsList,
|
|
1178
|
+
getPaymentsWithdrawalsRetrieve: () => getPaymentsWithdrawalsRetrieve
|
|
986
1179
|
});
|
|
987
1180
|
|
|
988
1181
|
// src/api/generated/ext_payments/api-instance.ts
|
|
@@ -1087,6 +1280,16 @@ async function getPaymentsCurrenciesList(client) {
|
|
|
1087
1280
|
const response = await api.ext_payments_payments.currenciesList();
|
|
1088
1281
|
return response;
|
|
1089
1282
|
}
|
|
1283
|
+
async function getPaymentsCurrenciesEstimateRetrieve(code, params, client) {
|
|
1284
|
+
const api = client || getAPIInstance();
|
|
1285
|
+
const response = await api.ext_payments_payments.currenciesEstimateRetrieve(code, params?.amount);
|
|
1286
|
+
return response;
|
|
1287
|
+
}
|
|
1288
|
+
async function getPaymentsCurrenciesWithdrawalEstimateRetrieve(code, params, client) {
|
|
1289
|
+
const api = client || getAPIInstance();
|
|
1290
|
+
const response = await api.ext_payments_payments.currenciesWithdrawalEstimateRetrieve(code, params?.amount);
|
|
1291
|
+
return response;
|
|
1292
|
+
}
|
|
1090
1293
|
async function getPaymentsPaymentsList(params, client) {
|
|
1091
1294
|
const api = client || getAPIInstance();
|
|
1092
1295
|
const response = await api.ext_payments_payments.paymentsList(params?.page, params?.page_size);
|
|
@@ -1255,11 +1458,11 @@ Method: GET`);
|
|
|
1255
1458
|
throw error;
|
|
1256
1459
|
}
|
|
1257
1460
|
}
|
|
1258
|
-
async function createPaymentsPaymentsCreateCreate(client) {
|
|
1461
|
+
async function createPaymentsPaymentsCreateCreate(data, client) {
|
|
1259
1462
|
const api = client || getAPIInstance();
|
|
1260
|
-
const response = await api.ext_payments_payments.paymentsCreateCreate();
|
|
1463
|
+
const response = await api.ext_payments_payments.paymentsCreateCreate(data);
|
|
1261
1464
|
try {
|
|
1262
|
-
return
|
|
1465
|
+
return PaymentCreateResponseSchema.parse(response);
|
|
1263
1466
|
} catch (error) {
|
|
1264
1467
|
consola.consola.error("\u274C Zod Validation Failed");
|
|
1265
1468
|
consola.consola.box(`createPaymentsPaymentsCreateCreate
|
|
@@ -1302,6 +1505,174 @@ async function getPaymentsTransactionsList(params, client) {
|
|
|
1302
1505
|
const response = await api.ext_payments_payments.transactionsList(params?.limit, params?.offset, params?.type);
|
|
1303
1506
|
return response;
|
|
1304
1507
|
}
|
|
1508
|
+
async function getPaymentsWithdrawalsList(params, client) {
|
|
1509
|
+
const api = client || getAPIInstance();
|
|
1510
|
+
const response = await api.ext_payments_payments.withdrawalsList(params?.page, params?.page_size);
|
|
1511
|
+
try {
|
|
1512
|
+
return PaginatedWithdrawalListListSchema.parse(response);
|
|
1513
|
+
} catch (error) {
|
|
1514
|
+
consola.consola.error("\u274C Zod Validation Failed");
|
|
1515
|
+
consola.consola.box(`getPaymentsWithdrawalsList
|
|
1516
|
+
Path: /cfg/payments/withdrawals/
|
|
1517
|
+
Method: GET`);
|
|
1518
|
+
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1519
|
+
consola.consola.error("Validation Issues:");
|
|
1520
|
+
error.issues.forEach((issue, index) => {
|
|
1521
|
+
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1522
|
+
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1523
|
+
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1524
|
+
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
consola.consola.error("Response data:", response);
|
|
1528
|
+
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1529
|
+
try {
|
|
1530
|
+
const event = new CustomEvent("zod-validation-error", {
|
|
1531
|
+
detail: {
|
|
1532
|
+
operation: "getPaymentsWithdrawalsList",
|
|
1533
|
+
path: "/cfg/payments/withdrawals/",
|
|
1534
|
+
method: "GET",
|
|
1535
|
+
error,
|
|
1536
|
+
response,
|
|
1537
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1538
|
+
},
|
|
1539
|
+
bubbles: true,
|
|
1540
|
+
cancelable: false
|
|
1541
|
+
});
|
|
1542
|
+
window.dispatchEvent(event);
|
|
1543
|
+
} catch (eventError) {
|
|
1544
|
+
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
throw error;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
async function getPaymentsWithdrawalsRetrieve(id, client) {
|
|
1551
|
+
const api = client || getAPIInstance();
|
|
1552
|
+
const response = await api.ext_payments_payments.withdrawalsRetrieve(id);
|
|
1553
|
+
try {
|
|
1554
|
+
return WithdrawalDetailSchema.parse(response);
|
|
1555
|
+
} catch (error) {
|
|
1556
|
+
consola.consola.error("\u274C Zod Validation Failed");
|
|
1557
|
+
consola.consola.box(`getPaymentsWithdrawalsRetrieve
|
|
1558
|
+
Path: /cfg/payments/withdrawals/{id}/
|
|
1559
|
+
Method: GET`);
|
|
1560
|
+
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1561
|
+
consola.consola.error("Validation Issues:");
|
|
1562
|
+
error.issues.forEach((issue, index) => {
|
|
1563
|
+
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1564
|
+
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1565
|
+
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1566
|
+
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1567
|
+
});
|
|
1568
|
+
}
|
|
1569
|
+
consola.consola.error("Response data:", response);
|
|
1570
|
+
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1571
|
+
try {
|
|
1572
|
+
const event = new CustomEvent("zod-validation-error", {
|
|
1573
|
+
detail: {
|
|
1574
|
+
operation: "getPaymentsWithdrawalsRetrieve",
|
|
1575
|
+
path: "/cfg/payments/withdrawals/{id}/",
|
|
1576
|
+
method: "GET",
|
|
1577
|
+
error,
|
|
1578
|
+
response,
|
|
1579
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1580
|
+
},
|
|
1581
|
+
bubbles: true,
|
|
1582
|
+
cancelable: false
|
|
1583
|
+
});
|
|
1584
|
+
window.dispatchEvent(event);
|
|
1585
|
+
} catch (eventError) {
|
|
1586
|
+
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
throw error;
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
async function createPaymentsWithdrawalsCancelCreate(id, client) {
|
|
1593
|
+
const api = client || getAPIInstance();
|
|
1594
|
+
const response = await api.ext_payments_payments.withdrawalsCancelCreate(id);
|
|
1595
|
+
try {
|
|
1596
|
+
return WithdrawalCancelResponseSchema.parse(response);
|
|
1597
|
+
} catch (error) {
|
|
1598
|
+
consola.consola.error("\u274C Zod Validation Failed");
|
|
1599
|
+
consola.consola.box(`createPaymentsWithdrawalsCancelCreate
|
|
1600
|
+
Path: /cfg/payments/withdrawals/{id}/cancel/
|
|
1601
|
+
Method: POST`);
|
|
1602
|
+
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1603
|
+
consola.consola.error("Validation Issues:");
|
|
1604
|
+
error.issues.forEach((issue, index) => {
|
|
1605
|
+
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1606
|
+
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1607
|
+
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1608
|
+
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1609
|
+
});
|
|
1610
|
+
}
|
|
1611
|
+
consola.consola.error("Response data:", response);
|
|
1612
|
+
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1613
|
+
try {
|
|
1614
|
+
const event = new CustomEvent("zod-validation-error", {
|
|
1615
|
+
detail: {
|
|
1616
|
+
operation: "createPaymentsWithdrawalsCancelCreate",
|
|
1617
|
+
path: "/cfg/payments/withdrawals/{id}/cancel/",
|
|
1618
|
+
method: "POST",
|
|
1619
|
+
error,
|
|
1620
|
+
response,
|
|
1621
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1622
|
+
},
|
|
1623
|
+
bubbles: true,
|
|
1624
|
+
cancelable: false
|
|
1625
|
+
});
|
|
1626
|
+
window.dispatchEvent(event);
|
|
1627
|
+
} catch (eventError) {
|
|
1628
|
+
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
throw error;
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
async function createPaymentsWithdrawalsCreateCreate(data, client) {
|
|
1635
|
+
const api = client || getAPIInstance();
|
|
1636
|
+
const response = await api.ext_payments_payments.withdrawalsCreateCreate(data);
|
|
1637
|
+
try {
|
|
1638
|
+
return WithdrawalCreateResponseSchema.parse(response);
|
|
1639
|
+
} catch (error) {
|
|
1640
|
+
consola.consola.error("\u274C Zod Validation Failed");
|
|
1641
|
+
consola.consola.box(`createPaymentsWithdrawalsCreateCreate
|
|
1642
|
+
Path: /cfg/payments/withdrawals/create/
|
|
1643
|
+
Method: POST`);
|
|
1644
|
+
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1645
|
+
consola.consola.error("Validation Issues:");
|
|
1646
|
+
error.issues.forEach((issue, index) => {
|
|
1647
|
+
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1648
|
+
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1649
|
+
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1650
|
+
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1651
|
+
});
|
|
1652
|
+
}
|
|
1653
|
+
consola.consola.error("Response data:", response);
|
|
1654
|
+
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1655
|
+
try {
|
|
1656
|
+
const event = new CustomEvent("zod-validation-error", {
|
|
1657
|
+
detail: {
|
|
1658
|
+
operation: "createPaymentsWithdrawalsCreateCreate",
|
|
1659
|
+
path: "/cfg/payments/withdrawals/create/",
|
|
1660
|
+
method: "POST",
|
|
1661
|
+
error,
|
|
1662
|
+
response,
|
|
1663
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1664
|
+
},
|
|
1665
|
+
bubbles: true,
|
|
1666
|
+
cancelable: false
|
|
1667
|
+
});
|
|
1668
|
+
window.dispatchEvent(event);
|
|
1669
|
+
} catch (eventError) {
|
|
1670
|
+
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
throw error;
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1305
1676
|
|
|
1306
1677
|
// src/api/generated/ext_payments/index.ts
|
|
1307
1678
|
var TOKEN_KEY = "auth_token";
|
|
@@ -1428,6 +1799,8 @@ var API = class {
|
|
|
1428
1799
|
return "./schema.json";
|
|
1429
1800
|
}
|
|
1430
1801
|
};
|
|
1802
|
+
|
|
1803
|
+
// src/api/index.ts
|
|
1431
1804
|
api.initializeExtensionAPI(configureAPI);
|
|
1432
1805
|
var apiPayments = api.createExtensionAPI(API);
|
|
1433
1806
|
function usePaymentsBalanceRetrieve(client) {
|
|
@@ -1448,24 +1821,10 @@ function usePaymentsPaymentsList(params, client) {
|
|
|
1448
1821
|
() => getPaymentsPaymentsList(params, client)
|
|
1449
1822
|
);
|
|
1450
1823
|
}
|
|
1451
|
-
function usePaymentsPaymentsRetrieve(id, client) {
|
|
1452
|
-
return useSWR__default.default(
|
|
1453
|
-
["cfg-payments-payment", id],
|
|
1454
|
-
() => getPaymentsPaymentsRetrieve(id, client)
|
|
1455
|
-
);
|
|
1456
|
-
}
|
|
1457
|
-
function useCreatePaymentsPaymentsConfirmCreate() {
|
|
1458
|
-
const { mutate } = useSWR.useSWRConfig();
|
|
1459
|
-
return async (id, client) => {
|
|
1460
|
-
const result = await createPaymentsPaymentsConfirmCreate(id, client);
|
|
1461
|
-
mutate("cfg-payments-payments-confirm");
|
|
1462
|
-
return result;
|
|
1463
|
-
};
|
|
1464
|
-
}
|
|
1465
1824
|
function useCreatePaymentsPaymentsCreateCreate() {
|
|
1466
1825
|
const { mutate } = useSWR.useSWRConfig();
|
|
1467
|
-
return async (client) => {
|
|
1468
|
-
const result = await createPaymentsPaymentsCreateCreate(client);
|
|
1826
|
+
return async (data, client) => {
|
|
1827
|
+
const result = await createPaymentsPaymentsCreateCreate(data, client);
|
|
1469
1828
|
mutate("cfg-payments-payments");
|
|
1470
1829
|
return result;
|
|
1471
1830
|
};
|
|
@@ -1476,287 +1835,1001 @@ function usePaymentsTransactionsList(params, client) {
|
|
|
1476
1835
|
() => getPaymentsTransactionsList(params, client)
|
|
1477
1836
|
);
|
|
1478
1837
|
}
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
await
|
|
1489
|
-
|
|
1490
|
-
const createPaymentMutation = useCreatePaymentsPaymentsCreateCreate();
|
|
1491
|
-
const confirmPaymentMutation = useCreatePaymentsPaymentsConfirmCreate();
|
|
1492
|
-
const getPayment = async (id) => {
|
|
1493
|
-
return getPaymentsPaymentsRetrieve(id, apiPayments);
|
|
1494
|
-
};
|
|
1495
|
-
const createPayment = async () => {
|
|
1496
|
-
const result = await createPaymentMutation(apiPayments);
|
|
1497
|
-
await refreshPayments();
|
|
1838
|
+
function usePaymentsWithdrawalsList(params, client) {
|
|
1839
|
+
return useSWR__default.default(
|
|
1840
|
+
params ? ["cfg-payments-withdrawals", params] : "cfg-payments-withdrawals",
|
|
1841
|
+
() => getPaymentsWithdrawalsList(params, client)
|
|
1842
|
+
);
|
|
1843
|
+
}
|
|
1844
|
+
function useCreatePaymentsWithdrawalsCancelCreate() {
|
|
1845
|
+
const { mutate } = useSWR.useSWRConfig();
|
|
1846
|
+
return async (id, client) => {
|
|
1847
|
+
const result = await createPaymentsWithdrawalsCancelCreate(id, client);
|
|
1848
|
+
mutate("cfg-payments-withdrawals-cancel");
|
|
1498
1849
|
return result;
|
|
1499
1850
|
};
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1851
|
+
}
|
|
1852
|
+
function useCreatePaymentsWithdrawalsCreateCreate() {
|
|
1853
|
+
const { mutate } = useSWR.useSWRConfig();
|
|
1854
|
+
return async (data, client) => {
|
|
1855
|
+
const result = await createPaymentsWithdrawalsCreateCreate(data, client);
|
|
1856
|
+
mutate("cfg-payments-withdrawals");
|
|
1503
1857
|
return result;
|
|
1504
1858
|
};
|
|
1505
|
-
const checkPaymentStatus = async (id) => {
|
|
1506
|
-
return getPaymentsPaymentsStatusRetrieve(id, apiPayments);
|
|
1507
|
-
};
|
|
1508
|
-
const value = {
|
|
1509
|
-
payments,
|
|
1510
|
-
isLoadingPayments,
|
|
1511
|
-
paymentsError,
|
|
1512
|
-
refreshPayments,
|
|
1513
|
-
getPayment,
|
|
1514
|
-
createPayment,
|
|
1515
|
-
confirmPayment,
|
|
1516
|
-
checkPaymentStatus
|
|
1517
|
-
};
|
|
1518
|
-
return /* @__PURE__ */ jsxRuntime.jsx(PaymentsContext.Provider, { value, children });
|
|
1519
|
-
}
|
|
1520
|
-
function usePaymentsContext() {
|
|
1521
|
-
const context = react.useContext(PaymentsContext);
|
|
1522
|
-
if (!context) {
|
|
1523
|
-
throw new Error("usePaymentsContext must be used within PaymentsProvider");
|
|
1524
|
-
}
|
|
1525
|
-
return context;
|
|
1526
1859
|
}
|
|
1527
|
-
react.createContext(void 0);
|
|
1528
|
-
|
|
1529
|
-
var OverviewContext = react.createContext(void 0);
|
|
1530
|
-
function OverviewProvider({ children }) {
|
|
1531
|
-
const swrConfig = {
|
|
1532
|
-
revalidateOnFocus: false,
|
|
1533
|
-
revalidateOnReconnect: false,
|
|
1534
|
-
revalidateIfStale: false
|
|
1535
|
-
};
|
|
1860
|
+
var WalletContext = react.createContext(void 0);
|
|
1861
|
+
function WalletProvider({ children }) {
|
|
1536
1862
|
const {
|
|
1537
1863
|
data: balance,
|
|
1538
|
-
error: balanceError,
|
|
1539
1864
|
isLoading: isLoadingBalance,
|
|
1540
1865
|
mutate: mutateBalance
|
|
1541
1866
|
} = usePaymentsBalanceRetrieve(apiPayments);
|
|
1542
1867
|
const {
|
|
1543
|
-
data:
|
|
1544
|
-
error: paymentsError,
|
|
1868
|
+
data: paymentsData,
|
|
1545
1869
|
isLoading: isLoadingPayments,
|
|
1546
1870
|
mutate: mutatePayments
|
|
1547
|
-
} = usePaymentsPaymentsList({}, apiPayments);
|
|
1871
|
+
} = usePaymentsPaymentsList({ page: 1, page_size: 20 }, apiPayments);
|
|
1548
1872
|
const {
|
|
1549
|
-
data:
|
|
1550
|
-
error: transactionsError,
|
|
1873
|
+
data: transactionsData,
|
|
1551
1874
|
isLoading: isLoadingTransactions,
|
|
1552
1875
|
mutate: mutateTransactions
|
|
1553
|
-
} = usePaymentsTransactionsList({}, apiPayments);
|
|
1876
|
+
} = usePaymentsTransactionsList({ limit: 20 }, apiPayments);
|
|
1877
|
+
const {
|
|
1878
|
+
data: currenciesData,
|
|
1879
|
+
isLoading: isLoadingCurrencies,
|
|
1880
|
+
mutate: mutateCurrencies
|
|
1881
|
+
} = usePaymentsCurrenciesList(apiPayments);
|
|
1882
|
+
const {
|
|
1883
|
+
data: withdrawalsData,
|
|
1884
|
+
isLoading: isLoadingWithdrawals,
|
|
1885
|
+
mutate: mutateWithdrawals
|
|
1886
|
+
} = usePaymentsWithdrawalsList({ page: 1, page_size: 20 }, apiPayments);
|
|
1554
1887
|
const createPaymentMutation = useCreatePaymentsPaymentsCreateCreate();
|
|
1555
|
-
const
|
|
1556
|
-
const
|
|
1557
|
-
const
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1888
|
+
const createWithdrawalMutation = useCreatePaymentsWithdrawalsCreateCreate();
|
|
1889
|
+
const cancelWithdrawalMutation = useCreatePaymentsWithdrawalsCancelCreate();
|
|
1890
|
+
const balanceAmount = react.useMemo(() => {
|
|
1891
|
+
if (!balance?.balance_usd) return 0;
|
|
1892
|
+
return parseFloat(balance.balance_usd) || 0;
|
|
1893
|
+
}, [balance]);
|
|
1894
|
+
const activity = react.useMemo(() => {
|
|
1895
|
+
const items = [];
|
|
1896
|
+
const payments = paymentsData?.results || [];
|
|
1897
|
+
for (const payment of payments) {
|
|
1898
|
+
items.push({
|
|
1899
|
+
id: `payment-${payment.id}`,
|
|
1900
|
+
type: "payment",
|
|
1901
|
+
amount: payment.amount_usd,
|
|
1902
|
+
amountDisplay: `+$${parseFloat(payment.amount_usd).toFixed(2)}`,
|
|
1903
|
+
currency: payment.currency_code,
|
|
1904
|
+
status: mapPaymentStatus(payment.status),
|
|
1905
|
+
statusDisplay: payment.status_display,
|
|
1906
|
+
description: `${payment.currency_code} payment`,
|
|
1907
|
+
createdAt: payment.created_at,
|
|
1908
|
+
payment
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
const withdrawals = withdrawalsData?.results || [];
|
|
1912
|
+
for (const withdrawal of withdrawals) {
|
|
1913
|
+
items.push({
|
|
1914
|
+
id: `withdrawal-${withdrawal.id}`,
|
|
1915
|
+
type: "withdrawal",
|
|
1916
|
+
amount: withdrawal.amount_usd,
|
|
1917
|
+
amountDisplay: `-$${parseFloat(withdrawal.amount_usd).toFixed(2)}`,
|
|
1918
|
+
currency: withdrawal.currency_code,
|
|
1919
|
+
status: mapWithdrawalStatus(withdrawal.status),
|
|
1920
|
+
statusDisplay: withdrawal.status_display,
|
|
1921
|
+
description: `${withdrawal.currency_code} withdrawal`,
|
|
1922
|
+
createdAt: withdrawal.created_at,
|
|
1923
|
+
withdrawal
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
const transactions = transactionsData?.results || transactionsData || [];
|
|
1927
|
+
if (Array.isArray(transactions)) {
|
|
1928
|
+
for (const tx of transactions) {
|
|
1929
|
+
if (tx.payment_id && payments.some((p) => p.id === tx.payment_id)) {
|
|
1930
|
+
continue;
|
|
1931
|
+
}
|
|
1932
|
+
const isDeposit = tx.transaction_type === "deposit";
|
|
1933
|
+
items.push({
|
|
1934
|
+
id: `tx-${tx.id}`,
|
|
1935
|
+
type: isDeposit ? "deposit" : "withdrawal",
|
|
1936
|
+
amount: tx.amount_usd,
|
|
1937
|
+
amountDisplay: `${isDeposit ? "+" : "-"}$${Math.abs(parseFloat(tx.amount_usd)).toFixed(2)}`,
|
|
1938
|
+
status: "completed",
|
|
1939
|
+
statusDisplay: "Completed",
|
|
1940
|
+
description: tx.description || tx.type_display,
|
|
1941
|
+
createdAt: tx.created_at,
|
|
1942
|
+
transaction: tx
|
|
1943
|
+
});
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
items.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
1947
|
+
return items;
|
|
1948
|
+
}, [paymentsData, withdrawalsData, transactionsData]);
|
|
1949
|
+
const currencies = react.useMemo(() => {
|
|
1950
|
+
const data = currenciesData?.currencies || currenciesData?.results || currenciesData || [];
|
|
1951
|
+
if (!Array.isArray(data)) return [];
|
|
1952
|
+
return data.filter((c) => c.is_enabled !== false).map((c) => ({
|
|
1953
|
+
code: c.code || c.currency_code || c.symbol,
|
|
1954
|
+
name: c.name || c.code,
|
|
1955
|
+
token: c.token || c.code,
|
|
1956
|
+
// Token symbol (e.g., USDT, WBTC) with fallback to code
|
|
1957
|
+
network: c.network || void 0,
|
|
1958
|
+
enabled: c.is_enabled !== false
|
|
1959
|
+
}));
|
|
1960
|
+
}, [currenciesData]);
|
|
1961
|
+
const addFunds = react.useCallback(async (data) => {
|
|
1962
|
+
const response = await createPaymentMutation(data, apiPayments);
|
|
1963
|
+
await Promise.all([mutateBalance(), mutatePayments(), mutateTransactions()]);
|
|
1964
|
+
return response.payment;
|
|
1965
|
+
}, [createPaymentMutation, mutateBalance, mutatePayments, mutateTransactions]);
|
|
1966
|
+
const withdraw = react.useCallback(async (data) => {
|
|
1967
|
+
const response = await createWithdrawalMutation(data, apiPayments);
|
|
1968
|
+
await Promise.all([mutateBalance(), mutateWithdrawals(), mutateTransactions()]);
|
|
1969
|
+
return response.withdrawal;
|
|
1970
|
+
}, [createWithdrawalMutation, mutateBalance, mutateWithdrawals, mutateTransactions]);
|
|
1971
|
+
const cancelWithdrawal = react.useCallback(async (id) => {
|
|
1972
|
+
await cancelWithdrawalMutation(id, apiPayments);
|
|
1973
|
+
await Promise.all([mutateBalance(), mutateWithdrawals(), mutateTransactions()]);
|
|
1974
|
+
}, [cancelWithdrawalMutation, mutateBalance, mutateWithdrawals, mutateTransactions]);
|
|
1975
|
+
const getPaymentDetails = react.useCallback(async (id) => {
|
|
1976
|
+
return apiPayments.ext_payments_payments.paymentsRetrieve(id);
|
|
1977
|
+
}, []);
|
|
1978
|
+
const getWithdrawalDetails = react.useCallback(async (id) => {
|
|
1979
|
+
return apiPayments.ext_payments_payments.withdrawalsRetrieve(id);
|
|
1980
|
+
}, []);
|
|
1981
|
+
const refreshWallet = react.useCallback(async () => {
|
|
1567
1982
|
await Promise.all([
|
|
1568
1983
|
mutateBalance(),
|
|
1569
1984
|
mutatePayments(),
|
|
1570
|
-
|
|
1985
|
+
mutateWithdrawals(),
|
|
1986
|
+
mutateTransactions(),
|
|
1987
|
+
mutateCurrencies()
|
|
1571
1988
|
]);
|
|
1572
|
-
};
|
|
1573
|
-
const
|
|
1574
|
-
|
|
1575
|
-
await refreshOverview();
|
|
1576
|
-
return result;
|
|
1577
|
-
};
|
|
1989
|
+
}, [mutateBalance, mutatePayments, mutateWithdrawals, mutateTransactions, mutateCurrencies]);
|
|
1990
|
+
const isLoading = isLoadingBalance || isLoadingPayments || isLoadingWithdrawals || isLoadingTransactions;
|
|
1991
|
+
const isLoadingActivity = isLoadingPayments || isLoadingWithdrawals || isLoadingTransactions;
|
|
1578
1992
|
const value = {
|
|
1579
1993
|
balance,
|
|
1994
|
+
balanceAmount,
|
|
1580
1995
|
isLoadingBalance,
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
overviewError,
|
|
1594
|
-
refreshOverview
|
|
1996
|
+
activity,
|
|
1997
|
+
isLoadingActivity,
|
|
1998
|
+
hasMoreActivity: (paymentsData?.count || 0) > 20 || (withdrawalsData?.count || 0) > 20,
|
|
1999
|
+
currencies,
|
|
2000
|
+
isLoadingCurrencies,
|
|
2001
|
+
addFunds,
|
|
2002
|
+
withdraw,
|
|
2003
|
+
cancelWithdrawal,
|
|
2004
|
+
getPaymentDetails,
|
|
2005
|
+
getWithdrawalDetails,
|
|
2006
|
+
refreshWallet,
|
|
2007
|
+
isLoading
|
|
1595
2008
|
};
|
|
1596
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2009
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WalletContext.Provider, { value, children });
|
|
1597
2010
|
}
|
|
1598
|
-
function
|
|
1599
|
-
const context = react.useContext(
|
|
2011
|
+
function useWallet() {
|
|
2012
|
+
const context = react.useContext(WalletContext);
|
|
1600
2013
|
if (!context) {
|
|
1601
|
-
throw new Error("
|
|
2014
|
+
throw new Error("useWallet must be used within WalletProvider");
|
|
1602
2015
|
}
|
|
1603
2016
|
return context;
|
|
1604
2017
|
}
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
2018
|
+
function mapPaymentStatus(status) {
|
|
2019
|
+
switch (status?.toLowerCase()) {
|
|
2020
|
+
case "completed":
|
|
2021
|
+
case "success":
|
|
2022
|
+
case "finished":
|
|
2023
|
+
return "completed";
|
|
2024
|
+
case "pending":
|
|
2025
|
+
case "waiting":
|
|
2026
|
+
return "pending";
|
|
2027
|
+
case "confirming":
|
|
2028
|
+
case "partially_paid":
|
|
2029
|
+
return "confirming";
|
|
2030
|
+
case "expired":
|
|
2031
|
+
return "expired";
|
|
2032
|
+
case "failed":
|
|
2033
|
+
case "error":
|
|
2034
|
+
case "cancelled":
|
|
2035
|
+
return "failed";
|
|
2036
|
+
default:
|
|
2037
|
+
return "pending";
|
|
2038
|
+
}
|
|
1623
2039
|
}
|
|
1624
|
-
function
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
2040
|
+
function mapWithdrawalStatus(status) {
|
|
2041
|
+
switch (status?.toLowerCase()) {
|
|
2042
|
+
case "completed":
|
|
2043
|
+
return "completed";
|
|
2044
|
+
case "pending":
|
|
2045
|
+
case "approved":
|
|
2046
|
+
return "pending";
|
|
2047
|
+
case "processing":
|
|
2048
|
+
return "confirming";
|
|
2049
|
+
case "rejected":
|
|
2050
|
+
case "cancelled":
|
|
2051
|
+
return "failed";
|
|
2052
|
+
default:
|
|
2053
|
+
return "pending";
|
|
1628
2054
|
}
|
|
1629
|
-
|
|
2055
|
+
}
|
|
2056
|
+
function BalanceHero({ onAddFunds, onWithdraw, className }) {
|
|
2057
|
+
const { balance, balanceAmount, isLoadingBalance, refreshWallet } = useWallet();
|
|
2058
|
+
const formattedBalance = new Intl.NumberFormat("en-US", {
|
|
2059
|
+
style: "currency",
|
|
2060
|
+
currency: "USD",
|
|
2061
|
+
minimumFractionDigits: 2,
|
|
2062
|
+
maximumFractionDigits: 2
|
|
2063
|
+
}).format(balanceAmount);
|
|
2064
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: lib.cn("flex flex-col items-center py-16 px-4", className), children: [
|
|
2065
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center mb-6", children: isLoadingBalance ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2066
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-12 w-48 mx-auto mb-2" }),
|
|
2067
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-4 w-24 mx-auto" })
|
|
2068
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2069
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-5xl font-bold tracking-tight tabular-nums", children: formattedBalance }),
|
|
2070
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mt-1", children: "Available Balance" })
|
|
2071
|
+
] }) }),
|
|
2072
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2073
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2074
|
+
uiCore.Button,
|
|
2075
|
+
{
|
|
2076
|
+
size: "lg",
|
|
2077
|
+
onClick: onAddFunds,
|
|
2078
|
+
className: "rounded-full px-6",
|
|
2079
|
+
children: [
|
|
2080
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-5 w-5 mr-2" }),
|
|
2081
|
+
"Add Funds"
|
|
2082
|
+
]
|
|
2083
|
+
}
|
|
2084
|
+
),
|
|
2085
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2086
|
+
uiCore.Button,
|
|
2087
|
+
{
|
|
2088
|
+
size: "lg",
|
|
2089
|
+
variant: "outline",
|
|
2090
|
+
onClick: onWithdraw,
|
|
2091
|
+
className: "rounded-full px-6",
|
|
2092
|
+
children: [
|
|
2093
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpRight, { className: "h-5 w-5 mr-2" }),
|
|
2094
|
+
"Withdraw"
|
|
2095
|
+
]
|
|
2096
|
+
}
|
|
2097
|
+
),
|
|
2098
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2099
|
+
uiCore.Button,
|
|
2100
|
+
{
|
|
2101
|
+
size: "icon",
|
|
2102
|
+
variant: "ghost",
|
|
2103
|
+
onClick: () => refreshWallet(),
|
|
2104
|
+
className: "rounded-full",
|
|
2105
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4" })
|
|
2106
|
+
}
|
|
2107
|
+
)
|
|
2108
|
+
] }),
|
|
2109
|
+
balance && !isLoadingBalance && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-6 mt-6 text-sm text-muted-foreground", children: [
|
|
2110
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
|
|
2111
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "block font-medium text-foreground", children: [
|
|
2112
|
+
"$",
|
|
2113
|
+
parseFloat(balance.total_deposited || "0").toFixed(2)
|
|
2114
|
+
] }),
|
|
2115
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total Deposited" })
|
|
2116
|
+
] }),
|
|
2117
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 w-px bg-border" }),
|
|
2118
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
|
|
2119
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "block font-medium text-foreground", children: [
|
|
2120
|
+
"$",
|
|
2121
|
+
parseFloat(balance.total_withdrawn || "0").toFixed(2)
|
|
2122
|
+
] }),
|
|
2123
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total Withdrawn" })
|
|
2124
|
+
] })
|
|
2125
|
+
] })
|
|
2126
|
+
] });
|
|
2127
|
+
}
|
|
2128
|
+
var statusConfig = {
|
|
2129
|
+
pending: {
|
|
2130
|
+
icon: lucideReact.Clock,
|
|
2131
|
+
color: "text-yellow-500",
|
|
2132
|
+
bg: "bg-yellow-500/10"
|
|
2133
|
+
},
|
|
2134
|
+
confirming: {
|
|
2135
|
+
icon: lucideReact.Loader2,
|
|
2136
|
+
color: "text-blue-500",
|
|
2137
|
+
bg: "bg-blue-500/10",
|
|
2138
|
+
animate: true
|
|
2139
|
+
},
|
|
2140
|
+
completed: {
|
|
2141
|
+
icon: lucideReact.CheckCircle2,
|
|
2142
|
+
color: "text-green-500",
|
|
2143
|
+
bg: "bg-green-500/10"
|
|
2144
|
+
},
|
|
2145
|
+
failed: {
|
|
2146
|
+
icon: lucideReact.XCircle,
|
|
2147
|
+
color: "text-red-500",
|
|
2148
|
+
bg: "bg-red-500/10"
|
|
2149
|
+
},
|
|
2150
|
+
expired: {
|
|
2151
|
+
icon: lucideReact.AlertCircle,
|
|
2152
|
+
color: "text-muted-foreground",
|
|
2153
|
+
bg: "bg-muted"
|
|
2154
|
+
}
|
|
2155
|
+
};
|
|
2156
|
+
function ActivityItem({ item, onClick }) {
|
|
2157
|
+
const config = statusConfig[item.status];
|
|
2158
|
+
const StatusIcon = config.icon;
|
|
2159
|
+
const isPositive = item.type === "payment" || item.type === "deposit";
|
|
2160
|
+
const DirectionIcon = isPositive ? lucideReact.ArrowDownLeft : lucideReact.ArrowUpRight;
|
|
2161
|
+
const relativeTime = moment3__default.default(item.createdAt).fromNow();
|
|
2162
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2163
|
+
"button",
|
|
2164
|
+
{
|
|
2165
|
+
onClick,
|
|
2166
|
+
className: lib.cn(
|
|
2167
|
+
"w-full flex items-center gap-4 p-4 rounded-xl",
|
|
2168
|
+
"cursor-pointer",
|
|
2169
|
+
"hover:bg-accent active:bg-accent/80 transition-colors",
|
|
2170
|
+
"text-left"
|
|
2171
|
+
),
|
|
2172
|
+
children: [
|
|
2173
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: lib.cn(
|
|
2174
|
+
"flex items-center justify-center w-10 h-10 rounded-full",
|
|
2175
|
+
isPositive ? "bg-green-500/10" : "bg-red-500/10"
|
|
2176
|
+
), children: item.currency ? /* @__PURE__ */ jsxRuntime.jsx(uiCore.TokenIcon, { symbol: item.currency, size: 24 }) : /* @__PURE__ */ jsxRuntime.jsx(DirectionIcon, { className: lib.cn(
|
|
2177
|
+
"h-5 w-5",
|
|
2178
|
+
isPositive ? "text-green-500" : "text-red-500"
|
|
2179
|
+
) }) }),
|
|
2180
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2181
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium truncate", children: item.description }) }),
|
|
2182
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
2183
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: relativeTime }),
|
|
2184
|
+
item.status !== "completed" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2185
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xB7" }),
|
|
2186
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: lib.cn("flex items-center gap-1", config.color), children: [
|
|
2187
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { className: lib.cn("h-3 w-3", config.animate && "animate-spin") }),
|
|
2188
|
+
item.statusDisplay
|
|
2189
|
+
] })
|
|
2190
|
+
] })
|
|
2191
|
+
] })
|
|
2192
|
+
] }),
|
|
2193
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
|
|
2194
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: lib.cn(
|
|
2195
|
+
"font-semibold tabular-nums",
|
|
2196
|
+
isPositive ? "text-green-600 dark:text-green-400" : "text-foreground"
|
|
2197
|
+
), children: item.amountDisplay }),
|
|
2198
|
+
item.status === "completed" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "h-4 w-4 text-green-500 ml-2 inline-block" })
|
|
2199
|
+
] })
|
|
2200
|
+
]
|
|
2201
|
+
}
|
|
2202
|
+
);
|
|
2203
|
+
}
|
|
2204
|
+
function ActivityList({
|
|
2205
|
+
onItemClick,
|
|
2206
|
+
onViewAll,
|
|
2207
|
+
limit = 10,
|
|
2208
|
+
className
|
|
2209
|
+
}) {
|
|
2210
|
+
const { activity, isLoadingActivity, hasMoreActivity } = useWallet();
|
|
2211
|
+
const displayedActivity = limit ? activity.slice(0, limit) : activity;
|
|
2212
|
+
if (isLoadingActivity) {
|
|
2213
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: lib.cn("space-y-2", className), children: [
|
|
2214
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-5 w-32" }) }),
|
|
2215
|
+
[1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 p-4", children: [
|
|
2216
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-10 w-10 rounded-full" }),
|
|
2217
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 space-y-2", children: [
|
|
2218
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-4 w-32" }),
|
|
2219
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-3 w-24" })
|
|
2220
|
+
] }),
|
|
2221
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-5 w-16" })
|
|
2222
|
+
] }, i))
|
|
2223
|
+
] });
|
|
2224
|
+
}
|
|
2225
|
+
if (activity.length === 0) {
|
|
2226
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: lib.cn("text-center py-12", className), children: [
|
|
2227
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex items-center justify-center w-16 h-16 rounded-full bg-muted mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-8 w-8 text-muted-foreground" }) }),
|
|
2228
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold mb-1", children: "No Activity Yet" }),
|
|
2229
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "Your transactions will appear here" })
|
|
2230
|
+
] });
|
|
2231
|
+
}
|
|
2232
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: lib.cn("pt-6", className), children: [
|
|
2233
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-2", children: [
|
|
2234
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-semibold text-lg", children: "Recent Activity" }),
|
|
2235
|
+
hasMoreActivity && onViewAll && /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { variant: "ghost", size: "sm", onClick: onViewAll, className: "text-primary", children: [
|
|
2236
|
+
"View All",
|
|
2237
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 ml-1" })
|
|
2238
|
+
] })
|
|
2239
|
+
] }),
|
|
2240
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border/50", children: displayedActivity.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2241
|
+
ActivityItem,
|
|
2242
|
+
{
|
|
2243
|
+
item,
|
|
2244
|
+
onClick: () => onItemClick?.(item)
|
|
2245
|
+
},
|
|
2246
|
+
item.id
|
|
2247
|
+
)) })
|
|
2248
|
+
] });
|
|
2249
|
+
}
|
|
2250
|
+
function useEstimate({
|
|
2251
|
+
currencyCode,
|
|
2252
|
+
amountUsd,
|
|
2253
|
+
minAmount = 0,
|
|
2254
|
+
debounceMs = 300,
|
|
2255
|
+
skip = false
|
|
2256
|
+
}) {
|
|
2257
|
+
const [estimate, setEstimate] = react.useState(null);
|
|
2258
|
+
const [isLoading, setIsLoading] = react.useState(false);
|
|
2259
|
+
const [error, setError] = react.useState(null);
|
|
2260
|
+
react.useEffect(() => {
|
|
2261
|
+
if (skip || !currencyCode || amountUsd < minAmount) {
|
|
2262
|
+
setEstimate(null);
|
|
2263
|
+
setError(null);
|
|
2264
|
+
return;
|
|
2265
|
+
}
|
|
2266
|
+
const fetchEstimate = async () => {
|
|
2267
|
+
setIsLoading(true);
|
|
2268
|
+
setError(null);
|
|
2269
|
+
try {
|
|
2270
|
+
const response = await apiPayments.ext_payments_payments.currenciesEstimateRetrieve(
|
|
2271
|
+
currencyCode,
|
|
2272
|
+
{ amount: amountUsd }
|
|
2273
|
+
);
|
|
2274
|
+
if (response?.success && response?.estimated_amount) {
|
|
2275
|
+
setEstimate({
|
|
2276
|
+
estimatedAmount: parseFloat(response.estimated_amount),
|
|
2277
|
+
usdRate: parseFloat(response.usd_rate) || 0,
|
|
2278
|
+
minAmountUsd: response.min_amount_usd ? parseFloat(response.min_amount_usd) : null,
|
|
2279
|
+
isStablecoin: response.is_stablecoin || false,
|
|
2280
|
+
// New fee fields
|
|
2281
|
+
amountToReceive: parseFloat(response.amount_to_receive) || amountUsd,
|
|
2282
|
+
serviceFeeUsd: parseFloat(response.service_fee_usd) || 0,
|
|
2283
|
+
serviceFeePercent: parseFloat(response.service_fee_percent) || 0,
|
|
2284
|
+
totalToPayUsd: parseFloat(response.total_to_pay_usd) || amountUsd
|
|
2285
|
+
});
|
|
2286
|
+
} else {
|
|
2287
|
+
setEstimate(null);
|
|
2288
|
+
}
|
|
2289
|
+
} catch (err) {
|
|
2290
|
+
console.error("Failed to fetch estimate:", err);
|
|
2291
|
+
setEstimate(null);
|
|
2292
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch estimate"));
|
|
2293
|
+
} finally {
|
|
2294
|
+
setIsLoading(false);
|
|
2295
|
+
}
|
|
2296
|
+
};
|
|
2297
|
+
const timeoutId = setTimeout(fetchEstimate, debounceMs);
|
|
2298
|
+
return () => clearTimeout(timeoutId);
|
|
2299
|
+
}, [currencyCode, amountUsd, minAmount, debounceMs, skip]);
|
|
2300
|
+
return { estimate, isLoading, error };
|
|
2301
|
+
}
|
|
2302
|
+
function useWithdrawalEstimate({
|
|
2303
|
+
currencyCode,
|
|
2304
|
+
amountUsd,
|
|
2305
|
+
minAmount = 10,
|
|
2306
|
+
debounceMs = 300,
|
|
2307
|
+
skip = false
|
|
2308
|
+
}) {
|
|
2309
|
+
const [estimate, setEstimate] = react.useState(null);
|
|
2310
|
+
const [isLoading, setIsLoading] = react.useState(false);
|
|
2311
|
+
const [error, setError] = react.useState(null);
|
|
2312
|
+
react.useEffect(() => {
|
|
2313
|
+
if (skip || !currencyCode || amountUsd < minAmount) {
|
|
2314
|
+
setEstimate(null);
|
|
2315
|
+
setError(null);
|
|
2316
|
+
return;
|
|
2317
|
+
}
|
|
2318
|
+
const fetchEstimate = async () => {
|
|
2319
|
+
setIsLoading(true);
|
|
2320
|
+
setError(null);
|
|
2321
|
+
try {
|
|
2322
|
+
const response = await apiPayments.ext_payments_payments.currenciesWithdrawalEstimateRetrieve(
|
|
2323
|
+
currencyCode,
|
|
2324
|
+
{ amount: amountUsd }
|
|
2325
|
+
);
|
|
2326
|
+
if (response?.success && response?.estimated_amount) {
|
|
2327
|
+
setEstimate({
|
|
2328
|
+
estimatedAmount: parseFloat(response.estimated_amount),
|
|
2329
|
+
usdRate: parseFloat(response.usd_rate) || 0,
|
|
2330
|
+
minAmountUsd: response.min_amount_usd ? parseFloat(response.min_amount_usd) : null,
|
|
2331
|
+
isStablecoin: response.is_stablecoin || false,
|
|
2332
|
+
// Withdrawal-specific fields
|
|
2333
|
+
amountRequested: parseFloat(response.amount_requested) || amountUsd,
|
|
2334
|
+
serviceFeeUsd: parseFloat(response.service_fee_usd) || 0,
|
|
2335
|
+
serviceFeePercent: parseFloat(response.service_fee_percent) || 0,
|
|
2336
|
+
networkFeeUsd: parseFloat(response.network_fee_usd) || 0,
|
|
2337
|
+
totalFeesUsd: parseFloat(response.total_fees_usd) || 0,
|
|
2338
|
+
amountToReceive: parseFloat(response.amount_to_receive) || 0
|
|
2339
|
+
});
|
|
2340
|
+
} else {
|
|
2341
|
+
setEstimate(null);
|
|
2342
|
+
}
|
|
2343
|
+
} catch (err) {
|
|
2344
|
+
console.error("Failed to fetch withdrawal estimate:", err);
|
|
2345
|
+
setEstimate(null);
|
|
2346
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch withdrawal estimate"));
|
|
2347
|
+
} finally {
|
|
2348
|
+
setIsLoading(false);
|
|
2349
|
+
}
|
|
2350
|
+
};
|
|
2351
|
+
const timeoutId = setTimeout(fetchEstimate, debounceMs);
|
|
2352
|
+
return () => clearTimeout(timeoutId);
|
|
2353
|
+
}, [currencyCode, amountUsd, minAmount, debounceMs, skip]);
|
|
2354
|
+
return { estimate, isLoading, error };
|
|
2355
|
+
}
|
|
2356
|
+
function useCurrencyOptions(currencies) {
|
|
2357
|
+
return react.useMemo(() => {
|
|
2358
|
+
return currencies.map((c) => ({
|
|
2359
|
+
value: c.code,
|
|
2360
|
+
label: c.name,
|
|
2361
|
+
token: c.token,
|
|
2362
|
+
network: c.network
|
|
2363
|
+
}));
|
|
2364
|
+
}, [currencies]);
|
|
2365
|
+
}
|
|
2366
|
+
function useDefaultCurrency({
|
|
2367
|
+
currencyOptions,
|
|
2368
|
+
savedCurrency,
|
|
2369
|
+
currentValue,
|
|
2370
|
+
setValue
|
|
2371
|
+
}) {
|
|
2372
|
+
react.useEffect(() => {
|
|
2373
|
+
if (currencyOptions.length > 0 && !currentValue) {
|
|
2374
|
+
const savedOption = savedCurrency && currencyOptions.find((c) => c.value === savedCurrency);
|
|
2375
|
+
if (savedOption) {
|
|
2376
|
+
setValue(savedOption.value);
|
|
2377
|
+
} else {
|
|
2378
|
+
const usdt = currencyOptions.find((c) => c.value.includes("USDT"));
|
|
2379
|
+
setValue(usdt?.value || currencyOptions[0].value);
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
}, [currencyOptions, savedCurrency, currentValue, setValue]);
|
|
2383
|
+
}
|
|
2384
|
+
function useAutoSave(value, save, validate) {
|
|
2385
|
+
const saveRef = react.useRef(save);
|
|
2386
|
+
const validateRef = react.useRef(validate);
|
|
2387
|
+
react.useEffect(() => {
|
|
2388
|
+
saveRef.current = save;
|
|
2389
|
+
validateRef.current = validate;
|
|
2390
|
+
});
|
|
2391
|
+
react.useEffect(() => {
|
|
2392
|
+
const isValid = validateRef.current ? validateRef.current(value) : Boolean(value);
|
|
2393
|
+
if (isValid) {
|
|
2394
|
+
saveRef.current(value);
|
|
2395
|
+
}
|
|
2396
|
+
}, [value]);
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
// src/utils/format.ts
|
|
2400
|
+
function formatUsdRate(rate) {
|
|
2401
|
+
if (rate >= 1) {
|
|
2402
|
+
return rate.toLocaleString(void 0, {
|
|
2403
|
+
minimumFractionDigits: 2,
|
|
2404
|
+
maximumFractionDigits: 2
|
|
2405
|
+
});
|
|
2406
|
+
} else if (rate >= 0.01) {
|
|
2407
|
+
return rate.toLocaleString(void 0, {
|
|
2408
|
+
minimumFractionDigits: 2,
|
|
2409
|
+
maximumFractionDigits: 4
|
|
2410
|
+
});
|
|
2411
|
+
} else if (rate >= 1e-4) {
|
|
2412
|
+
return rate.toLocaleString(void 0, {
|
|
2413
|
+
minimumFractionDigits: 4,
|
|
2414
|
+
maximumFractionDigits: 6
|
|
2415
|
+
});
|
|
2416
|
+
} else {
|
|
2417
|
+
return rate.toLocaleString(void 0, {
|
|
2418
|
+
minimumFractionDigits: 6,
|
|
2419
|
+
maximumFractionDigits: 8
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
function formatCryptoAmount(amount, isStablecoin) {
|
|
2424
|
+
const decimals = isStablecoin ? 2 : 8;
|
|
2425
|
+
return amount.toFixed(decimals);
|
|
2426
|
+
}
|
|
2427
|
+
function formatUsdAmount(amount, alwaysShowCents = false) {
|
|
2428
|
+
if (alwaysShowCents) {
|
|
2429
|
+
return amount.toFixed(2);
|
|
2430
|
+
}
|
|
2431
|
+
const hasCents = amount % 1 !== 0;
|
|
2432
|
+
if (hasCents) {
|
|
2433
|
+
return amount.toFixed(2);
|
|
2434
|
+
}
|
|
2435
|
+
return amount.toFixed(0);
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
// src/utils/errors.ts
|
|
2439
|
+
function extractErrorMessage(err, fallback = "An error occurred") {
|
|
2440
|
+
if (!err) return fallback;
|
|
2441
|
+
const error = err;
|
|
2442
|
+
const responseData = error.response?.data;
|
|
2443
|
+
const response = responseData || error.response;
|
|
2444
|
+
if (response) {
|
|
2445
|
+
if (typeof response.error === "string") return response.error;
|
|
2446
|
+
if (typeof response.message === "string") return response.message;
|
|
2447
|
+
if (typeof response.detail === "string") return response.detail;
|
|
2448
|
+
}
|
|
2449
|
+
if (typeof error.errorMessage === "string") return error.errorMessage;
|
|
2450
|
+
if (typeof error.message === "string") return error.message;
|
|
2451
|
+
return fallback;
|
|
1630
2452
|
}
|
|
1631
2453
|
var isDevelopment = process.env.NODE_ENV === "development";
|
|
1632
|
-
|
|
2454
|
+
consola.createConsola({
|
|
1633
2455
|
level: isDevelopment ? 4 : 1
|
|
1634
2456
|
}).withTag("ext-payments");
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
2457
|
+
function CurrencyCombobox({
|
|
2458
|
+
options,
|
|
2459
|
+
value,
|
|
2460
|
+
onChange,
|
|
2461
|
+
disabled,
|
|
2462
|
+
placeholder = "Select currency..."
|
|
2463
|
+
}) {
|
|
2464
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2465
|
+
uiCore.Combobox,
|
|
2466
|
+
{
|
|
2467
|
+
options,
|
|
2468
|
+
value,
|
|
2469
|
+
onValueChange: onChange,
|
|
2470
|
+
placeholder,
|
|
2471
|
+
searchPlaceholder: "Search...",
|
|
2472
|
+
disabled,
|
|
2473
|
+
className: "h-14",
|
|
2474
|
+
renderOption: (option) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-1", children: [
|
|
2475
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TokenIcon, { symbol: option.value, size: 24 }),
|
|
2476
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: option.label })
|
|
2477
|
+
] }),
|
|
2478
|
+
renderValue: (option) => option && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2479
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TokenIcon, { symbol: option.value, size: 24 }),
|
|
2480
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: option.label })
|
|
2481
|
+
] })
|
|
2482
|
+
}
|
|
1651
2483
|
);
|
|
1652
|
-
}
|
|
1653
|
-
var
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
var PaymentCreateSchema = zod.z.object({
|
|
1657
|
-
amount_usd: zod.z.number().min(0.01, "Amount must be at least $0.01"),
|
|
1658
|
-
currency_code: zod.z.string().min(1, "Please select a currency")
|
|
2484
|
+
}
|
|
2485
|
+
var AddFundsSchema = zod.z.object({
|
|
2486
|
+
amount: zod.z.number().min(1, "Minimum $1"),
|
|
2487
|
+
currency: zod.z.string().min(1, "Select a currency")
|
|
1659
2488
|
});
|
|
1660
|
-
var
|
|
1661
|
-
|
|
2489
|
+
var STORAGE_KEY = "payments:addFunds";
|
|
2490
|
+
function AddFundsSheet({ open, onOpenChange, onSuccess }) {
|
|
2491
|
+
const { currencies, isLoadingCurrencies, addFunds } = useWallet();
|
|
1662
2492
|
const [isSubmitting, setIsSubmitting] = react.useState(false);
|
|
1663
|
-
const
|
|
1664
|
-
const
|
|
2493
|
+
const [error, setError] = react.useState(null);
|
|
2494
|
+
const [saved, setSaved] = uiCore.useLocalStorage(STORAGE_KEY, {
|
|
2495
|
+
currency: "",
|
|
2496
|
+
amount: 100
|
|
2497
|
+
});
|
|
1665
2498
|
const form = reactHookForm.useForm({
|
|
1666
|
-
resolver: zod$1.zodResolver(
|
|
2499
|
+
resolver: zod$1.zodResolver(AddFundsSchema),
|
|
1667
2500
|
defaultValues: {
|
|
1668
|
-
|
|
1669
|
-
|
|
2501
|
+
amount: saved.amount,
|
|
2502
|
+
currency: saved.currency
|
|
1670
2503
|
}
|
|
1671
2504
|
});
|
|
1672
|
-
const
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
const currencyOptions =
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
const
|
|
2505
|
+
const watchedAmount = form.watch("amount");
|
|
2506
|
+
const watchedCurrency = form.watch("currency");
|
|
2507
|
+
useAutoSave(watchedAmount, (v) => setSaved((prev) => ({ ...prev, amount: v })), (v) => v > 0);
|
|
2508
|
+
useAutoSave(watchedCurrency, (v) => setSaved((prev) => ({ ...prev, currency: v })));
|
|
2509
|
+
const currencyOptions = useCurrencyOptions(currencies);
|
|
2510
|
+
useDefaultCurrency({
|
|
2511
|
+
currencyOptions,
|
|
2512
|
+
savedCurrency: saved.currency,
|
|
2513
|
+
currentValue: watchedCurrency,
|
|
2514
|
+
setValue: (v) => form.setValue("currency", v)
|
|
2515
|
+
});
|
|
2516
|
+
const { estimate, isLoading: isLoadingEstimate } = useEstimate({
|
|
2517
|
+
currencyCode: watchedCurrency,
|
|
2518
|
+
amountUsd: watchedAmount,
|
|
2519
|
+
minAmount: 1
|
|
2520
|
+
});
|
|
2521
|
+
const selectedCurrency = currencyOptions.find((c) => c.value === watchedCurrency);
|
|
2522
|
+
const displayData = react.useMemo(() => {
|
|
2523
|
+
if (!selectedCurrency || !estimate) return null;
|
|
2524
|
+
const token = selectedCurrency.token;
|
|
2525
|
+
const cryptoAmount = formatCryptoAmount(estimate.estimatedAmount, estimate.isStablecoin);
|
|
2526
|
+
const rate = formatUsdRate(estimate.usdRate);
|
|
2527
|
+
const belowMinimum = estimate.minAmountUsd ? watchedAmount < estimate.minAmountUsd : false;
|
|
2528
|
+
const minAmount = estimate.minAmountUsd ? formatUsdAmount(estimate.minAmountUsd) : void 0;
|
|
1692
2529
|
return {
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
rate
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
return () => {
|
|
1705
|
-
window.removeEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
|
|
1706
|
-
window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
2530
|
+
token,
|
|
2531
|
+
cryptoAmount,
|
|
2532
|
+
rate,
|
|
2533
|
+
showRate: !estimate.isStablecoin && estimate.usdRate > 0,
|
|
2534
|
+
belowMinimum,
|
|
2535
|
+
minAmount,
|
|
2536
|
+
// Fee breakdown from API
|
|
2537
|
+
amountToReceive: estimate.amountToReceive,
|
|
2538
|
+
serviceFeeUsd: estimate.serviceFeeUsd,
|
|
2539
|
+
serviceFeePercent: estimate.serviceFeePercent,
|
|
2540
|
+
totalToPayUsd: estimate.totalToPayUsd
|
|
1707
2541
|
};
|
|
1708
|
-
}, []);
|
|
1709
|
-
const
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
2542
|
+
}, [selectedCurrency, estimate, watchedAmount]);
|
|
2543
|
+
const handleSubmit = react.useCallback(async (data) => {
|
|
2544
|
+
try {
|
|
2545
|
+
setIsSubmitting(true);
|
|
2546
|
+
setError(null);
|
|
2547
|
+
const result = await addFunds({
|
|
2548
|
+
amount_usd: String(data.amount),
|
|
2549
|
+
currency_code: data.currency
|
|
2550
|
+
});
|
|
2551
|
+
form.reset();
|
|
2552
|
+
onOpenChange(false);
|
|
2553
|
+
onSuccess?.(result);
|
|
2554
|
+
} catch (err) {
|
|
2555
|
+
setError(extractErrorMessage(err, "Failed to create payment"));
|
|
2556
|
+
} finally {
|
|
2557
|
+
setIsSubmitting(false);
|
|
2558
|
+
}
|
|
2559
|
+
}, [addFunds, form, onOpenChange, onSuccess]);
|
|
2560
|
+
const handleOpenChange = react.useCallback((open2) => {
|
|
2561
|
+
if (open2) {
|
|
2562
|
+
form.reset({
|
|
2563
|
+
amount: saved.amount,
|
|
2564
|
+
currency: saved.currency
|
|
2565
|
+
});
|
|
2566
|
+
} else {
|
|
2567
|
+
setError(null);
|
|
1716
2568
|
}
|
|
1717
|
-
|
|
1718
|
-
|
|
2569
|
+
onOpenChange(open2);
|
|
2570
|
+
}, [form, onOpenChange, saved]);
|
|
2571
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheet, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResponsiveSheetContent, { className: "sm:max-w-md", children: [
|
|
2572
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResponsiveSheetHeader, { children: [
|
|
2573
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheetTitle, { children: "Add Funds" }),
|
|
2574
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheetDescription, { children: "Add funds to your wallet using cryptocurrency" })
|
|
2575
|
+
] }),
|
|
2576
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: form.handleSubmit(handleSubmit), className: "space-y-6 p-4 sm:p-0 sm:mt-4", children: [
|
|
2577
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2578
|
+
uiCore.FormField,
|
|
2579
|
+
{
|
|
2580
|
+
control: form.control,
|
|
2581
|
+
name: "amount",
|
|
2582
|
+
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.FormItem, { children: [
|
|
2583
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "Amount (USD)" }),
|
|
2584
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
2585
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-muted-foreground text-lg", children: "$" }),
|
|
2586
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2587
|
+
uiCore.Input,
|
|
2588
|
+
{
|
|
2589
|
+
type: "number",
|
|
2590
|
+
step: "0.01",
|
|
2591
|
+
min: "1",
|
|
2592
|
+
placeholder: "100",
|
|
2593
|
+
className: "pl-8 text-2xl h-14 font-semibold",
|
|
2594
|
+
...field,
|
|
2595
|
+
onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
|
|
2596
|
+
}
|
|
2597
|
+
)
|
|
2598
|
+
] }) }),
|
|
2599
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormMessage, {})
|
|
2600
|
+
] })
|
|
2601
|
+
}
|
|
2602
|
+
),
|
|
2603
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2604
|
+
uiCore.FormField,
|
|
2605
|
+
{
|
|
2606
|
+
control: form.control,
|
|
2607
|
+
name: "currency",
|
|
2608
|
+
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.FormItem, { children: [
|
|
2609
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "Pay with" }),
|
|
2610
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2611
|
+
CurrencyCombobox,
|
|
2612
|
+
{
|
|
2613
|
+
options: currencyOptions,
|
|
2614
|
+
value: field.value,
|
|
2615
|
+
onChange: field.onChange,
|
|
2616
|
+
disabled: isLoadingCurrencies
|
|
2617
|
+
}
|
|
2618
|
+
) }),
|
|
2619
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormMessage, {})
|
|
2620
|
+
] })
|
|
2621
|
+
}
|
|
2622
|
+
),
|
|
2623
|
+
selectedCurrency && watchedAmount >= 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted rounded-xl p-4 space-y-2", children: isLoadingEstimate ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center py-2", children: [
|
|
2624
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-5 w-5 animate-spin text-muted-foreground" }),
|
|
2625
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 text-sm text-muted-foreground", children: "Getting rate..." })
|
|
2626
|
+
] }) : displayData ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2627
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2628
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Amount" }),
|
|
2629
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2630
|
+
"$",
|
|
2631
|
+
formatUsdAmount(displayData.amountToReceive)
|
|
2632
|
+
] })
|
|
2633
|
+
] }),
|
|
2634
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2635
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
|
|
2636
|
+
"Service fee (",
|
|
2637
|
+
displayData.serviceFeePercent,
|
|
2638
|
+
"%)"
|
|
2639
|
+
] }),
|
|
2640
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2641
|
+
"+$",
|
|
2642
|
+
formatUsdAmount(displayData.serviceFeeUsd)
|
|
2643
|
+
] })
|
|
2644
|
+
] }),
|
|
2645
|
+
displayData.showRate && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm text-muted-foreground", children: [
|
|
2646
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Rate" }),
|
|
2647
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2648
|
+
"1 ",
|
|
2649
|
+
displayData.token,
|
|
2650
|
+
" = $",
|
|
2651
|
+
displayData.rate
|
|
2652
|
+
] })
|
|
2653
|
+
] }),
|
|
2654
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t pt-2 mt-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2655
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "You will send" }),
|
|
2656
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
|
|
2657
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 justify-end", children: [
|
|
2658
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TokenIcon, { symbol: displayData.token, size: 20 }),
|
|
2659
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono font-semibold text-lg", children: [
|
|
2660
|
+
displayData.cryptoAmount,
|
|
2661
|
+
" ",
|
|
2662
|
+
displayData.token
|
|
2663
|
+
] })
|
|
2664
|
+
] }),
|
|
2665
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-muted-foreground", children: [
|
|
2666
|
+
"~$",
|
|
2667
|
+
formatUsdAmount(displayData.totalToPayUsd)
|
|
2668
|
+
] })
|
|
2669
|
+
] })
|
|
2670
|
+
] }) }),
|
|
2671
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm pt-2", children: [
|
|
2672
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "You will receive" }),
|
|
2673
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
2674
|
+
"$",
|
|
2675
|
+
formatUsdAmount(displayData.amountToReceive)
|
|
2676
|
+
] })
|
|
2677
|
+
] }),
|
|
2678
|
+
displayData.belowMinimum && displayData.minAmount && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-destructive mt-2 pt-2 border-t border-destructive/20", children: [
|
|
2679
|
+
"Minimum amount: $",
|
|
2680
|
+
displayData.minAmount
|
|
2681
|
+
] })
|
|
2682
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center text-sm text-muted-foreground py-2", children: "Enter amount to see conversion" }) }),
|
|
2683
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(uiCore.Alert, { variant: "destructive", children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.AlertDescription, { children: error }) }),
|
|
2684
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2685
|
+
uiCore.Button,
|
|
2686
|
+
{
|
|
2687
|
+
type: "submit",
|
|
2688
|
+
size: "lg",
|
|
2689
|
+
className: "w-full h-14 text-lg rounded-xl",
|
|
2690
|
+
disabled: isSubmitting || currencyOptions.length === 0 || isLoadingEstimate || displayData?.belowMinimum,
|
|
2691
|
+
children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2692
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-5 w-5 mr-2 animate-spin" }),
|
|
2693
|
+
"Creating..."
|
|
2694
|
+
] }) : "Continue"
|
|
2695
|
+
}
|
|
2696
|
+
)
|
|
2697
|
+
] }) })
|
|
2698
|
+
] }) });
|
|
2699
|
+
}
|
|
2700
|
+
var WithdrawSchema = zod.z.object({
|
|
2701
|
+
amount: zod.z.number().min(10, "Minimum $10"),
|
|
2702
|
+
currency: zod.z.string().min(1, "Select a currency"),
|
|
2703
|
+
wallet_address: zod.z.string().min(26, "Invalid wallet address")
|
|
2704
|
+
});
|
|
2705
|
+
var STORAGE_KEY2 = "payments:withdraw";
|
|
2706
|
+
function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
2707
|
+
const { currencies, isLoadingCurrencies, withdraw, balanceAmount } = useWallet();
|
|
2708
|
+
const [isSubmitting, setIsSubmitting] = react.useState(false);
|
|
2709
|
+
const [error, setError] = react.useState(null);
|
|
2710
|
+
const [saved, setSaved] = uiCore.useLocalStorage(STORAGE_KEY2, {
|
|
2711
|
+
currency: "",
|
|
2712
|
+
wallet: ""
|
|
2713
|
+
});
|
|
2714
|
+
const form = reactHookForm.useForm({
|
|
2715
|
+
resolver: zod$1.zodResolver(WithdrawSchema),
|
|
2716
|
+
defaultValues: {
|
|
2717
|
+
amount: 10,
|
|
2718
|
+
currency: saved.currency,
|
|
2719
|
+
wallet_address: saved.wallet
|
|
2720
|
+
}
|
|
2721
|
+
});
|
|
2722
|
+
const watchedAmount = form.watch("amount");
|
|
2723
|
+
const watchedCurrency = form.watch("currency");
|
|
2724
|
+
const watchedWallet = form.watch("wallet_address");
|
|
2725
|
+
useAutoSave(watchedCurrency, (v) => setSaved((prev) => ({ ...prev, currency: v })));
|
|
2726
|
+
useAutoSave(watchedWallet, (v) => setSaved((prev) => ({ ...prev, wallet: v })), (v) => v.length >= 26);
|
|
2727
|
+
const currencyOptions = useCurrencyOptions(currencies);
|
|
2728
|
+
useDefaultCurrency({
|
|
2729
|
+
currencyOptions,
|
|
2730
|
+
savedCurrency: saved.currency,
|
|
2731
|
+
currentValue: watchedCurrency,
|
|
2732
|
+
setValue: (v) => form.setValue("currency", v)
|
|
2733
|
+
});
|
|
2734
|
+
const selectedCurrency = currencyOptions.find((c) => c.value === watchedCurrency);
|
|
2735
|
+
const amount = watchedAmount || 0;
|
|
2736
|
+
const { estimate, isLoading: isLoadingEstimate } = useWithdrawalEstimate({
|
|
2737
|
+
currencyCode: watchedCurrency,
|
|
2738
|
+
amountUsd: amount,
|
|
2739
|
+
minAmount: 10,
|
|
2740
|
+
skip: amount < 10
|
|
2741
|
+
});
|
|
2742
|
+
const cryptoDisplay = react.useMemo(() => {
|
|
2743
|
+
if (!selectedCurrency || !estimate) return null;
|
|
2744
|
+
return {
|
|
2745
|
+
token: selectedCurrency.token,
|
|
2746
|
+
cryptoAmount: formatCryptoAmount(estimate.estimatedAmount, estimate.isStablecoin)
|
|
2747
|
+
};
|
|
2748
|
+
}, [selectedCurrency, estimate]);
|
|
2749
|
+
const insufficientBalance = amount > balanceAmount;
|
|
2750
|
+
const handleSubmit = react.useCallback(async (data) => {
|
|
1719
2751
|
try {
|
|
1720
2752
|
setIsSubmitting(true);
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
2753
|
+
setError(null);
|
|
2754
|
+
const result = await withdraw({
|
|
2755
|
+
amount_usd: String(data.amount),
|
|
2756
|
+
currency_code: data.currency,
|
|
2757
|
+
wallet_address: data.wallet_address
|
|
2758
|
+
});
|
|
2759
|
+
form.reset();
|
|
2760
|
+
onOpenChange(false);
|
|
2761
|
+
onSuccess?.(result);
|
|
2762
|
+
} catch (err) {
|
|
2763
|
+
setError(extractErrorMessage(err, "Failed to create withdrawal request"));
|
|
1731
2764
|
} finally {
|
|
1732
2765
|
setIsSubmitting(false);
|
|
1733
2766
|
}
|
|
1734
|
-
};
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
2767
|
+
}, [withdraw, form, onOpenChange, onSuccess]);
|
|
2768
|
+
const handleOpenChange = react.useCallback((open2) => {
|
|
2769
|
+
if (open2) {
|
|
2770
|
+
form.reset({
|
|
2771
|
+
amount: 10,
|
|
2772
|
+
currency: saved.currency,
|
|
2773
|
+
wallet_address: saved.wallet
|
|
2774
|
+
});
|
|
2775
|
+
} else {
|
|
2776
|
+
setError(null);
|
|
2777
|
+
}
|
|
2778
|
+
onOpenChange(open2);
|
|
2779
|
+
}, [form, onOpenChange, saved]);
|
|
2780
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheet, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResponsiveSheetContent, { className: "sm:max-w-md", children: [
|
|
2781
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResponsiveSheetHeader, { children: [
|
|
2782
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheetTitle, { children: "Withdraw" }),
|
|
2783
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheetDescription, { children: "Withdraw funds to your cryptocurrency wallet" })
|
|
1739
2784
|
] }),
|
|
1740
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: form.handleSubmit(handleSubmit), className: "space-y-4", children: [
|
|
2785
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: form.handleSubmit(handleSubmit), className: "space-y-6 p-4 sm:p-0 sm:mt-4", children: [
|
|
1741
2786
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1742
2787
|
uiCore.FormField,
|
|
1743
2788
|
{
|
|
1744
2789
|
control: form.control,
|
|
1745
|
-
name: "
|
|
2790
|
+
name: "amount",
|
|
1746
2791
|
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.FormItem, { children: [
|
|
1747
2792
|
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "Amount (USD)" }),
|
|
2793
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
2794
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-muted-foreground text-lg", children: "$" }),
|
|
2795
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2796
|
+
uiCore.Input,
|
|
2797
|
+
{
|
|
2798
|
+
type: "number",
|
|
2799
|
+
step: "0.01",
|
|
2800
|
+
min: "10",
|
|
2801
|
+
placeholder: "10",
|
|
2802
|
+
className: "pl-8 text-2xl h-14 font-semibold",
|
|
2803
|
+
...field,
|
|
2804
|
+
onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
|
|
2805
|
+
}
|
|
2806
|
+
)
|
|
2807
|
+
] }) }),
|
|
2808
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormMessage, {}),
|
|
2809
|
+
insufficientBalance && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-destructive mt-1", children: [
|
|
2810
|
+
"Insufficient balance (Available: $",
|
|
2811
|
+
formatUsdAmount(balanceAmount),
|
|
2812
|
+
")"
|
|
2813
|
+
] })
|
|
2814
|
+
] })
|
|
2815
|
+
}
|
|
2816
|
+
),
|
|
2817
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2818
|
+
uiCore.FormField,
|
|
2819
|
+
{
|
|
2820
|
+
control: form.control,
|
|
2821
|
+
name: "currency",
|
|
2822
|
+
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.FormItem, { children: [
|
|
2823
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "Withdraw as" }),
|
|
1748
2824
|
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1749
|
-
|
|
2825
|
+
CurrencyCombobox,
|
|
1750
2826
|
{
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
...field,
|
|
1756
|
-
onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
|
|
2827
|
+
options: currencyOptions,
|
|
2828
|
+
value: field.value,
|
|
2829
|
+
onChange: field.onChange,
|
|
2830
|
+
disabled: isLoadingCurrencies
|
|
1757
2831
|
}
|
|
1758
2832
|
) }),
|
|
1759
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormDescription, { children: "The amount you want to pay in USD." }),
|
|
1760
2833
|
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormMessage, {})
|
|
1761
2834
|
] })
|
|
1762
2835
|
}
|
|
@@ -1765,122 +2838,366 @@ var CreatePaymentDialog = () => {
|
|
|
1765
2838
|
uiCore.FormField,
|
|
1766
2839
|
{
|
|
1767
2840
|
control: form.control,
|
|
1768
|
-
name: "
|
|
2841
|
+
name: "wallet_address",
|
|
1769
2842
|
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.FormItem, { children: [
|
|
1770
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "
|
|
1771
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1772
|
-
uiCore.
|
|
2843
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "Wallet Address" }),
|
|
2844
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2845
|
+
uiCore.Input,
|
|
1773
2846
|
{
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
children: [
|
|
1778
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.SelectValue, { placeholder: "Select currency..." }) }) }),
|
|
1779
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.SelectContent, { children: currencyOptions.map((curr) => /* @__PURE__ */ jsxRuntime.jsx(uiCore.SelectItem, { value: curr.code, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1780
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TokenIcon, { symbol: curr.code, size: 16 }),
|
|
1781
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: curr.code }),
|
|
1782
|
-
curr.network && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
1783
|
-
"(",
|
|
1784
|
-
curr.network,
|
|
1785
|
-
")"
|
|
1786
|
-
] })
|
|
1787
|
-
] }) }, curr.code)) })
|
|
1788
|
-
]
|
|
2847
|
+
placeholder: "Enter your wallet address",
|
|
2848
|
+
className: "font-mono text-sm",
|
|
2849
|
+
...field
|
|
1789
2850
|
}
|
|
1790
|
-
),
|
|
1791
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormDescription, { children: "The cryptocurrency to use for payment." }),
|
|
2851
|
+
) }),
|
|
1792
2852
|
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormMessage, {})
|
|
1793
2853
|
] })
|
|
1794
2854
|
}
|
|
1795
2855
|
),
|
|
1796
|
-
|
|
1797
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1798
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
1799
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
2856
|
+
amount >= 10 && selectedCurrency && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted rounded-xl p-4 space-y-2", children: [
|
|
2857
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2858
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Amount" }),
|
|
2859
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2860
|
+
"$",
|
|
2861
|
+
formatUsdAmount(amount)
|
|
2862
|
+
] })
|
|
2863
|
+
] }),
|
|
2864
|
+
isLoadingEstimate ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground py-2", children: [
|
|
2865
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
2866
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Calculating fees..." })
|
|
2867
|
+
] }) : estimate ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2868
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2869
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
|
|
2870
|
+
"Service fee (",
|
|
2871
|
+
estimate.serviceFeePercent,
|
|
2872
|
+
"%)"
|
|
2873
|
+
] }),
|
|
2874
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-destructive", children: [
|
|
2875
|
+
"-$",
|
|
2876
|
+
formatUsdAmount(estimate.serviceFeeUsd)
|
|
2877
|
+
] })
|
|
2878
|
+
] }),
|
|
2879
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2880
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Network fee" }),
|
|
2881
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-destructive", children: [
|
|
2882
|
+
"-$",
|
|
2883
|
+
formatUsdAmount(estimate.networkFeeUsd)
|
|
2884
|
+
] })
|
|
2885
|
+
] }),
|
|
2886
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t pt-2 mt-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2887
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "You will receive" }),
|
|
2888
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
|
|
2889
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-semibold", children: [
|
|
2890
|
+
"$",
|
|
2891
|
+
formatUsdAmount(estimate.amountToReceive)
|
|
2892
|
+
] }),
|
|
2893
|
+
cryptoDisplay && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
2894
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TokenIcon, { symbol: cryptoDisplay.token, size: 16 }),
|
|
2895
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
|
|
2896
|
+
cryptoDisplay.cryptoAmount,
|
|
2897
|
+
" ",
|
|
2898
|
+
cryptoDisplay.token
|
|
2899
|
+
] })
|
|
2900
|
+
] })
|
|
2901
|
+
] })
|
|
2902
|
+
] }) })
|
|
2903
|
+
] }) : null
|
|
2904
|
+
] }),
|
|
2905
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Alert, { children: [
|
|
2906
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "h-4 w-4" }),
|
|
2907
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.AlertDescription, { children: "Withdrawal requests require admin approval. Processing may take 24-48 hours." })
|
|
2908
|
+
] }),
|
|
2909
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(uiCore.Alert, { variant: "destructive", children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.AlertDescription, { children: error }) }),
|
|
2910
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2911
|
+
uiCore.Button,
|
|
2912
|
+
{
|
|
2913
|
+
type: "submit",
|
|
2914
|
+
size: "lg",
|
|
2915
|
+
className: "w-full h-14 text-lg rounded-xl",
|
|
2916
|
+
disabled: isSubmitting || currencyOptions.length === 0 || insufficientBalance || !estimate || estimate.amountToReceive <= 0 || isLoadingEstimate,
|
|
2917
|
+
children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2918
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-5 w-5 mr-2 animate-spin" }),
|
|
2919
|
+
"Submitting..."
|
|
2920
|
+
] }) : "Request Withdrawal"
|
|
2921
|
+
}
|
|
2922
|
+
)
|
|
2923
|
+
] }) })
|
|
2924
|
+
] }) });
|
|
2925
|
+
}
|
|
2926
|
+
var statusConfig2 = {
|
|
2927
|
+
pending: {
|
|
2928
|
+
icon: lucideReact.Clock,
|
|
2929
|
+
color: "text-yellow-500",
|
|
2930
|
+
bg: "bg-yellow-500/10",
|
|
2931
|
+
label: "Pending Approval"
|
|
2932
|
+
},
|
|
2933
|
+
approved: {
|
|
2934
|
+
icon: lucideReact.CheckCircle2,
|
|
2935
|
+
color: "text-blue-500",
|
|
2936
|
+
bg: "bg-blue-500/10",
|
|
2937
|
+
label: "Approved"
|
|
2938
|
+
},
|
|
2939
|
+
processing: {
|
|
2940
|
+
icon: lucideReact.RefreshCw,
|
|
2941
|
+
color: "text-blue-500",
|
|
2942
|
+
bg: "bg-blue-500/10",
|
|
2943
|
+
label: "Processing",
|
|
2944
|
+
animate: true
|
|
2945
|
+
},
|
|
2946
|
+
completed: {
|
|
2947
|
+
icon: lucideReact.CheckCircle2,
|
|
2948
|
+
color: "text-green-500",
|
|
2949
|
+
bg: "bg-green-500/10",
|
|
2950
|
+
label: "Completed"
|
|
2951
|
+
},
|
|
2952
|
+
rejected: {
|
|
2953
|
+
icon: lucideReact.XCircle,
|
|
2954
|
+
color: "text-red-500",
|
|
2955
|
+
bg: "bg-red-500/10",
|
|
2956
|
+
label: "Rejected"
|
|
2957
|
+
},
|
|
2958
|
+
cancelled: {
|
|
2959
|
+
icon: lucideReact.Ban,
|
|
2960
|
+
color: "text-muted-foreground",
|
|
2961
|
+
bg: "bg-muted",
|
|
2962
|
+
label: "Cancelled"
|
|
2963
|
+
}
|
|
2964
|
+
};
|
|
2965
|
+
function WithdrawalSheet({ withdrawalId, open, onOpenChange }) {
|
|
2966
|
+
const { getWithdrawalDetails, cancelWithdrawal, refreshWallet } = useWallet();
|
|
2967
|
+
const { data: withdrawal, isLoading, error, mutate } = useSWR__default.default(
|
|
2968
|
+
open && withdrawalId ? ["withdrawal-details", withdrawalId] : null,
|
|
2969
|
+
() => getWithdrawalDetails(withdrawalId),
|
|
2970
|
+
{ refreshInterval: 3e4 }
|
|
2971
|
+
);
|
|
2972
|
+
const displayData = react.useMemo(() => {
|
|
2973
|
+
const s = withdrawal?.status?.toLowerCase() || "pending";
|
|
2974
|
+
const config2 = statusConfig2[s] || statusConfig2.pending;
|
|
2975
|
+
const isPending = s === "pending";
|
|
2976
|
+
const isCompleted = s === "completed";
|
|
2977
|
+
const isRejected = s === "rejected";
|
|
2978
|
+
const isCancelled = s === "cancelled";
|
|
2979
|
+
const isProcessing = s === "processing" || s === "approved";
|
|
2980
|
+
const canCancel2 = isPending;
|
|
2981
|
+
let description2 = "";
|
|
2982
|
+
if (isPending) description2 = "Waiting for admin approval";
|
|
2983
|
+
else if (isProcessing) description2 = "Your withdrawal is being processed";
|
|
2984
|
+
else if (isCompleted) description2 = "Withdrawal completed successfully";
|
|
2985
|
+
else if (isRejected) description2 = "Withdrawal was rejected";
|
|
2986
|
+
else if (isCancelled) description2 = "Withdrawal was cancelled";
|
|
2987
|
+
const amountUsd2 = withdrawal?.amount_usd ? `$${parseFloat(withdrawal.amount_usd).toFixed(2)}` : "";
|
|
2988
|
+
const finalAmountUsd2 = withdrawal?.final_amount_usd ? `$${parseFloat(withdrawal.final_amount_usd).toFixed(2)}` : "";
|
|
2989
|
+
const totalFeeUsd2 = withdrawal?.total_fee_usd ? `$${parseFloat(withdrawal.total_fee_usd).toFixed(2)}` : "";
|
|
2990
|
+
const createdAt2 = withdrawal?.created_at ? moment3__default.default.utc(withdrawal.created_at).local().format("MMM D, YYYY HH:mm") : "";
|
|
2991
|
+
const completedAt2 = withdrawal?.completed_at ? moment3__default.default.utc(withdrawal.completed_at).local().format("MMM D, YYYY HH:mm") : null;
|
|
2992
|
+
return {
|
|
2993
|
+
status: s,
|
|
2994
|
+
config: config2,
|
|
2995
|
+
isPending,
|
|
2996
|
+
isCompleted,
|
|
2997
|
+
isRejected,
|
|
2998
|
+
isCancelled,
|
|
2999
|
+
isProcessing,
|
|
3000
|
+
canCancel: canCancel2,
|
|
3001
|
+
description: description2,
|
|
3002
|
+
amountUsd: amountUsd2,
|
|
3003
|
+
finalAmountUsd: finalAmountUsd2,
|
|
3004
|
+
totalFeeUsd: totalFeeUsd2,
|
|
3005
|
+
createdAt: createdAt2,
|
|
3006
|
+
completedAt: completedAt2
|
|
3007
|
+
};
|
|
3008
|
+
}, [withdrawal]);
|
|
3009
|
+
const { config, canCancel, description, amountUsd, finalAmountUsd, totalFeeUsd, createdAt, completedAt } = displayData;
|
|
3010
|
+
const StatusIcon = config.icon;
|
|
3011
|
+
const handleCancel = async () => {
|
|
3012
|
+
if (!withdrawalId) return;
|
|
3013
|
+
try {
|
|
3014
|
+
await cancelWithdrawal(withdrawalId);
|
|
3015
|
+
await mutate();
|
|
3016
|
+
await refreshWallet();
|
|
3017
|
+
} catch (err) {
|
|
3018
|
+
console.error("Failed to cancel withdrawal:", err);
|
|
3019
|
+
}
|
|
3020
|
+
};
|
|
3021
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheet, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResponsiveSheetContent, { className: "sm:max-w-lg", children: [
|
|
3022
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResponsiveSheetHeader, { children: [
|
|
3023
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheetTitle, { children: "Withdrawal Details" }),
|
|
3024
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheetDescription, { children: description })
|
|
3025
|
+
] }),
|
|
3026
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 sm:p-0 sm:mt-4 overflow-y-auto max-h-[70vh]", children: [
|
|
3027
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
3028
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-16 w-full rounded-xl" }),
|
|
3029
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-24 w-full rounded-xl" }),
|
|
3030
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-20 w-full rounded-xl" })
|
|
3031
|
+
] }),
|
|
3032
|
+
error && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12", children: [
|
|
3033
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "h-12 w-12 text-destructive mb-4" }),
|
|
3034
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Failed to load withdrawal" }),
|
|
3035
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Button, { onClick: () => mutate(), children: "Try Again" })
|
|
3036
|
+
] }),
|
|
3037
|
+
withdrawal && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
3038
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: lib.cn("flex items-center gap-3 p-4 rounded-xl", config.bg), children: [
|
|
3039
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { className: lib.cn("h-6 w-6", config.color, config.animate && "animate-spin") }),
|
|
3040
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
3041
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-semibold", children: config.label }),
|
|
3042
|
+
withdrawal.admin_notes && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: withdrawal.admin_notes })
|
|
3043
|
+
] })
|
|
3044
|
+
] }),
|
|
3045
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted rounded-xl p-4 space-y-3", children: [
|
|
3046
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
3047
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Amount" }),
|
|
3048
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: amountUsd })
|
|
3049
|
+
] }),
|
|
3050
|
+
totalFeeUsd && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
3051
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Total fees" }),
|
|
3052
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-destructive", children: [
|
|
3053
|
+
"-",
|
|
3054
|
+
totalFeeUsd
|
|
3055
|
+
] })
|
|
3056
|
+
] }),
|
|
3057
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between pt-2 border-t", children: [
|
|
3058
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "You receive" }),
|
|
3059
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3060
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TokenIcon, { symbol: withdrawal.currency_code, size: 24 }),
|
|
3061
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-bold text-lg", children: finalAmountUsd })
|
|
3062
|
+
] })
|
|
3063
|
+
] }),
|
|
3064
|
+
withdrawal.crypto_amount && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
3065
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Crypto amount" }),
|
|
3066
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
|
|
3067
|
+
withdrawal.crypto_amount,
|
|
1803
3068
|
" ",
|
|
1804
|
-
|
|
3069
|
+
withdrawal.currency_token
|
|
1805
3070
|
] })
|
|
1806
3071
|
] })
|
|
1807
3072
|
] }),
|
|
1808
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
1809
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
1810
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
1811
|
-
"
|
|
1812
|
-
|
|
1813
|
-
" USD"
|
|
3073
|
+
withdrawal.wallet_address && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
3074
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Destination Wallet" }),
|
|
3075
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3076
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 p-3 bg-muted rounded-xl font-mono text-sm break-all", children: withdrawal.wallet_address }),
|
|
3077
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CopyButton, { value: withdrawal.wallet_address, variant: "outline", className: "shrink-0" })
|
|
1814
3078
|
] })
|
|
1815
3079
|
] }),
|
|
1816
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
1817
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
1818
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
1819
|
-
"1 ",
|
|
1820
|
-
|
|
1821
|
-
" = $",
|
|
1822
|
-
calculateCryptoAmount.rate?.toFixed(2)
|
|
3080
|
+
withdrawal.transaction_hash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
3081
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
|
|
3082
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3083
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 p-3 bg-muted rounded-xl font-mono text-sm break-all", children: withdrawal.transaction_hash }),
|
|
3084
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CopyButton, { value: withdrawal.transaction_hash, variant: "outline", className: "shrink-0" })
|
|
1823
3085
|
] })
|
|
1824
3086
|
] }),
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
3087
|
+
withdrawal.explorer_link && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3088
|
+
uiCore.Button,
|
|
3089
|
+
{
|
|
3090
|
+
variant: "outline",
|
|
3091
|
+
className: "w-full",
|
|
3092
|
+
onClick: () => window.open(withdrawal.explorer_link, "_blank"),
|
|
3093
|
+
children: [
|
|
3094
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 mr-2" }),
|
|
3095
|
+
"View on Explorer"
|
|
3096
|
+
]
|
|
3097
|
+
}
|
|
3098
|
+
),
|
|
3099
|
+
canCancel && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3100
|
+
uiCore.Button,
|
|
3101
|
+
{
|
|
3102
|
+
variant: "destructive",
|
|
3103
|
+
className: "w-full",
|
|
3104
|
+
onClick: handleCancel,
|
|
3105
|
+
children: [
|
|
3106
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ban, { className: "h-4 w-4 mr-2" }),
|
|
3107
|
+
"Cancel Withdrawal"
|
|
3108
|
+
]
|
|
3109
|
+
}
|
|
3110
|
+
),
|
|
3111
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 text-xs text-muted-foreground pt-4 border-t", children: [
|
|
3112
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
3113
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Withdrawal ID" }),
|
|
3114
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: withdrawal.id })
|
|
3115
|
+
] }),
|
|
3116
|
+
withdrawal.internal_withdrawal_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
3117
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Reference #" }),
|
|
3118
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: withdrawal.internal_withdrawal_id })
|
|
3119
|
+
] }),
|
|
3120
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
3121
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Created" }),
|
|
3122
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: createdAt })
|
|
3123
|
+
] }),
|
|
3124
|
+
completedAt && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
3125
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Completed" }),
|
|
3126
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: completedAt })
|
|
3127
|
+
] }),
|
|
3128
|
+
withdrawal.currency_network && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
3129
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Network" }),
|
|
3130
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: withdrawal.currency_network })
|
|
3131
|
+
] })
|
|
3132
|
+
] }),
|
|
3133
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3134
|
+
uiCore.Button,
|
|
3135
|
+
{
|
|
3136
|
+
variant: "ghost",
|
|
3137
|
+
className: "w-full",
|
|
3138
|
+
onClick: () => mutate(),
|
|
3139
|
+
children: [
|
|
3140
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4 mr-2" }),
|
|
3141
|
+
"Refresh Status"
|
|
3142
|
+
]
|
|
3143
|
+
}
|
|
3144
|
+
)
|
|
1839
3145
|
] })
|
|
1840
|
-
] })
|
|
3146
|
+
] })
|
|
1841
3147
|
] }) });
|
|
3148
|
+
}
|
|
3149
|
+
var statusConfig3 = {
|
|
3150
|
+
pending: {
|
|
3151
|
+
icon: lucideReact.Clock,
|
|
3152
|
+
color: "text-yellow-500",
|
|
3153
|
+
bg: "bg-yellow-500/10",
|
|
3154
|
+
label: "Waiting for payment"
|
|
3155
|
+
},
|
|
3156
|
+
confirming: {
|
|
3157
|
+
icon: lucideReact.RefreshCw,
|
|
3158
|
+
color: "text-blue-500",
|
|
3159
|
+
bg: "bg-blue-500/10",
|
|
3160
|
+
label: "Confirming",
|
|
3161
|
+
animate: true
|
|
3162
|
+
},
|
|
3163
|
+
completed: {
|
|
3164
|
+
icon: lucideReact.CheckCircle2,
|
|
3165
|
+
color: "text-green-500",
|
|
3166
|
+
bg: "bg-green-500/10",
|
|
3167
|
+
label: "Completed"
|
|
3168
|
+
},
|
|
3169
|
+
failed: {
|
|
3170
|
+
icon: lucideReact.XCircle,
|
|
3171
|
+
color: "text-red-500",
|
|
3172
|
+
bg: "bg-red-500/10",
|
|
3173
|
+
label: "Failed"
|
|
3174
|
+
},
|
|
3175
|
+
expired: {
|
|
3176
|
+
icon: lucideReact.AlertCircle,
|
|
3177
|
+
color: "text-muted-foreground",
|
|
3178
|
+
bg: "bg-muted",
|
|
3179
|
+
label: "Expired"
|
|
3180
|
+
}
|
|
1842
3181
|
};
|
|
1843
|
-
|
|
1844
|
-
const
|
|
1845
|
-
const [paymentId, setPaymentId] = react.useState(null);
|
|
3182
|
+
function PaymentSheet({ paymentId, open, onOpenChange, onCreateNew }) {
|
|
3183
|
+
const { getPaymentDetails } = useWallet();
|
|
1846
3184
|
const [timeLeft, setTimeLeft] = react.useState("");
|
|
1847
|
-
const
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
3185
|
+
const { data: payment, isLoading, error, mutate } = useSWR__default.default(
|
|
3186
|
+
open && paymentId ? ["payment-details", paymentId] : null,
|
|
3187
|
+
() => getPaymentDetails(paymentId),
|
|
3188
|
+
{ refreshInterval: 1e4 }
|
|
1851
3189
|
);
|
|
1852
|
-
react.useEffect(() => {
|
|
1853
|
-
const handleOpen = (event) => {
|
|
1854
|
-
const customEvent = event;
|
|
1855
|
-
setPaymentId(customEvent.detail.id);
|
|
1856
|
-
setOpen(true);
|
|
1857
|
-
};
|
|
1858
|
-
const handleClose2 = () => {
|
|
1859
|
-
setOpen(false);
|
|
1860
|
-
setPaymentId(null);
|
|
1861
|
-
};
|
|
1862
|
-
window.addEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
|
|
1863
|
-
window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1864
|
-
return () => {
|
|
1865
|
-
window.removeEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
|
|
1866
|
-
window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1867
|
-
};
|
|
1868
|
-
}, []);
|
|
1869
|
-
const handleClose = () => {
|
|
1870
|
-
setOpen(false);
|
|
1871
|
-
setPaymentId(null);
|
|
1872
|
-
};
|
|
1873
3190
|
react.useEffect(() => {
|
|
1874
3191
|
if (!payment?.expires_at) return;
|
|
1875
3192
|
const updateTimeLeft = () => {
|
|
1876
|
-
const now =
|
|
1877
|
-
const expires =
|
|
3193
|
+
const now = moment3__default.default();
|
|
3194
|
+
const expires = moment3__default.default.utc(payment.expires_at);
|
|
1878
3195
|
const diff = expires.diff(now);
|
|
1879
3196
|
if (diff <= 0) {
|
|
1880
3197
|
setTimeLeft("Expired");
|
|
1881
3198
|
return;
|
|
1882
3199
|
}
|
|
1883
|
-
const duration =
|
|
3200
|
+
const duration = moment3__default.default.duration(diff);
|
|
1884
3201
|
const hours = Math.floor(duration.asHours());
|
|
1885
3202
|
const minutes = duration.minutes();
|
|
1886
3203
|
const seconds = duration.seconds();
|
|
@@ -1890,713 +3207,245 @@ var PaymentDetailsDialog = () => {
|
|
|
1890
3207
|
const interval = setInterval(updateTimeLeft, 1e3);
|
|
1891
3208
|
return () => clearInterval(interval);
|
|
1892
3209
|
}, [payment?.expires_at]);
|
|
1893
|
-
const
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
3210
|
+
const displayData = react.useMemo(() => {
|
|
3211
|
+
const s = payment?.status?.toLowerCase();
|
|
3212
|
+
let status;
|
|
3213
|
+
if (s === "completed" || s === "success" || s === "finished") status = "completed";
|
|
3214
|
+
else if (s === "confirming" || s === "partially_paid") status = "confirming";
|
|
3215
|
+
else if (s === "expired") status = "expired";
|
|
3216
|
+
else if (s === "failed" || s === "error" || s === "cancelled") status = "failed";
|
|
3217
|
+
else status = "pending";
|
|
3218
|
+
const config2 = statusConfig3[status];
|
|
3219
|
+
const isPending = status === "pending";
|
|
3220
|
+
const isExpired2 = status === "expired" || timeLeft === "Expired";
|
|
3221
|
+
const isCompleted = status === "completed";
|
|
3222
|
+
const isFailed = status === "failed";
|
|
3223
|
+
const isConfirming = status === "confirming";
|
|
3224
|
+
const canPay2 = isPending && !isExpired2;
|
|
3225
|
+
let description2 = "";
|
|
3226
|
+
if (canPay2) description2 = "Send cryptocurrency to complete payment";
|
|
3227
|
+
else if (isExpired2) description2 = "This payment has expired";
|
|
3228
|
+
else if (isCompleted) description2 = "Payment completed successfully";
|
|
3229
|
+
else if (isFailed) description2 = "Payment failed";
|
|
3230
|
+
else if (isConfirming) description2 = "Confirming your payment";
|
|
3231
|
+
const statusBadge2 = {
|
|
3232
|
+
bg: isExpired2 ? "bg-muted" : config2.bg,
|
|
3233
|
+
iconColor: isExpired2 ? "text-muted-foreground" : config2.color,
|
|
3234
|
+
iconAnimate: config2.animate,
|
|
3235
|
+
label: isExpired2 ? "Payment Expired" : config2.label,
|
|
3236
|
+
subtitle: canPay2 && timeLeft ? `Expires in ${timeLeft}` : isExpired2 ? "Please create a new payment to continue" : null
|
|
3237
|
+
};
|
|
3238
|
+
const qrCodeUrl2 = payment?.pay_address && canPay2 ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}` : null;
|
|
3239
|
+
const amountUsd2 = payment?.amount_usd ? `$${parseFloat(payment.amount_usd).toFixed(2)} USD` : "";
|
|
3240
|
+
const createdAt2 = payment?.created_at ? moment3__default.default.utc(payment.created_at).local().format("MMM D, YYYY HH:mm") : "";
|
|
3241
|
+
return {
|
|
3242
|
+
status,
|
|
3243
|
+
config: config2,
|
|
3244
|
+
isPending,
|
|
3245
|
+
isExpired: isExpired2,
|
|
3246
|
+
isCompleted,
|
|
3247
|
+
isFailed,
|
|
3248
|
+
isConfirming,
|
|
3249
|
+
canPay: canPay2,
|
|
3250
|
+
description: description2,
|
|
3251
|
+
statusBadge: statusBadge2,
|
|
3252
|
+
qrCodeUrl: qrCodeUrl2,
|
|
3253
|
+
amountUsd: amountUsd2,
|
|
3254
|
+
createdAt: createdAt2
|
|
3255
|
+
};
|
|
3256
|
+
}, [payment, timeLeft]);
|
|
3257
|
+
const { config, canPay, isExpired, description, statusBadge, qrCodeUrl, amountUsd, createdAt } = displayData;
|
|
3258
|
+
const StatusIcon = config.icon;
|
|
3259
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheet, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResponsiveSheetContent, { className: "sm:max-w-lg", children: [
|
|
3260
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResponsiveSheetHeader, { children: [
|
|
3261
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheetTitle, { children: "Payment Details" }),
|
|
3262
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResponsiveSheetDescription, { children: description })
|
|
3263
|
+
] }),
|
|
3264
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 sm:p-0 sm:mt-4 overflow-y-auto max-h-[70vh]", children: [
|
|
3265
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
3266
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-48 w-48 rounded-xl" }) }),
|
|
3267
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-12 w-full" }),
|
|
3268
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-24 w-full" })
|
|
1926
3269
|
] }),
|
|
1927
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12
|
|
1928
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "h-12 w-12 text-destructive" }),
|
|
1929
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children:
|
|
3270
|
+
error && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12", children: [
|
|
3271
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "h-12 w-12 text-destructive mb-4" }),
|
|
3272
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Failed to load payment" }),
|
|
1930
3273
|
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Button, { onClick: () => mutate(), children: "Try Again" })
|
|
1931
|
-
] })
|
|
1932
|
-
] }) });
|
|
1933
|
-
}
|
|
1934
|
-
const statusInfo = getStatusInfo();
|
|
1935
|
-
const StatusIcon = statusInfo.icon;
|
|
1936
|
-
const qrCodeUrl = payment.pay_address ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}` : null;
|
|
1937
|
-
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.DialogContent, { className: "sm:max-w-lg", children: [
|
|
1938
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.DialogHeader, { children: [
|
|
1939
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.DialogTitle, { children: "Payment Details" }),
|
|
1940
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.DialogDescription, { children: "Send cryptocurrency to complete your payment" })
|
|
1941
|
-
] }),
|
|
1942
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
1943
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-3 p-4 rounded-sm ${statusInfo.bg}`, children: [
|
|
1944
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { className: `h-5 w-5 ${statusInfo.color}` }),
|
|
1945
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
1946
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-semibold capitalize", children: payment.status }),
|
|
1947
|
-
payment.status === "pending" && timeLeft && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-muted-foreground", children: [
|
|
1948
|
-
"Expires in ",
|
|
1949
|
-
timeLeft
|
|
1950
|
-
] })
|
|
1951
|
-
] })
|
|
1952
3274
|
] }),
|
|
1953
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-
|
|
1954
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center
|
|
1955
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1956
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex
|
|
1957
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1958
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1959
|
-
payment.pay_amount || "0.00000000",
|
|
1960
|
-
" ",
|
|
1961
|
-
payment.currency_code
|
|
1962
|
-
] })
|
|
1963
|
-
] })
|
|
1964
|
-
] }),
|
|
1965
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
1966
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Equivalent to" }),
|
|
1967
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-lg", children: [
|
|
1968
|
-
"$",
|
|
1969
|
-
parseFloat(payment.amount_usd || "0").toFixed(2),
|
|
1970
|
-
" USD"
|
|
3275
|
+
payment && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
3276
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: lib.cn("flex items-center gap-3 p-4 rounded-xl", statusBadge.bg), children: [
|
|
3277
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { className: lib.cn("h-6 w-6", statusBadge.iconColor, statusBadge.iconAnimate && "animate-spin") }),
|
|
3278
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
3279
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-semibold", children: statusBadge.label }),
|
|
3280
|
+
statusBadge.subtitle && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: statusBadge.subtitle })
|
|
1971
3281
|
] })
|
|
1972
3282
|
] }),
|
|
1973
|
-
|
|
1974
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1975
|
-
|
|
1976
|
-
] }),
|
|
1977
|
-
payment.currency_network && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
1978
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Network" }),
|
|
1979
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: payment.currency_network })
|
|
1980
|
-
] })
|
|
1981
|
-
] }),
|
|
1982
|
-
qrCodeUrl && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center p-6 bg-white rounded-sm", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: qrCodeUrl, alt: "Payment QR Code", className: "w-48 h-48" }) }),
|
|
1983
|
-
payment.pay_address && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1984
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Payment Address" }),
|
|
1985
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1986
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.pay_address }),
|
|
1987
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CopyButton, { value: payment.pay_address, variant: "outline" })
|
|
1988
|
-
] })
|
|
1989
|
-
] }),
|
|
1990
|
-
payment.transaction_hash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1991
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
|
|
1992
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.transaction_hash })
|
|
1993
|
-
] }),
|
|
1994
|
-
payment.payment_url && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1995
|
-
uiCore.Button,
|
|
1996
|
-
{
|
|
1997
|
-
variant: "outline",
|
|
1998
|
-
className: "w-full",
|
|
1999
|
-
onClick: () => window.open(payment.payment_url, "_blank"),
|
|
2000
|
-
children: [
|
|
2001
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 mr-2" }),
|
|
2002
|
-
"Open in Payment Provider"
|
|
2003
|
-
]
|
|
2004
|
-
}
|
|
2005
|
-
),
|
|
2006
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t space-y-2 text-xs text-muted-foreground", children: [
|
|
2007
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
2008
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Payment ID" }),
|
|
2009
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: payment.id })
|
|
2010
|
-
] }),
|
|
2011
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
2012
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Created" }),
|
|
2013
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: moment__default.default.utc(payment.created_at).local().format("MMM D, YYYY HH:mm") })
|
|
2014
|
-
] }),
|
|
2015
|
-
payment.confirmations_count !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
2016
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Confirmations" }),
|
|
2017
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: payment.confirmations_count })
|
|
2018
|
-
] })
|
|
2019
|
-
] })
|
|
2020
|
-
] }),
|
|
2021
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.DialogFooter, { children: [
|
|
2022
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Button, { variant: "outline", onClick: handleClose, children: "Close" }),
|
|
2023
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { onClick: () => mutate(), variant: "ghost", size: "sm", children: [
|
|
2024
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4 mr-2" }),
|
|
2025
|
-
"Refresh"
|
|
2026
|
-
] })
|
|
2027
|
-
] })
|
|
2028
|
-
] }) });
|
|
2029
|
-
};
|
|
2030
|
-
var BalanceCard = () => {
|
|
2031
|
-
const {
|
|
2032
|
-
balance,
|
|
2033
|
-
isLoadingBalance,
|
|
2034
|
-
refreshBalance
|
|
2035
|
-
} = useOverviewContext();
|
|
2036
|
-
const formatCurrency = (amount) => {
|
|
2037
|
-
if (amount === null || amount === void 0) return "$0.00";
|
|
2038
|
-
return new Intl.NumberFormat("en-US", {
|
|
2039
|
-
style: "currency",
|
|
2040
|
-
currency: "USD",
|
|
2041
|
-
minimumFractionDigits: 2
|
|
2042
|
-
}).format(amount);
|
|
2043
|
-
};
|
|
2044
|
-
const formatDate = (dateStr) => {
|
|
2045
|
-
if (!dateStr) return "No transactions yet";
|
|
2046
|
-
try {
|
|
2047
|
-
return moment__default.default.utc(dateStr).local().format("MMM D, YYYY");
|
|
2048
|
-
} catch {
|
|
2049
|
-
return "Invalid date";
|
|
2050
|
-
}
|
|
2051
|
-
};
|
|
2052
|
-
if (isLoadingBalance) {
|
|
2053
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Card, { children: [
|
|
2054
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardTitle, { className: "flex items-center justify-between", children: [
|
|
2055
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2056
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { className: "h-5 w-5" }),
|
|
2057
|
-
"Account Balance"
|
|
2058
|
-
] }),
|
|
2059
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-8 w-20" })
|
|
2060
|
-
] }) }),
|
|
2061
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardContent, { className: "space-y-4", children: [
|
|
2062
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-10 w-32" }),
|
|
2063
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-4 w-48" })
|
|
2064
|
-
] })
|
|
2065
|
-
] });
|
|
2066
|
-
}
|
|
2067
|
-
const balanceData = balance?.balance || balance;
|
|
2068
|
-
const amountUsd = balanceData?.amount_usd ?? 0;
|
|
2069
|
-
const totalDeposited = balanceData?.total_deposited ?? 0;
|
|
2070
|
-
const totalWithdrawn = balanceData?.total_withdrawn ?? 0;
|
|
2071
|
-
const lastTransactionAt = balanceData?.last_transaction_at;
|
|
2072
|
-
const isEmpty = amountUsd === 0 && totalDeposited === 0;
|
|
2073
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Card, { children: [
|
|
2074
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardTitle, { className: "flex items-center justify-between", children: [
|
|
2075
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2076
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { className: "h-5 w-5" }),
|
|
2077
|
-
"Account Balance"
|
|
2078
|
-
] }),
|
|
2079
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2080
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Button, { variant: "ghost", size: "sm", onClick: refreshBalance, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4" }) }),
|
|
2081
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { size: "sm", onClick: () => openCreatePaymentDialog(), children: [
|
|
2082
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2083
|
-
"Add Funds"
|
|
2084
|
-
] })
|
|
2085
|
-
] })
|
|
2086
|
-
] }) }),
|
|
2087
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardContent, { className: "space-y-4", children: [
|
|
2088
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2089
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-4xl font-bold", children: formatCurrency(amountUsd) }),
|
|
2090
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mt-1", children: [
|
|
2091
|
-
"Available balance \u2022 Last updated ",
|
|
2092
|
-
formatDate(lastTransactionAt)
|
|
2093
|
-
] })
|
|
2094
|
-
] }),
|
|
2095
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4 pt-4 border-t", children: [
|
|
2096
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2097
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Total Deposited" }),
|
|
2098
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-semibold text-green-600", children: formatCurrency(totalDeposited) })
|
|
2099
|
-
] }),
|
|
2100
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2101
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Total Withdrawn" }),
|
|
2102
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-semibold text-red-600", children: formatCurrency(totalWithdrawn) })
|
|
2103
|
-
] })
|
|
2104
|
-
] }),
|
|
2105
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2106
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Badge, { variant: !isEmpty ? "default" : "secondary", children: !isEmpty ? "Active" : "New Account" }),
|
|
2107
|
-
isEmpty && /* @__PURE__ */ jsxRuntime.jsx(uiCore.Badge, { variant: "outline", children: "Empty Balance" })
|
|
2108
|
-
] })
|
|
2109
|
-
] })
|
|
2110
|
-
] });
|
|
2111
|
-
};
|
|
2112
|
-
var RecentPayments = () => {
|
|
2113
|
-
const { payments, isLoadingPayments } = useOverviewContext();
|
|
2114
|
-
const formatCurrency = (amount) => {
|
|
2115
|
-
if (amount === null || amount === void 0) return "$0.00";
|
|
2116
|
-
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
2117
|
-
return new Intl.NumberFormat("en-US", {
|
|
2118
|
-
style: "currency",
|
|
2119
|
-
currency: "USD",
|
|
2120
|
-
minimumFractionDigits: 2
|
|
2121
|
-
}).format(numAmount);
|
|
2122
|
-
};
|
|
2123
|
-
const getRelativeTime = (date) => {
|
|
2124
|
-
if (!date) return "N/A";
|
|
2125
|
-
const m = moment__default.default.utc(date).local();
|
|
2126
|
-
const now = moment__default.default();
|
|
2127
|
-
const diffInSeconds = now.diff(m, "seconds");
|
|
2128
|
-
if (diffInSeconds < 60) return "Just now";
|
|
2129
|
-
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
2130
|
-
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
2131
|
-
return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
2132
|
-
};
|
|
2133
|
-
const getStatusVariant = (status) => {
|
|
2134
|
-
switch (status?.toLowerCase()) {
|
|
2135
|
-
case "completed":
|
|
2136
|
-
case "success":
|
|
2137
|
-
return "default";
|
|
2138
|
-
case "pending":
|
|
2139
|
-
case "confirming":
|
|
2140
|
-
return "secondary";
|
|
2141
|
-
case "failed":
|
|
2142
|
-
case "error":
|
|
2143
|
-
case "expired":
|
|
2144
|
-
return "destructive";
|
|
2145
|
-
default:
|
|
2146
|
-
return "outline";
|
|
2147
|
-
}
|
|
2148
|
-
};
|
|
2149
|
-
if (isLoadingPayments) {
|
|
2150
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Card, { children: [
|
|
2151
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardTitle, { className: "flex items-center gap-2", children: [
|
|
2152
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-5 w-5" }),
|
|
2153
|
-
"Recent Payments"
|
|
2154
|
-
] }) }),
|
|
2155
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CardContent, { className: "space-y-3", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-3 border rounded-sm", children: [
|
|
2156
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
2157
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-4 w-32" }),
|
|
2158
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-3 w-24" })
|
|
2159
|
-
] }),
|
|
2160
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-6 w-16" })
|
|
2161
|
-
] }, i)) })
|
|
2162
|
-
] });
|
|
2163
|
-
}
|
|
2164
|
-
const recentPaymentsList = payments?.results?.slice(0, 5) || [];
|
|
2165
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Card, { children: [
|
|
2166
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardTitle, { className: "flex items-center justify-between", children: [
|
|
2167
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2168
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-5 w-5" }),
|
|
2169
|
-
"Recent Payments"
|
|
2170
|
-
] }),
|
|
2171
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { variant: "ghost", size: "sm", children: [
|
|
2172
|
-
"View All",
|
|
2173
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 ml-2" })
|
|
2174
|
-
] })
|
|
2175
|
-
] }) }),
|
|
2176
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CardContent, { children: recentPaymentsList.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
2177
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-12 w-12 mx-auto mb-4 opacity-50" }),
|
|
2178
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "No recent payments" }),
|
|
2179
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm mt-2", children: "Create your first payment to get started" })
|
|
2180
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: recentPaymentsList.map((payment) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2181
|
-
"div",
|
|
2182
|
-
{
|
|
2183
|
-
className: "flex items-center justify-between p-3 border rounded-sm hover:bg-accent cursor-pointer transition-colors",
|
|
2184
|
-
onClick: () => openPaymentDetailsDialog(String(payment.id)),
|
|
2185
|
-
children: [
|
|
2186
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
3283
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted rounded-xl p-4 space-y-3", children: [
|
|
3284
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
3285
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Amount to send" }),
|
|
2187
3286
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2188
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2189
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
payment.currency_code || "USD"
|
|
3287
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TokenIcon, { symbol: payment.currency_code, size: 24 }),
|
|
3288
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono font-bold text-lg", children: [
|
|
3289
|
+
payment.pay_amount,
|
|
3290
|
+
" ",
|
|
3291
|
+
payment.currency_code
|
|
3292
|
+
] })
|
|
2195
3293
|
] })
|
|
2196
3294
|
] }),
|
|
2197
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
}
|
|
2204
|
-
|
|
2205
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 lg:grid-cols-2", children: [
|
|
2206
|
-
/* @__PURE__ */ jsxRuntime.jsx(BalanceCard, {}),
|
|
2207
|
-
/* @__PURE__ */ jsxRuntime.jsx(RecentPayments, {})
|
|
2208
|
-
] }) });
|
|
2209
|
-
};
|
|
2210
|
-
var PaymentsList = () => {
|
|
2211
|
-
const pagination = components.useDRFPagination(1, 20);
|
|
2212
|
-
const {
|
|
2213
|
-
data: payments,
|
|
2214
|
-
error,
|
|
2215
|
-
isLoading: isLoadingPayments,
|
|
2216
|
-
mutate: refreshPayments
|
|
2217
|
-
} = usePaymentsPaymentsList(pagination.params, apiPayments);
|
|
2218
|
-
const paymentsList = payments?.results || [];
|
|
2219
|
-
payments?.count || 0;
|
|
2220
|
-
const [searchTerm, setSearchTerm] = react.useState("");
|
|
2221
|
-
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
2222
|
-
const formatCurrency = (amount) => {
|
|
2223
|
-
if (amount === null || amount === void 0) return "$0.00";
|
|
2224
|
-
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
2225
|
-
return new Intl.NumberFormat("en-US", {
|
|
2226
|
-
style: "currency",
|
|
2227
|
-
currency: "USD",
|
|
2228
|
-
minimumFractionDigits: 2
|
|
2229
|
-
}).format(numAmount);
|
|
2230
|
-
};
|
|
2231
|
-
const getRelativeTime = (date) => {
|
|
2232
|
-
if (!date) return "N/A";
|
|
2233
|
-
const m = moment__default.default.utc(date).local();
|
|
2234
|
-
const now = moment__default.default();
|
|
2235
|
-
const diffInSeconds = now.diff(m, "seconds");
|
|
2236
|
-
if (diffInSeconds < 60) return "Just now";
|
|
2237
|
-
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
2238
|
-
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
2239
|
-
return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
2240
|
-
};
|
|
2241
|
-
const formatDate = (date) => {
|
|
2242
|
-
if (!date) return "N/A";
|
|
2243
|
-
return moment__default.default.utc(date).local().format("MMM D, YYYY");
|
|
2244
|
-
};
|
|
2245
|
-
const getStatusVariant = (status) => {
|
|
2246
|
-
switch (status?.toLowerCase()) {
|
|
2247
|
-
case "completed":
|
|
2248
|
-
case "success":
|
|
2249
|
-
return "default";
|
|
2250
|
-
case "pending":
|
|
2251
|
-
case "confirming":
|
|
2252
|
-
return "secondary";
|
|
2253
|
-
case "failed":
|
|
2254
|
-
case "error":
|
|
2255
|
-
case "expired":
|
|
2256
|
-
return "destructive";
|
|
2257
|
-
default:
|
|
2258
|
-
return "outline";
|
|
2259
|
-
}
|
|
2260
|
-
};
|
|
2261
|
-
const handleSearch = (value) => {
|
|
2262
|
-
setSearchTerm(value);
|
|
2263
|
-
};
|
|
2264
|
-
const handleStatusFilter = (status) => {
|
|
2265
|
-
setStatusFilter(status);
|
|
2266
|
-
};
|
|
2267
|
-
const truncateId = (id) => {
|
|
2268
|
-
if (!id) return "N/A";
|
|
2269
|
-
const str = id.toString();
|
|
2270
|
-
return str.length > 8 ? `${str.slice(0, 8)}...` : str;
|
|
2271
|
-
};
|
|
2272
|
-
const filteredPayments = paymentsList.filter((payment) => {
|
|
2273
|
-
const matchesSearch = searchTerm ? payment.id?.toLowerCase().includes(searchTerm.toLowerCase()) || payment.status?.toLowerCase().includes(searchTerm.toLowerCase()) || payment.currency_code?.toLowerCase().includes(searchTerm.toLowerCase()) : true;
|
|
2274
|
-
const matchesStatus = statusFilter !== "all" ? payment.status?.toLowerCase() === statusFilter.toLowerCase() : true;
|
|
2275
|
-
return matchesSearch && matchesStatus;
|
|
2276
|
-
}).map((payment) => ({
|
|
2277
|
-
...payment,
|
|
2278
|
-
formattedDate: formatDate(payment.created_at),
|
|
2279
|
-
relativeTime: getRelativeTime(payment.created_at),
|
|
2280
|
-
truncatedId: truncateId(payment.id)
|
|
2281
|
-
}));
|
|
2282
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Card, { children: [
|
|
2283
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardTitle, { className: "flex items-center justify-between", children: [
|
|
2284
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Payment History" }),
|
|
2285
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2286
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { variant: "outline", size: "sm", onClick: () => refreshPayments(), disabled: isLoadingPayments, children: [
|
|
2287
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: `h-4 w-4 mr-2 ${isLoadingPayments ? "animate-spin" : ""}` }),
|
|
2288
|
-
"Refresh"
|
|
3295
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
3296
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Equivalent" }),
|
|
3297
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: amountUsd })
|
|
3298
|
+
] }),
|
|
3299
|
+
payment.currency_network && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm pt-2 border-t", children: [
|
|
3300
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Network" }),
|
|
3301
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: payment.currency_network })
|
|
3302
|
+
] })
|
|
2289
3303
|
] }),
|
|
2290
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2291
|
-
|
|
2292
|
-
"
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
3304
|
+
qrCodeUrl && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center p-6 bg-white rounded-xl", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: qrCodeUrl, alt: "Payment QR Code", className: "w-48 h-48" }) }),
|
|
3305
|
+
payment.pay_address && canPay && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
3306
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Payment Address" }),
|
|
3307
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3308
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 p-3 bg-muted rounded-xl font-mono text-sm break-all", children: payment.pay_address }),
|
|
3309
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.CopyButton, { value: payment.pay_address, variant: "outline", className: "shrink-0" })
|
|
3310
|
+
] })
|
|
3311
|
+
] }),
|
|
3312
|
+
isExpired && onCreateNew && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3313
|
+
uiCore.Button,
|
|
3314
|
+
{
|
|
3315
|
+
size: "lg",
|
|
3316
|
+
className: "w-full",
|
|
3317
|
+
onClick: () => {
|
|
3318
|
+
onOpenChange(false);
|
|
3319
|
+
onCreateNew();
|
|
3320
|
+
},
|
|
3321
|
+
children: "Create New Payment"
|
|
3322
|
+
}
|
|
3323
|
+
),
|
|
3324
|
+
payment.transaction_hash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
3325
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
|
|
3326
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 bg-muted rounded-xl font-mono text-sm break-all", children: payment.transaction_hash })
|
|
2309
3327
|
] }),
|
|
2310
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
3328
|
+
payment.payment_url && canPay && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3329
|
+
uiCore.Button,
|
|
3330
|
+
{
|
|
3331
|
+
variant: "outline",
|
|
3332
|
+
className: "w-full",
|
|
3333
|
+
onClick: () => window.open(payment.payment_url, "_blank"),
|
|
3334
|
+
children: [
|
|
3335
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 mr-2" }),
|
|
3336
|
+
"Open in Payment Provider"
|
|
3337
|
+
]
|
|
3338
|
+
}
|
|
3339
|
+
),
|
|
3340
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 text-xs text-muted-foreground pt-4 border-t", children: [
|
|
3341
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
3342
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Payment ID" }),
|
|
3343
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: payment.id })
|
|
2314
3344
|
] }),
|
|
2315
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2316
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2317
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2321
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3345
|
+
payment.internal_payment_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
3346
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Order #" }),
|
|
3347
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: payment.internal_payment_id })
|
|
3348
|
+
] }),
|
|
3349
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
3350
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Created" }),
|
|
3351
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: createdAt })
|
|
2322
3352
|
] })
|
|
2323
|
-
] })
|
|
2324
|
-
] }),
|
|
2325
|
-
isLoadingPayments ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border rounded-sm", children: [
|
|
2326
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
2327
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-4 w-32" }),
|
|
2328
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-3 w-24" })
|
|
2329
3353
|
] }),
|
|
2330
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2331
|
-
|
|
2332
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 mx-auto mb-4 bg-muted rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "w-8 h-8 text-muted-foreground" }) }),
|
|
2333
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-2", children: "No Payments Found" }),
|
|
2334
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-4", children: searchTerm || statusFilter !== "all" ? "No payments match your current filters" : "You haven't made any payments yet" }),
|
|
2335
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { onClick: () => openCreatePaymentDialog(), children: [
|
|
2336
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2337
|
-
"Create Payment"
|
|
2338
|
-
] })
|
|
2339
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2340
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Table, { children: [
|
|
2341
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.TableRow, { children: [
|
|
2342
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Date" }),
|
|
2343
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Amount" }),
|
|
2344
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Currency" }),
|
|
2345
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Status" }),
|
|
2346
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Provider" }),
|
|
2347
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Payment ID" }),
|
|
2348
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { className: "text-right", children: "Actions" })
|
|
2349
|
-
] }) }),
|
|
2350
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableBody, { children: filteredPayments.map((payment) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2351
|
-
uiCore.TableRow,
|
|
2352
|
-
{
|
|
2353
|
-
className: "cursor-pointer hover:bg-accent",
|
|
2354
|
-
onClick: () => openPaymentDetailsDialog(String(payment.id)),
|
|
2355
|
-
children: [
|
|
2356
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2357
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: payment.formattedDate }),
|
|
2358
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: payment.relativeTime })
|
|
2359
|
-
] }) }),
|
|
2360
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { className: "font-mono font-semibold", children: formatCurrency(payment.amount_usd) }),
|
|
2361
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.Badge, { variant: "outline", children: payment.currency_code || "USD" }) }),
|
|
2362
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.Badge, { variant: getStatusVariant(payment.status), children: payment.status }) }),
|
|
2363
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { className: "text-sm text-muted-foreground", children: "NowPayments" }),
|
|
2364
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { className: "font-mono text-sm text-muted-foreground", children: payment.truncatedId }),
|
|
2365
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2366
|
-
uiCore.Button,
|
|
2367
|
-
{
|
|
2368
|
-
variant: "ghost",
|
|
2369
|
-
size: "sm",
|
|
2370
|
-
onClick: (e) => {
|
|
2371
|
-
e.stopPropagation();
|
|
2372
|
-
openPaymentDetailsDialog(String(payment.id));
|
|
2373
|
-
},
|
|
2374
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4" })
|
|
2375
|
-
}
|
|
2376
|
-
) })
|
|
2377
|
-
]
|
|
2378
|
-
},
|
|
2379
|
-
payment.id
|
|
2380
|
-
)) })
|
|
2381
|
-
] }) }),
|
|
2382
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2383
|
-
components.StaticPagination,
|
|
3354
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3355
|
+
uiCore.Button,
|
|
2384
3356
|
{
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
3357
|
+
variant: "ghost",
|
|
3358
|
+
className: "w-full",
|
|
3359
|
+
onClick: () => mutate(),
|
|
3360
|
+
children: [
|
|
3361
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4 mr-2" }),
|
|
3362
|
+
"Refresh Status"
|
|
3363
|
+
]
|
|
2388
3364
|
}
|
|
2389
3365
|
)
|
|
2390
3366
|
] })
|
|
2391
3367
|
] })
|
|
2392
|
-
] });
|
|
2393
|
-
}
|
|
2394
|
-
var
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
const
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
return new Intl.NumberFormat("en-US", {
|
|
2409
|
-
style: "currency",
|
|
2410
|
-
currency: "USD",
|
|
2411
|
-
minimumFractionDigits: 2
|
|
2412
|
-
}).format(amount);
|
|
2413
|
-
};
|
|
2414
|
-
const formatDate = (date) => {
|
|
2415
|
-
if (!date) return "N/A";
|
|
2416
|
-
try {
|
|
2417
|
-
return moment__default.default.utc(date).local().format("MMM D, YYYY hh:mm A");
|
|
2418
|
-
} catch {
|
|
2419
|
-
return "Invalid date";
|
|
2420
|
-
}
|
|
2421
|
-
};
|
|
2422
|
-
const getRelativeTime = (date) => {
|
|
2423
|
-
if (!date) return "N/A";
|
|
2424
|
-
const m = moment__default.default.utc(date).local();
|
|
2425
|
-
const now = moment__default.default();
|
|
2426
|
-
const diffInSeconds = now.diff(m, "seconds");
|
|
2427
|
-
if (diffInSeconds < 60) return "Just now";
|
|
2428
|
-
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
2429
|
-
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
2430
|
-
return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
2431
|
-
};
|
|
2432
|
-
const getTypeVariant = (type) => {
|
|
2433
|
-
switch (type?.toLowerCase()) {
|
|
2434
|
-
case "deposit":
|
|
2435
|
-
case "credit":
|
|
2436
|
-
return "default";
|
|
2437
|
-
case "withdrawal":
|
|
2438
|
-
case "debit":
|
|
2439
|
-
return "destructive";
|
|
2440
|
-
default:
|
|
2441
|
-
return "outline";
|
|
3368
|
+
] }) });
|
|
3369
|
+
}
|
|
3370
|
+
var WalletContent = () => {
|
|
3371
|
+
const [addFundsOpen, setAddFundsOpen] = react.useState(false);
|
|
3372
|
+
const [withdrawOpen, setWithdrawOpen] = react.useState(false);
|
|
3373
|
+
const [selectedPaymentId, setSelectedPaymentId] = react.useState(null);
|
|
3374
|
+
const [paymentSheetOpen, setPaymentSheetOpen] = react.useState(false);
|
|
3375
|
+
const [selectedWithdrawalId, setSelectedWithdrawalId] = react.useState(null);
|
|
3376
|
+
const [withdrawalSheetOpen, setWithdrawalSheetOpen] = react.useState(false);
|
|
3377
|
+
const handleActivityClick = react.useCallback((item) => {
|
|
3378
|
+
if (item.payment) {
|
|
3379
|
+
setSelectedPaymentId(item.payment.id);
|
|
3380
|
+
setPaymentSheetOpen(true);
|
|
3381
|
+
} else if (item.withdrawal) {
|
|
3382
|
+
setSelectedWithdrawalId(item.withdrawal.id);
|
|
3383
|
+
setWithdrawalSheetOpen(true);
|
|
2442
3384
|
}
|
|
2443
|
-
};
|
|
2444
|
-
const
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
};
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
] }) }),
|
|
2498
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardContent, { className: "space-y-4", children: [
|
|
2499
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row gap-4", children: [
|
|
2500
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1", children: [
|
|
2501
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
|
|
2502
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2503
|
-
uiCore.Input,
|
|
2504
|
-
{
|
|
2505
|
-
placeholder: "Search by ID, description, or type...",
|
|
2506
|
-
value: searchTerm,
|
|
2507
|
-
onChange: (e) => handleSearch(e.target.value),
|
|
2508
|
-
className: "pl-10"
|
|
2509
|
-
}
|
|
2510
|
-
)
|
|
2511
|
-
] }),
|
|
2512
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Select, { value: typeFilter, onValueChange: handleTypeFilter, children: [
|
|
2513
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.SelectTrigger, { className: "w-full sm:w-48", children: [
|
|
2514
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "h-4 w-4 mr-2" }),
|
|
2515
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.SelectValue, { placeholder: "Filter by type" })
|
|
2516
|
-
] }),
|
|
2517
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.SelectContent, { children: [
|
|
2518
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.SelectItem, { value: "all", children: "All Types" }),
|
|
2519
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.SelectItem, { value: "deposit", children: "Deposits" }),
|
|
2520
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.SelectItem, { value: "withdrawal", children: "Withdrawals" })
|
|
2521
|
-
] })
|
|
2522
|
-
] })
|
|
2523
|
-
] }),
|
|
2524
|
-
filteredTransactions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-12", children: [
|
|
2525
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 mx-auto mb-4 bg-muted rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "w-8 h-8 text-muted-foreground" }) }),
|
|
2526
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-2", children: "No Transactions Found" }),
|
|
2527
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: searchTerm || typeFilter !== "all" ? "No transactions match your current filters" : "You don't have any transactions yet" })
|
|
2528
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Table, { children: [
|
|
2529
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.TableRow, { children: [
|
|
2530
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Date & Time" }),
|
|
2531
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Type" }),
|
|
2532
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Amount" }),
|
|
2533
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Balance After" }),
|
|
2534
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Description" }),
|
|
2535
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableHead, { children: "Reference" })
|
|
2536
|
-
] }) }),
|
|
2537
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableBody, { children: filteredTransactions.map((transaction, index) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.TableRow, { children: [
|
|
2538
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2539
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: transaction.formattedDate }),
|
|
2540
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: transaction.relativeTime })
|
|
2541
|
-
] }) }),
|
|
2542
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2543
|
-
getTypeIcon(transaction.type),
|
|
2544
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Badge, { variant: getTypeVariant(transaction.type), children: transaction.type || "Unknown" })
|
|
2545
|
-
] }) }),
|
|
2546
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { className: "font-mono font-semibold", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: transaction.isDeposit ? "text-green-600" : "text-red-600", children: [
|
|
2547
|
-
transaction.isDeposit ? "+" : "-",
|
|
2548
|
-
formatCurrency(Math.abs(transaction.amount || transaction.amount_usd || 0))
|
|
2549
|
-
] }) }),
|
|
2550
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { className: "font-mono", children: formatCurrency(transaction.balance_after || 0) }),
|
|
2551
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { className: "text-sm", children: transaction.description || transaction.note || "No description" }),
|
|
2552
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TableCell, { className: "font-mono text-sm text-muted-foreground", children: transaction.truncatedRef })
|
|
2553
|
-
] }, transaction.id || index)) })
|
|
2554
|
-
] }) })
|
|
2555
|
-
] })
|
|
3385
|
+
}, []);
|
|
3386
|
+
const handlePaymentCreated = react.useCallback((payment) => {
|
|
3387
|
+
setSelectedPaymentId(payment.id);
|
|
3388
|
+
setPaymentSheetOpen(true);
|
|
3389
|
+
}, []);
|
|
3390
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen", children: [
|
|
3391
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3392
|
+
BalanceHero,
|
|
3393
|
+
{
|
|
3394
|
+
onAddFunds: () => setAddFundsOpen(true),
|
|
3395
|
+
onWithdraw: () => setWithdrawOpen(true),
|
|
3396
|
+
className: "bg-muted/30 border-b"
|
|
3397
|
+
}
|
|
3398
|
+
),
|
|
3399
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3400
|
+
ActivityList,
|
|
3401
|
+
{
|
|
3402
|
+
onItemClick: handleActivityClick,
|
|
3403
|
+
limit: 20,
|
|
3404
|
+
className: "max-w-2xl mx-auto pb-12"
|
|
3405
|
+
}
|
|
3406
|
+
),
|
|
3407
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3408
|
+
AddFundsSheet,
|
|
3409
|
+
{
|
|
3410
|
+
open: addFundsOpen,
|
|
3411
|
+
onOpenChange: setAddFundsOpen,
|
|
3412
|
+
onSuccess: handlePaymentCreated
|
|
3413
|
+
}
|
|
3414
|
+
),
|
|
3415
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3416
|
+
WithdrawSheet,
|
|
3417
|
+
{
|
|
3418
|
+
open: withdrawOpen,
|
|
3419
|
+
onOpenChange: setWithdrawOpen
|
|
3420
|
+
}
|
|
3421
|
+
),
|
|
3422
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3423
|
+
PaymentSheet,
|
|
3424
|
+
{
|
|
3425
|
+
paymentId: selectedPaymentId,
|
|
3426
|
+
open: paymentSheetOpen,
|
|
3427
|
+
onOpenChange: setPaymentSheetOpen,
|
|
3428
|
+
onCreateNew: () => setAddFundsOpen(true)
|
|
3429
|
+
}
|
|
3430
|
+
),
|
|
3431
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3432
|
+
WithdrawalSheet,
|
|
3433
|
+
{
|
|
3434
|
+
withdrawalId: selectedWithdrawalId,
|
|
3435
|
+
open: withdrawalSheetOpen,
|
|
3436
|
+
onOpenChange: setWithdrawalSheetOpen
|
|
3437
|
+
}
|
|
3438
|
+
)
|
|
2556
3439
|
] });
|
|
2557
3440
|
};
|
|
2558
|
-
|
|
2559
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2560
|
-
}
|
|
2561
|
-
var PaymentsLayout = () => {
|
|
2562
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RootPaymentsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full p-6 space-y-6", children: [
|
|
2563
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2564
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "Payments" }),
|
|
2565
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "Manage your payments, balance, and transaction history" })
|
|
2566
|
-
] }),
|
|
2567
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Tabs, { defaultValue: "overview", className: "space-y-6", children: [
|
|
2568
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.TabsList, { className: "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground", children: [
|
|
2569
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.TabsTrigger, { value: "overview", className: "inline-flex items-center gap-2 px-3 py-1.5", children: [
|
|
2570
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { className: "h-4 w-4" }),
|
|
2571
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "Overview" })
|
|
2572
|
-
] }),
|
|
2573
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.TabsTrigger, { value: "payments", className: "inline-flex items-center gap-2 px-3 py-1.5", children: [
|
|
2574
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCard, { className: "h-4 w-4" }),
|
|
2575
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "Payments" })
|
|
2576
|
-
] }),
|
|
2577
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.TabsTrigger, { value: "transactions", className: "inline-flex items-center gap-2 px-3 py-1.5", children: [
|
|
2578
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-4 w-4" }),
|
|
2579
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "Transactions" })
|
|
2580
|
-
] })
|
|
2581
|
-
] }),
|
|
2582
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TabsContent, { value: "overview", className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsx(OverviewProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(PaymentsProvider, { children: [
|
|
2583
|
-
/* @__PURE__ */ jsxRuntime.jsx(OverviewView, {}),
|
|
2584
|
-
/* @__PURE__ */ jsxRuntime.jsx(CreatePaymentDialog, {})
|
|
2585
|
-
] }) }) }),
|
|
2586
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TabsContent, { value: "payments", className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsxs(PaymentsProvider, { children: [
|
|
2587
|
-
/* @__PURE__ */ jsxRuntime.jsx(PaymentsView, {}),
|
|
2588
|
-
/* @__PURE__ */ jsxRuntime.jsx(CreatePaymentDialog, {})
|
|
2589
|
-
] }) }),
|
|
2590
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiCore.TabsContent, { value: "transactions", className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsx(OverviewProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(TransactionsView, {}) }) })
|
|
2591
|
-
] }),
|
|
2592
|
-
/* @__PURE__ */ jsxRuntime.jsx(PaymentDetailsDialog, {})
|
|
2593
|
-
] }) });
|
|
2594
|
-
};
|
|
3441
|
+
function WalletPage() {
|
|
3442
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WalletProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(WalletContent, {}) });
|
|
3443
|
+
}
|
|
2595
3444
|
|
|
2596
3445
|
// package.json
|
|
2597
3446
|
var package_default = {
|
|
2598
3447
|
name: "@djangocfg/ext-payments",
|
|
2599
|
-
version: "1.0.
|
|
3448
|
+
version: "1.0.19",
|
|
2600
3449
|
description: "Payments system extension for DjangoCFG",
|
|
2601
3450
|
keywords: [
|
|
2602
3451
|
"django",
|
|
@@ -2633,11 +3482,6 @@ var package_default = {
|
|
|
2633
3482
|
import: "./dist/index.js",
|
|
2634
3483
|
require: "./dist/index.cjs"
|
|
2635
3484
|
},
|
|
2636
|
-
"./hooks": {
|
|
2637
|
-
types: "./dist/hooks.d.ts",
|
|
2638
|
-
import: "./dist/hooks.js",
|
|
2639
|
-
require: "./dist/hooks.cjs"
|
|
2640
|
-
},
|
|
2641
3485
|
"./config": {
|
|
2642
3486
|
types: "./dist/config.d.ts",
|
|
2643
3487
|
import: "./dist/config.js",
|
|
@@ -2665,8 +3509,10 @@ var package_default = {
|
|
|
2665
3509
|
"p-retry": "^7.0.0",
|
|
2666
3510
|
react: "^19",
|
|
2667
3511
|
swr: "^2.3.7",
|
|
2668
|
-
zod: "^4.
|
|
2669
|
-
moment: "^2.30.1"
|
|
3512
|
+
zod: "^4.3.4",
|
|
3513
|
+
moment: "^2.30.1",
|
|
3514
|
+
"react-hook-form": "^7.69.0",
|
|
3515
|
+
"@hookform/resolvers": "^5.2.2"
|
|
2670
3516
|
},
|
|
2671
3517
|
devDependencies: {
|
|
2672
3518
|
"@djangocfg/api": "workspace:*",
|
|
@@ -2743,6 +3589,10 @@ exports.API = API;
|
|
|
2743
3589
|
exports.APIClient = APIClient;
|
|
2744
3590
|
exports.APIError = APIError;
|
|
2745
3591
|
exports.APILogger = APILogger;
|
|
3592
|
+
exports.ActivityItem = ActivityItem;
|
|
3593
|
+
exports.ActivityList = ActivityList;
|
|
3594
|
+
exports.AddFundsSheet = AddFundsSheet;
|
|
3595
|
+
exports.BalanceHero = BalanceHero;
|
|
2746
3596
|
exports.BalanceSchema = BalanceSchema;
|
|
2747
3597
|
exports.CookieStorageAdapter = CookieStorageAdapter;
|
|
2748
3598
|
exports.CurrencySchema = CurrencySchema;
|
|
@@ -2754,35 +3604,48 @@ exports.Fetchers = fetchers_exports;
|
|
|
2754
3604
|
exports.LocalStorageAdapter = LocalStorageAdapter;
|
|
2755
3605
|
exports.MemoryStorageAdapter = MemoryStorageAdapter;
|
|
2756
3606
|
exports.NetworkError = NetworkError;
|
|
2757
|
-
exports.PAYMENT_EVENTS = PAYMENT_EVENTS;
|
|
2758
3607
|
exports.PaginatedPaymentListListSchema = PaginatedPaymentListListSchema;
|
|
3608
|
+
exports.PaginatedWithdrawalListListSchema = PaginatedWithdrawalListListSchema;
|
|
3609
|
+
exports.PaymentCreateRequestSchema = PaymentCreateRequestSchema;
|
|
3610
|
+
exports.PaymentCreateResponseSchema = PaymentCreateResponseSchema;
|
|
2759
3611
|
exports.PaymentDetailSchema = PaymentDetailSchema;
|
|
2760
3612
|
exports.PaymentListSchema = PaymentListSchema;
|
|
2761
|
-
exports.
|
|
3613
|
+
exports.PaymentSheet = PaymentSheet;
|
|
2762
3614
|
exports.REFRESH_TOKEN_KEY = REFRESH_TOKEN_KEY;
|
|
2763
3615
|
exports.Schemas = schemas_exports;
|
|
2764
3616
|
exports.TOKEN_KEY = TOKEN_KEY;
|
|
2765
3617
|
exports.TransactionSchema = TransactionSchema;
|
|
3618
|
+
exports.WalletPage = WalletPage;
|
|
3619
|
+
exports.WithdrawSheet = WithdrawSheet;
|
|
3620
|
+
exports.WithdrawalCancelResponseSchema = WithdrawalCancelResponseSchema;
|
|
3621
|
+
exports.WithdrawalCreateRequestSchema = WithdrawalCreateRequestSchema;
|
|
3622
|
+
exports.WithdrawalCreateResponseSchema = WithdrawalCreateResponseSchema;
|
|
3623
|
+
exports.WithdrawalDetailSchema = WithdrawalDetailSchema;
|
|
3624
|
+
exports.WithdrawalListSchema = WithdrawalListSchema;
|
|
3625
|
+
exports.WithdrawalSheet = WithdrawalSheet;
|
|
2766
3626
|
exports.apiPayments = apiPayments;
|
|
2767
3627
|
exports.clearAPITokens = clearAPITokens;
|
|
2768
|
-
exports.closePaymentsDialog = closePaymentsDialog;
|
|
2769
3628
|
exports.configureAPI = configureAPI;
|
|
2770
3629
|
exports.createPaymentsPaymentsConfirmCreate = createPaymentsPaymentsConfirmCreate;
|
|
2771
3630
|
exports.createPaymentsPaymentsCreateCreate = createPaymentsPaymentsCreateCreate;
|
|
3631
|
+
exports.createPaymentsWithdrawalsCancelCreate = createPaymentsWithdrawalsCancelCreate;
|
|
3632
|
+
exports.createPaymentsWithdrawalsCreateCreate = createPaymentsWithdrawalsCreateCreate;
|
|
2772
3633
|
exports.dispatchValidationError = dispatchValidationError;
|
|
2773
3634
|
exports.extensionConfig = extensionConfig;
|
|
2774
3635
|
exports.formatZodError = formatZodError;
|
|
2775
3636
|
exports.getAPIInstance = getAPIInstance;
|
|
2776
3637
|
exports.getPaymentsBalanceRetrieve = getPaymentsBalanceRetrieve;
|
|
3638
|
+
exports.getPaymentsCurrenciesEstimateRetrieve = getPaymentsCurrenciesEstimateRetrieve;
|
|
2777
3639
|
exports.getPaymentsCurrenciesList = getPaymentsCurrenciesList;
|
|
3640
|
+
exports.getPaymentsCurrenciesWithdrawalEstimateRetrieve = getPaymentsCurrenciesWithdrawalEstimateRetrieve;
|
|
2778
3641
|
exports.getPaymentsPaymentsList = getPaymentsPaymentsList;
|
|
2779
3642
|
exports.getPaymentsPaymentsRetrieve = getPaymentsPaymentsRetrieve;
|
|
2780
3643
|
exports.getPaymentsPaymentsStatusRetrieve = getPaymentsPaymentsStatusRetrieve;
|
|
2781
3644
|
exports.getPaymentsTransactionsList = getPaymentsTransactionsList;
|
|
3645
|
+
exports.getPaymentsWithdrawalsList = getPaymentsWithdrawalsList;
|
|
3646
|
+
exports.getPaymentsWithdrawalsRetrieve = getPaymentsWithdrawalsRetrieve;
|
|
2782
3647
|
exports.isAPIConfigured = isAPIConfigured;
|
|
2783
3648
|
exports.onValidationError = onValidationError;
|
|
2784
|
-
exports.openCreatePaymentDialog = openCreatePaymentDialog;
|
|
2785
|
-
exports.openPaymentDetailsDialog = openPaymentDetailsDialog;
|
|
2786
3649
|
exports.reconfigureAPI = reconfigureAPI;
|
|
2787
3650
|
exports.resetAPI = resetAPI;
|
|
2788
3651
|
exports.shouldRetry = shouldRetry;
|