diff --git a/admin/src/components/GameQuestionEditorDialog.tsx b/admin/src/components/GameQuestionEditorDialog.tsx new file mode 100644 index 0000000..26ccf20 --- /dev/null +++ b/admin/src/components/GameQuestionEditorDialog.tsx @@ -0,0 +1,249 @@ +import { useState, useEffect } from 'react' +import type { Question, Answer } from '@/types/models' +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog' +import { Button } from '@/components/ui/button' +import { Label } from '@/components/ui/label' +import { Input } from '@/components/ui/input' +import { Textarea } from '@/components/ui/textarea' +import { Card, CardContent } from '@/components/ui/card' +import { Plus, Trash2 } from 'lucide-react' + +interface GameQuestionEditorDialogProps { + open: boolean + question: Question | null + onSave: (question: Question) => void + onClose: () => void +} + +export function GameQuestionEditorDialog({ + open, + question, + onSave, + onClose, +}: GameQuestionEditorDialogProps) { + 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 }, + ]) + + // Инициализация формы при открытии диалога + useEffect(() => { + if (open) { + if (question) { + setQuestionText(question.question || '') + setAnswers( + question.answers && question.answers.length > 0 + ? [...question.answers] + : [ + { text: '', points: 100 }, + { text: '', points: 80 }, + { text: '', points: 60 }, + { text: '', points: 40 }, + { text: '', points: 20 }, + { text: '', points: 10 }, + ], + ) + } else { + setQuestionText('') + setAnswers([ + { text: '', points: 100 }, + { text: '', points: 80 }, + { text: '', points: 60 }, + { text: '', points: 40 }, + { text: '', points: 20 }, + { text: '', points: 10 }, + ]) + } + } + }, [open, question]) + + const handleAnswerChange = (index: number, field: 'text' | 'points', value: string | number) => { + const updatedAnswers = [...answers] + if (field === 'text') { + updatedAnswers[index].text = value as string + } else { + updatedAnswers[index].points = typeof value === 'number' ? value : parseInt(value as string) || 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: number) => { + if (answers.length > 1) { + setAnswers(answers.filter((_, i) => i !== index)) + } + } + + const handleSave = () => { + // Валидация + if (!questionText.trim()) { + return + } + + const validAnswers = answers + .filter(a => a.text.trim()) + .map(a => ({ + text: a.text.trim(), + points: a.points, + })) + + if (validAnswers.length === 0) { + return + } + + const questionData: Question = { + question: questionText.trim(), + answers: validAnswers, + } + + onSave(questionData) + } + + const isValid = + questionText.trim().length > 0 && + answers.filter(a => a.text.trim()).length > 0 + + return ( + + + + + {question ? 'Edit Question' : 'Create New Question'} + + + {question + ? 'Update the question information' + : 'Add a new question to the pack'} + + + +
+
+ +