"use client"; import { useState, useEffect } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { useAuth } from "@/contexts/AuthContext"; import { useGame } from "@/hooks/useGame"; import { ticketCodeSchema, TicketCodeFormData } from "@/lib/validations"; import { Input } from "@/components/ui/Input"; import Button from "@/components/Button"; import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/Card"; import { Modal } from "@/components/ui/Modal"; import { PRIZE_CONFIG } from "@/utils/constants"; import { PlayGameResponse } from "@/types"; import { useRouter } from "next/navigation"; import { ROUTES } from "@/utils/constants"; import Link from "next/link"; const PRIZES = [ { type: 'INFUSEUR', name: 'Infuseur à thé', color: 'bg-blue-100 text-blue-800' }, { type: 'THE_SIGNATURE', name: 'Thé signature 100g', color: 'bg-green-100 text-green-800' }, { type: 'COFFRET_DECOUVERTE', name: 'Coffret découverte 39€', color: 'bg-purple-100 text-purple-800' }, { type: 'COFFRET_PRESTIGE', name: 'Coffret prestige 69€', color: 'bg-amber-100 text-amber-800' }, { type: 'THE_GRATUIT', name: 'Thé gratuit en magasin', color: 'bg-pink-100 text-pink-800' }, ]; export default function JeuxPage() { const { user, isAuthenticated } = useAuth(); const { play, isPlaying } = useGame(); const router = useRouter(); const [showResultModal, setShowResultModal] = useState(false); const [showRouletteModal, setShowRouletteModal] = useState(false); const [gameResult, setGameResult] = useState(null); const [errorMessage, setErrorMessage] = useState(""); const [currentPrizeIndex, setCurrentPrizeIndex] = useState(0); const [isSpinning, setIsSpinning] = useState(false); // Protection stricte: redirection si non connecté useEffect(() => { if (!isAuthenticated) { router.push(`${ROUTES.LOGIN}?redirect=/jeux`); } }, [isAuthenticated, router]); const { register, handleSubmit, reset, formState: { errors }, } = useForm({ resolver: zodResolver(ticketCodeSchema), }); // Animation de la roulette useEffect(() => { if (isSpinning) { const interval = setInterval(() => { setCurrentPrizeIndex((prev) => (prev + 1) % PRIZES.length); }, 100); return () => clearInterval(interval); } }, [isSpinning]); const onSubmit = async (data: TicketCodeFormData) => { // Réinitialiser le message d'erreur setErrorMessage(""); // Afficher la modal de roulette et démarrer l'animation setShowRouletteModal(true); setIsSpinning(true); setCurrentPrizeIndex(0); const result = await play(data.ticketCode); if (result) { // Trouver l'index du prix gagné const winningIndex = PRIZES.findIndex(p => p.type === result.prize?.type); // Continuer à tourner pendant 3 secondes setTimeout(() => { setIsSpinning(false); if (winningIndex !== -1) { setCurrentPrizeIndex(winningIndex); } // Afficher le résultat après 2 secondes (pour montrer le gain) setTimeout(() => { setShowRouletteModal(false); setGameResult(result); setShowResultModal(true); setErrorMessage(""); reset(); }, 2000); }, 3000); } else { // En cas d'erreur, fermer la roulette et afficher l'erreur setIsSpinning(false); setShowRouletteModal(false); setErrorMessage("Ce code a déjà été utilisé ou est invalide. Si vous avez déjà utilisé ce code, consultez vos tickets dans 'Mes lots'."); } }; const closeModal = () => { setShowResultModal(false); setGameResult(null); }; const prizeConfig = gameResult?.prize ? PRIZE_CONFIG[gameResult.prize.type as keyof typeof PRIZE_CONFIG] : null; return (
{/* Formulaire Section */}

🎁 Jouez maintenant !

Bonjour {user?.firstName}, entrez le code de 10 caractères présent sur votre ticket de caisse

{errors.ticketCode && (

{errors.ticketCode.message}

)} {errorMessage && (

❌ {errorMessage}

→ Voir vos tickets déjà utilisés
)}

Format: TTP2025ABC (10 caractères)

💡 Bon à savoir :

  • Chaque code ne peut être utilisé qu'une seule fois
  • Consultez vos tickets sur la page Mes gains
{/* Roulette Modal */} {}} title="🎰 Tirage en cours..." size="md" >
{/* Roulette Display */}
{PRIZES.map((prize, index) => { const getPrizeIcon = (type: string) => { switch(type) { case 'INFUSEUR': return ( ); case 'THE_SIGNATURE': return ( ); case 'COFFRET_DECOUVERTE': return ( ); case 'COFFRET_PRESTIGE': return ( ); case 'THE_GRATUIT': return ( ); } }; return (
{getPrizeIcon(prize.type)}

{prize.name}

); })}
{/* Loading Animation */}
Tirage en cours...
{/* Result Modal */} {gameResult && prizeConfig && (
{gameResult.prize?.type === 'INFUSEUR' && ( )} {gameResult.prize?.type === 'THE_SIGNATURE' && ( )} {gameResult.prize?.type === 'COFFRET_DECOUVERTE' && ( )} {gameResult.prize?.type === 'COFFRET_PRESTIGE' && ( )} {gameResult.prize?.type === 'THE_GRATUIT' && ( )}

Félicitations ! 🎉

Vous avez gagné :

{prizeConfig.name}

{gameResult.message || "Présentez-vous en magasin pour récupérer votre lot !"}

)}
); }