import { useState, useEffect, useRef } from 'react'; import { Crown, Users, Play, ArrowLeft, Copy, Check, QrCode, UserMinus } from 'lucide-react'; import QRCodeGenerator from './QRCodeGenerator'; import { GAME_MODES } from '../utils/gameUtils'; function Lobby({ socket, playerData, roomData, onLeaveRoom, onGameStart }) { const [copied, setCopied] = useState(false); const [showQRCode, setShowQRCode] = useState(false); // Game mode selection (host only) const [multiModeEnabled, setMultiModeEnabled] = useState(false); const [selectedSingleMode, setSelectedSingleMode] = useState('fullHouse'); const [selectedMultiModes, setSelectedMultiModes] = useState({ first: 'fullHouse', second: 'corners', third: 'earlyFive' }); // HOST SUPERPOWERS - New state variables for lobby const [showPlayerManagement, setShowPlayerManagement] = useState(false); const [showTransferHost, setShowTransferHost] = useState(false); const [showKickConfirm, setShowKickConfirm] = useState(false); const [selectedPlayerToKick, setSelectedPlayerToKick] = useState(null); const [selectedPlayerForHost, setSelectedPlayerForHost] = useState(null); const [hostActionLoading, setHostActionLoading] = useState(false); // Ref for click outside detection const playerManagementRef = useRef(null); // Check if current player is host const isHost = roomData?.players?.find(p => p.id === playerData?.playerId)?.isHost; // HOST SUPERPOWERS - Functions for lobby const openKickConfirmation = (player) => { setSelectedPlayerToKick(player); setShowKickConfirm(true); setShowPlayerManagement(false); }; const confirmKickPlayer = () => { if (!selectedPlayerToKick || !socket) return; setHostActionLoading(true); socket.emit('kickPlayer', { targetPlayerId: selectedPlayerToKick.id }); setTimeout(() => { setHostActionLoading(false); setShowKickConfirm(false); setSelectedPlayerToKick(null); }, 1000); }; const openTransferHostDialog = () => { setShowTransferHost(true); setShowPlayerManagement(false); }; const confirmTransferHost = () => { if (!selectedPlayerForHost || !socket) return; setHostActionLoading(true); socket.emit('transferHost', { targetPlayerId: selectedPlayerForHost }); setTimeout(() => { setHostActionLoading(false); setShowTransferHost(false); setSelectedPlayerForHost(null); }, 1000); }; // Click outside to close dropdowns useEffect(() => { const handleClickOutside = (event) => { if (playerManagementRef.current && !playerManagementRef.current.contains(event.target)) { setShowPlayerManagement(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); // Socket event listeners useEffect(() => { if (!socket) return; // Listen for game start events socket.on('gameStarted', (data) => { onGameStart(data.room); }); socket.on('multiModeGameStarted', (data) => { onGameStart(data.room, data.activeGameModes); }); // Listen for host's game mode selection updates socket.on('gameModeSelectionUpdated', (data) => { setMultiModeEnabled(data.multiModeEnabled); if (data.multiModeEnabled) { setSelectedMultiModes(data.selectedMultiModes); } else { setSelectedSingleMode(data.selectedSingleMode); } }); // HOST SUPERPOWERS - Socket listeners for lobby socket.on('playerKicked', (data) => { // Handle being kicked if (playerData?.playerId === data.playerId) { onLeaveRoom(); } }); socket.on('hostTransferred', (data) => { // Handle host transfer notification - the roomData will be updated via other events console.log(`Host transferred from ${data.oldHost.nickname} to ${data.newHost.nickname}`); }); return () => { socket.off('gameStarted'); socket.off('multiModeGameStarted'); socket.off('gameModeSelectionUpdated'); socket.off('playerKicked'); socket.off('hostTransferred'); }; }, [socket, onGameStart]); // Update game mode selection and broadcast changes const handleMultiModeToggle = (enabled) => { setMultiModeEnabled(enabled); if (isHost && socket) { socket.emit('updateGameModeSelection', { multiModeEnabled: enabled, selectedSingleMode, selectedMultiModes }); } }; const handleSingleModeChange = (mode) => { setSelectedSingleMode(mode); if (isHost && socket) { socket.emit('updateGameModeSelection', { multiModeEnabled, selectedSingleMode: mode, selectedMultiModes }); } }; const handleMultiModeChange = (position, mode) => { const newMultiModes = { ...selectedMultiModes, [position]: mode }; setSelectedMultiModes(newMultiModes); if (isHost && socket) { socket.emit('updateGameModeSelection', { multiModeEnabled, selectedSingleMode, selectedMultiModes: newMultiModes }); } }; // Start game function (host only) const startGame = () => { if (!socket || !isHost) return; if (multiModeEnabled) { // Use maxModes from room data or calculate based on player count const maxModes = roomData?.maxModes || (roomData?.players?.length === 2 ? 2 : 3); const activeGameModes = []; if (maxModes >= 1) activeGameModes.push(selectedMultiModes.first); if (maxModes >= 2) activeGameModes.push(selectedMultiModes.second); if (maxModes >= 3) activeGameModes.push(selectedMultiModes.third); // Start multi-mode game socket.emit('startMultiModeGame', { activeGameModes: activeGameModes }); } else { // Start single-mode game socket.emit('startGame', { gameMode: selectedSingleMode }); } }; const copyRoomCode = async () => { try { await navigator.clipboard.writeText(playerData?.roomCode); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch (err) { // Handle copy error silently - user will notice if it doesn't work } }; return (
{roomData?.gameState === 'lobby' ? 'Waiting in Lobby' : `Status: ${roomData?.gameState}`}
Share the room code {playerData?.roomCode} with friends to invite them! {isHost && 💡 Tip: Use the QR button above for easier sharing}
Need at least 2 players to start the game
)}🎮 Waiting for host to configure game...
Game type will be selected by {roomData?.players?.find(p => p.isHost)?.nickname}
Multi-Mode Game:
Single Mode:
{GAME_MODES[selectedSingleMode]?.icon} {GAME_MODES[selectedSingleMode]?.name}
Are you sure you want to kick {selectedPlayerToKick.nickname} from the lobby?
Choose a player to transfer host role to: