Correção de horario e implantação da geração de Romaneio
This commit is contained in:
48
app/views/admin/romaneios/_avisos.html.erb
Normal file
48
app/views/admin/romaneios/_avisos.html.erb
Normal file
@@ -0,0 +1,48 @@
|
||||
<%# Divergências explicadas ONDE elas aparecem — não em documentação. %>
|
||||
<% multifolha = @romaneio.veiculos_multifolha %>
|
||||
|
||||
<% if @colunas_ausentes.include?('status') && @romaneio.operacao_tabela.present? %>
|
||||
<div class="p-4 bg-amber-900/20 border border-amber-500/40 rounded-xl text-amber-200/90 text-sm flex items-start gap-2">
|
||||
<span class="text-base leading-none">⚠️</span>
|
||||
<p>
|
||||
A operação <strong><%= @romaneio.operacao_label %></strong> não tem a coluna
|
||||
<strong>STATUS</strong>, então não dá para saber quem é paciente novo — a coluna
|
||||
<strong>APARELHO</strong> saiu vazia para todos e precisa ser preenchida à mão.
|
||||
Um romaneio em que ninguém recebe aparelho, entregue calado, vira aparelho não entregue.
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if @colunas_ausentes.include?('telefones') && @romaneio.operacao_tabela.present? %>
|
||||
<div class="p-4 bg-amber-900/20 border border-amber-500/40 rounded-xl text-amber-200/90 text-sm flex items-start gap-2">
|
||||
<span class="text-base leading-none">☎️</span>
|
||||
<p>
|
||||
A operação <strong><%= @romaneio.operacao_label %></strong> não tem a coluna
|
||||
<strong>TELEFONES</strong>. O que aparece na tabela veio do “TEL:” das anotações do
|
||||
plano, que nem sempre traz todos os números.
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if @romaneio.operacao_tabela.blank? %>
|
||||
<div class="p-4 bg-blue-900/20 border border-blue-500/40 rounded-xl text-blue-200/90 text-sm flex items-start gap-2">
|
||||
<span class="text-base leading-none">ℹ️</span>
|
||||
<p>
|
||||
Este romaneio foi importado <strong>sem operação vinculada</strong>: a coluna APARELHO
|
||||
não é preenchida sozinha e o telefone vem só das anotações do plano.
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if multifolha.any? %>
|
||||
<div class="p-4 bg-blue-900/20 border border-blue-500/40 rounded-xl text-blue-200/90 text-sm flex items-start gap-2">
|
||||
<span class="text-base leading-none">🖨️</span>
|
||||
<p>
|
||||
<% multifolha.each do |veiculo, total| %>
|
||||
<strong><%= veiculo %></strong> tem <%= total %> paradas →
|
||||
sai em <%= @romaneio.folhas_de(veiculo) %> folhas<%= ',' unless veiculo == multifolha.keys.last %>
|
||||
<% end %>
|
||||
— cada folha vai com o próprio bloco de assinatura, e a numeração continua entre elas.
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
13
app/views/admin/romaneios/_celula.html.erb
Normal file
13
app/views/admin/romaneios/_celula.html.erb
Normal file
@@ -0,0 +1,13 @@
|
||||
<%# Uma célula editável + o marcador de "editado". %>
|
||||
<div class="flex items-center gap-1">
|
||||
<input type="text"
|
||||
value="<%= linha.public_send(campo) %>"
|
||||
data-romaneio-target="celula"
|
||||
data-action="change->romaneio#salvarCelula"
|
||||
data-linha-id="<%= linha.id %>"
|
||||
data-campo="<%= campo %>"
|
||||
data-original="<%= linha.public_send(campo) %>"
|
||||
class="w-full bg-transparent border border-transparent hover:border-white/10 focus:border-orange-500
|
||||
focus:bg-[#1a1a1a] rounded-lg px-2 py-2 text-gray-100 focus:outline-none min-h-[40px]">
|
||||
<%= render 'marcador', linha: linha, campo: campo %>
|
||||
</div>
|
||||
55
app/views/admin/romaneios/_controles.html.erb
Normal file
55
app/views/admin/romaneios/_controles.html.erb
Normal file
@@ -0,0 +1,55 @@
|
||||
<%# Seletor de veículo + os dois campos de cabeçalho da folha. %>
|
||||
<div class="bg-[#111] border border-white/5 rounded-2xl p-4 space-y-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-300 mb-1.5">Veículo</label>
|
||||
<div class="flex gap-2">
|
||||
<%# ‹ › ao lado do select: com 72 veículos, uma lista lateral vira armadilha
|
||||
de scroll, mas percorrer o plano carro a carro é o que o operador faz. %>
|
||||
<button type="button" data-action="romaneio#anterior" aria-label="Veículo anterior"
|
||||
class="px-3 min-w-[48px] min-h-[48px] bg-[#1a1a1a] border border-white/10 rounded-xl
|
||||
text-white hover:bg-[#242424]">‹</button>
|
||||
<select data-romaneio-target="veiculo" data-action="romaneio#trocarVeiculo"
|
||||
class="flex-1 bg-[#1a1a1a] border border-white/10 rounded-xl px-3 py-3 text-white
|
||||
focus:outline-none focus:border-orange-500 min-h-[48px]">
|
||||
<% @veiculos.each do |v| %>
|
||||
<option value="<%= v.veiculo %>" <%= 'selected' if v.veiculo == @veiculo %>>
|
||||
<%= v.veiculo %> (<%= @romaneio.contagem_por_veiculo[v.veiculo].to_i %>)
|
||||
</option>
|
||||
<% end %>
|
||||
</select>
|
||||
<button type="button" data-action="romaneio#proximo" aria-label="Próximo veículo"
|
||||
class="px-3 min-w-[48px] min-h-[48px] bg-[#1a1a1a] border border-white/10 rounded-xl
|
||||
text-white hover:bg-[#242424]">›</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-300 mb-1.5">
|
||||
PLANO <span class="text-gray-500 font-normal">— texto do canto direito do PDF</span>
|
||||
</label>
|
||||
<input type="text" value="<%= @romaneio.rotulo_plano %>"
|
||||
data-romaneio-target="rotulo" data-action="change->romaneio#salvarRotulo"
|
||||
class="w-full bg-[#1a1a1a] border border-white/10 rounded-xl px-3 py-3 text-white
|
||||
focus:outline-none focus:border-orange-500 min-h-[48px]">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-300 mb-1.5">
|
||||
Motorista <span class="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]">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-300 mb-1.5">Buscar nesta folha</label>
|
||||
<input type="search" placeholder="NF, nome ou endereço…"
|
||||
data-action="input->romaneio#filtrar"
|
||||
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]">
|
||||
</div>
|
||||
</div>
|
||||
12
app/views/admin/romaneios/_marcador.html.erb
Normal file
12
app/views/admin/romaneios/_marcador.html.erb
Normal file
@@ -0,0 +1,12 @@
|
||||
<%# Ponto laranja = campo tocado por humano, e por isso protegido na reimportação.
|
||||
O botão ↺ devolve o valor do plano (e destrava o campo de novo) — sem ele, uma
|
||||
tecla acidental seria permanente. %>
|
||||
<span class="shrink-0 w-4 flex items-center justify-center"
|
||||
data-romaneio-marcador="<%= linha.id %>-<%= campo %>">
|
||||
<% if linha.editado?(campo) %>
|
||||
<button type="button" title="Editado — não será sobrescrito na reimportação. Clique para restaurar o valor do plano."
|
||||
data-action="romaneio#restaurar"
|
||||
data-linha-id="<%= linha.id %>" data-campo="<%= campo %>"
|
||||
class="text-orange-400 hover:text-orange-200 text-xs leading-none">●</button>
|
||||
<% end %>
|
||||
</span>
|
||||
21
app/views/admin/romaneios/_removidas.html.erb
Normal file
21
app/views/admin/romaneios/_removidas.html.erb
Normal file
@@ -0,0 +1,21 @@
|
||||
<%# Paradas que saíram do plano mas tinham edição humana. Não são impressas, e não
|
||||
são apagadas: quem decide o que fazer com elas é o operador. %>
|
||||
<% if linhas.any? %>
|
||||
<div class="bg-[#111] border border-amber-500/30 rounded-2xl p-4">
|
||||
<h2 class="text-amber-200 font-semibold text-sm mb-1">
|
||||
<%= linhas.size %> parada(s) saíram do plano
|
||||
</h2>
|
||||
<p class="text-gray-400 text-xs mb-3">
|
||||
Elas tinham edição sua, então foram guardadas em vez de apagadas — e não entram no PDF.
|
||||
Se voltarem ao plano numa próxima importação, voltam sozinhas para a folha.
|
||||
</p>
|
||||
<ul class="space-y-1 text-sm">
|
||||
<% linhas.each do |linha| %>
|
||||
<li class="text-gray-500 line-through">
|
||||
<span class="text-gray-400"><%= linha.veiculo %></span> ·
|
||||
NF <%= linha.nota_fiscal.presence || '—' %> · <%= linha.nome %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
59
app/views/admin/romaneios/_tabela.html.erb
Normal file
59
app/views/admin/romaneios/_tabela.html.erb
Normal file
@@ -0,0 +1,59 @@
|
||||
<%# Tabela editável do veículo selecionado.
|
||||
SEM paginação de propósito: acima de 1366px a lista inteira é o certo — esconder
|
||||
item em monitor grande atrapalha até o Ctrl+F do navegador, e conferir romaneio é
|
||||
exatamente procurar uma NF na lista. A busca acima filtra sem esconder nada.
|
||||
|
||||
<input> por célula, e não contenteditable: colar do Excel num contenteditable
|
||||
traz HTML junto. %>
|
||||
<div class="bg-[#111] border border-white/5 rounded-2xl overflow-hidden">
|
||||
<div class="px-4 py-3 border-b border-white/5 flex items-center justify-between">
|
||||
<h2 class="text-white font-semibold text-sm"><%= linhas.size %> paradas</h2>
|
||||
<span class="text-xs text-gray-500" data-romaneio-target="status">Alterações salvam sozinhas</span>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-[#1a1a1a] text-gray-400 text-xs uppercase tracking-wider">
|
||||
<tr>
|
||||
<th class="text-left px-2 py-2 w-10">#</th>
|
||||
<th class="text-left px-2 py-2 w-28">Nota fiscal</th>
|
||||
<th class="text-left px-2 py-2 w-56">Nome</th>
|
||||
<th class="text-left px-2 py-2">Endereço</th>
|
||||
<th class="text-center px-2 py-2 w-24">Aparelho</th>
|
||||
<th class="text-left px-2 py-2 w-44">Telefones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-white/5">
|
||||
<% linhas.each_with_index do |linha, i| %>
|
||||
<tr data-romaneio-target="linha"
|
||||
data-busca="<%= [linha.nota_fiscal, linha.nome, linha.endereco].join(' ').downcase %>">
|
||||
<td class="px-2 py-1 text-gray-500 text-xs"><%= i + 1 %></td>
|
||||
<% %w[nota_fiscal nome endereco].each do |campo| %>
|
||||
<td class="px-1 py-1">
|
||||
<%= render 'celula', linha: linha, campo: campo %>
|
||||
</td>
|
||||
<% end %>
|
||||
|
||||
<%# APARELHO só assume 'SIM' ou vazio: um botão de dois estados é alvo de
|
||||
toque de verdade e não deixa digitar um terceiro valor. %>
|
||||
<td class="px-1 py-1 text-center">
|
||||
<button type="button"
|
||||
data-action="romaneio#alternarAparelho"
|
||||
data-linha-id="<%= linha.id %>"
|
||||
data-valor="<%= linha.aparelho %>"
|
||||
class="<%= linha.aparelho == 'SIM' ? 'bg-green-600/20 text-green-300 border-green-600/40' : 'bg-[#1a1a1a] text-gray-500 border-white/10' %>
|
||||
w-full min-h-[40px] rounded-lg border font-semibold text-xs hover:border-orange-500 transition-colors">
|
||||
<%= linha.aparelho.presence || '—' %>
|
||||
</button>
|
||||
<%= render 'marcador', linha: linha, campo: 'aparelho' %>
|
||||
</td>
|
||||
|
||||
<td class="px-1 py-1">
|
||||
<%= render 'celula', linha: linha, campo: 'telefones' %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
144
app/views/admin/romaneios/index.html.erb
Normal file
144
app/views/admin/romaneios/index.html.erb
Normal file
@@ -0,0 +1,144 @@
|
||||
<%# app/views/admin/romaneios/index.html.erb %>
|
||||
<div class="space-y-6">
|
||||
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-white">Romaneio de entrega</h1>
|
||||
<p class="text-gray-400 text-sm mt-0.5">
|
||||
Monta o "CONTROLE DE ENTREGA" — uma folha por veículo, assinada pelo motorista na retirada
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<%= render 'shared/flash' %>
|
||||
|
||||
<div class="p-4 bg-blue-900/20 border border-blue-500/40 rounded-xl text-blue-200/90 text-sm flex items-start gap-2">
|
||||
<span class="text-base leading-none">ℹ️</span>
|
||||
<p>
|
||||
A coluna <strong>APARELHO</strong> é marcada sozinha para quem está como
|
||||
<strong>NOVO</strong> na operação do mês, e o <strong>telefone</strong> vem da própria
|
||||
operação — não é preciso subir uma segunda planilha. Tudo continua editável na tela
|
||||
antes de imprimir.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<%# Importação %>
|
||||
<div class="bg-[#111] border border-white/5 rounded-2xl p-5 space-y-4">
|
||||
<h2 class="text-white font-semibold">Importar plano</h2>
|
||||
|
||||
<%= form_with url: admin_romaneios_path, method: :post, multipart: true,
|
||||
data: { turbo: false }, class: 'space-y-4' do %>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-300 mb-1.5">Data do plano</label>
|
||||
<input type="date" name="planned_date" required value="<%= @data_padrao %>"
|
||||
class="w-full bg-[#1a1a1a] border border-white/10 rounded-xl px-3 py-3 text-white
|
||||
focus:outline-none focus:border-orange-500 min-h-[48px]">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-300 mb-1.5">
|
||||
Operação do mês
|
||||
<span class="text-gray-500 font-normal">(APARELHO e telefone)</span>
|
||||
</label>
|
||||
<select name="operacao_tabela"
|
||||
class="w-full bg-[#1a1a1a] border border-white/10 rounded-xl px-3 py-3 text-white
|
||||
focus:outline-none focus:border-orange-500 min-h-[48px]">
|
||||
<option value="">Sem operação — só o que o plano trouxer</option>
|
||||
<% @operacoes_agrupadas.each do |titulo, ops| %>
|
||||
<optgroup label="<%= titulo %>">
|
||||
<% ops.each do |op| %>
|
||||
<option value="<%= op[:tabela] %>"><%= op[:label] %></option>
|
||||
<% end %>
|
||||
</optgroup>
|
||||
<% end %>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-300 mb-1.5">
|
||||
PLANO <span class="text-gray-500 font-normal">(canto direito do PDF)</span>
|
||||
</label>
|
||||
<input type="text" name="rotulo_plano" placeholder="Ex.: EMAD 09.2026"
|
||||
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]">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col sm:flex-row gap-3 sm:items-center">
|
||||
<button type="submit"
|
||||
class="px-6 py-3 bg-[#f97316] hover:bg-orange-500 text-white font-semibold rounded-xl
|
||||
transition-colors min-h-[48px] whitespace-nowrap">
|
||||
<%= icone :buscar, cor: nil %> Buscar no SimpliRoute
|
||||
</button>
|
||||
|
||||
<%# Reserva: o plano do dia pode ainda não estar publicado. %>
|
||||
<details class="flex-1">
|
||||
<summary class="cursor-pointer text-sm text-gray-400 hover:text-white select-none py-3">
|
||||
Ou enviar a planilha do plano (.xlsx)
|
||||
</summary>
|
||||
<div class="mt-2 flex flex-col sm:flex-row gap-3">
|
||||
<input type="file" name="arquivo" accept=".xlsx"
|
||||
class="flex-1 text-sm text-gray-300 file:mr-3 file:py-2.5 file:px-4 file:rounded-lg
|
||||
file:border-0 file:bg-[#1a1a1a] file:text-gray-200 file:cursor-pointer">
|
||||
<button type="submit" formaction="<%= importar_planilha_admin_romaneios_path %>"
|
||||
class="px-5 py-3 bg-[#1a1a1a] hover:bg-[#242424] text-white border border-white/10
|
||||
rounded-xl min-h-[48px] whitespace-nowrap">
|
||||
<%= icone :baixar, cor: nil %> Enviar planilha
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-xs text-gray-500 mt-2">
|
||||
Use quando o plano do dia ainda não estiver publicado no SimpliRoute.
|
||||
O arquivo é lido na hora e não fica guardado no sistema.
|
||||
</p>
|
||||
</details>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%# Romaneios já importados %>
|
||||
<div class="bg-[#111] border border-white/5 rounded-2xl overflow-hidden">
|
||||
<% if @romaneios.empty? %>
|
||||
<div class="p-8 text-center">
|
||||
<p class="text-gray-400">Nenhum romaneio ainda.</p>
|
||||
<p class="text-gray-500 text-sm mt-1">Escolha a data do plano acima e clique em “Buscar no SimpliRoute”.</p>
|
||||
</div>
|
||||
<% else %>
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-[#1a1a1a] text-gray-400 text-xs uppercase tracking-wider">
|
||||
<tr>
|
||||
<th class="text-left px-4 py-3">Data</th>
|
||||
<th class="text-left px-4 py-3">Plano</th>
|
||||
<th class="text-left px-4 py-3">Operação</th>
|
||||
<th class="text-left px-4 py-3">Veículos</th>
|
||||
<th class="text-left px-4 py-3">Origem</th>
|
||||
<th class="px-4 py-3"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-white/5">
|
||||
<% @romaneios.each do |r| %>
|
||||
<tr class="hover:bg-white/5">
|
||||
<td class="px-4 py-3 text-white"><%= l r.planned_date, format: '%d/%m/%Y' %></td>
|
||||
<td class="px-4 py-3 text-gray-200"><%= r.rotulo_plano.presence || '—' %></td>
|
||||
<td class="px-4 py-3 text-gray-400"><%= r.operacao_label || '—' %></td>
|
||||
<td class="px-4 py-3 text-gray-400"><%= r.romaneio_veiculos.size %></td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="px-2 py-0.5 rounded-md text-xs bg-white/5 text-gray-300"><%= r.origem %></span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right whitespace-nowrap">
|
||||
<%= link_to rotulo(:editar, 'Abrir'), admin_romaneio_path(r),
|
||||
class: 'text-orange-400 hover:text-orange-300 font-medium' %>
|
||||
<%# button_to em BLOCO: sem bloco ele vira <input type="submit">, que
|
||||
não aceita o SVG do ícone dentro (ver ApplicationHelper#rotulo). %>
|
||||
<%= button_to admin_romaneio_path(r), method: :delete,
|
||||
form: { data: { turbo_confirm: 'Excluir este romaneio e todas as edições feitas nele?' },
|
||||
class: 'inline-block ml-3' },
|
||||
class: 'text-gray-500 hover:text-red-400' do %>
|
||||
<%= icone :excluir, cor: nil %> Excluir
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
89
app/views/admin/romaneios/show.html.erb
Normal file
89
app/views/admin/romaneios/show.html.erb
Normal file
@@ -0,0 +1,89 @@
|
||||
<%# app/views/admin/romaneios/show.html.erb
|
||||
Editor do romaneio: tabela editável à esquerda, o PDF REAL à direita.
|
||||
|
||||
A prévia é um <iframe> de mesma origem, e isso não é preferência: o CSP deste
|
||||
app está em modo enforcing com `object_src :none` (config/initializers/
|
||||
content_security_policy.rb), o que bloqueia <embed> e <object>; não há
|
||||
`frame_src`, então ele cai em `default_src :self` e o iframe passa. Uma data:
|
||||
URL seria barrada pelo mesmo fallback. %>
|
||||
<div class="space-y-5"
|
||||
data-controller="romaneio"
|
||||
data-romaneio-url-value="<%= admin_romaneio_path(@romaneio) %>"
|
||||
data-romaneio-pdf-url-value="<%= pdf_admin_romaneio_path(@romaneio) %>"
|
||||
data-romaneio-veiculo-value="<%= @veiculo %>">
|
||||
|
||||
<div class="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-white">
|
||||
Romaneio de <%= l @romaneio.planned_date, format: '%d/%m/%Y' %>
|
||||
</h1>
|
||||
<p class="text-gray-400 text-sm mt-0.5">
|
||||
<%= @romaneio.operacao_label || 'Sem operação vinculada' %> ·
|
||||
<%= @romaneio.contagem_por_veiculo.values.sum %> paradas em
|
||||
<%= @veiculos.size %> veículo(s) ·
|
||||
importado de <%= @romaneio.origem %>
|
||||
<%= "em #{l @romaneio.importado_em, format: '%d/%m %H:%M'}" if @romaneio.importado_em %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<%= link_to rotulo(:baixar, 'Baixar todos'),
|
||||
pdf_admin_romaneio_path(@romaneio),
|
||||
class: 'px-4 py-2.5 bg-[#f97316] hover:bg-orange-500 text-white font-semibold rounded-xl min-h-[44px] inline-flex items-center' %>
|
||||
<%# Em BLOCO: button_to sem bloco gera <input type="submit">, que não aceita
|
||||
o SVG do ícone (ver ApplicationHelper#rotulo). %>
|
||||
<%= button_to reimportar_admin_romaneio_path(@romaneio, veiculo: @veiculo), method: :post,
|
||||
form: { data: { turbo_confirm: 'Rebuscar o plano? Os campos que você editou são preservados.' } },
|
||||
class: 'px-4 py-2.5 bg-[#1a1a1a] hover:bg-[#242424] text-white border border-white/10 rounded-xl min-h-[44px]' do %>
|
||||
<%= icone :restaurar, cor: nil %> Reimportar plano
|
||||
<% end %>
|
||||
<%= link_to 'Voltar', admin_romaneios_path,
|
||||
class: 'px-4 py-2.5 text-gray-400 hover:text-white min-h-[44px] inline-flex items-center' %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render 'shared/flash' %>
|
||||
|
||||
<% if @veiculos.empty? %>
|
||||
<div class="bg-[#111] border border-white/5 rounded-2xl p-8 text-center">
|
||||
<p class="text-gray-400">Este romaneio está sem paradas.</p>
|
||||
<p class="text-gray-500 text-sm mt-1">Clique em “Reimportar plano” ou envie a planilha do plano na tela anterior.</p>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= render 'avisos' %>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-[minmax(0,1fr)_minmax(0,560px)] gap-5 items-start">
|
||||
<div class="space-y-4">
|
||||
<%= render 'controles' %>
|
||||
<%= render 'tabela', linhas: @linhas %>
|
||||
<%= render 'removidas', linhas: @removidas %>
|
||||
</div>
|
||||
|
||||
<%# Prévia — no celular vira um bloco recolhido: 6 colunas em tela pequena
|
||||
exigiriam zoom, e o que importa ali é editar, não conferir o layout. %>
|
||||
<div class="lg:sticky lg:top-4">
|
||||
<details class="lg:hidden bg-[#111] border border-white/5 rounded-2xl p-4 mb-4">
|
||||
<summary class="cursor-pointer text-white font-medium select-none min-h-[44px] flex items-center">
|
||||
<%= icone :visualizar %> Ver prévia do PDF
|
||||
</summary>
|
||||
<%= link_to 'Abrir o PDF deste veículo',
|
||||
pdf_admin_romaneio_path(@romaneio, veiculo: @veiculo),
|
||||
class: 'block mt-3 text-orange-400 hover:text-orange-300', target: '_blank', rel: 'noopener' %>
|
||||
</details>
|
||||
|
||||
<div class="hidden lg:block bg-[#111] border border-white/5 rounded-2xl p-4">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<h2 class="text-white font-semibold text-sm">Prévia — <%= @veiculo %></h2>
|
||||
<button type="button" data-action="romaneio#atualizarPreview"
|
||||
class="text-xs text-gray-400 hover:text-white px-3 py-2 rounded-lg hover:bg-white/5">
|
||||
<%= icone :restaurar, tamanho: 'w-4 h-4' %> Atualizar prévia
|
||||
</button>
|
||||
</div>
|
||||
<iframe data-romaneio-target="preview"
|
||||
src="<%= pdf_admin_romaneio_path(@romaneio, veiculo: @veiculo) %>"
|
||||
class="w-full h-[78vh] rounded-xl border border-white/10 bg-white"
|
||||
title="Pré-visualização do romaneio do veículo <%= @veiculo %>"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
Reference in New Issue
Block a user