mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-18 06:17:56 +00:00
refactor: Refatorando estilo da Essay Analysis
This commit is contained in:
parent
ccbac66d28
commit
8b45fe72e7
@ -12,13 +12,13 @@ const Progress = React.forwardRef<
|
|||||||
<ProgressPrimitive.Root
|
<ProgressPrimitive.Root
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative h-4 w-full overflow-hidden rounded-full bg-secondary",
|
"relative h-4 w-full overflow-hidden rounded-full bg-gray-200",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<ProgressPrimitive.Indicator
|
<ProgressPrimitive.Indicator
|
||||||
className="h-full w-full flex-1 bg-primary transition-all"
|
className="h-full w-full flex-1 bg-purple-600 transition-all"
|
||||||
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
||||||
/>
|
/>
|
||||||
</ProgressPrimitive.Root>
|
</ProgressPrimitive.Root>
|
||||||
|
|||||||
@ -40,6 +40,32 @@ interface Essay {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface EssayAnalysisData {
|
||||||
|
id: string;
|
||||||
|
essay_id: string;
|
||||||
|
overall_score: number;
|
||||||
|
suggestions: string;
|
||||||
|
created_at: string;
|
||||||
|
feedback: Array<{
|
||||||
|
structure_feedback: string;
|
||||||
|
content_feedback: string;
|
||||||
|
language_feedback: string;
|
||||||
|
}>;
|
||||||
|
strengths: Array<{
|
||||||
|
strength: string;
|
||||||
|
}>;
|
||||||
|
improvements: Array<{
|
||||||
|
improvement: string;
|
||||||
|
}>;
|
||||||
|
scores: Array<{
|
||||||
|
adequacy: number;
|
||||||
|
coherence: number;
|
||||||
|
cohesion: number;
|
||||||
|
vocabulary: number;
|
||||||
|
grammar: number;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
export function EssayAnalysis() {
|
export function EssayAnalysis() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@ -70,16 +96,57 @@ export function EssayAnalysis() {
|
|||||||
setEssay(essayData);
|
setEssay(essayData);
|
||||||
|
|
||||||
// Carregar análise
|
// Carregar análise
|
||||||
const { data: analysisData, error: analysisError } = await supabase
|
const { data, error: analysisError } = await supabase
|
||||||
.from('essay_analyses')
|
.from('essay_analyses')
|
||||||
.select('*')
|
.select(`
|
||||||
|
*,
|
||||||
|
feedback:essay_analysis_feedback(
|
||||||
|
structure_feedback,
|
||||||
|
content_feedback,
|
||||||
|
language_feedback
|
||||||
|
),
|
||||||
|
strengths:essay_analysis_strengths(
|
||||||
|
strength
|
||||||
|
),
|
||||||
|
improvements:essay_analysis_improvements(
|
||||||
|
improvement
|
||||||
|
),
|
||||||
|
scores:essay_analysis_scores(
|
||||||
|
adequacy,
|
||||||
|
coherence,
|
||||||
|
cohesion,
|
||||||
|
vocabulary,
|
||||||
|
grammar
|
||||||
|
)
|
||||||
|
`)
|
||||||
.eq('essay_id', id)
|
.eq('essay_id', id)
|
||||||
.order('created_at', { ascending: false })
|
.order('created_at', { ascending: false })
|
||||||
.limit(1)
|
.limit(1)
|
||||||
.single();
|
.single();
|
||||||
|
|
||||||
if (analysisError) throw analysisError;
|
if (analysisError) throw analysisError;
|
||||||
setAnalysis(analysisData);
|
|
||||||
|
// Transformar os dados para o formato esperado
|
||||||
|
const analysisData = data as EssayAnalysisData;
|
||||||
|
const analysis: EssayAnalysis = {
|
||||||
|
...analysisData,
|
||||||
|
feedback: {
|
||||||
|
structure: analysisData.feedback[0]?.structure_feedback || '',
|
||||||
|
content: analysisData.feedback[0]?.content_feedback || '',
|
||||||
|
language: analysisData.feedback[0]?.language_feedback || ''
|
||||||
|
},
|
||||||
|
strengths: analysisData.strengths?.map((s: { strength: string }) => s.strength) || [],
|
||||||
|
improvements: analysisData.improvements?.map((i: { improvement: string }) => i.improvement) || [],
|
||||||
|
criteria_scores: {
|
||||||
|
adequacy: analysisData.scores[0]?.adequacy || 0,
|
||||||
|
coherence: analysisData.scores[0]?.coherence || 0,
|
||||||
|
cohesion: analysisData.scores[0]?.cohesion || 0,
|
||||||
|
vocabulary: analysisData.scores[0]?.vocabulary || 0,
|
||||||
|
grammar: analysisData.scores[0]?.grammar || 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setAnalysis(analysis);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Erro ao carregar dados:', error);
|
console.error('Erro ao carregar dados:', error);
|
||||||
} finally {
|
} finally {
|
||||||
@ -93,158 +160,150 @@ export function EssayAnalysis() {
|
|||||||
return (
|
return (
|
||||||
<div className="container mx-auto p-6">
|
<div className="container mx-auto p-6">
|
||||||
<div className="flex items-center gap-4 mb-6">
|
<div className="flex items-center gap-4 mb-6">
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={() => navigate('/aluno/redacoes')}
|
onClick={() => navigate('/aluno/redacoes')}
|
||||||
className="text-purple-600 hover:text-purple-700"
|
className="flex items-center gap-2 text-gray-600 hover:text-gray-900"
|
||||||
trackingId="essay-analysis-back-to-list-button"
|
trackingId="essay-analysis-back-to-list-button"
|
||||||
>
|
>
|
||||||
<ArrowLeft className="mr-2 h-4 w-4" />
|
<ArrowLeft className="h-5 w-5" />
|
||||||
Voltar para lista de redações
|
Voltar para redações
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
</div>
|
||||||
variant="ghost"
|
|
||||||
onClick={() => navigate(`/aluno/redacoes/${id}`)}
|
<div className="bg-white rounded-xl shadow-sm border border-gray-200 p-6 space-y-6">
|
||||||
className="text-gray-600 hover:text-gray-900"
|
{/* Título e Tipo */}
|
||||||
trackingId="essay-analysis-back-to-essay-button"
|
<div className="border-b border-gray-200 pb-6">
|
||||||
>
|
<h1 className="text-2xl font-bold text-gray-900">{essay.title}</h1>
|
||||||
<ArrowLeft className="mr-2 h-4 w-4" />
|
<p className="text-gray-500 mt-1">
|
||||||
Voltar para redação
|
|
||||||
</Button>
|
|
||||||
<div>
|
|
||||||
<h1 className="text-3xl font-bold">{essay.title}</h1>
|
|
||||||
<p className="text-muted-foreground">
|
|
||||||
{essay.essay_type.title} • {essay.essay_genre.title}
|
{essay.essay_type.title} • {essay.essay_genre.title}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
{/* Grid de Cards */}
|
||||||
{/* Pontuação Geral */}
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
<Card>
|
{/* Pontuação Geral */}
|
||||||
<CardHeader>
|
<Card className="bg-purple-50 border-purple-100">
|
||||||
<CardTitle>Pontuação Geral</CardTitle>
|
<CardContent className="pt-6">
|
||||||
</CardHeader>
|
<div className="flex items-center justify-center">
|
||||||
<CardContent>
|
<div className="text-6xl font-bold text-purple-600">{analysis.overall_score}</div>
|
||||||
<div className="flex items-center justify-center">
|
<div className="text-2xl text-purple-600 ml-2">/100</div>
|
||||||
<div className="text-6xl font-bold text-primary">
|
|
||||||
{analysis.overall_score}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="text-2xl ml-1">/100</div>
|
<p className="text-center text-gray-600 mt-2">Pontuação Geral</p>
|
||||||
</div>
|
</CardContent>
|
||||||
</CardContent>
|
</Card>
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Pontos Fortes */}
|
{/* Pontos Fortes */}
|
||||||
<Card>
|
<Card className="bg-green-50 border-green-100">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2">
|
<CardTitle className="flex items-center gap-2 text-green-600">
|
||||||
<CheckCircle2 className="h-5 w-5 text-success" />
|
<CheckCircle2 className="h-5 w-5" />
|
||||||
Pontos Fortes
|
Pontos Fortes
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<ul className="list-disc list-inside space-y-2">
|
<ul className="list-disc list-inside space-y-2">
|
||||||
{analysis.strengths.map((strength, index) => (
|
{analysis.strengths.map((strength, index) => (
|
||||||
<li key={index} className="text-success">{strength}</li>
|
<li key={index} className="text-green-600">{strength}</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Pontos a Melhorar */}
|
{/* Pontos a Melhorar */}
|
||||||
<Card>
|
<Card className="bg-orange-50 border-orange-100">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2">
|
<CardTitle className="flex items-center gap-2 text-orange-600">
|
||||||
<XCircle className="h-5 w-5 text-destructive" />
|
<XCircle className="h-5 w-5" />
|
||||||
Pontos a Melhorar
|
Pontos a Melhorar
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<ul className="list-disc list-inside space-y-2">
|
<ul className="list-disc list-inside space-y-2">
|
||||||
{analysis.improvements.map((improvement, index) => (
|
{analysis.improvements.map((improvement, index) => (
|
||||||
<li key={index} className="text-destructive">{improvement}</li>
|
<li key={index} className="text-orange-600">{improvement}</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Feedback Detalhado */}
|
{/* Feedback Detalhado */}
|
||||||
<Card className="md:col-span-2">
|
<Card className="md:col-span-2 border-gray-200">
|
||||||
<CardHeader>
|
<CardHeader className="border-b border-gray-200">
|
||||||
<CardTitle>Feedback Detalhado</CardTitle>
|
<CardTitle>Feedback Detalhado</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4 pt-4">
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-semibold mb-2">Estrutura</h4>
|
<h4 className="font-semibold mb-2 text-gray-900">Estrutura</h4>
|
||||||
<p className="text-muted-foreground">{analysis.feedback.structure}</p>
|
<p className="text-gray-600">{analysis.feedback.structure}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-semibold mb-2">Conteúdo</h4>
|
<h4 className="font-semibold mb-2 text-gray-900">Conteúdo</h4>
|
||||||
<p className="text-muted-foreground">{analysis.feedback.content}</p>
|
<p className="text-gray-600">{analysis.feedback.content}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-semibold mb-2">Linguagem</h4>
|
<h4 className="font-semibold mb-2 text-gray-900">Linguagem</h4>
|
||||||
<p className="text-muted-foreground">{analysis.feedback.language}</p>
|
<p className="text-gray-600">{analysis.feedback.language}</p>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Critérios de Avaliação */}
|
{/* Critérios de Avaliação */}
|
||||||
<Card>
|
<Card className="border-gray-200">
|
||||||
<CardHeader>
|
<CardHeader className="border-b border-gray-200">
|
||||||
<CardTitle>Critérios de Avaliação</CardTitle>
|
<CardTitle>Critérios de Avaliação</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4 pt-4">
|
||||||
<div>
|
<div>
|
||||||
<div className="flex justify-between mb-1">
|
<div className="flex justify-between mb-1">
|
||||||
<span>Adequação ao Gênero</span>
|
<span className="text-gray-600">Adequação ao Gênero</span>
|
||||||
<span>{analysis.criteria_scores.adequacy}%</span>
|
<span className="font-medium">{analysis.criteria_scores.adequacy}%</span>
|
||||||
|
</div>
|
||||||
|
<Progress value={analysis.criteria_scores.adequacy} className="h-2" />
|
||||||
</div>
|
</div>
|
||||||
<Progress value={analysis.criteria_scores.adequacy} />
|
<div>
|
||||||
</div>
|
<div className="flex justify-between mb-1">
|
||||||
<div>
|
<span className="text-gray-600">Coerência</span>
|
||||||
<div className="flex justify-between mb-1">
|
<span className="font-medium">{analysis.criteria_scores.coherence}%</span>
|
||||||
<span>Coerência</span>
|
</div>
|
||||||
<span>{analysis.criteria_scores.coherence}%</span>
|
<Progress value={analysis.criteria_scores.coherence} className="h-2" />
|
||||||
</div>
|
</div>
|
||||||
<Progress value={analysis.criteria_scores.coherence} />
|
<div>
|
||||||
</div>
|
<div className="flex justify-between mb-1">
|
||||||
<div>
|
<span className="text-gray-600">Coesão</span>
|
||||||
<div className="flex justify-between mb-1">
|
<span className="font-medium">{analysis.criteria_scores.cohesion}%</span>
|
||||||
<span>Coesão</span>
|
</div>
|
||||||
<span>{analysis.criteria_scores.cohesion}%</span>
|
<Progress value={analysis.criteria_scores.cohesion} className="h-2" />
|
||||||
</div>
|
</div>
|
||||||
<Progress value={analysis.criteria_scores.cohesion} />
|
<div>
|
||||||
</div>
|
<div className="flex justify-between mb-1">
|
||||||
<div>
|
<span className="text-gray-600">Vocabulário</span>
|
||||||
<div className="flex justify-between mb-1">
|
<span className="font-medium">{analysis.criteria_scores.vocabulary}%</span>
|
||||||
<span>Vocabulário</span>
|
</div>
|
||||||
<span>{analysis.criteria_scores.vocabulary}%</span>
|
<Progress value={analysis.criteria_scores.vocabulary} className="h-2" />
|
||||||
</div>
|
</div>
|
||||||
<Progress value={analysis.criteria_scores.vocabulary} />
|
<div>
|
||||||
</div>
|
<div className="flex justify-between mb-1">
|
||||||
<div>
|
<span className="text-gray-600">Gramática</span>
|
||||||
<div className="flex justify-between mb-1">
|
<span className="font-medium">{analysis.criteria_scores.grammar}%</span>
|
||||||
<span>Gramática</span>
|
</div>
|
||||||
<span>{analysis.criteria_scores.grammar}%</span>
|
<Progress value={analysis.criteria_scores.grammar} className="h-2" />
|
||||||
</div>
|
</div>
|
||||||
<Progress value={analysis.criteria_scores.grammar} />
|
</CardContent>
|
||||||
</div>
|
</Card>
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Sugestões */}
|
{/* Sugestões */}
|
||||||
<Card className="md:col-span-3">
|
<Card className="md:col-span-3 bg-blue-50 border-blue-100">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Sugestões para Melhoria</CardTitle>
|
<CardTitle className="text-blue-600">Sugestões para Melhoria</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<p className="text-muted-foreground whitespace-pre-line">
|
<p className="text-gray-600 whitespace-pre-line">
|
||||||
{analysis.suggestions}
|
{analysis.suggestions}
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user