import { useState } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Countdown } from "./Countdown"; import { useToast } from "../contexts/ToastContext"; import type { QuoteResult, ConfirmResult } from "../api"; import type { ConfirmErrorState } from "../hooks/useClaimFlow"; export type ClaimModalPhase = "quote" | "sending" | "success" | "failure"; interface ClaimModalProps { phase: ClaimModalPhase; quote: QuoteResult | null; confirmResult: ConfirmResult | null; confirmError: ConfirmErrorState | null; lightningAddress: string; quoteExpired: boolean; onConfirm: () => void; onCancel: () => void; onRetry: () => void; onDone: () => void; } function CheckIcon() { return ( ); } function SpinnerIcon() { return ( ); } export function ClaimModal({ phase, quote, confirmResult, confirmError, lightningAddress, quoteExpired, onConfirm, onCancel, onRetry, onDone, }: ClaimModalProps) { const { showToast } = useToast(); const [paymentHashExpanded, setPaymentHashExpanded] = useState(false); const handleShare = () => { const amount = confirmResult?.payout_sats ?? 0; const text = `Just claimed ${amount} sats from the faucet!`; navigator.clipboard.writeText(text).then(() => showToast("Copied")); }; const copyPaymentHash = () => { const hash = confirmResult?.payment_hash; if (!hash) return; navigator.clipboard.writeText(hash).then(() => showToast("Copied")); }; return (
{phase === "quote" && quote && (

Confirm payout

{quote.payout_sats} sats
To {lightningAddress}
Expires in
)} {phase === "sending" && (

Sending sats via Lightning

)} {phase === "success" && confirmResult && (

Sent {confirmResult.payout_sats ?? 0} sats

{confirmResult.payment_hash && (
)} {confirmResult.next_eligible_at != null && (

Next eligible:

)}
)} {phase === "failure" && confirmError && (

{confirmError.message}

{confirmError.allowRetry && !quoteExpired && ( )} {(!confirmError.allowRetry || quoteExpired) && ( )}
)}
); }