Files
motor-de-encuestas/components/question-renderer.tsx
markosbenitez 3ec5da0e54 feat(wizard): autocomplete barrios desde geo_paraguay_full.json [4F]
- BarrioAutocompleteField: carga JSON estático, filtra por depto/ciudad (2.1/2.2), mín 2 chars, máx 10 sugerencias, texto libre permitido, teclado (↑↓ Enter Escape), ARIA listbox
- QuestionRenderer: branch code === '2.3' → BarrioAutocompleteField; prop answers? pasado desde WizardForm para contexto depto/ciudad
- globals.css: clases .barrio-autocomplete-* (wrapper, list, item, item--active)
- Incluye public/data/geo_paraguay_full.json (202 KB, sin commitear hasta ahora)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 19:41:55 -03:00

116 lines
2.8 KiB
TypeScript

'use client'
import type { AnswerValue, FormAnswers, Question, QuestionOption } from '@/lib/form-engine.types'
import { RadioGroup } from './widgets/radio-group'
import { CheckboxGroup } from './widgets/checkbox-group'
import { TextAreaField } from './widgets/text-area-field'
import { TextShortField } from './widgets/text-short-field'
import { BarrioAutocompleteField } from './widgets/barrio-autocomplete-field'
interface QuestionRendererProps {
question: Question
value: AnswerValue
onChange: (value: AnswerValue) => void
error?: string
answers?: FormAnswers
}
const YES_NO_OPTIONS: QuestionOption[] = [
{ value: 'true', label: 'Sí' },
{ value: 'false', label: 'No' },
]
export function QuestionRenderer({ question, value, onChange, error, answers }: QuestionRendererProps) {
const { code, type, prompt, required, max_select, options } = question
const legend = (
<>
<span className="q-code">{code} ·</span> {prompt}
</>
)
if (type === 'single_choice' && options) {
return (
<RadioGroup
name={code}
legend={legend}
options={options}
value={(value as string) ?? undefined}
required={required}
onChange={onChange}
error={error}
/>
)
}
if (type === 'multiple_choice' && options) {
return (
<CheckboxGroup
name={code}
legend={legend}
options={options}
value={(value as string[]) ?? []}
maxSelect={max_select}
required={required}
onChange={onChange}
error={error}
/>
)
}
// yes_no resuelto con el RadioGroup existente — dos opciones fijas, sin widget nuevo.
if (type === 'yes_no') {
return (
<RadioGroup
name={code}
legend={legend}
options={YES_NO_OPTIONS}
value={(value as string) ?? undefined}
required={required}
onChange={onChange}
error={error}
/>
)
}
if (type === 'text_short') {
if (code === '2.3') {
return (
<BarrioAutocompleteField
name={code}
label={legend}
value={(value as string) ?? ''}
required={required}
departamento={(answers?.['2.1:default'] as string) ?? null}
ciudad={(answers?.['2.2:default'] as string) ?? null}
onChange={onChange}
error={error}
/>
)
}
return (
<TextShortField
name={code}
label={legend}
value={(value as string) ?? ''}
required={required}
onChange={onChange}
error={error}
/>
)
}
if (type === 'text_long') {
return (
<TextAreaField
name={code}
label={legend}
value={(value as string) ?? ''}
required={required}
onChange={onChange}
error={error}
/>
)
}
return null
}