import React, { useState, useEffect, useRef } from 'react'; import { Trophy, Clock, Target, Zap, Crown, Medal, Star, ChevronRight, CreditCard, Lock, CheckCircle, AlertCircle, Settings, Edit, Save, X, LogOut, Eye, EyeOff } from 'lucide-react'; const SkillWinSite = () => { const [gameState, setGameState] = useState('intro'); const [score, setScore] = useState(0); const [bestScore, setBestScore] = useState(0); const [streak, setStreak] = useState(0); const [timeLeft, setTimeLeft] = useState(72); const [targets, setTargets] = useState([]); const [gameTime, setGameTime] = useState(30); const [isGameActive, setIsGameActive] = useState(false); const [isGameReady, setIsGameReady] = useState(false); const [showPayment, setShowPayment] = useState(false); const [paymentStep, setPaymentStep] = useState('form'); const [pseudo, setPseudo] = useState(''); const [hasSubmitted, setHasSubmitted] = useState(false); const [isAdmin, setIsAdmin] = useState(false); const [showAdminLogin, setShowAdminLogin] = useState(false); const [showAdminPanel, setShowAdminPanel] = useState(false); const [adminTab, setAdminTab] = useState('product'); const [adminPassword, setAdminPassword] = useState(''); const [showPassword, setShowPassword] = useState(false); const [loginError, setLoginError] = useState(''); const gameAreaRef = useRef(null); const [cardNumber, setCardNumber] = useState(''); const [expiryDate, setExpiryDate] = useState(''); const [cvc, setCvc] = useState(''); const [email, setEmail] = useState(''); const [dailyProduct, setDailyProduct] = useState({ name: "iPhone 16 Pro Max", image: "https://images.unsplash.com/photo-1695048064468-42ebe7df30f3?w=800", value: "1499€", description: "256 GB - Titane Naturel" }); const [contestEndDate, setContestEndDate] = useState(null); const [editProduct, setEditProduct] = useState({...dailyProduct}); const [editEndDate, setEditEndDate] = useState(''); const [leaderboard, setLeaderboard] = useState([ { pseudo: "AlexPro", score: 2847, avatar: "🎯" }, { pseudo: "SkillMaster", score: 2691, avatar: "👑" }, { pseudo: "SpeedyGon", score: 2534, avatar: "⚡" }, { pseudo: "NinjaClick", score: 2401, avatar: "🥷" }, { pseudo: "PrecisionX", score: 2298, avatar: "🎪" } ]); useEffect(() => { loadProductFromStorage(); loadContestEndDate(); checkForMidnightReset(); }, []); const loadProductFromStorage = async () => { try { const result = await window.storage.get('daily-product'); if (result && result.value) { const product = JSON.parse(result.value); setDailyProduct(product); setEditProduct(product); } } catch (error) { console.log('Produit par défaut utilisé'); } }; const loadContestEndDate = async () => { try { const result = await window.storage.get('contest-end-date'); if (result && result.value) { const endDate = new Date(result.value); setContestEndDate(endDate); setEditEndDate(result.value); } else { const defaultEnd = new Date(); defaultEnd.setHours(23, 59, 59, 999); setContestEndDate(defaultEnd); setEditEndDate(defaultEnd.toISOString().slice(0, 16)); } } catch (error) { const defaultEnd = new Date(); defaultEnd.setHours(23, 59, 59, 999); setContestEndDate(defaultEnd); setEditEndDate(defaultEnd.toISOString().slice(0, 16)); } }; const checkForMidnightReset = async () => { try { const lastReset = await window.storage.get('last-reset-date'); const today = new Date().toDateString(); if (!lastReset || lastReset.value !== today) { await window.storage.set('last-reset-date', today); await window.storage.delete('leaderboard-data'); setLeaderboard([]); } else { const leaderboardData = await window.storage.get('leaderboard-data'); if (leaderboardData && leaderboardData.value) { setLeaderboard(JSON.parse(leaderboardData.value)); } } } catch (error) { console.log('Vérification du reset échouée'); } }; const saveProductToStorage = async (product) => { try { await window.storage.set('daily-product', JSON.stringify(product)); return true; } catch (error) { console.error('Erreur de sauvegarde:', error); return false; } }; const saveContestEndDate = async (dateString) => { try { await window.storage.set('contest-end-date', dateString); return true; } catch (error) { console.error('Erreur de sauvegarde date:', error); return false; } }; const saveLeaderboard = async (data) => { try { await window.storage.set('leaderboard-data', JSON.stringify(data)); } catch (error) { console.error('Erreur sauvegarde classement:', error); } }; const handleAdminLogin = () => { if (adminPassword === 'admin123') { setIsAdmin(true); setShowAdminLogin(false); setShowAdminPanel(true); setAdminTab('product'); setLoginError(''); setAdminPassword(''); } else { setLoginError('Mot de passe incorrect'); } }; const handleAdminLogout = () => { setIsAdmin(false); setShowAdminPanel(false); setAdminPassword(''); }; const handleSaveProduct = async () => { const productSuccess = await saveProductToStorage(editProduct); const dateSuccess = await saveContestEndDate(editEndDate); if (productSuccess && dateSuccess) { setDailyProduct(editProduct); setContestEndDate(new Date(editEndDate)); setShowAdminPanel(false); alert('✅ Produit et date de fin mis à jour avec succès !'); } else { alert('❌ Erreur lors de la sauvegarde'); } }; useEffect(() => { if (!contestEndDate) return; const timer = setInterval(() => { const now = new Date(); const diff = contestEndDate - now; if (diff <= 0) { setTimeLeft(0); checkForMidnightReset(); } else { setTimeLeft(diff / 1000 / 3600); } }, 1000); return () => clearInterval(timer); }, [contestEndDate]); useEffect(() => { if (isGameActive && gameTime > 0) { const timer = setInterval(() => { setGameTime(prev => { if (prev <= 0.1) { setIsGameActive(false); return 0; } return prev - 0.1; }); }, 100); return () => clearInterval(timer); } }, [isGameActive, gameTime]); useEffect(() => { if (isGameActive && targets.length === 0) { const newTarget = { id: Date.now(), x: Math.random() * 80 + 10, y: Math.random() * 70 + 10, size: Math.random() * 30 + 40, speed: Math.random() * 2 + 1 }; setTargets([newTarget]); } }, [isGameActive, targets.length]); const startGame = () => { setGameState('playing'); setScore(0); setStreak(0); setGameTime(30); setIsGameReady(true); setIsGameActive(false); setTargets([]); setTimeout(() => { if (gameAreaRef.current) { gameAreaRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' }); } }, 100); }; const launchGame = () => { setIsGameActive(true); setIsGameReady(false); }; const hitTarget = (target, e) => { e.stopPropagation(); const basePoints = Math.floor(100 / (target.size / 50)); const newStreak = streak + 1; setStreak(newStreak); let bonusMultiplier = 1; if (newStreak >= 3 && newStreak < 5) bonusMultiplier = 1.2; else if (newStreak >= 5 && newStreak < 10) bonusMultiplier = 1.5; else if (newStreak >= 10) bonusMultiplier = 2; const finalPoints = Math.floor(basePoints * bonusMultiplier); setScore(prev => prev + finalPoints); const newTarget = { id: Date.now(), x: Math.random() * 80 + 10, y: Math.random() * 70 + 10, size: Math.random() * 30 + 40, speed: Math.random() * 2 + 1 }; setTargets([newTarget]); }; const missTarget = () => { setScore(prev => Math.max(0, prev - 20)); setStreak(0); }; const endGame = () => { setIsGameActive(false); if (score > bestScore) { setBestScore(score); } }; useEffect(() => { if (gameTime === 0 && isGameActive) { endGame(); } }, [gameTime, isGameActive]); const submitScore = () => { if (score > bestScore) { setBestScore(score); } setShowPayment(true); setPaymentStep('form'); }; const getPotentialRank = (currentScore) => { const testScore = Math.max(currentScore, bestScore); let rank = 1; for (let player of leaderboard) { if (player.score >= testScore) rank++; } return rank; }; const getRankMessage = (rank) => { if (rank === 1) return "🏆 Vous êtes à la 1ère place avec ce score !"; if (rank === 2) return "🥈 Vous êtes à la 2ème place avec ce score !"; if (rank === 3) return "🥉 Vous êtes à la 3ème place avec ce score !"; if (rank <= 5) return `🌟 Vous êtes dans le Top 5 avec ce score (${rank}ème place) !`; if (rank <= 10) return `⭐ Vous êtes dans le Top 10 avec ce score (${rank}ème place)`; return `Vous êtes à la ${rank}ème place avec ce score`; }; const formatCardNumber = (value) => { const v = value.replace(/\s+/g, '').replace(/[^0-9]/gi, ''); const matches = v.match(/\d{4,16}/g); const match = (matches && matches[0]) || ''; const parts = []; for (let i = 0, len = match.length; i < len; i += 4) { parts.push(match.substring(i, i + 4)); } if (parts.length) { return parts.join(' '); } else { return value; } }; const formatExpiryDate = (value) => { const v = value.replace(/\s+/g, '').replace(/[^0-9]/gi, ''); if (v.length >= 2) { return v.substring(0, 2) + (v.length > 2 ? '/' + v.substring(2, 4) : ''); } return v; }; const processPayment = () => { if (!pseudo.trim() || !email.trim() || cardNumber.replace(/\s/g, '').length < 16 || !expiryDate || !cvc) { setPaymentStep('error'); return; } setPaymentStep('processing'); const scoreToSubmit = Math.max(score, bestScore); setTimeout(() => { setPaymentStep('success'); setTimeout(() => { const existingPlayerIndex = leaderboard.findIndex(p => p.pseudo === pseudo); let newLeaderboard; if (existingPlayerIndex !== -1) { newLeaderboard = [...leaderboard]; if (scoreToSubmit > newLeaderboard[existingPlayerIndex].score) { newLeaderboard[existingPlayerIndex].score = scoreToSubmit; } } else { const newEntry = { pseudo: pseudo, score: scoreToSubmit, avatar: "🌟" }; newLeaderboard = [...leaderboard, newEntry]; } newLeaderboard = newLeaderboard .sort((a, b) => b.score - a.score) .slice(0, 10); setLeaderboard(newLeaderboard); setBestScore(scoreToSubmit); setHasSubmitted(true); setShowPayment(false); setGameState('submitted'); saveLeaderboard(newLeaderboard); setCardNumber(''); setExpiryDate(''); setCvc(''); }, 1500); }, 2000); }; const formatTime = (hours) => { const h = Math.floor(hours); const m = Math.floor((hours - h) * 60); const s = Math.floor(((hours - h) * 60 - m) * 60); return `${h}h ${m}m ${s}s`; }; return (

SkillWin

{formatTime(timeLeft)}
{!isAdmin ? ( ) : (
)}
🔥 Concours du Jour

Gagnez par votre talent !

Entraînez-vous gratuitement, puis payez 2,50€ uniquement pour soumettre votre meilleur score. Le joueur n°1 remporte le lot !

{dailyProduct.name}
Valeur: {dailyProduct.value}

{dailyProduct.name}

{dailyProduct.description}

setEditEndDate(e.target.value)} className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-green-400 focus:outline-none text-white" />

⏰ Le classement sera automatiquement réinitialisé à cette date

Cliquez sur les cibles

+100 points par cible (bonus pour petites cibles)

Attention aux clics ratés !

-20 points si vous cliquez à côté

Payez uniquement pour participer

2,50€ pour soumettre votre score

Gagnez par le talent

Le meilleur score remporte le lot

{!hasSubmitted && ( )} {hasSubmitted && (

Score soumis avec succès !

Bonne chance {pseudo} ! 🍀

)}
{gameState === 'playing' && (
Score: {score}
{streak >= 3 && (
🔥 Série: {streak}x {streak >= 10 && x2 BONUS!} {streak >= 5 && streak < 10 && x1.5!} {streak >= 3 && streak < 5 && x1.2!}
)}
Temps: {Math.ceil(gameTime)}s
{isGameReady && !isGameActive && (

Prêt(e) ?

Cliquez sur les cibles qui apparaissent

Attention : -20 points si vous ratez !

)} {!isGameActive && gameTime === 0 && (

Score final: {score}

{score > bestScore && (

🎉 Nouveau record !

)} {score > 0 && (

{getRankMessage(getPotentialRank(score))}

)}
{score > 0 && ( )}
)} {targets.map(target => (
hitTarget(target, e)} className="absolute bg-gradient-to-br from-red-500 to-pink-500 rounded-full cursor-pointer hover:scale-110 transition-transform flex items-center justify-center shadow-lg" style={{ left: `${target.x}%`, top: `${target.y}%`, width: `${target.size}px`, height: `${target.size}px`, animation: `pulse ${target.speed}s infinite` }} >
))}
{bestScore > 0 && (

Votre meilleur score: {bestScore}

)}
)}

Classement en Temps Réel

{leaderboard.map((player, index) => (
#{index + 1}
{player.avatar}

{player.pseudo}

{player.pseudo === pseudo && (

C'est vous !

)}

{player.score}

points

))}
{showAdminLogin && !isAdmin && (

Connexion Admin

🔐 Mode démo - Mot de passe : admin123

{ setAdminPassword(e.target.value); setLoginError(''); }} onKeyPress={(e) => e.key === 'Enter' && handleAdminLogin()} placeholder="Entrez le mot de passe" className="w-full px-4 py-3 pr-12 rounded-xl bg-white/10 border border-white/20 focus:border-blue-400 focus:outline-none text-white placeholder-gray-400" />
{loginError && (

{loginError}

)}
)} {showAdminPanel && isAdmin && (

Éditer le produit du jour

setEditProduct({...editProduct, name: e.target.value})} placeholder="Ex: iPhone 16 Pro Max" className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-green-400 focus:outline-none text-white placeholder-gray-400" />
setEditProduct({...editProduct, description: e.target.value})} placeholder="Ex: 256 GB - Titane Naturel" className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-green-400 focus:outline-none text-white placeholder-gray-400" />
setEditProduct({...editProduct, value: e.target.value})} placeholder="Ex: 1499€" className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-green-400 focus:outline-none text-white placeholder-gray-400" />
setEditProduct({...editProduct, image: e.target.value})} placeholder="https://..." className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-green-400 focus:outline-none text-white placeholder-gray-400" />

