120 lines
5.4 KiB
JavaScript
120 lines
5.4 KiB
JavaScript
function GameBoard({ questions, usedQuestions, onSelectQuestion, currentRound, isHost }) {
|
||
const isQuestionUsed = (category, points, questionIndex) => {
|
||
// Ищем этот конкретный вопрос в использованных
|
||
// Сначала проверяем по questionIndex (новый метод)
|
||
const foundByIndex = usedQuestions.find(
|
||
q => q.category === category && q.points === points && q.questionIndex === questionIndex
|
||
);
|
||
|
||
if (foundByIndex) {
|
||
console.log(`✓ Question used (by index): cat="${category}", pts=${points}, idx=${questionIndex}`);
|
||
return true;
|
||
}
|
||
|
||
// Для обратной совместимости: если в usedQuestions нет questionIndex,
|
||
// проверяем, сколько вопросов с такими баллами уже использовано
|
||
const usedCount = usedQuestions.filter(
|
||
q => q.category === category && q.points === points
|
||
).length;
|
||
|
||
if (usedCount === 0) return false;
|
||
|
||
// Получаем категорию и находим индекс вопроса среди вопросов с такими же баллами
|
||
const categoryData = questions.find(cat => cat.name === category);
|
||
const questionsWithSamePoints = categoryData?.questions
|
||
.map((q, idx) => ({ ...q, originalIndex: idx }))
|
||
.filter(q => q.points === points) || [];
|
||
|
||
const positionAmongSamePoints = questionsWithSamePoints.findIndex(q => q.originalIndex === questionIndex);
|
||
|
||
// Если позиция вопроса меньше количества использованных, значит он уже использован
|
||
return positionAmongSamePoints >= 0 && positionAmongSamePoints < usedCount;
|
||
}
|
||
|
||
const getPointsForRound = (basePoints, round) => {
|
||
return round === 2 ? basePoints * 2 : basePoints
|
||
}
|
||
|
||
// Проверить сколько вопросов осталось в категории
|
||
const hasAvailableQuestions = (category) => {
|
||
return category.questions.some((q, idx) => !isQuestionUsed(category.name, q.points, idx))
|
||
}
|
||
|
||
// Фильтруем категории - показываем только те, где есть доступные вопросы
|
||
const availableCategories = questions.filter(hasAvailableQuestions)
|
||
|
||
// Лог для отладки
|
||
console.log('📋 GameBoard render:', {
|
||
totalCategories: questions.length,
|
||
availableCategories: availableCategories.length,
|
||
usedQuestions: usedQuestions
|
||
});
|
||
|
||
return (
|
||
<div className="bg-slate-800 p-3 md:p-6 rounded-xl shadow-xl border border-slate-700">
|
||
{!isHost && (
|
||
<div className="mb-3 md:mb-4 bg-blue-900 p-3 md:p-4 rounded-lg text-center">
|
||
<p className="text-white text-sm md:text-lg font-medium">
|
||
Ведущий выбирает вопросы. Будьте готовы отвечать!
|
||
</p>
|
||
</div>
|
||
)}
|
||
{isHost && (
|
||
<div className="mb-3 md:mb-4 bg-blue-900 p-3 md:p-4 rounded-lg text-center">
|
||
<p className="text-white text-sm md:text-lg font-bold">
|
||
Выберите вопрос
|
||
</p>
|
||
</div>
|
||
)}
|
||
|
||
{availableCategories.length > 0 ? (
|
||
<div className="space-y-2">
|
||
{availableCategories.map((category, catIdx) => (
|
||
<div key={catIdx} className="flex flex-col md:flex-row gap-2">
|
||
{/* Название категории */}
|
||
<div className="bg-blue-900 p-2 md:p-4 rounded-lg flex items-center justify-center border border-blue-700 md:min-w-[200px]">
|
||
<h3 className="text-white font-bold text-sm md:text-lg text-center">
|
||
{category.name}
|
||
</h3>
|
||
</div>
|
||
|
||
{/* Вопросы по номиналам */}
|
||
<div className="grid grid-cols-5 md:flex gap-1 md:gap-2 flex-1">
|
||
{category.questions.map((question, questionIndex) => {
|
||
const displayPoints = getPointsForRound(question.points, currentRound)
|
||
const isUsed = isQuestionUsed(category.name, question.points, questionIndex)
|
||
|
||
return (
|
||
<button
|
||
key={questionIndex}
|
||
onClick={() => !isUsed && isHost && onSelectQuestion(category.name, question.points)}
|
||
disabled={isUsed || !isHost}
|
||
className={`flex-1 p-3 md:p-6 rounded-lg font-bold text-base md:text-2xl transition-all duration-200 ${
|
||
isUsed
|
||
? 'bg-slate-700 text-gray-500 cursor-not-allowed border border-slate-600'
|
||
: isHost
|
||
? 'bg-blue-600 text-white hover:bg-blue-700 cursor-pointer shadow-lg border border-blue-500'
|
||
: 'bg-blue-600 text-white cursor-default opacity-60 border border-blue-500'
|
||
}`}
|
||
>
|
||
{isUsed ? '—' : displayPoints}
|
||
</button>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
) : (
|
||
<div className="text-center py-8 md:py-12 bg-slate-700 rounded-lg border border-slate-600">
|
||
<p className="text-white text-lg md:text-2xl font-bold px-4">
|
||
Все вопросы раунда {currentRound} использованы!
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default GameBoard
|