3 Commits
v1.3.0 ... v1.4

Author SHA1 Message Date
Resistencia Dev
b68f4e9ff5 Fix: Update socket ID refs on reconnect (leader buttons bug)
Some checks failed
CI/CD - Francia Ocupada (La Resistencia) / build-and-deploy (push) Failing after 6s
2025-12-27 22:45:17 +01:00
Resistencia Dev
800db837bb docs: add .env.example template for configuration
Some checks failed
CI/CD - Francia Ocupada (La Resistencia) / build-and-deploy (push) Failing after 5s
2025-12-23 00:04:41 +01:00
Resistencia Dev
69e1f35886 feat: make admin dashboard password configurable via env variable NEXT_PUBLIC_ADMIN_PASSWORD
Some checks failed
CI/CD - Francia Ocupada (La Resistencia) / build-and-deploy (push) Failing after 6s
2025-12-23 00:00:03 +01:00
6 changed files with 67 additions and 8 deletions

View File

@@ -1,13 +1,25 @@
# ===========================================
# Archivo de ejemplo de configuración
# Copia este archivo a .env y modifica los valores
# ===========================================
# Configuración de red local
# Cambia esta IP a la IP de tu PC en la red local
HOST_IP=192.168.1.131
HOST_IP=192.168.1.XXX
# URLs para desarrollo local
NEXT_PUBLIC_API_URL=http://192.168.1.131:4000
CORS_ORIGIN=http://192.168.1.131:3000
NEXT_PUBLIC_API_URL=http://192.168.1.XXX:4000
CORS_ORIGIN=http://192.168.1.XXX:3000
# URLs para producción (descomentar y ajustar)
# NEXT_PUBLIC_API_URL=https://api.tudominio.com
# CORS_ORIGIN=https://tudominio.com
# Configuración de base de datos
DATABASE_URL=postgresql://postgres:password@db:5432/resistencia
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_PASSWORD=cambia_esta_contraseña
POSTGRES_DB=resistencia
# Contraseña del dashboard de administración
NEXT_PUBLIC_ADMIN_PASSWORD=cambia_esta_contraseña

View File

@@ -1,7 +1,12 @@
FROM node:20-alpine
# Build argument for API URL
# Build arguments
ARG NEXT_PUBLIC_API_URL=http://localhost:4000
ARG NEXT_PUBLIC_ADMIN_PASSWORD=admin123
# Make args available as env vars during build
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_ADMIN_PASSWORD=$NEXT_PUBLIC_ADMIN_PASSWORD
# Create app directory
WORKDIR /app

View File

@@ -5,7 +5,7 @@ import { motion, AnimatePresence } from 'framer-motion';
import { useSocket } from '../../hooks/useSocket';
import { Shield, Users, Gamepad2, LogOut, Clock, History, UserMinus, Key, ChevronDown } from 'lucide-react';
const ADMIN_PASSWORD = "admin123";
const ADMIN_PASSWORD = process.env.NEXT_PUBLIC_ADMIN_PASSWORD || "admin123";
export default function Dashboard() {
const { socket, isConnected } = useSocket();

View File

@@ -7,6 +7,7 @@ services:
dockerfile: client/Dockerfile
args:
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-https://api.franciaocupada.martivich.es}
- NEXT_PUBLIC_ADMIN_PASSWORD=${NEXT_PUBLIC_ADMIN_PASSWORD:-admin123}
ports:
- "3000:3000"
volumes:
@@ -15,6 +16,7 @@ services:
- /app/client/node_modules
environment:
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-https://api.franciaocupada.martivich.es}
- NEXT_PUBLIC_ADMIN_PASSWORD=${NEXT_PUBLIC_ADMIN_PASSWORD:-admin123}
depends_on:
- server
networks:

View File

@@ -405,8 +405,8 @@ io.on('connection', (socket) => {
const existingPlayer = game.state.players.find(p => p.name === playerName);
if (existingPlayer) {
// Actualizar el socket ID del jugador
existingPlayer.id = socket.id;
// Actualizar el socket ID del jugador y referencias
game.updatePlayerSocket(existingPlayer.id, socket.id);
// Unir al socket a la sala
socket.join(roomId);

View File

@@ -415,4 +415,44 @@ export class Game {
// Mantener solo los últimos 50 mensajes
if (this.state.history.length > 50) this.state.history.shift();
}
updatePlayerSocket(oldId: string, newId: string) {
const player = this.state.players.find(p => p.id === oldId);
if (!player) return;
// Actualizar ID del jugador
player.id = newId;
// Actualizar referencias en el estado
// 1. Host
if (this.hostId === oldId) {
this.hostId = newId;
this.state.hostId = newId;
}
// 2. Líder actual
if (this.state.currentLeaderId === oldId) {
this.state.currentLeaderId = newId;
}
// 3. Votos de Líder (leaderVotes)
if (this.state.leaderVotes && this.state.leaderVotes[oldId] !== undefined) {
this.state.leaderVotes[newId] = this.state.leaderVotes[oldId];
delete this.state.leaderVotes[oldId];
}
// 4. Votos de Equipo (teamVotes)
if (this.state.teamVotes && this.state.teamVotes[oldId] !== undefined) {
this.state.teamVotes[newId] = this.state.teamVotes[oldId];
delete this.state.teamVotes[oldId];
}
// 5. Equipo Propuesto (proposedTeam)
if (this.state.proposedTeam && this.state.proposedTeam.includes(oldId)) {
this.state.proposedTeam = this.state.proposedTeam.map(id => id === oldId ? newId : id);
}
this.log(`Jugador ${player.name} reconectado. ID actualizado.`);
}
}