@extends('layouts.app') @section('title', 'Dashboard') @section('page_title', 'Dashboard') @section('content')
{{-- Cards Superadmin / Operador --}} @hasanyrole('superadmin|operador')

Veículos Ativos

{{ $totalVeiculos }}

Motoristas Ativos

{{ $totalMotoristas }}

{{-- Solicitações aguardando --}}

Aguardando Análise

{{ $solicitacoesEnviadas ?? 0 }}

{{-- Em análise --}}

Em Análise

{{ $solicitacoesEmAnalise ?? 0 }}

{{-- Segunda linha: OS cards --}}

OS Hoje

{{ $ordensHoje ?? 0 }}

OS Programadas

{{ $ordensProgramadas ?? 0 }}

{{-- OS Em Execução --}}

OS Em Execução

{{ $ordensEmExecucao ?? 0 }}

{{-- Solicitações Em Execução --}}

Solicitações Em Execução

{{ $solicitacoesEmExecucaoOp ?? 0 }}

{{-- Seletor da visão do dashboard --}}
@if($dashboardVisao === 'operacional') Exibe a visão de execução, tempos, quilômetros, eficiência e recursos. @else Exibe a visão gerencial de volume, vínculos, rotas e distribuição histórica. @endif
@if($opStatus)@endif @if($histInicio)@endif @if($histFim)@endif
@if($dashboardVisao === 'operacional') {{-- Dashboard Operacional V2 --}}

Dashboard Operacional V2

A base selecionada combina volume e rankings; KPIs de telemetria só usam registros que realmente possuem marcos e hodômetros.

@if($opBase !== 'historica') Ver OS do Sistema → @endif
@if($histInicio)@endif @if($histFim)@endif
Mês atual
Registros considerados: @if($opBase !== 'historica')Sistema: {{ number_format($opSistemaTotal, 0, ',', '.') }}@endif @if($opBase !== 'sistema')Histórica importada: {{ number_format($opHistoricaTotal, 0, ',', '.') }}@endif @if($opBase === 'ambas')Sem duplicar as OS já copiadas para o histórico.@endif
@php $opCards = [ ['OS no período', $opTotal, 'Total filtrado'], ['Programadas', $opPorStatus['programado'] ?? 0, 'Aguardando início'], ['Em execução', $opPorStatus['em_execucao'] ?? 0, 'Viagem iniciada'], ['Concluídas', $opPorStatus['concluido'] ?? 0, 'Operação encerrada'], ['Km operação', $opKmCompletas ? number_format($opKmTotal, 1, ',', '.') . ' km' : '—', $opKmCompletas . ' OS completas'], ['Km carregado', $opKmCompletas ? number_format($opKmCarregado, 1, ',', '.') . ' km' : '—', 'Trecho produtivo'], ['Km vazio', $opKmCompletas ? number_format($opKmVazio, 1, ',', '.') . ' km' : '—', 'Antes + após carga'], ['Produtividade', $opPctProdutivo !== null ? number_format($opPctProdutivo, 1, ',', '.') . '%' : '—', $opPctVazio !== null ? number_format($opPctVazio, 1, ',', '.') . '% vazio' : 'Sem km completos'], ]; @endphp @foreach($opCards as [$titulo, $valor, $sub])

{{ $titulo }}

{{ $valor }}

{{ $sub }}

@endforeach

Volume operacional

OS por {{ $opPeriodicidade === 'dia' ? 'dia' : 'mês' }} no período selecionado.

{{ $opVolumePeriodo->sum('total') }} OS
@php $maxOpVolume = max(1, (int)($opVolumePeriodo->max('total') ?? 1)); @endphp @if($opVolumePeriodo->isNotEmpty())
@foreach($opVolumePeriodo as $p) @php $altura = max(4, round(($p['total'] / $maxOpVolume) * 100, 1)); @endphp
{{ $p['total'] }}
{{ $p['label'] }}
@endforeach
@else
Sem OS no período selecionado.
@endif

Qualidade dos dados operacionais

Cobertura necessária para indicadores confiáveis.

