@djangocfg/ext-payments 1.0.13 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/config.cjs +5 -8
  2. package/dist/config.js +5 -8
  3. package/dist/hooks.cjs +1 -1
  4. package/dist/hooks.js +1 -1
  5. package/dist/index.cjs +1085 -1107
  6. package/dist/index.d.cts +480 -41
  7. package/dist/index.d.ts +480 -41
  8. package/dist/index.js +1037 -1093
  9. package/package.json +13 -16
  10. package/src/api/generated/ext_payments/CLAUDE.md +7 -3
  11. package/src/api/generated/ext_payments/_utils/fetchers/ext_payments__payments.ts +237 -5
  12. package/src/api/generated/ext_payments/_utils/hooks/ext_payments__payments.ts +71 -3
  13. package/src/api/generated/ext_payments/_utils/schemas/PaginatedWithdrawalListList.schema.ts +24 -0
  14. package/src/api/generated/ext_payments/_utils/schemas/PaymentCreateRequest.schema.ts +21 -0
  15. package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCreateRequest.schema.ts +21 -0
  16. package/src/api/generated/ext_payments/_utils/schemas/WithdrawalDetail.schema.ts +42 -0
  17. package/src/api/generated/ext_payments/_utils/schemas/WithdrawalList.schema.ts +29 -0
  18. package/src/api/generated/ext_payments/_utils/schemas/index.ts +5 -0
  19. package/src/api/generated/ext_payments/enums.ts +36 -0
  20. package/src/api/generated/ext_payments/ext_payments__payments/client.ts +58 -5
  21. package/src/api/generated/ext_payments/ext_payments__payments/models.ts +141 -0
  22. package/src/api/generated/ext_payments/schema.json +579 -3
  23. package/src/components/ActivityItem.tsx +118 -0
  24. package/src/components/ActivityList.tsx +93 -0
  25. package/src/components/AddFundsSheet.tsx +258 -0
  26. package/src/components/BalanceHero.tsx +102 -0
  27. package/src/components/PaymentSheet.tsx +290 -0
  28. package/src/components/ResponsiveSheet.tsx +151 -0
  29. package/src/components/WithdrawSheet.tsx +329 -0
  30. package/src/components/index.ts +18 -0
  31. package/src/contexts/WalletContext.tsx +355 -0
  32. package/src/contexts/index.ts +12 -45
  33. package/src/index.ts +6 -18
  34. package/src/contexts/BalancesContext.tsx +0 -63
  35. package/src/contexts/CurrenciesContext.tsx +0 -64
  36. package/src/contexts/OverviewContext.tsx +0 -173
  37. package/src/contexts/PaymentsContext.tsx +0 -122
  38. package/src/contexts/PaymentsExtensionProvider.tsx +0 -56
  39. package/src/contexts/README.md +0 -201
  40. package/src/contexts/RootPaymentsContext.tsx +0 -66
  41. package/src/contexts/types.ts +0 -40
  42. package/src/hooks/index.ts +0 -20
  43. package/src/layouts/PaymentsLayout/PaymentsLayout.tsx +0 -90
  44. package/src/layouts/PaymentsLayout/components/CreatePaymentDialog.tsx +0 -274
  45. package/src/layouts/PaymentsLayout/components/PaymentDetailsDialog.tsx +0 -287
  46. package/src/layouts/PaymentsLayout/components/index.ts +0 -2
  47. package/src/layouts/PaymentsLayout/events.ts +0 -47
  48. package/src/layouts/PaymentsLayout/index.ts +0 -16
  49. package/src/layouts/PaymentsLayout/types.ts +0 -6
  50. package/src/layouts/PaymentsLayout/views/overview/components/BalanceCard.tsx +0 -121
  51. package/src/layouts/PaymentsLayout/views/overview/components/RecentPayments.tsx +0 -139
  52. package/src/layouts/PaymentsLayout/views/overview/components/index.ts +0 -2
  53. package/src/layouts/PaymentsLayout/views/overview/index.tsx +0 -21
  54. package/src/layouts/PaymentsLayout/views/payments/components/PaymentsList.tsx +0 -279
  55. package/src/layouts/PaymentsLayout/views/payments/components/index.ts +0 -1
  56. package/src/layouts/PaymentsLayout/views/payments/index.tsx +0 -18
  57. package/src/layouts/PaymentsLayout/views/transactions/components/TransactionsList.tsx +0 -260
  58. package/src/layouts/PaymentsLayout/views/transactions/components/index.ts +0 -1
  59. package/src/layouts/PaymentsLayout/views/transactions/index.tsx +0 -18
