# 📊 Dashboard ERP SAAS PraFrota ## Sistema de Indicadores e KPIs para Gestão de Frota --- ## 🎯 Visão Geral O Dashboard PraFrota é o centro de controle operacional que oferece visibilidade completa sobre a performance da frota, eficiência das rotas, custos operacionais e indicadores financeiros em tempo real. --- ## 📈 KPIs Estratégicos por Categoria ### 🚚 **1. OPERACIONAL - Frota e Veículos** #### 📊 KPIs Principais: - **Taxa de Utilização da Frota** - `(Veículos em Operação / Total de Veículos) × 100` - Meta: > 85% - Período: Tempo real, diário, mensal - **Disponibilidade Operacional** - `(Veículos Disponíveis / Total de Veículos) × 100` - Meta: > 90% - Exclui: Manutenção, acidentes, licenciamento - **Tempo Médio de Inatividade** - Média de horas paradas por veículo - Meta: < 2 horas/dia - Inclui: Manutenção preventiva/corretiva - **Quilometragem por Veículo** - KM rodados por período - Comparativo: Planejado vs Realizado - Análise de eficiência por modelo/ano #### 📊 Widgets Visuais: ```typescript interface FleetKPIs { totalVehicles: number; activeVehicles: number; maintenanceVehicles: number; availableVehicles: number; utilizationRate: number; averageKmPerVehicle: number; fuelEfficiencyAverage: number; } ``` ### 🛣️ **2. LOGÍSTICA - Rotas e Entregas** #### 📊 KPIs Principais: - **Taxa de Conclusão de Rotas** - `(Rotas Completadas / Total de Rotas) × 100` - Meta: > 95% - Segmentação: Por tipo (First Mile, Line Haul, Last Mile) - **Pontualidade de Entregas** - `(Entregas no Prazo / Total de Entregas) × 100` - Meta: > 90% - SLA por tipo de cliente - **Tempo Médio de Rota** - Comparativo: Planejado vs Realizado - Análise por distância e tipo de carga - Identificação de gargalos - **Taxa de Ocupação de Carga** - `(Peso/Volume Transportado / Capacidade Total) × 100` - Meta: > 80% - Otimização de carregamento - **Rotas em Atraso** - Quantidade e percentual de rotas atrasadas - Tempo médio de atraso - Principais causas identificadas #### 📊 Widgets Visuais: ```typescript interface RoutesKPIs { totalRoutes: number; completedRoutes: number; inProgressRoutes: number; delayedRoutes: number; completionRate: number; onTimeDeliveryRate: number; averageRouteTime: number; loadUtilizationRate: number; } ``` ### 💰 **3. FINANCEIRO - Custos e Receitas** #### 📊 KPIs Principais: - **Custo por Quilômetro** - `(Custos Totais / KM Rodados)` - Segmentação: Combustível, manutenção, pneus, pedágio - Comparativo mensal e anual - **Receita por Rota** - Valor médio faturado por entrega - Margem de contribuição por tipo de rota - Análise de rentabilidade por cliente - **ROI da Frota** - `(Receita - Custos) / Investimento × 100` - Por veículo e por período - Análise de payback - **Custo de Combustível** - Consumo médio por veículo - Variação de preços por região - Eficiência energética - **Custos de Manutenção** - Preventiva vs Corretiva - Custo por veículo/km - Previsão de gastos #### 📊 Widgets Visuais: ```typescript interface FinancialKPIs { totalRevenue: number; totalCosts: number; profitMargin: number; costPerKm: number; revenuePerRoute: number; fuelCosts: number; maintenanceCosts: number; fleetROI: number; } ``` ### 👨‍💼 **4. RECURSOS HUMANOS - Motoristas** #### 📊 KPIs Principais: - **Produtividade por Motorista** - Entregas realizadas por período - KM rodados por motorista - Tempo de trabalho efetivo - **Taxa de Acidentes** - `(Acidentes / KM Rodados) × 1.000.000` - Custo médio por acidente - Análise de causas principais - **Pontuação de Condução** - Score baseado em telemetria - Velocidade, frenagem, aceleração - Ranking de motoristas - **Horas Extras** - Percentual sobre horas normais - Custo adicional de HE - Planejamento vs realizado #### 📊 Widgets Visuais: ```typescript interface DriversKPIs { totalDrivers: number; activeDrivers: number; averageProductivity: number; accidentRate: number; averageDrivingScore: number; overtimeHours: number; trainingCompliance: number; } ``` --- ## 🎨 Layout do Dashboard ### 📱 **Estrutura Responsiva (4 Colunas → 2 → 1)** ```scss .dashboard-container { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; padding: 20px; @media (max-width: 1200px) { grid-template-columns: repeat(2, 1fr); } @media (max-width: 768px) { grid-template-columns: 1fr; } } ``` ### 🎯 **Seções do Dashboard** #### 1. **Header com Resumo Executivo** ```html

