From ccbac66d286610f8106cee01097b8542ee112ae6 Mon Sep 17 00:00:00 2001 From: Lucas Santana Date: Fri, 7 Feb 2025 10:32:28 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20adiciona=20novos=20recursos=20de=20form?= =?UTF-8?q?ata=C3=A7=C3=A3o=20e=20tracking=20no=20editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 30 ++ src/components/ui/editor.tsx | 63 +++- .../essays/EssayAnalysis.tsx | 316 ++++++++---------- 3 files changed, 223 insertions(+), 186 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 714a75e..d87f84a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -294,3 +294,33 @@ e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/). - Implementado feedback visual durante operações de salvamento - Otimizado carregamento inicial da redação - Adicionado tratamento de estados para diferentes status da redação + +## [0.2.0] - 2024-03-21 + +### Adicionado +- Novos recursos de formatação no editor: + - Tachado (strike-through) + - Código inline + - Lista com marcadores + - Lista numerada + - Citação (blockquote) +- Rastreamento de eventos (tracking) em todos os botões do editor + +### Modificado +- Melhorias no fluxo de redações: + - Carregamento correto do conteúdo após submissão para análise + - Salvamento automático do conteúdo antes da submissão + - Badge verde para status "analisada" + - Botão "Ver Análise" para redações analisadas + - Editor em modo somente leitura após submissão + - Contagem de palavras em todos os estados da redação + +### Técnico +- Refatoração do componente Editor para incluir novos recursos de formatação +- Adição de trackingId em todos os botões para análise de uso +- Melhorias de acessibilidade com aria-labels em português +- Refatoração do EssayPage para incluir lógica de salvamento antes da submissão para análise +- Melhoria na query do Supabase para incluir conteúdo explicitamente +- Implementação de feedback visual durante operações de salvamento +- Otimização do carregamento inicial da redação +- Adição de tratamento de estado para diferentes status da redação diff --git a/src/components/ui/editor.tsx b/src/components/ui/editor.tsx index 407c22b..d5460be 100644 --- a/src/components/ui/editor.tsx +++ b/src/components/ui/editor.tsx @@ -18,6 +18,11 @@ import { AlignCenter, AlignRight, Highlighter, + Strikethrough, + Code, + List, + ListOrdered, + Quote, } from 'lucide-react' interface EditorProps { @@ -47,6 +52,7 @@ function MenuBar({ editor }: MenuBarProps) { onClick={() => editor.chain().focus().toggleBold().run()} className={cn(editor.isActive('bold') && 'bg-muted')} aria-label="Negrito" + trackingId="editor-bold-button" > @@ -56,6 +62,7 @@ function MenuBar({ editor }: MenuBarProps) { onClick={() => editor.chain().focus().toggleItalic().run()} className={cn(editor.isActive('italic') && 'bg-muted')} aria-label="Itálico" + trackingId="editor-italic-button" > @@ -65,6 +72,7 @@ function MenuBar({ editor }: MenuBarProps) { onClick={() => editor.chain().focus().toggleUnderline().run()} className={cn(editor.isActive('underline') && 'bg-muted')} aria-label="Sublinhado" + trackingId="editor-underline-button" > @@ -74,9 +82,60 @@ function MenuBar({ editor }: MenuBarProps) { onClick={() => editor.chain().focus().toggleHighlight().run()} className={cn(editor.isActive('highlight') && 'bg-muted')} aria-label="Destacar" + trackingId="editor-highlight-button" > + + + + +
@@ -93,6 +153,7 @@ function MenuBar({ editor }: MenuBarProps) { onClick={() => editor.chain().focus().setTextAlign('center').run()} className={cn(editor.isActive({ textAlign: 'center' }) && 'bg-muted')} aria-label="Centralizar" + trackingId="editor-align-center-button" > @@ -102,6 +163,7 @@ function MenuBar({ editor }: MenuBarProps) { onClick={() => editor.chain().focus().setTextAlign('right').run()} className={cn(editor.isActive({ textAlign: 'right' }) && 'bg-muted')} aria-label="Alinhar à direita" + trackingId="editor-align-right-button" > @@ -124,7 +186,6 @@ export function Editor({ heading: false, codeBlock: false, horizontalRule: false, - table: false, }), Placeholder.configure({ placeholder, diff --git a/src/pages/student-dashboard/essays/EssayAnalysis.tsx b/src/pages/student-dashboard/essays/EssayAnalysis.tsx index 240bdb2..67cd5bc 100644 --- a/src/pages/student-dashboard/essays/EssayAnalysis.tsx +++ b/src/pages/student-dashboard/essays/EssayAnalysis.tsx @@ -3,9 +3,8 @@ 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, Loader2 } from 'lucide-react'; +import { ArrowLeft, CheckCircle2, XCircle } from 'lucide-react'; import { Progress } from '@/components/ui/progress'; -import { cn } from '@/lib/utils'; interface EssayAnalysis { id: string; @@ -73,50 +72,14 @@ export function EssayAnalysis() { // Carregar análise const { data: analysisData, error: analysisError } = await supabase .from('essay_analyses') - .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 - ) - `) + .select('*') .eq('essay_id', id) .order('created_at', { ascending: false }) .limit(1) .single(); if (analysisError) throw analysisError; - - // Transformar os dados para o formato esperado - const formattedAnalysis = { - ...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 => s.strength) || [], - improvements: analysisData.improvements?.map(i => 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(formattedAnalysis); + setAnalysis(analysisData); } catch (error) { console.error('Erro ao carregar dados:', error); } finally { @@ -124,177 +87,160 @@ export function EssayAnalysis() { } } - if (loading) { - return ( -
-
-
-
-
- {[1, 2, 3].map((i) => ( -
- ))} -
-
-
- ); - } - - if (!essay || !analysis) { - return ( -
-
-
Análise não encontrada
- -
-
- ); - } + if (loading) return
Carregando...
; + if (!essay || !analysis) return
Análise não encontrada
; return (
- {/* Cabeçalho */} -
-
- -
-

{essay.title}

-

- {essay.essay_type.title} • {essay.essay_genre.title} -

-
+
+ + +
+

{essay.title}

+

+ {essay.essay_type.title} • {essay.essay_genre.title} +

- {/* Conteúdo Principal */} -
- {/* Cartão de Pontuação */} - - -
-
- {analysis.overall_score} - /100 +
+ {/* Pontuação Geral */} + + + Pontuação Geral + + +
+
+ {analysis.overall_score}
-
Pontuação Geral
+
/100
- {/* Grid de Métricas */} -
- {/* Pontos Fortes */} - - - - - Pontos Fortes - - - -
    - {analysis.strengths.map((strength, index) => ( -
  • -
    - {strength} -
  • - ))} -
-
-
- - {/* Pontos a Melhorar */} - - - - - Pontos a Melhorar - - - -
    - {analysis.improvements.map((improvement, index) => ( -
  • -
    - {improvement} -
  • - ))} -
-
-
- - {/* Critérios de Avaliação */} - - - Critérios de Avaliação - - - {[ - { label: 'Adequação ao Gênero', value: analysis.criteria_scores.adequacy, color: 'bg-blue-500' }, - { label: 'Coerência', value: analysis.criteria_scores.coherence, color: 'bg-green-500' }, - { label: 'Coesão', value: analysis.criteria_scores.cohesion, color: 'bg-purple-500' }, - { label: 'Vocabulário', value: analysis.criteria_scores.vocabulary, color: 'bg-orange-500' }, - { label: 'Gramática', value: analysis.criteria_scores.grammar, color: 'bg-pink-500' } - ].map((criterion) => ( -
-
- {criterion.label} - {criterion.value}% -
-
-
-
-
+ {/* Pontos Fortes */} + + + + + Pontos Fortes + + + +
    + {analysis.strengths.map((strength, index) => ( +
  • {strength}
  • ))} - - -
+ +
+
+ + {/* Pontos a Melhorar */} + + + + + Pontos a Melhorar + + + +
    + {analysis.improvements.map((improvement, index) => ( +
  • {improvement}
  • + ))} +
+
+
{/* Feedback Detalhado */} - + Feedback Detalhado - -
-

Estrutura

-

{analysis.feedback.structure}

+ +
+

Estrutura

+

{analysis.feedback.structure}

-
-

Conteúdo

-

{analysis.feedback.content}

+
+

Conteúdo

+

{analysis.feedback.content}

-
-

Linguagem

-

{analysis.feedback.language}

+
+

Linguagem

+

{analysis.feedback.language}

+
+ + + + {/* Critérios de Avaliação */} + + + Critérios de Avaliação + + +
+
+ Adequação ao Gênero + {analysis.criteria_scores.adequacy}% +
+ +
+
+
+ Coerência + {analysis.criteria_scores.coherence}% +
+ +
+
+
+ Coesão + {analysis.criteria_scores.cohesion}% +
+ +
+
+
+ Vocabulário + {analysis.criteria_scores.vocabulary}% +
+ +
+
+
+ Gramática + {analysis.criteria_scores.grammar}% +
+
{/* Sugestões */} - + - Sugestões para Melhoria + Sugestões para Melhoria -

+

{analysis.suggestions}

@@ -302,4 +248,4 @@ export function EssayAnalysis() {
); -} \ No newline at end of file +} \ No newline at end of file