2025-12-31 17:57:11 +00:00
|
|
|
import { useState, useRef, useEffect } from 'react'
|
2025-12-31 16:53:26 +00:00
|
|
|
import Game from './components/Game'
|
|
|
|
|
import Snowflakes from './components/Snowflakes'
|
2025-12-31 17:40:34 +00:00
|
|
|
import QuestionsModal from './components/QuestionsModal'
|
|
|
|
|
import { questions as initialQuestions } from './data/questions'
|
2025-12-31 17:57:11 +00:00
|
|
|
import { getCookie, setCookie, deleteCookie } from './utils/cookies'
|
2025-12-31 16:53:26 +00:00
|
|
|
import './App.css'
|
|
|
|
|
|
|
|
|
|
function App() {
|
2025-12-31 17:40:34 +00:00
|
|
|
const [isQuestionsModalOpen, setIsQuestionsModalOpen] = useState(false)
|
2025-12-31 17:57:11 +00:00
|
|
|
const [questions, setQuestions] = useState(() => {
|
|
|
|
|
const savedQuestions = getCookie('gameQuestions')
|
|
|
|
|
return savedQuestions || initialQuestions
|
|
|
|
|
})
|
|
|
|
|
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(() => {
|
|
|
|
|
const savedIndex = getCookie('gameQuestionIndex')
|
|
|
|
|
return savedIndex !== null ? savedIndex : 0
|
|
|
|
|
})
|
2025-12-31 17:40:34 +00:00
|
|
|
const gameRef = useRef(null)
|
|
|
|
|
|
|
|
|
|
const currentQuestion = questions[currentQuestionIndex]
|
|
|
|
|
|
2025-12-31 17:57:11 +00:00
|
|
|
// Сохраняем вопросы в cookies при изменении
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (questions.length > 0) {
|
|
|
|
|
setCookie('gameQuestions', questions)
|
|
|
|
|
}
|
|
|
|
|
}, [questions])
|
|
|
|
|
|
|
|
|
|
// Сохраняем индекс вопроса в cookies при изменении
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setCookie('gameQuestionIndex', currentQuestionIndex)
|
|
|
|
|
}, [currentQuestionIndex])
|
|
|
|
|
|
2025-12-31 17:40:34 +00:00
|
|
|
const handleUpdateQuestions = (updatedQuestions) => {
|
|
|
|
|
setQuestions(updatedQuestions)
|
|
|
|
|
// Если текущий вопрос был удален, сбрасываем индекс
|
|
|
|
|
if (currentQuestionIndex >= updatedQuestions.length) {
|
|
|
|
|
setCurrentQuestionIndex(0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleOpenPlayersModal = () => {
|
|
|
|
|
if (gameRef.current) {
|
|
|
|
|
gameRef.current.openPlayersModal()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-31 17:57:11 +00:00
|
|
|
const handleNewGame = () => {
|
|
|
|
|
if (window.confirm('Начать новую игру? Текущий прогресс будет потерян.')) {
|
|
|
|
|
deleteCookie('gameQuestions')
|
|
|
|
|
deleteCookie('gameQuestionIndex')
|
|
|
|
|
deleteCookie('gamePlayers')
|
|
|
|
|
deleteCookie('gamePlayerScores')
|
|
|
|
|
deleteCookie('gameCurrentPlayerId')
|
|
|
|
|
deleteCookie('gameRevealedAnswers')
|
|
|
|
|
deleteCookie('gameOver')
|
|
|
|
|
|
|
|
|
|
setQuestions(initialQuestions)
|
|
|
|
|
setCurrentQuestionIndex(0)
|
|
|
|
|
|
|
|
|
|
if (gameRef.current) {
|
|
|
|
|
gameRef.current.newGame()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleShowAll = () => {
|
|
|
|
|
if (gameRef.current && gameRef.current.showAllAnswers) {
|
|
|
|
|
gameRef.current.showAllAnswers()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-31 16:53:26 +00:00
|
|
|
return (
|
|
|
|
|
<div className="app">
|
|
|
|
|
<Snowflakes />
|
|
|
|
|
<div className="app-content">
|
2025-12-31 17:40:34 +00:00
|
|
|
<div className="app-title-bar">
|
|
|
|
|
<div className="app-control-buttons">
|
|
|
|
|
<button
|
|
|
|
|
className="control-button control-button-players"
|
|
|
|
|
onClick={handleOpenPlayersModal}
|
|
|
|
|
title="Управление участниками"
|
|
|
|
|
>
|
|
|
|
|
👥
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
className="control-button control-button-questions"
|
|
|
|
|
onClick={() => setIsQuestionsModalOpen(true)}
|
|
|
|
|
title="Управление вопросами"
|
|
|
|
|
>
|
|
|
|
|
❓
|
|
|
|
|
</button>
|
2025-12-31 17:57:11 +00:00
|
|
|
<button
|
|
|
|
|
className="control-button control-button-new-game"
|
|
|
|
|
onClick={handleNewGame}
|
|
|
|
|
title="Новая игра"
|
|
|
|
|
>
|
|
|
|
|
🎮
|
|
|
|
|
</button>
|
2025-12-31 17:40:34 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h1 className="app-title">
|
|
|
|
|
<span className="title-number">100</span>
|
|
|
|
|
<span className="title-to">к</span>
|
|
|
|
|
<span className="title-number">1</span>
|
|
|
|
|
</h1>
|
|
|
|
|
|
|
|
|
|
{questions.length > 0 && currentQuestion && (
|
2025-12-31 17:57:11 +00:00
|
|
|
<div className="question-counter-wrapper">
|
|
|
|
|
<div className="question-counter">
|
|
|
|
|
{currentQuestionIndex + 1}/{questions.length}
|
|
|
|
|
</div>
|
|
|
|
|
<button
|
|
|
|
|
className="show-all-button-top"
|
|
|
|
|
onClick={handleShowAll}
|
|
|
|
|
title="Показать все ответы"
|
|
|
|
|
>
|
|
|
|
|
Показать все
|
|
|
|
|
</button>
|
2025-12-31 17:40:34 +00:00
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<QuestionsModal
|
|
|
|
|
isOpen={isQuestionsModalOpen}
|
|
|
|
|
onClose={() => setIsQuestionsModalOpen(false)}
|
|
|
|
|
questions={questions}
|
|
|
|
|
onUpdateQuestions={handleUpdateQuestions}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<Game
|
|
|
|
|
ref={gameRef}
|
|
|
|
|
questions={questions}
|
|
|
|
|
currentQuestionIndex={currentQuestionIndex}
|
|
|
|
|
onQuestionIndexChange={setCurrentQuestionIndex}
|
|
|
|
|
onQuestionsChange={setQuestions}
|
|
|
|
|
/>
|
2025-12-31 16:53:26 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default App
|
|
|
|
|
|