@@ -0,0 +1,355 @@
1
+ /**
2
+ * Wallet Context (Apple-style unified)
3
+ *
4
+ * Single context for all wallet operations:
5
+ * - Balance
6
+ * - Activity (payments + transactions merged)
7
+ * - Currencies
8
+ * - Payment operations
9
+ */
10
+
11
+ 'use client';
12
+
13
+ import React, { createContext, ReactNode, useContext, useMemo, useCallback } from 'react';
14
+
15
+ import { apiPayments } from '../api';
16
+ import * as Fetchers from '../api/generated/ext_payments/_utils/fetchers';
17
+ import {
18
+ usePaymentsBalanceRetrieve,
19
+ usePaymentsPaymentsList,
20
+ usePaymentsTransactionsList,
21
+ usePaymentsCurrenciesList,
22
+ usePaymentsWithdrawalsList,
23
+ useCreatePaymentsPaymentsCreateCreate,
24
+ useCreatePaymentsWithdrawalsCreateCreate,
25
+ useCreatePaymentsWithdrawalsCancelCreate,
26
+ } from '../api/generated/ext_payments/_utils/hooks';
27
+
28
+ import type {
29
+ Balance,
30
+ PaymentList,
31
+ Transaction,
32
+ PaymentCreateRequest,
33
+ PaymentDetail,
34
+ WithdrawalCreateRequest,
35
+ WithdrawalDetail,
36
+ WithdrawalList,
37
+ } from '../api/generated/ext_payments/_utils/schemas';
38
+
39
+ // ─────────────────────────────────────────────────────────────────────────────
40
+ // Types
41
+ // ─────────────────────────────────────────────────────────────────────────────
42
+
43
+ export type ActivityType = 'payment' | 'deposit' | 'withdrawal';
44
+
45
+ export interface ActivityItem {
46
+ id: string;
47
+ type: ActivityType;
48
+ amount: string;
49
+ amountDisplay: string;
50
+ currency?: string;
51
+ status: 'pending' | 'completed' | 'failed' | 'expired' | 'confirming';
52
+ statusDisplay: string;
53
+ description: string;
54
+ createdAt: string;
55
+ // Original data for details
56
+ payment?: PaymentList;
57
+ transaction?: Transaction;
58
+ withdrawal?: WithdrawalList;
59
+ }
60
+
61
+ export interface Currency {
62
+ code: string;
63
+ name: string;
64
+ network?: string;
65
+ rate: number;
66
+ enabled: boolean;
67
+ }
68
+
69
+ export interface WalletContextValue {
70
+ // Balance
71
+ balance: Balance | undefined;
72
+ balanceAmount: number;
73
+ isLoadingBalance: boolean;
74
+
75
+ // Activity (merged payments + transactions)
76
+ activity: ActivityItem[];
77
+ isLoadingActivity: boolean;
78
+ hasMoreActivity: boolean;
79
+
80
+ // Currencies
81
+ currencies: Currency[];
82
+ isLoadingCurrencies: boolean;
83
+
84
+ // Operations
85
+ addFunds: (data: PaymentCreateRequest) => Promise<PaymentDetail>;
86
+ withdraw: (data: WithdrawalCreateRequest) => Promise<WithdrawalDetail>;
87
+ cancelWithdrawal: (id: string) => Promise<void>;
88
+ getPaymentDetails: (id: string) => Promise<PaymentDetail | undefined>;
89
+ getWithdrawalDetails: (id: string) => Promise<WithdrawalDetail | undefined>;
90
+ refreshWallet: () => Promise<void>;
91
+
92
+ // Loading state
93
+ isLoading: boolean;
94
+ }
95
+
96
+ // ─────────────────────────────────────────────────────────────────────────────
97
+ // Context
98
+ // ─────────────────────────────────────────────────────────────────────────────
99
+
100
+ const WalletContext = createContext<WalletContextValue | undefined>(undefined);
101
+
102
+ // ─────────────────────────────────────────────────────────────────────────────
103
+ // Provider
104
+ // ─────────────────────────────────────────────────────────────────────────────
105
+
106
+ export function WalletProvider({ children }: { children: ReactNode }) {
107
+ // Fetch balance
108
+ const {
109
+ data: balance,
110
+ isLoading: isLoadingBalance,
111
+ mutate: mutateBalance,
112
+ } = usePaymentsBalanceRetrieve(apiPayments);
113
+
114
+ // Fetch recent payments
115
+ const {
116
+ data: paymentsData,
117
+ isLoading: isLoadingPayments,
118
+ mutate: mutatePayments,
119
+ } = usePaymentsPaymentsList({ page: 1, page_size: 20 }, apiPayments);
120
+
121
+ // Fetch recent transactions
122
+ const {
123
+ data: transactionsData,
124
+ isLoading: isLoadingTransactions,
125
+ mutate: mutateTransactions,
126
+ } = usePaymentsTransactionsList({ limit: 20 }, apiPayments);
127
+
128
+ // Fetch currencies
129
+ const {
130
+ data: currenciesData,
131
+ isLoading: isLoadingCurrencies,
132
+ mutate: mutateCurrencies,
133
+ } = usePaymentsCurrenciesList(apiPayments);
134
+
135
+ // Fetch recent withdrawals
136
+ const {
137
+ data: withdrawalsData,
138
+ isLoading: isLoadingWithdrawals,
139
+ mutate: mutateWithdrawals,
140
+ } = usePaymentsWithdrawalsList({ page: 1, page_size: 20 }, apiPayments);
141
+
142
+ // Mutation hooks
143
+ const createPaymentMutation = useCreatePaymentsPaymentsCreateCreate();
144
+ const createWithdrawalMutation = useCreatePaymentsWithdrawalsCreateCreate();
145
+ const cancelWithdrawalMutation = useCreatePaymentsWithdrawalsCancelCreate();
146
+
147
+ // Parse balance amount
148
+ const balanceAmount = useMemo(() => {
149
+ if (!balance?.balance_usd) return 0;
150
+ return parseFloat(balance.balance_usd) || 0;
151
+ }, [balance]);
152
+
153
+ // Merge and sort activity (payments + withdrawals + transactions)
154
+ const activity = useMemo<ActivityItem[]>(() => {
155
+ const items: ActivityItem[] = [];
156
+
157
+ // Add payments (deposits)
158
+ const payments = paymentsData?.results || [];
159
+ for (const payment of payments) {
160
+ items.push({
161
+ id: `payment-${payment.id}`,
162
+ type: 'payment',
163
+ amount: payment.amount_usd,
164
+ amountDisplay: `+$${parseFloat(payment.amount_usd).toFixed(2)}`,
165
+ currency: payment.currency_code,
166
+ status: mapPaymentStatus(payment.status),
167
+ statusDisplay: payment.status_display,
168
+ description: `${payment.currency_code} payment`,
169
+ createdAt: payment.created_at,
170
+ payment,
171
+ });
172
+ }
173
+
174
+ // Add withdrawals
175
+ const withdrawals = withdrawalsData?.results || [];
176
+ for (const withdrawal of withdrawals) {
177
+ items.push({
178
+ id: `withdrawal-${withdrawal.id}`,
179
+ type: 'withdrawal',
180
+ amount: withdrawal.amount_usd,
181
+ amountDisplay: `-$${parseFloat(withdrawal.amount_usd).toFixed(2)}`,
182
+ currency: withdrawal.currency_code,
183
+ status: mapWithdrawalStatus(withdrawal.status),
184
+ statusDisplay: withdrawal.status_display,
185
+ description: `${withdrawal.currency_code} withdrawal`,
186
+ createdAt: withdrawal.created_at,
187
+ withdrawal,
188
+ });
189
+ }
190
+
191
+ // Add transactions (only if not linked to a payment/withdrawal already shown)
192
+ const transactions = transactionsData?.results || transactionsData || [];
193
+ if (Array.isArray(transactions)) {
194
+ for (const tx of transactions) {
195
+ // Skip if this transaction is linked to a payment we already have
196
+ if (tx.payment_id && payments.some(p => p.id === tx.payment_id)) {
197
+ continue;
198
+ }
199
+
200
+ const isDeposit = tx.transaction_type === 'deposit';
201
+ items.push({
202
+ id: `tx-${tx.id}`,
203
+ type: isDeposit ? 'deposit' : 'withdrawal',
204
+ amount: tx.amount_usd,
205
+ amountDisplay: `${isDeposit ? '+' : '-'}$${Math.abs(parseFloat(tx.amount_usd)).toFixed(2)}`,
206
+ status: 'completed',
207
+ statusDisplay: 'Completed',
208
+ description: tx.description || tx.type_display,
209
+ createdAt: tx.created_at,
210
+ transaction: tx,
211
+ });
212
+ }
213
+ }
214
+
215
+ // Sort by date, newest first
216
+ items.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
217
+
218
+ return items;
219
+ }, [paymentsData, withdrawalsData, transactionsData]);
220
+
221
+ // Parse currencies
222
+ const currencies = useMemo<Currency[]>(() => {
223
+ const data = currenciesData?.currencies || currenciesData?.results || currenciesData || [];
224
+ if (!Array.isArray(data)) return [];
225
+
226
+ return data
227
+ .filter((c: any) => c.is_enabled !== false)
228
+ .map((c: any) => ({
229
+ code: c.code || c.currency_code || c.symbol,
230
+ name: c.name || c.code,
231
+ network: c.network || undefined,
232
+ rate: parseFloat(c.usd_rate || c.rate) || 1,
233
+ enabled: c.is_enabled !== false,
234
+ }));
235
+ }, [currenciesData]);
236
+
237
+ // Operations
238
+ const addFunds = useCallback(async (data: PaymentCreateRequest): Promise<PaymentDetail> => {
239
+ const result = await createPaymentMutation(data, apiPayments);
240
+ // Refresh all data
241
+ await Promise.all([mutateBalance(), mutatePayments(), mutateTransactions()]);
242
+ return result;
243
+ }, [createPaymentMutation, mutateBalance, mutatePayments, mutateTransactions]);
244
+
245
+ const withdraw = useCallback(async (data: WithdrawalCreateRequest): Promise<WithdrawalDetail> => {
246
+ const result = await createWithdrawalMutation(data, apiPayments);
247
+ // Refresh all data
248
+ await Promise.all([mutateBalance(), mutateWithdrawals(), mutateTransactions()]);
249
+ return result;
250
+ }, [createWithdrawalMutation, mutateBalance, mutateWithdrawals, mutateTransactions]);
251
+
252
+ const cancelWithdrawal = useCallback(async (id: string): Promise<void> => {
253
+ await cancelWithdrawalMutation(id, apiPayments);
254
+ // Refresh all data
255
+ await Promise.all([mutateBalance(), mutateWithdrawals(), mutateTransactions()]);
256
+ }, [cancelWithdrawalMutation, mutateBalance, mutateWithdrawals, mutateTransactions]);
257
+
258
+ const getPaymentDetails = useCallback(async (id: string): Promise<PaymentDetail | undefined> => {
259
+ return Fetchers.getPaymentsPaymentsRetrieve(id, apiPayments);
260
+ }, []);
261
+
262
+ const getWithdrawalDetails = useCallback(async (id: string): Promise<WithdrawalDetail | undefined> => {
263
+ return Fetchers.getPaymentsWithdrawalsRetrieve(id, apiPayments);
264
+ }, []);
265
+
266
+ const refreshWallet = useCallback(async () => {
267
+ await Promise.all([
268
+ mutateBalance(),
269
+ mutatePayments(),
270
+ mutateWithdrawals(),
271
+ mutateTransactions(),
272
+ mutateCurrencies(),
273
+ ]);
274
+ }, [mutateBalance, mutatePayments, mutateWithdrawals, mutateTransactions, mutateCurrencies]);
275
+
276
+ // Combined loading state
277
+ const isLoading = isLoadingBalance || isLoadingPayments || isLoadingWithdrawals || isLoadingTransactions;
278
+ const isLoadingActivity = isLoadingPayments || isLoadingWithdrawals || isLoadingTransactions;
279
+
280
+ const value: WalletContextValue = {
281
+ balance,
282
+ balanceAmount,
283
+ isLoadingBalance,
284
+ activity,
285
+ isLoadingActivity,
286
+ hasMoreActivity: (paymentsData?.count || 0) > 20 || (withdrawalsData?.count || 0) > 20,
287
+ currencies,
288
+ isLoadingCurrencies,
289
+ addFunds,
290
+ withdraw,
291
+ cancelWithdrawal,
292
+ getPaymentDetails,
293
+ getWithdrawalDetails,
294
+ refreshWallet,
295
+ isLoading,
296
+ };
297
+
298
+ return <WalletContext.Provider value={value}>{children}</WalletContext.Provider>;
299
+ }
300
+
301
+ // ─────────────────────────────────────────────────────────────────────────────
302
+ // Hook
303
+ // ─────────────────────────────────────────────────────────────────────────────
304
+
305
+ export function useWallet(): WalletContextValue {
306
+ const context = useContext(WalletContext);
307
+ if (!context) {
308
+ throw new Error('useWallet must be used within WalletProvider');
309
+ }
310
+ return context;
311
+ }
312
+
313
+ // ─────────────────────────────────────────────────────────────────────────────
314
+ // Helpers
315
+ // ─────────────────────────────────────────────────────────────────────────────
316
+
317
+ function mapPaymentStatus(status: string): ActivityItem['status'] {
318
+ switch (status?.toLowerCase()) {
319
+ case 'completed':
320
+ case 'success':
321
+ case 'finished':
322
+ return 'completed';
323
+ case 'pending':
324
+ case 'waiting':
325
+ return 'pending';
326
+ case 'confirming':
327
+ case 'partially_paid':
328
+ return 'confirming';
329
+ case 'expired':
330
+ return 'expired';
331
+ case 'failed':
332
+ case 'error':
333
+ case 'cancelled':
334
+ return 'failed';
335
+ default:
336
+ return 'pending';
337
+ }
338
+ }
339
+
340
+ function mapWithdrawalStatus(status: string): ActivityItem['status'] {
341
+ switch (status?.toLowerCase()) {
342
+ case 'completed':
343
+ return 'completed';
344
+ case 'pending':
345
+ case 'approved':
346
+ return 'pending';
347
+ case 'processing':
348
+ return 'confirming';
349
+ case 'rejected':
350
+ case 'cancelled':
351
+ return 'failed';
352
+ default:
353
+ return 'pending';
354
+ }
355
+ }
@@ -1,45 +1,12 @@
1
- // Payments
2
- export {
3
- PaymentsProvider,
4
- usePaymentsContext
5
- } from './PaymentsContext';
6
- export type {
7
- PaymentsContextValue,
8
- } from './PaymentsContext';
9
-
10
- // Balances
11
- export {
12
- BalancesProvider,
13
- useBalancesContext
14
- } from './BalancesContext';
15
- export type {
16
- BalancesContextValue,
17
- } from './BalancesContext';
18
-
19
- // Currencies
20
- export {
21
- CurrenciesProvider,
22
- useCurrenciesContext
23
- } from './CurrenciesContext';
24
- export type {
25
- CurrenciesContextValue,
26
- } from './CurrenciesContext';
27
-
28
- // Overview
29
- export {
30
- OverviewProvider,
31
- useOverviewContext
32
- } from './OverviewContext';
33
- export type {
34
- OverviewContextValue,
35
- } from './OverviewContext';
36
-
37
- // Root Payments (Global)
38
- export {
39
- RootPaymentsProvider,
40
- useRootPaymentsContext
41
- } from './RootPaymentsContext';
42
- export type {
43
- RootPaymentsContextValue,
44
- } from './RootPaymentsContext';
45
-
1
+ /**
2
+ * Wallet Context Exports
3
+ */
4
+
5
+ export {
6
+ WalletProvider,
7
+ useWallet,
8
+ type WalletContextValue,
9
+ type ActivityItem,
10
+ type ActivityType,
11
+ type Currency,
12
+ } from './WalletContext';
package/src/index.ts CHANGED
@@ -1,10 +1,7 @@
1
1
  /**
2
- * @djangocfg/ext-payments
2
+ * Wallet Extension (Apple-style)
3
3
  *
4
- * Payments system extension.
5
- * This entry point is server-safe (no SWR/React hooks).
6
- *
7
- * For React hooks, import from '@djangocfg/ext-payments/hooks'
4
+ * Simplified payments system with single page UX.
8
5
  */
