Atualização dos icones para um modelo chapado

This commit is contained in:
2026-07-20 15:08:09 -03:00
parent 7d3753f9c5
commit 42d06c50a7
34 changed files with 550 additions and 337 deletions

View File

@@ -2,8 +2,8 @@
<% content_for :title, 'Consolidações arquivadas' %>
<div class="flex items-center justify-between mb-6">
<h1 class="text-2xl font-bold text-white">📁 Consolidações arquivadas</h1>
<%= link_to 'Voltar às ativas', consolidacoes_path,
<h1 class="text-2xl font-bold text-white flex items-center gap-2"><%= icone :arquivadas %> Consolidações arquivadas</h1>
<%= link_to rotulo(:voltar, 'Voltar às ativas', cor: nil), consolidacoes_path,
class: 'text-gray-400 hover:text-white border border-[#2a2a2a] px-4 py-3 rounded-lg min-h-[48px] flex items-center' %>
</div>
@@ -26,12 +26,12 @@
<%= badge_status(c.status) %>
</div>
<p class="text-gray-400 text-sm">
📅 <%= l c.data_inicio, format: :short %> <%= l c.data_fim, format: :short %>
· 👤 <%= c.consolidacao_motoristas.count %> motorista(s)
<%= icone :calendario %> <%= l c.data_inicio, format: :short %> <%= icone :avancar, tamanho: 'w-3 h-3' %> <%= l c.data_fim, format: :short %>
· <%= icone :pessoa %> <%= c.consolidacao_motoristas.count %> motorista(s)
· Criada por <%= c.criador.nome_display %>
</p>
<p class="text-gray-500 text-xs mt-1">
📁 Arquivada
<%= icone :arquivar %> Arquivada
<% if c.arquivado_em.present? %>em <%= l c.arquivado_em, format: :short %><% end %>
<% if c.arquivador.present? %>por <%= c.arquivador.nome_display %><% end %>
</p>
@@ -45,12 +45,16 @@
<% if policy(c).destroy? %>
<div class="flex gap-2">
<%= button_to '♻️ Reativar', reativar_consolidacao_path(c), method: :post,
<%= button_to reativar_consolidacao_path(c), method: :post,
form: { data: { turbo_confirm: 'Reativar esta consolidação? Ela voltará para a lista de ativas.' } },
class: 'bg-orange-500 hover:bg-orange-600 text-black font-bold px-4 py-2.5 rounded-lg text-sm min-h-[44px]' %>
<%= button_to '🗑️ Excluir', consolidacao_path(c), method: :delete,
class: 'bg-orange-500 hover:bg-orange-600 text-black font-bold px-4 py-2.5 rounded-lg text-sm min-h-[44px] inline-flex items-center gap-2' do %>
<%= icone :restaurar, cor: nil, tamanho: 'w-4 h-4' %> Reativar
<% end %>
<%= button_to consolidacao_path(c), method: :delete,
form: { data: { turbo_confirm: 'EXCLUIR PERMANENTEMENTE esta consolidação e todas as suas classificações? Esta ação NÃO pode ser desfeita.' } },
class: 'text-red-400 hover:text-white hover:bg-red-600 border border-red-900 px-4 py-2.5 rounded-lg text-sm min-h-[44px]' %>
class: 'text-red-400 hover:text-white hover:bg-red-600 border border-red-900 px-4 py-2.5 rounded-lg text-sm min-h-[44px] inline-flex items-center gap-2' do %>
<%= icone :excluir, cor: nil, tamanho: 'w-4 h-4' %> Excluir
<% end %>
</div>
<% end %>
</div>
@@ -60,7 +64,7 @@
</div>
<% else %>
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-12 text-center">
<p class="text-5xl mb-4">🗂️</p>
<p class="mb-4"><%= icone :pasta, tamanho: 'w-12 h-12', cor: 'text-gray-600' %></p>
<p class="text-gray-400 mb-4">Nenhuma consolidação arquivada.</p>
<%= link_to 'Ver consolidações ativas', consolidacoes_path,
class: 'inline-block bg-orange-500 hover:bg-orange-600 text-black font-bold px-5 py-3 rounded-lg' %>

View File

