document.documentElement.setAttribute('data-theme', 'dark'); let statusIndicator = null; let checkingSites = new Map(); let totalSites = 0; let completedSites = 0; function createStatusIndicator() { statusIndicator = document.createElement('div'); statusIndicator.className = 'status-indicator'; statusIndicator.innerHTML = `
Loading Sites...
Initializing site checks...
`; document.body.appendChild(statusIndicator); return statusIndicator; } function updateStatusIndicator(status, text, progress = 0) { if (!statusIndicator) return; const statusIcon = statusIndicator.querySelector('.status-icon'); const statusTitle = statusIndicator.querySelector('.status-title'); const statusText = statusIndicator.querySelector('.status-text'); const progressFill = statusIndicator.querySelector('.progress-fill'); statusTitle.textContent = status; statusText.textContent = text; progressFill.style.width = `${progress}%`; if (status === 'Ready') { statusIcon.classList.add('ready'); setTimeout(() => { statusIndicator.classList.add('hidden'); setTimeout(() => statusIndicator.remove(), 300); }, 2000); } } function addSiteToCheck(siteName, siteUrl) { if (!statusIndicator) return; const checkingSitesContainer = statusIndicator.querySelector('.checking-sites'); const siteElement = document.createElement('div'); siteElement.className = 'checking-site'; siteElement.innerHTML = ` ${siteName}
`; checkingSitesContainer.appendChild(siteElement); checkingSites.set(siteName, siteElement); } function updateSiteStatus(siteName, isOnline) { const siteElement = checkingSites.get(siteName); if (!siteElement) return; const statusIcon = siteElement.querySelector('.site-status-icon'); statusIcon.classList.remove('checking'); statusIcon.classList.add(isOnline ? 'online' : 'offline'); siteElement.classList.add('completed', isOnline ? 'online' : 'offline'); completedSites++; const progress = (completedSites / totalSites) * 100; updateStatusIndicator( 'Checking Sites...', `Checked ${completedSites}/${totalSites} sites`, progress ); } async function checkSiteStatus(url, siteName) { try { console.log(`Checking status for: ${url}`); const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 3000); const response = await fetch(url, { method: 'HEAD', mode: 'no-cors', signal: controller.signal, headers: { 'Accept': 'text/html', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/133.0.0.0' } }); clearTimeout(timeoutId); const isOnline = response.type === 'opaque'; console.log(`Site ${url} is ${isOnline ? 'online' : 'offline'} (Type: ${response.type})`); if (siteName) { updateSiteStatus(siteName, isOnline); } return isOnline; } catch (error) { console.log(`Error checking ${url}:`, error.message); if (siteName) { updateSiteStatus(siteName, false); } return false; } } const supabaseUrl = 'https://zvfngpoxwrgswnzytadh.supabase.co'; const supabaseKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inp2Zm5ncG94d3Jnc3duenl0YWRoIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDAxNTIxNjMsImV4cCI6MjA1NTcyODE2M30.FNTCCMwi0QaKjOu8gtZsT5yQttUW8QiDDGXmzkn89QE'; async function loadSiteData() { try { console.log('Starting to load site data...'); createStatusIndicator(); updateStatusIndicator('Loading...', 'Fetching site data from database...', 0); const siteList = document.getElementById('site-list'); const headers = { 'accept': '*/*', 'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7', 'apikey': supabaseKey, 'authorization': `Bearer ${supabaseKey}`, 'content-type': 'application/json', 'cache-control': 'no-cache', 'pragma': 'no-cache', 'range': '0-9' }; console.log('Fetching from Supabase with headers:', headers); const response = await fetch(`${supabaseUrl}/rest/v1/public?select=*`, { method: 'GET', headers: headers }); if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); const data = await response.json(); siteList.innerHTML = ''; if (data && data.length > 0) { const configSite = data[0].data; totalSites = Object.keys(configSite).length; completedSites = 0; let latestUpdate = new Date(0); document.getElementById('sites-count').textContent = totalSites; updateStatusIndicator('Checking Sites...', `Starting checks for ${totalSites} sites...`, 0); Object.entries(configSite).forEach(([siteName, site]) => { addSiteToCheck(siteName, site.full_url); }); const statusChecks = Object.entries(configSite).map(async ([siteName, site]) => { const isOnline = await checkSiteStatus(site.full_url, siteName); return { siteName, site, isOnline }; }); const results = await Promise.all(statusChecks); updateStatusIndicator('Ready', 'All sites checked successfully!', 100); results.forEach(({ siteName, site, isOnline }) => { const siteItem = document.createElement('div'); siteItem.className = 'site-item'; siteItem.style.cursor = 'pointer'; const statusDot = document.createElement('div'); statusDot.className = 'site-status'; if (!isOnline) statusDot.classList.add('offline'); siteItem.appendChild(statusDot); const updateTime = new Date(site.time_change); if (updateTime > latestUpdate) { latestUpdate = updateTime; } const siteInfo = document.createElement('div'); siteInfo.className = 'site-info'; if (site.time_change) { const updateDate = new Date(site.time_change); const formattedDate = updateDate.toLocaleDateString('it-IT', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); const lastUpdate = document.createElement('span'); lastUpdate.className = 'last-update'; lastUpdate.innerHTML = ` ${formattedDate}`; siteInfo.appendChild(lastUpdate); } if (site.old_domain) { const oldDomain = document.createElement('span'); oldDomain.className = 'old-domain'; oldDomain.innerHTML = ` ${site.old_domain}`; siteInfo.appendChild(oldDomain); } siteItem.addEventListener('click', function() { window.open(site.full_url, '_blank', 'noopener,noreferrer'); }); const siteIcon = document.createElement('img'); siteIcon.src = `https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=${site.full_url}&size=128`; siteIcon.alt = `${siteName} icon`; siteIcon.onerror = function() { this.src = 'data:image/svg+xml;utf8,'; }; const siteTitle = document.createElement('h3'); siteTitle.textContent = siteName; siteItem.appendChild(siteIcon); siteItem.appendChild(siteTitle); siteItem.appendChild(siteInfo); siteList.appendChild(siteItem); }); const formattedDate = latestUpdate.toLocaleDateString('it-IT', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); document.getElementById('last-update-time').textContent = formattedDate; } else { siteList.innerHTML = '
No sites available
'; updateStatusIndicator('Ready', 'No sites found in database', 100); } } catch (error) { console.error('Errore:', error); siteList.innerHTML = `

Errore nel caricamento

`; if (statusIndicator) { updateStatusIndicator('Error', `Failed to load: ${error.message}`, 0); statusIndicator.querySelector('.status-icon').style.background = '#f44336'; } } } document.addEventListener('DOMContentLoaded', () => { loadSiteData(); });