diff --git a/app.js b/app.js index 6e4288b..8f8399c 100644 --- a/app.js +++ b/app.js @@ -1,16 +1,54 @@ +// =============================== +// CONFIG +// =============================== const API_URL = 'https://prova.patachina.it/photos'; +let photosData = []; +let currentPhoto = null; + +// =============================== +// DEBUG INIZIALE +// =============================== +console.log("app.js caricato correttamente"); + + +// =============================== +// FETCH DELLE FOTO +// =============================== async function loadPhotos() { - const res = await fetch(API_URL); - if (!res.ok) { - console.error('Errore nel fetch', res.status); + console.log("Inizio fetch:", API_URL); + + let res; + try { + res = await fetch(API_URL); + } catch (e) { + console.error("Errore fetch:", e); return; } - const data = await res.json(); - renderGallery(data); + + console.log("Status fetch:", res.status); + + const text = await res.text(); + console.log("Risposta grezza (prime 200 chars):", text.substring(0, 200)); + + try { + photosData = JSON.parse(text); + console.log("JSON parse OK, numero foto:", photosData.length); + } catch (e) { + console.error("Errore nel parse JSON:", e); + return; + } + + renderGallery(photosData); } + +// =============================== +// RENDER GALLERIA +// =============================== function renderGallery(photos) { + console.log("Render gallery, foto:", photos.length); + const gallery = document.getElementById('gallery'); gallery.innerHTML = ''; @@ -19,29 +57,48 @@ function renderGallery(photos) { thumbDiv.className = 'thumb'; const img = document.createElement('img'); - // anteprima img.src = `https://prova.patachina.it/${photo.thub1}`; img.alt = photo.name || ''; + img.loading = "lazy"; thumbDiv.appendChild(img); - // click: apri immagine grande + // Fallback se thub2 manca + const preview = photo.thub2 + ? `https://prova.patachina.it/${photo.thub2}` + : `https://prova.patachina.it/${photo.thub1}`; + thumbDiv.addEventListener('click', () => { - openModal(`https://prova.patachina.it/${photo.path}`); + openModal( + `https://prova.patachina.it/${photo.path}`, + preview, + photo + ); }); gallery.appendChild(thumbDiv); }); } -// Modal + +// =============================== +// MODALE IMMAGINE +// =============================== const modal = document.getElementById('modal'); const modalImg = document.getElementById('modalImage'); const modalClose = document.getElementById('modalClose'); -function openModal(src) { - modalImg.src = src; +function openModal(srcOriginal, srcPreview, photo) { + currentPhoto = photo; + + modalImg.src = srcPreview; modal.classList.add('open'); + + const img = new Image(); + img.src = srcOriginal; + img.onload = () => { + modalImg.src = srcOriginal; + }; } function closeModal() { @@ -54,5 +111,56 @@ modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); }); -// avvio + +// =============================== +// PANNELLO INFO +// =============================== +const infoPanel = document.getElementById('infoPanel'); +const infoBtn = document.getElementById('modalInfoBtn'); + +infoBtn.addEventListener('click', () => { + if (!currentPhoto) return; + + // Gestione sicura GPS null + const gps = currentPhoto.gps || { lat: '-', lng: '-', alt: '-' }; + + // Cartella estratta dal path + const folder = currentPhoto.path.split('/').slice(2, -1).join('/'); + + infoPanel.innerHTML = ` +

Informazioni

+ +
Nome: ${currentPhoto.name}
+
Data: ${currentPhoto.taken_at}
+ +
Latitudine: ${gps.lat}
+
Longitudine: ${gps.lng}
+
Altitudine: ${gps.alt} m
+ +
Dimensioni: ${currentPhoto.width} × ${currentPhoto.height}
+
Peso: ${(currentPhoto.size_bytes / 1024 / 1024).toFixed(2)} MB
+
Tipo: ${currentPhoto.mime_type}
+ +
Cartella: ${folder}
+ `; + + infoPanel.classList.add('open'); +}); + +// Chiudi pannello cliccando fuori +document.addEventListener('click', (e) => { + if (!infoPanel.classList.contains('open')) return; + + const clickedInsidePanel = infoPanel.contains(e.target); + const clickedInfoBtn = infoBtn.contains(e.target); + + if (!clickedInsidePanel && !clickedInfoBtn) { + infoPanel.classList.remove('open'); + } +}); + + +// =============================== +// AVVIO +// =============================== loadPhotos(); diff --git a/index.html b/index.html index 350bd86..7409425 100644 --- a/index.html +++ b/index.html @@ -2,79 +2,45 @@ - Galleria foto - + Galleria Foto + - -

Galleria foto

- - + + +
+

Galleria Foto

+
+ +
+ +
+ + + +
+ + + + + + + + + diff --git a/style.css b/style.css new file mode 100644 index 0000000..049e3e9 --- /dev/null +++ b/style.css @@ -0,0 +1,127 @@ +body { + font-family: sans-serif; + margin: 0; + padding: 0; + background: #fafafa; +} + +header { + padding: 10px 15px; + background: #333; + color: white; +} + +.gallery { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + gap: 8px; + padding: 10px; +} + +.thumb { + cursor: pointer; + overflow: hidden; + border-radius: 4px; + border: 1px solid #ddd; + background: white; +} + +.thumb img { + width: 100%; + height: 100%; + object-fit: cover; + display: block; +} + +/* Modal */ +.modal { + position: fixed; + inset: 0; + background: rgba(0,0,0,0.8); + display: none; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.modal.open { + display: flex; +} + +.modal-content { + max-width: 90vw; + max-height: 90vh; + position: relative; +} + +.modal-content img { + max-width: 100%; + max-height: 100%; + display: block; +} + +.modal-close { + position: absolute; + top: -10px; + right: -10px; + background: #fff; + border-radius: 50%; + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + font-weight: bold; + border: 1px solid #ccc; +} + +/* Info Button */ +.modal-info-btn { + position: absolute; + bottom: -10px; + right: 40px; + background: #fff; + border-radius: 50%; + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + border: 1px solid #ccc; + font-size: 16px; + z-index: 1500; +} + +/* Info Panel */ +.info-panel { + position: fixed; + top: 0; + right: -320px; + width: 320px; + height: 100%; + background: #fff; + padding: 16px; + box-shadow: -2px 0 6px rgba(0,0,0,0.25); + transition: right 0.3s ease; + overflow-y: auto; + z-index: 2000; +} + +.info-panel.open { + right: 0; +} + +.info-panel h3 { + margin-top: 0; +} + +.info-row { + margin-bottom: 10px; +} + +.info-row b { + display: inline-block; + width: 110px; +}