@php $qualidade = [ ['Timeline até saída do destino', $opTimelineCompletas], ['Km completos', $opKmCompletas], ['Com coordenada GPS', $opComGps], ['Telemetria externa', $opComTelemetriaExterna], ]; @endphp
@foreach($qualidade as [$label, $qtd]) @php $pct = $opTotal > 0 ? round(($qtd / $opTotal) * 100, 1) : 0; @endphp
{{ $label }}{{ $qtd }}/{{ $opTotal }} · {{ number_format($pct,1,',','.') }}%
@endforeach
@foreach([ ['Vazio até origem', $opMediaAteOrigem], ['Na origem', $opMediaNaOrigem], ['Trânsito carregado', $opMediaCarregado], ['No destino', $opMediaNoDestino], ['Vazio pós-destino', $opMediaPosDestino], ['Operação total', $opMediaTotal], ] as [$titulo, $minutos])

{{ $titulo }}

{{ \App\Models\OrdemServico::formatarDuracao($minutos) }}

tempo médio

@endforeach
@if($opEmExecucao->isNotEmpty())

Operações em execução

Acompanhamento rápido das viagens atualmente iniciadas no período.

Ver todas →
@foreach($opEmExecucao as $os) @endforeach
OSClienteRotaMotoristaConjuntoInício
{{ $os->numero_os }} {{ $os->cliente_solicitante ?: '—' }} {{ $os->origemLabel() }} → {{ $os->destinoLabel() }} {{ $os->motorista?->nome ?? $os->motorista_nome ?? '—' }} {{ $os->veiculo?->placa ?? $os->cavalo_placa ?? '—' }} + {{ $os->carreta?->placa ?? $os->carreta_placa ?? '—' }} {{ $os->inicio_viagem_em?->format('d/m H:i') ?? '—' }} Abrir
@endif @php $rankingOp = [ ['Clientes', $opTopClientes], ['Rotas', $opTopRotas], ['Motoristas', $opTopMotoristas], ['Cavalos', $opTopCavalos], ['Carrocerias', $opTopCarrocerias], ['Sondas / Plataformas', $opTopSondas], ]; @endphp
@foreach($rankingOp as [$titulo, $colecao]) @php $maximo = max(1, (int)($colecao->max('total') ?? 1)); @endphp

Top {{ $titulo }}

@forelse($colecao as $r) @php $w = round(($r->total / $maximo) * 100, 1); @endphp
{{ $r->label }}{{ $r->total }}
@empty

Sem dados.

@endforelse
@endforeach
@endif @if($dashboardVisao === 'historico') {{-- Dashboard gerencial baseado no histórico --}}

Dashboard gerencial — histórico operacional

Escolha a base histórica importada, os registros consolidados pelo Sistema ou ambas. Equivalências manuais continuam agrupando variantes.

@role('superadmin') Auditar histórico → @endrole
@if($opStatus)@endif
Todo período
Registros considerados: @if($histBase !== 'sistema')Histórica importada: {{ number_format($histImportados, 0, ',', '.') }}@endif @if($histBase !== 'historica')Sistema no histórico: {{ number_format($histSistema, 0, ',', '.') }}@endif
@foreach([ ['Operações', $histTotal, 'Total no período'], ['Clientes', $histClientes, 'Clientes vinculados'], ['Motoristas', $histMotoristas, 'Motoristas vinculados'], ['Rotas', $histRotas, 'Rotas vinculadas distintas'], ['Vínculo médio', number_format($histPercentualVinculo, 1, ',', '.') . '%', 'Cliente + origem + destino + motorista'], ['XLSX', $histImportados, 'Registros importados'], ['Sistema', $histSistema, 'Registros gerados pelo sistema'], ] as [$label, $valor, $sub])

{{ $label }}

{{ is_numeric($valor) ? number_format((float)$valor, 0, ',', '.') : $valor }}

{{ $sub }}

@endforeach
@php $maxMensal = max(1, (int)($histMensal->max('total') ?? 1)); $maxClientes = max(1, (int)($histTopClientes->max('total') ?? 1)); $maxRotas = max(1, (int)($histTopRotas->max('total') ?? 1)); $maxMotoristas = max(1, (int)($histTopMotoristas->max('total') ?? 1)); $maxOrigens = max(1, (int)($histTopOrigens->max('total') ?? 1)); $maxDestinos = max(1, (int)($histTopDestinos->max('total') ?? 1)); $maxStatus = max(1, (int)($histStatus->max('total') ?? 1)); $maxTipos = max(1, (int)($histTiposVeiculo->max('total') ?? 1)); @endphp

