mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-16 13:27:52 +00:00
feat: melhora layout da análise de redações com seção dedicada para competências do ENEM
Some checks are pending
Docker Build and Push / build (push) Waiting to run
Some checks are pending
Docker Build and Push / build (push) Waiting to run
- Separa critérios gerais e competências do ENEM em seções distintas - Adiciona nova seção dedicada com layout aprimorado para competências do ENEM - Melhora visualização das barras de progresso e justificativas - Inclui descrições detalhadas para cada competência - Implementa cards coloridos para melhor organização visual - Aprimora apresentação dos critérios gerais de avaliação patch: Apenas melhorias visuais, sem alterações na funcionalidade
This commit is contained in:
parent
2ff79ced53
commit
f883a6e9c2
@ -197,6 +197,15 @@ e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/).
|
||||
- Atualizada a função `analyze-essay` para salvar as notas e justificativas das competências
|
||||
- Adicionada restrição para garantir que os valores das competências estejam entre 0 e 200
|
||||
|
||||
### Modificado
|
||||
- Melhorado o layout da página de análise de redações:
|
||||
- Separação clara entre critérios gerais e competências do ENEM
|
||||
- Nova seção dedicada às competências do ENEM com layout aprimorado
|
||||
- Barras de progresso mais visíveis para as competências
|
||||
- Adicionadas descrições detalhadas para cada competência
|
||||
- Cards coloridos para justificativas das competências
|
||||
- Melhorias visuais nos critérios gerais de avaliação
|
||||
|
||||
## [1.5.0] - 2024-03-19
|
||||
|
||||
### Modificado
|
||||
|
||||
@ -17,7 +17,11 @@ interface TimeFilterOption {
|
||||
months: number | null;
|
||||
}
|
||||
|
||||
const METRICS_CONFIG: MetricConfig[] = [
|
||||
interface MetricNames {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
const WRITING_METRICS: MetricConfig[] = [
|
||||
{ key: 'score', name: 'Nota Geral', color: '#6366f1' },
|
||||
{ key: 'adequacy', name: 'Adequação', color: '#f43f5e' },
|
||||
{ key: 'coherence', name: 'Coerência', color: '#0ea5e9' },
|
||||
@ -26,6 +30,14 @@ const METRICS_CONFIG: MetricConfig[] = [
|
||||
{ key: 'grammar', name: 'Gramática', color: '#f59e0b' }
|
||||
];
|
||||
|
||||
const ENEM_METRICS: MetricConfig[] = [
|
||||
{ key: 'language_domain', name: 'Domínio da Língua', color: '#f43f5e' },
|
||||
{ key: 'proposal_comprehension', name: 'Compreensão da Proposta', color: '#0ea5e9' },
|
||||
{ key: 'argument_selection', name: 'Seleção de Argumentos', color: '#10b981' },
|
||||
{ key: 'linguistic_mechanisms', name: 'Mecanismos Linguísticos', color: '#8b5cf6' },
|
||||
{ key: 'intervention_proposal', name: 'Proposta de Intervenção', color: '#f59e0b' }
|
||||
];
|
||||
|
||||
const TIME_FILTERS: TimeFilterOption[] = [
|
||||
{ value: '3m', label: '3 meses', months: 3 },
|
||||
{ value: '6m', label: '6 meses', months: 6 },
|
||||
@ -39,13 +51,28 @@ interface WritingMetricsChartProps {
|
||||
}
|
||||
|
||||
export function WritingMetricsChart({ data = [], className = '' }: WritingMetricsChartProps) {
|
||||
const [visibleMetrics, setVisibleMetrics] = React.useState<Set<string>>(
|
||||
new Set(METRICS_CONFIG.map(metric => metric.key))
|
||||
const [visibleWritingMetrics, setVisibleWritingMetrics] = React.useState<Set<string>>(
|
||||
new Set(WRITING_METRICS.map(metric => metric.key))
|
||||
);
|
||||
const [visibleEnemMetrics, setVisibleEnemMetrics] = React.useState<Set<string>>(
|
||||
new Set(ENEM_METRICS.map(metric => metric.key))
|
||||
);
|
||||
const [timeFilter, setTimeFilter] = React.useState<TimeFilter>('12m');
|
||||
|
||||
const toggleMetric = (metricKey: string) => {
|
||||
setVisibleMetrics(prev => {
|
||||
const toggleWritingMetric = (metricKey: string) => {
|
||||
setVisibleWritingMetrics(prev => {
|
||||
const newSet = new Set(prev);
|
||||
if (newSet.has(metricKey)) {
|
||||
newSet.delete(metricKey);
|
||||
} else {
|
||||
newSet.add(metricKey);
|
||||
}
|
||||
return newSet;
|
||||
});
|
||||
};
|
||||
|
||||
const toggleEnemMetric = (metricKey: string) => {
|
||||
setVisibleEnemMetrics(prev => {
|
||||
const newSet = new Set(prev);
|
||||
if (newSet.has(metricKey)) {
|
||||
newSet.delete(metricKey);
|
||||
@ -76,13 +103,13 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
||||
|
||||
const filteredData = React.useMemo(() => filterDataByTime(data), [data, timeFilter]);
|
||||
|
||||
return (
|
||||
<div className={`bg-white rounded-xl shadow-sm border border-gray-200 p-8 ${className}`}>
|
||||
const renderChart = (title: string, description: string, metrics: MetricConfig[], visibleMetrics: Set<string>, toggleMetric: (key: string) => void) => (
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-200 p-8 mb-8">
|
||||
<div className="flex flex-col gap-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-1">
|
||||
<h2 className="text-xl font-semibold text-gray-900">Evolução da Escrita por Semana</h2>
|
||||
<p className="text-sm text-gray-500">Acompanhe seu progresso na escrita ao longo do tempo</p>
|
||||
<h2 className="text-xl font-semibold text-gray-900">{title}</h2>
|
||||
<p className="text-sm text-gray-500">{description}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
{/* Filtro de Período */}
|
||||
@ -106,7 +133,7 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
||||
</div>
|
||||
<div
|
||||
className="text-gray-400 hover:text-gray-600 cursor-help transition-colors"
|
||||
title="Gráfico mostrando a evolução das suas métricas de escrita ao longo das semanas"
|
||||
title={`Gráfico mostrando a evolução das suas ${title.toLowerCase()} ao longo das semanas`}
|
||||
>
|
||||
<HelpCircle className="h-4 w-4" />
|
||||
</div>
|
||||
@ -115,7 +142,7 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
||||
|
||||
{/* Pill Buttons */}
|
||||
<div className="flex flex-wrap gap-2 p-1">
|
||||
{METRICS_CONFIG.map(metric => (
|
||||
{metrics.map(metric => (
|
||||
<button
|
||||
key={metric.key}
|
||||
onClick={() => toggleMetric(metric.key)}
|
||||
@ -179,15 +206,9 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
||||
/>
|
||||
<Tooltip
|
||||
formatter={(value: number, name: string) => {
|
||||
const metricNames: { [key: string]: string } = {
|
||||
score: 'Nota Geral',
|
||||
adequacy: 'Adequação',
|
||||
coherence: 'Coerência',
|
||||
cohesion: 'Coesão',
|
||||
vocabulary: 'Vocabulário',
|
||||
grammar: 'Gramática',
|
||||
const metricNames: MetricNames = metrics.reduce((acc, m) => ({ ...acc, [m.key]: m.name }), {
|
||||
minutesWriting: 'Minutos Escrevendo'
|
||||
};
|
||||
});
|
||||
return [value, metricNames[name] || name];
|
||||
}}
|
||||
contentStyle={{
|
||||
@ -207,7 +228,7 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
||||
paddingBottom: '20px'
|
||||
}}
|
||||
/>
|
||||
{METRICS_CONFIG.map(metric => (
|
||||
{metrics.map(metric => (
|
||||
visibleMetrics.has(metric.key) && (
|
||||
<Line
|
||||
key={metric.key}
|
||||
@ -238,4 +259,23 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{renderChart(
|
||||
"Evolução da Escrita por Semana",
|
||||
"Acompanhe seu progresso na escrita ao longo do tempo",
|
||||
WRITING_METRICS,
|
||||
visibleWritingMetrics,
|
||||
toggleWritingMetric
|
||||
)}
|
||||
{renderChart(
|
||||
"Evolução das Competências do ENEM",
|
||||
"Acompanhe seu progresso nas competências do ENEM ao longo do tempo",
|
||||
ENEM_METRICS,
|
||||
visibleEnemMetrics,
|
||||
toggleEnemMetric
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -67,6 +67,16 @@ interface EssayAnalysis {
|
||||
content_feedback: string;
|
||||
language_feedback: string;
|
||||
}>;
|
||||
language_domain_value: number;
|
||||
language_domain_justification: string;
|
||||
proposal_comprehension_value: number;
|
||||
proposal_comprehension_justification: string;
|
||||
argument_selection_value: number;
|
||||
argument_selection_justification: string;
|
||||
linguistic_mechanisms_value: number;
|
||||
linguistic_mechanisms_justification: string;
|
||||
intervention_proposal_value: number;
|
||||
intervention_proposal_justification: string;
|
||||
}
|
||||
|
||||
interface ProcessedEssayAnalysis {
|
||||
@ -86,6 +96,28 @@ interface ProcessedEssayAnalysis {
|
||||
content_feedback: string;
|
||||
language_feedback: string;
|
||||
};
|
||||
competencies: {
|
||||
language_domain: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
proposal_comprehension: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
argument_selection: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
linguistic_mechanisms: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
intervention_proposal: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export function StudentDashboardPage() {
|
||||
@ -170,6 +202,11 @@ export function StudentDashboardPage() {
|
||||
cohesion: 0,
|
||||
vocabulary: 0,
|
||||
grammar: 0,
|
||||
language_domain: 0,
|
||||
proposal_comprehension: 0,
|
||||
argument_selection: 0,
|
||||
linguistic_mechanisms: 0,
|
||||
intervention_proposal: 0,
|
||||
minutesWriting: 0
|
||||
};
|
||||
}
|
||||
@ -181,6 +218,11 @@ export function StudentDashboardPage() {
|
||||
acc[week].cohesion += analysis.scores.cohesion;
|
||||
acc[week].vocabulary += analysis.scores.vocabulary;
|
||||
acc[week].grammar += analysis.scores.grammar;
|
||||
acc[week].language_domain += analysis.competencies.language_domain.value;
|
||||
acc[week].proposal_comprehension += analysis.competencies.proposal_comprehension.value;
|
||||
acc[week].argument_selection += analysis.competencies.argument_selection.value;
|
||||
acc[week].linguistic_mechanisms += analysis.competencies.linguistic_mechanisms.value;
|
||||
acc[week].intervention_proposal += analysis.competencies.intervention_proposal.value;
|
||||
acc[week].minutesWriting += 30; // Tempo médio estimado por redação
|
||||
|
||||
return acc;
|
||||
@ -195,6 +237,11 @@ export function StudentDashboardPage() {
|
||||
cohesion: Math.round(data.cohesion / data.count),
|
||||
vocabulary: Math.round(data.vocabulary / data.count),
|
||||
grammar: Math.round(data.grammar / data.count),
|
||||
language_domain: Math.round(data.language_domain / data.count),
|
||||
proposal_comprehension: Math.round(data.proposal_comprehension / data.count),
|
||||
argument_selection: Math.round(data.argument_selection / data.count),
|
||||
linguistic_mechanisms: Math.round(data.linguistic_mechanisms / data.count),
|
||||
intervention_proposal: Math.round(data.intervention_proposal / data.count),
|
||||
minutesWriting: data.minutesWriting
|
||||
}))
|
||||
.sort((a, b) => a.week.localeCompare(b.week));
|
||||
@ -342,7 +389,17 @@ export function StudentDashboardPage() {
|
||||
structure_feedback,
|
||||
content_feedback,
|
||||
language_feedback
|
||||
)
|
||||
),
|
||||
language_domain_value,
|
||||
language_domain_justification,
|
||||
proposal_comprehension_value,
|
||||
proposal_comprehension_justification,
|
||||
argument_selection_value,
|
||||
argument_selection_justification,
|
||||
linguistic_mechanisms_value,
|
||||
linguistic_mechanisms_justification,
|
||||
intervention_proposal_value,
|
||||
intervention_proposal_justification
|
||||
)
|
||||
`)
|
||||
.eq('student_id', session.user.id)
|
||||
@ -373,6 +430,28 @@ export function StudentDashboardPage() {
|
||||
structure_feedback: analysis.essay_analysis_feedback?.[0]?.structure_feedback || '',
|
||||
content_feedback: analysis.essay_analysis_feedback?.[0]?.content_feedback || '',
|
||||
language_feedback: analysis.essay_analysis_feedback?.[0]?.language_feedback || ''
|
||||
},
|
||||
competencies: {
|
||||
language_domain: {
|
||||
value: analysis.language_domain_value || 0,
|
||||
justification: analysis.language_domain_justification || ''
|
||||
},
|
||||
proposal_comprehension: {
|
||||
value: analysis.proposal_comprehension_value || 0,
|
||||
justification: analysis.proposal_comprehension_justification || ''
|
||||
},
|
||||
argument_selection: {
|
||||
value: analysis.argument_selection_value || 0,
|
||||
justification: analysis.argument_selection_justification || ''
|
||||
},
|
||||
linguistic_mechanisms: {
|
||||
value: analysis.linguistic_mechanisms_value || 0,
|
||||
justification: analysis.linguistic_mechanisms_justification || ''
|
||||
},
|
||||
intervention_proposal: {
|
||||
value: analysis.intervention_proposal_value || 0,
|
||||
justification: analysis.intervention_proposal_justification || ''
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
@ -389,14 +468,24 @@ export function StudentDashboardPage() {
|
||||
coherence: acc.coherence + (analysis.scores?.coherence || 0),
|
||||
cohesion: acc.cohesion + (analysis.scores?.cohesion || 0),
|
||||
vocabulary: acc.vocabulary + (analysis.scores?.vocabulary || 0),
|
||||
grammar: acc.grammar + (analysis.scores?.grammar || 0)
|
||||
grammar: acc.grammar + (analysis.scores?.grammar || 0),
|
||||
language_domain: acc.language_domain + (analysis.competencies?.language_domain?.value || 0),
|
||||
proposal_comprehension: acc.proposal_comprehension + (analysis.competencies?.proposal_comprehension?.value || 0),
|
||||
argument_selection: acc.argument_selection + (analysis.competencies?.argument_selection?.value || 0),
|
||||
linguistic_mechanisms: acc.linguistic_mechanisms + (analysis.competencies?.linguistic_mechanisms?.value || 0),
|
||||
intervention_proposal: acc.intervention_proposal + (analysis.competencies?.intervention_proposal?.value || 0)
|
||||
}), {
|
||||
score: 0,
|
||||
adequacy: 0,
|
||||
coherence: 0,
|
||||
cohesion: 0,
|
||||
vocabulary: 0,
|
||||
grammar: 0
|
||||
grammar: 0,
|
||||
language_domain: 0,
|
||||
proposal_comprehension: 0,
|
||||
argument_selection: 0,
|
||||
linguistic_mechanisms: 0,
|
||||
intervention_proposal: 0
|
||||
});
|
||||
|
||||
console.log('Soma das métricas:', metricsSum);
|
||||
@ -412,7 +501,12 @@ export function StudentDashboardPage() {
|
||||
averageCoherence: Math.round(metricsSum.coherence / totalAnalyses),
|
||||
averageCohesion: Math.round(metricsSum.cohesion / totalAnalyses),
|
||||
averageVocabulary: Math.round(metricsSum.vocabulary / totalAnalyses),
|
||||
averageGrammar: Math.round(metricsSum.grammar / totalAnalyses)
|
||||
averageGrammar: Math.round(metricsSum.grammar / totalAnalyses),
|
||||
averageLanguageDomain: Math.round(metricsSum.language_domain / totalAnalyses),
|
||||
averageProposalComprehension: Math.round(metricsSum.proposal_comprehension / totalAnalyses),
|
||||
averageArgumentSelection: Math.round(metricsSum.argument_selection / totalAnalyses),
|
||||
averageLinguisticMechanisms: Math.round(metricsSum.linguistic_mechanisms / totalAnalyses),
|
||||
averageInterventionProposal: Math.round(metricsSum.intervention_proposal / totalAnalyses)
|
||||
};
|
||||
|
||||
console.log('Métricas de escrita calculadas:', writingMetrics);
|
||||
@ -543,72 +637,6 @@ export function StudentDashboardPage() {
|
||||
{/* Gráfico de Evolução da Escrita */}
|
||||
<WritingMetricsChart data={weeklyMetrics.writing} className="mb-8" />
|
||||
</div>
|
||||
|
||||
{/* Histórias Recentes */}
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold text-gray-900">Histórias Recentes</h2>
|
||||
<button
|
||||
onClick={() => navigate('/aluno/historias')}
|
||||
className="flex items-center gap-2 text-purple-600 hover:text-purple-700"
|
||||
>
|
||||
Ver todas
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{recentStories.length === 0 ? (
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-200 p-12 text-center">
|
||||
<BookOpen className="h-12 w-12 text-gray-400 mx-auto mb-4" />
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-2">
|
||||
Nenhuma história ainda
|
||||
</h3>
|
||||
<p className="text-gray-500 mb-6">
|
||||
Comece sua jornada criando sua primeira história!
|
||||
</p>
|
||||
<button
|
||||
onClick={() => navigate('/aluno/historias/nova')}
|
||||
className="inline-flex items-center gap-2 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition"
|
||||
>
|
||||
<Plus className="h-5 w-5" />
|
||||
Criar História
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{recentStories.map((story) => (
|
||||
<div
|
||||
key={story.id}
|
||||
className="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden cursor-pointer hover:shadow-md transition"
|
||||
onClick={() => navigate(`/aluno/historias/${story.id}`)}
|
||||
>
|
||||
{story.cover && (
|
||||
<div className="relative aspect-video">
|
||||
<img
|
||||
src={`${story.cover.image_url}?width=400&height=300&quality=80&format=webp`}
|
||||
alt={story.title}
|
||||
className="w-full h-48 object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="p-6">
|
||||
<h3 className="font-medium text-gray-900 mb-2">{story.title}</h3>
|
||||
<div className="flex items-center justify-between text-sm text-gray-500">
|
||||
<span>{new Date(story.created_at).toLocaleDateString()}</span>
|
||||
<span className={`px-2 py-1 rounded-full text-xs font-medium ${
|
||||
story.status === 'published'
|
||||
? 'bg-green-100 text-green-800'
|
||||
: 'bg-yellow-100 text-yellow-800'
|
||||
}`}>
|
||||
{story.status === 'published' ? 'Publicada' : 'Rascunho'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -3,7 +3,7 @@ import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { ArrowLeft, CheckCircle2, XCircle } from 'lucide-react';
|
||||
import { ArrowLeft, CheckCircle2, XCircle, BookOpen, Brain, MessageSquare, Puzzle, Target } from 'lucide-react';
|
||||
import { Progress } from '@/components/ui/progress';
|
||||
|
||||
interface EssayAnalysis {
|
||||
@ -25,6 +25,28 @@ interface EssayAnalysis {
|
||||
vocabulary: number;
|
||||
grammar: number;
|
||||
};
|
||||
competencies: {
|
||||
language_domain: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
proposal_comprehension: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
argument_selection: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
linguistic_mechanisms: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
intervention_proposal: {
|
||||
value: number;
|
||||
justification: string;
|
||||
};
|
||||
};
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
@ -64,6 +86,16 @@ interface EssayAnalysisData {
|
||||
vocabulary: number;
|
||||
grammar: number;
|
||||
}>;
|
||||
language_domain_value: number;
|
||||
language_domain_justification: string;
|
||||
proposal_comprehension_value: number;
|
||||
proposal_comprehension_justification: string;
|
||||
argument_selection_value: number;
|
||||
argument_selection_justification: string;
|
||||
linguistic_mechanisms_value: number;
|
||||
linguistic_mechanisms_justification: string;
|
||||
intervention_proposal_value: number;
|
||||
intervention_proposal_justification: string;
|
||||
}
|
||||
|
||||
export function EssayAnalysis() {
|
||||
@ -117,7 +149,17 @@ export function EssayAnalysis() {
|
||||
cohesion,
|
||||
vocabulary,
|
||||
grammar
|
||||
)
|
||||
),
|
||||
language_domain_value,
|
||||
language_domain_justification,
|
||||
proposal_comprehension_value,
|
||||
proposal_comprehension_justification,
|
||||
argument_selection_value,
|
||||
argument_selection_justification,
|
||||
linguistic_mechanisms_value,
|
||||
linguistic_mechanisms_justification,
|
||||
intervention_proposal_value,
|
||||
intervention_proposal_justification
|
||||
`)
|
||||
.eq('essay_id', id)
|
||||
.order('created_at', { ascending: false })
|
||||
@ -143,6 +185,28 @@ export function EssayAnalysis() {
|
||||
cohesion: analysisData.scores[0]?.cohesion || 0,
|
||||
vocabulary: analysisData.scores[0]?.vocabulary || 0,
|
||||
grammar: analysisData.scores[0]?.grammar || 0
|
||||
},
|
||||
competencies: {
|
||||
language_domain: {
|
||||
value: analysisData.language_domain_value || 0,
|
||||
justification: analysisData.language_domain_justification || ''
|
||||
},
|
||||
proposal_comprehension: {
|
||||
value: analysisData.proposal_comprehension_value || 0,
|
||||
justification: analysisData.proposal_comprehension_justification || ''
|
||||
},
|
||||
argument_selection: {
|
||||
value: analysisData.argument_selection_value || 0,
|
||||
justification: analysisData.argument_selection_justification || ''
|
||||
},
|
||||
linguistic_mechanisms: {
|
||||
value: analysisData.linguistic_mechanisms_value || 0,
|
||||
justification: analysisData.linguistic_mechanisms_justification || ''
|
||||
},
|
||||
intervention_proposal: {
|
||||
value: analysisData.intervention_proposal_value || 0,
|
||||
justification: analysisData.intervention_proposal_justification || ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -305,6 +369,107 @@ export function EssayAnalysis() {
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Nova seção de Competências do ENEM */}
|
||||
<div className="mt-8 bg-white rounded-xl shadow-sm border border-gray-200 p-6">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-6">Competências do ENEM</h2>
|
||||
<div className="grid grid-cols-1 gap-8">
|
||||
{/* Competência 1 */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<BookOpen className="h-6 w-6 text-purple-600" />
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-gray-900">Competência 1: Domínio da Língua</h3>
|
||||
<p className="text-sm text-gray-500">Demonstrar domínio da modalidade escrita formal da Língua Portuguesa</p>
|
||||
</div>
|
||||
<div className="ml-auto">
|
||||
<span className="text-2xl font-bold text-purple-600">{analysis.competencies.language_domain.value}</span>
|
||||
<span className="text-gray-500">/200</span>
|
||||
</div>
|
||||
</div>
|
||||
<Progress value={(analysis.competencies.language_domain.value / 200) * 100} className="h-3" />
|
||||
<p className="text-gray-600 bg-purple-50 rounded-lg p-4 border border-purple-100">
|
||||
{analysis.competencies.language_domain.justification}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Competência 2 */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Brain className="h-6 w-6 text-blue-600" />
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-gray-900">Competência 2: Compreensão da Proposta</h3>
|
||||
<p className="text-sm text-gray-500">Compreender a proposta de redação e aplicar conceitos das várias áreas de conhecimento</p>
|
||||
</div>
|
||||
<div className="ml-auto">
|
||||
<span className="text-2xl font-bold text-blue-600">{analysis.competencies.proposal_comprehension.value}</span>
|
||||
<span className="text-gray-500">/200</span>
|
||||
</div>
|
||||
</div>
|
||||
<Progress value={(analysis.competencies.proposal_comprehension.value / 200) * 100} className="h-3" />
|
||||
<p className="text-gray-600 bg-blue-50 rounded-lg p-4 border border-blue-100">
|
||||
{analysis.competencies.proposal_comprehension.justification}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Competência 3 */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<MessageSquare className="h-6 w-6 text-green-600" />
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-gray-900">Competência 3: Seleção de Argumentos</h3>
|
||||
<p className="text-sm text-gray-500">Selecionar, relacionar, organizar e interpretar informações, fatos, opiniões e argumentos</p>
|
||||
</div>
|
||||
<div className="ml-auto">
|
||||
<span className="text-2xl font-bold text-green-600">{analysis.competencies.argument_selection.value}</span>
|
||||
<span className="text-gray-500">/200</span>
|
||||
</div>
|
||||
</div>
|
||||
<Progress value={(analysis.competencies.argument_selection.value / 200) * 100} className="h-3" />
|
||||
<p className="text-gray-600 bg-green-50 rounded-lg p-4 border border-green-100">
|
||||
{analysis.competencies.argument_selection.justification}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Competência 4 */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Puzzle className="h-6 w-6 text-orange-600" />
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-gray-900">Competência 4: Mecanismos Linguísticos</h3>
|
||||
<p className="text-sm text-gray-500">Demonstrar conhecimento dos mecanismos linguísticos necessários para a construção da argumentação</p>
|
||||
</div>
|
||||
<div className="ml-auto">
|
||||
<span className="text-2xl font-bold text-orange-600">{analysis.competencies.linguistic_mechanisms.value}</span>
|
||||
<span className="text-gray-500">/200</span>
|
||||
</div>
|
||||
</div>
|
||||
<Progress value={(analysis.competencies.linguistic_mechanisms.value / 200) * 100} className="h-3" />
|
||||
<p className="text-gray-600 bg-orange-50 rounded-lg p-4 border border-orange-100">
|
||||
{analysis.competencies.linguistic_mechanisms.justification}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Competência 5 */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Target className="h-6 w-6 text-red-600" />
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-gray-900">Competência 5: Proposta de Intervenção</h3>
|
||||
<p className="text-sm text-gray-500">Elaborar proposta de intervenção para o problema abordado</p>
|
||||
</div>
|
||||
<div className="ml-auto">
|
||||
<span className="text-2xl font-bold text-red-600">{analysis.competencies.intervention_proposal.value}</span>
|
||||
<span className="text-gray-500">/200</span>
|
||||
</div>
|
||||
</div>
|
||||
<Progress value={(analysis.competencies.intervention_proposal.value / 200) * 100} className="h-3" />
|
||||
<p className="text-gray-600 bg-red-50 rounded-lg p-4 border border-red-100">
|
||||
{analysis.competencies.intervention_proposal.justification}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -21,6 +21,11 @@ export interface WritingMetrics {
|
||||
averageCohesion: number;
|
||||
averageVocabulary: number;
|
||||
averageGrammar: number;
|
||||
averageLanguageDomain: number;
|
||||
averageProposalComprehension: number;
|
||||
averageArgumentSelection: number;
|
||||
averageLinguisticMechanisms: number;
|
||||
averageInterventionProposal: number;
|
||||
}
|
||||
|
||||
export interface WeeklyReadingMetrics {
|
||||
@ -43,6 +48,11 @@ export interface WeeklyWritingMetrics {
|
||||
cohesion: number;
|
||||
vocabulary: number;
|
||||
grammar: number;
|
||||
language_domain: number;
|
||||
proposal_comprehension: number;
|
||||
argument_selection: number;
|
||||
linguistic_mechanisms: number;
|
||||
intervention_proposal: number;
|
||||
minutesWriting: number;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user