2026-01-03 14:07:04 +00:00
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
|
import { useNavigate } from 'react-router-dom';
|
|
|
|
|
import { useAuth } from '../context/AuthContext';
|
|
|
|
|
import { useRoom } from '../hooks/useRoom';
|
|
|
|
|
import { questionsApi } from '../services/api';
|
2026-01-07 13:24:30 +00:00
|
|
|
import NameInputModal from '../components/NameInputModal';
|
2026-01-03 14:07:04 +00:00
|
|
|
|
|
|
|
|
const CreateRoom = () => {
|
|
|
|
|
const navigate = useNavigate();
|
2026-01-07 13:24:30 +00:00
|
|
|
const { user, loginAnonymous, loading: authLoading } = useAuth();
|
2026-01-03 14:07:04 +00:00
|
|
|
const { createRoom, loading: roomLoading } = useRoom();
|
|
|
|
|
|
|
|
|
|
const [questionPacks, setQuestionPacks] = useState([]);
|
|
|
|
|
const [selectedPackId, setSelectedPackId] = useState('');
|
2026-01-09 21:36:49 +00:00
|
|
|
const [hostName, setHostName] = useState('');
|
2026-01-03 14:07:04 +00:00
|
|
|
const [settings, setSettings] = useState({
|
|
|
|
|
maxPlayers: 10,
|
|
|
|
|
allowSpectators: true,
|
|
|
|
|
timerEnabled: false,
|
|
|
|
|
timerDuration: 30,
|
|
|
|
|
});
|
|
|
|
|
const [loading, setLoading] = useState(true);
|
2026-01-07 13:24:30 +00:00
|
|
|
const [isNameModalOpen, setIsNameModalOpen] = useState(false);
|
|
|
|
|
|
|
|
|
|
// Проверка авторизации и показ модального окна для ввода имени
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!authLoading && !user) {
|
|
|
|
|
setIsNameModalOpen(true);
|
|
|
|
|
} else if (user) {
|
|
|
|
|
setIsNameModalOpen(false);
|
|
|
|
|
}
|
|
|
|
|
}, [authLoading, user]);
|
|
|
|
|
|
|
|
|
|
// Обработка ввода имени и авторизация
|
|
|
|
|
const handleNameSubmit = async (name) => {
|
|
|
|
|
try {
|
|
|
|
|
await loginAnonymous(name);
|
|
|
|
|
setIsNameModalOpen(false);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Login error:', error);
|
|
|
|
|
alert('Ошибка при авторизации. Попробуйте еще раз.');
|
|
|
|
|
}
|
|
|
|
|
};
|
2026-01-03 14:07:04 +00:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const fetchPacks = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const response = await questionsApi.getPacks(user?.id);
|
|
|
|
|
setQuestionPacks(response.data);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching question packs:', error);
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-07 13:24:30 +00:00
|
|
|
if (user) {
|
|
|
|
|
fetchPacks();
|
|
|
|
|
} else {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
2026-01-03 14:07:04 +00:00
|
|
|
}, [user]);
|
|
|
|
|
|
|
|
|
|
const handleCreateRoom = async () => {
|
2026-01-06 20:27:50 +00:00
|
|
|
if (!user) {
|
2026-01-07 13:24:30 +00:00
|
|
|
setIsNameModalOpen(true);
|
2026-01-03 14:07:04 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
2026-01-06 20:27:50 +00:00
|
|
|
const room = await createRoom(
|
|
|
|
|
user.id,
|
|
|
|
|
selectedPackId || undefined,
|
|
|
|
|
settings,
|
2026-01-09 21:36:49 +00:00
|
|
|
hostName.trim() || undefined,
|
2026-01-06 20:27:50 +00:00
|
|
|
);
|
2026-01-03 14:07:04 +00:00
|
|
|
navigate(`/room/${room.code}`);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error creating room:', error);
|
|
|
|
|
alert('Ошибка создания комнаты');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (loading) {
|
|
|
|
|
return <div className="loading">Загрузка...</div>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="create-room-page">
|
|
|
|
|
<div className="create-room-container">
|
|
|
|
|
<h1>Создать комнату</h1>
|
|
|
|
|
|
2026-01-09 21:36:49 +00:00
|
|
|
<div className="form-group">
|
|
|
|
|
<label>Ваше имя как ведущего:</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={hostName}
|
|
|
|
|
onChange={(e) => setHostName(e.target.value)}
|
|
|
|
|
placeholder="Ведущий"
|
|
|
|
|
maxLength={50}
|
|
|
|
|
/>
|
|
|
|
|
<small className="form-hint">Оставьте пустым для использования «Ведущий»</small>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-01-03 14:07:04 +00:00
|
|
|
<div className="form-group">
|
2026-01-06 20:27:50 +00:00
|
|
|
<label>Выберите пак вопросов (можно добавить позже):</label>
|
2026-01-03 14:07:04 +00:00
|
|
|
<select
|
|
|
|
|
value={selectedPackId}
|
|
|
|
|
onChange={(e) => setSelectedPackId(e.target.value)}
|
|
|
|
|
>
|
2026-01-06 20:27:50 +00:00
|
|
|
<option value="">Без пака вопросов</option>
|
2026-01-03 14:07:04 +00:00
|
|
|
{questionPacks.map((pack) => (
|
|
|
|
|
<option key={pack.id} value={pack.id}>
|
|
|
|
|
{pack.name} ({pack.questionCount} вопросов)
|
|
|
|
|
</option>
|
|
|
|
|
))}
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="form-group">
|
|
|
|
|
<label>Максимум игроков:</label>
|
|
|
|
|
<input
|
|
|
|
|
type="number"
|
|
|
|
|
min="2"
|
|
|
|
|
max="20"
|
|
|
|
|
value={settings.maxPlayers}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setSettings({ ...settings, maxPlayers: parseInt(e.target.value) })
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="form-group checkbox">
|
|
|
|
|
<label>
|
|
|
|
|
<input
|
|
|
|
|
type="checkbox"
|
|
|
|
|
checked={settings.allowSpectators}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setSettings({ ...settings, allowSpectators: e.target.checked })
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
Разрешить зрителей
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="form-group checkbox">
|
|
|
|
|
<label>
|
|
|
|
|
<input
|
|
|
|
|
type="checkbox"
|
|
|
|
|
checked={settings.timerEnabled}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setSettings({ ...settings, timerEnabled: e.target.checked })
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
Включить таймер
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{settings.timerEnabled && (
|
|
|
|
|
<div className="form-group">
|
|
|
|
|
<label>Время на ответ (сек):</label>
|
|
|
|
|
<input
|
|
|
|
|
type="number"
|
|
|
|
|
min="10"
|
|
|
|
|
max="120"
|
|
|
|
|
value={settings.timerDuration}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setSettings({ ...settings, timerDuration: parseInt(e.target.value) })
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div className="button-group">
|
|
|
|
|
<button
|
|
|
|
|
onClick={handleCreateRoom}
|
2026-01-06 20:27:50 +00:00
|
|
|
disabled={roomLoading}
|
2026-01-03 14:07:04 +00:00
|
|
|
className="primary"
|
|
|
|
|
>
|
|
|
|
|
{roomLoading ? 'Создание...' : 'Создать комнату'}
|
|
|
|
|
</button>
|
|
|
|
|
<button onClick={() => navigate('/')}>Назад</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-01-07 13:24:30 +00:00
|
|
|
|
|
|
|
|
<NameInputModal
|
|
|
|
|
isOpen={isNameModalOpen}
|
|
|
|
|
onSubmit={handleNameSubmit}
|
|
|
|
|
onCancel={null}
|
|
|
|
|
/>
|
2026-01-03 14:07:04 +00:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default CreateRoom;
|