(function () { var root = document.getElementById('nc-blog-map-root'); if (!root || typeof L === 'undefined') return; var mapEl = root.querySelector('.blog-listing-map-el'); var sidebar = root.querySelector('.blog-listing-map-sidebar'); var countEl = root.querySelector('.blog-listing-map-count'); if (!mapEl || !sidebar) return; var NC_AREAS = [ 'North County', 'Oceanside', 'Escondido', 'Encinitas', 'Vista', 'Carlsbad', 'Ramona', 'San Marcos', 'Poway', 'Rancho Bernardo', 'Cardiff', 'Solana Beach', 'Fallbrook', 'Valley Center', '4S Ranch', 'Rancho Santa Fe', ]; var CAT_COLORS = { thrift: '#6c3cff', antique: '#d97706', consignment: '#ec4899', garage: '#ea580c', swap: '#2563eb', books: '#0d9488', vinyl: '#9333ea', sporting: '#16a34a', furniture: '#b45309', }; var CAT_LABELS = { thrift: 'Thrift Store', antique: 'Antiques', consignment: 'Consignment', garage: 'Garage / Estate Sale', swap: 'Swap Meet', books: 'Bookstore', vinyl: 'Vinyl / Records', sporting: 'Sporting Goods', furniture: 'Furniture', }; function catKey(item) { var pc = (item.primaryCategory || '').toLowerCase(); if (pc.indexOf('antique') >= 0) return 'antique'; if (pc.indexOf('consignment') >= 0) return 'consignment'; if (pc.indexOf('garage') >= 0 || pc.indexOf('estate') >= 0) return 'garage'; if (pc.indexOf('swap') >= 0) return 'swap'; if (pc.indexOf('book') >= 0) return 'books'; if (pc.indexOf('vinyl') >= 0 || pc.indexOf('record') >= 0) return 'vinyl'; if (pc.indexOf('sport') >= 0) return 'sporting'; if (pc.indexOf('furniture') >= 0) return 'furniture'; return 'thrift'; } function esc(s) { return String(s || '') .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } fetch('/api/listings') .then(function (r) { return r.json(); }) .then(function (all) { var items = all.filter(function (l) { var area = (l.area || '').trim().toLowerCase(); return l.lat && l.lng && NC_AREAS.some(function (a) { return area.indexOf(a.toLowerCase()) >= 0; }); }); if (countEl) countEl.textContent = items.length + ' stores'; var map = L.map(mapEl, { zoomControl: true, scrollWheelZoom: false }) .setView([33.14, -117.23], 10); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors', maxZoom: 19, }).addTo(map); mapEl.addEventListener('wheel', function (e) { if (e.ctrlKey) { e.preventDefault(); map.setZoom(map.getZoom() + (e.deltaY > 0 ? -1 : 1)); } }, { passive: false }); var bounds = []; var mkrs = []; items.forEach(function (item, i) { var n = i + 1; var key = catKey(item); var color = CAT_COLORS[key] || '#6c3cff'; bounds.push([item.lat, item.lng]); var iconHtml = '
' + n + '
'; var icon = L.divIcon({ className: '', html: iconHtml, iconSize: [24, 24], iconAnchor: [12, 12], popupAnchor: [0, -14], }); var marker = L.marker([item.lat, item.lng], { icon: icon }); var addr = (item.address || '').trim(); var dirUrl = 'https://www.google.com/maps/search/?api=1&query=' + encodeURIComponent(addr || item.name + ' San Diego'); var label = CAT_LABELS[key] || item.primaryCategory || 'Shop'; var popupHtml = '
' + '' + '' + (addr ? '' : '') + 'Get Directions ↗' + '
'; marker.bindPopup(popupHtml, { maxWidth: 260 }); marker.addTo(map); mkrs.push({ marker: marker, item: item, color: color, n: n }); }); if (bounds.length > 1) { map.fitBounds(bounds, { padding: [24, 24], maxZoom: 12 }); } sidebar.innerHTML = mkrs.map(function (m, i) { return '
' + '
' + m.n + '
' + '
' + '
' + esc(m.item.name) + '
' + '
' + esc(m.item.area) + '
' + '
'; }).join(''); var sidebarItems = sidebar.querySelectorAll('.nc-sidebar-item'); sidebarItems.forEach(function (el) { el.addEventListener('click', function () { var mk = mkrs[parseInt(el.dataset.idx, 10)]; map.setView(mk.marker.getLatLng(), 14, { animate: true }); mk.marker.openPopup(); sidebarItems.forEach(function (x) { x.classList.remove('highlighted'); }); el.classList.add('highlighted'); }); }); map.invalidateSize(); setTimeout(function () { map.invalidateSize(); }, 250); setTimeout(function () { map.invalidateSize(); }, 800); }) .catch(function () { if (sidebar) sidebar.textContent = 'Could not load listings.'; }); })();