Fix: Resolver error de React hooks en fase MISSION
- Mover useState de cardOrder al nivel del componente - Eliminar IIFE que causaba violación de reglas de hooks - Usar cardOrder directamente en lugar de successFirst - Ahora la fase MISSION debería funcionar correctamente
This commit is contained in:
@@ -15,6 +15,10 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB
|
|||||||
// Hooks para FASE REVEAL ROLE
|
// Hooks para FASE REVEAL ROLE
|
||||||
const [revealCard, setRevealCard] = useState(false);
|
const [revealCard, setRevealCard] = useState(false);
|
||||||
|
|
||||||
|
// Orden aleatorio de cartas de misión (se genera una vez)
|
||||||
|
const [cardOrder] = useState(() => Math.random() > 0.5);
|
||||||
|
|
||||||
|
|
||||||
// Timer para avanzar automáticamente en REVEAL_ROLE
|
// Timer para avanzar automáticamente en REVEAL_ROLE
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (gameState.phase === 'reveal_role' as any) {
|
if (gameState.phase === 'reveal_role' as any) {
|
||||||
@@ -463,109 +467,104 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB
|
|||||||
) : (
|
) : (
|
||||||
<div className="text-white text-xl font-mono animate-pulse">
|
<div className="text-white text-xl font-mono animate-pulse">
|
||||||
VOTO REGISTRADO. ESPERANDO AL RESTO...
|
VOTO REGISTRADO. ESPERANDO AL RESTO...
|
||||||
|
```
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* FASE: MISIÓN */}
|
{/* FASE: MISIÓN */}
|
||||||
{gameState.phase === GamePhase.MISSION && (() => {
|
{gameState.phase === GamePhase.MISSION && (
|
||||||
// Generar orden aleatorio de cartas (solo una vez por jugador)
|
<motion.div
|
||||||
const [cardOrder] = useState(() => Math.random() > 0.5);
|
key="mission"
|
||||||
const successFirst = cardOrder;
|
className="fixed inset-0 flex items-center justify-center bg-black/90 z-50"
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
>
|
||||||
|
{gameState.proposedTeam.includes(currentPlayerId) ? (
|
||||||
|
<div className="flex flex-col items-center gap-8 w-full max-w-6xl px-4">
|
||||||
|
<h2 className="text-4xl md:text-5xl font-bold text-white mb-4 drop-shadow-2xl text-center uppercase tracking-wider animate-pulse">
|
||||||
|
🎯 ¡ESTÁS EN LA MISIÓN!
|
||||||
|
</h2>
|
||||||
|
<p className="text-white text-xl mb-4 text-center">
|
||||||
|
Elige el resultado de tu participación
|
||||||
|
</p>
|
||||||
|
|
||||||
return (
|
{/* DEBUG INFO - TEMPORAL */}
|
||||||
<motion.div
|
<div className="text-xs text-gray-400 bg-black/50 p-2 rounded">
|
||||||
key="mission"
|
Debug: Tu ID: {currentPlayerId} | Equipo: [{gameState.proposedTeam.join(', ')}]
|
||||||
className="fixed inset-0 flex items-center justify-center bg-black/90 z-50"
|
</div>
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
>
|
|
||||||
{gameState.proposedTeam.includes(currentPlayerId) ? (
|
|
||||||
<div className="flex flex-col items-center gap-8 w-full max-w-6xl px-4">
|
|
||||||
<h2 className="text-4xl md:text-5xl font-bold text-white mb-4 drop-shadow-2xl text-center uppercase tracking-wider animate-pulse">
|
|
||||||
🎯 ¡ESTÁS EN LA MISIÓN!
|
|
||||||
</h2>
|
|
||||||
<p className="text-white text-xl mb-4 text-center">
|
|
||||||
Elige el resultado de tu participación
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{/* DEBUG INFO - TEMPORAL */}
|
{/* Cartas en orden aleatorio */}
|
||||||
<div className="text-xs text-gray-400 bg-black/50 p-2 rounded">
|
<div className="flex gap-12 flex-wrap justify-center">
|
||||||
Debug: Tu ID: {currentPlayerId} | Equipo: [{gameState.proposedTeam.join(', ')}]
|
{cardOrder ? (
|
||||||
</div>
|
<>
|
||||||
|
{/* Carta de Éxito primero */}
|
||||||
|
<button onClick={() => actions.voteMission(true)} className="group">
|
||||||
|
<motion.div
|
||||||
|
className="w-64 h-96 bg-gradient-to-br from-blue-600 to-blue-900 rounded-2xl shadow-2xl border-4 border-blue-400 flex flex-col items-center justify-center p-6 transform transition-all hover:scale-110 hover:rotate-3 hover:shadow-blue-500/50"
|
||||||
|
whileHover={{ scale: 1.1, rotate: 3 }}
|
||||||
|
whileTap={{ scale: 0.95 }}
|
||||||
|
>
|
||||||
|
<Image src="/assets/images/tokens/mission_success.png" alt="Success" width={180} height={180} className="drop-shadow-2xl" />
|
||||||
|
<span className="mt-6 text-white font-bold text-2xl tracking-widest uppercase">ÉXITO</span>
|
||||||
|
</motion.div>
|
||||||
|
</button>
|
||||||
|
|
||||||
{/* Cartas en orden aleatorio */}
|
{/* Carta de Sabotaje segundo (solo para espías) */}
|
||||||
<div className="flex gap-12 flex-wrap justify-center">
|
{currentPlayer?.faction === 'spies' && (
|
||||||
{successFirst ? (
|
<button onClick={() => actions.voteMission(false)} className="group">
|
||||||
<>
|
|
||||||
{/* Carta de Éxito primero */}
|
|
||||||
<button onClick={() => actions.voteMission(true)} className="group">
|
|
||||||
<motion.div
|
<motion.div
|
||||||
className="w-64 h-96 bg-gradient-to-br from-blue-600 to-blue-900 rounded-2xl shadow-2xl border-4 border-blue-400 flex flex-col items-center justify-center p-6 transform transition-all hover:scale-110 hover:rotate-3 hover:shadow-blue-500/50"
|
className="w-64 h-96 bg-gradient-to-br from-red-600 to-red-900 rounded-2xl shadow-2xl border-4 border-red-400 flex flex-col items-center justify-center p-6 transform transition-all hover:scale-110 hover:-rotate-3 hover:shadow-red-500/50"
|
||||||
whileHover={{ scale: 1.1, rotate: 3 }}
|
whileHover={{ scale: 1.1, rotate: -3 }}
|
||||||
whileTap={{ scale: 0.95 }}
|
whileTap={{ scale: 0.95 }}
|
||||||
>
|
>
|
||||||
<Image src="/assets/images/tokens/mission_success.png" alt="Success" width={180} height={180} className="drop-shadow-2xl" />
|
<Image src="/assets/images/tokens/mission_fail.png" alt="Fail" width={180} height={180} className="drop-shadow-2xl" />
|
||||||
<span className="mt-6 text-white font-bold text-2xl tracking-widest uppercase">ÉXITO</span>
|
<span className="mt-6 text-white font-bold text-2xl tracking-widest uppercase">SABOTAJE</span>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
{/* Carta de Sabotaje segundo (solo para espías) */}
|
</>
|
||||||
{currentPlayer?.faction === 'spies' && (
|
) : (
|
||||||
<button onClick={() => actions.voteMission(false)} className="group">
|
<>
|
||||||
<motion.div
|
{/* Carta de Sabotaje primero (solo para espías) */}
|
||||||
className="w-64 h-96 bg-gradient-to-br from-red-600 to-red-900 rounded-2xl shadow-2xl border-4 border-red-400 flex flex-col items-center justify-center p-6 transform transition-all hover:scale-110 hover:-rotate-3 hover:shadow-red-500/50"
|
{currentPlayer?.faction === 'spies' && (
|
||||||
whileHover={{ scale: 1.1, rotate: -3 }}
|
<button onClick={() => actions.voteMission(false)} className="group">
|
||||||
whileTap={{ scale: 0.95 }}
|
|
||||||
>
|
|
||||||
<Image src="/assets/images/tokens/mission_fail.png" alt="Fail" width={180} height={180} className="drop-shadow-2xl" />
|
|
||||||
<span className="mt-6 text-white font-bold text-2xl tracking-widest uppercase">SABOTAJE</span>
|
|
||||||
</motion.div>
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
{/* Carta de Sabotaje primero (solo para espías) */}
|
|
||||||
{currentPlayer?.faction === 'spies' && (
|
|
||||||
<button onClick={() => actions.voteMission(false)} className="group">
|
|
||||||
<motion.div
|
|
||||||
className="w-64 h-96 bg-gradient-to-br from-red-600 to-red-900 rounded-2xl shadow-2xl border-4 border-red-400 flex flex-col items-center justify-center p-6 transform transition-all hover:scale-110 hover:-rotate-3 hover:shadow-red-500/50"
|
|
||||||
whileHover={{ scale: 1.1, rotate: -3 }}
|
|
||||||
whileTap={{ scale: 0.95 }}
|
|
||||||
>
|
|
||||||
<Image src="/assets/images/tokens/mission_fail.png" alt="Fail" width={180} height={180} className="drop-shadow-2xl" />
|
|
||||||
<span className="mt-6 text-white font-bold text-2xl tracking-widest uppercase">SABOTAJE</span>
|
|
||||||
</motion.div>
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Carta de Éxito segundo */}
|
|
||||||
<button onClick={() => actions.voteMission(true)} className="group">
|
|
||||||
<motion.div
|
<motion.div
|
||||||
className="w-64 h-96 bg-gradient-to-br from-blue-600 to-blue-900 rounded-2xl shadow-2xl border-4 border-blue-400 flex flex-col items-center justify-center p-6 transform transition-all hover:scale-110 hover:rotate-3 hover:shadow-blue-500/50"
|
className="w-64 h-96 bg-gradient-to-br from-red-600 to-red-900 rounded-2xl shadow-2xl border-4 border-red-400 flex flex-col items-center justify-center p-6 transform transition-all hover:scale-110 hover:-rotate-3 hover:shadow-red-500/50"
|
||||||
whileHover={{ scale: 1.1, rotate: 3 }}
|
whileHover={{ scale: 1.1, rotate: -3 }}
|
||||||
whileTap={{ scale: 0.95 }}
|
whileTap={{ scale: 0.95 }}
|
||||||
>
|
>
|
||||||
<Image src="/assets/images/tokens/mission_success.png" alt="Success" width={180} height={180} className="drop-shadow-2xl" />
|
<Image src="/assets/images/tokens/mission_fail.png" alt="Fail" width={180} height={180} className="drop-shadow-2xl" />
|
||||||
<span className="mt-6 text-white font-bold text-2xl tracking-widest uppercase">ÉXITO</span>
|
<span className="mt-6 text-white font-bold text-2xl tracking-widest uppercase">SABOTAJE</span>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</button>
|
</button>
|
||||||
</>
|
)}
|
||||||
)}
|
|
||||||
</div>
|
{/* Carta de Éxito segundo */}
|
||||||
|
<button onClick={() => actions.voteMission(true)} className="group">
|
||||||
|
<motion.div
|
||||||
|
className="w-64 h-96 bg-gradient-to-br from-blue-600 to-blue-900 rounded-2xl shadow-2xl border-4 border-blue-400 flex flex-col items-center justify-center p-6 transform transition-all hover:scale-110 hover:rotate-3 hover:shadow-blue-500/50"
|
||||||
|
whileHover={{ scale: 1.1, rotate: 3 }}
|
||||||
|
whileTap={{ scale: 0.95 }}
|
||||||
|
>
|
||||||
|
<Image src="/assets/images/tokens/mission_success.png" alt="Success" width={180} height={180} className="drop-shadow-2xl" />
|
||||||
|
<span className="mt-6 text-white font-bold text-2xl tracking-widest uppercase">ÉXITO</span>
|
||||||
|
</motion.div>
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
</div>
|
||||||
<div className="text-white text-3xl font-mono bg-black/70 p-8 rounded-xl border-2 border-white/20 text-center">
|
) : (
|
||||||
<div className="animate-pulse mb-4 text-5xl">⏳</div>
|
<div className="text-white text-3xl font-mono bg-black/70 p-8 rounded-xl border-2 border-white/20 text-center">
|
||||||
La misión está en curso...<br />
|
<div className="animate-pulse mb-4 text-5xl">⏳</div>
|
||||||
<span className="text-lg text-gray-400 mt-2 block">Esperando a que el equipo complete su votación.</span>
|
La misión está en curso...<br />
|
||||||
</div>
|
<span className="text-lg text-gray-400 mt-2 block">Esperando a que el equipo complete su votación.</span>
|
||||||
)}
|
</div>
|
||||||
</motion.div>
|
)}
|
||||||
);
|
</motion.div>
|
||||||
})()}
|
)}
|
||||||
|
|
||||||
{/* FASE: REVELACIÓN DE CARTAS */}
|
{/* FASE: REVELACIÓN DE CARTAS */}
|
||||||
{gameState.phase === 'mission_reveal' as any && (
|
{gameState.phase === 'mission_reveal' as any && (
|
||||||
|
|||||||
Reference in New Issue
Block a user