@djangocfg/layouts 2.1.10 → 2.1.15

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 (107) hide show
  1. package/README.md +53 -161
  2. package/package.json +6 -6
  3. package/src/components/RedirectPage/RedirectPage.tsx +1 -1
  4. package/src/index.ts +0 -6
  5. package/src/layouts/AppLayout/AppLayout.tsx +1 -1
  6. package/src/layouts/AppLayout/BaseApp.tsx +1 -1
  7. package/src/layouts/AuthLayout/AuthContext.tsx +1 -1
  8. package/src/layouts/AuthLayout/OAuthCallback.tsx +1 -1
  9. package/src/layouts/AuthLayout/OAuthProviders.tsx +1 -1
  10. package/src/layouts/PrivateLayout/PrivateLayout.tsx +1 -1
  11. package/src/layouts/PrivateLayout/components/PrivateHeader.tsx +1 -1
  12. package/src/layouts/ProfileLayout/ProfileLayout.tsx +2 -2
  13. package/src/layouts/ProfileLayout/components/AvatarSection.tsx +2 -2
  14. package/src/layouts/ProfileLayout/components/ProfileForm.tsx +2 -2
  15. package/src/layouts/PublicLayout/components/PublicMobileDrawer.tsx +1 -1
  16. package/src/layouts/PublicLayout/components/PublicNavigation.tsx +1 -1
  17. package/src/layouts/_components/UserMenu.tsx +1 -1
  18. package/src/layouts/index.ts +0 -2
  19. package/src/snippets/Analytics/useAnalytics.ts +1 -1
  20. package/src/snippets/index.ts +0 -3
  21. package/src/auth/README.md +0 -962
  22. package/src/auth/context/AccountsContext.tsx +0 -240
  23. package/src/auth/context/AuthContext.tsx +0 -604
  24. package/src/auth/context/index.ts +0 -4
  25. package/src/auth/context/types.ts +0 -68
  26. package/src/auth/hooks/index.ts +0 -17
  27. package/src/auth/hooks/useAuthForm.ts +0 -332
  28. package/src/auth/hooks/useAuthGuard.ts +0 -25
  29. package/src/auth/hooks/useAuthRedirect.ts +0 -51
  30. package/src/auth/hooks/useAutoAuth.ts +0 -49
  31. package/src/auth/hooks/useGithubAuth.ts +0 -184
  32. package/src/auth/hooks/useLocalStorage.ts +0 -214
  33. package/src/auth/hooks/useProfileCache.ts +0 -146
  34. package/src/auth/hooks/useSessionStorage.ts +0 -189
  35. package/src/auth/index.ts +0 -10
  36. package/src/auth/middlewares/index.ts +0 -1
  37. package/src/auth/middlewares/proxy.ts +0 -32
  38. package/src/auth/server.ts +0 -6
  39. package/src/auth/utils/errors.ts +0 -34
  40. package/src/auth/utils/index.ts +0 -2
  41. package/src/auth/utils/validation.ts +0 -14
  42. package/src/contexts/LeadsContext.tsx +0 -156
  43. package/src/contexts/NewsletterContext.tsx +0 -263
  44. package/src/contexts/SupportContext.tsx +0 -256
  45. package/src/contexts/index.ts +0 -59
  46. package/src/contexts/knowbase/ChatContext.tsx +0 -174
  47. package/src/contexts/knowbase/DocumentsContext.tsx +0 -304
  48. package/src/contexts/knowbase/SessionsContext.tsx +0 -174
  49. package/src/contexts/knowbase/index.ts +0 -61
  50. package/src/contexts/payments/BalancesContext.tsx +0 -65
  51. package/src/contexts/payments/CurrenciesContext.tsx +0 -66
  52. package/src/contexts/payments/OverviewContext.tsx +0 -174
  53. package/src/contexts/payments/PaymentsContext.tsx +0 -132
  54. package/src/contexts/payments/README.md +0 -201
  55. package/src/contexts/payments/RootPaymentsContext.tsx +0 -68
  56. package/src/contexts/payments/index.ts +0 -50
  57. package/src/layouts/PaymentsLayout/PaymentsLayout.tsx +0 -92
  58. package/src/layouts/PaymentsLayout/components/CreatePaymentDialog.tsx +0 -291
  59. package/src/layouts/PaymentsLayout/components/PaymentDetailsDialog.tsx +0 -290
  60. package/src/layouts/PaymentsLayout/components/index.ts +0 -2
  61. package/src/layouts/PaymentsLayout/events.ts +0 -47
  62. package/src/layouts/PaymentsLayout/index.ts +0 -16
  63. package/src/layouts/PaymentsLayout/types.ts +0 -6
  64. package/src/layouts/PaymentsLayout/views/overview/components/BalanceCard.tsx +0 -128
  65. package/src/layouts/PaymentsLayout/views/overview/components/RecentPayments.tsx +0 -142
  66. package/src/layouts/PaymentsLayout/views/overview/components/index.ts +0 -2
  67. package/src/layouts/PaymentsLayout/views/overview/index.tsx +0 -20
  68. package/src/layouts/PaymentsLayout/views/payments/components/PaymentsList.tsx +0 -276
  69. package/src/layouts/PaymentsLayout/views/payments/components/index.ts +0 -1
  70. package/src/layouts/PaymentsLayout/views/payments/index.tsx +0 -17
  71. package/src/layouts/PaymentsLayout/views/transactions/components/TransactionsList.tsx +0 -273
  72. package/src/layouts/PaymentsLayout/views/transactions/components/index.ts +0 -1
  73. package/src/layouts/PaymentsLayout/views/transactions/index.tsx +0 -17
  74. package/src/layouts/SupportLayout/README.md +0 -91
  75. package/src/layouts/SupportLayout/SupportLayout.tsx +0 -179
  76. package/src/layouts/SupportLayout/components/CreateTicketDialog.tsx +0 -155
  77. package/src/layouts/SupportLayout/components/MessageInput.tsx +0 -92
  78. package/src/layouts/SupportLayout/components/MessageList.tsx +0 -314
  79. package/src/layouts/SupportLayout/components/TicketCard.tsx +0 -96
  80. package/src/layouts/SupportLayout/components/TicketList.tsx +0 -153
  81. package/src/layouts/SupportLayout/components/index.ts +0 -6
  82. package/src/layouts/SupportLayout/context/SupportLayoutContext.tsx +0 -263
  83. package/src/layouts/SupportLayout/context/index.ts +0 -2
  84. package/src/layouts/SupportLayout/events.ts +0 -33
  85. package/src/layouts/SupportLayout/hooks/index.ts +0 -2
  86. package/src/layouts/SupportLayout/hooks/useInfiniteMessages.ts +0 -119
  87. package/src/layouts/SupportLayout/hooks/useInfiniteTickets.ts +0 -92
  88. package/src/layouts/SupportLayout/index.ts +0 -8
  89. package/src/layouts/SupportLayout/types.ts +0 -21
  90. package/src/snippets/Chat/ChatUIContext.tsx +0 -110
  91. package/src/snippets/Chat/ChatWidget.tsx +0 -476
  92. package/src/snippets/Chat/README.md +0 -122
  93. package/src/snippets/Chat/components/MessageInput.tsx +0 -124
  94. package/src/snippets/Chat/components/MessageList.tsx +0 -169
  95. package/src/snippets/Chat/components/SessionList.tsx +0 -192
  96. package/src/snippets/Chat/components/index.ts +0 -9
  97. package/src/snippets/Chat/hooks/index.ts +0 -6
  98. package/src/snippets/Chat/hooks/useInfiniteSessions.ts +0 -82
  99. package/src/snippets/Chat/index.tsx +0 -45
  100. package/src/snippets/Chat/types.ts +0 -80
  101. package/src/snippets/ContactForm/ContactForm.tsx +0 -346
  102. package/src/snippets/ContactForm/ContactFormProvider.tsx +0 -153
  103. package/src/snippets/ContactForm/ContactInfo.tsx +0 -114
  104. package/src/snippets/ContactForm/ContactPage.tsx +0 -131
  105. package/src/snippets/ContactForm/dynamic.tsx +0 -55
  106. package/src/snippets/ContactForm/index.ts +0 -34
  107. package/src/snippets/ContactForm/types.ts +0 -110
