@djangocfg/layouts 1.0.4 → 1.0.5

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 (28) hide show
  1. package/package.json +5 -5
  2. package/src/layouts/PaymentsLayout/PaymentsLayout.tsx +47 -65
  3. package/src/layouts/PaymentsLayout/components/CreatePaymentDialog.tsx +118 -163
  4. package/src/layouts/PaymentsLayout/components/PaymentDetailsDialog.tsx +31 -45
  5. package/src/layouts/PaymentsLayout/components/index.ts +1 -4
  6. package/src/layouts/PaymentsLayout/events.ts +23 -84
  7. package/src/layouts/PaymentsLayout/index.ts +7 -11
  8. package/src/layouts/PaymentsLayout/types.ts +3 -16
  9. package/src/layouts/PaymentsLayout/views/overview/components/BalanceCard.tsx +45 -16
  10. package/src/layouts/PaymentsLayout/views/overview/components/RecentPayments.tsx +16 -12
  11. package/src/layouts/PaymentsLayout/views/overview/components/index.ts +0 -2
  12. package/src/layouts/PaymentsLayout/views/overview/index.tsx +3 -6
  13. package/src/layouts/PaymentsLayout/views/payments/components/PaymentsList.tsx +50 -30
  14. package/src/layouts/PaymentsLayout/views/payments/components/index.ts +0 -1
  15. package/src/layouts/PaymentsLayout/views/payments/index.tsx +1 -2
  16. package/src/layouts/PaymentsLayout/views/transactions/components/TransactionsList.tsx +273 -0
  17. package/src/layouts/PaymentsLayout/views/transactions/components/index.ts +1 -0
  18. package/src/layouts/PaymentsLayout/views/transactions/index.tsx +5 -17
  19. package/src/layouts/PaymentsLayout/README.md +0 -133
  20. package/src/layouts/PaymentsLayout/components/CreateApiKeyDialog.tsx +0 -172
  21. package/src/layouts/PaymentsLayout/components/DeleteApiKeyDialog.tsx +0 -100
  22. package/src/layouts/PaymentsLayout/context/RootPaymentsContext.tsx +0 -129
  23. package/src/layouts/PaymentsLayout/views/apikeys/components/ApiKeyMetrics.tsx +0 -109
  24. package/src/layouts/PaymentsLayout/views/apikeys/components/ApiKeysList.tsx +0 -194
  25. package/src/layouts/PaymentsLayout/views/apikeys/components/index.ts +0 -3
  26. package/src/layouts/PaymentsLayout/views/apikeys/index.tsx +0 -19
  27. package/src/layouts/PaymentsLayout/views/overview/components/MetricsCards.tsx +0 -103
  28. package/src/layouts/PaymentsLayout/views/tariffs/index.tsx +0 -29
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Payment Details Dialog
2
+ * Payment Details Dialog (v2.0 - Simplified)
3
3
  * Shows payment details with QR code, address, and status
4
4
  */
5
5
 
