document.addEventListener("DOMContentLoaded", () => {
// Step 1: Attach lat/lng data to each card
const listings = document.querySelectorAll("a[href^='/listings/']");
listings.forEach(listing => {
const geoSpan = listing.querySelector(".geo-data");
if (geoSpan) {
const lat = geoSpan.dataset.lat;
const lng = geoSpan.dataset.lng;
if (lat && lng) {
listing.classList.add("listing");
listing.dataset.lat = lat;
listing.dataset.lng = lng;
}
}
});
// Step 2: Proceed with distance sorting
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error);
}
function success(position) {
const userLat = position.coords.latitude;
const userLng = position.coords.longitude;
const cards = document.querySelectorAll('.listing');
const results = [];
cards.forEach(card => {
const lat = parseFloat(card.dataset.lat);
const lng = parseFloat(card.dataset.lng);
const distance = getDistanceFromLatLonInMi(userLat, userLng, lat, lng);
results.push({ element: card, distance });
});
results.sort((a, b) => a.distance - b.distance);
const container = cards[0]?.parentNode;
results.forEach(r => {
container.appendChild(r.element);
});
// Optional: Add distance display
results.forEach(result => {
const distText = document.createElement('p');
distText.innerText = `📍 ${result.distance.toFixed(2)} mi from you`;
distText.classList.add("text-sm", "text-gray-500", "mt-2");
result.element.appendChild(distText);
});
}
function error(err) {
console.warn(`ERROR(${err.code}): ${err.message}`);
}
function getDistanceFromLatLonInMi(lat1, lon1, lat2, lon2) {
const R = 3958.8; // Miles
const dLat = deg2rad(lat2 - lat1);
const dLon = deg2rad(lon2 - lon1);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
function deg2rad(deg) {
return deg * (Math.PI / 180);
}
});