sto-k-odnomu/src/pages/CreateRoom.jsx

223 lines
6.9 KiB
React
Raw Normal View History

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('');
const [settings, setSettings] = useState({
maxPlayers: 10,
allowSpectators: true,
timerEnabled: false,
timerDuration: 30,
2026-01-10 00:18:08 +00:00
password: '',
2026-01-03 14:07:04 +00:00
});
const [loading, setLoading] = useState(true);
2026-01-07 13:24:30 +00:00
const [isNameModalOpen, setIsNameModalOpen] = useState(false);
2026-01-09 23:27:21 +00:00
const [isHostNameModalOpen, setIsHostNameModalOpen] = useState(false);
2026-01-07 13:24:30 +00:00
// Проверка авторизации и показ модального окна для ввода имени
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;
}
2026-01-09 23:27:21 +00:00
// Всегда спрашиваем имя хоста перед созданием комнаты
setIsHostNameModalOpen(true);
};
const handleHostNameSubmit = async (name) => {
setIsHostNameModalOpen(false);
2026-01-03 14:07:04 +00:00
try {
2026-01-10 00:18:08 +00:00
// Очищаем пустой пароль перед отправкой
const cleanSettings = { ...settings };
if (!cleanSettings.password || !cleanSettings.password.trim()) {
delete cleanSettings.password;
} else {
cleanSettings.password = cleanSettings.password.trim();
}
2026-01-06 20:27:50 +00:00
const room = await createRoom(
user.id,
selectedPackId || undefined,
2026-01-10 00:18:08 +00:00
cleanSettings,
2026-01-09 23:27:21 +00:00
name.trim(),
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>
<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>
)}
2026-01-10 00:18:08 +00:00
<div className="form-group">
<label>Пароль на комнату (необязательно):</label>
<input
type="password"
value={settings.password}
onChange={(e) =>
setSettings({ ...settings, password: e.target.value })
}
placeholder="Оставьте пустым для публичной комнаты"
/>
<small style={{ color: 'rgba(255, 255, 255, 0.6)', fontSize: '0.85rem', marginTop: '5px', display: 'block' }}>
Если указан пароль, только игроки с паролем смогут присоединиться к комнате
</small>
</div>
2026-01-03 14:07:04 +00:00
<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-09 23:27:21 +00:00
<NameInputModal
isOpen={isHostNameModalOpen}
onSubmit={handleHostNameSubmit}
onCancel={() => setIsHostNameModalOpen(false)}
title="Введите ваше имя как ведущего"
description="Чтобы создать комнату, введите ваше имя как ведущего"
/>
2026-01-03 14:07:04 +00:00
</div>
);
};
export default CreateRoom;