feat: complete node task 2a
This commit is contained in:
+54
-66
@@ -79,68 +79,6 @@ async function updateClocks() {
|
||||
updateClocks();
|
||||
setInterval(updateClocks, 1000);
|
||||
|
||||
// --- Airport Autocomplete ---
|
||||
// const airportInput = document.querySelector('input[placeholder*="airport"]');
|
||||
// let dropdownDiv;
|
||||
// if (airportInput) {
|
||||
// console.log("hi");
|
||||
// dropdownDiv = document.createElement("div");
|
||||
// dropdownDiv.className =
|
||||
// "absolute bg-white border border-gray-300 rounded shadow z-10 w-full max-h-48 overflow-y-auto top-[calc(100%+10px)]";
|
||||
// dropdownDiv.style.display = "none";
|
||||
// airportInput.parentNode.appendChild(dropdownDiv);
|
||||
// airportInput.addEventListener("input", async function () {
|
||||
// const val = airportInput.value.trim();
|
||||
// if (val.length < 3) {
|
||||
// dropdownDiv.style.display = "none";
|
||||
// return;
|
||||
// }
|
||||
// try {
|
||||
// const res = await fetch(`/airports?search=${encodeURIComponent(val)}`);
|
||||
// if (!res.ok) throw new Error("Failed to fetch airports");
|
||||
// const airports = await res.json();
|
||||
// if (!Array.isArray(airports) || airports.length === 0) {
|
||||
// dropdownDiv.innerHTML =
|
||||
// '<div class="p-2 text-gray-500">No results</div>';
|
||||
// dropdownDiv.style.display = "block";
|
||||
// return;
|
||||
// }
|
||||
// dropdownDiv.innerHTML = airports
|
||||
// .map(
|
||||
// (a, i) =>
|
||||
// `<div class="p-2 hover:bg-sky-100 cursor-pointer" data-index="${i}">${a.name}</div>`
|
||||
// )
|
||||
// .join("");
|
||||
// dropdownDiv.style.display = "block";
|
||||
// Array.from(dropdownDiv.children).forEach((child, i) => {
|
||||
// child.addEventListener("click", () => {
|
||||
// airportInput.value = child.textContent;
|
||||
// dropdownDiv.style.display = "none";
|
||||
// selectedAirport = airports[i];
|
||||
// console.log("hey");
|
||||
// airportInput.textContent = `hold`;
|
||||
// if (selectedAirport) {
|
||||
// console.log(selectedAirport);
|
||||
// airportInput.value = `${selectedAirport.name} (${selectedAirport.code})`;
|
||||
// showMap(
|
||||
// Number(selectedAirport.latitude_deg),
|
||||
// Number(selectedAirport.longitude_deg)
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// } catch (err) {
|
||||
// dropdownDiv.innerHTML =
|
||||
// '<div class="p-2 text-red-500">Error loading airports</div>';
|
||||
// dropdownDiv.style.display = "block";
|
||||
// }
|
||||
// });
|
||||
// // Hide dropdown on blur
|
||||
// airportInput.addEventListener("blur", () =>
|
||||
// setTimeout(() => (dropdownDiv.style.display = "none"), 200)
|
||||
// );
|
||||
// }
|
||||
|
||||
// --- Airport Autocomplete ---
|
||||
const airportInput = document.querySelector('input[placeholder*="airport"]');
|
||||
let dropdownDiv;
|
||||
@@ -163,10 +101,6 @@ if (airportInput) {
|
||||
selectedAirport = currentAirports[index]; // Use latest fetched data
|
||||
airportInput.value = `${selectedAirport.name} (${selectedAirport.code})`; // Set once
|
||||
|
||||
// showMap(
|
||||
// Number(selectedAirport.latitude_deg),
|
||||
// Number(selectedAirport.longitude_deg)
|
||||
// );
|
||||
onAirportSelected(selectedAirport);
|
||||
dropdownDiv.style.display = "none";
|
||||
});
|
||||
@@ -307,6 +241,11 @@ function logWidgetClick(widgetName) {
|
||||
widget_name: widgetName,
|
||||
browser_type: navigator.userAgent,
|
||||
}),
|
||||
}).then(async (res) => {
|
||||
if (res.status === 429) {
|
||||
const data = await res.json();
|
||||
if (data.redirect) window.location.href = data.redirect;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -394,6 +333,55 @@ if (coinInput && coinBtn && coinResult) {
|
||||
});
|
||||
}
|
||||
|
||||
// --- Upload Widget ---
|
||||
const uploadInput = document.querySelector(
|
||||
'input[type="file"][id="upload-input"]'
|
||||
);
|
||||
const uploadBtn = document.getElementById("upload-btn");
|
||||
const uploadPreview = document.getElementById("upload-preview");
|
||||
const uploadError = document.getElementById("upload-error");
|
||||
|
||||
async function fetchLatestUpload() {
|
||||
try {
|
||||
const res = await fetch("/upload/latest");
|
||||
const data = await res.json();
|
||||
if (data.url && uploadPreview) {
|
||||
uploadPreview.src = data.url;
|
||||
uploadPreview.style.display = "";
|
||||
} else if (uploadPreview) {
|
||||
uploadPreview.style.display = "none";
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (uploadBtn && uploadInput) {
|
||||
uploadBtn.addEventListener("click", async function () {
|
||||
if (!uploadInput.files || !uploadInput.files[0]) {
|
||||
if (uploadError) uploadError.textContent = "Please select an image.";
|
||||
return;
|
||||
}
|
||||
const formData = new FormData();
|
||||
formData.append("image", uploadInput.files[0]);
|
||||
try {
|
||||
const res = await fetch("/upload", { method: "POST", body: formData });
|
||||
const data = await res.json();
|
||||
if (data.url) {
|
||||
if (uploadPreview) {
|
||||
uploadPreview.src = data.url;
|
||||
uploadPreview.style.display = "";
|
||||
}
|
||||
if (uploadError) uploadError.textContent = "";
|
||||
} else {
|
||||
if (uploadError)
|
||||
uploadError.textContent = data.error || "Upload failed.";
|
||||
}
|
||||
} catch (err) {
|
||||
if (uploadError) uploadError.textContent = "Upload failed.";
|
||||
}
|
||||
});
|
||||
}
|
||||
fetchLatestUpload();
|
||||
|
||||
// Attach click listeners to widgets
|
||||
function attachAnalyticListeners() {
|
||||
const widgets = [
|
||||
|
||||
Reference in New Issue
Block a user