import React, { useState, useEffect } from 'react'; import { X, Gift } from 'lucide-react'; import { Language, AdminConfig, UserAccount } from '../types'; import { TRANSLATIONS } from '../constants/translations'; // @ts-ignore import confetti from 'canvas-confetti'; interface RedPacketModalProps { isVisible: boolean; onClose: () => void; language: Language; adminConfig: AdminConfig; user?: UserAccount; onUpdateUser: (balance: number) => void; onOpenShare: () => void; } export const RedPacketModal: React.FC = ({ isVisible, onClose, language, adminConfig, user, onUpdateUser, onOpenShare }) => { const [stage, setStage] = useState<'closed' | 'opened'>('closed'); const [amount, setAmount] = useState(0); const t = TRANSLATIONS[language]; // Determine target amount const max = adminConfig.redPacketMax || 2000; // If user exists, show their balance. If no user (guest), show default almost-max (e.g. max - 20) const userBalance = user?.redPacketBalance ?? (max - 20); useEffect(() => { if (isVisible) { setStage('closed'); // Animate amount up to userBalance let current = 0; // Animation speed const step = userBalance / 40; const interval = setInterval(() => { current += step; if (current >= userBalance) { current = userBalance; clearInterval(interval); } setAmount(Math.floor(current)); }, 30); return () => clearInterval(interval); } }, [isVisible, userBalance]); if (!isVisible) return null; const handleOpen = () => { setStage('opened'); confetti({ particleCount: 150, spread: 80, origin: { y: 0.6 }, colors: ['#fbbf24', '#ef4444', '#ffffff'] }); // Ensure user gets this balance if they haven't already if (user && (user.redPacketBalance === undefined || user.redPacketBalance === 0)) { onUpdateUser(userBalance); } }; const handleWithdraw = () => { onOpenShare(); onClose(); }; return (
{stage === 'closed' ? ( // Stage 1: The Big Red Envelope

{t.pddRedPacketTitle}

{t.pddRedPacketDesc}

) : ( // Stage 2: The "Almost There" Trap

Account Balance

¥{amount}

{t.pddWithdrawTitle}

{t.pddWithdrawDesc}

{['User 123 withdrew ¥2000', 'Amy unlocked VIP', 'Mike got ¥500'].map((txt, i) => (
{txt} 1m ago
))}
)}
); };