story-generator/src/pages/student-dashboard/PhonicsProgressPage.tsx
Lucas Santana f37f8f2f6d
Some checks are pending
Docker Build and Push / build (push) Waiting to run
fix: corrige tipos e queries dos hooks de exercícios fônicos
- Corrige tipo de retorno em useExerciseWords
- Ajusta usePhonicsExercises para filtrar por categoria
- Atualiza queries para usar inner join e ordenação
- Adiciona interfaces para melhor tipagem
- Corrige convenção de nomes para snake_case
2025-01-18 06:53:24 -03:00

113 lines
4.1 KiB
TypeScript

import { usePhonicsProgress } from "@/hooks/phonics/usePhonicsProgress";
import { usePhonicsExercises } from "@/hooks/phonics/usePhonicsExercises";
import { useAuth } from "@/hooks/useAuth";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Progress } from "@/components/ui/progress";
import { Star, Trophy } from "lucide-react";
export function PhonicsProgressPage() {
const { user } = useAuth();
const { data: progress } = usePhonicsProgress(user?.id || "");
const { data: exercises } = usePhonicsExercises();
if (!user || !progress || !exercises) return null;
const totalExercises = exercises.length;
const completedExercises = progress.filter(p => p.completed).length;
const totalStars = progress.reduce((acc, p) => acc + p.stars, 0);
const totalXP = progress.reduce((acc, p) => acc + p.xp_earned, 0);
const completionRate = (completedExercises / totalExercises) * 100;
return (
<div className="container py-6 space-y-8">
<div className="space-y-2">
<h1 className="text-2xl font-bold">Seu Progresso</h1>
<p className="text-muted-foreground">
Acompanhe seu desenvolvimento nos exercícios fônicos
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<Card>
<CardHeader>
<CardTitle className="text-lg">Exercícios Completados</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-2">
<div className="text-3xl font-bold">
{completedExercises} / {totalExercises}
</div>
<Progress value={completionRate} className="h-2" />
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-lg">Estrelas Conquistadas</CardTitle>
</CardHeader>
<CardContent>
<div className="flex items-center gap-2">
<Star className="w-8 h-8 text-yellow-400 fill-yellow-400" />
<span className="text-3xl font-bold">{totalStars}</span>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-lg">XP Total</CardTitle>
</CardHeader>
<CardContent>
<div className="flex items-center gap-2">
<Trophy className="w-8 h-8 text-purple-500" />
<span className="text-3xl font-bold">{totalXP}</span>
</div>
</CardContent>
</Card>
</div>
<Card>
<CardHeader>
<CardTitle>Histórico de Exercícios</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-4">
{exercises.map((exercise) => {
const exerciseProgress = progress.find(p => p.exercise_id === exercise.id);
const progressValue = exerciseProgress ? exerciseProgress.best_score * 100 : 0;
return (
<div key={exercise.id} className="flex items-center gap-4">
<div className="flex-1">
<div className="font-medium">{exercise.title}</div>
<div className="text-sm text-muted-foreground">
{exerciseProgress?.completed ? "Completo" : "Pendente"}
</div>
</div>
<div className="flex items-center gap-2">
{Array.from({ length: 3 }).map((_, i) => (
<Star
key={i}
className={`w-4 h-4 ${
i < (exerciseProgress?.stars || 0)
? "text-yellow-400 fill-yellow-400"
: "text-gray-300"
}`}
/>
))}
</div>
<div className="w-32">
<Progress value={progressValue} className="h-2" />
</div>
</div>
);
})}
</div>
</CardContent>
</Card>
</div>
);
}