diff --git a/src/components/ZapDialog.tsx b/src/components/ZapDialog.tsx index 7aff211..fb2709b 100644 --- a/src/components/ZapDialog.tsx +++ b/src/components/ZapDialog.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useRef } from 'react'; +import { useState, useEffect, useRef, forwardRef } from 'react'; import { Zap, Copy, Check, ExternalLink, Sparkle, Sparkles, Star, Rocket, ArrowLeft, X } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { @@ -47,6 +47,193 @@ const presetAmounts = [ { amount: 1000, icon: Rocket }, ]; +interface ZapContentProps { + invoice: string | null; + amount: number | string; + comment: string; + isZapping: boolean; + qrCodeUrl: string; + copied: boolean; + hasWebLN: boolean; + handleZap: () => void; + handleCopy: () => void; + openInWallet: () => void; + setAmount: (amount: number | string) => void; + setComment: (comment: string) => void; + inputRef: React.RefObject; + zap: (amount: number, comment: string) => void; +} + +// Moved ZapContent outside of ZapDialog to prevent re-renders causing focus loss +const ZapContent = forwardRef(({ + invoice, + amount, + comment, + isZapping, + qrCodeUrl, + copied, + hasWebLN, + handleZap, + handleCopy, + openInWallet, + setAmount, + setComment, + inputRef, + zap, +}, ref) => ( +
+ {invoice ? ( +
+ {/* Payment amount display */} +
+
{amount} sats
+
+ + + +
+ {/* QR Code */} +
+ + + {qrCodeUrl ? ( + Lightning Invoice QR Code + ) : ( +
+ )} + + +
+ + {/* Invoice input */} +
+ +
+ e.currentTarget.select()} + /> + +
+
+ + {/* Payment buttons */} +
+ {hasWebLN && ( + + )} + + + +
+ Scan the QR code or copy the invoice to pay with any Lightning wallet. +
+
+
+
+ ) : ( + <> +
+ { + if (value) { + setAmount(parseInt(value, 10)); + } + }} + className="grid grid-cols-5 gap-2 w-full" + > + {presetAmounts.map(({ amount: presetAmount, icon: Icon }) => ( + + + {presetAmount} + + ))} + +
+
+ OR +
+
+ setAmount(e.target.value)} + className="w-full" + /> +