sto-k-odnomu/src/pages/GamePage.jsx
2026-01-06 23:46:49 +03:00

219 lines
6.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import { useRoom } from '../hooks/useRoom';
import { questionsApi } from '../services/api';
import Game from '../components/Game';
import './GamePage.css';
const GamePage = () => {
const { roomCode } = useParams();
const navigate = useNavigate();
const { user } = useAuth();
const {
room,
participants,
loading,
error,
updateQuestionPack,
} = useRoom(roomCode);
const [questions, setQuestions] = useState([]);
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
const [loadingQuestions, setLoadingQuestions] = useState(true);
const [questionPacks, setQuestionPacks] = useState([]);
const [selectedPackId, setSelectedPackId] = useState('');
const [updatingPack, setUpdatingPack] = useState(false);
useEffect(() => {
const loadQuestions = async () => {
if (!room) return;
setLoadingQuestions(true);
try {
if (room.questionPackId) {
// Загружаем вопросы из пака
if (room.questionPack && room.questionPack.questions) {
const packQuestions = room.questionPack.questions;
if (Array.isArray(packQuestions)) {
setQuestions(packQuestions);
} else {
setQuestions([]);
}
} else {
// Загружаем пак отдельно, если он не включен в room
const response = await questionsApi.getPack(room.questionPackId);
if (response.data && response.data.questions) {
setQuestions(
Array.isArray(response.data.questions)
? response.data.questions
: [],
);
} else {
setQuestions([]);
}
}
} else {
// Пак не выбран, начинаем с пустого списка вопросов
setQuestions([]);
}
} catch (error) {
console.error('Error loading questions:', error);
setQuestions([]);
} finally {
setLoadingQuestions(false);
}
};
loadQuestions();
}, [room]);
useEffect(() => {
const fetchPacks = async () => {
if (user && room && room.hostId === user.id) {
try {
const response = await questionsApi.getPacks(user.id);
setQuestionPacks(response.data);
} catch (error) {
console.error('Error fetching question packs:', error);
}
}
};
fetchPacks();
}, [user, room]);
useEffect(() => {
if (room && room.questionPackId) {
setSelectedPackId(room.questionPackId);
} else {
setSelectedPackId('');
}
}, [room]);
const handleUpdateQuestionPack = async () => {
if (!selectedPackId) {
alert('Выберите пак вопросов');
return;
}
try {
setUpdatingPack(true);
await updateQuestionPack(selectedPackId);
// Перезагружаем вопросы после обновления пака
const response = await questionsApi.getPack(selectedPackId);
if (response.data && response.data.questions) {
setQuestions(
Array.isArray(response.data.questions)
? response.data.questions
: [],
);
setCurrentQuestionIndex(0);
}
} catch (error) {
console.error('Error updating question pack:', error);
alert('Ошибка при обновлении пака вопросов');
} finally {
setUpdatingPack(false);
}
};
const handleQuestionsChange = (newQuestions) => {
setQuestions(newQuestions);
if (currentQuestionIndex >= newQuestions.length) {
setCurrentQuestionIndex(0);
}
};
if (loading || loadingQuestions) {
return <div className="loading">Загрузка игры...</div>;
}
if (error) {
return (
<div className="error-page">
<h1>Ошибка</h1>
<p>{error}</p>
<button onClick={() => navigate('/')}>На главную</button>
</div>
);
}
if (!room) {
return (
<div className="error-page">
<h1>Комната не найдена</h1>
<button onClick={() => navigate('/')}>На главную</button>
</div>
);
}
const isHost = user && room.hostId === user.id;
return (
<div className="game-page">
{isHost && (
<div className="host-controls">
<div className="pack-selector-inline">
<label>Пак вопросов:</label>
<select
value={selectedPackId}
onChange={(e) => setSelectedPackId(e.target.value)}
disabled={updatingPack}
>
<option value="">
{room.questionPackId
? 'Изменить пак вопросов'
: 'Выберите пак вопросов'}
</option>
{questionPacks.map((pack) => (
<option key={pack.id} value={pack.id}>
{pack.name} ({pack.questionCount} вопросов)
</option>
))}
</select>
<button
onClick={handleUpdateQuestionPack}
disabled={
!selectedPackId ||
selectedPackId === room.questionPackId ||
updatingPack
}
className="secondary"
>
{updatingPack ? 'Сохранение...' : 'Применить'}
</button>
<button
onClick={() => navigate(`/room/${roomCode}`)}
className="secondary"
>
Назад в комнату
</button>
</div>
</div>
)}
<div className="game-container">
{questions.length === 0 && (
<div className="no-questions-banner">
<p>
Вопросы не загружены.
{isHost
? ' Выберите пак вопросов выше, чтобы начать игру.'
: ' Ожидайте, пока ведущий добавит вопросы.'}
</p>
</div>
)}
<Game
questions={questions}
currentQuestionIndex={currentQuestionIndex}
onQuestionIndexChange={setCurrentQuestionIndex}
onQuestionsChange={handleQuestionsChange}
/>
</div>
</div>
);
};
export default GamePage;