import { useState, useEffect } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Progress } from "@/components/ui/progress"; import { useUpdatePhonicsProgress } from "@/hooks/phonics/usePhonicsProgress"; import { ExerciseFactory } from "./exercises/ExerciseFactory"; import { Timer } from "lucide-react"; import type { PhonicsExercise, UpdateProgressParams } from "@/types/phonics"; import { cn } from "@/lib/utils"; interface ExercisePlayerProps { exercise: PhonicsExercise; student_id: string; onComplete: (result: { score: number; stars: number; xp_earned: number; completed: boolean; }) => void; onExit: () => void; } export function ExercisePlayer({ exercise, student_id, onComplete, onExit }: ExercisePlayerProps) { const [currentStep, setCurrentStep] = useState(0); const [score, setScore] = useState(0); const [timeSpent, setTimeSpent] = useState(0); const [showFeedback, setShowFeedback] = useState(false); const [lastAnswerCorrect, setLastAnswerCorrect] = useState(null); const updateProgress = useUpdatePhonicsProgress(); useEffect(() => { const timer = setInterval(() => { setTimeSpent((prev) => prev + 1); }, 1000); return () => clearInterval(timer); }, []); const handleAnswer = async (word: string, isCorrect: boolean) => { setLastAnswerCorrect(isCorrect); setShowFeedback(true); if (isCorrect) { setScore((prev) => prev + 1); } // Aguardar feedback antes de prosseguir await new Promise(resolve => setTimeout(resolve, 1500)); setShowFeedback(false); // Filtra apenas as palavras corretas const correctWords = exercise.words?.filter(w => w.is_correct_answer) || []; if (currentStep < correctWords.length - 1) { setCurrentStep((prev) => prev + 1); } else { handleComplete(); } }; const handleComplete = async () => { // Filtra apenas as palavras corretas const correctWords = exercise.words?.filter(w => w.is_correct_answer) || []; const finalScore = score / correctWords.length; const stars = Math.ceil(finalScore * 3); const xp_earned = Math.round(finalScore * exercise.points); const completed = finalScore >= exercise.required_score; const updateParams: UpdateProgressParams = { student_id, exercise_id: exercise.id, best_score: finalScore, last_score: finalScore, completed, stars, xp_earned, time_spent_seconds: timeSpent, correct_answers_count: score, total_answers_count: correctWords.length }; await updateProgress.mutateAsync(updateParams); onComplete({ score: finalScore, stars, xp_earned, completed }); }; if (!exercise.words?.length) { return (
Carregando exercício...
); } // Filtra apenas as palavras corretas e ordena por order_index const correctWords = exercise.words .filter(w => w.is_correct_answer) .sort((a, b) => (a.order_index || 0) - (b.order_index || 0)); // Pega a palavra atual const currentWord = correctWords[currentStep]; // Pega as opções (incluindo a palavra correta) const options = exercise.words .filter(w => w.order_index === currentWord.order_index) .map(w => w.word) .sort(() => Math.random() - 0.5); const progress = ((currentStep + 1) / correctWords.length) * 100; return (
{exercise.title}
{Math.floor(timeSpent / 60)}:{(timeSpent % 60).toString().padStart(2, '0')}
Exercício {currentStep + 1} de {correctWords.length}
{showFeedback && (
{lastAnswerCorrect ? "Muito bem!" : "Tente novamente na próxima!"}
)}
); }