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 (
Entraînez-vous gratuitement, puis payez 2,50€ uniquement pour soumettre votre meilleur score. Le joueur n°1 remporte le lot !
{dailyProduct.description}
⏰ 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
Score soumis avec succès !
Bonne chance {pseudo} ! 🍀
Cliquez sur les cibles qui apparaissent
Attention : -20 points si vous ratez !
Score final: {score}
{score > bestScore && (🎉 Nouveau record !
)} {score > 0 && ({getRankMessage(getPotentialRank(score))}
Votre meilleur score: {bestScore}
{player.pseudo}
{player.pseudo === pseudo && (C'est vous !
)}{player.score}
points
🔐 Mode démo - Mot de passe : admin123
💡 Utilisez Unsplash, Pexels ou uploadez votre image sur un hébergeur
{editProduct.name || 'Nom du produit'}
{editProduct.description || 'Description'}
{editProduct.value || 'Valeur'}
💡 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)))}
Montant à payer
2,50€
Paiement sécurisé via Stripe • Vos données sont protégées
> )} {paymentStep === 'processing' && (Veuillez patienter
Votre score a été enregistré
Score soumis
{Math.max(score, bestScore)} points
Veuillez vérifier vos informations