💡 Utilisez Unsplash, Pexels ou uploadez votre image sur un hébergeur

Preview { e.target.src = 'https://via.placeholder.com/150?text=Image+invalide'; }} />

{editProduct.name || 'Nom du produit'}

{editProduct.description || 'Description'}

{editProduct.value || 'Valeur'}

)} {showPayment && (
{paymentStep === 'form' && ( <>

Paiement sécurisé

Stripe

💡 Mode démo - Utilisez n'importe quelle carte de test (ex: 4242 4242 4242 4242) {hasSubmitted && Vous pouvez soumettre plusieurs scores pour améliorer votre classement !}

Votre score à soumettre

{score > bestScore ? score : bestScore} points

{getRankMessage(getPotentialRank(Math.max(score, bestScore)))}

setPseudo(e.target.value)} placeholder="Votre pseudo" className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-blue-400 focus:outline-none text-white placeholder-gray-400" maxLength={20} />
setEmail(e.target.value)} placeholder="votre@email.com" className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-blue-400 focus:outline-none text-white placeholder-gray-400" />
setCardNumber(formatCardNumber(e.target.value))} placeholder="4242 4242 4242 4242" maxLength={19} className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-blue-400 focus:outline-none text-white placeholder-gray-400 font-mono" />
setExpiryDate(formatExpiryDate(e.target.value))} placeholder="MM/AA" maxLength={5} className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-blue-400 focus:outline-none text-white placeholder-gray-400 font-mono" />
setCvc(e.target.value.replace(/\D/g, '').slice(0, 3))} placeholder="123" maxLength={3} className="w-full px-4 py-3 rounded-xl bg-white/10 border border-white/20 focus:border-blue-400 focus:outline-none text-white placeholder-gray-400 font-mono" />

Montant à payer

2,50€

Paiement sécurisé via Stripe • Vos données sont protégées

)} {paymentStep === 'processing' && (

Traitement du paiement...

Veuillez patienter

)} {paymentStep === 'success' && (

Paiement réussi !

Votre score a été enregistré

Score soumis

{Math.max(score, bestScore)} points

)} {paymentStep === 'error' && (

Erreur

Veuillez vérifier vos informations

)}
)}
); }; export default SkillWinSite;