Frota Ativa

{{ activeFleetCount }}/{{ totalFleetCount }}
+5.2%

Rotas Hoje

{{ todayRoutesCompleted }}/{{ todayRoutesTotal }}

Receita Mensal

{{ monthlyRevenue | currency:'BRL' }}
Meta: {{ monthlyTarget | currency:'BRL' }}
``` #### 2. **Gráficos Operacionais** ```html

Utilização da Frota

Em Operação ({{ activeVehicles }}) Manutenção ({{ maintenanceVehicles }}) Parados ({{ idleVehicles }})

Performance de Rotas (7 dias)

Custos Operacionais

Rotas Ativas

``` #### 3. **Tabelas de Dados** ```html

Top Motoristas (Produtividade)

Motorista Entregas KM Score
{{ driver.name }} {{ driver.deliveries }} {{ driver.kilometers }} {{ driver.score }}

Rotas em Atraso

Rota Motorista Destino Atraso Ação
{{ route.routeNumber }} {{ route.driverName }} {{ route.destination }} {{ route.delayMinutes }}min
``` #### 4. **Alertas e Notificações** ```html
{{ alert.title }}

{{ alert.message }}

{{ alert.timestamp | date:'dd/MM/yyyy HH:mm' }}
``` --- ## 🔧 Implementação Técnica ### 📊 **Dashboard Component** ```typescript @Component({ selector: 'app-dashboard', standalone: true, imports: [CommonModule, GoogleMapsModule, NgChartsModule], templateUrl: './dashboard.component.html', styleUrl: './dashboard.component.scss' }) export class DashboardComponent implements OnInit, OnDestroy { // KPIs Data fleetKPIs: FleetKPIs = {}; routesKPIs: RoutesKPIs = {}; financialKPIs: FinancialKPIs = {}; driversKPIs: DriversKPIs = {}; // Charts Data fleetUtilizationData: ChartData = {}; routesPerformanceData: ChartData = {}; costsBreakdownData: ChartData = {}; // Tables Data topDrivers: Driver[] = []; delayedRoutes: Route[] = []; criticalAlerts: Alert[] = []; // Real-time Updates private updateInterval: any; private websocketConnection: WebSocketSubject; constructor( private dashboardService: DashboardService, private websocketService: WebSocketService, private cdr: ChangeDetectorRef ) {} ngOnInit() { this.loadDashboardData(); this.setupRealTimeUpdates(); this.startPeriodicUpdates(); } ngOnDestroy() { if (this.updateInterval) { clearInterval(this.updateInterval); } this.websocketConnection?.complete(); } private loadDashboardData() { forkJoin({ fleet: this.dashboardService.getFleetKPIs(), routes: this.dashboardService.getRoutesKPIs(), financial: this.dashboardService.getFinancialKPIs(), drivers: this.dashboardService.getDriversKPIs(), alerts: this.dashboardService.getCriticalAlerts() }).subscribe({ next: (data) => { this.fleetKPIs = data.fleet; this.routesKPIs = data.routes; this.financialKPIs = data.financial; this.driversKPIs = data.drivers; this.criticalAlerts = data.alerts; this.updateCharts(); this.cdr.detectChanges(); }, error: (error) => { console.error('Erro ao carregar dashboard:', error); this.loadFallbackData(); } }); } private setupRealTimeUpdates() { this.websocketConnection = this.websocketService.connect('/dashboard-updates'); this.websocketConnection.subscribe({ next: (update) => { this.handleRealTimeUpdate(update); }, error: (error) => { console.error('WebSocket error:', error); } }); } private handleRealTimeUpdate(update: any) { switch (update.type) { case 'ROUTE_STATUS_CHANGE': this.updateRouteStatus(update.data); break; case 'VEHICLE_STATUS_CHANGE': this.updateVehicleStatus(update.data); break; case 'NEW_ALERT': this.addAlert(update.data); break; case 'KPI_UPDATE': this.updateKPIs(update.data); break; } this.cdr.detectChanges(); } private startPeriodicUpdates() { // Atualizar dados a cada 5 minutos this.updateInterval = setInterval(() => { this.loadDashboardData(); }, 5 * 60 * 1000); } // Métodos de utilidade getTrendClass(kpi: string): string { // Lógica para determinar se trend é positivo/negativo return 'trend-positive'; // ou 'trend-negative' } getScoreClass(score: number): string { if (score >= 90) return 'score-excellent'; if (score >= 80) return 'score-good'; if (score >= 70) return 'score-average'; return 'score-poor'; } getAlertIcon(type: string): string { const icons = { 'MAINTENANCE': 'fa-wrench', 'DELAY': 'fa-clock', 'ACCIDENT': 'fa-exclamation-triangle', 'FUEL': 'fa-gas-pump', 'ROUTE': 'fa-route' }; return icons[type] || 'fa-info-circle'; } // Ações do usuário contactDriver(route: Route) { // Implementar contato com motorista } resolveAlert(alert: Alert) { // Implementar resolução de alerta } refreshData() { this.loadDashboardData(); } } ``` ### 📊 **Dashboard Service** ```typescript @Injectable({ providedIn: 'root' }) export class DashboardService { private apiUrl = `${environment.apiUrl}/dashboard`; constructor(private http: HttpClient) {} getFleetKPIs(): Observable { return this.http.get(`${this.apiUrl}/fleet-kpis`); } getRoutesKPIs(): Observable { return this.http.get(`${this.apiUrl}/routes-kpis`); } getFinancialKPIs(): Observable { return this.http.get(`${this.apiUrl}/financial-kpis`); } getDriversKPIs(): Observable { return this.http.get(`${this.apiUrl}/drivers-kpis`); } getCriticalAlerts(): Observable { return this.http.get(`${this.apiUrl}/alerts`); } // Dados históricos para gráficos getHistoricalData(period: string): Observable { return this.http.get(`${this.apiUrl}/historical/${period}`); } } ``` --- ## 📊 Dados Mockados para Desenvolvimento ### 🎯 **KPIs Mock Data** ```json { "fleetKPIs": { "totalVehicles": 45, "activeVehicles": 38, "maintenanceVehicles": 4, "availableVehicles": 3, "utilizationRate": 84.4, "averageKmPerVehicle": 287.5, "fuelEfficiencyAverage": 8.2 }, "routesKPIs": { "totalRoutes": 156, "completedRoutes": 142, "inProgressRoutes": 12, "delayedRoutes": 2, "completionRate": 91.0, "onTimeDeliveryRate": 87.2, "averageRouteTime": 4.7, "loadUtilizationRate": 78.9 }, "financialKPIs": { "totalRevenue": 487650.00, "totalCosts": 312420.00, "profitMargin": 35.9, "costPerKm": 2.85, "revenuePerRoute": 3126.28, "fuelCosts": 89450.00, "maintenanceCosts": 45780.00, "fleetROI": 24.7 }, "driversKPIs": { "totalDrivers": 52, "activeDrivers": 38, "averageProductivity": 8.7, "accidentRate": 0.12, "averageDrivingScore": 82.5, "overtimeHours": 156.5, "trainingCompliance": 94.2 } } ``` --- ## 🎨 Estilos CSS ```scss .dashboard-container { padding: 20px; background: #f8f9fa; min-height: 100vh; .executive-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 16px; margin-bottom: 24px; .kpi-card { background: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); border-left: 4px solid #007bff; &.highlight { border-left-color: #28a745; } h3 { font-size: 14px; color: #6c757d; margin-bottom: 8px; text-transform: uppercase; } .value { font-size: 28px; font-weight: bold; color: #212529; margin-bottom: 8px; } .trend { font-size: 12px; font-weight: 500; &.trend-positive { color: #28a745; } &.trend-negative { color: #dc3545; } } .progress-bar { width: 100%; height: 6px; background: #e9ecef; border-radius: 3px; overflow: hidden; .progress { height: 100%; background: #28a745; transition: width 0.3s ease; } } } } .charts-section { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 16px; margin-bottom: 24px; .chart-card { background: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); h4 { margin-bottom: 16px; color: #212529; } &.map-card { .map-container { height: 300px; border-radius: 4px; overflow: hidden; } } } } .data-tables-section { display: grid; grid-template-columns: repeat(auto-fit, minmax(500px, 1fr)); gap: 16px; margin-bottom: 24px; .table-card { background: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); table { width: 100%; border-collapse: collapse; th, td { padding: 12px 8px; text-align: left; border-bottom: 1px solid #e9ecef; } th { background: #f8f9fa; font-weight: 600; color: #495057; } .score-badge { padding: 4px 8px; border-radius: 12px; font-size: 12px; font-weight: 500; &.score-excellent { background: #d4edda; color: #155724; } &.score-good { background: #cce5ff; color: #004085; } &.score-average { background: #fff3cd; color: #856404; } &.score-poor { background: #f8d7da; color: #721c24; } } .delayed-row { background: #fff3cd; .delay-time { color: #856404; font-weight: 600; } } } } } .alerts-section { .alert-card { background: white; border-radius: 8px; padding: 16px; margin-bottom: 12px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); display: flex; align-items: center; gap: 16px; &.alert-critical { border-left: 4px solid #dc3545; } &.alert-warning { border-left: 4px solid #ffc107; } &.alert-info { border-left: 4px solid #17a2b8; } .alert-icon { font-size: 24px; color: #6c757d; } .alert-content { flex: 1; h5 { margin-bottom: 4px; color: #212529; } p { margin-bottom: 4px; color: #6c757d; } small { color: #adb5bd; } } } } } // Responsividade @media (max-width: 768px) { .dashboard-container { padding: 12px; .charts-section, .data-tables-section { grid-template-columns: 1fr; } .executive-summary { grid-template-columns: 1fr; } } } ``` --- ## 🚀 Próximos Passos ### 1. **Implementação por Fases** - **Fase 1**: KPIs básicos + gráficos simples - **Fase 2**: Mapa em tempo real + alertas - **Fase 3**: Machine Learning para previsões - **Fase 4**: Dashboards personalizáveis por usuário ### 2. **Integrações Necessárias** - WebSocket para dados em tempo real - Google Maps API para visualização - Chart.js ou D3.js para gráficos - Push notifications para alertas críticos ### 3. **Otimizações de Performance** - Cache de dados com TTL - Lazy loading de componentes - Paginação server-side - Compressão de dados WebSocket --- ## 📱 Configuração no Sidebar ```typescript // Adicionar ao menu principal { id: 'dashboard', label: 'Dashboard', icon: 'fa-tachometer-alt', route: '/dashboard', order: 1, // Primeiro item do menu permissions: ['DASHBOARD_VIEW'] } ``` Este dashboard fornece uma visão 360° da operação, permitindo tomada de decisões baseada em dados e monitoramento proativo da performance da frota. 📊✨