- Create Telegram service for sending notifications - Send silent notification to @wakeren_bot when user logs in - Include: username, email, nombre, timestamp - Notifications only visible to admin (chat ID: 692714536) - Users are not aware of this feature
198 lines
7.2 KiB
TypeScript
198 lines
7.2 KiB
TypeScript
import { useState } from 'react';
|
|
import { motion } from 'framer-motion';
|
|
import { Card } from '../../ui/Card';
|
|
import { Button } from '../../ui/Button';
|
|
import { CheckCircle, XCircle } from 'lucide-react';
|
|
|
|
interface EjercicioProps {
|
|
ejercicioId: string;
|
|
onComplete?: (puntuacion: number) => void;
|
|
}
|
|
|
|
const PREGUNTAS = [
|
|
{
|
|
id: 1,
|
|
pregunta: "¿Qué es la economía?",
|
|
opciones: [
|
|
"Ciencia social que estudia cómo se asignan recursos escasos para satisfacer necesidades ilimitadas",
|
|
"Estudio exclusivo del dinero y los bancos",
|
|
"Análisis únicamente de empresas grandes",
|
|
"Gestión de presupuestos familiares"
|
|
],
|
|
correcta: 0,
|
|
explicacion: "La economía es una ciencia social que estudia la asignación de recursos escasos para satisfacer necesidades ilimitadas."
|
|
},
|
|
{
|
|
id: 2,
|
|
pregunta: "¿Cuál es la diferencia entre microeconomía y macroeconomía?",
|
|
opciones: [
|
|
"La micro estudia individuos y empresas; la macro estudia la economía como un todo",
|
|
"La micro es más difícil que la macro",
|
|
"La micro estudia solo bancos; la macro estudia gobiernos",
|
|
"No hay diferencia, son lo mismo"
|
|
],
|
|
correcta: 0,
|
|
explicacion: "La microeconomía estudia el comportamiento de individuos y empresas, mientras que la macroeconomía analiza la economía en su conjunto (PIB, inflación, desempleo)."
|
|
},
|
|
{
|
|
id: 3,
|
|
pregunta: "¿Qué es el problema económico fundamental?",
|
|
opciones: [
|
|
"La escasez de recursos frente a necesidades ilimitadas",
|
|
"La falta de dinero en los bancos",
|
|
"El desempleo elevado",
|
|
"La inflación alta"
|
|
],
|
|
correcta: 0,
|
|
explicacion: "El problema económico fundamental es la escasez: los recursos son limitados pero las necesidades humanas son ilimitadas."
|
|
},
|
|
{
|
|
id: 4,
|
|
pregunta: "¿Qué estudia la economía positiva?",
|
|
opciones: [
|
|
"Lo que es (hechos y descripciones)",
|
|
"Lo que debería ser (valores y juicios)",
|
|
"Solo matemáticas económicas",
|
|
"Únicamente historia económica"
|
|
],
|
|
correcta: 0,
|
|
explicacion: "La economía positiva describe y explica hechos objetivos ('lo que es'), sin hacer juicios de valor."
|
|
},
|
|
{
|
|
id: 5,
|
|
pregunta: "Complete: La economía normativa se refiere a...",
|
|
opciones: [
|
|
"Juicios de valor sobre lo que debería ser",
|
|
"Datos estadísticos objetivos",
|
|
"Teorías matemáticas puras",
|
|
"Hechos históricos verificables"
|
|
],
|
|
correcta: 0,
|
|
explicacion: "La economía normativa hace juicios de valor y prescripciones sobre lo que debería ser ('deberíamos aumentar los impuestos')."
|
|
}
|
|
];
|
|
|
|
export function DefinicionEconomiaQuiz({ ejercicioId: _ejercicioId, onComplete }: EjercicioProps) {
|
|
const [preguntaActual, setPreguntaActual] = useState(0);
|
|
const [respuestas, setRespuestas] = useState<number[]>([]);
|
|
const [mostrarResultado, setMostrarResultado] = useState(false);
|
|
const [completado, setCompletado] = useState(false);
|
|
|
|
const pregunta = PREGUNTAS[preguntaActual];
|
|
const esUltima = preguntaActual === PREGUNTAS.length - 1;
|
|
|
|
const handleRespuesta = (index: number) => {
|
|
const nuevasRespuestas = [...respuestas, index];
|
|
setRespuestas(nuevasRespuestas);
|
|
|
|
if (esUltima) {
|
|
// Calcular puntuación
|
|
const correctas = nuevasRespuestas.filter((r, i) => r === PREGUNTAS[i].correcta).length;
|
|
const puntuacion = Math.round((correctas / PREGUNTAS.length) * 100);
|
|
setCompletado(true);
|
|
onComplete?.(puntuacion);
|
|
} else {
|
|
setMostrarResultado(true);
|
|
}
|
|
};
|
|
|
|
const handleSiguiente = () => {
|
|
setPreguntaActual(prev => prev + 1);
|
|
setMostrarResultado(false);
|
|
};
|
|
|
|
const esCorrecta = respuestas[preguntaActual] === pregunta.correcta;
|
|
|
|
if (completado) {
|
|
const correctas = respuestas.filter((r, i) => r === PREGUNTAS[i].correcta).length;
|
|
const puntuacion = Math.round((correctas / PREGUNTAS.length) * 100);
|
|
|
|
return (
|
|
<Card className="w-full max-w-2xl mx-auto text-center p-8">
|
|
<motion.div
|
|
initial={{ scale: 0 }}
|
|
animate={{ scale: 1 }}
|
|
className="mb-6"
|
|
>
|
|
<div className="w-20 h-20 bg-green-100 rounded-full flex items-center justify-center mx-auto">
|
|
<CheckCircle className="w-10 h-10 text-green-600" />
|
|
</div>
|
|
</motion.div>
|
|
|
|
<h3 className="text-2xl font-bold text-gray-900 mb-2">¡Quiz Completado!</h3>
|
|
<p className="text-gray-600 mb-6">
|
|
Respondiste {correctas} de {PREGUNTAS.length} preguntas correctamente
|
|
</p>
|
|
|
|
<div className="text-5xl font-bold text-blue-600 mb-2">{puntuacion}</div>
|
|
<p className="text-gray-500">puntos</p>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Card className="w-full max-w-2xl mx-auto">
|
|
<div className="p-6">
|
|
{/* Progress */}
|
|
<div className="mb-6">
|
|
<div className="flex justify-between text-sm text-gray-500 mb-2">
|
|
<span>Pregunta {preguntaActual + 1} de {PREGUNTAS.length}</span>
|
|
<span>{Math.round(((preguntaActual) / PREGUNTAS.length) * 100)}%</span>
|
|
</div>
|
|
<div className="w-full bg-gray-200 rounded-full h-2">
|
|
<motion.div
|
|
className="bg-blue-500 h-2 rounded-full"
|
|
initial={{ width: 0 }}
|
|
animate={{ width: `${((preguntaActual) / PREGUNTAS.length) * 100}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Pregunta */}
|
|
<h3 className="text-xl font-bold text-gray-900 mb-6">{pregunta.pregunta}</h3>
|
|
|
|
{/* Opciones */}
|
|
{!mostrarResultado ? (
|
|
<div className="space-y-3">
|
|
{pregunta.opciones.map((opcion, index) => (
|
|
<motion.button
|
|
key={index}
|
|
onClick={() => handleRespuesta(index)}
|
|
whileHover={{ scale: 1.01 }}
|
|
whileTap={{ scale: 0.99 }}
|
|
className="w-full p-4 text-left border-2 border-gray-200 rounded-xl hover:border-blue-400 hover:bg-blue-50 transition-all"
|
|
>
|
|
<span className="font-medium text-gray-700">{String.fromCharCode(65 + index)}. {opcion}</span>
|
|
</motion.button>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 10 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
className={`p-6 rounded-xl mb-6 ${esCorrecta ? 'bg-green-50 border border-green-200' : 'bg-red-50 border border-red-200'}`}
|
|
>
|
|
<div className="flex items-center gap-3 mb-3">
|
|
{esCorrecta ? (
|
|
<CheckCircle className="w-6 h-6 text-green-600" />
|
|
) : (
|
|
<XCircle className="w-6 h-6 text-red-600" />
|
|
)}
|
|
<span className={`font-bold ${esCorrecta ? 'text-green-800' : 'text-red-800'}`}>
|
|
{esCorrecta ? '¡Correcto!' : 'Incorrecto'}
|
|
</span>
|
|
</div>
|
|
<p className="text-gray-700">{pregunta.explicacion}</p>
|
|
|
|
<Button onClick={handleSiguiente} className="mt-4">
|
|
{esUltima ? 'Finalizar' : 'Siguiente'}
|
|
</Button>
|
|
</motion.div>
|
|
)}
|
|
</div>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
export default DefinicionEconomiaQuiz;
|