Inclusão de uma tabela de acompanhamento

This commit is contained in:
2026-07-13 18:12:04 -03:00
parent bd61b32edd
commit 75d82227c9
4 changed files with 171 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
<%# app/views/operacoes_dashboard/_espelho.html.erb %>
<%# Tabela espelho da planilha da operação: uma linha por NF com resultado,
ocorrência, motorista etc. Busca textual (param q) e paginação (param pg)
são server-side; o restante da URL (modo/operação/período/cross-filters)
é preservado nos links e no form. %>
<% pg_path = ->(n) { operacoes_dashboard_path(request.query_parameters.merge('pg' => n)) } %>
<% resultado_badge = ->(status) {
if status == 'completed'
['Entregue', 'bg-green-500/10 text-green-400 border-green-500/30']
elsif Entrega::STATUS_FALHA.include?(status)
['Falha', 'bg-red-500/10 text-red-400 border-red-500/30']
else
['Pendente', 'bg-yellow-500/10 text-yellow-400 border-yellow-500/30']
end
} %>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
<div class="flex flex-wrap items-center justify-between gap-3 mb-4">
<div>
<h2 class="text-lg font-semibold text-white">📋 Planilha da operação</h2>
<p class="text-gray-400 text-sm">Espelho por NF — pesquise por nota, motorista, unidade, ocorrência, veículo...</p>
</div>
<form method="get" action="<%= operacoes_dashboard_path %>" data-turbo="false" class="flex flex-wrap items-center gap-2">
<% request.query_parameters.except('q', 'pg').each do |k, v| %>
<input type="hidden" name="<%= k %>" value="<%= v %>">
<% end %>
<div class="relative">
<span class="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-gray-500">🔎</span>
<input type="search" name="q" value="<%= @busca %>" placeholder="Pesquisar..."
class="pl-9 pr-3 py-2 bg-[#0a0a0a] border border-white/10 rounded-xl text-white text-sm
w-52 sm:w-72 focus:outline-none focus:border-orange-500 placeholder-gray-500">
</div>
<button type="submit"
class="px-3 py-2 rounded-xl text-sm bg-[#0a0a0a] border border-white/10 text-gray-300 hover:border-orange-500">
Buscar
</button>
<% if @busca.present? %>
<%= link_to '✕ Limpar', operacoes_dashboard_path(request.query_parameters.except('q', 'pg')),
data: { turbo: false }, class: 'text-xs text-orange-400 hover:text-orange-300 whitespace-nowrap' %>
<% end %>
</form>
</div>
<% if @espelho_linhas.blank? %>
<p class="text-gray-400 text-sm py-8 text-center">
<%= @busca.present? ? %(Nenhuma entrega encontrada para "#{@busca}".) : 'Nenhuma entrega para exibir.' %>
</p>
<% else %>
<div class="overflow-x-auto">
<table class="w-full text-sm whitespace-nowrap">
<thead>
<tr class="text-gray-400 text-left border-b border-white/5">
<th class="py-2 pr-3 font-medium">Data</th>
<th class="py-2 px-3 font-medium">NF</th>
<% if @modo == 'global' %>
<th class="py-2 px-3 font-medium">Operação</th>
<% end %>
<th class="py-2 px-3 font-medium">Destinatário</th>
<th class="py-2 px-3 font-medium">Unidade</th>
<th class="py-2 px-3 font-medium">Motorista</th>
<th class="py-2 px-3 font-medium">Veículo</th>
<th class="py-2 px-3 font-medium">Resultado</th>
<th class="py-2 px-3 font-medium">Ocorrência</th>
<th class="py-2 pl-3 font-medium">Status</th>
</tr>
</thead>
<tbody>
<% @espelho_linhas.each do |r| %>
<% rotulo, badge_css = resultado_badge.(r['status']) %>
<% data = r['checkout'] || r['planned_date'] %>
<% endereco = r['endereco_completo'].presence || r['address'].presence %>
<tr class="border-b border-white/5 hover:bg-white/[0.02]">
<td class="py-2.5 pr-3 text-gray-300">
<%= data.respond_to?(:strftime) ? data.strftime('%d/%m/%y %H:%M') : data.to_s.first(16) %>
</td>
<td class="py-2.5 px-3 text-white font-medium"><%= r['reference_id'] %></td>
<% if @modo == 'global' %>
<td class="py-2.5 px-3 text-gray-400"><%= r['operacao'] %></td>
<% end %>
<td class="py-2.5 px-3 text-gray-300" title="<%= endereco %>">
<%= (r['nome_completo'].presence || '—').truncate(28) %>
</td>
<td class="py-2.5 px-3 text-gray-400"><%= r['contact_name'].to_s.truncate(24).presence || '—' %></td>
<td class="py-2.5 px-3 text-gray-300"><%= r['driver'].presence || '—' %></td>
<td class="py-2.5 px-3 text-gray-400"><%= r['vehicle'].presence || '—' %></td>
<td class="py-2.5 px-3">
<span class="inline-block px-2 py-0.5 rounded-full text-xs font-semibold border <%= badge_css %>">
<%= rotulo %>
</span>
</td>
<td class="py-2.5 px-3 text-gray-400" title="<%= r['observation'] %>">
<%= r['observation'].to_s.truncate(32).presence || '—' %>
</td>
<td class="py-2.5 pl-3 text-gray-400"><%= r['status_gade'].presence || '—' %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
<%# Paginação: « 1 … janela em torno da atual … última » %>
<div class="flex flex-wrap items-center justify-between gap-2 mt-3">
<p class="text-gray-400 text-xs">
<%= (@espelho_pagina - 1) * OperacoesDashboardController::ESPELHO_POR_PAGINA + 1 %><%=
[(@espelho_pagina) * OperacoesDashboardController::ESPELHO_POR_PAGINA, @espelho_total].min %>
de <%= @espelho_total %> entregas
</p>
<% if @espelho_paginas > 1 %>
<div class="flex items-center gap-1">
<% if @espelho_pagina > 1 %>
<%= link_to '', pg_path.(@espelho_pagina - 1), data: { turbo: false },
class: 'px-3 py-1.5 rounded-lg text-xs font-semibold bg-[#0a0a0a] text-gray-400 border border-white/5 hover:text-white' %>
<% end %>
<% janela = ([1, @espelho_pagina - 2].max..[@espelho_paginas, @espelho_pagina + 2].min).to_a %>
<% paginas = ([1] + janela + [@espelho_paginas]).uniq %>
<% anterior = 0 %>
<% paginas.each do |p| %>
<% if p > anterior + 1 %>
<span class="px-1 text-gray-500 text-xs">…</span>
<% end %>
<% anterior = p %>
<% if p == @espelho_pagina %>
<span class="px-3 py-1.5 rounded-lg text-xs font-semibold bg-[#f97316] text-white"><%= p %></span>
<% else %>
<%= link_to p, pg_path.(p), data: { turbo: false },
class: 'px-3 py-1.5 rounded-lg text-xs font-semibold bg-[#0a0a0a] text-gray-400 border border-white/5 hover:text-white' %>
<% end %>
<% end %>
<% if @espelho_pagina < @espelho_paginas %>
<%= link_to '', pg_path.(@espelho_pagina + 1), data: { turbo: false },
class: 'px-3 py-1.5 rounded-lg text-xs font-semibold bg-[#0a0a0a] text-gray-400 border border-white/5 hover:text-white' %>
<% end %>
</div>
<% end %>
</div>
<% end %>
</div>