diff --git a/ui/components/api-key-input.tsx b/ui/components/api-key-input.tsx new file mode 100644 index 00000000..85e62f05 --- /dev/null +++ b/ui/components/api-key-input.tsx @@ -0,0 +1,39 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import * as React from 'react'; +import { Input } from '@/components/ui/input'; + +interface ApiKeyInputProps extends React.ComponentProps<'input'> { + onApiKeyChange: (apiKey: string) => void; +} + +export function ApiKeyInput({ + value, + onApiKeyChange, + ...props +}: ApiKeyInputProps) { + const [internalValue, setInternalValue] = useState(value || ''); + + useEffect(() => { + setInternalValue(value || ''); + }, [value]); + + useEffect(() => { + const handler = setTimeout(() => { + onApiKeyChange(internalValue as string); + }, 300); + + return () => clearTimeout(handler); + }, [internalValue, onApiKeyChange]); + + return ( + setInternalValue(e.target.value)} + placeholder='sk-...' + className='font-mono text-sm' + {...props} + /> + ); +} diff --git a/ui/components/child-key-creator.tsx b/ui/components/child-key-creator.tsx index 460108b9..d82added 100644 --- a/ui/components/child-key-creator.tsx +++ b/ui/components/child-key-creator.tsx @@ -2,6 +2,7 @@ import { useState } from 'react'; import { WalletService } from '@/lib/api/services/wallet'; +import { ApiKeyInput } from './api-key-input'; import { Button } from '@/components/ui/button'; import { Card, @@ -250,12 +251,22 @@ export function ChildKeyCreator({ - handleApiKeyChange(e.target.value)} - placeholder='sk-...' - className='font-mono text-sm' - /> +
+
+ +
+ +
)} diff --git a/ui/components/landing/cashu-payment-workflow.tsx b/ui/components/landing/cashu-payment-workflow.tsx index 7af3e231..5608833f 100644 --- a/ui/components/landing/cashu-payment-workflow.tsx +++ b/ui/components/landing/cashu-payment-workflow.tsx @@ -11,6 +11,7 @@ import { Input } from '@/components/ui/input'; import { Separator } from '@/components/ui/separator'; import { KeyOptions } from '@/components/key-options'; import { WalletBalanceStats } from './wallet-balance-stats'; +import { ApiKeyInput } from '../api-key-input'; import type { ChildKeyInfo, WalletSnapshot } from './key-info-details'; export type RefundReceipt = { @@ -271,7 +272,7 @@ export function CashuPaymentWorkflow({ onWalletInfoUpdated?.(null); } }, - [apiKey] + [apiKey, onWalletInfoUpdated] ); const showManageDetails = hasInteractedManage || Boolean(walletInfo); @@ -342,11 +343,9 @@ export function CashuPaymentWorkflow({ )}
- handleApiKeyChange(event.target.value)} - placeholder='sk-...' - className='font-mono text-sm' + onApiKeyChange={handleApiKeyChange} onFocus={() => setHasInteractedManage(true)} />
diff --git a/ui/components/landing/key-info-details.tsx b/ui/components/landing/key-info-details.tsx index 053a51fa..dbadeb1c 100644 --- a/ui/components/landing/key-info-details.tsx +++ b/ui/components/landing/key-info-details.tsx @@ -4,6 +4,7 @@ import { type JSX, useState, useCallback, useEffect } from 'react'; import { Copy, RefreshCcw, RotateCcw, Trash2 } from 'lucide-react'; import type { RefundReceipt } from './cashu-payment-workflow'; import { toast } from 'sonner'; +import { ApiKeyInput } from '../api-key-input'; import { Card, CardContent, @@ -13,7 +14,6 @@ import { } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; -import { Input } from '@/components/ui/input'; import { WalletService } from '@/lib/api/services/wallet'; export type ChildKeyInfo = { @@ -188,12 +188,7 @@ export function KeyInfoDetails({
- handleKeyChange(e.target.value)} - placeholder='sk-...' - className='font-mono text-sm' - /> +
+
+
+ )} +
+ Validity + + {formatDate(walletInfo.validityDate)} + +
+
+ + + + + Infos + + +
+ + Spendable Balance + + + {formatSats(walletInfo.balanceMsats)} sats + +
+
+ + Total Requests + + + {walletInfo.totalRequests} + +
+
+ Total Spent +
+

+ {formatSats(walletInfo.totalSpent)} sats +

+

+ {formatMsats(walletInfo.totalSpent)} msats +

+
+
+ {walletInfo.balanceLimit !== null && ( +
+
+ + Spend Limit + + + {formatSats(walletInfo.balanceLimit)} sats + +
+ {walletInfo.balanceLimitReset && ( +
+ + Reset Policy + + + {walletInfo.balanceLimitReset} + +
+ )} +
+ )} +
+
+
+ + {!walletInfo.isChild && + walletInfo.childKeys && + walletInfo.childKeys.length > 0 && ( + + + + Child Keys ({walletInfo.childKeys.length}) + + + Secondary keys using this account's balance + + + +
+ {walletInfo.childKeys.map((ck) => ( +
+
+ + {ck.api_key} + +
+ + {onResetSpent && ( + + )} +
+
+
+ ))} +
+
+
+ )} +
+ ); +}