Con los números de preguntas y secciones
This commit is contained in:
@@ -32,6 +32,7 @@ export function QuestionRenderer({
|
||||
const error = errors[code]
|
||||
|
||||
// A1 (Departamento) renders a combined geo widget that also handles A2 (Ciudad)
|
||||
// Code badges for A1/A2 are rendered inside GeoSelectWidget.
|
||||
if (code === 'A1') {
|
||||
return (
|
||||
<GeoSelectWidget
|
||||
@@ -47,11 +48,13 @@ export function QuestionRenderer({
|
||||
// A2 is rendered inside the GeoSelectWidget above — skip here to avoid duplication
|
||||
if (code === 'A2') return null
|
||||
|
||||
const legend = <><span className="q-code">{code} ·</span> {prompt}</>
|
||||
|
||||
if (type === 'single_choice' && isArrayOptions(options)) {
|
||||
return (
|
||||
<RadioGroup
|
||||
name={code}
|
||||
legend={prompt}
|
||||
legend={legend}
|
||||
options={options}
|
||||
value={answers[code] as string | undefined}
|
||||
required={required}
|
||||
@@ -65,7 +68,7 @@ export function QuestionRenderer({
|
||||
return (
|
||||
<CheckboxGroup
|
||||
name={code}
|
||||
legend={prompt}
|
||||
legend={legend}
|
||||
options={options}
|
||||
value={(answers[code] as string[]) ?? []}
|
||||
maxSelect={max_select}
|
||||
@@ -80,7 +83,7 @@ export function QuestionRenderer({
|
||||
return (
|
||||
<RatingScale
|
||||
name={code}
|
||||
legend={prompt}
|
||||
legend={legend}
|
||||
ratingOptions={options}
|
||||
value={answers[code] as number | undefined}
|
||||
required={required}
|
||||
@@ -94,7 +97,7 @@ export function QuestionRenderer({
|
||||
return (
|
||||
<TextShortField
|
||||
name={code}
|
||||
label={prompt}
|
||||
label={legend}
|
||||
value={(answers[code] as string) ?? ''}
|
||||
required={required}
|
||||
onChange={(v) => onChange(code, v)}
|
||||
@@ -107,7 +110,7 @@ export function QuestionRenderer({
|
||||
return (
|
||||
<TextAreaField
|
||||
name={code}
|
||||
label={prompt}
|
||||
label={legend}
|
||||
value={(answers[code] as string) ?? ''}
|
||||
required={required}
|
||||
onChange={(v) => onChange(code, v)}
|
||||
|
||||
@@ -9,9 +9,9 @@ import { ProgressBar } from './progress-bar'
|
||||
import { QuestionRenderer } from './question-renderer'
|
||||
|
||||
// Section metadata (code prefix → display title)
|
||||
const SECTIONS: { prefix: string; title: string; sensitive?: boolean }[] = [
|
||||
const SECTIONS: { prefix: string; title: string }[] = [
|
||||
{ prefix: 'A', title: 'Datos Generales' },
|
||||
{ prefix: '1', title: 'Prevalencia: cuidado y discapacidad', sensitive: true },
|
||||
{ prefix: '1', title: 'Prevalencia: cuidado y discapacidad' },
|
||||
{ prefix: '2', title: 'Intensidad y rol del cuidado' },
|
||||
{ prefix: '3', title: 'Impacto económico del cuidado' },
|
||||
{ prefix: '4', title: 'Tiempo y descanso' },
|
||||
@@ -190,13 +190,13 @@ export function SurveyForm({ survey, questions }: SurveyFormProps) {
|
||||
return v !== null && v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0)
|
||||
}).length
|
||||
|
||||
type Section = { prefix: string; title: string; sensitive?: boolean; questions: Question[] }
|
||||
type Section = { prefix: string; title: string; questions: Question[] }
|
||||
const sectionMap = new Map<string, Section>()
|
||||
for (const q of visibleQuestions) {
|
||||
const prefix = getSectionPrefix(q.code)
|
||||
if (!sectionMap.has(prefix)) {
|
||||
const meta = SECTIONS.find((s) => s.prefix === prefix)
|
||||
sectionMap.set(prefix, { prefix, title: meta?.title ?? prefix, sensitive: meta?.sensitive, questions: [] })
|
||||
sectionMap.set(prefix, { prefix, title: meta?.title ?? prefix, questions: [] })
|
||||
}
|
||||
sectionMap.get(prefix)!.questions.push(q)
|
||||
}
|
||||
@@ -242,13 +242,7 @@ export function SurveyForm({ survey, questions }: SurveyFormProps) {
|
||||
aria-labelledby={`section-${section.prefix}`}
|
||||
>
|
||||
<div className="section-header">
|
||||
<h2 id={`section-${section.prefix}`} className="section-title">{section.title}</h2>
|
||||
{section.sensitive && (
|
||||
<p className="section-sensitive-note" role="note">
|
||||
Esta sección contiene preguntas sensibles sobre salud o discapacidad.
|
||||
Responder es completamente voluntario.
|
||||
</p>
|
||||
)}
|
||||
<h2 id={`section-${section.prefix}`} className="section-title">Sección {section.prefix} · {section.title}</h2>
|
||||
</div>
|
||||
{section.questions.map((q) => (
|
||||
<div key={q.id} className="question-wrapper" data-code={q.code}>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
'use client'
|
||||
import type { ReactNode } from 'react'
|
||||
import type { QuestionOption } from '@/lib/types'
|
||||
|
||||
interface CheckboxGroupProps {
|
||||
name: string
|
||||
legend: string
|
||||
legend: ReactNode
|
||||
options: QuestionOption[]
|
||||
value: string[]
|
||||
maxSelect: number | null
|
||||
|
||||
@@ -31,7 +31,7 @@ export function GeoSelectWidget({
|
||||
{/* Departamento */}
|
||||
<div className="geo-select-group">
|
||||
<label className="question-legend" htmlFor="A1">
|
||||
Departamento
|
||||
<span className="q-code">A1 ·</span> Departamento
|
||||
</label>
|
||||
<select
|
||||
id="A1"
|
||||
@@ -58,7 +58,7 @@ export function GeoSelectWidget({
|
||||
className={`question-legend${cityDisabled ? ' geo-label-disabled' : ''}`}
|
||||
htmlFor="A2"
|
||||
>
|
||||
Ciudad
|
||||
<span className="q-code">A2 ·</span> Ciudad
|
||||
{cityDisabled && (
|
||||
<span className="geo-disabled-hint"> (seleccioná un departamento primero)</span>
|
||||
)}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
'use client'
|
||||
import type { ReactNode } from 'react'
|
||||
import type { QuestionOption } from '@/lib/types'
|
||||
|
||||
interface RadioGroupProps {
|
||||
name: string
|
||||
legend: string
|
||||
legend: ReactNode
|
||||
options: QuestionOption[]
|
||||
value: string | undefined
|
||||
required: boolean
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
'use client'
|
||||
import type { ReactNode } from 'react'
|
||||
import type { RatingOptions } from '@/lib/types'
|
||||
|
||||
interface RatingScaleProps {
|
||||
name: string
|
||||
legend: string
|
||||
legend: ReactNode
|
||||
ratingOptions: RatingOptions
|
||||
value: number | undefined
|
||||
required: boolean
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use client'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
interface TextAreaFieldProps {
|
||||
name: string
|
||||
label: string
|
||||
label: ReactNode
|
||||
value: string
|
||||
required: boolean
|
||||
onChange: (value: string) => void
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use client'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
interface TextShortFieldProps {
|
||||
name: string
|
||||
label: string
|
||||
label: ReactNode
|
||||
value: string
|
||||
required: boolean
|
||||
placeholder?: string
|
||||
|
||||
Reference in New Issue
Block a user