import { useState } from 'react' import { questionsApi } from '../services/api' import './GameManagementModal.css' import './QuestionsModal.css' const GameManagementModal = ({ isOpen, onClose, room, participants, currentQuestion, currentQuestionIndex, totalQuestions, revealedAnswers, questions = [], onUpdateQuestions, availablePacks = [], onStartGame, onEndGame, onNextQuestion, onPreviousQuestion, onRevealAnswer, onHideAnswer, onShowAllAnswers, onHideAllAnswers, onAwardPoints, onPenalty, }) => { const [activeTab, setActiveTab] = useState('players') // players | game | answers | scoring | questions const [selectedPlayer, setSelectedPlayer] = useState(null) const [customPoints, setCustomPoints] = useState(10) // Questions management state const [editingQuestion, setEditingQuestion] = useState(null) const [questionText, setQuestionText] = useState('') const [answers, setAnswers] = useState([ { text: '', points: 100 }, { text: '', points: 80 }, { text: '', points: 60 }, { text: '', points: 40 }, { text: '', points: 20 }, { text: '', points: 10 }, ]) const [jsonError, setJsonError] = useState('') const [showPackImport, setShowPackImport] = useState(false) const [selectedPack, setSelectedPack] = useState(null) const [packQuestions, setPackQuestions] = useState([]) const [selectedQuestionIndices, setSelectedQuestionIndices] = useState(new Set()) if (!isOpen) return null const gameStatus = room?.status || 'WAITING' const areAllAnswersRevealed = currentQuestion ? revealedAnswers.length === currentQuestion.answers.length : false // Handlers const handleBackdropClick = (e) => { if (e.target === e.currentTarget) onClose() } const handleRevealAnswer = (index) => { if (revealedAnswers.includes(index)) { onHideAnswer(index) } else { onRevealAnswer(index) } } const handleAwardPoints = (points) => { if (selectedPlayer) { onAwardPoints(selectedPlayer, points) } } const handlePenalty = () => { if (selectedPlayer) { onPenalty(selectedPlayer) } } // Questions management handlers const resetQuestionForm = () => { setEditingQuestion(null) setQuestionText('') setAnswers([ { text: '', points: 100 }, { text: '', points: 80 }, { text: '', points: 60 }, { text: '', points: 40 }, { text: '', points: 20 }, { text: '', points: 10 }, ]) setJsonError('') } const handleEditQuestion = (question) => { setEditingQuestion(question) setQuestionText(question.text) setAnswers([...question.answers]) setJsonError('') } const handleCancelEditQuestion = () => { resetQuestionForm() } const handleAnswerChange = (index, field, value) => { const updatedAnswers = [...answers] if (field === 'text') { updatedAnswers[index].text = value } else if (field === 'points') { updatedAnswers[index].points = parseInt(value) || 0 } setAnswers(updatedAnswers) } const handleAddAnswer = () => { const minPoints = Math.min(...answers.map(a => a.points)) setAnswers([...answers, { text: '', points: Math.max(0, minPoints - 10) }]) } const handleRemoveAnswer = (index) => { if (answers.length > 1) { setAnswers(answers.filter((_, i) => i !== index)) } } const validateQuestionForm = () => { if (!questionText.trim()) { setJsonError('Введите текст вопроса') return false } if (answers.length === 0) { setJsonError('Добавьте хотя бы один ответ') return false } const hasEmptyAnswers = answers.some(a => !a.text.trim()) if (hasEmptyAnswers) { setJsonError('Заполните все ответы') return false } return true } const handleSaveQuestion = () => { if (!validateQuestionForm()) return const questionData = { id: editingQuestion ? editingQuestion.id : Date.now(), text: questionText.trim(), answers: answers .filter(a => a.text.trim()) .map(a => ({ text: a.text.trim(), points: a.points, })), } let updatedQuestions if (editingQuestion) { updatedQuestions = questions.map(q => q.id === editingQuestion.id ? questionData : q ) } else { updatedQuestions = [...questions, questionData] } onUpdateQuestions(updatedQuestions) resetQuestionForm() } const handleDeleteQuestion = (questionId) => { if (window.confirm('Вы уверены, что хотите удалить этот вопрос?')) { const updatedQuestions = questions.filter(q => q.id !== questionId) onUpdateQuestions(updatedQuestions) if (editingQuestion && editingQuestion.id === questionId) { resetQuestionForm() } } } const handleExportJson = () => { try { const jsonString = JSON.stringify(questions, null, 2) const blob = new Blob([jsonString], { type: 'application/json' }) const url = URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = 'questions.json' document.body.appendChild(link) link.click() document.body.removeChild(link) URL.revokeObjectURL(url) setJsonError('') } catch (error) { setJsonError('Ошибка при экспорте: ' + error.message) } } const handleImportJson = () => { const input = document.createElement('input') input.type = 'file' input.accept = '.json' input.onchange = (e) => { const file = e.target.files[0] if (!file) return const reader = new FileReader() reader.onload = (event) => { try { const jsonContent = JSON.parse(event.target.result) if (!Array.isArray(jsonContent)) { setJsonError('JSON должен содержать массив вопросов') return } const isValid = jsonContent.every(q => q.id && typeof q.text === 'string' && Array.isArray(q.answers) && q.answers.every(a => a.text && typeof a.points === 'number') ) if (!isValid) { setJsonError('Неверный формат JSON. Ожидается массив объектов с полями: id, text, answers') return } onUpdateQuestions(jsonContent) setJsonError('') alert(`Успешно импортировано ${jsonContent.length} вопросов`) } catch (error) { setJsonError('Ошибка при импорте: ' + error.message) } } reader.readAsText(file) } input.click() } const handleSelectPack = async (packId) => { if (!packId) { setPackQuestions([]) setSelectedPack(null) return } try { const response = await questionsApi.getPack(packId) setPackQuestions(response.data.questions || []) setSelectedPack(packId) setSelectedQuestionIndices(new Set()) } catch (error) { console.error('Error fetching pack:', error) setJsonError('Ошибка загрузки пака вопросов') } } const handleToggleQuestion = (index) => { const newSelected = new Set(selectedQuestionIndices) if (newSelected.has(index)) { newSelected.delete(index) } else { newSelected.add(index) } setSelectedQuestionIndices(newSelected) } const handleImportSelected = () => { const indices = Array.from(selectedQuestionIndices) const questionsToImport = indices.map(idx => packQuestions[idx]).filter(Boolean) const copiedQuestions = questionsToImport.map(q => ({ id: Date.now() + Math.random(), text: q.text, answers: q.answers.map(a => ({ text: a.text, points: a.points })), })) const updatedQuestions = [...questions, ...copiedQuestions] onUpdateQuestions(updatedQuestions) setSelectedQuestionIndices(new Set()) setShowPackImport(false) setJsonError('') alert(`Импортировано ${copiedQuestions.length} вопросов`) } return (
Нет участников
) : ( participants.map((participant) => (Нет вопросов. Добавьте вопросы для игры.
) : (