Operações por mês

Evolução do volume no período selecionado.

{{ $histMensal->count() }} mês(es)
@if($histMensal->isNotEmpty())
@foreach($histMensal as $m) @php $altura = max(4, round(($m['total'] / $maxMensal) * 100, 1)); @endphp
{{ number_format($m['total'],0,',','.') }}
{{ $m['label'] }}
@endforeach
@else
Sem dados no período selecionado.
@endif

Status das operações

Distribuição dos registros históricos.

@forelse($histStatus as $r) @php $w = round(($r->total / $maxStatus) * 100, 1); @endphp
{{ str_replace('_',' ', $r->label) }}{{ number_format($r->total,0,',','.') }}
@empty

Sem dados.

@endforelse
@foreach([ ['Top clientes', $histTopClientes, $maxClientes], ['Top rotas', $histTopRotas, $maxRotas], ['Top motoristas', $histTopMotoristas, $maxMotoristas], ] as [$titulo, $colecao, $maximo])

{{ $titulo }}

@forelse($colecao as $r) @php $w = round(($r->total / $maximo) * 100, 1); @endphp
{{ $r->label }}{{ number_format($r->total,0,',','.') }}
@empty

Sem dados.

@endforelse
@endforeach
@foreach([ ['Principais origens', $histTopOrigens, $maxOrigens], ['Principais destinos', $histTopDestinos, $maxDestinos], ['Tipos de veículo solicitados', $histTiposVeiculo, $maxTipos], ] as [$titulo, $colecao, $maximo])

{{ $titulo }}

@forelse($colecao as $r) @php $w = round(($r->total / $maximo) * 100, 1); @endphp
{{ $r->label }}{{ number_format($r->total,0,',','.') }}
@empty

Sem dados.

@endforelse
@endforeach
@endif @endhasanyrole {{-- Cards do Cliente --}} @role('cliente')

Minhas Solicitações

{{ $minhasSolicitacoes ?? 0 }}

Rascunhos

{{ $solicitacoesRascunho ?? 0 }}

Enviadas

{{ $solicitacoesEnviadas ?? 0 }}

Aprovadas

{{ $solicitacoesAprovadas ?? 0 }}

Em Execução

{{ $solicitacoesEmExecucaoCount ?? 0 }}

{{-- Solicitações Em Execução (com OS vinculadas) --}} @if(isset($solicitacoesEmExecucao) && $solicitacoesEmExecucao->isNotEmpty())

Em Execução

{{ $solicitacoesEmExecucao->count() }}
@foreach($solicitacoesEmExecucao as $solEmEx)
{{ $solEmEx->numero_solicitacao }} @if($solEmEx->assunto) — {{ $solEmEx->assunto }} @endif
Ver detalhes →
@foreach($solEmEx->itens as $itemEx)
{{ $itemEx->origemLabel() }}
{{ $itemEx->destinoLabel() }}
{{ $itemEx->data_coleta?->format('d/m/Y') }}{{ $itemEx->hora_coleta ? ' às '.$itemEx->hora_coleta : '' }}
@if($itemEx->motorista)
{{ $itemEx->motorista->nome }}
@endif @if($itemEx->veiculo)
{{ $itemEx->veiculo->placa }}
@endif @php $ibadge = ['pendente'=>'bg-gray-100 text-gray-700','confirmado'=>'bg-green-100 text-green-800','executado'=>'bg-teal-100 text-teal-800','cancelado'=>'bg-red-100 text-red-700'][$itemEx->status] ?? 'bg-gray-100 text-gray-700'; @endphp {{ $itemEx->statusLabel() }}
@endforeach
@endforeach
@endif {{-- Atalho para nova solicitação --}}

Precisa solicitar transporte?

Use o formulário digital para substituir o envio por e-mail. Criar nova solicitação →

@endrole {{-- Info box Superadmin --}} @role('superadmin')

Clientes

{{ $totalClientes }}

Usuários

{{ $totalUsuarios }}

@endrole
@endsection