9
6
 
10
7
  // API client (server-safe)
@@ -12,27 +9,18 @@ export * from './api/generated/ext_payments';
12
9
  export { API } from './api/generated/ext_payments';
13
10
  export { apiPayments } from './api';
14
11
 
15
- // Layout components
16
- export { PaymentsLayout } from './layouts/PaymentsLayout';
17
- export type { PaymentsLayoutProps } from './layouts/PaymentsLayout/PaymentsLayout';
18
-
19
- // Events
20
- export * from './layouts/PaymentsLayout/events';
21
-
22
- // Types
23
- export type { PaymentTab } from './layouts/PaymentsLayout/types';
12
+ // Components
13
+ export * from './components';
24
14
 
25
15
  // Re-export API types for convenience
26
16
  export type {
27
17
  Balance,
28
- Currency,
29
18
  PaymentList,
30
19
  PaymentDetail,
20
+ PaymentCreateRequest,
31
21
  Transaction,
32
22
  PaginatedPaymentListList,
33
23
  } from './api/generated/ext_payments/_utils/schemas';
34
24
 
35
- // Note: Hooks are NOT exported here to keep this bundle server-safe
36
- // Use: import { usePaymentsList } from '@djangocfg/ext-payments/hooks'
37
- // Export config
25
+ // Config
38
26
  export { extensionConfig } from './config';
