import { useState } from "react"; import { Countdown } from "./Countdown"; import type { DenialState } from "../hooks/useClaimFlow"; const DENIAL_CODE_EXPLANATIONS: Record = { cooldown_pubkey: "You've already claimed recently. Each pubkey has a cooldown period.", cooldown_ip: "This IP has reached the claim limit for the cooldown period.", account_too_new: "Your Nostr account is too new. The faucet requires a minimum account age.", low_activity: "Your Nostr profile doesn't meet the minimum activity score (notes, following).", invalid_nip98: "Nostr signature verification failed.", invalid_lightning_address: "The Lightning address format is invalid or could not be resolved.", quote_expired: "The quote expired before confirmation.", payout_failed: "The Lightning payment failed. You can try again.", faucet_disabled: "The faucet is temporarily disabled.", emergency_stop: "The faucet is in emergency stop mode.", insufficient_balance: "The faucet pool has insufficient balance.", daily_budget_exceeded: "The daily payout budget has been reached.", }; interface ClaimDenialPanelProps { denial: DenialState; onDismiss?: () => void; /** When provided, shows a "Check again" button (e.g. in wizard step 2) */ onCheckAgain?: () => void; } export function ClaimDenialPanel({ denial, onDismiss, onCheckAgain }: ClaimDenialPanelProps) { const [whyExpanded, setWhyExpanded] = useState(false); const explanation = denial.code ? DENIAL_CODE_EXPLANATIONS[denial.code] ?? null : null; return (

Not eligible yet

{denial.message}

{denial.next_eligible_at != null && (

Next claim in:

)} {(denial.code || explanation) && (
{whyExpanded && (
{denial.code &&

Code: {denial.code}

} {explanation &&

{explanation}

}
)}
)}
{onCheckAgain != null && ( )} {onDismiss && ( )}
); }