Esta aplicación web construida con React que permite a los usuarios diseñar un proyecto de creador de encuestas personalizadas, recopilar respuestas y generar estadísticas visuales de los resultados. Está orientado a investigadores, educadores o cualquier persona que necesite recopilar datos de forma estructurada.
Funcionalidades clave del creador de encuestas personalizadas:
– Creación de preguntas de tipo texto u opción múltiple.
– Interfaz limpia y adaptable (Tailwind CSS + shadcn/ui).
– Recopilación de respuestas.
– Visualización de estadísticas (gráficos con Recharts).
import React, { useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from "recharts";
export default function SurveyCreatorApp() {
const [questions, setQuestions] = useState([]);
const [questionText, setQuestionText] = useState("");
const [questionType, setQuestionType] = useState("text");
const [responses, setResponses] = useState([]);
const [showSurvey, setShowSurvey] = useState(false);
const [showResults, setShowResults] = useState(false);
const addQuestion = () => {
setQuestions([
...questions,
{ text: questionText, type: questionType, id: Date.now(), options: [], answers: [] },
]);
setQuestionText("");
setQuestionType("text");
};
const handleAnswer = (id, answer) => {
setResponses(prev => {
const updated = [...prev];
const qIndex = questions.findIndex(q => q.id === id);
if (!updated[qIndex]) updated[qIndex] = [];
updated[qIndex].push(answer);
return updated;
});
};
const generateReport = () => {
setShowResults(true);
};
return (
<div className="p-6 max-w-4xl mx-auto">
<h1 className="text-3xl font-bold mb-4">Creador de Encuestas Personalizadas</h1>
{!showSurvey && !showResults && (
<Card className="mb-4">
<CardContent className="space-y-4">
<Input
placeholder="Texto de la pregunta"
value={questionText}
onChange={(e) => setQuestionText(e.target.value)}
/>
<select
className="border p-2 rounded"
value={questionType}
onChange={(e) => setQuestionType(e.target.value)}
>
<option value="text">Respuesta de Texto</option>
<option value="multiple">Opción Múltiple</option>
</select>
<Button onClick={addQuestion}>Agregar Pregunta</Button>
<Button onClick={() => setShowSurvey(true)} variant="secondary">
Comenzar Encuesta
</Button>
</CardContent>
</Card>
)}
{showSurvey && !showResults && (
<Card className="mb-4">
<CardContent className="space-y-4">
{questions.map((q, index) => (
<div key={q.id} className="border p-4 rounded">
<p className="font-medium mb-2">{q.text}</p>
{q.type === "text" ? (
<Textarea
placeholder="Tu respuesta..."
onBlur={(e) => handleAnswer(q.id, e.target.value)}
/>
) : (
<div className="space-y-2">
{["Opción A", "Opción B", "Opción C"].map((opt, idx) => (
<label key={idx} className="block">
<input
type="radio"
name={`q-${index}`}
value={opt}
onChange={(e) => handleAnswer(q.id, e.target.value)}
/> {opt}
</label>
))}
</div>
)}
</div>
))}
<Button onClick={generateReport}>Finalizar y Ver Resultados</Button>
</CardContent>
</Card>
)}
{showResults && (
<div className="space-y-6">
<h2 className="text-2xl font-semibold">Resultados de la Encuesta</h2>
{questions.map((q, index) => (
<div key={q.id} className="bg-gray-100 p-4 rounded shadow">
<p className="font-bold mb-2">{q.text}</p>
{q.type === "text" ? (
<ul className="list-disc pl-6">
{(responses[index] || []).map((r, idx) => (
<li key={idx}>{r}</li>
))}
</ul>
) : (
<ResponsiveContainer width="100%" height={200}>
<BarChart
data={Object.entries(
(responses[index] || []).reduce((acc, val) => {
acc[val] = (acc[val] || 0) + 1;
return acc;
}, {})
).map(([name, value]) => ({ name, value }))}
>
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Bar dataKey="value" fill="#8884d8" />
</BarChart>
</ResponsiveContainer>
)}
</div>
))}
</div>
)}
</div>
);
}
Explicación línea por línea del creador de encuestas personalizadas
1. Importaciones y Setup
import React, { useState } from "react";
React y el hook useState
para manejar el estado interno de la app.
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
Importa componentes de UI desde la librería shadcn/ui
para un diseño moderno.
import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from "recharts";
Componentes de Recharts para crear gráficos de barras responsivos.
2. Componente Principal
export default function SurveyCreatorApp() {
Define el componente principal de la aplicación.
3. Estados (useState)
const [questions, setQuestions] = useState([]);
Guarda las preguntas creadas por el usuario.
const [questionText, setQuestionText] = useState("");
const [questionText, setQuestionText] = useState(«»);
const [questionType, setQuestionType] = useState("text");
Tipo de pregunta seleccionada: «text» o «multiple».
const [responses, setResponses] = useState([]);
Almacena las respuestas dadas por los usuarios.
const [showSurvey, setShowSurvey] = useState(false);
Controla si se debe mostrar el formulario de encuesta.
const [showResults, setShowResults] = useState(false);
Controla si se deben mostrar los resultados.
4. Agregar Pregunta
const addQuestion = () => {
setQuestions([
...questions,
{ text: questionText, type: questionType, id: Date.now(), options: [], answers: [] },
]);
setQuestionText("");
setQuestionType("text");
};
Función para agregar una nueva pregunta al arreglo questions
.
– Usa Date.now()
como ID único.
– Limpia el input después de agregar.
5. Guardar Respuesta
const handleAnswer = (id, answer) => {
setResponses(prev => {
const updated = [...prev];
const qIndex = questions.findIndex(q => q.id === id);
if (!updated[qIndex]) updated[qIndex] = [];
updated[qIndex].push(answer);
return updated;
});
};
Guarda las respuestas por pregunta:
– Encuentra el índice de la pregunta.
– Inserta la respuesta en la posición correspondiente del arreglo responses
.
6. Mostrar Resultados del creador de encuestas personalizadas
const generateReport = () => {
setShowResults(true);
};
Activa la visualización de resultados.
7. Render UI
return (
<div className="p-6 max-w-4xl mx-auto">
Crea un contenedor centrado con padding.
<h1 className="text-3xl font-bold mb-4">Creador de Encuestas Personalizadas</h1>
Título principal.
8. Formulario de Creación de Preguntas
{!showSurvey && !showResults && (
<Card className="mb-4">
...
Muestra el formulario solo si no está en modo encuesta ni resultados.
<Input ... /> // Campo para escribir la pregunta.
<select ...> // Selección del tipo de pregunta.
<Button onClick={addQuestion}>Agregar Pregunta</Button>
<Button onClick={() => setShowSurvey(true)} variant="secondary">
Comenzar Encuesta
</Button>
9. Formulario de Encuesta (responder)
{showSurvey && !showResults && (
<Card className="mb-4">
...
Renderiza la encuesta activa.
{questions.map((q, index) => (
<div key={q.id}>...</div>
))}
Itera sobre las preguntas.
Para preguntas de texto:
<Textarea onBlur={(e) => handleAnswer(q.id, e.target.value)} />
Para opción múltiple:
<input type=\"radio\" ... />
10. Resultados del creador de encuestas personalizadas
{showResults && (
<div className=\"space-y-6\">
Renderiza los resultados.
Para preguntas de texto:
<ul> <li>{respuesta}</li> </ul>
Para opción múltiple:
<ResponsiveContainer> <BarChart ... /> </ResponsiveContainer>
Grafica con Recharts los conteos de cada opción.