Corrige 3 erros de runtime + filtro de faixa de datas no dashboard
Erros corrigidos (reportados em prints): - Logout dava "No route matches [GET] /auth/logout": link usava method: :delete (rails-ujs), que o Turbo ignora -> agora data-turbo-method - /admin/usuarios estourava NoMethodError 'admin_ou_gerente?'/'admin?' na UserPolicy -> adicionados helpers que delegam para o User - Nova consolidação estourava NoMethodError 'new?' na ConsolidacaoPolicy -> ApplicationPolicy passa a definir new? (= create?) e edit? (= update?) Dashboard: - Substitui a navegação por mês por um filtro de calendário com faixa de datas (Flatpickr, range mode) que auto-submete inicio/fim - Controller passa a consultar por período (Entrega.no_periodo) em vez de do_mes; gráfico diário limitado a ~1 trimestre Specs: UserPolicy + new? na ConsolidacaoPolicy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3,39 +3,27 @@
|
||||
|
||||
<div class="space-y-6">
|
||||
|
||||
<%# Header + filtro de mês %>
|
||||
<%# Header + filtro por faixa de datas %>
|
||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-white">Dashboard</h1>
|
||||
<p class="text-gray-400 text-sm mt-0.5">
|
||||
<%= @data_referencia.strftime('%B de %Y').capitalize %> · Atualizado às <%= Time.now.strftime('%H:%M') %>
|
||||
<%= @periodo_inicio.strftime('%d/%m/%Y') %> – <%= @periodo_fim.strftime('%d/%m/%Y') %>
|
||||
· Atualizado às <%= Time.now.strftime('%H:%M') %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<%# Navegação de mês %>
|
||||
<div class="flex items-center gap-2">
|
||||
<%= link_to dashboard_path(data: (@data_referencia - 1.month).to_s),
|
||||
class: 'p-2.5 bg-[#1a1a1a] hover:bg-white/10 border border-white/10 rounded-xl
|
||||
text-gray-400 hover:text-white transition-colors' do %>
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
|
||||
</svg>
|
||||
<% end %>
|
||||
|
||||
<div class="px-4 py-2.5 bg-[#1a1a1a] border border-white/10 rounded-xl text-white font-medium min-w-[140px] text-center">
|
||||
<%= @data_referencia.strftime('%b %Y').capitalize %>
|
||||
<%# Filtro de calendário — seleciona uma faixa de datas %>
|
||||
<form id="dashboard-filtro-form" method="get" action="<%= dashboard_path %>" class="flex items-center gap-2">
|
||||
<div class="relative">
|
||||
<span class="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-orange-500">📅</span>
|
||||
<input type="text" id="periodo-range" readonly placeholder="Selecione o período"
|
||||
class="cursor-pointer pl-4 pr-10 py-2.5 bg-[#1a1a1a] border border-white/10 rounded-xl
|
||||
text-white text-sm w-[240px] focus:outline-none focus:border-orange-500 placeholder-gray-500">
|
||||
</div>
|
||||
|
||||
<% unless @data_referencia >= Date.today.beginning_of_month %>
|
||||
<%= link_to dashboard_path(data: (@data_referencia + 1.month).to_s),
|
||||
class: 'p-2.5 bg-[#1a1a1a] hover:bg-white/10 border border-white/10 rounded-xl
|
||||
text-gray-400 hover:text-white transition-colors' do %>
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
|
||||
</svg>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<input type="hidden" name="inicio" id="inicio-hidden" value="<%= @periodo_inicio.strftime('%Y-%m-%d') %>">
|
||||
<input type="hidden" name="fim" id="fim-hidden" value="<%= @periodo_fim.strftime('%Y-%m-%d') %>">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<%# CARDS GRANDES — KPIs %>
|
||||
@@ -81,7 +69,7 @@
|
||||
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
|
||||
<p class="text-gray-400 text-sm font-medium mb-2">🚗 Motoristas</p>
|
||||
<p class="text-4xl font-black text-white mb-1"><%= @motoristas.count %></p>
|
||||
<p class="text-gray-500 text-sm">com entregas no mês</p>
|
||||
<p class="text-gray-500 text-sm">com entregas no período</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -93,7 +81,7 @@
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h2 class="text-lg font-semibold text-white">Evolução Diária</h2>
|
||||
<p class="text-gray-400 text-sm">Valor estimado por dia no mês</p>
|
||||
<p class="text-gray-400 text-sm">Valor estimado por dia no período</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-xs text-gray-500">
|
||||
<span class="inline-block w-3 h-0.5 bg-[#f97316] rounded"></span> Valor (R$)
|
||||
@@ -137,7 +125,7 @@
|
||||
<% else %>
|
||||
<div class="text-center py-8 text-gray-500">
|
||||
<div class="text-3xl mb-2">🚚</div>
|
||||
<p class="text-sm">Nenhuma entrega paga neste mês</p>
|
||||
<p class="text-sm">Nenhuma entrega paga neste período</p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
@@ -162,6 +150,41 @@
|
||||
|
||||
</div>
|
||||
|
||||
<%# Flatpickr — date range picker (CDN, mesmo padrão do Chart.js) %>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/l10n/pt.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
const input = document.getElementById('periodo-range');
|
||||
if (!input || typeof flatpickr === 'undefined') return;
|
||||
|
||||
const inicio = document.getElementById('inicio-hidden').value;
|
||||
const fim = document.getElementById('fim-hidden').value;
|
||||
|
||||
// formata Date local → YYYY-MM-DD (evita deslocamento de fuso do toISOString)
|
||||
const toISO = (d) =>
|
||||
d.getFullYear() + '-' +
|
||||
String(d.getMonth() + 1).padStart(2, '0') + '-' +
|
||||
String(d.getDate()).padStart(2, '0');
|
||||
|
||||
flatpickr(input, {
|
||||
mode: 'range',
|
||||
locale: 'pt',
|
||||
dateFormat: 'd/m/Y',
|
||||
defaultDate: [inicio, fim],
|
||||
maxDate: 'today',
|
||||
onClose: function (selectedDates) {
|
||||
if (selectedDates.length === 2) {
|
||||
document.getElementById('inicio-hidden').value = toISO(selectedDates[0]);
|
||||
document.getElementById('fim-hidden').value = toISO(selectedDates[1]);
|
||||
document.getElementById('dashboard-filtro-form').requestSubmit();
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<%# Chart.js via CDN %>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user