Correção de responsividade geral

This commit is contained in:
2026-07-22 01:04:22 -03:00
parent 84d6607d63
commit dc1b5c1b41
2 changed files with 94 additions and 55 deletions

View File

@@ -7,6 +7,7 @@ import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [
"linha", "checkbox", "selecionarTodos", "busca", "buscaVazia",
"barraSelecao", "contadorSelecao",
"resumo", "listaCol", "btnResumoLabel",
"toggles", "barra", "barraManuais", "percentual", "chipVeiculo",
"consolidarBtn", "consolidarHint",
@@ -98,6 +99,22 @@ export default class extends Controller {
if (linha && linha.classList.contains("hidden")) return
c.checked = marcar
})
this.atualizarSelecao()
}
// ── Barra de ações em massa: só existe quando há seleção ──
// Sem isto os 5 botões de pilar ficavam fixos no topo o tempo todo, comendo
// a altura da lista para não fazer nada (clicar sem seleção só alertava).
atualizarSelecao() {
const n = this.checkboxTargets.filter(c => c.checked).length
if (this.hasContadorSelecaoTarget) this.contadorSelecaoTarget.textContent = n
if (this.hasBarraSelecaoTarget) this.barraSelecaoTarget.classList.toggle("hidden", n === 0)
}
limparSelecao() {
this.checkboxTargets.forEach(c => (c.checked = false))
if (this.hasSelecionarTodosTarget) this.selecionarTodosTarget.checked = false
this.atualizarSelecao()
}
// O pilar está ativo (ring-2) na entrega indicada?
@@ -137,8 +154,7 @@ export default class extends Controller {
valor: valor
})
ids.forEach(id => this.setToggle(id, tipo, !remover))
this.checkboxTargets.forEach(c => c.checked = false)
if (this.hasSelecionarTodosTarget) this.selecionarTodosTarget.checked = false
this.limparSelecao() // some a barra de ações junto com a seleção
this.atualizarResumo(resp)
}

View File

