234 lines
8.1 KiB
React
234 lines
8.1 KiB
React
// components/Lobby.js
|
||
import React, { useState } from 'react';
|
||
import './Lobby.css';
|
||
|
||
const Lobby = ({
|
||
onCreateRoom,
|
||
onJoinRoom,
|
||
players,
|
||
roomCode,
|
||
isHost,
|
||
onStartGame,
|
||
gameSettings,
|
||
setGameSettings
|
||
}) => {
|
||
const [playerName, setPlayerName] = useState("");
|
||
const [playerAvatar, setPlayerAvatar] = useState("👤");
|
||
const [joinCode, setJoinCode] = useState("");
|
||
const [showCreateForm, setShowCreateForm] = useState(true);
|
||
const [showSettings, setShowSettings] = useState(false);
|
||
|
||
const avatars = ["👤", "👨💻", "👩🎨", "👨🚀", "🦸♂️", "🦸♀️", "🐱", "🐶", "🦊", "🐼"];
|
||
|
||
const handleCreateSubmit = (e) => {
|
||
e.preventDefault();
|
||
if (playerName.trim()) {
|
||
onCreateRoom(playerName, playerAvatar);
|
||
}
|
||
};
|
||
|
||
const handleJoinSubmit = (e) => {
|
||
e.preventDefault();
|
||
if (playerName.trim() && joinCode.trim()) {
|
||
onJoinRoom(playerName, playerAvatar, joinCode);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="lobby-container">
|
||
<div className="lobby-card">
|
||
<div className="lobby-header">
|
||
<h1>🎮 Игровое лобби</h1>
|
||
<p>Присоединяйтесь к викторине или создайте свою комнату</p>
|
||
</div>
|
||
|
||
<div className="lobby-tabs">
|
||
<button
|
||
className={`tab ${showCreateForm ? 'active' : ''}`}
|
||
onClick={() => setShowCreateForm(true)}
|
||
>
|
||
Создать комнату
|
||
</button>
|
||
<button
|
||
className={`tab ${!showCreateForm ? 'active' : ''}`}
|
||
onClick={() => setShowCreateForm(false)}
|
||
>
|
||
Присоединиться
|
||
</button>
|
||
</div>
|
||
|
||
{showCreateForm ? (
|
||
<form onSubmit={handleCreateSubmit} className="lobby-form">
|
||
<div className="form-group">
|
||
<label>Ваше имя:</label>
|
||
<input
|
||
type="text"
|
||
value={playerName}
|
||
onChange={(e) => setPlayerName(e.target.value)}
|
||
placeholder="Введите ваше имя"
|
||
maxLength="20"
|
||
required
|
||
/>
|
||
</div>
|
||
|
||
<div className="form-group">
|
||
<label>Выберите аватар:</label>
|
||
<div className="avatar-selection">
|
||
{avatars.map(avatar => (
|
||
<div
|
||
key={avatar}
|
||
className={`avatar-option ${playerAvatar === avatar ? 'selected' : ''}`}
|
||
onClick={() => setPlayerAvatar(avatar)}
|
||
>
|
||
<span className="avatar-emoji">{avatar}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div className="form-group">
|
||
<label>Настройки комнаты:</label>
|
||
<button
|
||
type="button"
|
||
className="settings-button"
|
||
onClick={() => setShowSettings(!showSettings)}
|
||
>
|
||
⚙️ Настройки игры
|
||
</button>
|
||
|
||
{showSettings && (
|
||
<div className="game-settings">
|
||
<div className="setting-item">
|
||
<label>Время на вопрос (секунд):</label>
|
||
<select
|
||
value={gameSettings.timePerQuestion}
|
||
onChange={(e) => setGameSettings({
|
||
...gameSettings,
|
||
timePerQuestion: parseInt(e.target.value)
|
||
})}
|
||
>
|
||
<option value="15">15 секунд</option>
|
||
<option value="30">30 секунд</option>
|
||
<option value="45">45 секунд</option>
|
||
<option value="60">60 секунд</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div className="setting-item">
|
||
<label>Сложность:</label>
|
||
<select
|
||
value={gameSettings.difficulty}
|
||
onChange={(e) => setGameSettings({
|
||
...gameSettings,
|
||
difficulty: e.target.value
|
||
})}
|
||
>
|
||
<option value="easy">Легкая</option>
|
||
<option value="medium">Средняя</option>
|
||
<option value="hard">Сложная</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div className="setting-item">
|
||
<label>
|
||
<input
|
||
type="checkbox"
|
||
checked={gameSettings.showCorrectAnswer}
|
||
onChange={(e) => setGameSettings({
|
||
...gameSettings,
|
||
showCorrectAnswer: e.target.checked
|
||
})}
|
||
/>
|
||
Показывать правильный ответ после вопроса
|
||
</label>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
<button type="submit" className="create-button">
|
||
Создать комнату 🚀
|
||
</button>
|
||
</form>
|
||
) : (
|
||
<form onSubmit={handleJoinSubmit} className="lobby-form">
|
||
<div className="form-group">
|
||
<label>Ваше имя:</label>
|
||
<input
|
||
type="text"
|
||
value={playerName}
|
||
onChange={(e) => setPlayerName(e.target.value)}
|
||
placeholder="Введите ваше имя"
|
||
maxLength="20"
|
||
required
|
||
/>
|
||
</div>
|
||
|
||
<div className="form-group">
|
||
<label>Выберите аватар:</label>
|
||
<div className="avatar-selection">
|
||
{avatars.map(avatar => (
|
||
<div
|
||
key={avatar}
|
||
className={`avatar-option ${playerAvatar === avatar ? 'selected' : ''}`}
|
||
onClick={() => setPlayerAvatar(avatar)}
|
||
>
|
||
<span className="avatar-emoji">{avatar}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div className="form-group">
|
||
<label>Код комнаты:</label>
|
||
<input
|
||
type="text"
|
||
value={joinCode}
|
||
onChange={(e) => setJoinCode(e.target.value.toUpperCase())}
|
||
placeholder="Введите код комнаты"
|
||
maxLength="6"
|
||
required
|
||
/>
|
||
</div>
|
||
|
||
<button type="submit" className="join-button">
|
||
Присоединиться 🎮
|
||
</button>
|
||
</form>
|
||
)}
|
||
|
||
{roomCode && (
|
||
<div className="room-info">
|
||
<h3>Ваша комната:</h3>
|
||
<div className="room-code">
|
||
Код: <strong>{roomCode}</strong>
|
||
<button
|
||
onClick={() => navigator.clipboard.writeText(roomCode)}
|
||
className="copy-button"
|
||
>
|
||
📋
|
||
</button>
|
||
</div>
|
||
<div className="players-list">
|
||
<h4>Игроки в комнате ({players.length}):</h4>
|
||
{players.map(player => (
|
||
<div key={player.id} className="lobby-player">
|
||
<span className="player-avatar">{player.avatar}</span>
|
||
<span className="player-name">{player.name}</span>
|
||
{player.isHost && <span className="host-tag">Хост</span>}
|
||
</div>
|
||
))}
|
||
</div>
|
||
{isHost && players.length > 0 && (
|
||
<button onClick={onStartGame} className="start-game-btn">
|
||
Начать игру 🎯
|
||
</button>
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default Lobby; |