Adição de Mata com os pontos da onde foi entreque e corrige o filtro ao vivo

This commit is contained in:
2026-06-29 21:06:08 -03:00
parent 6b899ebafa
commit 7d6c79f878
5 changed files with 144 additions and 27 deletions

View File

@@ -333,19 +333,88 @@
}
// ── Mapa de calor (Leaflet) ──
function escapeHtml(s) {
return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
});
}
function popupHtml(p) {
const linha = (icone, val) => val ? ('<div>' + icone + ' ' + escapeHtml(val) + '</div>') : '';
return '' +
'<div style="min-width:200px">' +
'<div style="font-weight:700;color:#f97316">NF ' + escapeHtml(p.nf) + '</div>' +
'<div style="font-weight:600;margin-bottom:4px">' + escapeHtml(p.nome) + '</div>' +
'<div style="color:#16a34a;font-size:11px;margin-bottom:6px">✔ Entrega realizada</div>' +
linha('📍', p.endereco) +
linha('🏥', p.unidade) +
linha('🚚', p.motorista) +
linha('🕒', p.checkout) +
'</div>';
}
function initMapas() {
if (typeof L === 'undefined') return;
document.querySelectorAll('.mapa-calor').forEach(function (el) {
if (el._leaflet_id) return;
const pontos = JSON.parse(el.dataset.pontos || '[]');
const centro = JSON.parse(el.dataset.centro || '[-23.55,-46.63]');
document.querySelectorAll('.mapa-box').forEach(function (box) {
const el = box.querySelector('.mapa-calor');
if (!el || el._leaflet_id) return;
const heat = JSON.parse(el.dataset.heat || '[]');
const pontos = JSON.parse(el.dataset.pontos || '[]');
const centro = JSON.parse(el.dataset.centro || '[-23.55,-46.63]');
const mapa = L.map(el).setView(centro, 11);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap', maxZoom: 19
}).addTo(mapa);
if (pontos.length && L.heatLayer) {
L.heatLayer(pontos, { radius: 18, blur: 22, maxZoom: 14 }).addTo(mapa);
// Camada de calor
const heatLayer = (heat.length && L.heatLayer)
? L.heatLayer(heat, { radius: 18, blur: 22, maxZoom: 14 }) : null;
// Camada de pontos (marcadores com popup)
const marcadores = L.layerGroup();
pontos.forEach(function (p) {
L.circleMarker([p.lat, p.lng], {
radius: 6, color: '#0a0a0a', weight: 1,
fillColor: '#f97316', fillOpacity: 0.85
}).bindPopup(popupHtml(p)).addTo(marcadores);
});
// Começa no Calor (cai para Pontos se não houver calor)
let atual = heatLayer || marcadores;
atual.addTo(mapa);
function mostrar(view) {
mapa.removeLayer(heatLayer || marcadores);
if (marcadores) mapa.removeLayer(marcadores);
if (heatLayer) mapa.removeLayer(heatLayer);
if (view === 'pontos') { marcadores.addTo(mapa); }
else { (heatLayer || marcadores).addTo(mapa); }
box.querySelectorAll('.map-toggle button').forEach(function (b) {
const on = b.dataset.view === view;
b.classList.toggle('bg-orange-500', on);
b.classList.toggle('text-black', on);
b.classList.toggle('font-semibold', on);
b.classList.toggle('text-gray-300', !on);
});
}
box.querySelectorAll('.map-toggle button').forEach(function (b) {
b.addEventListener('click', function () { mostrar(b.dataset.view); });
});
// Tela cheia (Fullscreen API sobre o container do mapa)
const btnFs = box.querySelector('.map-fullscreen');
if (btnFs) {
btnFs.addEventListener('click', function () {
if (document.fullscreenElement) { document.exitFullscreen(); }
else if (el.requestFullscreen) { el.requestFullscreen(); }
});
}
document.addEventListener('fullscreenchange', function () {
setTimeout(function () { mapa.invalidateSize(); }, 150);
});
setTimeout(function () { mapa.invalidateSize(); }, 200);
});
}