[#104] Create/Updatehttps://project.mdnd-it.cc/work_packages/104
This commit is contained in:
@@ -0,0 +1,500 @@
|
||||
// src/components/DeckCreator/TaskCardEditor.jsx
|
||||
// Feladat kártya szerkesztő (Quiz, Igaz/Hamis, Párosítás, Szöveges)
|
||||
|
||||
import React from "react"
|
||||
import { FaPlus, FaTrash, FaCheck, FaTimes } from "react-icons/fa"
|
||||
|
||||
const taskSubTypes = [
|
||||
{ value: 'quiz', label: '📋 Quiz (A/B/C/D)', description: 'Feleletválasztós kérdés' },
|
||||
{ value: 'truefalse', label: '✅ Igaz/Hamis', description: 'Igaz vagy hamis állítás' },
|
||||
{ value: 'matching', label: '🔗 Párosítás', description: 'Elemek összekapcsolása' },
|
||||
{ value: 'text', label: '✏️ Szöveges válasz', description: 'Szabadszöveges válasz' }
|
||||
]
|
||||
|
||||
const timeLimits = [
|
||||
{ value: 15, label: '15 másodperc' },
|
||||
{ value: 30, label: '30 másodperc' },
|
||||
{ value: 45, label: '45 másodperc' },
|
||||
{ value: 60, label: '1 perc' },
|
||||
{ value: 90, label: '1.5 perc' },
|
||||
{ value: 120, label: '2 perc' }
|
||||
]
|
||||
|
||||
export default function TaskCardEditor({ card, onChange }) {
|
||||
|
||||
const updateField = (field, value) => {
|
||||
onChange({ [field]: value })
|
||||
}
|
||||
|
||||
const updateOption = (index, value) => {
|
||||
const newOptions = [...card.options]
|
||||
newOptions[index] = value
|
||||
onChange({ options: newOptions })
|
||||
}
|
||||
|
||||
const addMatchingPair = () => {
|
||||
const newLeft = [...(card.leftItems || []), '']
|
||||
const newRight = [...(card.rightItems || []), '']
|
||||
const newCorrectPairs = { ...(card.correctPairs || {}), [newLeft.length - 1]: newRight.length - 1 }
|
||||
|
||||
onChange({
|
||||
leftItems: newLeft,
|
||||
rightItems: newRight,
|
||||
correctPairs: newCorrectPairs
|
||||
})
|
||||
}
|
||||
|
||||
const removeMatchingPair = (index) => {
|
||||
const newLeft = card.leftItems.filter((_, i) => i !== index)
|
||||
const newRight = card.rightItems.filter((_, i) => i !== index)
|
||||
const newCorrectPairs = {}
|
||||
|
||||
// Újraszámozás
|
||||
Object.entries(card.correctPairs).forEach(([leftIdx, rightIdx]) => {
|
||||
const newLeftIdx = parseInt(leftIdx) > index ? parseInt(leftIdx) - 1 : parseInt(leftIdx)
|
||||
const newRightIdx = parseInt(rightIdx) > index ? parseInt(rightIdx) - 1 : parseInt(rightIdx)
|
||||
if (newLeftIdx !== index && newRightIdx !== index) {
|
||||
newCorrectPairs[newLeftIdx] = newRightIdx
|
||||
}
|
||||
})
|
||||
|
||||
onChange({
|
||||
leftItems: newLeft,
|
||||
rightItems: newRight,
|
||||
correctPairs: newCorrectPairs
|
||||
})
|
||||
}
|
||||
|
||||
const addAcceptedAnswer = () => {
|
||||
const newAnswers = [...(card.acceptedAnswers || []), '']
|
||||
onChange({ acceptedAnswers: newAnswers })
|
||||
}
|
||||
|
||||
const updateAcceptedAnswer = (index, value) => {
|
||||
const newAnswers = [...card.acceptedAnswers]
|
||||
newAnswers[index] = value
|
||||
onChange({ acceptedAnswers: newAnswers })
|
||||
}
|
||||
|
||||
const removeAcceptedAnswer = (index) => {
|
||||
const newAnswers = card.acceptedAnswers.filter((_, i) => i !== index)
|
||||
onChange({ acceptedAnswers: newAnswers })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto space-y-6">
|
||||
{/* Feladat típus választó */}
|
||||
<div className="bg-[color:var(--color-surface)] rounded-xl p-6">
|
||||
<h3 className="text-lg font-semibold text-[color:var(--color-text)] mb-4">
|
||||
🎯 Feladat típusa
|
||||
</h3>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
{taskSubTypes.map(type => (
|
||||
<button
|
||||
key={type.value}
|
||||
onClick={() => updateField('subType', type.value)}
|
||||
className={`
|
||||
p-4 rounded-xl border text-left transition-all duration-200 hover:scale-105
|
||||
${card.subType === type.value
|
||||
? 'bg-[color:var(--color-success)]/10 border-[color:var(--color-success)] shadow-lg'
|
||||
: 'bg-[color:var(--color-background)] border-[color:var(--color-surface-selected)] hover:bg-[color:var(--color-surface-selected)]'
|
||||
}
|
||||
`}
|
||||
>
|
||||
<div className="font-semibold text-[color:var(--color-text)]">
|
||||
{type.label}
|
||||
</div>
|
||||
<div className="text-sm text-[color:var(--color-text-muted)] mt-1">
|
||||
{type.description}
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quiz típus szerkesztő */}
|
||||
{card.subType === 'quiz' && (
|
||||
<div className="bg-[color:var(--color-surface)] rounded-xl p-6">
|
||||
<h3 className="text-lg font-semibold text-[color:var(--color-text)] mb-4">
|
||||
📋 Quiz kérdés
|
||||
</h3>
|
||||
|
||||
{/* Kérdés */}
|
||||
<div className="mb-6">
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
|
||||
Kérdés
|
||||
</label>
|
||||
<textarea
|
||||
value={card.question || ''}
|
||||
onChange={(e) => updateField('question', e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200 resize-none"
|
||||
rows="3"
|
||||
placeholder="Írd be a kérdést..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Válaszlehetőségek */}
|
||||
<div className="space-y-3">
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium">
|
||||
Válaszlehetőségek
|
||||
</label>
|
||||
|
||||
{['A', 'B', 'C', 'D'].map((letter, index) => (
|
||||
<div key={index} className="flex items-center gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => updateField('correctAnswer', index)}
|
||||
className={`
|
||||
w-8 h-8 rounded-full flex items-center justify-center font-bold text-sm transition-all duration-200
|
||||
${card.correctAnswer === index
|
||||
? 'bg-[color:var(--color-success)] text-[color:var(--color-text-inverse)]'
|
||||
: 'bg-[color:var(--color-background)] text-[color:var(--color-text)] border border-[color:var(--color-surface-selected)]'
|
||||
}
|
||||
`}
|
||||
>
|
||||
{letter}
|
||||
</button>
|
||||
|
||||
{card.correctAnswer === index && (
|
||||
<FaCheck className="text-[color:var(--color-success)] text-sm" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
value={card.options?.[index] || ''}
|
||||
onChange={(e) => updateOption(index, e.target.value)}
|
||||
className="flex-1 px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200"
|
||||
placeholder={`${letter} válasz...`}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Igaz/Hamis típus szerkesztő */}
|
||||
{card.subType === 'truefalse' && (
|
||||
<div className="bg-[color:var(--color-surface)] rounded-xl p-6">
|
||||
<h3 className="text-lg font-semibold text-[color:var(--color-text)] mb-4">
|
||||
✅ Igaz/Hamis állítás
|
||||
</h3>
|
||||
|
||||
{/* Állítás */}
|
||||
<div className="mb-6">
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
|
||||
Állítás
|
||||
</label>
|
||||
<textarea
|
||||
value={card.statement || ''}
|
||||
onChange={(e) => updateField('statement', e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200 resize-none"
|
||||
rows="3"
|
||||
placeholder="Írd be az állítást..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Helyes válasz */}
|
||||
<div>
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-3">
|
||||
Helyes válasz
|
||||
</label>
|
||||
|
||||
<div className="flex gap-4">
|
||||
<button
|
||||
onClick={() => updateField('isTrue', true)}
|
||||
className={`
|
||||
flex items-center gap-3 px-6 py-3 rounded-xl font-medium transition-all duration-200 hover:scale-105
|
||||
${card.isTrue === true
|
||||
? 'bg-[color:var(--color-success)] text-[color:var(--color-text-inverse)] shadow-lg'
|
||||
: 'bg-[color:var(--color-background)] text-[color:var(--color-text)] border border-[color:var(--color-surface-selected)]'
|
||||
}
|
||||
`}
|
||||
>
|
||||
<FaCheck />
|
||||
✅ IGAZ
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => updateField('isTrue', false)}
|
||||
className={`
|
||||
flex items-center gap-3 px-6 py-3 rounded-xl font-medium transition-all duration-200 hover:scale-105
|
||||
${card.isTrue === false
|
||||
? 'bg-[color:var(--color-error)] text-[color:var(--color-text-inverse)] shadow-lg'
|
||||
: 'bg-[color:var(--color-background)] text-[color:var(--color-text)] border border-[color:var(--color-surface-selected)]'
|
||||
}
|
||||
`}
|
||||
>
|
||||
<FaTimes />
|
||||
❌ HAMIS
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Párosítás típus szerkesztő */}
|
||||
{card.subType === 'matching' && (
|
||||
<div className="bg-[color:var(--color-surface)] rounded-xl p-6">
|
||||
<h3 className="text-lg font-semibold text-[color:var(--color-text)] mb-4">
|
||||
🔗 Párosítás feladat
|
||||
</h3>
|
||||
|
||||
{/* Feladat leírás */}
|
||||
<div className="mb-6">
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
|
||||
Feladat leírása
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={card.taskDescription || ''}
|
||||
onChange={(e) => updateField('taskDescription', e.target.value)}
|
||||
className="w-full px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200"
|
||||
placeholder="Pl.: Párosítsd a országokat a fővárosukkal"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Párosítások */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<label className="text-[color:var(--color-text-muted)] text-sm font-medium">
|
||||
Párosítások
|
||||
</label>
|
||||
<button
|
||||
onClick={addMatchingPair}
|
||||
className="flex items-center gap-2 px-3 py-1 rounded-lg bg-[color:var(--color-success)] text-[color:var(--color-text-inverse)] text-sm font-medium hover:bg-[color:var(--color-success)]/80 transition-all duration-200"
|
||||
>
|
||||
<FaPlus />
|
||||
Új pár
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{(card.leftItems || []).map((leftItem, index) => (
|
||||
<div key={index} className="grid grid-cols-5 gap-3 items-center">
|
||||
<input
|
||||
type="text"
|
||||
value={leftItem}
|
||||
onChange={(e) => {
|
||||
const newLeft = [...card.leftItems]
|
||||
newLeft[index] = e.target.value
|
||||
onChange({ leftItems: newLeft })
|
||||
}}
|
||||
className="col-span-2 px-3 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200 text-sm"
|
||||
placeholder="Bal oldal..."
|
||||
/>
|
||||
|
||||
<div className="text-center text-[color:var(--color-text-muted)]">↔</div>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
value={card.rightItems?.[index] || ''}
|
||||
onChange={(e) => {
|
||||
const newRight = [...(card.rightItems || [])]
|
||||
newRight[index] = e.target.value
|
||||
onChange({ rightItems: newRight })
|
||||
}}
|
||||
className="px-3 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200 text-sm"
|
||||
placeholder="Jobb oldal..."
|
||||
/>
|
||||
|
||||
<button
|
||||
onClick={() => removeMatchingPair(index)}
|
||||
className="p-2 rounded-lg bg-[color:var(--color-error)]/10 text-[color:var(--color-error)] hover:bg-[color:var(--color-error)]/20 transition-all duration-200"
|
||||
>
|
||||
<FaTrash className="text-xs" />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Szöveges válasz típus szerkesztő */}
|
||||
{card.subType === 'text' && (
|
||||
<div className="bg-[color:var(--color-surface)] rounded-xl p-6">
|
||||
<h3 className="text-lg font-semibold text-[color:var(--color-text)] mb-4">
|
||||
✏️ Szöveges válasz
|
||||
</h3>
|
||||
|
||||
{/* Kérdés */}
|
||||
<div className="mb-6">
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
|
||||
Kérdés
|
||||
</label>
|
||||
<textarea
|
||||
value={card.question || ''}
|
||||
onChange={(e) => updateField('question', e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200 resize-none"
|
||||
rows="3"
|
||||
placeholder="Írd be a kérdést..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Elfogadott válaszok */}
|
||||
<div className="mb-6">
|
||||
<div className="flex justify-between items-center mb-3">
|
||||
<label className="text-[color:var(--color-text-muted)] text-sm font-medium">
|
||||
Elfogadott válaszok
|
||||
</label>
|
||||
<button
|
||||
onClick={addAcceptedAnswer}
|
||||
className="flex items-center gap-2 px-3 py-1 rounded-lg bg-[color:var(--color-success)] text-[color:var(--color-text-inverse)] text-sm font-medium hover:bg-[color:var(--color-success)]/80 transition-all duration-200"
|
||||
>
|
||||
<FaPlus />
|
||||
Új válasz
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
{(card.acceptedAnswers || ['', '', '']).map((answer, index) => (
|
||||
<div key={index} className="flex gap-2">
|
||||
<input
|
||||
type="text"
|
||||
value={answer}
|
||||
onChange={(e) => updateAcceptedAnswer(index, e.target.value)}
|
||||
className="flex-1 px-3 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200 text-sm"
|
||||
placeholder={`Elfogadott válasz ${index + 1}...`}
|
||||
/>
|
||||
|
||||
{(card.acceptedAnswers?.length || 0) > 1 && (
|
||||
<button
|
||||
onClick={() => removeAcceptedAnswer(index)}
|
||||
className="p-2 rounded-lg bg-[color:var(--color-error)]/10 text-[color:var(--color-error)] hover:bg-[color:var(--color-error)]/20 transition-all duration-200"
|
||||
>
|
||||
<FaTrash className="text-xs" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="text-xs text-[color:var(--color-text-muted)] mt-2">
|
||||
Vesszővel elválasztva is megadhatsz több elfogadott választ egy mezőben
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Beállítások */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<label className="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={card.caseSensitive || false}
|
||||
onChange={(e) => updateField('caseSensitive', e.target.checked)}
|
||||
className="w-4 h-4 text-[color:var(--color-success)] border-[color:var(--color-surface-selected)] rounded focus:ring-[color:var(--color-success)]"
|
||||
/>
|
||||
<span className="text-[color:var(--color-text)]">Kis/nagy betű érzékeny</span>
|
||||
</label>
|
||||
|
||||
<label className="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={card.exactMatch || false}
|
||||
onChange={(e) => updateField('exactMatch', e.target.checked)}
|
||||
className="w-4 h-4 text-[color:var(--color-success)] border-[color:var(--color-surface-selected)] rounded focus:ring-[color:var(--color-success)]"
|
||||
/>
|
||||
<span className="text-[color:var(--color-text)]">Pontos egyezés</span>
|
||||
</label>
|
||||
|
||||
<label className="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={card.partialAccepted || true}
|
||||
onChange={(e) => updateField('partialAccepted', e.target.checked)}
|
||||
className="w-4 h-4 text-[color:var(--color-success)] border-[color:var(--color-surface-selected)] rounded focus:ring-[color:var(--color-success)]"
|
||||
/>
|
||||
<span className="text-[color:var(--color-text)]">Részleges elfogadás</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Tipp */}
|
||||
<div className="mt-4">
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
|
||||
Tipp (opcionális)
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={card.hint || ''}
|
||||
onChange={(e) => updateField('hint', e.target.value)}
|
||||
className="w-full px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200"
|
||||
placeholder="Segítő tipp a játékosoknak..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Közös beállítások */}
|
||||
<div className="bg-[color:var(--color-surface)] rounded-xl p-6">
|
||||
<h3 className="text-lg font-semibold text-[color:var(--color-text)] mb-4">
|
||||
⚙️ Beállítások
|
||||
</h3>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{/* Pontszám */}
|
||||
<div>
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
|
||||
💰 Pontszám
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
value={card.points || 10}
|
||||
onChange={(e) => updateField('points', parseInt(e.target.value) || 0)}
|
||||
className="w-full px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200"
|
||||
min="0"
|
||||
max="1000"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Időlimit */}
|
||||
<div>
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
|
||||
⏱️ Időlimit
|
||||
</label>
|
||||
<select
|
||||
value={card.timeLimit || 30}
|
||||
onChange={(e) => updateField('timeLimit', parseInt(e.target.value))}
|
||||
className="w-full px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200"
|
||||
>
|
||||
{timeLimits.map(time => (
|
||||
<option key={time.value} value={time.value}>
|
||||
{time.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Karakterlimit (csak szöveges válasznál) */}
|
||||
{card.subType === 'text' && (
|
||||
<div>
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
|
||||
📝 Karakterlimit
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
value={card.characterLimit || 100}
|
||||
onChange={(e) => updateField('characterLimit', parseInt(e.target.value) || 0)}
|
||||
className="w-full px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200"
|
||||
min="10"
|
||||
max="500"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Magyarázat */}
|
||||
<div className="mt-6">
|
||||
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
|
||||
💡 Magyarázat (opcionális)
|
||||
</label>
|
||||
<textarea
|
||||
value={card.explanation || ''}
|
||||
onChange={(e) => updateField('explanation', e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200 resize-none"
|
||||
rows="3"
|
||||
placeholder="Magyarázat a helyes válaszhoz..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user