diff --git a/client/public/assets/images/missions/mission1.png b/client/public/assets/images/missions/mission1.png index 62ddd8e..4b8e2f2 100644 Binary files a/client/public/assets/images/missions/mission1.png and b/client/public/assets/images/missions/mission1.png differ diff --git a/client/public/assets/images/missions/mission2-p2.png b/client/public/assets/images/missions/mission2-p2.png new file mode 100644 index 0000000..7db0cc9 Binary files /dev/null and b/client/public/assets/images/missions/mission2-p2.png differ diff --git a/client/public/assets/images/missions/mission2.png b/client/public/assets/images/missions/mission2.png index 8172968..4051b13 100644 Binary files a/client/public/assets/images/missions/mission2.png and b/client/public/assets/images/missions/mission2.png differ diff --git a/client/public/assets/images/missions/mission3.png b/client/public/assets/images/missions/mission3.png index a8b5d49..b4aba26 100644 Binary files a/client/public/assets/images/missions/mission3.png and b/client/public/assets/images/missions/mission3.png differ diff --git a/client/public/assets/images/missions/mission4.png b/client/public/assets/images/missions/mission4.png index bec0515..26625da 100644 Binary files a/client/public/assets/images/missions/mission4.png and b/client/public/assets/images/missions/mission4.png differ diff --git a/client/public/assets/images/missions/mission5.png b/client/public/assets/images/missions/mission5.png index 592bd6f..3783fb6 100644 Binary files a/client/public/assets/images/missions/mission5.png and b/client/public/assets/images/missions/mission5.png differ diff --git a/client/public/assets/images/missions/original_backup/mission1.png b/client/public/assets/images/missions/original_backup/mission1.png new file mode 100644 index 0000000..62ddd8e Binary files /dev/null and b/client/public/assets/images/missions/original_backup/mission1.png differ diff --git a/client/public/assets/images/missions/original_backup/mission2.png b/client/public/assets/images/missions/original_backup/mission2.png new file mode 100644 index 0000000..8172968 Binary files /dev/null and b/client/public/assets/images/missions/original_backup/mission2.png differ diff --git a/client/public/assets/images/missions/original_backup/mission3.png b/client/public/assets/images/missions/original_backup/mission3.png new file mode 100644 index 0000000..a8b5d49 Binary files /dev/null and b/client/public/assets/images/missions/original_backup/mission3.png differ diff --git a/client/public/assets/images/missions/original_backup/mission4.png b/client/public/assets/images/missions/original_backup/mission4.png new file mode 100644 index 0000000..bec0515 Binary files /dev/null and b/client/public/assets/images/missions/original_backup/mission4.png differ diff --git a/client/public/assets/images/missions/original_backup/mission5.png b/client/public/assets/images/missions/original_backup/mission5.png new file mode 100644 index 0000000..592bd6f Binary files /dev/null and b/client/public/assets/images/missions/original_backup/mission5.png differ diff --git a/client/public/assets/images/missions/quadrades/mission1.png b/client/public/assets/images/missions/quadrades/mission1.png new file mode 100644 index 0000000..f3e5a22 Binary files /dev/null and b/client/public/assets/images/missions/quadrades/mission1.png differ diff --git a/client/public/assets/images/missions/quadrades/mission2.jpg b/client/public/assets/images/missions/quadrades/mission2.jpg new file mode 100644 index 0000000..5a7bdeb Binary files /dev/null and b/client/public/assets/images/missions/quadrades/mission2.jpg differ diff --git a/client/public/assets/images/missions/quadrades/mission2.png b/client/public/assets/images/missions/quadrades/mission2.png new file mode 100644 index 0000000..21b1a79 Binary files /dev/null and b/client/public/assets/images/missions/quadrades/mission2.png differ diff --git a/client/public/assets/images/missions/quadrades/mission3.png b/client/public/assets/images/missions/quadrades/mission3.png new file mode 100644 index 0000000..66c3a0f Binary files /dev/null and b/client/public/assets/images/missions/quadrades/mission3.png differ diff --git a/client/public/assets/images/missions/quadrades/mission4.png b/client/public/assets/images/missions/quadrades/mission4.png new file mode 100644 index 0000000..10491b7 Binary files /dev/null and b/client/public/assets/images/missions/quadrades/mission4.png differ diff --git a/client/public/assets/images/missions/quadrades/mission5.jpg b/client/public/assets/images/missions/quadrades/mission5.jpg new file mode 100644 index 0000000..9cf8ba0 Binary files /dev/null and b/client/public/assets/images/missions/quadrades/mission5.jpg differ diff --git a/client/public/assets/images/missions/quadrades/mission5.png b/client/public/assets/images/missions/quadrades/mission5.png new file mode 100644 index 0000000..4c22329 Binary files /dev/null and b/client/public/assets/images/missions/quadrades/mission5.png differ diff --git a/client/public/assets/images/missions/thumbdown.jpg b/client/public/assets/images/missions/thumbdown.jpg new file mode 100644 index 0000000..2c9f2d5 Binary files /dev/null and b/client/public/assets/images/missions/thumbdown.jpg differ diff --git a/client/public/assets/images/missions/thumbup.jpg b/client/public/assets/images/missions/thumbup.jpg new file mode 100644 index 0000000..2e3eae8 Binary files /dev/null and b/client/public/assets/images/missions/thumbup.jpg differ diff --git a/client/public/assets/images/tokens/accept_leader.jpg b/client/public/assets/images/tokens/accept_leader.jpg new file mode 100644 index 0000000..2c9f2d5 Binary files /dev/null and b/client/public/assets/images/tokens/accept_leader.jpg differ diff --git a/client/public/assets/images/tokens/accept_leader.png b/client/public/assets/images/tokens/accept_leader.png index e0f9c8b..5165894 100644 Binary files a/client/public/assets/images/tokens/accept_leader.png and b/client/public/assets/images/tokens/accept_leader.png differ diff --git a/client/public/assets/images/tokens/deny_leader.jpg b/client/public/assets/images/tokens/deny_leader.jpg new file mode 100644 index 0000000..2e3eae8 Binary files /dev/null and b/client/public/assets/images/tokens/deny_leader.jpg differ diff --git a/client/public/assets/images/tokens/deny_leader.png b/client/public/assets/images/tokens/deny_leader.png index a38afcc..b0022b2 100644 Binary files a/client/public/assets/images/tokens/deny_leader.png and b/client/public/assets/images/tokens/deny_leader.png differ diff --git a/client/public/assets/images/tokens/originals/accept_leader.png b/client/public/assets/images/tokens/originals/accept_leader.png new file mode 100644 index 0000000..e0f9c8b Binary files /dev/null and b/client/public/assets/images/tokens/originals/accept_leader.png differ diff --git a/client/public/assets/images/tokens/originals/deny_leader.png b/client/public/assets/images/tokens/originals/deny_leader.png new file mode 100644 index 0000000..a38afcc Binary files /dev/null and b/client/public/assets/images/tokens/originals/deny_leader.png differ diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx index 326fa16..a345c76 100644 --- a/client/src/app/page.tsx +++ b/client/src/app/page.tsx @@ -100,6 +100,7 @@ export default function Home() {

Sala de Espera

+

{gameState.roomName}

Operación en curso. Esperando activación...

diff --git a/client/src/components/GameBoard.tsx b/client/src/components/GameBoard.tsx index b82b2ba..e6bd5cb 100644 --- a/client/src/components/GameBoard.tsx +++ b/client/src/components/GameBoard.tsx @@ -53,14 +53,10 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB // Estado para controlar cuándo mostrar el tablero const [showBoard, setShowBoard] = useState(false); - // Mostrar tablero 7 segundos después de MISSION_RESULT + // Mostrar tablero durante MISSION_RESULT useEffect(() => { if (gameState.phase === GamePhase.MISSION_RESULT) { setShowBoard(true); - const timer = setTimeout(() => { - setShowBoard(false); - }, 7000); // 7 segundos - return () => clearTimeout(timer); } else { setShowBoard(false); } @@ -91,11 +87,11 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB // Coordenadas porcentuales de los hexágonos de misión en el mapa const missionCoords = [ - { left: '12%', top: '55%' }, // Misión 1 - { left: '28%', top: '15%' }, // Misión 2 - { left: '52%', top: '25%' }, // Misión 3 - { left: '42%', top: '70%' }, // Misión 4 - { left: '82%', top: '40%' }, // Misión 5 + { left: '18%', top: '60%' }, // Misión 1 - Abajo izquierda + { left: '25%', top: '18%' }, // Misión 2 - Arriba izquierda + { left: '50%', top: '75%' }, // Misión 3 - Abajo centro + { left: '50%', top: '30%' }, // Misión 4 - Centro + { left: '80%', top: '45%' }, // Misión 5 - Derecha ]; // Nombres de las misiones @@ -120,7 +116,7 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB

- Sombras en París + Traidores en París

{/* Audio Auto-Play - Solo para el host */} @@ -295,8 +291,8 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB } return ( -
- +
+ {/* Fondo */}
-
+ {/* Contenedor principal */} +
{/* --- MAPA TÁCTICO (TABLERO) O CARTA DE MISIÓN O ASSASSIN_PHASE --- */} {/* No mostrar el tablero en fases de victoria */} @@ -415,16 +412,6 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB
); })} - - {/* TRACK DE VOTOS FALLIDOS */} -
-
Votos Rechazados
-
- {[...Array(5)].map((_, i) => ( -
- ))} -
-
) : ( /* CARTA DE MISIÓN CON TÍTULO */ @@ -478,13 +465,13 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB {gameState.leaderVotes?.[currentPlayerId] === undefined ? (
@@ -660,11 +640,11 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB disabled={missionVote !== null} > - Fail + Fail SABOTAJE @@ -680,11 +660,11 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB disabled={missionVote !== null} > - Fail + Fail SABOTAJE @@ -697,11 +677,11 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB disabled={missionVote !== null} > - Success + Success ÉXITO @@ -800,9 +780,9 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB
- {/* JUGADORES (TIENDA DE CAMPAÑA - Adaptable) */} -
-
+ {/* JUGADORES - POSICIONADOS ABSOLUTAMENTE EN EL FONDO */} +
+
{gameState.players.map((player) => { const isSelected = selectedTeam.includes(player.id); const isMe = player.id === currentPlayerId; @@ -815,16 +795,15 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB key={player.id} onClick={() => isLeader && gameState.phase === GamePhase.TEAM_BUILDING && toggleTeamSelection(player.id)} className={` - relative flex flex-col items-center cursor-pointer transition-all duration-300 - ${isSelected ? 'scale-110' : 'scale-100 opacity-80 hover:opacity-100'} - `} + relative flex flex-col items-center cursor-pointer transition-all duration-300 group + ${isSelected ? 'scale-110 z-10' : 'scale-100 opacity-70 hover:opacity-100 hover:scale-105'} + `} > {/* Avatar */} -
+
{player.name} +
L
)} @@ -846,14 +825,17 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB gameState.phase === 'mission_reveal' as any || gameState.phase === 'mission_result' as any ) && ( -
+
)}
{/* Nombre */} - + {player.name}
@@ -924,7 +906,7 @@ function VotingTimer() { }, [timeLeft]); return ( -
+
{timeLeft}
); diff --git a/client/src/components/GameBoard_temp.tsx b/client/src/components/GameBoard_temp.tsx index 3896eae..b4a74c0 100644 --- a/client/src/components/GameBoard_temp.tsx +++ b/client/src/components/GameBoard_temp.tsx @@ -236,13 +236,15 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB } return ( -
+
+ {/* Fondo */}
Game Background
-
+ {/* Contenedor principal con altura calculada */} +
6 ? 'h-[70%]' : 'h-[85%]'}`}> {/* --- MAPA TÁCTICO (TABLERO) --- */}
@@ -315,7 +317,7 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB
{/* --- ÁREA DE JUEGO (CARTAS Y ACCIONES) --- */} -
+
{/* FASE: VOTACIÓN DE LÍDER */} @@ -488,57 +490,184 @@ export default function GameBoard({ gameState, currentPlayerId, actions }: GameB
+
- {/* JUGADORES (TIENDA DE CAMPAÑA) */} -
-
- {gameState.players.map((player) => { - const isSelected = selectedTeam.includes(player.id); - const isMe = player.id === currentPlayerId; + {/* Área de jugadores fija en el pie - Fuera del contenedor principal */} +
6 ? 'h-[30vh]' : 'h-[15vh]'}`}> +
6 ? 'grid grid-cols-5 auto-rows-fr gap-y-2 gap-x-4 content-center justify-items-center' : 'flex items-center justify-center gap-6'}`}> + {gameState.players.map((player) => { + const isSelected = selectedTeam.includes(player.id); + const isMe = player.id === currentPlayerId; - // Avatar logic - const avatarSrc = `/assets/images/characters/${player.avatar}`; + // Avatar logic + const avatarSrc = `/assets/images/characters/${player.avatar}`; + return ( +
isLeader && gameState.phase === GamePhase.TEAM_BUILDING && toggleTeamSelection(player.id)} + className={` + relative flex flex-col items-center cursor-pointer transition-all duration-300 group + ${isSelected ? 'scale-110 z-10' : 'scale-100 opacity-70 hover:opacity-100 hover:scale-105'} + `} + > + {/* Avatar */} +
6 ? 'w-12 h-12' : 'w-20 h-20'} + ${isSelected ? 'border-yellow-400 ring-4 ring-yellow-400/30 shadow-yellow-400/20' : 'border-gray-500 group-hover:border-gray-300'} + ${player.isLeader ? 'ring-2 ring-white' : ''} + `}> + {player.name} + + {/* Icono de Líder */} + {player.isLeader && ( +
6 ? 'w-5 h-5' : 'w-6 h-6'}`}> + L +
+ )} +
+ + {/* Nombre */} + + {player.name} + +
+ ); + })} +
+
+ + {/* HISTÓRICO DE MISIONES (Esquina superior derecha) */} + {gameState.missionHistory.length > 0 && ( +
+
Historial
+
+ {gameState.missionHistory.map((mission, idx) => { return ( -
isLeader && gameState.phase === GamePhase.TEAM_BUILDING && toggleTeamSelection(player.id)} - className={` - relative flex flex-col items-center cursor-pointer transition-all duration-300 - ${isSelected ? 'scale-110' : 'scale-100 opacity-80 hover:opacity-100'} - `} - > - {/* Avatar */} -
- {player.name} - - {/* Icono de Líder */} - {player.isLeader && ( -
- L -
- )} +
+
+ {mission.round}
- - {/* Nombre */} - - {player.name} - +
); })}
+ )} +
+ ); +} - {/* HISTÓRICO DE MISIONES (Esquina superior derecha) */} - {gameState.missionHistory.length > 0 && ( -
-
Historial
+// Subcomponente para el Timer de Votación +function VotingTimer({ onTimeout }: { onTimeout: () => void }) { + const [timeLeft, setTimeLeft] = useState(10); + + useEffect(() => { + if (timeLeft <= 0) { + onTimeout(); + return; + } + const interval = setInterval(() => setTimeLeft(t => t - 1), 1000); + return () => clearInterval(interval); + }, [timeLeft, onTimeout]); + + return ( +
+ {timeLeft} +
+ ); +} + +// Subcomponente para la revelación de cartas de misión +function MissionReveal({ votes, onComplete }: { votes: boolean[], onComplete: () => void }) { + const [revealedCount, setRevealedCount] = useState(0); + + useEffect(() => { + if (revealedCount < votes.length) { + const timer = setTimeout(() => { + setRevealedCount(prev => prev + 1); + }, 1500); + return () => clearTimeout(timer); + } else if (revealedCount === votes.length) { + const timer = setTimeout(() => { + onComplete(); + }, 2000); + return () => clearTimeout(timer); + } + }, [revealedCount, votes.length, onComplete]); + + return ( + +

Revelando Votos...

+
+ {votes.map((vote, idx) => ( + + {vote + + ))} +
+
+ ); +} + +// Subcomponente para el resultado de la misión +function MissionResult({ gameState, onContinue }: { gameState: GameState, onContinue: () => void }) { + const lastResult = gameState.questResults[gameState.currentRound - 1]; + const lastMission = gameState.missionHistory[gameState.missionHistory.length - 1]; + + return ( + +

+ {lastResult ? '¡MISIÓN EXITOSA!' : '¡MISIÓN FALLIDA!'} +

+
+
+ Votos de Éxito: {lastMission?.successes || 0} +
+
+ Votos de Sabotaje: {lastMission?.fails || 0} +
+
+ +
+ ); +} diff --git a/client/src/components/MissionResult.tsx b/client/src/components/MissionResult.tsx index 8f351a3..c3e17ed 100644 --- a/client/src/components/MissionResult.tsx +++ b/client/src/components/MissionResult.tsx @@ -23,12 +23,12 @@ export default function MissionResult({ gameState, onContinue, isHost }: Mission return ( -

- Resultado de Misión +

+ Resultado de la misión

-
+
{votes.map((vote, idx) => (