File size: 5,858 Bytes
8fb4cca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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<RedPacketModalProps> = ({ 
  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 (
    <div className="fixed inset-0 z-[120] flex items-center justify-center p-4 bg-black/80 backdrop-blur-sm animate-fade-in">
       <div className="relative w-full max-w-sm">
          <button onClick={onClose} className="absolute -top-10 right-0 p-2 bg-white/20 rounded-full text-white hover:bg-white/40">
             <X className="w-5 h-5" />
          </button>
          
          {stage === 'closed' ? (
             // Stage 1: The Big Red Envelope
             <div className="bg-gradient-to-b from-red-500 to-red-600 rounded-3xl shadow-2xl overflow-hidden text-center p-8 relative animate-bounce-slow">
                 <div className="absolute top-0 left-1/2 -translate-x-1/2 w-32 h-32 bg-red-700 rounded-b-full opacity-50"></div>
                 <div className="relative z-10 pt-10">
                    <p className="text-yellow-200 text-lg font-bold mb-2">{t.pddRedPacketTitle}</p>
                    <h3 className="text-3xl font-bold text-white mb-8">{t.pddRedPacketDesc}</h3>
                    
                    <button 
                       onClick={handleOpen}
                       className="w-24 h-24 rounded-full bg-yellow-400 border-4 border-yellow-200 text-red-600 font-bold text-xl shadow-lg hover:scale-110 transition-transform flex items-center justify-center mx-auto"
                    >
                       <span className="animate-pulse">{t.pddRedPacketCta}</span>
                    </button>
                 </div>
             </div>
          ) : (
             // Stage 2: The "Almost There" Trap
             <div className="bg-white rounded-3xl shadow-2xl overflow-hidden relative">
                 <div className="bg-red-500 p-6 text-center pb-12">
                     <p className="text-white/80 text-sm font-bold uppercase tracking-wider">Account Balance</p>
                     <h2 className="text-5xl font-bold text-white mt-2">¥{amount}</h2>
                 </div>
                 
                 <div className="px-6 -mt-8 relative z-10">
                    <div className="bg-white rounded-xl shadow-lg p-6 border border-gray-100 text-center">
                        <p className="text-gray-800 font-bold text-lg">{t.pddWithdrawTitle}</p>
                        <div className="w-full h-3 bg-gray-100 rounded-full mt-3 overflow-hidden">
                           <div className="h-full bg-red-500 animate-pulse" style={{ width: `${(amount / max) * 100}%` }}></div>
                        </div>
                        <p className="text-xs text-red-500 mt-2 font-bold">{t.pddWithdrawDesc}</p>
                        
                        <button 
                           onClick={handleWithdraw}
                           className="w-full py-3 bg-red-500 text-white rounded-full font-bold mt-4 shadow-lg shadow-red-200 hover:bg-red-600 flex items-center justify-center gap-2"
                        >
                           <Gift className="w-4 h-4" /> Share to Withdraw
                        </button>
                    </div>
                 </div>
                 
                 <div className="p-6 bg-gray-50">
                    <div className="space-y-3">
                       {['User 123 withdrew ¥2000', 'Amy unlocked VIP', 'Mike got ¥500'].map((txt, i) => (
                          <div key={i} className="flex items-center gap-2 text-xs text-gray-500">
                             <div className="w-6 h-6 bg-gray-200 rounded-full"></div>
                             <span>{txt}</span>
                             <span className="ml-auto text-gray-400">1m ago</span>
                          </div>
                       ))}
                    </div>
                 </div>
             </div>
          )}
       </div>
    </div>
  );
};