import React, { useState } from 'react'; import { Player } from '../types'; import { motion, AnimatePresence } from 'framer-motion'; import { Sparkles, User, X, Link, Check, QrCode, Crown, LogOut, UserX, Loader2, Pencil } from 'lucide-react'; import { QRCodeSVG } from 'qrcode.react'; import { PlayerAvatar } from './PlayerAvatar'; import toast from 'react-hot-toast'; interface LobbyProps { quizTitle: string; players: Player[]; gamePin: string | null; role: 'HOST' | 'CLIENT'; onStart: () => void; onEndGame?: () => void; currentPlayerId?: string | null; hostParticipates?: boolean; presenterId?: string | null; onSetPresenter?: (playerId: string | null) => void; onKickPlayer?: (playerId: string) => void; onLeaveGame?: () => void; hostName?: string | null; onHostNameChange?: (name: string) => void; } export const Lobby: React.FC = ({ quizTitle, players, gamePin, role, onStart, onEndGame, currentPlayerId, hostParticipates = false, presenterId, onSetPresenter, onKickPlayer, onLeaveGame, hostName, onHostNameChange }) => { const isHost = role === 'HOST'; const hostPlayer = players.find(p => p.id === 'host'); const realPlayers = players.filter(p => p.id !== 'host'); const currentPlayer = currentPlayerId ? players.find(p => p.id === currentPlayerId) : null; const [linkCopied, setLinkCopied] = useState(false); const [isQrModalOpen, setIsQrModalOpen] = useState(false); const [isStarting, setIsStarting] = useState(false); const [isEditingName, setIsEditingName] = useState(false); const [editedName, setEditedName] = useState(hostName || 'Host'); const handleStart = () => { setIsStarting(true); onStart(); }; const handleNameSubmit = () => { if (onHostNameChange && editedName.trim()) { onHostNameChange(editedName.trim()); } setIsEditingName(false); }; const isPresenter = currentPlayerId === presenterId; const canSelectPresenter = isHost && !hostParticipates && onSetPresenter; React.useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') setIsQrModalOpen(false); }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, []); const copyJoinLink = async () => { if (!gamePin) return; const joinUrl = `${window.location.origin}/play/${gamePin}`; await navigator.clipboard.writeText(joinUrl); setLinkCopied(true); toast.success('Join link copied!'); setTimeout(() => setLinkCopied(false), 2000); }; return (

{quizTitle}

Live
Game PIN
{gamePin}
Players
{realPlayers.length}
{isHost && (
)}
{isHost && gamePin && ( )}
Join at kaboot.com
{gamePin}
{isHost && ( )}

{quizTitle}

Live Lobby
{realPlayers.length} Players
{isHost ? ( <>
{realPlayers.length === 0 && !hostParticipates && (
Waiting for players to join...
)} {realPlayers.length > 0 && !hostParticipates && canSelectPresenter && (
Click a player to make them presenter (can advance screens)
)} {hostParticipates && hostPlayer && ( {isEditingName ? (
{ e.preventDefault(); handleNameSubmit(); }} className="flex items-center gap-2"> setEditedName(e.target.value)} onBlur={handleNameSubmit} autoFocus maxLength={20} className="bg-white/80 text-black px-2 py-1 rounded-lg text-base font-bold w-28 outline-none focus:ring-2 focus:ring-yellow-600" />
) : ( )} HOST
)} {realPlayers.map((player) => { const isPlayerPresenter = player.id === presenterId; return ( canSelectPresenter && onSetPresenter(player.id)} className={`bg-white text-black px-4 md:px-6 py-2 md:py-3 rounded-full font-black text-base md:text-xl shadow-[0_4px_0_rgba(0,0,0,0.2)] flex items-center gap-2 md:gap-3 border-b-4 ${ isPlayerPresenter ? 'border-yellow-400 ring-2 ring-yellow-400' : 'border-gray-200' } ${canSelectPresenter ? 'cursor-pointer hover:scale-105 transition-transform' : ''}`} > {isPlayerPresenter && ( )} {player.name} {isPlayerPresenter && ( PRESENTER )} {onKickPlayer && ( )} ); })}
{onEndGame && ( )} ) : (
{isPresenter && (
)} {currentPlayer ? ( ) : ( )}

{currentPlayer?.name || "You're in!"}

{isPresenter ? (
You are the Presenter

You can advance screens during the game

) : (

Waiting for the host to start...

)}
{/* Player list */}
{players.length} Player{players.length !== 1 ? 's' : ''} Connected
{players.map((player) => { const isCurrentPlayer = player.id === currentPlayerId; const isPlayerHost = player.id === 'host'; const isPlayerPresenter = player.id === presenterId; return ( {isPlayerPresenter && !isPlayerHost && ( )} {player.name} {isPlayerHost && ( HOST )} {isCurrentPlayer && !isPlayerHost && ( YOU )} ); })}
{onLeaveGame && ( Leave Game )}
)}
{isQrModalOpen && ( setIsQrModalOpen(false)} > e.stopPropagation()} >

Scan to Join

Or visit URL
{`${window.location.origin}/play/${gamePin}`}
Tap backdrop or ESC to close
)}
); };