Atualização do layout da tela de consolidação do motorista

This commit is contained in:
2026-06-26 13:55:32 -03:00
parent 1bda666d5a
commit 418cf43353
3 changed files with 26 additions and 61 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -6,7 +6,7 @@ import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [
"linha", "checkbox", "selecionarTodos", "modoRemover", "rotuloAcao",
"linha", "checkbox", "selecionarTodos",
"toggles", "barra", "barraManuais", "percentual", "chipVeiculo",
"contadorClassificadas", "contadorTotal", "contadorManuais", "manuaisInfo",
"qtdNormal", "qtdRetirada", "qtdBonus", "qtdDesconto", "qtdExtraordinaria",
@@ -64,50 +64,21 @@ export default class extends Controller {
}
}
// ── Marcar todos como Normal ───────────────────────────────
async marcarTodos(event) {
const tipo = event.currentTarget.dataset.tipo
const remover = this.modoRemover
const verbo = remover ? "REMOVER de TODAS as entregas" : "Marcar TODAS as entregas como"
if (!confirm(`${verbo} ${this.labelTipo(tipo)}?`)) return
let valor = null
if (tipo === "extraordinaria" && !remover) {
valor = this.pedirValor()
if (valor === null) return
}
const resp = await this.post(this.massaUrlValue, {
tipo: tipo,
motorista: this.motoristaValue,
vehicle: this.veiculoValue,
tracking_ids: [], // vazio = todas (do veículo selecionado, se houver)
acao: remover ? "remover" : "adicionar",
valor: valor
})
this.linhaTargets.forEach(l => this.setToggle(l.dataset.tracking, tipo, !remover))
this.atualizarResumo(resp)
}
// ── Selecionar / desmarcar todos os checkboxes ─────────────
selecionarTodos(event) {
const marcar = event.currentTarget.checked
this.checkboxTargets.forEach(c => { c.checked = marcar })
}
// ── Modo das ações em massa: adicionar (padrão) ou remover ──
get modoRemover() {
return this.hasModoRemoverTarget && this.modoRemoverTarget.checked
// O pilar está ativo (ring-2) na entrega indicada?
pilarAtivo(tracking, tipo) {
const grupo = this.togglesTargets.find(t => t.dataset.tracking === tracking)
if (!grupo) return false
const btn = grupo.querySelector(`.toggle-btn[data-tipo="${tipo}"]`)
return !!btn && btn.classList.contains("ring-2")
}
alternarModo() {
if (this.hasRotuloAcaoTarget) {
this.rotuloAcaoTarget.textContent =
this.modoRemover ? "Remover dos selecionados:" : "Selecionados como:"
}
}
// ── Marcar selecionados como X ─────────────────────────────
// ── Aplicar/remover o pilar nos selecionados (toggle em massa) ──
async marcarSelecionados(event) {
const tipo = event.currentTarget.dataset.tipo
const ids = this.checkboxTargets.filter(c => c.checked).map(c => c.value)
@@ -117,7 +88,9 @@ export default class extends Controller {
return
}
const remover = this.modoRemover
// Toggle em massa: se TODAS as selecionadas já têm o pilar, remove de todas;
// caso contrário, aplica em todas.
const remover = ids.every(id => this.pilarAtivo(id, tipo))
let valor = null
if (tipo === "extraordinaria" && !remover) {

View File

@@ -1,7 +1,7 @@
<%# app/views/consolidacao_entregas/validar.html.erb — PASSO 2: Validar entregas %>
<% content_for :title, "Validar — #{@motorista}" %>
<div class="max-w-6xl mx-auto" data-controller="validacao"
<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 %>"
@@ -9,6 +9,9 @@
data-validacao-veiculo-value="<%= @veiculo %>"
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-6">
<%= link_to '← Voltar (Passo 1)', wizard_consolidacao_path(@consolidacao),
@@ -78,28 +81,15 @@
<%# Ações em massa + filtro %>
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-4 mb-4 flex flex-wrap items-center gap-3">
<span class="text-gray-400 text-sm font-semibold">Ações em massa:</span>
<button data-action="click->validacao#marcarTodos" data-tipo="entrega_normal"
class="bg-orange-500 hover:bg-orange-600 text-black font-bold px-4 py-2.5 rounded-lg text-sm min-h-[44px]">
✓ Marcar todos como Normal
</button>
<label class="flex items-center gap-2 text-gray-300 text-sm cursor-pointer select-none border-l border-[#2a2a2a] pl-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>
<label class="flex items-center gap-2 text-sm cursor-pointer select-none border-l border-[#2a2a2a] pl-3">
<input type="checkbox" data-validacao-target="modoRemover" data-action="change->validacao#alternarModo"
class="rounded text-red-500 bg-[#0a0a0a] border-[#2a2a2a] w-5 h-5">
<span class="text-gray-300">Modo remover (desmarcar)</span>
</label>
<div class="flex items-center gap-2">
<span class="text-gray-500 text-sm" data-validacao-target="rotuloAcao">Selecionados como:</span>
<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"
@@ -264,11 +254,13 @@
</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-4">
<div class="grid grid-cols-1 lg:grid-cols-4 gap-4 lg:flex-1 lg:min-h-0">
<%# ── Lista de entregas (3 colunas) ─────────────────── %>
<div class="lg:col-span-3 space-y-2">
<%# ── Lista de entregas (3 colunas) — área rolável ──── %>
<div class="lg:col-span-3 space-y-2 lg:overflow-y-auto lg:pr-1">
<% if @entregas.any? %>
<% @entregas.each do |e| %>
<% tipos_ativos = (@classificacoes[e.tracking_id] || []).map(&:tipo) %>
@@ -325,9 +317,9 @@
<% end %>
</div>
<%# ── Resumo lateral (1 coluna, sticky) ─────────────── %>
<div class="lg:col-span-1">
<div class="bg-[#1a1a1a] border border-[#2a2a2a] rounded-xl p-5 sticky top-4 space-y-4">
<%# ── 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">