# 📊 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
```
#### 3. **Tabelas de Dados**
```html
Top Motoristas (Produtividade)
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. 📊✨