@@ -4,14 +4,14 @@
<div data-controller="nota-avulsa"
data-nota-avulsa-buscar-url-value="<%= buscar_nf_consolidacoes_path %>">
<div class="flex items-center justify-between mb-6">
<h1 class="text-2xl font-bold text-white">📦 Consolidações</h1>
<h1 class="text-2xl font-bold text-white flex items-center gap-2"><%= icone :consolidacoes %> Consolidações</h1>
<div class="flex gap-2">
<%= link_to '📁 Arquivadas', arquivadas_consolidacoes_path,
<%= link_to rotulo(:arquivadas, 'Arquivadas'), arquivadas_consolidacoes_path,
class: 'text-gray-400 hover:text-white border border-[#2a2a2a] px-4 py-3 rounded-lg min-h-[48px] flex items-center transition-colors' %>
<% if policy(Consolidacao).create? %>
<button type="button" data-action="nota-avulsa#abrir"
class="text-white border border-dashed border-orange-500/60 hover:border-orange-500 font-semibold px-4 py-3 rounded-lg min-h-[48px] flex items-center transition-colors">
Nota avulsa
class="text-white border border-dashed border-orange-500/60 hover:border-orange-500 font-semibold px-4 py-3 rounded-lg min-h-[48px] flex items-center gap-2 transition-colors">
<%= icone :adicionar %> Nota avulsa
</button>
<% end %>
<%= link_to '+ Nova Consolidação', new_consolidacao_path,
@@ -25,9 +25,9 @@
class="hidden fixed inset-0 z-50 bg-black/70 flex items-center justify-center p-4">
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-2xl w-full max-w-lg p-6 max-h-[90vh] overflow-y-auto text-left">
<div class="flex items-center justify-between mb-1">
<h2 class="text-xl font-bold text-white"> Nota avulsa</h2>
<h2 class="text-xl font-bold text-white flex items-center gap-2"><%= icone :adicionar %> Nota avulsa</h2>
<button type="button" data-action="nota-avulsa#fechar"
class="text-gray-500 hover:text-white text-2xl leading-none"></button>
class="text-gray-500 hover:text-white leading-none" aria-label="Fechar"><%= icone :fechar, cor: nil, tamanho: 'w-5 h-5' %></button>
</div>
<p class="text-gray-400 text-sm mb-4">Para uma nota que chegou por fora: busque a NF e crie uma consolidação já com o apontamento do motorista.</p>
@@ -50,14 +50,14 @@
<div data-nota-avulsa-target="confirmar" class="hidden border-t border-[#2a2a2a] pt-4">
<label class="block text-gray-400 text-sm mb-2">Classificar como <span class="text-gray-600">(pode marcar mais de uma)</span></label>
<div class="grid grid-cols-2 gap-2 mb-4">
<% [['entrega_normal', '🚚 Entrega Normal', Configuracao.preco_entrega],
['retirada', '📦 Retirada', Configuracao.preco_retirada],
['bonus', 'Bônus', Configuracao.preco_bonus],
['desconto', '⚠️ Desconto', Configuracao.preco_desconto],
['extraordinaria', 'Entrega Extraordinária', Configuracao.preco_extraordinaria]].each do |tipo, label, preco| %>
<% [['entrega_normal', :caminhao, 'Entrega Normal', Configuracao.preco_entrega],
['retirada', :retirada, 'Retirada', Configuracao.preco_retirada],
['bonus', :bonus, 'Bônus', Configuracao.preco_bonus],
['desconto', :desconto, 'Desconto', Configuracao.preco_desconto],
['extraordinaria', :extraordinaria, 'Entrega Extraordinária', Configuracao.preco_extraordinaria]].each do |tipo, ic, label, preco| %>
<label class="flex items-center gap-2 bg-[#0a0a0a] border border-[#2a2a2a] rounded-lg px-3 py-3 cursor-pointer hover:border-orange-500 text-sm text-white">
<%= check_box_tag 'tipos[]', tipo, tipo == 'entrega_normal', id: nil, class: 'accent-orange-500' %>
<span><%= label %><br><span class="text-gray-500 text-xs"><%= moeda(preco) %></span></span>
<span><%= icone ic %> <%= label %><br><span class="text-gray-500 text-xs"><%= moeda(preco) %></span></span>
</label>
<% end %>
</div>
@@ -77,11 +77,11 @@
class: 'bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-3 py-2.5 focus:border-orange-500 focus:outline-none' %>
<%= f.select :status,
options_for_select([['Todos os status', ''], ['📝 Rascunho', 'rascunho'], ['Finalizada', 'finalizada']], params[:status]),
options_for_select([['Todos os status', ''], ['Rascunho', 'rascunho'], ['Finalizada', 'finalizada']], params[:status]),
{}, class: 'bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-3 py-2.5' %>
<%= f.select :pagamento,
options_for_select([['💵 Pagamento (todos)', ''], ['💰 Pagas', 'pago'], ['Parciais', 'parcial'], ['🕗 Pendentes', 'pendente']], params[:pagamento]),
options_for_select([['Pagamento (todos)', ''], ['Pagas', 'pago'], ['Parciais', 'parcial'], ['Pendentes', 'pendente']], params[:pagamento]),
{}, class: 'bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-3 py-2.5' %>
<%= f.date_field :inicio, value: params[:inicio],
@@ -110,12 +110,12 @@
<% if c.finalizada? %><%= badge_pagamento(c.status_pagamento) %><% end %>
</div>
<p class="text-gray-400 text-sm">
📅 <%= l c.data_inicio, format: :short %> → <%= l c.data_fim, format: :short %>
· 👤 <%= c.consolidacao_motoristas.count %> motorista(s)
<%= icone :calendario %> <%= l c.data_inicio, format: :short %> → <%= l c.data_fim, format: :short %>
· <%= icone :pessoa %> <%= c.consolidacao_motoristas.count %> motorista(s)
· Criada por <%= c.criador.nome_display %>
</p>
<% if c.operacoes.present? %>
<p class="text-gray-500 text-xs mt-1">🗂️ <%= c.operacoes_label.join(' · ') %></p>
<p class="text-gray-500 text-xs mt-1"><%= icone :pasta %> <%= c.operacoes_label.join(' · ') %></p>
<% end %>
</div>
<div class="text-right">
@@ -128,7 +128,7 @@
</div>
<% else %>
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-12 text-center">
<p class="text-5xl mb-4">📭</p>
<p class="mb-4"><%= icone :vazio, tamanho: 'w-12 h-12', cor: 'text-gray-600' %></p>
<p class="text-gray-400 mb-4">Nenhuma consolidação encontrada.</p>
<%= link_to 'Criar primeira consolidação', new_consolidacao_path,
class: 'inline-block bg-orange-500 hover:bg-orange-600 text-black font-bold px-5 py-3 rounded-lg' %>

View File

@@ -2,13 +2,13 @@
<% content_for :title, 'Nova Consolidação' %>
<div class="max-w-3xl mx-auto">
<h1 class="text-2xl font-bold text-white mb-6"> Nova Consolidação</h1>
<h1 class="text-2xl font-bold text-white mb-6 flex items-center gap-2"><%= icone :adicionar %> Nova Consolidação</h1>
<%= form_with model: @consolidacao, class: 'bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-6 space-y-6' do |f| %>
<% if @consolidacao.errors.any? %>
<div class="bg-red-900/40 border border-red-600 rounded-lg p-4">
<p class="text-red-400 font-bold mb-1">⚠️ Corrija os erros:</p>
<p class="text-red-400 font-bold mb-1 flex items-center gap-2"><%= icone :alerta, cor: nil %> Corrija os erros:</p>
<ul class="text-red-300 text-sm list-disc list-inside">
<% @consolidacao.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
@@ -20,7 +20,7 @@
<%# Operação — multi-select opcional (pré-preenche e filtra por NF) %>
<div>
<label class="block text-white font-semibold mb-2">
🗂️ Operação <span class="text-gray-500 font-normal text-sm">(opcional — preenche motoristas, veículos e período, e filtra as entregas por nota fiscal)</span>
<%= icone :pasta %> Operação <span class="text-gray-500 font-normal text-sm">(opcional — preenche motoristas, veículos e período, e filtra as entregas por nota fiscal)</span>
</label>
<div id="operacoes-lista"
class="bg-[#0a0a0a] border border-[#2a2a2a] rounded-lg p-3 max-h-48 overflow-y-auto space-y-1">

View File

@@ -15,7 +15,7 @@
<% if @consolidacao.finalizada? %><%= badge_pagamento(@consolidacao.status_pagamento) %><% end %>
</div>
<p class="text-gray-400 text-sm mt-1">
📅 <%= l @consolidacao.data_inicio, format: :short %> <%= l @consolidacao.data_fim, format: :short %>
<%= icone :calendario %> <%= l @consolidacao.data_inicio, format: :short %> <%= icone :avancar, tamanho: 'w-3 h-3' %> <%= l @consolidacao.data_fim, format: :short %>
· Criada por <%= @consolidacao.criador.nome_display %>
<% if @consolidacao.finalizada? %>
· Finalizada por <%= @consolidacao.finalizador&.nome_display %> em <%= l @consolidacao.finalizado_em, format: :short %>
@@ -23,7 +23,7 @@
</p>
<% if @consolidacao.operacoes.present? %>
<p class="text-gray-400 text-sm mt-1">
🗂️ Operação:
<%= icone :pasta %> Operação:
<% @consolidacao.operacoes_label.each do |op| %>
<span class="inline-block bg-[#2a2a2a] text-gray-200 rounded-full px-2.5 py-0.5 text-xs"><%= op %></span>
<% end %>
@@ -32,16 +32,18 @@
</div>
<div class="flex gap-2">
<% if @consolidacao.rascunho? %>
<%= link_to '✏️ Continuar validação', wizard_consolidacao_path(@consolidacao),
<%= link_to rotulo(:editar, 'Continuar validação', cor: nil), wizard_consolidacao_path(@consolidacao),
class: 'bg-orange-500 hover:bg-orange-600 text-black font-bold px-5 py-3 rounded-lg min-h-[48px] flex items-center' %>
<% end %>
<%= link_to '📊 Relatório financeiro', gerar_pdf_financeiro_consolidacao_path(@consolidacao),
<%= link_to rotulo(:dashboard, 'Relatório financeiro'), gerar_pdf_financeiro_consolidacao_path(@consolidacao),
data: { turbo: false },
class: 'bg-[#1a1a1a] hover:bg-[#2a2a2a] text-white border border-orange-500 font-semibold px-4 py-3 rounded-lg min-h-[48px] flex items-center' %>
<% if policy(@consolidacao).destroy? && !@consolidacao.arquivada? %>
<%= button_to '📁 Arquivar', arquivar_consolidacao_path(@consolidacao), method: :post,
<%= button_to arquivar_consolidacao_path(@consolidacao), method: :post,
form: { data: { turbo_confirm: 'Arquivar esta consolidação? Ela não será excluída, apenas movida para o arquivo.' } },
class: 'text-gray-400 hover:text-white border border-[#2a2a2a] px-4 py-3 rounded-lg min-h-[48px]' %>
class: 'text-gray-400 hover:text-white border border-[#2a2a2a] px-4 py-3 rounded-lg min-h-[48px] flex items-center gap-2' do %>
<%= icone :arquivar, cor: nil, tamanho: 'w-4 h-4' %> Arquivar
<% end %>
<% end %>
</div>
</div>
@@ -49,7 +51,7 @@
<%# ── Pagamento da operação inteira ─────────────────────── %>
<% if pode_pagar %>
<div class="flex flex-col sm:flex-row sm:items-center gap-2 mt-4 bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-4">
<span class="text-gray-400 text-sm font-medium mr-1">💵 Operação inteira:</span>
<span class="text-gray-400 text-sm font-medium mr-1"><%= icone :pagamento %> Operação inteira:</span>
<% if @consolidacao.status_pagamento != :pago %>
<%# Form único (id) — os inputs de NF e os botões "Marcar pago" de cada
linha se associam a ele via atributo HTML5 form=, evitando <form> aninhado. %>
@@ -57,15 +59,19 @@
id: 'form-pagar-tudo', class: 'flex items-center gap-2' do |f| %>
<%= f.select :forma_pagamento, options_for_select(formas_pagamento, 'pix'),
{}, class: 'bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-3 py-2.5 text-sm' %>
<%= f.submit '💰 Marcar tudo como pago',
<%= f.button type: :submit,
data: { turbo_confirm: 'Marcar TODOS os motoristas pendentes desta consolidação como PAGOS? Confirme que a Nota Fiscal de cada um foi preenchida.' },
class: 'bg-green-600 hover:bg-green-700 text-white font-bold px-4 py-2.5 rounded-lg text-sm cursor-pointer min-h-[44px]' %>
class: 'bg-green-600 hover:bg-green-700 text-white font-bold px-4 py-2.5 rounded-lg text-sm cursor-pointer min-h-[44px] inline-flex items-center gap-2' do %>
<%= icone :dinheiro, cor: nil, tamanho: 'w-4 h-4' %> Marcar tudo como pago
<% end %>
<% end %>
<% end %>
<% if @consolidacao.status_pagamento != :pendente %>
<%= button_to '↩ Estornar tudo', cancelar_pagamento_consolidacao_path(@consolidacao), method: :post,
data: { turbo_confirm: 'Estornar o pagamento de TODOS os motoristas?' },
class: 'text-gray-400 hover:text-white border border-[#2a2a2a] px-4 py-2.5 rounded-lg text-sm min-h-[44px]' %>
<%= button_to cancelar_pagamento_consolidacao_path(@consolidacao), method: :post,
form: { data: { turbo_confirm: 'Estornar o pagamento de TODOS os motoristas?' } },
class: 'text-gray-400 hover:text-white border border-[#2a2a2a] px-4 py-2.5 rounded-lg text-sm min-h-[44px] inline-flex items-center gap-2' do %>
<%= icone :estornar, cor: nil, tamanho: 'w-4 h-4' %> Estornar tudo
<% end %>
<% end %>
</div>
<% end %>
@@ -78,7 +84,7 @@
</div>
<%# Motoristas + botões de PDF %>
<h2 class="text-white font-bold text-lg mb-3">👥 Motoristas</h2>
<h2 class="text-white font-bold text-lg mb-3 flex items-center gap-2"><%= icone :usuarios %> Motoristas</h2>
<div class="space-y-3">
<% @motoristas.each do |cm| %>
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-5">
@@ -91,45 +97,49 @@
<% end %>
</div>
<p class="text-orange-500 font-black text-xl"><%= moeda(cm.valor_total) %></p>
<%# Breakdown por veículo (consolidados 🔒 / abertos). Informativo — o
<%# Breakdown por veículo (consolidados / abertos). Informativo — o
pagamento continua sendo do motorista inteiro. %>
<% veiculos = @veiculos_por_motorista[cm.motorista_nome] %>
<% if veiculos.present? %>
<div class="flex flex-wrap gap-1.5 mt-1">
<% veiculos.each do |cv| %>
<span class="text-xs px-2 py-0.5 rounded border <%= cv.fechado? ? 'border-green-500/50 text-green-400' : 'border-[#2a2a2a] text-gray-400' %>">
<%= cv.fechado? ? '🔒' : '○' %> <%= cv.vehicle %> · <%= moeda(cv.valor_total) %>
<%= cv.fechado? ? icone(:travado, cor: nil, tamanho: 'w-3 h-3') : icone(:ponto_vazio, cor: nil, tamanho: 'w-3 h-3') %> <%= cv.vehicle %> · <%= moeda(cv.valor_total) %>
</span>
<% end %>
</div>
<% end %>
<% if cm.pago? %>
<p class="text-green-400 text-xs mt-1">
💰 Pago em <%= l cm.pago_em, format: :short %>
<%= icone :dinheiro, cor: nil %> Pago em <%= l cm.pago_em, format: :short %>
<% if cm.forma_pagamento.present? %>via <%= cm.forma_pagamento.humanize %><% end %>
<% if cm.pagador.present? %>por <%= cm.pagador.nome_display %><% end %>
</p>
<% if cm.nota_fiscal.present? %>
<p class="text-gray-300 text-xs mt-0.5">🧾 NF <%= cm.nota_fiscal %></p>
<p class="text-gray-300 text-xs mt-0.5"><%= icone :nota_fiscal %> NF <%= cm.nota_fiscal %></p>
<% end %>
<% end %>
<% if pode_pagar %>
<div class="mt-2">
<% if cm.pago? %>
<%= button_to '↩ Estornar pagamento', cancelar_pagamento_consolidacao_path(@consolidacao, consolidacao_motorista_id: cm.id), method: :post,
data: { turbo_confirm: "Estornar o pagamento de #{cm.motorista_nome}?" },
class: 'text-gray-400 hover:text-white border border-[#2a2a2a] px-3 py-2 rounded-lg text-xs min-h-[40px]' %>
<%= button_to cancelar_pagamento_consolidacao_path(@consolidacao, consolidacao_motorista_id: cm.id), method: :post,
form: { data: { turbo_confirm: "Estornar o pagamento de #{cm.motorista_nome}?" } },
class: 'text-gray-400 hover:text-white border border-[#2a2a2a] px-3 py-2 rounded-lg text-xs min-h-[40px] inline-flex items-center gap-1.5' do %>
<%= icone :estornar, cor: nil, tamanho: 'w-3.5 h-3.5' %> Estornar pagamento
<% end %>
<% else %>
<%# Inputs/botão associados ao form único #form-pagar-tudo via atributo form=. %>
<div class="flex items-center gap-2 flex-wrap">
<%= text_field_tag "notas_fiscais[#{cm.id}]", nil, form: 'form-pagar-tudo',
placeholder: 'Nº Nota Fiscal',
class: 'bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-2 py-2 text-xs w-36' %>
<%= button_tag '💰 Marcar pago', type: :submit, form: 'form-pagar-tudo',
<%= button_tag type: :submit, form: 'form-pagar-tudo',
name: 'consolidacao_motorista_id', value: cm.id,
data: { turbo_confirm: "Marcar #{cm.motorista_nome} como pago?" },
class: 'bg-green-600 hover:bg-green-700 text-white font-bold px-3 py-2 rounded-lg text-xs cursor-pointer min-h-[40px]' %>
class: 'bg-green-600 hover:bg-green-700 text-white font-bold px-3 py-2 rounded-lg text-xs cursor-pointer min-h-[40px] inline-flex items-center gap-1.5' do %>
<%= icone :dinheiro, cor: nil, tamanho: 'w-3.5 h-3.5' %> Marcar pago
<% end %>
</div>
<% end %>
</div>
@@ -139,13 +149,13 @@
<%# Preview abre modal %>
<button onclick="abrirPreview('<%= preview_extrato_consolidacao_path(@consolidacao, motorista: cm.motorista_nome) %>')"
class="bg-[#0a0a0a] hover:bg-[#2a2a2a] text-white border border-orange-500 font-semibold px-4 py-3 rounded-lg text-sm min-h-[48px]">
👁️ Ver antes de gerar
<%= icone :visualizar %> Ver antes de gerar
</button>
<%= link_to '📄 Relatório Individual',
<%= link_to rotulo(:documento, 'Relatório Individual', cor: nil),
gerar_pdf_relatorio_consolidacao_path(@consolidacao, motorista: cm.motorista_nome),
data: { turbo: false },
class: 'bg-orange-800 hover:bg-orange-700 text-white font-semibold px-4 py-3 rounded-lg text-sm min-h-[48px] flex items-center' %>
<%= link_to '🧾 Gerar Extrato',
<%= link_to rotulo(:nota_fiscal, 'Gerar Extrato', cor: nil),
gerar_pdf_extrato_consolidacao_path(@consolidacao, motorista: cm.motorista_nome),
data: { turbo: false },
class: 'bg-orange-500 hover:bg-orange-600 text-black font-bold px-4 py-3 rounded-lg text-sm min-h-[48px] flex items-center' %>
@@ -158,7 +168,7 @@
<%# ── Apontamentos manuais (notas que chegaram por fora) ─────────────── %>
<% if @apontamentos.present? %>
<% pode_editar = !(@consolidacao.finalizada? && current_user.operador?) %>
<h2 class="text-white font-bold text-lg mt-8 mb-3"> Apontamentos manuais</h2>
<h2 class="text-white font-bold text-lg mt-8 mb-3 flex items-center gap-2"><%= icone :adicionar %> Apontamentos manuais</h2>
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl overflow-hidden">
<table class="w-full text-sm">
<thead class="bg-[#0a0a0a] text-gray-400">
@@ -179,9 +189,9 @@
<tr>
<td class="px-4 py-3">
<p class="text-white font-bold"><%= if pilares.first.termo?
'📄 Entrega de termo'
rotulo(:documento, 'Entrega de termo')
elsif pilares.first.termo_especial?
'📋 Entrega de termo especial'
rotulo(:termo_especial, 'Entrega de termo especial')
else
"NF #{nf_exibida.presence || '—'}"
end %></p>
@@ -200,11 +210,12 @@
<td class="px-4 py-3 text-right font-bold <%= total.negative? ? 'text-red-400' : 'text-white' %>"><%= moeda(total) %></td>
<% if pode_editar %>
<td class="px-4 py-3 text-right">
<%= button_to '✕ Remover',
remover_apontamento_consolidacao_consolidacao_entregas_path(@consolidacao, tracking_id: pilares.first.tracking_id, motorista: motorista),
<%= button_to remover_apontamento_consolidacao_consolidacao_entregas_path(@consolidacao, tracking_id: pilares.first.tracking_id, motorista: motorista),
method: :delete,
form: { data: { turbo_confirm: eh_termo ? "Remover a entrega de termo de #{motorista}?" : "Remover o apontamento da NF #{nf_exibida.presence || '—'} de #{motorista}?" } },
class: 'text-gray-400 hover:text-red-400 border border-[#2a2a2a] hover:border-red-500/50 px-3 py-2 rounded-lg text-xs min-h-[40px]' %>
class: 'text-gray-400 hover:text-red-400 border border-[#2a2a2a] hover:border-red-500/50 px-3 py-2 rounded-lg text-xs min-h-[40px] inline-flex items-center gap-1.5' do %>
<%= icone :fechar, cor: nil, tamanho: 'w-3 h-3' %> Remover
<% end %>
</td>
<% end %>
</tr>
@@ -219,8 +230,8 @@
<div id="modal-preview" class="fixed inset-0 bg-black/80 z-50 hidden items-center justify-center p-4">
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-2xl max-w-2xl w-full max-h-[85vh] flex flex-col">
<div class="flex items-center justify-between px-6 py-4 border-b border-[#2a2a2a]">
<h3 class="text-white font-bold">👁️ Pré-visualização do Extrato</h3>
<button onclick="fecharPreview()" class="text-gray-400 hover:text-white text-2xl min-w-[44px] min-h-[44px]"></button>
<h3 class="text-white font-bold flex items-center gap-2"><%= icone :visualizar %> Pré-visualização do Extrato</h3>
<button onclick="fecharPreview()" class="text-gray-400 hover:text-white min-w-[44px] min-h-[44px]" aria-label="Fechar"><%= icone :fechar, cor: nil, tamanho: 'w-5 h-5' %></button>
</div>
<div id="modal-preview-conteudo" class="overflow-y-auto p-6 flex-1">
<div class="flex justify-center py-10"><div class="spinner w-10 h-10"></div></div>
@@ -228,11 +239,11 @@
<div class="flex gap-3 px-6 py-4 border-t border-[#2a2a2a]">
<a id="modal-confirmar" href="#" data-turbo="false"
class="flex-1 bg-orange-500 hover:bg-orange-600 text-black font-bold py-3 rounded-lg text-center min-h-[48px] flex items-center justify-center">
Confirmar e baixar PDF
<%= icone :confirmar, cor: nil %> Confirmar e baixar PDF
</a>
<button onclick="fecharPreview()"
class="px-6 py-3 text-gray-400 hover:text-white border border-[#2a2a2a] rounded-lg min-h-[48px]">
Voltar
<%= icone :voltar, cor: nil, tamanho: 'w-4 h-4' %> Voltar
</button>
</div>
</div>

View File

@@ -8,7 +8,7 @@
<%= link_to '← Voltar para o resumo', consolidacao_path(@consolidacao), class: 'text-gray-500 hover:text-orange-500 text-sm' %>
<h1 class="text-2xl font-bold text-white mt-2"><%= @consolidacao.nome %></h1>
<p class="text-gray-400 text-sm">
📅 <%= l @consolidacao.data_inicio, format: :short %> <%= l @consolidacao.data_fim, format: :short %>
<%= icone :calendario %> <%= l @consolidacao.data_inicio, format: :short %> <%= icone :avancar, tamanho: 'w-3 h-3' %> <%= l @consolidacao.data_fim, format: :short %>
· <%= badge_status(@consolidacao.status) %>
</p>
</div>
@@ -42,20 +42,20 @@
<%# Botão único + menu suspenso %>
<button type="button" data-action="ferramentas#toggle"
class="w-full md:w-auto inline-flex items-center justify-center gap-2 bg-[#1a1a1a] hover:bg-[#2a2a2a] text-white border border-dashed border-[#3a3a3a] hover:border-orange-500 font-semibold px-4 py-3 rounded-lg min-h-[48px]">
Adicionar / Ferramentas
<span class="text-gray-500">▾</span>
<%= icone :adicionar %> Adicionar / Ferramentas
<%= icone :expandir, cor: 'text-gray-500' %>
</button>
<div data-ferramentas-target="menu"
class="hidden absolute z-40 mt-2 w-72 bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl shadow-xl overflow-hidden">
<button type="button" data-action="apontamento#abrir ferramentas#fechar"
class="w-full text-left px-4 py-3 hover:bg-[#2a2a2a] border-l-2 border-transparent hover:border-orange-500">
<span class="block text-white font-semibold">📝 Apontamento manual</span>
<span class="block text-white font-semibold"><%= icone :apontamento %> Apontamento manual</span>
<span class="block text-gray-500 text-xs">nota que chegou por fora (busca pela NF)</span>
</button>
<button type="button" data-action="adicionar-motorista#abrir ferramentas#fechar"
class="w-full text-left px-4 py-3 hover:bg-[#2a2a2a] border-t border-[#2a2a2a] border-l-2 border-l-transparent hover:border-l-green-500">
<span class="block text-white font-semibold">🧑‍✈️ Adicionar motorista</span>
<span class="block text-white font-semibold"><%= icone :motorista %> Adicionar motorista</span>
<span class="block text-gray-500 text-xs">incluir/restaurar um motorista nesta consolidação</span>
</button>
</div>
@@ -67,7 +67,7 @@
<div class="flex items-center justify-between mb-1">
<h2 class="text-xl font-bold text-white">Apontamento manual</h2>
<button type="button" data-action="apontamento#fechar"
class="text-gray-500 hover:text-white text-2xl leading-none"></button>
class="text-gray-500 hover:text-white leading-none" aria-label="Fechar"><%= icone :fechar, cor: nil, tamanho: 'w-5 h-5' %></button>
</div>
<p class="text-gray-400 text-sm mb-4">Busque a nota pela base de rastreio e adicione ao fechamento do motorista correspondente.</p>
@@ -89,22 +89,22 @@
<div data-apontamento-target="confirmar" class="hidden border-t border-[#2a2a2a] pt-4">
<label class="block text-gray-400 text-sm mb-2">Classificar como <span class="text-gray-600">(pode marcar mais de uma)</span></label>
<div class="grid grid-cols-2 gap-2 mb-4">
<% [['entrega_normal', '🚚 Entrega Normal', Configuracao.preco_entrega],
['retirada', '📦 Retirada', Configuracao.preco_retirada],
['bonus', 'Bônus', Configuracao.preco_bonus],
['desconto', '⚠️ Desconto', Configuracao.preco_desconto],
['extraordinaria', 'Entrega Extraordinária', Configuracao.preco_extraordinaria]].each do |tipo, label, preco| %>
<% [['entrega_normal', :caminhao, 'Entrega Normal', Configuracao.preco_entrega],
['retirada', :retirada, 'Retirada', Configuracao.preco_retirada],
['bonus', :bonus, 'Bônus', Configuracao.preco_bonus],
['desconto', :desconto, 'Desconto', Configuracao.preco_desconto],
['extraordinaria', :extraordinaria, 'Entrega Extraordinária', Configuracao.preco_extraordinaria]].each do |tipo, ic, label, preco| %>
<label class="flex items-center gap-2 bg-[#0a0a0a] border border-[#2a2a2a] rounded-lg px-3 py-3 cursor-pointer hover:border-orange-500 text-sm text-white">
<input type="checkbox" value="<%= tipo %>" data-apontamento-target="tipoCheck"
<%= 'checked' if tipo == 'entrega_normal' %>
class="accent-orange-500">
<span><%= label %><br><span class="text-gray-500 text-xs"><%= moeda(preco) %></span></span>
<span><%= icone ic %> <%= label %><br><span class="text-gray-500 text-xs"><%= moeda(preco) %></span></span>
</label>
<% end %>
</div>
<button type="button" data-action="apontamento#apontar"
class="w-full bg-green-600 hover:bg-green-500 text-white font-bold py-3.5 rounded-lg min-h-[48px]">
Adicionar apontamento
Adicionar apontamento <%= icone :confirmar, cor: nil %>
</button>
</div>
</div>
@@ -115,9 +115,9 @@
class="hidden fixed inset-0 z-50 bg-black/70 flex items-center justify-center p-4">
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-2xl w-full max-w-md p-6">
<div class="flex items-center justify-between mb-1">
<h2 class="text-xl font-bold text-white">🧑‍✈️ Adicionar motorista</h2>
<h2 class="text-xl font-bold text-white flex items-center gap-2"><%= icone :motorista %> Adicionar motorista</h2>
<button type="button" data-action="adicionar-motorista#fechar"
class="text-gray-500 hover:text-white text-2xl leading-none"></button>
class="text-gray-500 hover:text-white leading-none" aria-label="Fechar"><%= icone :fechar, cor: nil, tamanho: 'w-5 h-5' %></button>
</div>
<p class="text-gray-400 text-sm mb-4">Inclua um motorista nesta consolidação. Se ele estava arquivado, será restaurado.</p>
@@ -128,7 +128,7 @@
class="w-full bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-3 py-3 text-base focus:border-orange-500 focus:outline-none mb-4">
<datalist id="motoristas-disponiveis">
<% Array(@motoristas_periodo).each do |m| %>
<option value="<%= m[:nome] %>" label="<%= '🚚 ' + m[:veiculos].join(', ') if m[:veiculos].any? %>"></option>
<option value="<%= m[:nome] %>" label="<%= m[:veiculos].join(', ') if m[:veiculos].any? %>"></option>
<% end %>
</datalist>
@@ -141,7 +141,7 @@
class="w-full text-left px-3 py-2 bg-[#0a0a0a] border border-[#2a2a2a] hover:border-orange-500 rounded-lg">
<span class="block text-white text-sm font-semibold"><%= m[:nome] %></span>
<% if m[:veiculos].any? %>
<span class="block text-gray-500 text-xs">🚚 <%= m[:veiculos].join(', ') %></span>
<span class="block text-gray-500 text-xs"><%= icone :caminhao %> <%= m[:veiculos].join(', ') %></span>
<% end %>
</button>
<% end %>
@@ -152,7 +152,7 @@
<button type="submit"
class="w-full bg-green-600 hover:bg-green-500 text-white font-bold py-3.5 rounded-lg min-h-[48px]">
Adicionar
Adicionar <%= icone :confirmar, cor: nil %>
</button>
<% end %>
</div>
@@ -174,7 +174,7 @@
<div class="flex items-center gap-4">
<div class="w-12 h-12 rounded-full flex items-center justify-center text-xl font-black
<%= m[:completo] ? 'bg-green-600 text-white' : 'bg-orange-500 text-black' %>">
<%= m[:completo] ? '✓' : m[:registro].motorista_nome.first.upcase %>
<%= m[:completo] ? icone(:confirmar, cor: nil, tamanho: 'w-6 h-6') : m[:registro].motorista_nome.first.upcase %>
</div>
<div>
<p class="text-white font-bold text-lg"><%= m[:registro].motorista_nome %></p>
@@ -184,13 +184,13 @@
<%= m[:classificadas] %>/<%= m[:total] %> classificadas
</span>
<% if m[:apontamentos].positive? %>
· <span class="text-orange-400"> <%= m[:apontamentos] %> apontamento<%= 's' if m[:apontamentos] > 1 %></span>
· <span class="text-orange-400"><%= icone :adicionar, cor: nil, tamanho: 'w-3 h-3' %> <%= m[:apontamentos] %> apontamento<%= 's' if m[:apontamentos] > 1 %></span>
<% end %>
</p>
<% if m[:veiculos_total] > 0 %>
<p class="text-xs mt-0.5">
<span class="<%= m[:veiculos_fechados] == m[:veiculos_total] ? 'text-green-400' : 'text-gray-400' %>">
🚗 <%= m[:veiculos_fechados] %>/<%= m[:veiculos_total] %> veículo<%= 's' if m[:veiculos_total] > 1 %> consolidado<%= 's' if m[:veiculos_fechados] != 1 %>
<%= icone :veiculo, cor: nil %> <%= m[:veiculos_fechados] %>/<%= m[:veiculos_total] %> veículo<%= 's' if m[:veiculos_total] > 1 %> consolidado<%= 's' if m[:veiculos_fechados] != 1 %>
</span>
<% if m[:veiculos_pendentes].any? %>
<span class="text-orange-400">· pendente<%= 's' if m[:veiculos_pendentes].size > 1 %>: <%= m[:veiculos_pendentes].join(', ') %></span>
@@ -201,7 +201,7 @@
</div>
<div class="text-right <%= 'pr-10' if pode_arquivar_motorista %>">
<p class="text-orange-500 font-bold"><%= moeda(m[:registro].valor_total) %></p>
<span class="text-gray-600 text-2xl">→</span>
<%= icone :avancar, cor: 'text-gray-600', tamanho: 'w-5 h-5' %>
</div>
</div>
<div class="mt-3">
@@ -214,13 +214,14 @@
<% end %>
<% if pode_arquivar_motorista %>
<%= button_to '🗄️',
arquivar_motorista_consolidacao_path(@consolidacao, consolidacao_motorista_id: m[:registro].id),
<%= button_to arquivar_motorista_consolidacao_path(@consolidacao, consolidacao_motorista_id: m[:registro].id),
method: :post,
form: { data: { turbo_confirm: "Arquivar #{m[:registro].motorista_nome} desta consolidação? Você poderá restaurar depois." },
class: 'absolute top-3 right-3' },
class: 'text-gray-500 hover:text-red-400 border border-[#2a2a2a] hover:border-red-500/50 rounded-lg w-9 h-9 flex items-center justify-center',
title: "Arquivar #{m[:registro].motorista_nome}" %>
title: "Arquivar #{m[:registro].motorista_nome}" do %>
<%= icone :arquivar, cor: nil, tamanho: 'w-4 h-4' %>
<% end %>
<% end %>
</div>
<% end %>
@@ -229,7 +230,7 @@
<%# Motoristas arquivados — restauráveis %>
<% if @arquivados.present? %>
<div class="mt-6">
<h2 class="text-gray-400 font-semibold text-sm mb-2">🗄️ Motoristas arquivados (<%= @arquivados.size %>)</h2>
<h2 class="text-gray-400 font-semibold text-sm mb-2 flex items-center gap-2"><%= icone :arquivar %> Motoristas arquivados (<%= @arquivados.size %>)</h2>
<div class="space-y-2">
<% @arquivados.each do |cm| %>
<div class="flex items-center justify-between bg-[#141414] border border-[#2a2a2a] border-dashed rounded-xl px-4 py-3">
@@ -239,17 +240,19 @@
</div>
<div class="flex items-center gap-2">
<% if pode_arquivar_motorista %>
<%= button_to '♻️ Restaurar',
desarquivar_motorista_consolidacao_path(@consolidacao, consolidacao_motorista_id: cm.id),
<%= button_to desarquivar_motorista_consolidacao_path(@consolidacao, consolidacao_motorista_id: cm.id),
method: :post,
class: 'text-green-400 hover:text-green-300 border border-[#2a2a2a] hover:border-green-500/50 px-3 py-2 rounded-lg text-xs min-h-[40px]' %>
class: 'text-green-400 hover:text-green-300 border border-[#2a2a2a] hover:border-green-500/50 px-3 py-2 rounded-lg text-xs min-h-[40px] inline-flex items-center gap-1.5' do %>
<%= icone :restaurar, cor: nil, tamanho: 'w-3.5 h-3.5' %> Restaurar
<% end %>
<% end %>
<% if policy(@consolidacao).destroy? %>
<%= button_to '🗑️ Excluir',
excluir_motorista_consolidacao_path(@consolidacao, consolidacao_motorista_id: cm.id),
<%= button_to excluir_motorista_consolidacao_path(@consolidacao, consolidacao_motorista_id: cm.id),
method: :delete,
form: { data: { turbo_confirm: "Excluir DEFINITIVAMENTE #{cm.motorista_nome} desta consolidação? Os lançamentos dele serão apagados e isso não pode ser desfeito." } },
class: 'text-red-400 hover:text-red-300 border border-[#2a2a2a] hover:border-red-500/50 px-3 py-2 rounded-lg text-xs min-h-[40px]' %>
class: 'text-red-400 hover:text-red-300 border border-[#2a2a2a] hover:border-red-500/50 px-3 py-2 rounded-lg text-xs min-h-[40px] inline-flex items-center gap-1.5' do %>
<%= icone :excluir, cor: nil, tamanho: 'w-3.5 h-3.5' %> Excluir
<% end %>
<% end %>
</div>
</div>
@@ -272,25 +275,28 @@
<% if @consolidacao.rascunho? %>
<div class="flex flex-col sm:flex-row gap-2">
<% if !tudo_completo && tem_consolidados && tem_pendentes %>
<%= button_to '🔒 Arquivar pendentes e finalizar',
finalizar_parcial_consolidacao_path(@consolidacao),
<%= button_to finalizar_parcial_consolidacao_path(@consolidacao),
method: :post,
data: { turbo_confirm: 'Arquivar TODOS os veículos ainda não classificados 100% e finalizar? Eles ficam de fora desta consolidação (você resolve depois). Os veículos consolidados são pagos normalmente.' },
class: 'bg-orange-500 hover:bg-orange-600 text-black font-bold px-5 py-3.5 rounded-lg min-h-[48px] flex items-center justify-center text-center' %>
form: { data: { turbo_confirm: 'Arquivar TODOS os veículos ainda não classificados 100% e finalizar? Eles ficam de fora desta consolidação (você resolve depois). Os veículos consolidados são pagos normalmente.' } },
class: 'bg-orange-500 hover:bg-orange-600 text-black font-bold px-5 py-3.5 rounded-lg min-h-[48px] flex items-center justify-center text-center gap-2' do %>
<%= icone :travado, cor: nil, tamanho: 'w-4 h-4' %> Arquivar pendentes e finalizar
<% end %>
<% end %>
<%= button_to 'Finalizar consolidação ✓', finalizar_consolidacao_path(@consolidacao),
<%= button_to finalizar_consolidacao_path(@consolidacao),
method: :post,
disabled: !tudo_completo,
data: { turbo_confirm: 'Finalizar? Após finalizada, a consolidação não poderá ser editada por operadores.' },
class: "font-bold px-6 py-3.5 rounded-lg min-h-[48px] transition-colors
#{tudo_completo ? 'bg-green-600 hover:bg-green-500 text-white cursor-pointer' : 'bg-[#2a2a2a] text-gray-600 cursor-not-allowed'}" %>
form: { data: { turbo_confirm: 'Finalizar? Após finalizada, a consolidação não poderá ser editada por operadores.' } },
class: "font-bold px-6 py-3.5 rounded-lg min-h-[48px] transition-colors inline-flex items-center justify-center gap-2
#{tudo_completo ? 'bg-green-600 hover:bg-green-500 text-white cursor-pointer' : 'bg-[#2a2a2a] text-gray-600 cursor-not-allowed'}" do %>
Finalizar consolidação <%= icone :confirmar, cor: nil %>
<% end %>
</div>
<% end %>
</div>
</div>
<% unless tudo_completo %>
<p class="text-gray-500 text-sm mt-2 text-center">
⚠️ Classifique todas as entregas de todos os motoristas para finalizar tudo<% if tem_consolidados && tem_pendentes %> — ou use <strong>“Arquivar pendentes e finalizar”</strong> para fechar só os veículos já consolidados.<% end %>
<%= icone :alerta, cor: 'text-amber-400' %> Classifique todas as entregas de todos os motoristas para finalizar tudo<% if tem_consolidados && tem_pendentes %> — ou use <strong>“Arquivar pendentes e finalizar”</strong> para fechar só os veículos já consolidados.<% end %>
</p>
<% end %>
</div>