156 lines
No EOL
5.8 KiB
TypeScript
156 lines
No EOL
5.8 KiB
TypeScript
import React, {useState, useRef, useEffect} from "react";
|
||
import AnswerOption from '../AnswerOption/AnswerOption';
|
||
import AddAnswerButton from "../AddAnswerButton/AddAnswerButton.tsx";
|
||
import TypeDropdown from "../TypeDropdown/TypeDropdown.tsx";
|
||
import styles from './QuestionItem.module.css'
|
||
|
||
|
||
interface QuestionItemProps {
|
||
indexQuestion: number;
|
||
initialTextQuestion?: string;
|
||
valueQuestion: string;
|
||
onChangeQuestion: (valueQuestion: string) => void;
|
||
onDeleteQuestion: (index: number) => void;
|
||
}
|
||
|
||
const QuestionItem: React.FC<QuestionItemProps> = ({indexQuestion, initialTextQuestion = `Вопрос ${indexQuestion}`,
|
||
valueQuestion, onChangeQuestion, onDeleteQuestion}) => {
|
||
const [selectedType, setSelectedType] = useState<'single' | 'multiply'>('single');
|
||
const [answerOption, setAnswerOption] = useState(['']);
|
||
const [textQuestion, setTextQuestion] = useState(initialTextQuestion);
|
||
const [isEditingQuestion, setIsEditingQuestion] = useState(false);
|
||
|
||
const [selectedAnswers, setSelectedAnswers] = useState<number[]>([]);
|
||
|
||
const textareaQuestionRef = useRef<HTMLTextAreaElement>(null);
|
||
|
||
const handleTypeChange = (type: 'single' | 'multiply') => {
|
||
setSelectedType(type);
|
||
}
|
||
|
||
const handleAddAnswer = () => {
|
||
setAnswerOption([...answerOption, '']);
|
||
};
|
||
|
||
const handleQuestionClick = () => {
|
||
setIsEditingQuestion(true);
|
||
}
|
||
|
||
const handleTextareaQuestionChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||
setTextQuestion(event.target.value);
|
||
|
||
if (textareaQuestionRef.current) {
|
||
textareaQuestionRef.current.style.height = 'auto';
|
||
textareaQuestionRef.current.style.height = `${textareaQuestionRef.current.scrollHeight}px`;
|
||
}
|
||
}
|
||
|
||
const handleSaveQuestion = () => {
|
||
setIsEditingQuestion(false);
|
||
onChangeQuestion(textQuestion);
|
||
}
|
||
|
||
const handleQuestionKeyDown = (keyDownEvent: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||
if (keyDownEvent.key === 'Enter') {
|
||
keyDownEvent.preventDefault();
|
||
handleSaveQuestion()
|
||
}
|
||
}
|
||
|
||
const handleQuestionBlur = () => {
|
||
handleSaveQuestion()
|
||
}
|
||
|
||
useEffect(() => {
|
||
if (isEditingQuestion && textareaQuestionRef.current) {
|
||
textareaQuestionRef.current.focus();
|
||
textareaQuestionRef.current.style.height = 'auto';
|
||
textareaQuestionRef.current.style.height = `${textareaQuestionRef.current.scrollHeight}px`;
|
||
}
|
||
}, [isEditingQuestion]);
|
||
|
||
const handleAnswerChange = (index: number, value: string) => {
|
||
const newAnswerOption = [...answerOption];
|
||
newAnswerOption[index] = value;
|
||
setAnswerOption(newAnswerOption);
|
||
}
|
||
|
||
const handleDeleteAnswer = (index: number) => {
|
||
const newAnswerOption = answerOption.filter((_, i) => i !== index);
|
||
setAnswerOption(newAnswerOption);
|
||
setSelectedAnswers(selectedAnswers.filter((i) => i !== index));
|
||
};
|
||
|
||
useEffect(() => {
|
||
setTextQuestion(valueQuestion);
|
||
}, [valueQuestion]);
|
||
|
||
const handleDeleteQuestion = () => {
|
||
onDeleteQuestion(indexQuestion);
|
||
};
|
||
|
||
const toggleSelect = (index: number) => {
|
||
if (selectedType === 'single') {
|
||
setSelectedAnswers([index]);
|
||
} else {
|
||
setSelectedAnswers((prev) => {
|
||
if (prev.includes(index)) {
|
||
return prev.filter((i) => i !== index);
|
||
} else {
|
||
return [...prev, index];
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className={styles.questionCard}>
|
||
<div className={styles.questionContainer}>
|
||
<div className={styles.question}>
|
||
{isEditingQuestion ? (
|
||
<textarea
|
||
className={styles.questionTextarea}
|
||
ref={textareaQuestionRef}
|
||
value={textQuestion === initialTextQuestion ? '' : textQuestion}
|
||
onChange={handleTextareaQuestionChange}
|
||
onKeyDown={handleQuestionKeyDown}
|
||
onBlur={handleQuestionBlur}
|
||
placeholder={initialTextQuestion}
|
||
rows={1}
|
||
/>
|
||
) : (
|
||
<button className={styles.buttonQuestion} onClick={handleQuestionClick}>
|
||
<h2 className={styles.textQuestion}>{textQuestion || initialTextQuestion}</h2>
|
||
</button>
|
||
)}
|
||
<TypeDropdown selectedType={selectedType} onTypeChange={handleTypeChange}/>
|
||
</div>
|
||
|
||
{answerOption.map((answerText, index) => (
|
||
<AnswerOption
|
||
key={index}
|
||
selectedType={selectedType}
|
||
index={index + 1}
|
||
value={answerText}
|
||
onChange={(value) => handleAnswerChange(index, value)}
|
||
onDelete={() => handleDeleteAnswer(index)}
|
||
isSelected={selectedAnswers.includes(index)}
|
||
toggleSelect={() => toggleSelect(index)}
|
||
/>
|
||
))}
|
||
|
||
<div className={styles.questionActions}>
|
||
<AddAnswerButton
|
||
onClick={handleAddAnswer}
|
||
/>
|
||
<button className={styles.deleteQuestionButton} onClick={handleDeleteQuestion}>
|
||
Удалить{/**/}
|
||
<img className={styles.basketImg} src='../../../public/deleteQuestion.svg' alt='deleteQuestion' />
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default QuestionItem; |