Imṕlantação do dash board de acompanhamento diario das entregas

This commit is contained in:
2026-06-29 20:04:32 -03:00
parent 16032be620
commit 11531479f8
35 changed files with 848 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
<%# locals: metricas (Analytics::OperacaoMetricas), titulo (opcional) %>
<% titulo = local_assigns[:titulo] %>
<% ins = metricas.insucessos_pct %>
<% pd = metricas.por_dia %>
<div class="space-y-4">
<% if titulo.present? %>
<div class="flex items-center justify-between">
<h2 class="text-lg font-bold text-white"><%= titulo %></h2>
<span class="text-xs text-gray-500"><%= metricas.total %> entregas</span>
</div>
<% end %>
<%# ── KPIs ─────────────────────────────────────────────── %>
<div class="grid grid-cols-2 xl:grid-cols-4 gap-4">
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-2">📦 Total de Entregas</p>
<p class="text-4xl font-black text-white"><%= metricas.total %></p>
</div>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-2">✅ Total de Sucesso</p>
<p class="text-4xl font-black text-green-400"><%= metricas.sucesso %></p>
</div>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-2">❌ Total de Recusas</p>
<p class="text-4xl font-black text-red-400"><%= metricas.recusas %></p>
</div>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-2">⏳ Entregas Pendentes</p>
<p class="text-4xl font-black text-yellow-400"><%= metricas.pendentes %></p>
</div>
</div>
<%# ── Insucessos % + Índices de falha + Status ─────────── %>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-4">
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-4">Insucessos %</p>
<% if metricas.total.zero? %>
<p class="text-center py-8 text-gray-500 text-sm">Sem dados no período.</p>
<% else %>
<div class="relative h-56">
<canvas class="dash-donut"
data-completed="<%= ins[:completed] %>"
data-failed="<%= ins[:failed] %>"></canvas>
</div>
<div class="flex justify-center gap-4 mt-3 text-xs">
<span class="text-cyan-400">● Completas <%= ins[:pct_completed] %>%</span>
<span class="text-indigo-400">● Falhas <%= ins[:pct_failed] %>%</span>
</div>
<% end %>
</div>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-4">Índices de Falha</p>
<%= render 'tabela_simples',
cabecalhos: ['Observação', 'Total', '%'],
linhas: metricas.indices_falha.map { |h| [h[:observation], h[:total], "#{h[:pct]}%"] },
vazio: 'Nenhuma falha no período.' %>
</div>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-4">Por Status</p>
<%= render 'tabela_simples',
cabecalhos: ['Status', 'Quantidade'],
linhas: metricas.por_status_gade.map { |h| [h[:status], h[:total]] },
vazio: 'Sem dados.',
total: metricas.total %>
</div>
</div>
<%# ── Motoristas + STS ─────────────────────────────────── %>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-4">Notas fiscais por Motorista</p>
<div class="max-h-80 overflow-y-auto">
<%= render 'tabela_simples',
cabecalhos: ['Motorista', 'Notas fiscais'],
linhas: metricas.por_motorista.map { |h| [h[:nome], h[:total]] },
vazio: 'Sem dados.',
total: metricas.total %>
</div>
</div>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-4">Entregas por STS (Unidade)</p>
<div class="max-h-80 overflow-y-auto">
<%= render 'tabela_simples',
cabecalhos: ['Unidade', 'NFs entregues'],
linhas: metricas.por_sts.map { |h| [h[:nome], h[:total]] },
vazio: 'Sem dados.',
total: metricas.sucesso %>
</div>
</div>
</div>
<%# ── Entregas por dia ─────────────────────────────────── %>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<p class="text-gray-400 text-sm font-medium mb-4">Entregas por Dia</p>
<% if pd[:labels].empty? %>
<p class="text-center py-8 text-gray-500 text-sm">Sem dados no período.</p>
<% else %>
<div class="relative h-72">
<canvas class="dash-bars"
data-labels="<%= pd[:labels].to_json %>"
data-completed="<%= pd[:completed].to_json %>"
data-failed="<%= pd[:failed].to_json %>"></canvas>
</div>
<% end %>
</div>
</div>