-
- {/* Progreso de preguntas */}
-
- {Array.from({ length: MAX_PREGUNTAS }).map((_, i) => (
+ {/* ─── Contenedor rojo con imagen + nombre de categoría (top-right) ─── */}
+ {categoria && (
+
+ {/* Círculo blanco con imagen de categoría */}
+ {CAT_IMG[categoria.nombre] && (
- ))}
+ className="rounded-full flex items-center justify-center shrink-0"
+ style={{
+ width: '52px',
+ height: '52px',
+ backgroundColor: '#FFFFFF',
+ boxShadow: '0 2px 8px rgba(0,0,0,0.2)',
+ }}
+ >
+

+
+ )}
+
+ {categoria.nombre}
+
+
+ )}
+
+ {/* ─── Contenido principal: Ruleta + Panel de pregunta ─── */}
+
+
+ {/* ─── Columna izquierda: Ruleta 40% ─── */}
+
+
- {/* Ruleta SVG */}
-
+ {/* ─── Columna derecha: Panel de pregunta 60% ─── */}
+
+ {pregunta && !estado.completado && (
+
+ {/* Header con pregunta (fondo transparente) */}
+
+
+ {/* Opciones */}
+
+ {pregunta.opciones.map((opcion, i) => (
+
+ ))}
+
+
+ )}
+
+ {/* Temporizador debajo del panel */}
+ {pregunta && !estado.completado && (
+
+
+ {estado.tiempoRestante}seg
+
+
+ )}
+
+ {/* Sin pregunta activa: placeholder */}
+ {!pregunta && !estado.completado && (
+
+
+ Gira la ruleta para obtener una pregunta
+
+
+ Cada respuesta correcta te acerca al objetivo de {MAX_PREGUNTAS} preguntas
+
+
+ )}
+
- {/* Modal pregunta */}
- {estado.preguntaActual && !estado.completado && (
-
)}
diff --git a/src/components/screens/Intro.tsx b/src/components/screens/Intro.tsx
new file mode 100644
index 0000000..d5e2569
--- /dev/null
+++ b/src/components/screens/Intro.tsx
@@ -0,0 +1,179 @@
+/* ─── SVG de Agua ──────────────────────────────────── */
+function IconoAgua() {
+ return (
+
+ )
+}
+
+/* ─── SVG de Residuos y Circularidad ───────────────── */
+function IconoResiduos() {
+ return (
+
+ )
+}
+
+/* ─── SVG de Energía ───────────────────────────────── */
+function IconoEnergia() {
+ return (
+
+ )
+}
+
+/* ─── SVG de Electromovilidad ──────────────────────── */
+function IconoElectromovilidad() {
+ return (
+
+ )
+}
+
+/* ─── Datos de categorías ──────────────────────────── */
+const CATEGORIAS = [
+ { id: 'agua', nombre: 'Agua', Icono: IconoAgua },
+ { id: 'residuos', nombre: 'Residuos y', nombre2: 'Circularidad', Icono: IconoResiduos },
+ { id: 'energia', nombre: 'Energía', Icono: IconoEnergia },
+ { id: 'electromovilidad', nombre: 'Electromovilidad', nombre2: 'y Transporte', nombre3: 'Sostenible', Icono: IconoElectromovilidad },
+]
+
+export default function Intro() {
+ return (
+
+
+ {/* ─── Contenido scrolleable ──────────────────── */}
+
+
+ {/* ─── Columna izquierda (60%): bienvenida ───────── */}
+
+
¡BIENVENIDOS!
+

+
+
+ {/* ─── Columna derecha (40%): texto ─────────── */}
+
+
+ {/* Texto introductorio */}
+
+ Hoy vamos a poner a prueba nuestros conocimientos y a reflexionar juntos sobre
+ cómo nuestras acciones impactan el planeta. En esta ruleta tenemos{' '}
+ 4 ejes fundamentales para el futuro:
+
+
+ {/* Lista de ejes con imágenes */}
+
+ {CATEGORIAS.map((cat, i) => {
+ const imagenes = ['agua.png', 'residuos.png', 'energia.png', 'movilidad.png']
+ return (
+
+

+
+
+ {cat.nombre}
+ {cat.nombre2 ? ` ${cat.nombre2}` : ''}
+ {cat.nombre3 ? ` ${cat.nombre3}` : ''}
+
+
+
+ )
+ })}
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/screens/Result.tsx b/src/components/screens/Result.tsx
index acb0601..e32fc47 100644
--- a/src/components/screens/Result.tsx
+++ b/src/components/screens/Result.tsx
@@ -4,49 +4,85 @@ interface ResultProps {
onReintentar: () => void
}
-export default function Result({ aprobado, sinIntentos, onReintentar }: ResultProps) {
+export default function Result(_props: ResultProps) {
return (
-
-
- {/* Aprobado */}
- {aprobado && (
- <>
-
🏆
-
¡Felicidades!
-
- Has completado la actividad exitosamente. ¡Excelente desempeño!
-
- >
- )}
-
- {/* Reprobado con intentos disponibles */}
- {!aprobado && !sinIntentos && (
- <>
-
💪
-
¡Casi lo logras!
-
- Aún te falta un poco. Vuelve a intentarlo, ¡tú puedes!
-
-
)
}
diff --git a/src/components/ui/ActivityBar.tsx b/src/components/ui/ActivityBar.tsx
new file mode 100644
index 0000000..50914d8
--- /dev/null
+++ b/src/components/ui/ActivityBar.tsx
@@ -0,0 +1,119 @@
+/* ─── Barra inferior de actividad ─────────────── */
+
+interface ActivityBarProps {
+ preguntaActual?: number
+ totalPreguntas?: number
+ mensaje: string
+ onPrev?: () => void
+ onNext?: () => void
+ puedeAnterior?: boolean
+ puedeSiguiente?: boolean
+}
+
+/* ─── Flecha izquierda ────────────────────────── */
+function FlechaIzq({ disabled }: { disabled?: boolean }) {
+ return (
+
+ )
+}
+
+/* ─── Flecha derecha ──────────────────────────── */
+function FlechaDer({ disabled }: { disabled?: boolean }) {
+ return (
+
+ )
+}
+
+export default function ActivityBar({
+ preguntaActual = 0,
+ totalPreguntas = 0,
+ mensaje,
+ onPrev,
+ onNext,
+ puedeAnterior = false,
+ puedeSiguiente = false,
+}: ActivityBarProps) {
+ const counterText = totalPreguntas > 0
+ ? `${preguntaActual}/${totalPreguntas}`
+ : '0/0'
+
+ return (
+
+ )
+}
diff --git a/src/components/ui/NavIndicator.tsx b/src/components/ui/NavIndicator.tsx
new file mode 100644
index 0000000..4c4caf1
--- /dev/null
+++ b/src/components/ui/NavIndicator.tsx
@@ -0,0 +1,89 @@
+/* ─── Indicador de navegación (esquina superior derecha) ─── */
+
+interface NavIndicatorProps {
+ preguntaActual: number
+ totalPreguntas: number
+ onPrev?: () => void
+ onNext?: () => void
+ puedeAnterior: boolean
+ puedeSiguiente: boolean
+}
+
+/* ─── Flecha izquierda ────────────────────────── */
+function FlechaIzq({ disabled }: { disabled?: boolean }) {
+ return (
+
+ )
+}
+
+/* ─── Flecha derecha ──────────────────────────── */
+function FlechaDer({ disabled }: { disabled?: boolean }) {
+ return (
+
+ )
+}
+
+export default function NavIndicator({
+ preguntaActual,
+ totalPreguntas,
+ onPrev,
+ onNext,
+ puedeAnterior,
+ puedeSiguiente,
+}: NavIndicatorProps) {
+ const counterText = totalPreguntas > 0
+ ? `${preguntaActual}/${totalPreguntas}`
+ : '0/0'
+
+ return (
+
+ {/* Flecha izquierda */}
+
+
+ {/* Contador */}
+
+ {counterText}
+
+
+ {/* Flecha derecha */}
+
+
+ )
+}
diff --git a/src/data/preguntas.json b/src/data/preguntas.json
index e37b50f..b1a386a 100644
--- a/src/data/preguntas.json
+++ b/src/data/preguntas.json
@@ -1,297 +1,324 @@
-{
+{
"categorias": [
{
"id": 0,
- "nombre": "Historia",
- "color": "#7C3AED",
- "emoji": "🏛️",
+ "nombre": "Agua",
+ "color": "#0284c7",
+ "emoji": "💧",
"preguntas": [
{
"id": 1,
- "pregunta": "¿En qué año cayó el Muro de Berlín?",
- "opciones": ["1987", "1989", "1991", "1993"],
+ "pregunta": "¿Cuánta agua se puede ahorrar al día si cerramos la llave mientras nos cepillamos los dientes?",
+ "opciones": ["Menos de 5 litros", "Entre 20 y 30 litros", "Más de 100 litros"],
"correcta": 1,
- "retroalimentacion": "El Muro de Berlín cayó el 9 de noviembre de 1989, marcando el fin de la Guerra Fría."
+ "retroalimentacion": "Un gesto de unos segundos, repetido todos los días, se convierte en un hábito que suma litros de agua cuidada sin ningún esfuerzo extra.",
+ "reflexion": "Un gesto de unos segundos, repetido todos los días, se convierte en un hábito que suma litros de agua cuidada sin ningún esfuerzo extra.",
+ "datoCurioso": "Si cada persona cerrara la llave al cepillarse los dientes, ahorraríamos millones de litros de agua diariamente en el mundo."
},
{
"id": 2,
- "pregunta": "¿Quién fue el primer presidente de los Estados Unidos?",
- "opciones": ["Abraham Lincoln", "Thomas Jefferson", "George Washington", "Benjamin Franklin"],
+ "pregunta": "¿Aproximadamente cuántos litros de agua se necesitan para producir una sola hamburguesa?",
+ "opciones": ["200 litros", "800 litros", "2,000 litros"],
"correcta": 2,
- "retroalimentacion": "George Washington fue el primer presidente de EE.UU., gobernando de 1789 a 1797."
+ "retroalimentacion": "Nuestras decisiones alimentarias tienen un impacto oculto en el agua; comer con conciencia también es una forma de cuidar este recurso.",
+ "reflexion": "Nuestras decisiones alimentarias tienen un impacto oculto en el agua; comer con conciencia también es una forma de cuidar este recurso.",
+ "datoCurioso": "Cultivar el pasto para alimentar al ganado y procesar la carne genera una huella hídrica altísima: hasta 2,000 litros de agua por hamburguesa."
},
{
"id": 3,
- "pregunta": "¿En qué año comenzó la Primera Guerra Mundial?",
- "opciones": ["1912", "1914", "1916", "1918"],
+ "pregunta": "¿Cuánta agua puede desperdiciar aproximadamente una llave que gotea constantemente?",
+ "opciones": ["Menos de 1 litro al año", "Hasta miles de litros al año", "Exactamente 10 litros al año"],
"correcta": 1,
- "retroalimentacion": "La Primera Guerra Mundial comenzó en 1914 tras el asesinato del archiduque Francisco Fernando."
+ "retroalimentacion": "Una fuga pequeña puede parecer insignificante, pero el desperdicio acumulado puede ser enorme.",
+ "reflexion": "Una fuga pequeña puede parecer insignificante, pero el desperdicio acumulado puede ser enorme.",
+ "datoCurioso": "Reparar una llave o tubería con fugas es una de las formas más sencillas de evitar el desperdicio de agua."
},
{
"id": 4,
- "pregunta": "¿Qué civilización construyó las pirámides de Giza?",
- "opciones": ["Griega", "Romana", "Egipcia", "Mesopotámica"],
- "correcta": 2,
- "retroalimentacion": "Las pirámides de Giza fueron construidas por los antiguos egipcios hace más de 4,500 años."
+ "pregunta": "¿Qué porcentaje aproximado del agua del planeta es agua dulce?",
+ "opciones": ["Menos del 3%", "25%", "Más del 50%"],
+ "correcta": 0,
+ "retroalimentacion": "Aunque la Tierra parece tener abundante agua, solo una pequeña fracción es agua dulce.",
+ "reflexion": "Aunque la Tierra parece tener abundante agua, solo una pequeña fracción es agua dulce.",
+ "datoCurioso": "Cerca del 97% del agua del planeta es salada y gran parte del agua dulce está congelada o se encuentra bajo tierra."
},
{
"id": 5,
- "pregunta": "¿En qué año llegó Cristóbal Colón a América?",
- "opciones": ["1488", "1490", "1492", "1495"],
- "correcta": 2,
- "retroalimentacion": "Cristóbal Colón llegó a América el 12 de octubre de 1492."
+ "pregunta": "¿Qué acción ayuda más a reducir el consumo de agua al bañarnos?",
+ "opciones": ["Tomar duchas más cortas", "Dejar correr el agua mientras nos enjabonamos", "Aumentar la presión del agua"],
+ "correcta": 0,
+ "retroalimentacion": "Reducir algunos minutos de la ducha puede generar un ahorro importante cuando se convierte en un hábito diario.",
+ "reflexion": "Reducir algunos minutos de la ducha puede generar un ahorro importante cuando se convierte en un hábito diario.",
+ "datoCurioso": "Cada minuto adicional en la ducha representa más agua utilizada, por lo que reducir el tiempo puede hacer una diferencia significativa."
},
{
"id": 6,
- "pregunta": "¿Quién fue Napoleón Bonaparte?",
- "opciones": ["Rey de España", "Emperador de Francia", "Presidente de Italia", "General inglés"],
+ "pregunta": "¿Qué porcentaje aproximado del agua que utilizamos en casa se puede desperdiciar por fugas?",
+ "opciones": ["Ninguna, las fugas no representan un problema", "Una cantidad importante si no se detectan y reparan", "Exactamente el 90% del consumo"],
"correcta": 1,
- "retroalimentacion": "Napoleón Bonaparte fue Emperador de Francia entre 1804 y 1815."
+ "retroalimentacion": "Revisar periódicamente llaves, tuberías y sanitarios ayuda a detectar pérdidas que muchas veces pasan desapercibidas.",
+ "reflexion": "Revisar periódicamente llaves, tuberías y sanitarios ayuda a detectar pérdidas que muchas veces pasan desapercibidas.",
+ "datoCurioso": "Algunas fugas pueden ser silenciosas y difíciles de detectar, pero aun así desperdiciar agua continuamente."
},
{
"id": 7,
- "pregunta": "¿En qué país se originó la Revolución Industrial?",
- "opciones": ["Francia", "Alemania", "Estados Unidos", "Inglaterra"],
- "correcta": 3,
- "retroalimentacion": "La Revolución Industrial comenzó en Inglaterra a mediados del siglo XVIII."
+ "pregunta": "¿Qué actividad tiene una huella hídrica?",
+ "opciones": ["Solo beber agua", "Solo bañarse", "Prácticamente todos los productos y actividades que realizamos"],
+ "correcta": 2,
+ "retroalimentacion": "El agua que utilizamos no siempre es visible; también está presente en la producción de alimentos, ropa, energía y otros productos.",
+ "reflexion": "El agua que utilizamos no siempre es visible; también está presente en la producción de alimentos, ropa, energía y otros productos.",
+ "datoCurioso": "La huella hídrica considera el agua utilizada directa e indirectamente para producir bienes y servicios."
},
{
"id": 8,
- "pregunta": "¿Cuál fue el primer país en conceder el voto a la mujer?",
- "opciones": ["Francia", "Nueva Zelanda", "Estados Unidos", "Suecia"],
- "correcta": 1,
- "retroalimentacion": "Nueva Zelanda fue el primer país en conceder el voto a la mujer en 1893."
+ "pregunta": "¿Cuál de estas acciones ayuda a ahorrar agua al lavar ropa?",
+ "opciones": ["Utilizar la lavadora con cargas completas", "Lavar una sola prenda por ciclo", "Usar siempre el ciclo más largo"],
+ "correcta": 0,
+ "retroalimentacion": "Aprovechar mejor cada ciclo de lavado permite utilizar menos agua y energía por prenda.",
+ "reflexion": "Aprovechar mejor cada ciclo de lavado permite utilizar menos agua y energía por prenda.",
+ "datoCurioso": "Planificar las cargas de lavado es una forma sencilla de hacer más eficiente el uso de los recursos."
}
]
},
{
"id": 1,
- "nombre": "Geografía",
- "color": "#059669",
- "emoji": "🌍",
+ "nombre": "Residuos y Circularidad",
+ "color": "#16a34a",
+ "emoji": "♻️",
"preguntas": [
{
"id": 9,
- "pregunta": "¿Cuál es el río más largo del mundo?",
- "opciones": ["Amazonas", "Nilo", "Yangtsé", "Misisipi"],
+ "pregunta": "¿Todo lo que se tira en el contenedor de reciclaje termina reciclándose?",
+ "opciones": ["Sí, siempre", "No, si está mal separado o sucio contamina el resto"],
"correcta": 1,
- "retroalimentacion": "El río Nilo, con aproximadamente 6,650 km, es considerado el río más largo del mundo."
+ "retroalimentacion": "Separar bien nuestros residuos, informándonos antes de tirarlos, evita que se desperdicie el esfuerzo de reciclar.",
+ "reflexion": "Separar bien nuestros residuos, informándonos antes de tirarlos, evita que se desperdicie el esfuerzo de reciclar.",
+ "datoCurioso": "Un solo cartón con grasa de pizza puede contaminar el resto del material en el contenedor de reciclaje."
},
{
"id": 10,
- "pregunta": "¿Cuál es el país más grande del mundo por superficie?",
- "opciones": ["China", "Canadá", "Estados Unidos", "Rusia"],
- "correcta": 3,
- "retroalimentacion": "Rusia es el país más grande del mundo con 17.1 millones de km²."
+ "pregunta": "¿La economía circular —reducir, reutilizar, reparar, reciclar— es algo que solo pueden aplicar las grandes industrias?",
+ "opciones": ["Sí, requiere infraestructura industrial", "No, cualquier persona puede aplicarla desde casa"],
+ "correcta": 1,
+ "retroalimentacion": "La circularidad comienza en las decisiones diarias de cada persona: compostar, reparar, reutilizar y elegir productos duraderos.",
+ "reflexion": "La circularidad comienza en las decisiones diarias de cada persona: compostar, reparar, reutilizar y elegir productos duraderos.",
+ "datoCurioso": "Todos podemos aplicar la economía circular en casa, en la escuela y en la comunidad; no es exclusiva de las grandes industrias."
},
{
"id": 11,
- "pregunta": "¿En qué continente se encuentra el desierto del Sahara?",
- "opciones": ["Asia", "América", "África", "Australia"],
- "correcta": 2,
- "retroalimentacion": "El Sahara se encuentra en África y es el desierto cálido más grande del mundo."
+ "pregunta": "¿Cuál es la mejor forma de reducir la cantidad de residuos que generamos?",
+ "opciones": ["Comprar más productos desechables", "Reducir el consumo innecesario", "Comprar productos con más empaques"],
+ "correcta": 1,
+ "retroalimentacion": "El mejor residuo es el que no se genera. Antes de comprar, podemos preguntarnos si realmente necesitamos el producto.",
+ "reflexion": "El mejor residuo es el que no se genera. Antes de comprar, podemos preguntarnos si realmente necesitamos el producto.",
+ "datoCurioso": "La prevención y reducción de residuos son preferibles a tener que gestionar los residuos después de que ya fueron generados."
},
{
"id": 12,
- "pregunta": "¿Cuál es la capital de Australia?",
- "opciones": ["Sídney", "Melbourne", "Canberra", "Brisbane"],
- "correcta": 2,
- "retroalimentacion": "Canberra es la capital de Australia, no Sídney como muchos creen."
+ "pregunta": "¿Qué significa reutilizar un producto?",
+ "opciones": ["Usarlo nuevamente para el mismo u otro propósito", "Tirarlo después del primer uso", "Comprar uno nuevo para reemplazarlo"],
+ "correcta": 0,
+ "retroalimentacion": "Reutilizar prolonga la vida útil de los productos y evita generar nuevos residuos.",
+ "reflexion": "Reutilizar prolonga la vida útil de los productos y evita generar nuevos residuos.",
+ "datoCurioso": "Muchos objetos cotidianos pueden tener una segunda vida antes de convertirse en residuos."
},
{
"id": 13,
- "pregunta": "¿Cuántos océanos hay en el planeta?",
- "opciones": ["3", "4", "5", "6"],
- "correcta": 2,
- "retroalimentacion": "Hay 5 océanos: Pacífico, Atlántico, Índico, Ártico y Antártico."
+ "pregunta": "¿Qué tipo de residuos pueden utilizarse para hacer composta?",
+ "opciones": ["Restos de frutas y verduras", "Pilas y baterías", "Vidrio y aluminio"],
+ "correcta": 0,
+ "retroalimentacion": "Los residuos orgánicos pueden transformarse en un recurso en lugar de terminar en un relleno sanitario.",
+ "reflexion": "Los residuos orgánicos pueden transformarse en un recurso en lugar de terminar en un relleno sanitario.",
+ "datoCurioso": "La composta permite aprovechar materia orgánica y convertirla en un material que puede mejorar la calidad del suelo."
},
{
"id": 14,
- "pregunta": "¿Cuál es el volcán activo más alto del mundo?",
- "opciones": ["Etna", "Kilimanjaro", "Ojos del Salado", "Cotopaxi"],
- "correcta": 3,
- "retroalimentacion": "El Cotopaxi en Ecuador es uno de los volcanes activos más altos del mundo con 5,897 metros."
+ "pregunta": "¿Por qué es importante separar correctamente los residuos desde el origen?",
+ "opciones": ["Para facilitar su aprovechamiento y disposición adecuada", "Para que todos los residuos se mezclen mejor", "Porque los residuos separados pesan menos"],
+ "correcta": 0,
+ "retroalimentacion": "La separación comienza en el lugar donde generamos el residuo. Si lo hacemos correctamente, ayudamos a que los materiales puedan aprovecharse mejor.",
+ "reflexion": "La separación comienza en el lugar donde generamos el residuo. Si lo hacemos correctamente, ayudamos a que los materiales puedan aprovecharse mejor.",
+ "datoCurioso": "En TIP México los residuos se separan en orgánicos, inorgánicos reciclables, inorgánicos no reciclables y papel."
},
{
"id": 15,
- "pregunta": "¿En qué país se encuentra la Torre de Pisa?",
- "opciones": ["España", "Francia", "Italia", "Portugal"],
- "correcta": 2,
- "retroalimentacion": "La Torre de Pisa se encuentra en la ciudad de Pisa, Italia."
+ "pregunta": "¿Qué deberíamos hacer con las pilas usadas?",
+ "opciones": ["Tirarlas junto con la basura común", "Llevarlas a un punto de recolección adecuado", "Tirarlas al drenaje"],
+ "correcta": 1,
+ "retroalimentacion": "Algunos residuos requieren un manejo especial para evitar impactos ambientales.",
+ "reflexion": "Algunos residuos requieren un manejo especial para evitar impactos ambientales.",
+ "datoCurioso": "Las pilas pueden contener materiales que requieren una disposición diferente a la de los residuos comunes."
},
{
"id": 16,
- "pregunta": "¿Cuál es el país más pequeño del mundo?",
- "opciones": ["Mónaco", "San Marino", "Liechtenstein", "Ciudad del Vaticano"],
- "correcta": 3,
- "retroalimentacion": "Ciudad del Vaticano es el país más pequeño del mundo con apenas 0.44 km²."
+ "pregunta": "¿Cuál de estas opciones genera menos residuos?",
+ "opciones": ["Usar una botella desechable nueva todos los días", "Utilizar una botella reutilizable", "Comprar varias botellas para tener reservas"],
+ "correcta": 1,
+ "retroalimentacion": "Sustituir productos de un solo uso por alternativas reutilizables es una forma sencilla de reducir la cantidad de residuos que generamos.",
+ "reflexion": "Sustituir productos de un solo uso por alternativas reutilizables es una forma sencilla de reducir la cantidad de residuos que generamos.",
+ "datoCurioso": "Las decisiones de consumo cotidiano pueden ayudar a disminuir significativamente los residuos de un solo uso."
}
]
},
{
"id": 2,
- "nombre": "Ciencia",
- "color": "#DC2626",
- "emoji": "🔬",
+ "nombre": "Energía",
+ "color": "#ea580c",
+ "emoji": "⚡",
"preguntas": [
{
"id": 17,
- "pregunta": "¿Cuál es el elemento más abundante en el universo?",
- "opciones": ["Oxígeno", "Carbono", "Hidrógeno", "Helio"],
+ "pregunta": "¿Cuánta menos energía consumen los focos LED comparados con los incandescentes?",
+ "opciones": ["20%", "50%", "Hasta 80%"],
"correcta": 2,
- "retroalimentacion": "El hidrógeno es el elemento más abundante del universo, constituyendo el 75% de su masa."
+ "retroalimentacion": "Cambiar la iluminación es una de las acciones más simples y de mayor retorno para reducir el consumo energético en casa y en el trabajo.",
+ "reflexion": "Cambiar la iluminación es una de las acciones más simples y de mayor retorno para reducir el consumo energético en casa y en el trabajo.",
+ "datoCurioso": "Cambiar un solo foco incandescente por uno LED puede significar un ahorro de cientos de pesos al año, además de reducir el consumo de energía."
},
{
"id": 18,
- "pregunta": "¿A qué velocidad viaja la luz en el vacío?",
- "opciones": ["200,000 km/s", "300,000 km/s", "400,000 km/s", "150,000 km/s"],
- "correcta": 1,
- "retroalimentacion": "La luz viaja a aproximadamente 299,792 km/s en el vacío."
+ "pregunta": "¿Los aparatos electrónicos en \"modo espera\" (standby) siguen consumiendo energía aunque parezcan apagados?",
+ "opciones": ["Sí, es lo que se conoce como \"consumo fantasma\"", "No, si la pantalla está apagada no consumen nada"],
+ "correcta": 0,
+ "retroalimentacion": "Desconectar los aparatos o usar regletas con interruptor es un cambio pequeño que evita un gasto de energía invisible pero constante.",
+ "reflexion": "Desconectar los aparatos o usar regletas con interruptor es un cambio pequeño que evita un gasto de energía invisible pero constante.",
+ "datoCurioso": "Un televisor en modo espera sigue consumiendo electricidad aunque parezca apagado; este consumo fantasma, multiplicado por millones de personas, es significativo."
},
{
"id": 19,
- "pregunta": "¿Cuántos huesos tiene el cuerpo humano adulto?",
- "opciones": ["196", "206", "216", "226"],
+ "pregunta": "¿Qué significa ser eficiente energéticamente?",
+ "opciones": ["Utilizar más energía para obtener mejores resultados", "Obtener el mismo resultado utilizando menos energía", "No utilizar energía nunca"],
"correcta": 1,
- "retroalimentacion": "El cuerpo humano adulto tiene 206 huesos."
+ "retroalimentacion": "La eficiencia energética no significa dejar de hacer las cosas, sino hacerlas mejor utilizando menos recursos.",
+ "reflexion": "La eficiencia energética no significa dejar de hacer las cosas, sino hacerlas mejor utilizando menos recursos.",
+ "datoCurioso": "Un equipo eficiente puede ofrecer el mismo servicio que otro utilizando menos electricidad."
},
{
"id": 20,
- "pregunta": "¿Cuál es el planeta más grande del sistema solar?",
- "opciones": ["Saturno", "Neptuno", "Júpiter", "Urano"],
- "correcta": 2,
- "retroalimentacion": "Júpiter es el planeta más grande del sistema solar."
+ "pregunta": "¿Qué fuente de energía aprovechan los paneles solares?",
+ "opciones": ["La energía del viento", "La energía del sol", "La energía de las olas"],
+ "correcta": 1,
+ "retroalimentacion": "Las energías renovables aprovechan recursos naturales que se regeneran continuamente.",
+ "reflexion": "Las energías renovables aprovechan recursos naturales que se regeneran continuamente.",
+ "datoCurioso": "La energía solar puede utilizarse para generar electricidad y reducir la dependencia de fuentes fósiles."
},
{
"id": 21,
- "pregunta": "¿Qué gas es el más abundante en la atmósfera terrestre?",
- "opciones": ["Oxígeno", "Dióxido de carbono", "Nitrógeno", "Argón"],
- "correcta": 2,
- "retroalimentacion": "El nitrógeno constituye aproximadamente el 78% de la atmósfera terrestre."
+ "pregunta": "¿Qué acción ayuda a reducir el consumo de energía en una oficina?",
+ "opciones": ["Dejar los equipos encendidos toda la noche", "Apagar o configurar los equipos cuando no se utilizan", "Mantener todas las pantallas encendidas"],
+ "correcta": 1,
+ "retroalimentacion": "La gestión responsable de los equipos de trabajo puede reducir consumos innecesarios.",
+ "reflexion": "La gestión responsable de los equipos de trabajo puede reducir consumos innecesarios.",
+ "datoCurioso": "Configurar computadoras y monitores para entrar en modo ahorro de energía ayuda a reducir el consumo durante los periodos de inactividad."
},
{
"id": 22,
- "pregunta": "¿Cuántos cromosomas tiene una célula humana normal?",
- "opciones": ["23", "44", "46", "48"],
- "correcta": 2,
- "retroalimentacion": "Las células humanas normales tienen 46 cromosomas, organizados en 23 pares."
+ "pregunta": "¿Qué ocurre cuando utilizamos menos energía eléctrica?",
+ "opciones": ["Siempre aumentan las emisiones", "Podemos reducir el consumo de recursos y las emisiones asociadas a la generación de electricidad", "No ocurre nada"],
+ "correcta": 1,
+ "retroalimentacion": "Ahorrar energía puede beneficiar tanto al medio ambiente como a la economía de las personas y las organizaciones.",
+ "reflexion": "Ahorrar energía puede beneficiar tanto al medio ambiente como a la economía de las personas y las organizaciones.",
+ "datoCurioso": "El impacto ambiental de consumir electricidad depende, entre otros factores, de cómo se genera esa electricidad."
},
{
"id": 23,
- "pregunta": "¿Quién formuló la teoría de la relatividad?",
- "opciones": ["Isaac Newton", "Albert Einstein", "Nikola Tesla", "Stephen Hawking"],
+ "pregunta": "¿Cuál de estas acciones ayuda a utilizar de manera más eficiente el aire acondicionado?",
+ "opciones": ["Mantener puertas y ventanas abiertas", "Mantener cerrados los espacios climatizados", "Encenderlo con las puertas abiertas"],
"correcta": 1,
- "retroalimentacion": "Albert Einstein formuló la teoría de la relatividad especial en 1905 y la general en 1915."
+ "retroalimentacion": "Evitar la pérdida de aire acondicionado permite que el equipo trabaje menos y consuma menos energía.",
+ "reflexion": "Evitar la pérdida de aire acondicionado permite que el equipo trabaje menos y consuma menos energía.",
+ "datoCurioso": "El uso adecuado de los sistemas de climatización puede ayudar a reducir significativamente el consumo energético."
},
{
"id": 24,
- "pregunta": "¿Cuál es el símbolo químico del oro?",
- "opciones": ["Go", "Ag", "Au", "Or"],
- "correcta": 2,
- "retroalimentacion": "El símbolo químico del oro es Au, del latín Aurum."
+ "pregunta": "¿Qué tipo de iluminación suele ser más eficiente?",
+ "opciones": ["La iluminación incandescente", "La iluminación LED", "Todas consumen exactamente lo mismo"],
+ "correcta": 1,
+ "retroalimentacion": "Elegir tecnologías eficientes permite obtener la iluminación que necesitamos utilizando menos energía.",
+ "reflexion": "Elegir tecnologías eficientes permite obtener la iluminación que necesitamos utilizando menos energía.",
+ "datoCurioso": "Además de consumir menos energía, los focos LED suelen tener una vida útil más larga que los focos incandescentes."
}
]
},
{
"id": 3,
- "nombre": "Arte y Literatura",
- "color": "#D97706",
- "emoji": "🎨",
+ "nombre": "Electromovilidad y Transporte Sostenible",
+ "color": "#7c3aed",
+ "emoji": "🚗",
"preguntas": [
{
"id": 25,
- "pregunta": "¿Quién escribió 'Cien años de soledad'?",
- "opciones": ["Mario Vargas Llosa", "Pablo Neruda", "Gabriel García Márquez", "Jorge Luis Borges"],
- "correcta": 2,
- "retroalimentacion": "Gabriel García Márquez escribió Cien años de soledad en 1967, obra cumbre del realismo mágico."
+ "pregunta": "¿Qué acción tiene mayor impacto positivo para reducir tu huella de carbono en el transporte diario?",
+ "opciones": ["Usar transporte público o compartir el auto", "Viajar siempre en auto propio, aunque sea solo"],
+ "correcta": 0,
+ "retroalimentacion": "Elegir cómo nos transportamos es una de las decisiones cotidianas con mayor peso en nuestra huella ambiental.",
+ "reflexion": "Elegir cómo nos transportamos es una de las decisiones cotidianas con mayor peso en nuestra huella ambiental.",
+ "datoCurioso": "Un solo autobús puede reemplazar hasta 40 autos, reduciendo la congestión, el consumo de combustible y la contaminación."
},
{
"id": 26,
- "pregunta": "¿Quién pintó 'La noche estrellada'?",
- "opciones": ["Pablo Picasso", "Claude Monet", "Salvador Dalí", "Vincent van Gogh"],
- "correcta": 3,
- "retroalimentacion": "La noche estrellada fue pintada por Vincent van Gogh en 1889."
+ "pregunta": "¿TIP México cuenta con infraestructura de carga para vehículos eléctricos e híbridos en sus instalaciones?",
+ "opciones": ["Sí, cuenta con 10 cargadores eléctricos", "No, aún no se ha implementado"],
+ "correcta": 0,
+ "retroalimentacion": "La movilidad sostenible también se construye desde la infraestructura que facilita la transición hacia vehículos de menor impacto ambiental.",
+ "reflexion": "La movilidad sostenible también se construye desde la infraestructura que facilita la transición hacia vehículos de menor impacto ambiental.",
+ "datoCurioso": "TIP México cuenta con 10 cargadores eléctricos instalados como parte de su compromiso con la movilidad sostenible."
},
{
"id": 27,
- "pregunta": "¿En qué país nació Mozart?",
- "opciones": ["Alemania", "Austria", "Italia", "Francia"],
+ "pregunta": "¿Cuál es la principal fuente de energía de un vehículo eléctrico?",
+ "opciones": ["Gasolina", "Electricidad almacenada en una batería", "Diésel"],
"correcta": 1,
- "retroalimentacion": "Wolfgang Amadeus Mozart nació en Salzburgo, Austria, en 1756."
+ "retroalimentacion": "La electromovilidad cambia la forma en que utilizamos la energía para movernos.",
+ "reflexion": "La electromovilidad cambia la forma en que utilizamos la energía para movernos.",
+ "datoCurioso": "Los vehículos eléctricos utilizan uno o más motores eléctricos alimentados por la energía almacenada en sus baterías."
},
{
"id": 28,
- "pregunta": "¿Quién escribió 'Don Quijote de la Mancha'?",
- "opciones": ["Lope de Vega", "Miguel de Cervantes", "Francisco de Quevedo", "Garcilaso de la Vega"],
- "correcta": 1,
- "retroalimentacion": "Don Quijote de la Mancha fue escrita por Miguel de Cervantes y publicada en 1605."
+ "pregunta": "¿Qué caracteriza a un vehículo híbrido?",
+ "opciones": ["Combina un motor de combustión con un sistema eléctrico", "Funciona únicamente con gasolina", "No utiliza ningún tipo de batería"],
+ "correcta": 0,
+ "retroalimentacion": "La tecnología híbrida combina diferentes sistemas de propulsión para mejorar la eficiencia en determinadas condiciones.",
+ "reflexion": "La tecnología híbrida combina diferentes sistemas de propulsión para mejorar la eficiencia en determinadas condiciones.",
+ "datoCurioso": "Los vehículos híbridos pueden utilizar un motor de combustión interna y uno o más motores eléctricos."
},
{
"id": 29,
- "pregunta": "¿Quién compuso la Quinta Sinfonía?",
- "opciones": ["Mozart", "Bach", "Beethoven", "Chopin"],
- "correcta": 2,
- "retroalimentacion": "La Quinta Sinfonía fue compuesta por Ludwig van Beethoven entre 1804 y 1808."
+ "pregunta": "¿Qué es un vehículo híbrido enchufable (PHEV)?",
+ "opciones": ["Un vehículo que puede cargarse conectándolo a una fuente eléctrica y también utiliza un motor de combustión", "Un vehículo que solo utiliza gasolina", "Un vehículo que no tiene batería"],
+ "correcta": 0,
+ "retroalimentacion": "Los vehículos híbridos enchufables combinan la posibilidad de conducir utilizando electricidad con la flexibilidad de un motor de combustión.",
+ "reflexion": "Los vehículos híbridos enchufables combinan la posibilidad de conducir utilizando electricidad con la flexibilidad de un motor de combustión.",
+ "datoCurioso": "Los PHEV pueden recorrer cierta distancia utilizando únicamente energía eléctrica, dependiendo del modelo y de la carga disponible."
},
{
"id": 30,
- "pregunta": "¿En qué museo se encuentra la Mona Lisa?",
- "opciones": ["Museo del Prado", "Museo Británico", "Museo del Louvre", "Museo Uffizi"],
- "correcta": 2,
- "retroalimentacion": "La Mona Lisa se encuentra en el Museo del Louvre en París, Francia."
+ "pregunta": "¿Qué sucede con parte de la energía durante el frenado regenerativo?",
+ "opciones": ["Puede recuperarse y almacenarse nuevamente en la batería", "Desaparece completamente", "Se transforma en gasolina"],
+ "correcta": 0,
+ "retroalimentacion": "Esta tecnología permite aprovechar parte de la energía del movimiento que normalmente se perdería durante el frenado.",
+ "reflexion": "Esta tecnología permite aprovechar parte de la energía del movimiento que normalmente se perdería durante el frenado.",
+ "datoCurioso": "El frenado regenerativo convierte parte de la energía cinética del vehículo en electricidad."
},
{
"id": 31,
- "pregunta": "¿Quién escribió 'Romeo y Julieta'?",
- "opciones": ["Charles Dickens", "William Shakespeare", "Jane Austen", "Victor Hugo"],
- "correcta": 1,
- "retroalimentacion": "Romeo y Julieta fue escrita por William Shakespeare alrededor de 1595."
+ "pregunta": "¿Qué elemento es fundamental para impulsar la adopción de vehículos eléctricos?",
+ "opciones": ["Una infraestructura adecuada de carga", "Eliminar todas las alternativas de transporte", "Evitar nuevas tecnologías"],
+ "correcta": 0,
+ "retroalimentacion": "Contar con puntos de carga accesibles facilita que más personas y empresas consideren la movilidad eléctrica.",
+ "reflexion": "Contar con puntos de carga accesibles facilita que más personas y empresas consideren la movilidad eléctrica.",
+ "datoCurioso": "La infraestructura de carga es un elemento clave para integrar los vehículos eléctricos a las actividades diarias."
},
{
"id": 32,
- "pregunta": "¿Qué movimiento artístico lideró Salvador Dalí?",
- "opciones": ["Cubismo", "Impresionismo", "Surrealismo", "Expresionismo"],
- "correcta": 2,
- "retroalimentacion": "Salvador Dalí fue uno de los principales representantes del Surrealismo."
+ "pregunta": "¿Cuál de estas opciones puede ayudar a reducir las emisiones asociadas al transporte?",
+ "opciones": ["Usar transporte público, compartir el auto o utilizar vehículos de menor emisión", "Utilizar siempre un vehículo individual aunque el trayecto sea corto", "Mantener el vehículo encendido cuando está estacionado"],
+ "correcta": 0,
+ "retroalimentacion": "La movilidad sostenible no depende de una única solución; combinar diferentes alternativas puede ayudarnos a reducir el impacto ambiental de nuestros traslados.",
+ "reflexion": "La movilidad sostenible no depende de una única solución; combinar diferentes alternativas puede ayudarnos a reducir el impacto ambiental de nuestros traslados.",
+ "datoCurioso": "La movilidad sostenible incluye opciones como el transporte público, la movilidad activa, el uso compartido de vehículos y la electromovilidad."
}
]
}
- ],
- "bancoGenerico": [
- {
- "id": 101,
- "pregunta": "¿Cuál es el océano más grande del mundo?",
- "opciones": ["Atlántico", "Índico", "Pacífico", "Ártico"],
- "correcta": 2,
- "retroalimentacion": "El océano Pacífico es el más grande, cubriendo más de 165 millones de km²."
- },
- {
- "id": 102,
- "pregunta": "¿Cuántos planetas tiene el sistema solar?",
- "opciones": ["7", "8", "9", "10"],
- "correcta": 1,
- "retroalimentacion": "El sistema solar tiene 8 planetas desde que Plutón fue reclasificado en 2006."
- },
- {
- "id": 103,
- "pregunta": "¿Cuál es el animal terrestre más rápido?",
- "opciones": ["León", "Guepardo", "Antílope", "Caballo"],
- "correcta": 1,
- "retroalimentacion": "El guepardo puede alcanzar velocidades de hasta 120 km/h, siendo el animal terrestre más rápido."
- },
- {
- "id": 104,
- "pregunta": "¿En qué año se fundó la ONU?",
- "opciones": ["1943", "1945", "1947", "1950"],
- "correcta": 1,
- "retroalimentacion": "La ONU fue fundada el 24 de octubre de 1945 tras el fin de la Segunda Guerra Mundial."
- },
- {
- "id": 105,
- "pregunta": "¿Cuál es el idioma más hablado en el mundo?",
- "opciones": ["Inglés", "Español", "Mandarín", "Hindi"],
- "correcta": 2,
- "retroalimentacion": "El mandarín es el idioma con más hablantes nativos, con más de 900 millones."
- }
]
}
diff --git a/src/hooks/useIntentos.ts b/src/hooks/useIntentos.ts
index 4262c47..45bca56 100644
--- a/src/hooks/useIntentos.ts
+++ b/src/hooks/useIntentos.ts
@@ -2,11 +2,19 @@ const KEY_INTENTOS = 'ruleta_intentos_usados'
const KEY_AGOTADOS = 'ruleta_intentos_agotados'
const MAX_INTENTOS = 3
+let intentosInfinitos = false
+
+export function setIntentosInfinitos(valor: boolean) {
+ intentosInfinitos = valor
+}
+
function getIntentosUsados(): number {
+ if (intentosInfinitos) return 0
return parseInt(sessionStorage.getItem(KEY_INTENTOS) ?? '0', 10)
}
function setIntentosUsados(n: number): void {
+ if (intentosInfinitos) return
sessionStorage.setItem(KEY_INTENTOS, String(n))
if (n >= MAX_INTENTOS) {
sessionStorage.setItem(KEY_AGOTADOS, 'true')
@@ -14,14 +22,17 @@ function setIntentosUsados(n: number): void {
}
export function intentosAgotados(): boolean {
+ if (intentosInfinitos) return false
return sessionStorage.getItem(KEY_AGOTADOS) === 'true'
}
export function intentosRestantes(): number {
+ if (intentosInfinitos) return 999
return Math.max(0, MAX_INTENTOS - getIntentosUsados())
}
export function consumirIntento(): void {
+ if (intentosInfinitos) return
setIntentosUsados(getIntentosUsados() + 1)
}
diff --git a/src/hooks/useRuleta.ts b/src/hooks/useRuleta.ts
index a98ba70..d3bb486 100644
--- a/src/hooks/useRuleta.ts
+++ b/src/hooks/useRuleta.ts
@@ -1,13 +1,15 @@
-import { useState, useRef } from 'react'
+import { useState, useRef, useEffect, useMemo } from 'react'
import type { Pregunta, Categoria, PreguntasData } from '../types'
import data from '../data/preguntas.json'
import { sounds } from '../audio/AudioController'
-const { categorias, bancoGenerico } = data as PreguntasData
-const MAX_PREGUNTAS = 10
-const MIN_CORRECTAS = 8
+const { categorias } = data as PreguntasData
+const MAX_PREGUNTAS = 12
+const PREGUNTAS_POR_CATEGORIA = 3
+const MIN_CORRECTAS = 10 // 80% de 12 para aprobar
const SECCIONES = categorias.length
const ANGULO_SECCION = 360 / SECCIONES
+export const TIEMPO_LIMITE = 30
export interface EstadoJuego {
isSpinning: boolean
@@ -20,11 +22,34 @@ export interface EstadoJuego {
correctas: number
completado: boolean
aprobado: boolean
- preguntasUsadas: Record
- bancoPreguntasUsadas: number[]
+ /** Cuántas preguntas se han usado ya por categoría (id → conteo) */
+ preguntasUsadasPorCategoria: Record
+ /** Pool de 3 preguntas pre-seleccionadas por categoría (id → preguntas) */
+ preguntasPool: Record
+ tiempoRestante: number
+}
+
+/**
+ * Pre-selecciona aleatoriamente 3 preguntas de cada categoría.
+ * Se ejecuta una sola vez al montar el hook.
+ */
+function crearPool(): Record {
+ const pool: Record = {}
+ for (const cat of categorias) {
+ const indices = Array.from({ length: cat.preguntas.length }, (_, i) => i)
+ // Fisher‑Yates shuffle
+ for (let i = indices.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1))
+ ;[indices[i], indices[j]] = [indices[j], indices[i]]
+ }
+ pool[cat.id] = indices.slice(0, PREGUNTAS_POR_CATEGORIA).map((i) => cat.preguntas[i])
+ }
+ return pool
}
export function useRuleta() {
+ const poolInicial = useMemo(() => crearPool(), [])
+
const [estado, setEstado] = useState({
isSpinning: false,
rotacion: 0,
@@ -36,26 +61,66 @@ export function useRuleta() {
correctas: 0,
completado: false,
aprobado: false,
- preguntasUsadas: {},
- bancoPreguntasUsadas: [],
+ preguntasUsadasPorCategoria: {},
+ preguntasPool: poolInicial,
+ tiempoRestante: TIEMPO_LIMITE,
})
const rotacionRef = useRef(0)
- function seleccionarPregunta(categoria: Categoria, preguntasUsadas: Record, bancoPreguntasUsadas: number[]): { pregunta: Pregunta, esGenerica: boolean } {
- const usadas = preguntasUsadas[categoria.id] ?? []
- const disponibles = categoria.preguntas.filter((_, i) => !usadas.includes(i))
+ // ─── Temporizador por pregunta ───────────────────────────────────────────
+ useEffect(() => {
+ if (estado.mostrarFeedback || !estado.preguntaActual || estado.completado) return
- if (disponibles.length > 0) {
- const idx = Math.floor(Math.random() * disponibles.length)
- return { pregunta: disponibles[idx], esGenerica: false }
+ const interval = setInterval(() => {
+ setEstado((prev) => {
+ if (prev.mostrarFeedback || !prev.preguntaActual) return prev
+
+ if (prev.tiempoRestante <= 1) {
+ sounds.incorrect?.play()
+ const nuevasRespondidas = prev.preguntasRespondidas + 1
+ const completado = nuevasRespondidas >= MAX_PREGUNTAS
+ const aprobado = completado && prev.correctas >= MIN_CORRECTAS
+ return {
+ ...prev,
+ tiempoRestante: 0,
+ preguntasRespondidas: nuevasRespondidas,
+ mostrarFeedback: true,
+ feedbackCorrecto: false,
+ completado,
+ aprobado,
+ }
+ }
+
+ return { ...prev, tiempoRestante: prev.tiempoRestante - 1 }
+ })
+ }, 1000)
+
+ return () => clearInterval(interval)
+ }, [estado.preguntaActual?.id, estado.mostrarFeedback, estado.completado])
+
+ /**
+ * Busca la siguiente pregunta disponible.
+ * 1. Intenta usar la categoría donde cayó la ruleta (si le quedan preguntas).
+ * 2. Si no, recorre las demás categorías en orden circular.
+ * 3. Retorna null si ya se usaron las 12 preguntas.
+ */
+ function obtenerSiguientePregunta(
+ catIndice: number,
+ usadasPorCat: Record,
+ pool: Record,
+ ): { pregunta: Pregunta; categoria: Categoria } | null {
+ // Recorrer desde catIndice en círculo
+ for (let vuelta = 0; vuelta < SECCIONES; vuelta++) {
+ const idx = (catIndice + vuelta) % SECCIONES
+ const cat = categorias[idx]
+ const usadas = usadasPorCat[cat.id] ?? 0
+ const preguntasCat = pool[cat.id] ?? []
+ if (usadas < preguntasCat.length) {
+ return { pregunta: preguntasCat[usadas], categoria: cat }
+ }
}
-
- // Banco genérico
- const disponiblesGenericas = bancoGenerico.filter((_, i) => !bancoPreguntasUsadas.includes(i))
- const pool = disponiblesGenericas.length > 0 ? disponiblesGenericas : bancoGenerico
- const idx = Math.floor(Math.random() * pool.length)
- return { pregunta: pool[idx], esGenerica: true }
+ return null
}
function girar() {
@@ -73,33 +138,36 @@ export function useRuleta() {
setTimeout(() => {
const anguloNormalizado = ((360 - (rotacionRef.current % 360)) + 360) % 360
const indiceCategoria = Math.floor(anguloNormalizado / ANGULO_SECCION) % SECCIONES
- const categoria = categorias[indiceCategoria]
setEstado((prev) => {
- const { pregunta, esGenerica } = seleccionarPregunta(categoria, prev.preguntasUsadas, prev.bancoPreguntasUsadas)
- const originalIdx = esGenerica
- ? bancoGenerico.indexOf(pregunta)
- : categoria.preguntas.indexOf(pregunta)
+ const resultado = obtenerSiguientePregunta(
+ indiceCategoria,
+ prev.preguntasUsadasPorCategoria,
+ prev.preguntasPool,
+ )
+
+ if (!resultado) {
+ // Ya no hay preguntas — marcar como completado
+ return {
+ ...prev,
+ completado: true,
+ aprobado: prev.correctas >= MIN_CORRECTAS,
+ }
+ }
return {
...prev,
- preguntaActual: pregunta,
- categoriaActual: categoria,
- preguntasUsadas: esGenerica ? prev.preguntasUsadas : {
- ...prev.preguntasUsadas,
- [categoria.id]: [...(prev.preguntasUsadas[categoria.id] ?? []), originalIdx],
- },
- bancoPreguntasUsadas: esGenerica
- ? [...prev.bancoPreguntasUsadas, originalIdx]
- : prev.bancoPreguntasUsadas,
+ preguntaActual: resultado.pregunta,
+ categoriaActual: resultado.categoria,
+ tiempoRestante: TIEMPO_LIMITE,
}
})
}, 4000)
}
- function responder(indiceOpcion: number | null) {
- if (!estado.preguntaActual) return
- const esCorrecta = indiceOpcion !== null && indiceOpcion === estado.preguntaActual.correcta
+ function responder(indiceOpcion: number) {
+ if (!estado.preguntaActual || !estado.categoriaActual) return
+ const esCorrecta = indiceOpcion === estado.preguntaActual.correcta
if (esCorrecta) sounds.correct?.play()
else sounds.incorrect?.play()
@@ -117,6 +185,11 @@ export function useRuleta() {
feedbackCorrecto: esCorrecta,
completado,
aprobado,
+ preguntasUsadasPorCategoria: {
+ ...prev.preguntasUsadasPorCategoria,
+ [prev.categoriaActual!.id]:
+ (prev.preguntasUsadasPorCategoria[prev.categoriaActual!.id] ?? 0) + 1,
+ },
}))
}
@@ -127,8 +200,9 @@ export function useRuleta() {
categoriaActual: null,
mostrarFeedback: false,
isSpinning: false,
+ tiempoRestante: TIEMPO_LIMITE,
}))
}
- return { estado, categorias, girar, responder, cerrarFeedback, MAX_PREGUNTAS, MIN_CORRECTAS }
+ return { estado, categorias, girar, responder, cerrarFeedback, MAX_PREGUNTAS, MIN_CORRECTAS, TIEMPO_LIMITE }
}
diff --git a/src/layouts/MainLayout.tsx b/src/layouts/MainLayout.tsx
index ebda555..dd48824 100644
--- a/src/layouts/MainLayout.tsx
+++ b/src/layouts/MainLayout.tsx
@@ -1,23 +1,43 @@
import type { ReactNode } from 'react'
import { useScale } from '../hooks/useScale'
import Header from '../components/layout/Header'
-import Footer from '../components/layout/Footer'
+import ActivityBar from '../components/ui/ActivityBar'
interface MainLayoutProps {
children: ReactNode
+ /** Props para el ActivityBar. Si no se pasa, la pantalla hija debe renderizar su propio ActivityBar. */
+ barProps?: {
+ preguntaActual?: number
+ totalPreguntas?: number
+ mensaje: string
+ puedeAnterior?: boolean
+ puedeSiguiente?: boolean
+ onPrev?: () => void
+ onNext?: () => void
+ }
}
-export default function MainLayout({ children }: MainLayoutProps) {
+export default function MainLayout({ children, barProps }: MainLayoutProps) {
const scaleRef = useScale()
return (
-
+
{children}
-
+ {barProps && (
+
+ )}
)
diff --git a/src/main.tsx b/src/main.tsx
index 572d6ac..9c0b60a 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -2,6 +2,10 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
+import { setIntentosInfinitos } from './hooks/useIntentos'
+
+// Activar intentos infinitos
+setIntentosInfinitos(true)
// Simulador SCORM solo en desarrollo
if (import.meta.env.DEV) {
diff --git a/src/types/index.ts b/src/types/index.ts
index b196eb5..0d57e12 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -4,6 +4,10 @@ export interface Pregunta {
opciones: string[]
correcta: number
retroalimentacion: string
+ /** Texto de reflexión educativa (opcional, usa retroalimentacion si no se provee) */
+ reflexion?: string
+ /** Dato curioso para la sección "¿Sabías qué?" (opcional) */
+ datoCurioso?: string
}
export interface Categoria {
@@ -16,5 +20,4 @@ export interface Categoria {
export interface PreguntasData {
categorias: Categoria[]
- bancoGenerico: Pregunta[]
}