@@ -1,63 +0,0 @@
1
- 'use client';
2
-
3
- import React, { createContext, ReactNode, useContext } from 'react';
4
-
5
- import { apiPayments } from '../api';
6
- import { usePaymentsBalanceRetrieve } from '../api/generated/ext_payments/_utils/hooks';
7
-
8
- // ─────────────────────────────────────────────────────────────────────────
9
- // Context Type
10
- // ─────────────────────────────────────────────────────────────────────────
11
-
12
- export interface BalancesContextValue {
13
- // Balance data - single endpoint returns balance info
14
- balance: any | undefined;
15
- isLoadingBalance: boolean;
16
- balanceError: Error | undefined;
17
- refreshBalance: () => Promise<void>;
18
- }
19
-
20
- // ─────────────────────────────────────────────────────────────────────────
21
- // Context
22
- // ─────────────────────────────────────────────────────────────────────────
23
-
24
- const BalancesContext = createContext<BalancesContextValue | undefined>(undefined);
25
-
26
- // ─────────────────────────────────────────────────────────────────────────
27
- // Provider
28
- // ─────────────────────────────────────────────────────────────────────────
29
-
30
- export function BalancesProvider({ children }: { children: ReactNode }) {
31
- // Get balance from /cfg/payments/balance/
32
- const {
33
- data: balance,
34
- error: balanceError,
35
- isLoading: isLoadingBalance,
36
- mutate: mutateBalance,
37
- } = usePaymentsBalanceRetrieve(apiPayments);
38
-
39
- const refreshBalance = async () => {
40
- await mutateBalance();
41
- };
42
-
43
- const value: BalancesContextValue = {
44
- balance,
45
- isLoadingBalance,
46
- balanceError,
47
- refreshBalance,
48
- };
49
-
50
- return <BalancesContext.Provider value={value}>{children}</BalancesContext.Provider>;
51
- }
52
-
53
- // ─────────────────────────────────────────────────────────────────────────
54
- // Hook
55
- // ─────────────────────────────────────────────────────────────────────────
56
-
57
- export function useBalancesContext(): BalancesContextValue {
58
- const context = useContext(BalancesContext);
59
- if (!context) {
60
- throw new Error('useBalancesContext must be used within BalancesProvider');
61
- }
62
- return context;
63
- }
@@ -1,64 +0,0 @@
1
- 'use client';
2
-
3
- import React, { createContext, ReactNode, useContext } from 'react';
4
-
5
- import { apiPayments } from '../api';
6
- import { usePaymentsCurrenciesList } from '../api/generated/ext_payments/_utils/hooks';
7
-
8
- // ─────────────────────────────────────────────────────────────────────────
9
- // Context Type
10
- // ─────────────────────────────────────────────────────────────────────────
11
-
12
- export interface CurrenciesContextValue {
13
- // Currencies data - returns raw response with currencies array
14
- currencies: any | undefined;
15
- isLoadingCurrencies: boolean;
16
- currenciesError: Error | undefined;
17
- refreshCurrencies: () => Promise<void>;
18
- }
19
-
20
- // ─────────────────────────────────────────────────────────────────────────
21
- // Context
22
- // ─────────────────────────────────────────────────────────────────────────
23
-
24
- const CurrenciesContext = createContext<CurrenciesContextValue | undefined>(undefined);
25
-
26
- // ─────────────────────────────────────────────────────────────────────────
27
- // Provider
28
- // ─────────────────────────────────────────────────────────────────────────
29
-
30
- export function CurrenciesProvider({ children }: { children: ReactNode }) {
31
- // Get currencies list from /cfg/payments/currencies/
32
- const {
33
- data: currencies,
34
- error: currenciesError,
35
- isLoading: isLoadingCurrencies,
36
- mutate: mutateCurrencies,
37
- } = usePaymentsCurrenciesList(apiPayments);
38
-
39
- const refreshCurrencies = async () => {
40
- await mutateCurrencies();
41
- };
42
-
43
- const value: CurrenciesContextValue = {
44
- currencies,
45
- isLoadingCurrencies,
46
- currenciesError,
47
- refreshCurrencies,
48
- };
49
-
50
- return <CurrenciesContext.Provider value={value}>{children}</CurrenciesContext.Provider>;
51
- }
52
-
53
- // ─────────────────────────────────────────────────────────────────────────
54
- // Hook
55
- // ─────────────────────────────────────────────────────────────────────────
56
-
57
- export function useCurrenciesContext(): CurrenciesContextValue {
58
- const context = useContext(CurrenciesContext);
59
- if (!context) {
60
- throw new Error('useCurrenciesContext must be used within CurrenciesProvider');
61
- }
62
- return context;
63
- }
64
-