Terminado sprint 2A
This commit is contained in:
110
components/summary-screen.tsx
Normal file
110
components/summary-screen.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
'use client'
|
||||
import type { FormAnswers, Question, QuestionOption, RatingOptions } from '@/lib/types'
|
||||
import { isQuestionVisible } from '@/lib/conditional'
|
||||
|
||||
interface SummaryScreenProps {
|
||||
surveyTitle: string
|
||||
questions: Question[]
|
||||
answers: FormAnswers
|
||||
onStartOver: () => void
|
||||
}
|
||||
|
||||
function formatAnswer(question: Question, raw: FormAnswers[string]): string {
|
||||
if (raw === null || raw === undefined || raw === '') return '—'
|
||||
|
||||
const { type, options } = question
|
||||
|
||||
if ((type === 'single_choice') && Array.isArray(options)) {
|
||||
const opt = (options as QuestionOption[]).find((o) => o.value === raw)
|
||||
return opt?.label ?? String(raw)
|
||||
}
|
||||
|
||||
if (type === 'multiple_choice' && Array.isArray(raw) && Array.isArray(options)) {
|
||||
const opts = options as QuestionOption[]
|
||||
const labels = (raw as string[]).map(
|
||||
(v) => opts.find((o) => o.value === v)?.label ?? v
|
||||
)
|
||||
return labels.length > 0 ? labels.join(', ') : '—'
|
||||
}
|
||||
|
||||
if (type === 'rating' && options && !Array.isArray(options)) {
|
||||
const ro = options as RatingOptions
|
||||
return `${raw} / ${ro.max} (${ro.min_label} → ${ro.max_label})`
|
||||
}
|
||||
|
||||
return String(raw)
|
||||
}
|
||||
|
||||
// Section titles by first question code prefix
|
||||
const SECTION_TITLES: Record<string, string> = {
|
||||
A: 'Datos Generales',
|
||||
B: '¿Vivís con discapacidad?',
|
||||
C: 'Familiares con Discapacidad',
|
||||
D: 'Adultos Mayores a Cargo',
|
||||
E: 'Tu Rol como Cuidador/a',
|
||||
F: 'Impacto Económico',
|
||||
G: 'Bienestar y Descanso',
|
||||
H: 'Necesidades',
|
||||
}
|
||||
|
||||
export function SummaryScreen({
|
||||
surveyTitle,
|
||||
questions,
|
||||
answers,
|
||||
onStartOver,
|
||||
}: SummaryScreenProps) {
|
||||
const visibleQuestions = questions.filter((q) => isQuestionVisible(q, answers))
|
||||
|
||||
let lastSection = ''
|
||||
|
||||
return (
|
||||
<div className="summary-container" role="main">
|
||||
<div className="summary-header">
|
||||
<h1 className="summary-title">Resumen de tus respuestas</h1>
|
||||
<p className="summary-subtitle">
|
||||
{surveyTitle} — revisá lo que respondiste antes de continuar al envío.
|
||||
</p>
|
||||
<p className="summary-note" role="note">
|
||||
<strong>Nota:</strong> en esta etapa no se envía nada a la base de datos.
|
||||
El envío definitivo (con consentimiento) será en el paso siguiente.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<dl className="summary-list">
|
||||
{visibleQuestions.map((q) => {
|
||||
const section = q.code.replace(/\d+$/, '')
|
||||
const showHeader = section !== lastSection
|
||||
lastSection = section
|
||||
|
||||
return (
|
||||
<div key={q.id}>
|
||||
{showHeader && (
|
||||
<h2 className="summary-section-heading">
|
||||
{SECTION_TITLES[section] ?? section}
|
||||
</h2>
|
||||
)}
|
||||
<div className="summary-item">
|
||||
<dt className="summary-question">
|
||||
<span className="summary-code">{q.code}</span> {q.prompt}
|
||||
</dt>
|
||||
<dd className="summary-answer">
|
||||
{formatAnswer(q, answers[q.code] ?? null)}
|
||||
</dd>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</dl>
|
||||
|
||||
<div className="summary-actions">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onStartOver}
|
||||
className="btn btn-secondary"
|
||||
>
|
||||
Volver a la encuesta
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user