Files
Reem-Notas/app/views/admin/romaneios/_veiculos.html.erb
2026-08-28 16:20:29 -03:00

149 lines
8.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<%# Coluna "Veículos" — a lista INTEIRA visível, como no programa original.
Antes era um <select> com : resolvia o scroll de 72 carros, mas o operador
não conseguia VER o plano — via um carro por vez e perdia a noção de quantas
paradas cada um tem, que é justamente a conferência que ele faz antes de
mandar imprimir.
── NO CELULAR É UM BLOCO RECOLHIDO (diretriz 3) ───────────────────────────
Aberto, este painel tem os 72 carros mais o campo de motorista e três botões:
media 1.160px de altura e empurrava a EDIÇÃO — busca, campo PLANO e a tabela
de paradas — para 1.330px e 1.533px de rolagem, ou seja, duas telas abaixo do
que o operador foi fazer ali. Medido em 28/08/2026 no iPhone.
Recolhido, o rótulo mostra o que importa de relance (carro atual e quantas
paradas) e a edição sobe para a primeira tela. Um toque abre a lista inteira.
⚠️ NÃO VOLTE PARA <details>/<summary>. Foi a primeira tentativa e ela
APAGOU A COLUNA INTEIRA NO DESKTOP (28/08/2026): lista de veículos, campo do
motorista, "Ver prévia do PDF", "PDF deste veículo" e "PDF de todos" — tudo
sumiu, sobrando uma faixa vazia ao lado da tabela. O raciocínio era que
`lg:block` no conteúdo venceria o recolhimento do <details> fechado; não
vence. O navegador não esconde o conteúdo de um <details> fechado com um
`display` que dê para sobrescrever — nos motores atuais é `content-visibility`
no `::details-content` — então `display:block` no filho não traz nada de
volta, e como o <summary> estava `lg:hidden` não sobrava nem o que clicar.
O interruptor aqui é um checkbox + `peer`, CSS puro: sem JavaScript (o
romaneio_controller.js já ficou 404 em produção uma vez — ver README de
28/08) e sem depender de comportamento nativo de elemento nenhum. As três
regras são utilitárias e a ordem que o Tailwind gera resolve sozinha:
`hidden` (base) < `peer-checked:block` (estado) < `lg:block` (responsivo).
No desktop o conteúdo é block SEMPRE, marcado ou não. %>
<div class="bg-[#111] border border-white/5 rounded-2xl overflow-hidden">
<%# sr-only e não `hidden`: o checkbox precisa continuar existindo no layout
para o `peer` funcionar e para chegar nele pelo teclado. %>
<input type="checkbox" id="painel-veiculos" class="peer sr-only">
<label for="painel-veiculos"
class="lg:hidden cursor-pointer min-h-[56px] px-4 py-3 flex items-center gap-3
text-white hover:bg-white/5">
<span class="font-semibold truncate"><%= @veiculo %></span>
<span class="text-xs px-2 py-0.5 rounded-lg bg-white/5 text-gray-400 shrink-0">
<%= @romaneio.contagem_por_veiculo[@veiculo].to_i %> paradas
</span>
<span class="ml-auto text-xs text-orange-400 shrink-0">trocar veículo</span>
</label>
<div class="hidden peer-checked:block lg:block p-4 space-y-3">
<div class="flex items-center justify-between">
<h2 class="text-white font-semibold text-sm">Veículos</h2>
<span class="text-xs text-gray-500"><%= @veiculos.size %> no plano</span>
</div>
<div class="flex lg:flex-col gap-2 overflow-x-auto lg:overflow-x-visible
lg:overflow-y-auto lg:max-h-[46vh] pb-1 lg:pb-0
lg:pr-1 [scrollbar-width:thin]">
<% @veiculos.each do |v| %>
<% atual = v.veiculo == @veiculo %>
<%# Link de verdade (não botão com JS): o veículo vive na query string, então
ele é endereçável, volta com o "voltar" do navegador e sobrevive a um F5. %>
<a href="<%= admin_romaneio_path(@romaneio, veiculo: v.veiculo, previa: (1 if @previa)) %>"
data-romaneio-target="itemVeiculo" data-veiculo="<%= v.veiculo %>"
<%= 'data-atual="1"'.html_safe if atual %>
class="shrink-0 lg:shrink flex items-center justify-between gap-3 min-h-[48px]
px-3 rounded-xl border transition-colors
<%= atual ? 'bg-[#f97316] border-orange-400 text-white font-semibold'
: 'bg-[#1a1a1a] border-white/10 text-gray-300 hover:border-orange-500 hover:text-white' %>">
<span class="whitespace-nowrap"><%= v.veiculo %></span>
<%# A contagem é o que o operador confere: carro sem parada ou com parada
demais é erro de plano, e some quando só um veículo aparece por vez. %>
<span class="text-xs px-2 py-0.5 rounded-lg
<%= atual ? 'bg-black/25' : 'bg-white/5 text-gray-400' %>">
<%= @romaneio.contagem_por_veiculo[v.veiculo].to_i %>
</span>
</a>
<% end %>
</div>
<%# Setas para andar na LISTA (a prévia tem as suas). Links de verdade pelo
mesmo motivo dos itens acima: o veículo mora na query string. %>
<div class="flex gap-2 pt-1">
<% nomes_v = @veiculos.map(&:veiculo) %>
<% pos_v = nomes_v.index(@veiculo) %>
<% ant_v = pos_v&.positive? ? nomes_v[pos_v - 1] : nil %>
<% prox_v = pos_v && pos_v < nomes_v.size - 1 ? nomes_v[pos_v + 1] : nil %>
<% base_v = 'flex-1 min-h-[48px] flex items-center justify-center rounded-xl border' %>
<% if ant_v %>
<a href="<%= admin_romaneio_path(@romaneio, veiculo: ant_v, previa: (1 if @previa)) %>" aria-label="Veículo anterior"
class="<%= base_v %> bg-[#1a1a1a] border-white/10 text-white hover:bg-[#242424]"></a>
<% else %>
<span class="<%= base_v %> bg-[#1a1a1a]/50 border-white/5 text-gray-600"></span>
<% end %>
<% if prox_v %>
<a href="<%= admin_romaneio_path(@romaneio, veiculo: prox_v, previa: (1 if @previa)) %>" aria-label="Próximo veículo"
class="<%= base_v %> bg-[#1a1a1a] border-white/10 text-white hover:bg-[#242424]"></a>
<% else %>
<span class="<%= base_v %> bg-[#1a1a1a]/50 border-white/5 text-gray-600"></span>
<% end %>
</div>
<div class="pt-4 mt-1 border-t border-white/5">
<%# "Motorista deste veículo — só na tela" não cabe numa linha na coluna
estreita; o complemento vai embaixo, como legenda, em vez de quebrar no
meio do travessão. %>
<label class="block text-sm font-medium text-gray-300 mb-1.5">
Motorista deste veículo
<span class="block text-xs text-gray-500 font-normal">só na tela, não sai impresso</span>
</label>
<% atual = @veiculos.find { |v| v.veiculo == @veiculo } %>
<input type="text" value="<%= atual&.motorista %>" placeholder="Quem leva este carro"
data-romaneio-target="motorista" data-action="change->romaneio#salvarMotorista"
class="w-full bg-[#1a1a1a] border border-white/10 rounded-xl px-3 py-3 text-white
placeholder-gray-600 focus:outline-none focus:border-orange-500 min-h-[48px]">
<p class="text-xs text-gray-500 mt-1.5">
A linha do rodapé é assinada à mão na retirada.
</p>
</div>
<div class="space-y-3 pt-4 mt-4 border-t border-white/5">
<%# Link, não botão: a prévia aberta é a URL `?previa=1` (ver `_previa`),
então isto funciona com o JavaScript fora do ar — foi o botão daqui que
ficou morto três vezes seguidas. %>
<%= link_to admin_romaneio_path(@romaneio, veiculo: @veiculo, previa: 1),
class: 'w-full min-h-[48px] flex items-center justify-center gap-2 bg-[#1a1a1a]
hover:bg-[#242424] text-white border border-white/10 rounded-xl' do %>
<%= icone :visualizar, cor: nil, espaco: false %> Ver prévia do PDF
<% end %>
<%= link_to pdf_admin_romaneio_path(@romaneio, veiculo: @veiculo),
target: '_blank', rel: 'noopener',
class: 'w-full min-h-[48px] flex items-center justify-center gap-2 bg-[#1a1a1a]
hover:bg-[#242424] text-white border border-white/10 rounded-xl' do %>
<%= icone :baixar, cor: nil, espaco: false %> PDF deste veículo
<% end %>
<%# Rótulo em DUAS linhas de propósito. "PDF de TODOS os veículos" numa linha
só não cabe nos 260px da coluna: quebrava sozinho e deixava o ícone
pendurado num degrau ao lado do texto. Aqui a quebra é intencional — o
ícone fica centrado na altura e a contagem vira a segunda linha, que
ainda informa quantas folhas saem. %>
<%= link_to pdf_admin_romaneio_path(@romaneio),
class: 'w-full min-h-[56px] flex items-center justify-center gap-2.5 px-3 py-2
bg-[#f97316] hover:bg-orange-500 text-white rounded-xl text-left' do %>
<%= icone :baixar, cor: nil, espaco: false, classe: 'shrink-0' %>
<span class="leading-tight">
<span class="block font-semibold">PDF de todos</span>
<span class="block text-xs text-white/80"><%= @veiculos.size %> veículos, uma folha cada</span>
</span>
<% end %>
</div>
</div>
</div>