Mudança dos cardes das operaçoes no formato vertical e adição do logo na tela inicial
This commit is contained in:
@@ -4,12 +4,8 @@
|
||||
|
||||
<%# Logo / Header %>
|
||||
<div class="text-center mb-10">
|
||||
<div class="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-[#f97316] mb-4">
|
||||
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M13 16V6a1 1 0 00-1-1H4a1 1 0 00-1 1v10a1 1 0 001 1h1m8-1a1 1 0 01-1 1H9m4-1V8a1 1 0 011-1h2.586a1 1 0 01.707.293l3.414 3.414a1 1 0 01.293.707V16a1 1 0 01-1 1h-1m-6-1a1 1 0 001 1h1M5 17a2 2 0 104 0m-4 0a2 2 0 114 0m6 0a2 2 0 104 0m-4 0a2 2 0 114 0"/>
|
||||
</svg>
|
||||
</div>
|
||||
<%= image_tag '/logo-reem.png', alt: 'Reem Transporte',
|
||||
class: 'h-20 w-auto mx-auto mb-4 object-contain' %>
|
||||
<h1 class="text-3xl font-bold text-white">Reem Logística</h1>
|
||||
<p class="text-gray-400 mt-1 text-sm">Sistema de Controle de Custos</p>
|
||||
</div>
|
||||
|
||||
@@ -17,34 +17,27 @@
|
||||
|
||||
<%# ── KPIs ─────────────────────────────────────────────── %>
|
||||
<% pct_total = ->(parte) { metricas.total.zero? ? 0 : (parte * 100.0 / metricas.total).round(1) } %>
|
||||
<div class="grid grid-cols-2 xl:grid-cols-4 gap-4">
|
||||
<div class="group bg-[#1a1a1a] rounded-2xl border border-white/5 p-6 transition-all duration-200 hover:border-white/20 hover:bg-[#202020] hover:-translate-y-0.5 hover:shadow-lg hover:shadow-black/40">
|
||||
<p class="text-gray-400 text-sm font-medium mb-2">📦 Total de Entregas</p>
|
||||
<p class="text-4xl font-black text-white inline-block origin-left transition-transform duration-200 group-hover:scale-110"><%= metricas.total %></p>
|
||||
<p class="text-xs text-gray-500 mt-2 h-0 overflow-hidden opacity-0 transition-all duration-200 group-hover:h-4 group-hover:opacity-100">
|
||||
✅ <%= metricas.sucesso %> · <span class="text-blue-500">●</span> <%= metricas.recusas %> · ⏳ <%= metricas.pendentes %>
|
||||
</p>
|
||||
<%# Cards de status empilhados na vertical (orientação da img 13): título discreto
|
||||
em cima, número grande colorido embaixo. %>
|
||||
<div class="space-y-3">
|
||||
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
|
||||
<p class="text-gray-400 text-sm font-medium mb-1">Total de Entregas</p>
|
||||
<p class="text-5xl font-black text-white leading-none"><%= metricas.total %></p>
|
||||
</div>
|
||||
<div class="group bg-[#1a1a1a] rounded-2xl border border-white/5 p-6 transition-all duration-200 hover:border-green-500/40 hover:bg-[#202020] hover:-translate-y-0.5 hover:shadow-lg hover:shadow-black/40">
|
||||
<p class="text-gray-400 text-sm font-medium mb-2">✅ Total de Sucesso</p>
|
||||
<p class="text-4xl font-black text-green-400 inline-block origin-left transition-transform duration-200 group-hover:scale-110"><%= metricas.sucesso %></p>
|
||||
<p class="text-xs text-gray-500 mt-2 h-0 overflow-hidden opacity-0 transition-all duration-200 group-hover:h-4 group-hover:opacity-100">
|
||||
<%= pct_total.(metricas.sucesso) %>% do total
|
||||
</p>
|
||||
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
|
||||
<p class="text-gray-400 text-sm font-medium mb-1">Total de Sucesso</p>
|
||||
<p class="text-5xl font-black text-green-400 leading-none"><%= metricas.sucesso %></p>
|
||||
<p class="text-xs text-gray-500 mt-2"><%= pct_total.(metricas.sucesso) %>% do total</p>
|
||||
</div>
|
||||
<div class="group bg-[#1a1a1a] rounded-2xl border border-white/5 p-6 transition-all duration-200 hover:border-blue-500/40 hover:bg-[#202020] hover:-translate-y-0.5 hover:shadow-lg hover:shadow-black/40">
|
||||
<p class="text-gray-400 text-sm font-medium mb-2">❌ Total de Recusas</p>
|
||||
<p class="text-4xl font-black text-blue-500 inline-block origin-left transition-transform duration-200 group-hover:scale-110"><%= metricas.recusas %></p>
|
||||
<p class="text-xs text-gray-500 mt-2 h-0 overflow-hidden opacity-0 transition-all duration-200 group-hover:h-4 group-hover:opacity-100">
|
||||
<%= pct_total.(metricas.recusas) %>% do total
|
||||
</p>
|
||||
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
|
||||
<p class="text-gray-400 text-sm font-medium mb-1">Total de Recusas</p>
|
||||
<p class="text-5xl font-black text-blue-500 leading-none"><%= metricas.recusas %></p>
|
||||
<p class="text-xs text-gray-500 mt-2"><%= pct_total.(metricas.recusas) %>% do total</p>
|
||||
</div>
|
||||
<div class="group bg-[#1a1a1a] rounded-2xl border border-white/5 p-6 transition-all duration-200 hover:border-yellow-500/40 hover:bg-[#202020] hover:-translate-y-0.5 hover:shadow-lg hover:shadow-black/40">
|
||||
<p class="text-gray-400 text-sm font-medium mb-2">⏳ Entregas Pendentes</p>
|
||||
<p class="text-4xl font-black text-yellow-400 inline-block origin-left transition-transform duration-200 group-hover:scale-110"><%= metricas.pendentes %></p>
|
||||
<p class="text-xs text-gray-500 mt-2 h-0 overflow-hidden opacity-0 transition-all duration-200 group-hover:h-4 group-hover:opacity-100">
|
||||
<%= pct_total.(metricas.pendentes) %>% do total
|
||||
</p>
|
||||
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-6">
|
||||
<p class="text-gray-400 text-sm font-medium mb-1">Entregas Pendentes</p>
|
||||
<p class="text-5xl font-black text-yellow-400 leading-none"><%= metricas.pendentes %></p>
|
||||
<p class="text-xs text-gray-500 mt-2"><%= pct_total.(metricas.pendentes) %>% do total</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -310,6 +310,37 @@
|
||||
});
|
||||
});
|
||||
|
||||
// Plugin: desenha o valor centralizado DENTRO de cada segmento da barra
|
||||
// (pula segmentos baixos demais e valores zero).
|
||||
const barValueLabels = {
|
||||
id: 'barValueLabels',
|
||||
afterDatasetsDraw: function (chart) {
|
||||
const g = chart.ctx;
|
||||
g.save();
|
||||
g.font = '600 11px system-ui, -apple-system, sans-serif';
|
||||
g.fillStyle = '#ffffff';
|
||||
g.textAlign = 'center';
|
||||
g.textBaseline = 'middle';
|
||||
chart.data.datasets.forEach(function (ds, i) {
|
||||
const meta = chart.getDatasetMeta(i);
|
||||
if (meta.hidden) return;
|
||||
meta.data.forEach(function (bar, idx) {
|
||||
const v = Number(ds.data[idx]) || 0;
|
||||
if (!v) return;
|
||||
const p = bar.getProps(['x', 'y', 'base'], true);
|
||||
if (Math.abs(p.base - p.y) < 16) return; // segmento pequeno demais
|
||||
g.fillText(String(v), p.x, (p.y + p.base) / 2);
|
||||
});
|
||||
});
|
||||
g.restore();
|
||||
}
|
||||
};
|
||||
|
||||
// Total do dia (soma das séries) para o % no tooltip.
|
||||
const totalDoDia = function (datasets, idx) {
|
||||
return datasets.reduce(function (s, d) { return s + (Number(d.data[idx]) || 0); }, 0);
|
||||
};
|
||||
|
||||
document.querySelectorAll('canvas.dash-bars').forEach(function (ctx) {
|
||||
Chart.getChart(ctx)?.destroy();
|
||||
new Chart(ctx, {
|
||||
@@ -321,8 +352,10 @@
|
||||
{ label: 'Falhas', data: JSON.parse(ctx.dataset.failed), backgroundColor: COR_FAIL }
|
||||
]
|
||||
},
|
||||
plugins: [barValueLabels],
|
||||
options: {
|
||||
responsive: true, maintainAspectRatio: false,
|
||||
interaction: { mode: 'index', intersect: false },
|
||||
onHover: cursorPonteiro,
|
||||
onClick: function (e, els) {
|
||||
if (!els.length) return;
|
||||
@@ -334,7 +367,32 @@
|
||||
x: { stacked: true, ticks: { color: '#6b7280', maxTicksLimit: 12 }, grid: { color: 'rgba(255,255,255,0.04)' } },
|
||||
y: { stacked: true, beginAtZero: true, ticks: { color: '#6b7280' }, grid: { color: 'rgba(255,255,255,0.04)' } }
|
||||
},
|
||||
plugins: { legend: { labels: { color: '#9ca3af' } } }
|
||||
plugins: {
|
||||
legend: { labels: { color: '#9ca3af' } },
|
||||
// Card de hover no tema escuro do app: data + Completas/Falhas (n e %) + Total.
|
||||
tooltip: {
|
||||
mode: 'index', intersect: false,
|
||||
backgroundColor: '#1f1f1f',
|
||||
borderColor: 'rgba(255,255,255,0.1)', borderWidth: 1,
|
||||
titleColor: '#ffffff', bodyColor: '#d1d5db', footerColor: '#9ca3af',
|
||||
padding: 12, cornerRadius: 12, boxPadding: 4, usePointStyle: true,
|
||||
titleFont: { weight: '700' }, footerFont: { weight: '600' },
|
||||
callbacks: {
|
||||
title: function (items) { return items.length ? items[0].label : ''; },
|
||||
label: function (item) {
|
||||
const total = totalDoDia(item.chart.data.datasets, item.dataIndex);
|
||||
const v = Number(item.raw) || 0;
|
||||
const pct = total ? (v * 100 / total).toFixed(2) : '0.00';
|
||||
return ' ' + item.dataset.label + ': ' + v + ' (' + pct + '%)';
|
||||
},
|
||||
footer: function (items) {
|
||||
if (!items.length) return '';
|
||||
const total = totalDoDia(items[0].chart.data.datasets, items[0].dataIndex);
|
||||
return 'Total: ' + total + ' (100%)';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user