@@ -19,11 +19,7 @@ import {
19
19
  import { Copy, ExternalLink, CheckCircle2, Clock, XCircle, AlertCircle, RefreshCw } from 'lucide-react';
20
20
  import { Hooks, api } from '@djangocfg/api';
21
21
  import type { API } from '@djangocfg/api';
22
-
23
- export const PAYMENT_DETAILS_EVENTS = {
24
- OPEN_PAYMENT_DETAILS: 'open-payment-details',
25
- CLOSE_PAYMENT_DETAILS: 'close-payment-details',
26
- } as const;
22
+ import { PAYMENT_EVENTS } from '../events';
27
23
 
28
24
  export const PaymentDetailsDialog: React.FC = () => {
29
25
  const [open, setOpen] = useState(false);
@@ -32,25 +28,17 @@ export const PaymentDetailsDialog: React.FC = () => {
32
28
  const [timeLeft, setTimeLeft] = useState<string>('');
33
29
 
34
30
  // Load payment data by ID using hook
35
- // Only fetch when dialog is open and paymentId is set
36
31
  const shouldFetch = open && !!paymentId;
37
- const { data: payment, isLoading, error, mutate } = Hooks.usePaymentsPaymentRetrieve(
32
+ const { data: payment, isLoading, error, mutate } = Hooks.usePaymentsPaymentsRetrieve(
38
33
  shouldFetch ? paymentId : '',
39
34
  api as unknown as API
40
35
  );
41
36
 
42
- // Debug logging
43
- useEffect(() => {
44
- if (error) {
45
- console.error('Payment loading error:', error);
46
- }
47
- }, [error]);
48
-
37
+ // Listen for open/close events
49
38
  useEffect(() => {
50
39
  const handleOpen = (event: Event) => {
51
- const customEvent = event as CustomEvent<{ paymentId: string }>;
52
- console.log('Opening payment details for ID:', customEvent.detail.paymentId);
53
- setPaymentId(customEvent.detail.paymentId);
40
+ const customEvent = event as CustomEvent<{ id: string }>;
41
+ setPaymentId(customEvent.detail.id);
54
42
  setOpen(true);
55
43
  };
56
44
 
@@ -59,17 +47,18 @@ export const PaymentDetailsDialog: React.FC = () => {
59
47
  setPaymentId(null);
60
48
  };
61
49
 
62
- window.addEventListener(PAYMENT_DETAILS_EVENTS.OPEN_PAYMENT_DETAILS, handleOpen);
63
- window.addEventListener(PAYMENT_DETAILS_EVENTS.CLOSE_PAYMENT_DETAILS, handleClose);
50
+ window.addEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
51
+ window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose);
64
52
 
65
53
  return () => {
66
- window.removeEventListener(PAYMENT_DETAILS_EVENTS.OPEN_PAYMENT_DETAILS, handleOpen);
67
- window.removeEventListener(PAYMENT_DETAILS_EVENTS.CLOSE_PAYMENT_DETAILS, handleClose);
54
+ window.removeEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
55
+ window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose);
68
56
  };
69
57
  }, []);
70
58
 
71
59
  const handleClose = () => {
72
60
  setOpen(false);
61
+ setPaymentId(null);
73
62
  };
74
63
 
75
64
  const handleCopyAddress = async () => {
@@ -109,15 +98,19 @@ export const PaymentDetailsDialog: React.FC = () => {
109
98
 
110
99
  // Get status icon and color
111
100
  const getStatusInfo = () => {
112
- switch (payment?.status) {
101
+ switch (payment?.status?.toLowerCase()) {
113
102
  case 'pending':
114
103
  return { icon: Clock, color: 'text-yellow-500', bg: 'bg-yellow-500/10' };
115
104
  case 'completed':
105
+ case 'success':
116
106
  return { icon: CheckCircle2, color: 'text-green-500', bg: 'bg-green-500/10' };
117
107
  case 'failed':
108
+ case 'error':
118
109
  return { icon: XCircle, color: 'text-red-500', bg: 'bg-red-500/10' };
119
110
  case 'expired':
120
111
  return { icon: AlertCircle, color: 'text-gray-500', bg: 'bg-gray-500/10' };
112
+ case 'confirming':
113
+ return { icon: RefreshCw, color: 'text-blue-500', bg: 'bg-blue-500/10' };
121
114
  default:
122
115
  return { icon: Clock, color: 'text-gray-500', bg: 'bg-gray-500/10' };
123
116
  }
@@ -142,7 +135,7 @@ export const PaymentDetailsDialog: React.FC = () => {
142
135
  );
143
136
  }
144
137
 
145
- // Error state - only show error if we actually tried to fetch and failed
138
+ // Error state
146
139
  if (shouldFetch && !isLoading && (error || !payment)) {
147
140
  return (
148
141
  <Dialog open={open} onOpenChange={(isOpen) => !isOpen && handleClose()}>
@@ -166,7 +159,7 @@ export const PaymentDetailsDialog: React.FC = () => {
166
159
  const statusInfo = getStatusInfo();
167
160
  const StatusIcon = statusInfo.icon;
168
161
 
169
- // Generate QR code URL (using simple data URL)
162
+ // Generate QR code URL
170
163
  const qrCodeUrl = payment.pay_address
171
164
  ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}`
172
165
  : null;
@@ -200,29 +193,31 @@ export const PaymentDetailsDialog: React.FC = () => {
200
193
  <div className="flex items-center justify-between p-4 bg-muted rounded-sm">
201
194
  <span className="text-sm text-muted-foreground">Amount to send</span>
202
195
  <div className="flex items-center gap-2">
203
- <TokenIcon symbol={String(payment.currency || 'BTC')} size={20} />
196
+ <TokenIcon symbol={String(payment.currency_code || 'BTC')} size={20} />
204
197
  <span className="font-mono font-bold text-lg">
205
- {payment.amount_crypto?.toFixed(8)} {payment.currency}
198
+ {payment.pay_amount || '0.00000000'} {payment.currency_code}
206
199
  </span>
207
200
  </div>
208
201
  </div>
209
202
 
210
203
  <div className="flex items-center justify-between px-4">
211
204
  <span className="text-sm text-muted-foreground">Equivalent to</span>
212
- <span className="font-semibold text-lg">${payment.amount_usd?.toFixed(2)} USD</span>
205
+ <span className="font-semibold text-lg">
206
+ ${parseFloat(payment.amount_usd || '0').toFixed(2)} USD
207
+ </span>
213
208
  </div>
214
209
 
215
- {payment.provider_payment_id && (
210
+ {payment.internal_payment_id && (
216
211
  <div className="flex items-center justify-between px-4">
217
212
  <span className="text-sm text-muted-foreground">Payment Order #</span>
218
- <span className="font-mono font-medium">{payment.provider_payment_id}</span>
213
+ <span className="font-mono font-medium">{payment.internal_payment_id}</span>
219
214
  </div>
220
215
  )}
221
216
 
222
- {payment.network && (
217
+ {payment.currency_network && (
223
218
  <div className="flex items-center justify-between px-4">
224
219
  <span className="text-sm text-muted-foreground">Network</span>
225
- <span className="font-medium">{payment.network}</span>
220
+ <span className="font-medium">{payment.currency_network}</span>
226
221
  </div>
227
222
  )}
228
223
  </div>
@@ -303,21 +298,12 @@ export const PaymentDetailsDialog: React.FC = () => {
303
298
  <Button variant="outline" onClick={handleClose}>
304
299
  Close
305
300
  </Button>
301
+ <Button onClick={() => mutate()} variant="ghost" size="sm">
302
+ <RefreshCw className="h-4 w-4 mr-2" />
303
+ Refresh
304
+ </Button>
306
305
  </DialogFooter>
307
306
  </DialogContent>
308
307
  </Dialog>
309
308
  );
310
309
  };
311
-
312
- // Helper function to open payment details dialog
313
- export const openPaymentDetails = (paymentId: string) => {
314
- window.dispatchEvent(
315
- new CustomEvent(PAYMENT_DETAILS_EVENTS.OPEN_PAYMENT_DETAILS, {
316
- detail: { paymentId },
317
- })
318
- );
319
- };
320
-
321
- export const closePaymentDetails = () => {
322
- window.dispatchEvent(new Event(PAYMENT_DETAILS_EVENTS.CLOSE_PAYMENT_DETAILS));
323
- };
@@ -1,5 +1,2 @@
1
- export { CreateApiKeyDialog } from './CreateApiKeyDialog';
2
- export { DeleteApiKeyDialog } from './DeleteApiKeyDialog';
3
1
  export { CreatePaymentDialog } from './CreatePaymentDialog';
4
- export { PaymentDetailsDialog, openPaymentDetails, closePaymentDetails } from './PaymentDetailsDialog';
5
-
2
+ export { PaymentDetailsDialog } from './PaymentDetailsDialog';
@@ -1,106 +1,45 @@
1
1
  /**
2
- * Payments Layout Events
3
- * Event-based communication for dialogs and actions
2
+ * Payment Events System (v2.0 - Simplified)
3
+ *
4
+ * Event-based communication for dialogs using DOM events
5
+ * Removed: API Keys events (deprecated)
4
6
  */
5
7
 
6
- import { events } from '@djangocfg/ui';
7
- import type { APIKeyDetail, Payment } from './types';
8
-
9
8
  // ─────────────────────────────────────────────────────────────────────────
10
- // Dialog Events
9
+ // Event Names
11
10
  // ─────────────────────────────────────────────────────────────────────────
12
11
 
13
- export const PAYMENTS_DIALOG_EVENTS = {
14
- // API Keys
15
- OPEN_CREATE_APIKEY_DIALOG: 'OPEN_CREATE_APIKEY_DIALOG',
16
- OPEN_EDIT_APIKEY_DIALOG: 'OPEN_EDIT_APIKEY_DIALOG',
17
- OPEN_DELETE_APIKEY_DIALOG: 'OPEN_DELETE_APIKEY_DIALOG',
18
-
19
- // Payments
20
- OPEN_CREATE_PAYMENT_DIALOG: 'OPEN_CREATE_PAYMENT_DIALOG',
21
- OPEN_PAYMENT_DETAILS_DIALOG: 'OPEN_PAYMENT_DETAILS_DIALOG',
22
- OPEN_CANCEL_PAYMENT_DIALOG: 'OPEN_CANCEL_PAYMENT_DIALOG',
23
-
24
- // Close
25
- CLOSE_PAYMENTS_DIALOG: 'CLOSE_PAYMENTS_DIALOG',
12
+ export const PAYMENT_EVENTS = {
13
+ OPEN_CREATE_PAYMENT_DIALOG: 'payments:open-create-payment',
14
+ OPEN_PAYMENT_DETAILS_DIALOG: 'payments:open-payment-details',
15
+ CLOSE_DIALOG: 'payments:close-dialog',
26
16
  } as const;
27
17
 
28
18
  // ─────────────────────────────────────────────────────────────────────────
29
19
  // Event Types
30
20
  // ─────────────────────────────────────────────────────────────────────────
31
21
 
32
- export interface PaymentsDialogEvent {
33
- type: typeof PAYMENTS_DIALOG_EVENTS[keyof typeof PAYMENTS_DIALOG_EVENTS];
34
- payload?: {
35
- // API Keys
36
- keyId?: string;
37
- keyData?: APIKeyDetail;
38
- initialKeyData?: Partial<APIKeyDetail>;
39
-
40
- // Payments
41
- paymentId?: string;
42
- paymentData?: Payment;
43
- initialPaymentData?: Partial<Payment>;
44
- };
45
- }
46
-
47
- // ─────────────────────────────────────────────────────────────────────────
48
- // API Keys Events
49
- // ─────────────────────────────────────────────────────────────────────────
50
-
51
- export const openCreateApiKeyDialog = (initialData?: Partial<APIKeyDetail>) => {
52
- events.publish({
53
- type: PAYMENTS_DIALOG_EVENTS.OPEN_CREATE_APIKEY_DIALOG,
54
- payload: { initialKeyData: initialData },
55
- });
56
- };
57
-
58
- export const openEditApiKeyDialog = (keyId: string, keyData?: APIKeyDetail) => {
59
- events.publish({
60
- type: PAYMENTS_DIALOG_EVENTS.OPEN_EDIT_APIKEY_DIALOG,
61
- payload: { keyId, keyData },
62
- });
63
- };
64
-
65
- export const openDeleteApiKeyDialog = (keyId: string, keyData?: APIKeyDetail) => {
66
- events.publish({
67
- type: PAYMENTS_DIALOG_EVENTS.OPEN_DELETE_APIKEY_DIALOG,
68
- payload: { keyId, keyData },
69
- });
70
- };
22
+ export type PaymentEvent =
23
+ | { type: 'OPEN_CREATE_PAYMENT' }
24
+ | { type: 'OPEN_PAYMENT_DETAILS'; id: string }
25
+ | { type: 'CLOSE_DIALOG' };
71
26
 
72
27
  // ─────────────────────────────────────────────────────────────────────────
73
- // Payments Events
28
+ // Helper Functions
74
29
  // ─────────────────────────────────────────────────────────────────────────
75
30
 
76
- export const openCreatePaymentDialog = (initialData?: Partial<Payment>) => {
77
- events.publish({
78
- type: PAYMENTS_DIALOG_EVENTS.OPEN_CREATE_PAYMENT_DIALOG,
79
- payload: { initialPaymentData: initialData },
80
- });
81
- };
82
-
83
- export const openPaymentDetailsDialog = (paymentId: string, paymentData?: Payment) => {
84
- events.publish({
85
- type: PAYMENTS_DIALOG_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG,
86
- payload: { paymentId, paymentData },
87
- });
31
+ export const openCreatePaymentDialog = () => {
32
+ window.dispatchEvent(new Event(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG));
88
33
  };
89
34
 
90
- export const openCancelPaymentDialog = (paymentId: string, paymentData?: Payment) => {
91
- events.publish({
92
- type: PAYMENTS_DIALOG_EVENTS.OPEN_CANCEL_PAYMENT_DIALOG,
93
- payload: { paymentId, paymentData },
94
- });
35
+ export const openPaymentDetailsDialog = (id: string) => {
36
+ window.dispatchEvent(
37
+ new CustomEvent(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, {
38
+ detail: { id },
39
+ })
40
+ );
95
41
  };
96
42
 
97
- // ─────────────────────────────────────────────────────────────────────────
98
- // Close Events
99
- // ─────────────────────────────────────────────────────────────────────────
100
-
101
43
  export const closePaymentsDialog = () => {
102
- events.publish({
103
- type: PAYMENTS_DIALOG_EVENTS.CLOSE_PAYMENTS_DIALOG,
104
- });
44
+ window.dispatchEvent(new Event(PAYMENT_EVENTS.CLOSE_DIALOG));
105
45
  };
106
-
@@ -1,20 +1,16 @@
1
1
  /**
2
- * Payments Layout
3
- * Export main layout and types
2
+ * Payments Layout (v2.0 - Simplified)
3
+ *
4
+ * Exports:
5
+ * - PaymentsLayout: Main layout component
6
+ * - PaymentTab: Tab type definition
7
+ * - Payment events: openCreatePaymentDialog, openPaymentDetailsDialog, closePaymentsDialog
4
8
  */
5
9
 
6
10
  export { PaymentsLayout } from './PaymentsLayout';
7
- export type { PaymentsLayoutProps } from './PaymentsLayout';
8
11
  export type { PaymentTab } from './types';
9
-
10
- // Re-export events for convenience
11
12
  export {
12
- openCreateApiKeyDialog,
13
- openEditApiKeyDialog,
14
- openDeleteApiKeyDialog,
15
13
  openCreatePaymentDialog,
16
14
  openPaymentDetailsDialog,
17
- openCancelPaymentDialog,
18
- closePaymentsDialog,
15
+ closePaymentsDialog
19
16
  } from './events';
20
-
@@ -1,19 +1,6 @@
1
1
  /**
2
- * Payments Layout Types
2
+ * Payments Layout Types (v2.0 - Simplified)
3
3
  */
4
4
 
5
- // Tab types for navigation
6
- export type PaymentTab = 'overview' | 'payments' | 'transactions' | 'apikeys' | 'tariffs';
7
-
8
- // Re-export API types for convenience
9
- export type {
10
- Payment,
11
- UserBalance,
12
- Currency,
13
- APIKeyDetail,
14
- PaginatedPaymentListList,
15
- PaginatedUserBalanceList,
16
- PaginatedCurrencyListList,
17
- PaginatedAPIKeyListList,
18
- } from '@djangocfg/api/cfg/contexts';
19
-
5
+ // Tab types for navigation (removed apikeys and tariffs)
6
+ export type PaymentTab = 'overview' | 'payments' | 'transactions';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Balance Card Component
2
+ * Balance Card Component (v2.0 - Simplified)
3
3
  * Display user balance with quick actions
4
4
  */
5
5
 
@@ -21,9 +21,9 @@ import { openCreatePaymentDialog } from '../../../events';
21
21
 
22
22
  export const BalanceCard: React.FC = () => {
23
23
  const {
24
- balanceSummary,
25
- isLoadingSummary,
26
- refreshSummary
24
+ balance,
25
+ isLoadingBalance,
26
+ refreshBalance
27
27
  } = useOverviewContext();
28
28
 
29
29
  const formatCurrency = (amount?: number | null) => {
@@ -35,7 +35,20 @@ export const BalanceCard: React.FC = () => {
35
35
  }).format(amount);
36
36
  };
37
37
 
38
- if (isLoadingSummary) {
38
+ const formatDate = (dateStr?: string) => {
39
+ if (!dateStr) return 'No transactions yet';
40
+ try {
41
+ return new Date(dateStr).toLocaleDateString('en-US', {
42
+ year: 'numeric',
43
+ month: 'short',
44
+ day: 'numeric',
45
+ });
46
+ } catch {
47
+ return 'Invalid date';
48
+ }
49
+ };
50
+
51
+ if (isLoadingBalance) {
39
52
  return (
40
53
  <Card>
41
54
  <CardHeader>
@@ -55,6 +68,14 @@ export const BalanceCard: React.FC = () => {
55
68
  );
56
69
  }
57
70
 
71
+ // Extract balance data from response: { success, balance: { amount_usd, total_deposited, total_withdrawn, last_transaction_at } }
72
+ const balanceData = balance?.balance || balance;
73
+ const amountUsd = balanceData?.amount_usd ?? 0;
74
+ const totalDeposited = balanceData?.total_deposited ?? 0;
75
+ const totalWithdrawn = balanceData?.total_withdrawn ?? 0;
76
+ const lastTransactionAt = balanceData?.last_transaction_at;
77
+ const isEmpty = amountUsd === 0 && totalDeposited === 0;
78
+
58
79
  return (
59
80
  <Card>
60
81
  <CardHeader>
@@ -64,7 +85,7 @@ export const BalanceCard: React.FC = () => {
64
85
  Account Balance
65
86
  </div>
66
87
  <div className="flex items-center gap-2">
67
- <Button variant="ghost" size="sm" onClick={refreshSummary}>
88
+ <Button variant="ghost" size="sm" onClick={refreshBalance}>
68
89
  <RefreshCw className="h-4 w-4" />
69
90
  </Button>
70
91
  <Button size="sm" onClick={() => openCreatePaymentDialog()}>
@@ -77,23 +98,31 @@ export const BalanceCard: React.FC = () => {
77
98
  <CardContent className="space-y-4">
78
99
  <div>
79
100
  <div className="text-4xl font-bold">
80
- {balanceSummary ? formatCurrency(balanceSummary.balance_usd) : '$0.00'}
101
+ {formatCurrency(amountUsd)}
81
102
  </div>
82
103
  <p className="text-sm text-muted-foreground mt-1">
83
- {balanceSummary?.balance_display || 'No balance available'}
104
+ Available balance Last updated {formatDate(lastTransactionAt)}
84
105
  </p>
85
106
  </div>
86
107
 
87
- {balanceSummary && (
88
- <div className="flex items-center gap-2">
89
- <Badge variant={balanceSummary.has_transactions ? 'default' : 'secondary'}>
90
- {balanceSummary.has_transactions ? 'Active' : 'New Account'}
91
- </Badge>
92
- {balanceSummary.is_empty && <Badge variant="outline">Empty Balance</Badge>}
108
+ <div className="grid grid-cols-2 gap-4 pt-4 border-t">
109
+ <div>
110
+ <p className="text-xs text-muted-foreground">Total Deposited</p>
111
+ <p className="text-lg font-semibold text-green-600">{formatCurrency(totalDeposited)}</p>
112
+ </div>
113
+ <div>
114
+ <p className="text-xs text-muted-foreground">Total Withdrawn</p>
115
+ <p className="text-lg font-semibold text-red-600">{formatCurrency(totalWithdrawn)}</p>
93
116
  </div>
94
- )}
117
+ </div>
118
+
119
+ <div className="flex items-center gap-2">
120
+ <Badge variant={!isEmpty ? 'default' : 'secondary'}>
121
+ {!isEmpty ? 'Active' : 'New Account'}
122
+ </Badge>
123
+ {isEmpty && <Badge variant="outline">Empty Balance</Badge>}
124
+ </div>
95
125
  </CardContent>
96
126
  </Card>
97
127
  );
98
128
  };
99
-
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Recent Payments Component
3
- * Display recent payment transactions
2
+ * Recent Payments Component (v2.0 - Simplified)
3
+ * Display recent payment transactions from payments list
4
4
  */
5
5
 
6
6
  'use client';
@@ -20,15 +20,16 @@ import { useOverviewContext } from '@djangocfg/api/cfg/contexts';
20
20
  import { openPaymentDetailsDialog } from '../../../events';
21
21
 
22
22
  export const RecentPayments: React.FC = () => {
23
- const { recentPayments, isLoadingOverview } = useOverviewContext();
23
+ const { payments, isLoadingPayments } = useOverviewContext();
24
24
 
25
- const formatCurrency = (amount?: number | null) => {
25
+ const formatCurrency = (amount?: number | string | null) => {
26
26
  if (amount === null || amount === undefined) return '$0.00';
27
+ const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
27
28
  return new Intl.NumberFormat('en-US', {
28
29
  style: 'currency',
29
30
  currency: 'USD',
30
31
  minimumFractionDigits: 2,
31
- }).format(amount);
32
+ }).format(numAmount);
32
33
  };
33
34
 
34
35
  const getRelativeTime = (date: string | null | undefined): string => {
@@ -52,16 +53,18 @@ export const RecentPayments: React.FC = () => {
52
53
  case 'success':
53
54
  return 'default';
54
55
  case 'pending':
56
+ case 'confirming':
55
57
  return 'secondary';
56
58
  case 'failed':
57
59
  case 'error':
60
+ case 'expired':
58
61
  return 'destructive';
59
62
  default:
60
63
  return 'outline';
61
64
  }
62
65
  };
63
66
 
64
- if (isLoadingOverview) {
67
+ if (isLoadingPayments) {
65
68
  return (
66
69
  <Card>
67
70
  <CardHeader>
@@ -85,7 +88,8 @@ export const RecentPayments: React.FC = () => {
85
88
  );
86
89
  }
87
90
 
88
- const payments = recentPayments?.results || [];
91
+ // Get first 5 payments for recent list
92
+ const recentPaymentsList = payments?.results?.slice(0, 5) || [];
89
93
 
90
94
  return (
91
95
  <Card>
@@ -102,18 +106,19 @@ export const RecentPayments: React.FC = () => {
102
106
  </CardTitle>
103
107
  </CardHeader>
104
108
  <CardContent>
105
- {payments.length === 0 ? (
109
+ {recentPaymentsList.length === 0 ? (
106
110
  <div className="text-center py-8 text-muted-foreground">
107
111
  <History className="h-12 w-12 mx-auto mb-4 opacity-50" />
108
112
  <p>No recent payments</p>
113
+ <p className="text-sm mt-2">Create your first payment to get started</p>
109
114
  </div>
110
115
  ) : (
111
116
  <div className="space-y-3">
112
- {payments.map((payment) => (
117
+ {recentPaymentsList.map((payment) => (
113
118
  <div
114
119
  key={payment.id}
115
120
  className="flex items-center justify-between p-3 border rounded-sm hover:bg-accent cursor-pointer transition-colors"
116
- onClick={() => openPaymentDetailsDialog(payment.id)}
121
+ onClick={() => openPaymentDetailsDialog(String(payment.id))}
117
122
  >
118
123
  <div className="flex-1">
119
124
  <div className="flex items-center gap-2">
@@ -123,7 +128,7 @@ export const RecentPayments: React.FC = () => {
123
128
  </Badge>
124
129
  </div>
125
130
  <p className="text-sm text-muted-foreground">
126
- {getRelativeTime(payment.created_at)} • {payment.provider || 'Unknown provider'}
131
+ {getRelativeTime(payment.created_at)} • {payment.currency_code || 'USD'}
127
132
  </p>
128
133
  </div>
129
134
  <ExternalLink className="h-4 w-4 text-muted-foreground" />
@@ -135,4 +140,3 @@ export const RecentPayments: React.FC = () => {
135
140
  </Card>
136
141
  );
137
142
  };
138
-
@@ -1,4 +1,2 @@
1
- export { MetricsCards } from './MetricsCards';
2
1
  export { BalanceCard } from './BalanceCard';
3
2
  export { RecentPayments } from './RecentPayments';
4
-
@@ -1,18 +1,16 @@
1
1
  /**
2
- * Overview View
3
- * Dashboard with metrics, balance, and recent activity
2
+ * Overview View (v2.0 - Simplified)
3
+ * Dashboard with balance and recent payments
4
4
  */
5
5
 
6
6
  'use client';
7
7
 
8
8
  import React from 'react';
9
- import { MetricsCards, BalanceCard, RecentPayments } from './components';
9
+ import { BalanceCard, RecentPayments } from './components';
10
10
 
11
11
  export const OverviewView: React.FC = () => {
12
12
  return (
13
13
  <div className="space-y-6">
14
- <MetricsCards />
15
-
16
14
  <div className="grid gap-6 lg:grid-cols-2">
17
15
  <BalanceCard />
18
16
  <RecentPayments />
@@ -20,4 +18,3 @@ export const OverviewView: React.FC = () => {
20
18
  </div>
21
19
  );
22
20
  };
23
-