story-generator/src/components/dashboard/DashboardMetrics.tsx
Lucas Santana 478ca2441d
Some checks are pending
Docker Build and Push / build (push) Waiting to run
refactor: extrai componentes de métricas do dashboard
Modulariza os cards de métricas em componentes reutilizáveis:

- Cria componente MetricCard para cards individuais
- Cria componente DashboardMetrics para agrupamento
- Move configurações de métricas para constantes
- Adiciona suporte a tooltips e ícones personalizados
- Mantém responsividade e acessibilidade
- Simplifica o StudentDashboardPage

Mudanças técnicas:
- Extrai lógica de renderização para componentes dedicados
- Centraliza configuração de métricas em constantes
- Melhora tipagem com interfaces dedicadas
- Adiciona suporte a tooltips informativos
- Mantém consistência visual com o design system
- Reduz duplicação de código
2025-02-06 14:34:58 -03:00

160 lines
5.1 KiB
TypeScript

import React from 'react';
import { BookOpen, Clock, TrendingUp, Award, Mic, Target, Brain, Gauge, Pause, XCircle, HelpCircle } from 'lucide-react';
import { MetricCard } from './MetricCard';
interface DashboardMetricsData {
totalStories: number;
averageReadingFluency: number;
totalReadingTime: number;
currentLevel: number;
averagePronunciation: number;
averageAccuracy: number;
averageComprehension: number;
averageWordsPerMinute: number;
averagePauses: number;
averageErrors: number;
}
interface DashboardMetricsProps {
data: DashboardMetricsData;
className?: string;
}
const MAIN_METRICS = [
{
key: 'totalStories',
title: 'Total de Histórias',
getValue: (data: DashboardMetricsData) => data.totalStories,
icon: BookOpen,
iconColor: 'text-purple-600',
iconBgColor: 'bg-purple-100'
},
{
key: 'averageReadingFluency',
title: 'Fluência Média',
getValue: (data: DashboardMetricsData) => `${data.averageReadingFluency}%`,
icon: TrendingUp,
iconColor: 'text-green-600',
iconBgColor: 'bg-green-100'
},
{
key: 'totalReadingTime',
title: 'Tempo de Leitura',
getValue: (data: DashboardMetricsData) => `${data.totalReadingTime}min`,
icon: Clock,
iconColor: 'text-blue-600',
iconBgColor: 'bg-blue-100'
},
{
key: 'currentLevel',
title: 'Nível Atual',
getValue: (data: DashboardMetricsData) => data.currentLevel,
icon: Award,
iconColor: 'text-yellow-600',
iconBgColor: 'bg-yellow-100'
}
];
const DETAILED_METRICS = [
{
key: 'averagePronunciation',
title: 'Pronúncia Média',
getValue: (data: DashboardMetricsData) => `${data.averagePronunciation}%`,
icon: Mic,
iconColor: 'text-indigo-600',
iconBgColor: 'bg-indigo-100',
tooltip: 'Avalia a qualidade da sua pronúncia durante a leitura, considerando a clareza e correção dos sons das palavras'
},
{
key: 'averageAccuracy',
title: 'Precisão na Leitura',
getValue: (data: DashboardMetricsData) => `${data.averageAccuracy}%`,
icon: Target,
iconColor: 'text-pink-600',
iconBgColor: 'bg-pink-100',
tooltip: 'Indica o quão preciso você é ao ler as palavras, sem trocas ou omissões de letras e sílabas'
},
{
key: 'averageComprehension',
title: 'Compreensão do Texto',
getValue: (data: DashboardMetricsData) => `${data.averageComprehension}%`,
icon: Brain,
iconColor: 'text-orange-600',
iconBgColor: 'bg-orange-100',
tooltip: 'Avalia seu nível de entendimento do texto durante a leitura, baseado no ritmo e entonação adequados'
},
{
key: 'averageWordsPerMinute',
title: 'Velocidade de Leitura',
getValue: (data: DashboardMetricsData) => `${data.averageWordsPerMinute} WPM`,
icon: Gauge,
iconColor: 'text-cyan-600',
iconBgColor: 'bg-cyan-100',
tooltip: 'Média de palavras lidas por minuto (WPM), indicando a velocidade e fluidez da sua leitura'
},
{
key: 'averagePauses',
title: 'Pausas na Leitura',
getValue: (data: DashboardMetricsData) => data.averagePauses,
icon: Pause,
iconColor: 'text-amber-600',
iconBgColor: 'bg-amber-100',
tooltip: 'Média de pausas não planejadas durante a leitura, indicando momentos de hesitação'
},
{
key: 'averageErrors',
title: 'Erros de Leitura',
getValue: (data: DashboardMetricsData) => data.averageErrors,
icon: XCircle,
iconColor: 'text-red-600',
iconBgColor: 'bg-red-100',
tooltip: 'Média de erros cometidos durante a leitura, como trocas, omissões ou adições de palavras'
}
];
export function DashboardMetrics({ data, className = '' }: DashboardMetricsProps) {
return (
<div className={className}>
{/* Métricas Principais */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
{MAIN_METRICS.map(metric => (
<MetricCard
key={metric.key}
title={metric.title}
value={metric.getValue(data)}
icon={metric.icon}
iconColor={metric.iconColor}
iconBgColor={metric.iconBgColor}
/>
))}
</div>
{/* Métricas Detalhadas */}
<div className="mb-8">
<div className="flex items-center gap-2 mb-4">
<h2 className="text-lg font-semibold text-gray-900">Métricas Detalhadas de Leitura</h2>
<div
className="text-gray-400 hover:text-gray-600 cursor-help transition-colors"
title="Estas métricas são calculadas com base em todas as suas gravações de leitura, fornecendo uma visão detalhada do seu progresso"
>
<HelpCircle className="h-4 w-4" />
</div>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{DETAILED_METRICS.map(metric => (
<MetricCard
key={metric.key}
title={metric.title}
value={metric.getValue(data)}
icon={metric.icon}
iconColor={metric.iconColor}
iconBgColor={metric.iconBgColor}
tooltip={metric.tooltip}
/>
))}
</div>
</div>
</div>
);
}