import React from 'react'
/**
* Renderizador Dinámico de Campos de Respuesta
* Renderiza el input apropiado según la configuración de la pregunta
*/
export function QuestionAnswerInput({ question, value, onChange, onSave }) {
const config = question.options || {}
const questionType = config.type || question.type
// BOOLEAN (2 opciones)
if (questionType === 'boolean' && config.choices?.length === 2) {
const [choice1, choice2] = config.choices
return (
{
onChange(e.target.value)
onSave?.()
}}
className="mr-3"
/>
{choice1.status === 'ok' ? '✓' : '✗'} {choice1.label}
{
onChange(e.target.value)
onSave?.()
}}
className="mr-3"
/>
{choice2.status === 'ok' ? '✓' : '✗'} {choice2.label}
)
}
// SINGLE CHOICE (selección única)
if (questionType === 'single_choice' && config.choices) {
return (
)
}
// MULTIPLE CHOICE (selección múltiple)
if (questionType === 'multiple_choice' && config.choices) {
const selectedValues = value ? (Array.isArray(value) ? value : value.split(',')) : []
const handleToggle = (choiceValue) => {
let newValues
if (selectedValues.includes(choiceValue)) {
newValues = selectedValues.filter(v => v !== choiceValue)
} else {
newValues = [...selectedValues, choiceValue]
}
onChange(newValues.join(','))
onSave?.()
}
return (
{config.choices.map((choice, idx) => (
handleToggle(choice.value)}
className="mr-3 w-4 h-4"
/>
{choice.label}
{choice.points > 0 && (
+{choice.points} pts
)}
))}
)
}
// SCALE (escala numérica)
if (questionType === 'scale') {
const min = config.min || 1
const max = config.max || 5
const step = config.step || 1
const labels = config.labels || {}
const options = []
for (let i = min; i <= max; i += step) {
options.push(i)
}
return (
{labels.min && {labels.min} }
{labels.max && {labels.max} }
{options.map(num => (
{
onChange(String(num))
onSave?.()
}}
className={`w-12 h-12 rounded-full font-bold transition ${
value === String(num)
? 'bg-blue-600 text-white scale-110'
: 'bg-gray-200 text-gray-700 hover:bg-gray-300'
}`}
>
{num}
))}
{value && (
Seleccionado:
{value}
/ {max}
)}
)
}
// TEXT (texto libre)
if (questionType === 'text') {
const multiline = config.multiline !== false
const maxLength = config.max_length || 500
if (multiline) {
return (
)
} else {
return (
onChange(e.target.value)}
onBlur={onSave}
maxLength={maxLength}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
placeholder="Ingrese su respuesta..."
/>
)
}
}
// NUMBER (valor numérico)
if (questionType === 'number') {
const min = config.min ?? 0
const max = config.max ?? 100
const unit = config.unit || ''
return (
onChange(e.target.value)}
onBlur={onSave}
min={min}
max={max}
step="any"
className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
placeholder={`${min} - ${max}`}
/>
{unit && {unit} }
)
}
// DATE (fecha)
if (questionType === 'date') {
return (
{
onChange(e.target.value)
onSave?.()
}}
min={config.min_date}
max={config.max_date}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
/>
)
}
// TIME (hora)
if (questionType === 'time') {
return (
{
onChange(e.target.value)
onSave?.()
}}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
/>
)
}
// PHOTO_ONLY (solo foto, sin campo de respuesta)
if (questionType === 'photo_only') {
return (
📸 Esta pregunta solo requiere fotografías. Adjunta las imágenes en la sección de fotos abajo.
)
}
// AI_ASSISTANT (Chat con asistente) - No requiere UI aquí, el botón está en App.jsx
if (questionType === 'ai_assistant') {
return null
}
// Fallback para tipos desconocidos
return (
)
}
export default QuestionAnswerInput