@@ -12,38 +12,43 @@
<%# 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 flex items-center gap-2"><%= icone :caminhao, espaco: false %> <%= @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 safe_join(['Revisar (Passo 3)', icone(:avancar, cor: nil)], ' '),
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>
<%# Cabeçalho compacto: voltar, identificação e progresso numa faixa só.
Espaço vertical aqui é CARO — tudo isto fica fixo e é subtraído da lista,
que é o que o ADM realmente precisa ver. Antes eram 178px em dois cards. %>
<div class="flex flex-wrap items-center gap-x-3 gap-y-2 mb-2">
<%= link_to wizard_consolidacao_path(@consolidacao), title: 'Voltar (Passo 1)',
class: 'shrink-0 inline-flex items-center justify-center gap-1 bg-[#1a1a1a] hover:bg-[#2a2a2a] text-white border border-[#2a2a2a] hover:border-orange-500 font-semibold px-3 h-11 rounded-lg text-sm' do %>
←<span class="hidden sm:inline">Passo 1</span>
<% end %>
<%# basis-40: o nome não pode ser espremido até virar "P…" — se não couber
com o resto, a linha quebra em vez de esmagar a identificação. %>
<div class="min-w-0 flex-1 basis-40">
<h1 class="text-lg lg:text-xl font-bold text-white flex items-center gap-2 truncate"><%= icone :caminhao, espaco: false %> <%= @motorista %></h1>
<p class="text-gray-400 text-xs truncate"><%= @consolidacao.nome %> · <%= l @consolidacao.data_inicio, format: :short %> → <%= l @consolidacao.data_fim, format: :short %></p>
</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">
<%# Progresso ao lado do título (em vez de um card de 70px só p/ ele). No
celular vai para uma linha própria, no fim, para não brigar pelo espaço. %>
<p class="order-last w-full text-left sm:order-none sm:w-auto sm:shrink-0 sm:text-right text-xs text-gray-300">
<% if @veiculos_sel.any? %><%= icone :caminhao %> <%= @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="contadorClassificadas"><%= @classificadas %></span>/<span data-validacao-target="contadorTotal"><%= @total_entregas %></span>
<span class="hidden sm:inline">classificadas</span>
<span data-validacao-target="manuaisInfo" class="<%= 'hidden' unless @manuais.positive? %> text-blue-400">·
+<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>
<span class="text-orange-500 font-bold ml-1" data-validacao-target="percentual"></span>
</p>
<%= link_to revisar_consolidacao_consolidacao_entregas_path(@consolidacao, motorista: @motorista),
class: 'shrink-0 bg-orange-500 hover:bg-orange-600 text-black font-bold px-4 h-11 rounded-lg flex items-center gap-1 text-sm' do %>
Revisar<span class="hidden sm:inline"> (Passo 3)</span><%= icone :avancar, cor: nil %>
<% end %>
</div>
<%# Barra com 2 segmentos: laranja = elegíveis classificadas · azul = manuais %>
<div class="w-full bg-[#0a0a0a] rounded-full h-1.5 flex overflow-hidden mb-2">
<div data-validacao-target="barra" class="h-1.5 bg-orange-500 transition-all duration-300" style="width: 0%"></div>
<div data-validacao-target="barraManuais" class="h-1.5 bg-blue-500 transition-all duration-300" style="width: 0%"></div>
</div>
<%# Fechar por veículo — filtra a tela por carro, mostra o estado (pronto/
@@ -136,47 +141,36 @@
</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">
<%# Barra de ações — uma linha só. O botão "Adicionar lançamento" (bloco
abaixo, que carrega os modais) entra NESTA mesma faixa via flex `order`,
sem precisar mover os modais de lugar. %>
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl px-3 py-2 mb-2 flex flex-wrap items-center gap-x-3 gap-y-2">
<label class="order-1 flex items-center gap-2 text-gray-300 text-sm cursor-pointer select-none h-11">
<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 flex items-center gap-2">
<div class="order-3 ml-auto flex items-center gap-2">
<%# Oculta/mostra o resumo lateral (mais largura para a lista) %>
<button type="button" data-action="validacao#toggleResumo"
class="text-gray-400 hover:text-white text-sm border border-[#2a2a2a] hover:border-orange-500 px-3 py-2 rounded-lg whitespace-nowrap">
class="text-gray-400 hover:text-white text-sm border border-[#2a2a2a] hover:border-orange-500 px-3 h-11 rounded-lg whitespace-nowrap">
<%= icone :dashboard %> <span data-validacao-target="btnResumoLabel">Ocultar resumo</span>
</button>
<%= 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>
class: 'text-orange-400 hover:text-orange-300 text-sm border border-orange-500/40 px-3 h-11 rounded-lg flex items-center' %>
</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. %>
controllers existentes são reaproveitados; só o gatilho mudou.
Fica DENTRO da barra de ações (order-2) para não custar uma linha própria;
os modais são `fixed`, então não afetam o layout da faixa. %>
<% unless @consolidacao.finalizada? && current_user.operador? %>
<div class="relative mb-3"
<div class="order-2 relative"
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) %>"
@@ -184,7 +178,7 @@
<%# 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]">
class="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 h-11 rounded-lg text-sm whitespace-nowrap">
<%= icone :adicionar %> Adicionar lançamento
<%= icone :expandir, cor: 'text-gray-500', espaco: false %>
</button>
@@ -347,6 +341,34 @@
</div>
</div>
<% end %>
</div>
<%# Fim da barra de ações %>
<%# Ações em massa — SÓ aparecem quando há entregas selecionadas. Ocupavam
160px fixos para botões que, sem seleção, respondiam com um alerta
pedindo para selecionar algo. %>
<div data-validacao-target="barraSelecao"
class="hidden bg-orange-500/10 border border-orange-500/40 rounded-xl px-3 py-2 mb-2 flex flex-wrap items-center gap-x-3 gap-y-2">
<span class="text-sm text-white font-semibold whitespace-nowrap">
<span data-validacao-target="contadorSelecao">0</span> selecionada(s)
</span>
<span class="text-gray-400 text-xs">aplicar <span class="hidden sm:inline">(clique de novo p/ remover)</span>:</span>
<div class="flex items-center gap-2 flex-wrap">
<button data-action="click->validacao#marcarSelecionados" data-tipo="entrega_normal"
class="bg-orange-500 text-black font-bold px-3 h-11 rounded-lg text-xs">Normal</button>
<button data-action="click->validacao#marcarSelecionados" data-tipo="retirada"
class="bg-orange-800 text-white font-bold px-3 h-11 rounded-lg text-xs">Retirada</button>
<button data-action="click->validacao#marcarSelecionados" data-tipo="bonus"
class="bg-white text-black font-bold px-3 h-11 rounded-lg text-xs border border-orange-500">Bônus</button>
<button data-action="click->validacao#marcarSelecionados" data-tipo="desconto"
class="bg-black text-white font-bold px-3 h-11 rounded-lg text-xs border border-gray-700">Desconto</button>
<button data-action="click->validacao#marcarSelecionados" data-tipo="extraordinaria"
class="bg-purple-600 text-white font-bold px-3 h-11 rounded-lg text-xs">Extra</button>
</div>
<button type="button" data-action="validacao#limparSelecao"
class="ml-auto text-gray-400 hover:text-white text-xs underline whitespace-nowrap">limpar seleção</button>
</div>
</div>
<%# Fim do cabeçalho fixo — abaixo só a lista de NFs rola. %>
@@ -375,6 +397,7 @@
<%# Checkbox seleção em massa %>
<input type="checkbox" data-validacao-target="checkbox" value="<%= e.tracking_id %>"
data-action="change->validacao#atualizarSelecao"
class="rounded text-orange-500 bg-[#0a0a0a] border-[#2a2a2a] w-5 h-5">
<%# Dados da entrega %>