diff --git a/client/src/app/dashboard/page.tsx b/client/src/app/dashboard/page.tsx
index 1b2a53e..600488c 100644
--- a/client/src/app/dashboard/page.tsx
+++ b/client/src/app/dashboard/page.tsx
@@ -46,7 +46,7 @@ export default function Dashboard() {
socket.off('admin_action_success');
};
}
- }, [isAuthenticated, socket]);
+ }, [isAuthenticated, socket, setActiveGames, setGameHistory]);
const handleLogin = (e: React.FormEvent) => {
e.preventDefault();
@@ -308,7 +308,7 @@ export default function Dashboard() {
{entry.winner ? (entry.winner === 'resistance' ? 'RES' : 'SPIES') : 'LOGOUT'}
diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx
index dd13b2d..72900e2 100644
--- a/client/src/app/page.tsx
+++ b/client/src/app/page.tsx
@@ -55,7 +55,7 @@ export default function Home() {
setHasReconnected(true);
}
- }, [session, isConnected, hasReconnected]);
+ }, [session, isConnected, hasReconnected, actions, setPlayerName, setFullPlayerName, setView, setHasReconnected]);
// Efecto para cambiar a vista de juego cuando el servidor nos une
useEffect(() => {
@@ -71,7 +71,7 @@ export default function Home() {
updateSession({ currentView: 'lobby', roomId: undefined });
}
}
- }, [gameState, view, hasReconnected]);
+ }, [gameState, view, hasReconnected, updateSession, setView]);
// Listener para errores de socket que deben expulsar al lobby
useEffect(() => {
@@ -88,7 +88,7 @@ export default function Home() {
return () => {
socket.off('error', handleError);
};
- }, [socket, updateSession]);
+ }, [socket, updateSession, setView]);
const handleLogin = (e: React.FormEvent) => {
e.preventDefault();
diff --git a/client/src/hooks/useSessionStorage.ts b/client/src/hooks/useSessionStorage.ts
index 445e151..1964ec4 100644
--- a/client/src/hooks/useSessionStorage.ts
+++ b/client/src/hooks/useSessionStorage.ts
@@ -1,4 +1,4 @@
-import { useState, useEffect } from 'react';
+import { useState, useEffect, useCallback } from 'react';
interface SessionData {
playerName: string;
@@ -25,24 +25,26 @@ export function useSessionStorage() {
}, []);
// Guardar sesión
- const saveSession = (data: SessionData) => {
+ const saveSession = useCallback((data: SessionData) => {
localStorage.setItem('resistencia_session', JSON.stringify(data));
setSession(data);
- };
+ }, []);
// Actualizar sesión parcialmente
- const updateSession = (partial: Partial) => {
- if (session) {
- const updated = { ...session, ...partial };
- saveSession(updated);
- }
- };
+ const updateSession = useCallback((partial: Partial) => {
+ setSession(prev => {
+ if (!prev) return null;
+ const updated = { ...prev, ...partial };
+ localStorage.setItem('resistencia_session', JSON.stringify(updated));
+ return updated;
+ });
+ }, []);
// Limpiar sesión
- const clearSession = () => {
+ const clearSession = useCallback(() => {
localStorage.removeItem('resistencia_session');
setSession(null);
- };
+ }, []);
return {
session,
diff --git a/client/src/hooks/useSocket.ts b/client/src/hooks/useSocket.ts
index 5e09733..37de62a 100644
--- a/client/src/hooks/useSocket.ts
+++ b/client/src/hooks/useSocket.ts
@@ -1,7 +1,7 @@
-import { useEffect, useState } from 'react';
+import { useEffect, useState, useMemo } from 'react';
import { io, Socket } from 'socket.io-client';
-import { GameState, Player } from '../../../shared/types';
+import { GameState } from '../../../shared/types';
const SOCKET_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000';
@@ -35,25 +35,23 @@ export const useSocket = () => {
});
// Manejar propio unirse a partida
- socketInstance.on('game_joined', ({ roomId, state }) => {
+ socketInstance.on('game_joined', ({ state }) => {
setGameState(state);
- // Podríamos guardar el roomId en localStorage o similar si quisiéramos persistencia
});
socketInstance.on('error', (msg: string) => {
- alert(msg); // Simple error handling for now
+ alert(msg);
});
// Manejar finalización de partida por el host
socketInstance.on('game_finalized', () => {
console.log('La partida ha sido finalizada por el host');
- setGameState(null); // Resetear estado para volver al lobby
+ setGameState(null);
});
// Manejar cuando un jugador abandona la partida
socketInstance.on('player_left_game', ({ playerName }: { playerName: string }) => {
console.log(`${playerName} ha abandonado la partida`);
- // El servidor ya habrá cerrado la partida, solo mostramos mensaje
});
setSocket(socketInstance);
@@ -63,71 +61,52 @@ export const useSocket = () => {
};
}, []);
- // Funciones helper para enviar acciones
- const createGame = (hostName: string, maxPlayers: number, password?: string) => {
- socket?.emit('create_game', { hostName, maxPlayers, password });
- };
-
- const joinGame = (roomId: string, playerName: string, password?: string) => {
- socket?.emit('join_game', { roomId, playerName, password });
- };
-
- const refreshRooms = () => {
- socket?.emit('get_rooms');
- };
-
- const startGame = () => {
- socket?.emit('start_game', { roomId: gameState?.roomId });
- };
-
- const proposeTeam = (teamIds: string[]) => {
- socket?.emit('propose_team', { roomId: gameState?.roomId, teamIds });
- };
-
- const voteTeam = (approve: boolean) => {
- socket?.emit('vote_team', { roomId: gameState?.roomId, approve });
- };
-
- const voteMission = (success: boolean) => {
- socket?.emit('vote_mission', { roomId: gameState?.roomId, success });
- };
-
- const assassinKill = (targetId: string) => {
- socket?.emit('assassin_kill', { roomId: gameState?.roomId, targetId });
- };
-
- const leaveGame = () => {
- socket?.emit('leave_game', { roomId: gameState?.roomId });
- };
-
- const reconnectSession = (sessionData: { playerName: string; roomId?: string }) => {
- socket?.emit('reconnect_session', sessionData);
- };
+ const actions = useMemo(() => ({
+ createGame: (hostName: string, maxPlayers: number, password?: string) => {
+ socket?.emit('create_game', { hostName, maxPlayers, password });
+ },
+ joinGame: (roomId: string, playerName: string, password?: string) => {
+ socket?.emit('join_game', { roomId, playerName, password });
+ },
+ refreshRooms: () => {
+ socket?.emit('get_rooms');
+ },
+ startGame: () => {
+ socket?.emit('start_game', { roomId: gameState?.roomId });
+ },
+ proposeTeam: (teamIds: string[]) => {
+ socket?.emit('propose_team', { roomId: gameState?.roomId, teamIds });
+ },
+ voteTeam: (approve: boolean) => {
+ socket?.emit('vote_team', { roomId: gameState?.roomId, approve });
+ },
+ voteMission: (success: boolean) => {
+ socket?.emit('vote_mission', { roomId: gameState?.roomId, success });
+ },
+ voteLeader: (approve: boolean) => socket?.emit('vote_leader', { roomId: gameState?.roomId, approve }),
+ assassinKill: (targetId: string) => {
+ socket?.emit('assassin_kill', { roomId: gameState?.roomId, targetId });
+ },
+ leaveGame: () => {
+ socket?.emit('leave_game', { roomId: gameState?.roomId });
+ },
+ reconnectSession: (sessionData: { playerName: string; roomId?: string }) => {
+ socket?.emit('reconnect_session', sessionData);
+ },
+ finishIntro: () => socket?.emit('finish_intro', { roomId: gameState?.roomId }),
+ finishReveal: () => socket?.emit('finish_reveal', { roomId: gameState?.roomId }),
+ finishRollCall: () => socket?.emit('finish_roll_call', { roomId: gameState?.roomId }),
+ finishMissionReveal: () => socket?.emit('finish_reveal', { roomId: gameState?.roomId }),
+ finishMissionResult: () => socket?.emit('finish_mission_result', { roomId: gameState?.roomId }),
+ restartGame: () => socket?.emit('restart_game', { roomId: gameState?.roomId }),
+ finalizeGame: () => socket?.emit('finalize_game', { roomId: gameState?.roomId })
+ }), [socket, gameState?.roomId]);
return {
socket,
isConnected,
gameState,
roomsList,
- actions: {
- createGame,
- joinGame,
- refreshRooms,
- startGame,
- proposeTeam,
- voteTeam,
- voteMission,
- voteLeader: (approve: boolean) => socket?.emit('vote_leader', { roomId: gameState?.roomId, approve }),
- assassinKill,
- leaveGame,
- reconnectSession,
- finishIntro: () => socket?.emit('finish_intro', { roomId: gameState?.roomId }),
- finishReveal: () => socket?.emit('finish_reveal', { roomId: gameState?.roomId }),
- finishRollCall: () => socket?.emit('finish_roll_call', { roomId: gameState?.roomId }),
- finishMissionReveal: () => socket?.emit('finish_reveal', { roomId: gameState?.roomId }),
- finishMissionResult: () => socket?.emit('finish_mission_result', { roomId: gameState?.roomId }),
- restartGame: () => socket?.emit('restart_game', { roomId: gameState?.roomId }),
- finalizeGame: () => socket?.emit('finalize_game', { roomId: gameState?.roomId })
- }
+ actions
};
};