Adição do campo de busca no mapa
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
.flatpickr-months .flatpickr-prev-month svg, .flatpickr-months .flatpickr-next-month svg { fill: #f97316; }
|
||||
/* O mapa do Leaflet usa fundo claro — moldura escura ao redor */
|
||||
.leaflet-container { background: #1a1a1a; }
|
||||
/* Realça ruas e nomes no tile escuro (CARTO dark_all tem baixo contraste) */
|
||||
.tiles-escuro-contraste { filter: brightness(1.45) contrast(1.2) saturate(0.9); }
|
||||
</style>
|
||||
<% end %>
|
||||
|
||||
@@ -356,6 +358,7 @@
|
||||
linha('📍', p.endereco) +
|
||||
linha('🏥', p.unidade) +
|
||||
linha('🚚', p.motorista) +
|
||||
linha('🚗', p.veiculo) +
|
||||
linha('🕒', p.checkout) +
|
||||
foto +
|
||||
'</div>';
|
||||
@@ -389,7 +392,8 @@
|
||||
// Camadas base (todas grátis, sem chave): escuro (padrão, combina com o
|
||||
// tema), claro e satélite.
|
||||
const escuro = L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
|
||||
attribution: '© OpenStreetMap © CARTO', subdomains: 'abcd', maxZoom: 20
|
||||
attribution: '© OpenStreetMap © CARTO', subdomains: 'abcd', maxZoom: 20,
|
||||
className: 'tiles-escuro-contraste'
|
||||
});
|
||||
const claro = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap', maxZoom: 19
|
||||
@@ -412,21 +416,26 @@
|
||||
// O popup é uma FUNÇÃO, então o HTML da foto só é montado/baixado quando
|
||||
// o balão é clicado — nada de imagem é requisitado ao carregar o mapa.
|
||||
let marcadores = null;
|
||||
let entradas = []; // [{ marker, p }] — para a busca filtrar sem recriar
|
||||
const resultadosBusca = L.layerGroup();
|
||||
function construirMarcadores() {
|
||||
if (marcadores) return marcadores;
|
||||
marcadores = L.layerGroup();
|
||||
pontos.forEach(function (p) {
|
||||
L.marker([p.lat, p.lng], { icon: ICONE })
|
||||
.bindPopup(function () { return popupHtml(p); }, { maxWidth: 260 })
|
||||
.addTo(marcadores);
|
||||
const marker = L.marker([p.lat, p.lng], { icon: ICONE })
|
||||
.bindPopup(function () { return popupHtml(p); }, { maxWidth: 260 });
|
||||
marker.addTo(marcadores);
|
||||
entradas.push({ marker: marker, p: p });
|
||||
});
|
||||
return marcadores;
|
||||
}
|
||||
|
||||
// Começa no Calor (cai para Pontos se não houver calor)
|
||||
let vistaAtual = heatLayer ? 'heat' : 'pontos';
|
||||
(heatLayer || construirMarcadores()).addTo(mapa);
|
||||
|
||||
function mostrar(view) {
|
||||
vistaAtual = view;
|
||||
if (heatLayer) mapa.removeLayer(heatLayer);
|
||||
if (marcadores) mapa.removeLayer(marcadores);
|
||||
if (view === 'pontos') { construirMarcadores().addTo(mapa); }
|
||||
@@ -441,9 +450,62 @@
|
||||
}
|
||||
|
||||
box.querySelectorAll('.map-toggle button').forEach(function (b) {
|
||||
b.addEventListener('click', function () { mostrar(b.dataset.view); });
|
||||
b.addEventListener('click', function () {
|
||||
const inputBusca = box.querySelector('.mapa-busca');
|
||||
if (inputBusca && inputBusca.value) { inputBusca.value = ''; }
|
||||
limparBusca();
|
||||
mostrar(b.dataset.view);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Busca por NF / paciente / veículo ──
|
||||
const inputBusca = box.querySelector('.mapa-busca');
|
||||
const infoBusca = box.querySelector('.mapa-busca-info');
|
||||
|
||||
function limparBusca() {
|
||||
mapa.removeLayer(resultadosBusca);
|
||||
resultadosBusca.clearLayers();
|
||||
if (infoBusca) infoBusca.textContent = '';
|
||||
}
|
||||
|
||||
function aplicarBusca(termo) {
|
||||
const q = String(termo || '').trim().toLowerCase();
|
||||
if (!q) {
|
||||
limparBusca();
|
||||
mostrar(vistaAtual); // restaura a visão padrão (Calor ou Pontos)
|
||||
return;
|
||||
}
|
||||
construirMarcadores();
|
||||
if (heatLayer) mapa.removeLayer(heatLayer);
|
||||
if (marcadores) mapa.removeLayer(marcadores);
|
||||
resultadosBusca.clearLayers();
|
||||
|
||||
const casa = function (v) { return String(v == null ? '' : v).toLowerCase().indexOf(q) !== -1; };
|
||||
const achados = entradas.filter(function (e) {
|
||||
return casa(e.p.nf) || casa(e.p.nome) || casa(e.p.veiculo);
|
||||
});
|
||||
achados.forEach(function (e) { e.marker.addTo(resultadosBusca); });
|
||||
resultadosBusca.addTo(mapa);
|
||||
|
||||
if (achados.length) {
|
||||
const grupo = L.featureGroup(achados.map(function (e) { return e.marker; }));
|
||||
mapa.fitBounds(grupo.getBounds(), { padding: [40, 40], maxZoom: 16 });
|
||||
if (achados.length === 1) { achados[0].marker.openPopup(); }
|
||||
if (infoBusca) infoBusca.textContent = achados.length + (achados.length === 1 ? ' resultado' : ' resultados');
|
||||
} else {
|
||||
if (infoBusca) infoBusca.textContent = 'Nenhum resultado';
|
||||
}
|
||||
}
|
||||
|
||||
if (inputBusca) {
|
||||
let debounce = null;
|
||||
inputBusca.addEventListener('input', function () {
|
||||
clearTimeout(debounce);
|
||||
const valor = inputBusca.value;
|
||||
debounce = setTimeout(function () { aplicarBusca(valor); }, 200);
|
||||
});
|
||||
}
|
||||
|
||||
// Tela cheia (Fullscreen API sobre o container do mapa)
|
||||
const btnFs = box.querySelector('.map-fullscreen');
|
||||
if (btnFs) {
|
||||
|
||||
Reference in New Issue
Block a user