212 lines
No EOL
6.5 KiB
JavaScript
212 lines
No EOL
6.5 KiB
JavaScript
// ===============================
|
||
// AVVIO
|
||
// ===============================
|
||
console.log("main.js avviato");
|
||
|
||
// ===============================
|
||
// PATCH: misura l'altezza reale dell'header e aggiorna --header-h
|
||
// (serve per far partire la mappa subito sotto l’header, anche su mobile)
|
||
// ===============================
|
||
(function () {
|
||
const root = document.documentElement;
|
||
const header = document.querySelector('header');
|
||
|
||
function setHeaderHeight() {
|
||
const h = header ? Math.round(header.getBoundingClientRect().height) : 60;
|
||
root.style.setProperty('--header-h', h + 'px');
|
||
}
|
||
|
||
setHeaderHeight();
|
||
|
||
if (window.ResizeObserver && header) {
|
||
const ro = new ResizeObserver(setHeaderHeight);
|
||
ro.observe(header);
|
||
} else {
|
||
window.addEventListener('resize', setHeaderHeight);
|
||
window.addEventListener('orientationchange', setHeaderHeight);
|
||
}
|
||
|
||
window.addEventListener('load', setHeaderHeight);
|
||
})();
|
||
|
||
// ===============================
|
||
// PATCH: quando si apre la mappa (#globalMap.open) invalida le dimensioni Leaflet
|
||
// (utile perché prima era display:none; invalidateSize evita “tagli” o tile sfasati)
|
||
// ===============================
|
||
(function () {
|
||
const mapEl = document.getElementById('globalMap');
|
||
if (!mapEl) return;
|
||
|
||
function invalidateWhenOpen() {
|
||
if (!mapEl.classList.contains('open')) return;
|
||
// Aspetta un tick così il layout è aggiornato
|
||
setTimeout(() => {
|
||
try {
|
||
// Sostituisci con la tua variabile dell'istanza L.map, se diversa
|
||
window.leafletMapInstance?.invalidateSize();
|
||
} catch (e) {
|
||
console.warn('invalidateSize non eseguito:', e);
|
||
}
|
||
}, 0);
|
||
}
|
||
|
||
// 1) Osserva il cambio classe (quando aggiungi .open)
|
||
const mo = new MutationObserver((mutations) => {
|
||
if (mutations.some(m => m.attributeName === 'class')) {
|
||
invalidateWhenOpen();
|
||
}
|
||
});
|
||
mo.observe(mapEl, { attributes: true, attributeFilter: ['class'] });
|
||
|
||
// 2) Fallback: se usi il bottone #openMapBtn per aprire/chiudere
|
||
document.getElementById('openMapBtn')?.addEventListener('click', () => {
|
||
setTimeout(invalidateWhenOpen, 0);
|
||
});
|
||
})();
|
||
|
||
// ===============================
|
||
// LOGIN AUTOMATICO SU INDEX
|
||
// ===============================
|
||
document.addEventListener("DOMContentLoaded", async () => {
|
||
try {
|
||
// 1) Carica config
|
||
const cfgRes = await fetch('/config');
|
||
const cfg = await cfgRes.json();
|
||
window.BASE_URL = cfg.baseUrl;
|
||
|
||
// 2) Recupera token salvato
|
||
const savedToken = localStorage.getItem("token");
|
||
|
||
// Se non c'è token → mostra login
|
||
if (!savedToken) {
|
||
document.getElementById("loginModal").style.display = "flex";
|
||
return;
|
||
}
|
||
|
||
// 3) Verifica token
|
||
const ping = await fetch(`${window.BASE_URL}/photos`, {
|
||
headers: { "Authorization": "Bearer " + savedToken }
|
||
});
|
||
|
||
if (!ping.ok) {
|
||
// Token invalido → cancella e mostra login
|
||
localStorage.removeItem("token");
|
||
document.getElementById("loginModal").style.display = "flex";
|
||
return;
|
||
}
|
||
|
||
// 4) Token valido → salva e carica gallery
|
||
window.token = savedToken;
|
||
loadPhotos();
|
||
|
||
} catch (err) {
|
||
console.error("Errore autenticazione:", err);
|
||
document.getElementById("loginModal").style.display = "flex";
|
||
}
|
||
});
|
||
|
||
// ===============================
|
||
// VARIABILI GLOBALI
|
||
// ===============================
|
||
let currentSort = "desc";
|
||
let currentGroup = "auto";
|
||
let currentFilter = null;
|
||
|
||
window.currentSort = currentSort;
|
||
window.currentGroup = currentGroup;
|
||
window.currentFilter = currentFilter;
|
||
|
||
// ===============================
|
||
// MENU ⋮
|
||
// ===============================
|
||
const optionsBtn = document.getElementById("optionsBtn");
|
||
const optionsSheetEl = document.getElementById("optionsSheet");
|
||
|
||
optionsBtn?.addEventListener("click", () => {
|
||
optionsSheetEl?.classList.add("open");
|
||
});
|
||
|
||
// ===============================
|
||
// BOTTONI OPZIONI
|
||
// ===============================
|
||
document.querySelectorAll("#optionsSheet .sheet-btn").forEach(btn => {
|
||
btn.addEventListener("click", () => {
|
||
if (btn.dataset.sort) window.currentSort = currentSort = btn.dataset.sort;
|
||
if (btn.dataset.group) window.currentGroup = currentGroup = btn.dataset.group;
|
||
if (btn.dataset.filter) window.currentFilter = currentFilter = btn.dataset.filter;
|
||
|
||
optionsSheetEl?.classList.remove("open");
|
||
refreshGallery();
|
||
});
|
||
});
|
||
|
||
// ===============================
|
||
// REFRESH GALLERY
|
||
// ===============================
|
||
function refreshGallery() {
|
||
console.log("Aggiornamento galleria...");
|
||
|
||
const data = Array.isArray(window.photosData) ? window.photosData : [];
|
||
let photos = [...data];
|
||
|
||
if (typeof applyFilters === 'function') photos = applyFilters(photos);
|
||
if (typeof sortByDate === 'function') photos = sortByDate(photos, currentSort);
|
||
|
||
let sections = [{ label: 'Tutte', photos }];
|
||
if (typeof groupByDate === 'function') sections = groupByDate(photos, currentGroup);
|
||
|
||
if (typeof renderGallery === 'function') {
|
||
renderGallery(sections);
|
||
}
|
||
}
|
||
|
||
window.refreshGallery = refreshGallery;
|
||
|
||
// ===============================
|
||
// SETTINGS (⚙️) — apre admin.html
|
||
// ===============================
|
||
const settingsBtn = document.getElementById('settingsBtn');
|
||
settingsBtn?.addEventListener('click', () => {
|
||
window.location.href = "admin.html";
|
||
});
|
||
|
||
// ===============================
|
||
// LOGIN SUBMIT
|
||
// ===============================
|
||
document.getElementById("loginSubmit").addEventListener("click", async () => {
|
||
const email = document.getElementById("loginEmail").value;
|
||
const password = document.getElementById("loginPassword").value;
|
||
const errorEl = document.getElementById("loginError");
|
||
|
||
errorEl.textContent = "";
|
||
|
||
try {
|
||
const res = await fetch(`${window.BASE_URL}/auth/login`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ email, password })
|
||
});
|
||
|
||
if (!res.ok) {
|
||
errorEl.textContent = "Utente o password errati";
|
||
return;
|
||
}
|
||
|
||
const data = await res.json();
|
||
const token = data.token;
|
||
|
||
// Salva token
|
||
localStorage.setItem("token", token);
|
||
window.token = token;
|
||
|
||
// Chiudi login
|
||
document.getElementById("loginModal").style.display = "none";
|
||
|
||
// Carica gallery
|
||
loadPhotos();
|
||
|
||
} catch (err) {
|
||
console.error("Errore login:", err);
|
||
errorEl.textContent = "Errore di connessione al server";
|
||
}
|
||
}); |