%# app/views/dashboard/index.html.erb %>
<%# Fase 3: Dashboard com cards, gráfico Chart.js e cálculo ao vivo %>
<%# Não cachear no Turbo: o snapshot congelava o gráfico/calendário (DOM já
<%# alterado pelo JS, sem reexecutar scripts) e só voltava com F5. %>
<% content_for :head do %>
<%# Flatpickr — CSS no
(evita flash sem estilo) + tema escuro oficial %>
<%# Header + filtro por faixa de datas %>
Dashboard
<%= @periodo_inicio.strftime('%d/%m/%Y') %> – <%= @periodo_fim.strftime('%d/%m/%Y') %>
· Atualizado às <%= Time.now.strftime('%H:%M') %>
<%# Filtro de calendário — seleciona uma faixa de datas %>
<%# CARDS GRANDES — KPIs
auto-fit + minmax em vez de `xl:grid-cols-5`: o breakpoint xl olha a JANELA
(1280px), mas com a sidebar aberta sobram ~960px de conteúdo — 5 colunas de
~176px, e "R$ 82.692,00" em text-4xl era cortado pelo overflow-hidden do
card. Com auto-fit o número de colunas cai sozinho quando o menu está
aberto e sobe quando ele é recolhido, sem depender de breakpoint. %>
<%# Card 1: Valor estimado — sempre 2 faixas: é o maior número da tela %>
<%= icone :dinheiro, cor: nil, espaco: false %> Valor Estimado
<%# break-words: se ainda faltar espaço, quebra a linha em vez de cortar %>
<%= moeda(@valor_estimado) %>
<%# "Atendidas" = concluídas + falhadas (motorista foi ao local e fechou
a visita). É a mesma base que a consolidação paga, por isso o rótulo
NÃO pode voltar a dizer "concluídas": o valor acima inclui as falhas. %>
<%= @entregas_atendidas %> entregas atendidas
<%= @entregas_pagas %> concluídas · <%= @entregas_falhadas %> falhadas
<%# Card destacado: total consolidado e pago (consolidações finalizadas do período) %>
<%= icone :consolidado_pago, espaco: false %> Consolidado / Pago
<%= moeda(@fin_custo_total) %>
consolidado no período
<%= moeda(@fin_pago) %>
pago
<%# Card 2: Total de entregas %>
<%= icone :consolidacoes, espaco: false %> Total Entregas
<%= @total_entregas %>
<%= @entregas_pagas %> entregues
·
<%= @entregas_pendentes %> pendentes
·
<%= @entregas_falhadas %> falhadas
<%# Card 3: Consolidações %>
<%= icone :planilha, espaco: false %> Consolidações
<%= @consolidacoes_mes.count %>
<%= @consolidacoes_abertas %> abertas
·
<%= @consolidacoes_fechadas %> fechadas
<%# Card 4: Motoristas ativos %>
<%= icone :veiculo, espaco: false %> Motoristas
<%= @motoristas.count %>
com entregas no período
<%# KPIs FINANCEIROS (consolidações finalizadas, já com filtro de operação) %>
<%= icone :dinheiro, espaco: false %> Custo total
<%= moeda(@fin_custo_total) %>
<%= @fin_qtd_entregas %> entregas classificadas
<%= icone :ticket, espaco: false %> Ticket médio
<%= moeda(@fin_ticket_medio) %>
por entrega
<%= icone :sucesso, cor: 'text-green-500', espaco: false %> Pago
<%= moeda(@fin_pago) %>
já confirmado
<%= icone :relogio, cor: 'text-amber-400', espaco: false %> A pagar
<%= moeda(@fin_pendente) %>
pendente
<%# GRÁFICO + MOTORISTAS (lado a lado no desktop) %>
<%# Gráficos diários (Chart.js) — flex-col p/ preencher a altura do card de motoristas %>
Evolução do custo
Valor estimado por dia no período<%= ' · operação filtrada' if @operacao_filtro.present? %>
Valor (R$)
<%# Pagamentos por dia (fluxo de caixa) — quando o dinheiro saiu de fato %>
Pagamentos por dia
Valor pago aos motoristas por data de pagamento
<% if @pag_pago_qtd.positive? %>
Pago no dia
Acumulado
<% end %>
<% if @pag_pago_qtd.positive? %>
<% else %>
<%= icone :custo, tamanho: 'w-8 h-8', cor: 'text-gray-600', espaco: false %>
Nenhum pagamento realizado neste período
<% if @pag_pend_valor.positive? %>
<%= moeda(@pag_pend_valor) %>
aguardando pagamento (<%= @pag_pend_qtd %> motorista(s))
<% end %>
<% end %>
<%# Top motoristas %>
<%= icone :ranking, espaco: false %> Motoristas
<% if @motoristas.any? %>
<% @motoristas.each_with_index do |m, i| %>
<%= i + 1 %>
<%= m[:nome] %>
<%= moeda(m[:valor]) %>
<%# Barra de progresso %>
<% max = @motoristas.first[:entregas].to_f %>
<%= m[:entregas] %> entregas
<% end %>
<% else %>
<%= icone :caminhao, tamanho: 'w-8 h-8', cor: 'text-gray-600', espaco: false %>
Nenhuma entrega concluída neste período
<% end %>
<%# ── FINANCEIRO POR OPERAÇÃO ───────────────────────────── %>
<%# Custo por operação (barra) %>
<%= icone :tag, espaco: false %> Custo por operação
Valor consolidado no período
<% if @fin_por_operacao.any? %>
<% else %>
<%= icone :tag, tamanho: 'w-8 h-8', cor: 'text-gray-600', espaco: false %>
Sem dados no período
<% end %>
<%# Composição por tipo (rosca) %>
<%= icone :composicao, espaco: false %> Composição do custo
Por tipo de lançamento
<% if @fin_por_tipo.any? %>
<% else %>
<%= icone :composicao, tamanho: 'w-8 h-8', cor: 'text-gray-600', espaco: false %>
Sem dados no período
<% end %>
<%# Custo por motorista (barra) %>
<%= icone :pessoa, espaco: false %> Custo por motorista
Por motorista no período
<% if @fin_por_motorista.any? %>
<% else %>
<%= icone :pessoa, tamanho: 'w-8 h-8', cor: 'text-gray-600', espaco: false %>
Sem dados no período
<% end %>
<%# ── PAGAMENTOS (pago x pendente) ──────────────────────── %>
<%# Rosca pago vs a pagar (por valor) %>
<%= icone :pagamento, espaco: false %> Pagamentos
Pagos por data de pagamento · pendentes no período
<% if (@pag_pago_qtd + @pag_pend_qtd).zero? %>
<%= icone :nota_fiscal, tamanho: 'w-8 h-8', cor: 'text-gray-600', espaco: false %>
Nenhum pagamento ou pendência no período
<% else %>
● Pago no período
<%= moeda(@pag_pago_valor) %> · <%= @pag_pago_qtd %> pagamento(s)
● A pagar
<%= moeda(@pag_pend_valor) %> · <%= @pag_pend_qtd %> motorista(s)
<% end %>
<%# Tabelas: pagamentos realizados (com data) + pendentes %>
<%# Pagamentos realizados no período (filtrados por pago_em) %>
<%= icone :sucesso, cor: 'text-green-500', espaco: false %> Pagamentos realizados no período
<% if @pagamentos_feitos.any? %>
| Pago em |
Motorista |
Consolidação |
Forma |
Valor |
<% @pagamentos_feitos.each do |cm| %>
| <%= l cm.pago_em.to_date, format: :short %> |
<%= cm.motorista_nome %> |
<%= link_to cm.consolidacao.nome, consolidacao_path(cm.consolidacao),
class: 'text-gray-300 hover:text-orange-500' %>
|
<%= cm.forma_pagamento&.humanize || '—' %> |
<%= moeda(cm.valor_total) %> |
<% end %>
<% else %>
Nenhum pagamento realizado neste período.
<% end %>
<%# Pendentes (consolidações finalizadas do período sem pagamento) %>
<%= icone :relogio, cor: 'text-amber-400', espaco: false %> Pagamentos pendentes
<% if @pagamentos_pendentes.any? %>
| Motorista |
Consolidação |
Valor |
<% @pagamentos_pendentes.each do |cm| %>
| <%= cm.motorista_nome %> |
<%= link_to cm.consolidacao.nome, consolidacao_path(cm.consolidacao),
class: 'text-gray-300 hover:text-orange-500' %>
|
<%= moeda(cm.valor_total) %> |
<% end %>
<% else %>
Nenhuma pendência no período. <%= icone :sucesso, cor: 'text-green-500', espaco: false %>
<% end %>
<%# Por operação %>
<% if @por_operacao.any? %>
<%= icone :operacao, espaco: false %> Entregas por Local
<% total_op = @por_operacao.values.sum.to_f %>
<% @por_operacao.each do |local, qtd| %>
<%= qtd %>
<%= local.to_s.truncate(20) %>
<%= ((qtd / total_op) * 100).round %>%
<% end %>
<% end %>
<%# Flatpickr — date range picker (JS via CDN; CSS já carregado no ) %>
<%# Paginação client-side das tabelas de pagamentos (10 por página) %>
<%# Filtro de operação — submete o form ao marcar/desmarcar %>
<%# Chart.js via CDN %>
<%# Fluxo de pagamentos: barras (pago no dia) + linha (acumulado no período) %>
<%# Rosca de pagamentos (pago x a pagar, por valor) %>
<%# ── Gráficos financeiros por operação ─────────────────────── %>