photo_server_json_flutter_c.../public/js/main.js
2026-02-26 11:48:04 +01:00

212 lines
No EOL
6.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ===============================
// 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 lheader, 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";
}
});