Add kick player and leave game functionality
- Host can kick players from lobby (removes from game, clears presenter if needed) - Client can voluntarily leave game - Fix browser-compatible base64 decoding for document upload (atob vs Buffer)
This commit is contained in:
parent
3122748bae
commit
79820f5298
7 changed files with 1640 additions and 10 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Player } from '../types';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { Sparkles, User, X, Link, Check, QrCode, Crown } from 'lucide-react';
|
||||
import { Sparkles, User, X, Link, Check, QrCode, Crown, LogOut, UserX } from 'lucide-react';
|
||||
import { QRCodeSVG } from 'qrcode.react';
|
||||
import { PlayerAvatar } from './PlayerAvatar';
|
||||
import toast from 'react-hot-toast';
|
||||
|
|
@ -17,9 +17,11 @@ interface LobbyProps {
|
|||
hostParticipates?: boolean;
|
||||
presenterId?: string | null;
|
||||
onSetPresenter?: (playerId: string | null) => void;
|
||||
onKickPlayer?: (playerId: string) => void;
|
||||
onLeaveGame?: () => void;
|
||||
}
|
||||
|
||||
export const Lobby: React.FC<LobbyProps> = ({ quizTitle, players, gamePin, role, onStart, onEndGame, currentPlayerId, hostParticipates = false, presenterId, onSetPresenter }) => {
|
||||
export const Lobby: React.FC<LobbyProps> = ({ quizTitle, players, gamePin, role, onStart, onEndGame, currentPlayerId, hostParticipates = false, presenterId, onSetPresenter, onKickPlayer, onLeaveGame }) => {
|
||||
const isHost = role === 'HOST';
|
||||
const hostPlayer = players.find(p => p.id === 'host');
|
||||
const realPlayers = players.filter(p => p.id !== 'host');
|
||||
|
|
@ -209,6 +211,18 @@ export const Lobby: React.FC<LobbyProps> = ({ quizTitle, players, gamePin, role,
|
|||
{isPlayerPresenter && (
|
||||
<span className="text-xs bg-yellow-400 text-yellow-900 px-2 py-0.5 rounded-full">PRESENTER</span>
|
||||
)}
|
||||
{onKickPlayer && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onKickPlayer(player.id);
|
||||
}}
|
||||
className="ml-1 p-1 rounded-full hover:bg-red-100 text-gray-400 hover:text-red-500 transition-colors"
|
||||
title="Kick player"
|
||||
>
|
||||
<UserX size={16} />
|
||||
</button>
|
||||
)}
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
|
|
@ -272,6 +286,19 @@ export const Lobby: React.FC<LobbyProps> = ({ quizTitle, players, gamePin, role,
|
|||
) : (
|
||||
<p className="text-lg md:text-2xl font-bold opacity-80">Waiting for the host to start...</p>
|
||||
)}
|
||||
|
||||
{onLeaveGame && (
|
||||
<motion.button
|
||||
initial={{ y: 20, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{ delay: 0.3 }}
|
||||
onClick={onLeaveGame}
|
||||
className="mt-8 bg-white/20 hover:bg-white/30 text-white px-6 py-3 rounded-full font-bold flex items-center gap-2 transition-all active:scale-95"
|
||||
>
|
||||
<LogOut size={20} />
|
||||
Leave Game
|
||||
</motion.button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue