398 lines
26 KiB
Plaintext
398 lines
26 KiB
Plaintext
<%# app/views/consolidacao_entregas/validar.html.erb — PASSO 2: Validar entregas %>
|
||
<% content_for :title, "Validar — #{@motorista}" %>
|
||
|
||
<div class="max-w-6xl mx-auto lg:h-[calc(100vh-4rem)] lg:flex lg:flex-col" data-controller="validacao"
|
||
data-validacao-url-value="<%= classificar_consolidacao_consolidacao_entregas_path(@consolidacao) %>"
|
||
data-validacao-massa-url-value="<%= classificar_em_massa_consolidacao_consolidacao_entregas_path(@consolidacao) %>"
|
||
data-validacao-motorista-value="<%= @motorista %>"
|
||
data-validacao-total-value="<%= @total_entregas %>"
|
||
data-validacao-veiculos-value="<%= @veiculos_sel.to_json %>"
|
||
data-validacao-preco-extraordinaria-value="<%= @precos[:extraordinaria] %>">
|
||
|
||
<%# Cabeçalho + controles fixos no topo (no desktop); só a lista de NFs rola. %>
|
||
<div class="lg:shrink-0">
|
||
|
||
<%# Header %>
|
||
<div class="mb-3">
|
||
<%= link_to '← Voltar (Passo 1)', wizard_consolidacao_path(@consolidacao),
|
||
class: 'inline-flex items-center gap-1 bg-[#1a1a1a] hover:bg-[#2a2a2a] text-white border border-[#2a2a2a] hover:border-orange-500 font-semibold px-4 py-2.5 rounded-lg text-sm min-h-[44px]' %>
|
||
<div class="flex items-center justify-between mt-2">
|
||
<div>
|
||
<h1 class="text-2xl font-bold text-white">🚚 <%= @motorista %></h1>
|
||
<p class="text-gray-400 text-sm"><%= @consolidacao.nome %> · <%= l @consolidacao.data_inicio, format: :short %> → <%= l @consolidacao.data_fim, format: :short %></p>
|
||
</div>
|
||
<%= link_to 'Revisar (Passo 3) →',
|
||
revisar_consolidacao_consolidacao_entregas_path(@consolidacao, motorista: @motorista),
|
||
class: 'bg-orange-500 hover:bg-orange-600 text-black font-bold px-5 py-3 rounded-lg min-h-[48px] flex items-center' %>
|
||
</div>
|
||
</div>
|
||
|
||
<%# Barra de progresso (reflete o veículo selecionado, se houver) %>
|
||
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-3 mb-3">
|
||
<div class="flex justify-between text-sm mb-2">
|
||
<span class="text-white font-semibold">
|
||
<% if @veiculos_sel.any? %>🚚 <%= @veiculos_sel.join(', ') %> — <% end %>
|
||
<span data-validacao-target="contadorClassificadas"><%= @classificadas %></span>
|
||
de <span data-validacao-target="contadorTotal"><%= @total_entregas %></span> entregas classificadas
|
||
<span data-validacao-target="manuaisInfo" class="<%= 'hidden' unless @manuais.positive? %> text-blue-400 font-normal">·
|
||
+<span data-validacao-target="contadorManuais"><%= @manuais %></span> manuais</span>
|
||
</span>
|
||
<span class="text-orange-500 font-bold" data-validacao-target="percentual"></span>
|
||
</div>
|
||
<%# Barra com 2 segmentos: laranja/verde = elegíveis classificadas · azul = lançamentos manuais %>
|
||
<div class="w-full bg-[#0a0a0a] rounded-full h-3 flex overflow-hidden">
|
||
<div data-validacao-target="barra" class="h-3 bg-orange-500 transition-all duration-300" style="width: 0%"></div>
|
||
<div data-validacao-target="barraManuais" class="h-3 bg-blue-500 transition-all duration-300" style="width: 0%"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<%# Fechar por veículo — filtra a tela por carro e mostra quais já estão fechados.
|
||
Só aparece quando o motorista usou mais de um veículo no período. %>
|
||
<% if @veiculos_status.size > 1 %>
|
||
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-3 mb-3">
|
||
<div class="flex items-center gap-2 mb-2">
|
||
<span class="text-gray-400 text-sm font-semibold">🚗 Fechar por veículo:</span>
|
||
<span class="text-gray-600 text-xs">clique para filtrar/somar um ou vários carros (clique de novo p/ tirar)</span>
|
||
</div>
|
||
<div class="flex flex-wrap gap-2">
|
||
<%# Chip "Todos" — limpa a seleção (mostra todos os carros) %>
|
||
<%= link_to validar_consolidacao_consolidacao_entregas_path(@consolidacao, motorista: @motorista),
|
||
class: "px-3 py-2 rounded-lg text-sm font-semibold border min-h-[40px] flex items-center
|
||
#{@veiculos_sel.empty? ? 'border-orange-500 text-orange-400 bg-orange-500/10' : 'border-[#2a2a2a] text-gray-300 hover:border-orange-500'}" do %>
|
||
Todos
|
||
<% end %>
|
||
|
||
<% @veiculos_status.each do |v| %>
|
||
<% selecionado = @veiculos_sel.include?(v[:vehicle]) %>
|
||
<%# Alterna este veículo dentro da seleção atual (multi-seleção) %>
|
||
<% nova_sel = selecionado ? (@veiculos_sel - [v[:vehicle]]) : (@veiculos_sel + [v[:vehicle]]) %>
|
||
<%= link_to validar_consolidacao_consolidacao_entregas_path(@consolidacao, motorista: @motorista, vehicle: nova_sel.presence),
|
||
data: { 'validacao-target': 'chipVeiculo', vehicle: v[:vehicle], eligible: v[:eligible] },
|
||
class: "px-3 py-2 rounded-lg text-sm font-semibold border min-h-[40px] flex items-center gap-2 transition-colors
|
||
#{selecionado ? 'border-orange-500 text-orange-400 bg-orange-500/10' : (v[:fechado] ? 'border-green-500 text-green-400 bg-green-500/10' : 'border-[#2a2a2a] text-gray-300 hover:border-orange-500')}" do %>
|
||
<span><%= v[:vehicle] %></span>
|
||
<span class="text-xs <%= v[:fechado] ? 'text-green-400' : 'text-gray-500' %>">
|
||
<span data-chip-feito><%= v[:classificadas] %></span>/<span data-chip-total><%= v[:eligible] %></span>
|
||
<span data-chip-check><%= '✓' if v[:fechado] %></span>
|
||
</span>
|
||
<% end %>
|
||
<% end %>
|
||
</div>
|
||
</div>
|
||
<% end %>
|
||
|
||
<%# Ações em massa + filtro %>
|
||
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-3 mb-3 flex flex-wrap items-center gap-3">
|
||
<label class="flex items-center gap-2 text-gray-300 text-sm cursor-pointer select-none">
|
||
<input type="checkbox" data-validacao-target="selecionarTodos"
|
||
data-action="change->validacao#selecionarTodos"
|
||
class="rounded text-orange-500 bg-[#0a0a0a] border-[#2a2a2a] w-5 h-5">
|
||
Selecionar todos
|
||
</label>
|
||
|
||
<div class="flex items-center gap-2 flex-wrap border-l border-[#2a2a2a] pl-3">
|
||
<span class="text-gray-500 text-sm">Aplicar nos selecionados <span class="text-gray-600">(clique de novo p/ remover)</span>:</span>
|
||
<button data-action="click->validacao#marcarSelecionados" data-tipo="entrega_normal"
|
||
class="bg-orange-500 text-black font-bold px-3 py-2 rounded-lg text-xs min-h-[44px]">Normal</button>
|
||
<button data-action="click->validacao#marcarSelecionados" data-tipo="retirada"
|
||
class="bg-orange-800 text-white font-bold px-3 py-2 rounded-lg text-xs min-h-[44px]">Retirada</button>
|
||
<button data-action="click->validacao#marcarSelecionados" data-tipo="bonus"
|
||
class="bg-white text-black font-bold px-3 py-2 rounded-lg text-xs border border-orange-500 min-h-[44px]">Bônus</button>
|
||
<button data-action="click->validacao#marcarSelecionados" data-tipo="desconto"
|
||
class="bg-black text-white font-bold px-3 py-2 rounded-lg text-xs border border-gray-700 min-h-[44px]">Desconto</button>
|
||
<button data-action="click->validacao#marcarSelecionados" data-tipo="extraordinaria"
|
||
class="bg-purple-600 text-white font-bold px-3 py-2 rounded-lg text-xs min-h-[44px]">Extra</button>
|
||
</div>
|
||
|
||
<div class="ml-auto">
|
||
<%= link_to params[:apenas_pendentes] == '1' ? 'Mostrar todas' : 'Apenas não classificadas',
|
||
validar_consolidacao_consolidacao_entregas_path(@consolidacao, motorista: @motorista, vehicle: @veiculos_sel.presence,
|
||
apenas_pendentes: params[:apenas_pendentes] == '1' ? nil : '1'),
|
||
class: 'text-orange-400 hover:text-orange-300 text-sm border border-orange-500/40 px-3 py-2 rounded-lg' %>
|
||
</div>
|
||
</div>
|
||
|
||
<%# Caixa de ferramentas — concentra os lançamentos avulsos (registro manual de
|
||
entrega e entrega de termo) num único botão com menu suspenso. Os modais e
|
||
controllers existentes são reaproveitados; só o gatilho mudou. %>
|
||
<% unless @consolidacao.finalizada? && current_user.operador? %>
|
||
<div class="relative mb-3"
|
||
data-controller="ferramentas apontamento-manual apontamento-termo"
|
||
data-apontamento-manual-apontar-manual-url-value="<%= apontar_manual_consolidacao_consolidacao_entregas_path(@consolidacao) %>"
|
||
data-apontamento-termo-apontar-termo-url-value="<%= apontar_termo_consolidacao_consolidacao_entregas_path(@consolidacao) %>"
|
||
data-apontamento-termo-motorista-value="<%= @motorista %>">
|
||
|
||
<%# 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 lançamento
|
||
<span class="text-gray-500">▾</span>
|
||
</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-manual#abrir ferramentas#fechar"
|
||
class="w-full text-left px-4 py-3 hover:bg-[#2a2a2a] border-l-2 border-transparent hover:border-purple-500">
|
||
<span class="block text-white font-semibold">📝 Registrar entrega manualmente</span>
|
||
<span class="block text-gray-500 text-xs">fora da base de rastreio</span>
|
||
</button>
|
||
<button type="button" data-action="apontamento-termo#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-blue-500">
|
||
<span class="block text-white font-semibold">📄 Entrega de termo</span>
|
||
<span class="block text-gray-500 text-xs">sem nota/código — só quantidade</span>
|
||
</button>
|
||
</div>
|
||
|
||
<%# Modal — registro manual de entrega %>
|
||
<div data-apontamento-manual-target="modal" data-action="click->apontamento-manual#fundo"
|
||
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">
|
||
<div class="flex items-center justify-between mb-1">
|
||
<h2 class="text-xl font-bold text-white">Registro manual de entrega</h2>
|
||
<button type="button" data-action="apontamento-manual#fechar"
|
||
class="text-gray-500 hover:text-white text-2xl leading-none">✕</button>
|
||
</div>
|
||
<p class="text-gray-400 text-sm mb-4">Lançe uma entrega à mão, sem buscar na base de rastreio. Use quando o motorista foi ao local mas a nota ficou registrada com outro motorista.</p>
|
||
|
||
<p data-apontamento-manual-target="erro" class="hidden bg-red-500/10 text-red-400 border border-red-500/30 rounded-lg px-3 py-2 text-sm mb-3"></p>
|
||
|
||
<%# Motorista (default = o motorista da tela; pode trocar) %>
|
||
<label class="block text-gray-400 text-sm mb-1">Motorista</label>
|
||
<input data-apontamento-manual-target="motorista" type="text" list="motoristas-consolidacao"
|
||
value="<%= @motorista %>" placeholder="Nome do motorista"
|
||
class="w-full bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-3 py-3 text-base focus:border-purple-500 focus:outline-none mb-3">
|
||
<datalist id="motoristas-consolidacao">
|
||
<% Array(@motoristas_consolidacao).each do |nome| %>
|
||
<option value="<%= nome %>"></option>
|
||
<% end %>
|
||
</datalist>
|
||
|
||
<%# NF + observação (texto livre) %>
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 mb-3">
|
||
<div>
|
||
<label class="block text-gray-400 text-sm mb-1">NF <span class="text-gray-600">(opcional)</span></label>
|
||
<input data-apontamento-manual-target="nf" type="text" inputmode="numeric" placeholder="Número da nota"
|
||
class="w-full bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-3 py-3 text-base focus:border-purple-500 focus:outline-none">
|
||
</div>
|
||
<div>
|
||
<label class="block text-gray-400 text-sm mb-1">Observação / local <span class="text-gray-600">(opcional)</span></label>
|
||
<input data-apontamento-manual-target="obs" type="text" placeholder="Ex.: UBS Sacomã"
|
||
class="w-full bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-3 py-3 text-base focus:border-purple-500 focus:outline-none">
|
||
</div>
|
||
</div>
|
||
|
||
<%# Pilares (múltiplos) %>
|
||
<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-3">
|
||
<% [['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| %>
|
||
<label class="flex items-center gap-2 bg-[#0a0a0a] border border-[#2a2a2a] rounded-lg px-3 py-3 cursor-pointer hover:border-purple-500 text-sm text-white">
|
||
<input type="checkbox" value="<%= tipo %>" data-apontamento-manual-target="tipoCheck"
|
||
<%= 'checked' if tipo == 'entrega_normal' %>
|
||
class="accent-purple-500">
|
||
<span><%= label %><br><span class="text-gray-500 text-xs"><%= moeda(preco) %></span></span>
|
||
</label>
|
||
<% end %>
|
||
</div>
|
||
|
||
<%# Valor customizado da Extraordinária (opcional) %>
|
||
<div class="mb-4">
|
||
<label class="block text-gray-400 text-sm mb-1">Valor da Extraordinária <span class="text-gray-600">(opcional — vazio usa o padrão)</span></label>
|
||
<input data-apontamento-manual-target="valorExtra" type="text" inputmode="decimal" placeholder="<%= moeda(Configuracao.preco_extraordinaria) %>"
|
||
class="w-full bg-[#0a0a0a] border border-[#2a2a2a] text-white rounded-lg px-3 py-3 text-base focus:border-purple-500 focus:outline-none">
|
||
</div>
|
||
|
||
<button type="button" data-action="apontamento-manual#adicionar"
|
||
class="w-full bg-green-600 hover:bg-green-500 text-white font-bold py-3.5 rounded-lg min-h-[48px]">
|
||
Adicionar apontamento ✓
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<%# Modal — entrega de termo %>
|
||
<div data-apontamento-termo-target="modal" data-action="click->apontamento-termo#fundo"
|
||
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">📄 Entrega de termo</h2>
|
||
<button type="button" data-action="apontamento-termo#fechar"
|
||
class="text-gray-500 hover:text-white text-2xl leading-none">✕</button>
|
||
</div>
|
||
<p class="text-gray-400 text-sm mb-4">Entrega sem nota fiscal nem código de rastreio. Informe quantos termos foram entregues.</p>
|
||
|
||
<p data-apontamento-termo-target="erro" class="hidden bg-red-500/10 text-red-400 border border-red-500/30 rounded-lg px-3 py-2 text-sm mb-3"></p>
|
||
|
||
<%# Motorista (contexto da tela) + preço unitário %>
|
||
<div class="flex items-center justify-between bg-[#0a0a0a] border border-[#2a2a2a] rounded-lg px-4 py-3 mb-4">
|
||
<div>
|
||
<p class="text-gray-500 text-xs">Motorista</p>
|
||
<p class="text-white font-semibold">🚚 <%= @motorista %></p>
|
||
</div>
|
||
<div class="text-right">
|
||
<p class="text-gray-500 text-xs">Preço por termo</p>
|
||
<p class="text-blue-400 font-semibold"><%= moeda(Configuracao.preco_termo) %></p>
|
||
</div>
|
||
</div>
|
||
|
||
<%# Stepper de quantidade %>
|
||
<label class="block text-gray-400 text-sm mb-2">Quantidade de termos</label>
|
||
<div class="flex items-center justify-center gap-3 mb-5">
|
||
<button type="button" data-action="apontamento-termo#menos"
|
||
class="w-12 h-12 rounded-lg bg-[#0a0a0a] border border-[#2a2a2a] hover:border-blue-500 text-white text-2xl font-bold leading-none">−</button>
|
||
<input data-apontamento-termo-target="quantidade" type="text" inputmode="numeric" value="1" readonly
|
||
class="w-24 text-center bg-[#0a0a0a] border border-[#2a2a2a] text-white text-2xl font-bold rounded-lg py-2.5 focus:outline-none">
|
||
<button type="button" data-action="apontamento-termo#mais"
|
||
class="w-12 h-12 rounded-lg bg-[#0a0a0a] border border-[#2a2a2a] hover:border-blue-500 text-white text-2xl font-bold leading-none">+</button>
|
||
</div>
|
||
|
||
<button type="button" data-action="apontamento-termo#adicionar"
|
||
class="w-full bg-green-600 hover:bg-green-500 text-white font-bold py-3.5 rounded-lg min-h-[48px]">
|
||
Adicionar termos ✓
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<% end %>
|
||
</div>
|
||
<%# Fim do cabeçalho fixo — abaixo só a lista de NFs rola. %>
|
||
|
||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-3 lg:flex-1 lg:min-h-0">
|
||
|
||
<%# ── Lista de entregas (3 colunas) — área rolável ──── %>
|
||
<div class="lg:col-span-3 space-y-2 lg:overflow-y-auto lg:pr-1">
|
||
<%# 🔍 Busca na listagem — filtra os cards por NF, local, endereço ou veículo %>
|
||
<div class="sticky top-0 z-20 bg-[#0a0a0a] pb-2">
|
||
<div class="relative">
|
||
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500 pointer-events-none">🔍</span>
|
||
<input type="search" data-validacao-target="busca" data-action="input->validacao#filtrarBusca"
|
||
placeholder="Buscar NF, local, endereço ou veículo…" autocomplete="off"
|
||
class="w-full bg-[#1a1a1a] border border-[#2a2a2a] rounded-lg pl-10 pr-3 py-2.5 text-sm text-gray-200 placeholder-gray-500 focus:border-orange-500 focus:outline-none">
|
||
</div>
|
||
<p data-validacao-target="buscaVazia" class="hidden text-gray-500 text-xs mt-2 px-1">Nenhuma nota encontrada para a busca.</p>
|
||
</div>
|
||
<% if @entregas.any? %>
|
||
<% @entregas.each do |e| %>
|
||
<% tipos_ativos = (@classificacoes[e.tracking_id] || []).map(&:tipo) %>
|
||
<div class="bg-[#1a1a1a] border <%= e.falhada? ? 'border-red-500/50' : 'border-[#2a2a2a]' %> rounded-xl p-4 flex flex-col lg:flex-row lg:items-center gap-3"
|
||
data-validacao-target="linha" data-tracking="<%= e.tracking_id %>"
|
||
data-vehicle="<%= e.vehicle.presence || '(sem veículo)' %>"
|
||
data-busca="<%= [e.numero_nf, e.local, e.address, e.vehicle].compact.join(' ').downcase %>"
|
||
data-classificada="<%= tipos_ativos.any? ? '1' : '0' %>">
|
||
|
||
<%# Checkbox seleção em massa %>
|
||
<input type="checkbox" data-validacao-target="checkbox" value="<%= e.tracking_id %>"
|
||
class="rounded text-orange-500 bg-[#0a0a0a] border-[#2a2a2a] w-5 h-5">
|
||
|
||
<%# Dados da entrega %>
|
||
<div class="flex-1 min-w-0">
|
||
<p class="text-white font-semibold truncate">
|
||
NF <%= e.numero_nf %> · <%= e.local %>
|
||
<% if e.falhada? %>
|
||
<span class="ml-1 align-middle text-[10px] font-bold uppercase tracking-wide bg-red-500/20 text-red-400 border border-red-500/40 px-1.5 py-0.5 rounded">⚠️ Insucesso</span>
|
||
<% else %>
|
||
<span class="ml-1 align-middle text-[10px] font-bold uppercase tracking-wide bg-green-500/20 text-green-400 border border-green-500/40 px-1.5 py-0.5 rounded">✓ Entregue</span>
|
||
<% end %>
|
||
</p>
|
||
<p class="text-gray-400 text-xs truncate">📍 <%= e.address.presence || 'sem endereço' %></p>
|
||
<p class="text-gray-500 text-xs">
|
||
📅 <%= e.checkout&.strftime('%d/%m/%Y') || '—' %> · 🚚 <%= e.vehicle.presence || 'sem veículo' %>
|
||
<% if e.atraso_minutos > 0 %> · ⏱️ atraso <%= e.atraso_minutos %>min<% end %>
|
||
</p>
|
||
</div>
|
||
|
||
<%# Toggles coloridos — laranja=normal, laranja escuro=retirada, branco=bônus, preto=desconto %>
|
||
<div class="flex flex-wrap gap-1.5 lg:shrink-0" data-validacao-target="toggles" data-tracking="<%= e.tracking_id %>">
|
||
<% [
|
||
['entrega_normal', 'Normal', 'bg-orange-500 text-black'],
|
||
['retirada', 'Retirada', 'bg-orange-800 text-white'],
|
||
['bonus', 'Bônus', 'bg-white text-black border border-orange-500'],
|
||
['desconto', 'Desc.', 'bg-black text-white border border-gray-700'],
|
||
['extraordinaria', 'Extra', 'bg-purple-600 text-white']
|
||
].each do |tipo, label, cores| %>
|
||
<button data-action="click->validacao#classificar"
|
||
data-tracking="<%= e.tracking_id %>" data-tipo="<%= tipo %>"
|
||
class="toggle-btn <%= cores %> font-bold px-3 py-2.5 rounded-lg text-xs min-h-[44px] transition-all
|
||
<%= tipos_ativos.include?(tipo) ? 'ring-2 ring-green-400 scale-105' : 'opacity-50 hover:opacity-100' %>">
|
||
<%= label %>
|
||
</button>
|
||
<% end %>
|
||
</div>
|
||
</div>
|
||
<% end %>
|
||
<% else %>
|
||
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-10 text-center">
|
||
<p class="text-4xl mb-3">🎉</p>
|
||
<p class="text-gray-400">Nenhuma entrega pendente neste filtro.</p>
|
||
</div>
|
||
<% end %>
|
||
</div>
|
||
|
||
<%# ── Resumo lateral (1 coluna) — rola junto se precisar ─────── %>
|
||
<div class="lg:col-span-1 lg:overflow-y-auto">
|
||
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-5 space-y-4">
|
||
<h3 class="text-white font-bold">📊 Resumo</h3>
|
||
|
||
<div class="space-y-2 text-sm">
|
||
<div class="flex justify-between items-center">
|
||
<span class="flex items-center gap-2"><span class="w-3 h-3 bg-orange-500 rounded-full"></span> Normal</span>
|
||
<span class="text-white font-bold" data-validacao-target="qtdNormal">0</span>
|
||
</div>
|
||
<div class="flex justify-between items-center">
|
||
<span class="flex items-center gap-2"><span class="w-3 h-3 bg-orange-800 rounded-full"></span> Retirada</span>
|
||
<span class="text-white font-bold" data-validacao-target="qtdRetirada">0</span>
|
||
</div>
|
||
<div class="flex justify-between items-center">
|
||
<span class="flex items-center gap-2"><span class="w-3 h-3 bg-white rounded-full border border-orange-500"></span> Bônus</span>
|
||
<span class="text-white font-bold" data-validacao-target="qtdBonus">0</span>
|
||
</div>
|
||
<div class="flex justify-between items-center">
|
||
<span class="flex items-center gap-2"><span class="w-3 h-3 bg-black border border-gray-600 rounded-full"></span> Desconto</span>
|
||
<span class="text-white font-bold" data-validacao-target="qtdDesconto">0</span>
|
||
</div>
|
||
<div class="flex justify-between items-center">
|
||
<span class="flex items-center gap-2"><span class="w-3 h-3 bg-purple-600 rounded-full"></span> Extraordinária</span>
|
||
<span class="text-white font-bold" data-validacao-target="qtdExtraordinaria">0</span>
|
||
</div>
|
||
<div class="flex justify-between items-center">
|
||
<span class="flex items-center gap-2"><span class="w-3 h-3 bg-blue-600 rounded-full"></span> Termo</span>
|
||
<span class="text-white font-bold" data-validacao-target="qtdTermo">0</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="border-t border-[#2a2a2a] pt-4 flex justify-between items-center text-sm">
|
||
<span class="flex items-center gap-2 text-blue-400"><span class="w-3 h-3 bg-blue-500 rounded-full"></span> Apontamentos manuais</span>
|
||
<span class="text-blue-400 font-bold" data-validacao-target="qtdManuais"><%= @manuais %></span>
|
||
</div>
|
||
|
||
<div class="border-t border-[#2a2a2a] pt-4">
|
||
<p class="text-gray-500 text-xs mb-1">Total do motorista</p>
|
||
<p class="text-orange-500 font-black text-2xl" data-validacao-target="valorTotal">R$ 0,00</p>
|
||
</div>
|
||
|
||
<div class="border-t border-[#2a2a2a] pt-4 text-xs text-gray-500 space-y-1">
|
||
<p>💰 Normal: <%= moeda(@precos[:entrega_normal]) %></p>
|
||
<p>📦 Retirada: <%= moeda(@precos[:retirada]) %></p>
|
||
<p>⭐ Bônus: <%= moeda(@precos[:bonus]) %></p>
|
||
<p>⚠️ Desconto: -<%= moeda(@precos[:desconto]) %></p>
|
||
<p>✨ Extraordinária: <%= moeda(@precos[:extraordinaria]) %> (valor por entrega)</p>
|
||
<p>📄 Termo: <%= moeda(@precos[:termo]) %></p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<%# Estado inicial para o Stimulus %>
|
||
<script type="application/json" id="validacao-estado-inicial">
|
||
<% _todas = @classificacoes.values.flatten %>
|
||
<%= raw({
|
||
classificadas: @classificadas,
|
||
manuais: @manuais,
|
||
por_tipo: _todas.group_by(&:tipo).transform_values { |arr| arr.sum(&:quantidade) },
|
||
valor_total: _todas.sum { |c| c.tipo == 'desconto' ? -c.valor_aplicado : c.valor_aplicado }.to_f
|
||
}.to_json) %>
|
||
</script>
|