# US-ACT-007: Sistema de feedback básico **Épica:** EAI-002 - Actividades Básicas Hardcodeadas **Sprint:** Mes 1, Semana 4 **Story Points:** 5 SP **Presupuesto:** $1,800 MXN **Prioridad:** Alta (Alcance Inicial) **Estado:** ✅ Completada (Mes 1) --- ## Descripción Como **estudiante**, quiero **recibir feedback claro e inmediato al responder actividades** para **entender mis aciertos y errores de forma educativa**. **Contexto del Alcance Inicial:** Sistema centralizado de feedback para todas las mecánicas. Mensajes pre-cargados, explicaciones hardcodeadas, y animaciones simples. NO usa IA para generar feedback personalizado. --- ## Criterios de Aceptación - [ ] **CA-01:** Feedback inmediato al enviar respuesta (< 1 segundo) - [ ] **CA-02:** Mensaje "Correcto" con animación positiva (confetti, check verde) - [ ] **CA-03:** Mensaje "Incorrecto" con animación neutra (sin penalización negativa) - [ ] **CA-04:** Explicación educativa de la respuesta correcta - [ ] **CA-05:** Visualización de XP y monedas ganadas - [ ] **CA-06:** Botón para continuar a siguiente actividad - [ ] **CA-07:** Mensajes motivacionales aleatorios - [ ] **CA-08:** Feedback adaptado según tipo de actividad --- ## Especificaciones Técnicas ### Backend **Mensajes Motivacionales:** ```typescript const MOTIVATIONAL_MESSAGES = { correct: [ '¡Excelente trabajo! Sigues avanzando como un verdadero sabio maya.', '¡Correcto! Tu conocimiento crece como las pirámides mayas.', '¡Muy bien! Los antiguos mayas estarían orgullosos.', '¡Perfecto! Continúa tu camino al conocimiento.', ], incorrect: [ 'No te preocupes, cada error es una oportunidad para aprender.', 'Sigue intentando, estás en el camino correcto.', 'Aprender requiere práctica. ¡Tú puedes!', 'Los sabios mayas también comenzaron desde cero.', ] } // En el servicio class FeedbackService { generateFeedback(isCorrect: boolean, explanation: string, xpEarned: number, coinsEarned: number) { const messages = isCorrect ? MOTIVATIONAL_MESSAGES.correct : MOTIVATIONAL_MESSAGES.incorrect const randomMessage = messages[Math.floor(Math.random() * messages.length)] return { isCorrect, message: randomMessage, explanation, rewards: isCorrect ? { xp: xpEarned, coins: coinsEarned } : null } } } ``` ### Frontend **Componente de Feedback:** ```typescript // components/activities/FeedbackSection.tsx import { CheckCircleIcon, XCircleIcon } from '@heroicons/react/24/solid' import confetti from 'canvas-confetti' import { useEffect } from 'react' interface FeedbackSectionProps { feedback: { isCorrect: boolean message: string explanation: string rewards?: { xp: number, coins: number } } onContinue: () => void } export function FeedbackSection({ feedback, onContinue }: FeedbackSectionProps) { useEffect(() => { if (feedback.isCorrect) { // Animación de confetti confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }) } }, [feedback.isCorrect]) return (
{/* Icono y mensaje principal */}
{feedback.isCorrect ? ( ) : ( )}

{feedback.isCorrect ? '¡Correcto!' : 'Sigue intentando'}

{/* Mensaje motivacional */}

{feedback.message}

{/* Explicación */}

Explicación:

{feedback.explanation}

{/* Recompensas */} {feedback.rewards && (

XP Ganado

+{feedback.rewards.xp}

💰

ML Coins

+{feedback.rewards.coins}

)} {/* Botón continuar */}
) } ``` **Animaciones CSS:** ```css /* Animación de entrada del feedback */ @keyframes slideInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .feedback-enter { animation: slideInUp 0.3s ease-out; } /* Animación del check verde */ @keyframes scaleIn { 0% { transform: scale(0); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } .check-icon { animation: scaleIn 0.5s ease-out; } ``` **Toasts para notificaciones rápidas:** ```typescript // components/ui/Toast.tsx import { toast, Toaster } from 'react-hot-toast' // Uso en actividades const showSuccessToast = () => { toast.success('¡Respuesta correcta! +10 XP', { icon: '✅', duration: 3000, position: 'top-center', }) } const showErrorToast = () => { toast.error('Respuesta incorrecta. Intenta de nuevo.', { icon: '💡', duration: 3000, position: 'top-center', }) } // En App.tsx ``` --- ## Dependencias **Antes:** - US-ACT-001 a US-ACT-006 (Todas las mecánicas) - US-FUND-008 (UI/UX base) **Librería:** `canvas-confetti`, `react-hot-toast` --- ## Definición de Hecho (DoD) - [x] Componente FeedbackSection reutilizable - [x] Animaciones de confetti para respuestas correctas - [x] Mensajes motivacionales aleatorios - [x] Visualización de recompensas - [x] Toasts para notificaciones rápidas - [x] Responsive - [x] Accesible (ARIA labels) --- ## Notas del Alcance Inicial - ✅ Mensajes pre-escritos (hardcoded) - ✅ Feedback genérico para todos los usuarios - ✅ Animaciones simples (CSS + confetti) - ✅ Sin feedback personalizado con IA - ✅ Sin análisis de errores comunes - ⚠️ **Extensión futura:** EXT-020-AIFeedback (feedback personalizado con IA) - ⚠️ **Extensión futura:** EXT-021-Analytics (análisis de patrones de error) --- ## Testing ```typescript describe('FeedbackSection', () => { it('should show correct feedback for right answer') it('should show incorrect feedback for wrong answer') it('should display rewards for correct answer') it('should not display rewards for incorrect answer') it('should trigger confetti on correct answer') it('should call onContinue when button clicked') }) describe('Motivational Messages', () => { it('should return random correct message') it('should return random incorrect message') it('should not repeat same message consecutively') }) ``` --- ## Estimación **Desglose de Esfuerzo (5 SP = ~1.75 días):** - Componente FeedbackSection: 0.75 días - Animaciones: 0.25 días - Mensajes motivacionales: 0.25 días - Toasts: 0.25 días - Testing: 0.25 días **Riesgos:** - Animaciones pueden afectar performance en dispositivos lentos - Balance entre feedback positivo sin trivializar errores --- **Creado:** 2025-11-02 **Actualizado:** 2025-11-02 **Responsable:** Equipo Frontend + UX