@@ -1,291 +0,0 @@
1
- // @ts-nocheck
2
- /**
3
- * Create Payment Dialog (v2.0 - Simplified)
4
- * Dialog for creating new payments
5
- */
6
-
7
- 'use client';
8
-
9
- import React, { useState, useEffect, useMemo } from 'react';
10
- import {
11
- Dialog,
12
- DialogContent,
13
- DialogDescription,
14
- DialogFooter,
15
- DialogHeader,
16
- DialogTitle,
17
- Form,
18
- FormControl,
19
- FormDescription,
20
- FormField,
21
- FormItem,
22
- FormLabel,
23
- FormMessage,
24
- Input,
25
- Select,
26
- SelectContent,
27
- SelectItem,
28
- SelectTrigger,
29
- SelectValue,
30
- Button,
31
- TokenIcon,
32
- } from '@djangocfg/ui-nextjs';
33
- import { Plus, RefreshCw } from 'lucide-react';
34
- import { useForm } from 'react-hook-form';
35
- import { zodResolver } from '@hookform/resolvers/zod';
36
- import { z } from 'zod';
37
- import { usePaymentsContext, useRootPaymentsContext } from '@djangocfg/layouts/contexts';
38
- import { PAYMENT_EVENTS, closePaymentsDialog } from '../events';
39
- import { openPaymentDetailsDialog } from '../events';
40
- import { paymentsLogger } from '../../../utils/logger';
41
-
42
- // Payment creation schema
43
- const PaymentCreateSchema = z.object({
44
- amount_usd: z.number().min(0.01, 'Amount must be at least $0.01'),
45
- currency_code: z.string().min(1, 'Please select a currency'),
46
- });
47
-
48
- type PaymentCreateRequest = z.infer<typeof PaymentCreateSchema>;
49
-
50
- export const CreatePaymentDialog: React.FC = () => {
51
- const [open, setOpen] = useState(false);
52
- const [isSubmitting, setIsSubmitting] = useState(false);
53
-
54
- const { createPayment } = usePaymentsContext();
55
- const { currencies, isLoadingCurrencies } = useRootPaymentsContext();
56
-
57
- const form = useForm<PaymentCreateRequest>({
58
- resolver: zodResolver(PaymentCreateSchema),
59
- defaultValues: {
60
- amount_usd: 10,
61
- currency_code: 'USDT',
62
- },
63
- });
64
-
65
- // Extract currencies list from response (handle different possible structures)
66
- const currenciesList = useMemo(() => {
67
- const data = currencies?.currencies || currencies?.results || currencies || [];
68
- return Array.isArray(data) ? data : [];
69
- }, [currencies]);
70
-
71
- // Get currency options for select
72
- const currencyOptions = useMemo(() => {
73
- return currenciesList
74
- .filter((curr: any) => curr.is_enabled !== false)
75
- .map((curr: any) => ({
76
- code: curr.code || curr.currency_code || curr.symbol,
77
- name: curr.name || curr.code || curr.currency_code,
78
- usd_rate: curr.usd_rate || curr.rate || 1,
79
- network: curr.network || null,
80
- }));
81
- }, [currenciesList]);
82
-
83
- // Calculate crypto amount from USD
84
- const calculateCryptoAmount = useMemo(() => {
85
- const amountUsd = form.watch('amount_usd');
86
- const currencyCode = form.watch('currency_code');
87
- const currency = currencyOptions.find((c: any) => c.code === currencyCode);
88
-
89
- if (!currency || !currency.usd_rate || !amountUsd) {
90
- return null;
91
- }
92
-
93
- const cryptoAmount = amountUsd / currency.usd_rate;
94
- return {
95
- amount: cryptoAmount,
96
- currency: currency.code,
97
- rate: currency.usd_rate,
98
- network: currency.network,
99
- };
100
- }, [form.watch('amount_usd'), form.watch('currency_code'), currencyOptions]);
101
-
102
- // Listen for open/close events
103
- useEffect(() => {
104
- const handleOpen = () => setOpen(true);
105
- const handleClose = () => setOpen(false);
106
-
107
- window.addEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
108
- window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose);
109
-
110
- return () => {
111
- window.removeEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
112
- window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose);
113
- };
114
- }, []);
115
-
116
- const handleClose = () => {
117
- setOpen(false);
118
- form.reset();
119
- };
120
-
121
- // Initialize default currency if not set
122
- useEffect(() => {
123
- if (currencyOptions.length > 0 && !form.getValues('currency_code')) {
124
- form.setValue('currency_code', currencyOptions[0].code);
125
- }
126
- }, [currencyOptions, form]);
127
-
128
- const handleSubmit = async (data: PaymentCreateRequest) => {
129
- try {
130
- setIsSubmitting(true);
131
-
132
- const result = await createPayment();
133
- handleClose();
134
- closePaymentsDialog();
135
-
136
- // Extract payment ID from result
137
- const paymentData = result as any;
138
- const paymentId = paymentData?.payment?.id || paymentData?.id;
139
-
140
- if (paymentId) {
141
- openPaymentDetailsDialog(String(paymentId));
142
- }
143
- } catch (error) {
144
- paymentsLogger.error('Failed to create payment:', error);
145
- } finally {
146
- setIsSubmitting(false);
147
- }
148
- };
149
-
150
- return (
151
- <Dialog open={open} onOpenChange={(isOpen) => !isOpen && handleClose()}>
152
- <DialogContent className="sm:max-w-md">
153
- <DialogHeader>
154
- <DialogTitle>Create Payment</DialogTitle>
155
- <DialogDescription>
156
- Create a new payment to add funds to your account.
157
- </DialogDescription>
158
- </DialogHeader>
159
-
160
- <Form {...form}>
161
- <form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-4">
162
- <FormField
163
- control={form.control}
164
- name="amount_usd"
165
- render={({ field }) => (
166
- <FormItem>
167
- <FormLabel>Amount (USD)</FormLabel>
168
- <FormControl>
169
- <Input
170
- type="number"
171
- step="0.01"
172
- min="0.01"
173
- placeholder="10.00"
174
- {...field}
175
- onChange={(e) => field.onChange(parseFloat(e.target.value) || 0)}
176
- />
177
- </FormControl>
178
- <FormDescription>
179
- The amount you want to pay in USD.
180
- </FormDescription>
181
- <FormMessage />
182
- </FormItem>
183
- )}
184
- />
185
-
186
- <FormField
187
- control={form.control}
188
- name="currency_code"
189
- render={({ field }) => (
190
- <FormItem>
191
- <FormLabel>Currency</FormLabel>
192
- <Select
193
- onValueChange={field.onChange}
194
- defaultValue={field.value}
195
- disabled={isLoadingCurrencies}
196
- >
197
- <FormControl>
198
- <SelectTrigger>
199
- <SelectValue placeholder="Select currency..." />
200
- </SelectTrigger>
201
- </FormControl>
202
- <SelectContent>
203
- {currencyOptions.map((curr: any) => (
204
- <SelectItem key={curr.code} value={curr.code}>
205
- <div className="flex items-center gap-2">
206
- <TokenIcon symbol={curr.code} size={16} />
207
- <span>{curr.code}</span>
208
- {curr.network && (
209
- <span className="text-xs text-muted-foreground">
210
- ({curr.network})
211
- </span>
212
- )}
213
- </div>
214
- </SelectItem>
215
- ))}
216
- </SelectContent>
217
- </Select>
218
- <FormDescription>
219
- The cryptocurrency to use for payment.
220
- </FormDescription>
221
- <FormMessage />
222
- </FormItem>
223
- )}
224
- />
225
-
226
- {/* Conversion Information */}
227
- {calculateCryptoAmount && (
228
- <div className="rounded-sm bg-muted p-4 space-y-3">
229
- {/* Amount to Send in Crypto */}
230
- <div className="flex items-center justify-between">
231
- <span className="text-sm text-muted-foreground">You will send</span>
232
- <div className="flex items-center gap-2">
233
- <TokenIcon symbol={calculateCryptoAmount.currency} size={16} />
234
- <span className="font-mono font-semibold">
235
- {calculateCryptoAmount.amount.toFixed(8)} {calculateCryptoAmount.currency}
236
- </span>
237
- </div>
238
- </div>
239
-
240
- {/* USD Amount Received */}
241
- <div className="flex items-center justify-between">
242
- <span className="text-sm text-muted-foreground">You will receive</span>
243
- <span className="text-lg font-bold">
244
- ${form.watch('amount_usd')?.toFixed(2)} USD
245
- </span>
246
- </div>
247
-
248
- {/* Exchange Rate */}
249
- <div className="flex items-center justify-between text-xs">
250
- <span className="text-muted-foreground">Rate</span>
251
- <span className="font-medium">
252
- 1 {calculateCryptoAmount.currency} = ${calculateCryptoAmount.rate?.toFixed(2)}
253
- </span>
254
- </div>
255
-
256
- {/* Network Info */}
257
- {calculateCryptoAmount.network && (
258
- <div className="border-t pt-3">
259
- <div className="flex items-center justify-between">
260
- <span className="text-sm text-muted-foreground">Network</span>
261
- <span className="text-sm font-medium">{calculateCryptoAmount.network}</span>
262
- </div>
263
- </div>
264
- )}
265
- </div>
266
- )}
267
-
268
- <DialogFooter>
269
- <Button type="button" variant="outline" onClick={handleClose} disabled={isSubmitting}>
270
- Cancel
271
- </Button>
272
- <Button type="submit" disabled={isSubmitting || currencyOptions.length === 0}>
273
- {isSubmitting ? (
274
- <>
275
- <RefreshCw className="h-4 w-4 mr-2 animate-spin" />
276
- Creating...
277
- </>
278
- ) : (
279
- <>
280
- <Plus className="h-4 w-4 mr-2" />
281
- Create Payment
282
- </>
283
- )}
284
- </Button>
285
- </DialogFooter>
286
- </form>
287
- </Form>
288
- </DialogContent>
289
- </Dialog>
290
- );
291
- };
@@ -1,290 +0,0 @@
1
- /**
2
- * Payment Details Dialog (v2.0 - Simplified)
3
- * Shows payment details with QR code, address, and status
4
- */
5
-
6
- 'use client';
7
-
8
- import React, { useState, useEffect } from 'react';
9
- import {
10
- Dialog,
11
- DialogContent,
12
- DialogDescription,
13
- DialogFooter,
14
- DialogHeader,
15
- DialogTitle,
16
- Button,
17
- TokenIcon,
18
- CopyButton,
19
- } from '@djangocfg/ui-nextjs';
20
- import { ExternalLink, CheckCircle2, Clock, XCircle, AlertCircle, RefreshCw } from 'lucide-react';
21
- import { Hooks, api } from '@djangocfg/api';
22
- import type { API } from '@djangocfg/api';
23
- import { PAYMENT_EVENTS } from '../events';
24
-
25
- export const PaymentDetailsDialog: React.FC = () => {
26
- const [open, setOpen] = useState(false);
27
- const [paymentId, setPaymentId] = useState<string | null>(null);
28
- const [timeLeft, setTimeLeft] = useState<string>('');
29
-
30
- // Load payment data by ID using hook
31
- const shouldFetch = open && !!paymentId;
32
- const { data: payment, isLoading, error, mutate } = Hooks.usePaymentsPaymentsRetrieve(
33
- shouldFetch ? paymentId : '',
34
- api as unknown as API
35
- );
36
-
37
- // Listen for open/close events
38
- useEffect(() => {
39
- const handleOpen = (event: Event) => {
40
- const customEvent = event as CustomEvent<{ id: string }>;
41
- setPaymentId(customEvent.detail.id);
42
- setOpen(true);
43
- };
44
-
45
- const handleClose = () => {
46
- setOpen(false);
47
- setPaymentId(null);
48
- };
49
-
50
- window.addEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
51
- window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose);
52
-
53
- return () => {
54
- window.removeEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
55
- window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose);
56
- };
57
- }, []);
58
-
59
- const handleClose = () => {
60
- setOpen(false);
61
- setPaymentId(null);
62
- };
63
-
64
- // Calculate time left until expiration
65
- useEffect(() => {
66
- if (!payment?.expires_at) return;
67
-
68
- const updateTimeLeft = () => {
69
- const now = new Date().getTime();
70
- const expires = new Date(payment.expires_at!).getTime();
71
- const diff = expires - now;
72
-
73
- if (diff <= 0) {
74
- setTimeLeft('Expired');
75
- return;
76
- }
77
-
78
- const hours = Math.floor(diff / (1000 * 60 * 60));
79
- const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
80
- const seconds = Math.floor((diff % (1000 * 60)) / 1000);
81
-
82
- setTimeLeft(`${hours}h ${minutes}m ${seconds}s`);
83
- };
84
-
85
- updateTimeLeft();
86
- const interval = setInterval(updateTimeLeft, 1000);
87
-
88
- return () => clearInterval(interval);
89
- }, [payment?.expires_at]);
90
-
91
- // Get status icon and color
92
- const getStatusInfo = () => {
93
- switch (payment?.status?.toLowerCase()) {
94
- case 'pending':
95
- return { icon: Clock, color: 'text-yellow-500', bg: 'bg-yellow-500/10' };
96
- case 'completed':
97
- case 'success':
98
- return { icon: CheckCircle2, color: 'text-green-500', bg: 'bg-green-500/10' };
99
- case 'failed':
100
- case 'error':
101
- return { icon: XCircle, color: 'text-red-500', bg: 'bg-red-500/10' };
102
- case 'expired':
103
- return { icon: AlertCircle, color: 'text-gray-500', bg: 'bg-gray-500/10' };
104
- case 'confirming':
105
- return { icon: RefreshCw, color: 'text-blue-500', bg: 'bg-blue-500/10' };
106
- default:
107
- return { icon: Clock, color: 'text-gray-500', bg: 'bg-gray-500/10' };
108
- }
109
- };
110
-
111
- if (!open) return null;
112
-
113
- // Loading state
114
- if (isLoading) {
115
- return (
116
- <Dialog open={open} onOpenChange={(isOpen) => !isOpen && handleClose()}>
117
- <DialogContent className="sm:max-w-lg">
118
- <DialogHeader>
119
- <DialogTitle>Payment Details</DialogTitle>
120
- <DialogDescription>Loading payment information...</DialogDescription>
121
- </DialogHeader>
122
- <div className="flex items-center justify-center py-12">
123
- <RefreshCw className="h-8 w-8 animate-spin text-muted-foreground" />
124
- </div>
125
- </DialogContent>
126
- </Dialog>
127
- );
128
- }
129
-
130
- // Error state
131
- if (shouldFetch && !isLoading && (error || !payment)) {
132
- return (
133
- <Dialog open={open} onOpenChange={(isOpen) => !isOpen && handleClose()}>
134
- <DialogContent className="sm:max-w-lg">
135
- <DialogHeader>
136
- <DialogTitle>Payment Details</DialogTitle>
137
- <DialogDescription>Failed to load payment information</DialogDescription>
138
- </DialogHeader>
139
- <div className="flex flex-col items-center justify-center py-12 space-y-4">
140
- <XCircle className="h-12 w-12 text-destructive" />
141
- <p className="text-sm text-muted-foreground">
142
- {error ? `Error: ${error}` : 'Payment not found'}
143
- </p>
144
- <Button onClick={() => mutate()}>Try Again</Button>
145
- </div>
146
- </DialogContent>
147
- </Dialog>
148
- );
149
- }
150
-
151
- const statusInfo = getStatusInfo();
152
- const StatusIcon = statusInfo.icon;
153
-
154
- // Generate QR code URL
155
- const qrCodeUrl = payment.pay_address
156
- ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}`
157
- : null;
158
-
159
- return (
160
- <Dialog open={open} onOpenChange={(isOpen) => !isOpen && handleClose()}>
161
- <DialogContent className="sm:max-w-lg">
162
- <DialogHeader>
163
- <DialogTitle>Payment Details</DialogTitle>
164
- <DialogDescription>
165
- Send cryptocurrency to complete your payment
166
- </DialogDescription>
167
- </DialogHeader>
168
-
169
- <div className="space-y-6">
170
- {/* Status Badge */}
171
- <div className={`flex items-center gap-3 p-4 rounded-sm ${statusInfo.bg}`}>
172
- <StatusIcon className={`h-5 w-5 ${statusInfo.color}`} />
173
- <div className="flex-1">
174
- <div className="font-semibold capitalize">{payment.status}</div>
175
- {payment.status === 'pending' && timeLeft && (
176
- <div className="text-sm text-muted-foreground">
177
- Expires in {timeLeft}
178
- </div>
179
- )}
180
- </div>
181
- </div>
182
-
183
- {/* Amount Information */}
184
- <div className="space-y-3">
185
- <div className="flex items-center justify-between p-4 bg-muted rounded-sm">
186
- <span className="text-sm text-muted-foreground">Amount to send</span>
187
- <div className="flex items-center gap-2">
188
- <TokenIcon symbol={String(payment.currency_code || 'BTC')} size={20} />
189
- <span className="font-mono font-bold text-lg">
190
- {payment.pay_amount || '0.00000000'} {payment.currency_code}
191
- </span>
192
- </div>
193
- </div>
194
-
195
- <div className="flex items-center justify-between px-4">
196
- <span className="text-sm text-muted-foreground">Equivalent to</span>
197
- <span className="font-semibold text-lg">
198
- ${parseFloat(payment.amount_usd || '0').toFixed(2)} USD
199
- </span>
200
- </div>
201
-
202
- {payment.internal_payment_id && (
203
- <div className="flex items-center justify-between px-4">
204
- <span className="text-sm text-muted-foreground">Payment Order #</span>
205
- <span className="font-mono font-medium">{payment.internal_payment_id}</span>
206
- </div>
207
- )}
208
-
209
- {payment.currency_network && (
210
- <div className="flex items-center justify-between px-4">
211
- <span className="text-sm text-muted-foreground">Network</span>
212
- <span className="font-medium">{payment.currency_network}</span>
213
- </div>
214
- )}
215
- </div>
216
-
217
- {/* QR Code */}
218
- {qrCodeUrl && payment.status === 'pending' && (
219
- <div className="flex justify-center p-6 bg-white rounded-sm">
220
- <img src={qrCodeUrl} alt="Payment QR Code" className="w-48 h-48" />
221
- </div>
222
- )}
223
-
224
- {/* Payment Address */}
225
- {payment.pay_address && payment.status === 'pending' && (
226
- <div className="space-y-2">
227
- <label className="text-sm font-medium">Payment Address</label>
228
- <div className="flex items-center gap-2">
229
- <div className="flex-1 p-3 bg-muted rounded-sm font-mono text-sm break-all">
230
- {payment.pay_address}
231
- </div>
232
- <CopyButton value={payment.pay_address} variant="outline" />
233
- </div>
234
- </div>
235
- )}
236
-
237
- {/* Transaction Hash */}
238
- {payment.transaction_hash && (
239
- <div className="space-y-2">
240
- <label className="text-sm font-medium">Transaction Hash</label>
241
- <div className="p-3 bg-muted rounded-sm font-mono text-sm break-all">
242
- {payment.transaction_hash}
243
- </div>
244
- </div>
245
- )}
246
-
247
- {/* Payment URL */}
248
- {payment.payment_url && payment.status === 'pending' && (
249
- <Button
250
- variant="outline"
251
- className="w-full"
252
- onClick={() => window.open(payment.payment_url!, '_blank')}
253
- >
254
- <ExternalLink className="h-4 w-4 mr-2" />
255
- Open in Payment Provider
256
- </Button>
257
- )}
258
-
259
- {/* Additional Info */}
260
- <div className="pt-4 border-t space-y-2 text-xs text-muted-foreground">
261
- <div className="flex justify-between">
262
- <span>Payment ID</span>
263
- <span className="font-mono">{payment.id}</span>
264
- </div>
265
- <div className="flex justify-between">
266
- <span>Created</span>
267
- <span>{new Date(payment.created_at!).toLocaleString()}</span>
268
- </div>
269
- {payment.confirmations_count !== undefined && (
270
- <div className="flex justify-between">
271
- <span>Confirmations</span>
272
- <span>{payment.confirmations_count}</span>
273
- </div>
274
- )}
275
- </div>
276
- </div>
277
-
278
- <DialogFooter>
279
- <Button variant="outline" onClick={handleClose}>
280
- Close
281
- </Button>
282
- <Button onClick={() => mutate()} variant="ghost" size="sm">
283
- <RefreshCw className="h-4 w-4 mr-2" />
284
- Refresh
285
- </Button>
286
- </DialogFooter>
287
- </DialogContent>
288
- </Dialog>
289
- );
290
- };
@@ -1,2 +0,0 @@
1
- export { CreatePaymentDialog } from './CreatePaymentDialog';
2
- export { PaymentDetailsDialog } from './PaymentDetailsDialog';
@@ -1,47 +0,0 @@
1
- "use client"
2
-
3
- /**
4
- * Payment Events System (v2.0 - Simplified)
5
- *
6
- * Event-based communication for dialogs using DOM events
7
- * Removed: API Keys events (deprecated)
8
- */
9
-
10
- // ─────────────────────────────────────────────────────────────────────────
11
- // Event Names
12
- // ─────────────────────────────────────────────────────────────────────────
13
-
14
- export const PAYMENT_EVENTS = {
15
- OPEN_CREATE_PAYMENT_DIALOG: 'payments:open-create-payment',
16
- OPEN_PAYMENT_DETAILS_DIALOG: 'payments:open-payment-details',
17
- CLOSE_DIALOG: 'payments:close-dialog',
18
- } as const;
19
-
20
- // ─────────────────────────────────────────────────────────────────────────
21
- // Event Types
22
- // ─────────────────────────────────────────────────────────────────────────
23
-
24
- export type PaymentEvent =
25
- | { type: 'OPEN_CREATE_PAYMENT' }
26
- | { type: 'OPEN_PAYMENT_DETAILS'; id: string }
27
- | { type: 'CLOSE_DIALOG' };
28
-
29
- // ─────────────────────────────────────────────────────────────────────────
30
- // Helper Functions
31
- // ─────────────────────────────────────────────────────────────────────────
32
-
33
- export const openCreatePaymentDialog = () => {
34
- window.dispatchEvent(new Event(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG));
35
- };
36
-
37
- export const openPaymentDetailsDialog = (id: string) => {
38
- window.dispatchEvent(
39
- new CustomEvent(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, {
40
- detail: { id },
41
- })
42
- );
43
- };
44
-
45
- export const closePaymentsDialog = () => {
46
- window.dispatchEvent(new Event(PAYMENT_EVENTS.CLOSE_DIALOG));
47
- };
@@ -1,16 +0,0 @@
1
- /**
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
8
- */
9
-
10
- export { PaymentsLayout } from './PaymentsLayout';
11
- export type { PaymentTab } from './types';
12
- export {
13
- openCreatePaymentDialog,
14
- openPaymentDetailsDialog,
15
- closePaymentsDialog
16
- } from './events';
@@ -1,6 +0,0 @@
1
- /**
2
- * Payments Layout Types (v2.0 - Simplified)
3
- */
4
-
5
- // Tab types for navigation (removed apikeys and tariffs)
6
- export type PaymentTab = 'overview' | 'payments' | 'transactions';