11document . documentElement . setAttribute ( 'data-theme' , 'dark' ) ;
22
3- function initGridControls ( ) {
4- const gridSize = document . getElementById ( 'grid-size' ) ;
5- const siteGrid = document . querySelector ( '.site-grid' ) ;
6-
7- gridSize . addEventListener ( 'change' , function ( ) {
8- switch ( this . value ) {
9- case 'small' :
10- siteGrid . style . gridTemplateColumns = 'repeat(auto-fill, minmax(200px, 1fr))' ;
11- break ;
12- case 'medium' :
13- siteGrid . style . gridTemplateColumns = 'repeat(auto-fill, minmax(300px, 1fr))' ;
14- break ;
15- case 'large' :
16- siteGrid . style . gridTemplateColumns = 'repeat(auto-fill, minmax(400px, 1fr))' ;
17- break ;
18- }
19- localStorage . setItem ( 'preferredGridSize' , this . value ) ;
20- } ) ;
3+ let statusIndicator = null ;
4+ let checkingSites = new Map ( ) ;
5+ let totalSites = 0 ;
6+ let completedSites = 0 ;
217
22- const savedSize = localStorage . getItem ( 'preferredGridSize' ) ;
23- if ( savedSize ) {
24- gridSize . value = savedSize ;
25- gridSize . dispatchEvent ( new Event ( 'change' ) ) ;
8+ function createStatusIndicator ( ) {
9+ statusIndicator = document . createElement ( 'div' ) ;
10+ statusIndicator . className = 'status-indicator' ;
11+ statusIndicator . innerHTML = `
12+ <div class="status-header">
13+ <div class="status-icon"></div>
14+ <span class="status-title">Loading Sites...</span>
15+ </div>
16+ <div class="status-text">Initializing site checks...</div>
17+ <div class="progress-bar">
18+ <div class="progress-fill"></div>
19+ </div>
20+ <div class="checking-sites"></div>
21+ ` ;
22+ document . body . appendChild ( statusIndicator ) ;
23+ return statusIndicator ;
24+ }
25+
26+ function updateStatusIndicator ( status , text , progress = 0 ) {
27+ if ( ! statusIndicator ) return ;
28+
29+ const statusIcon = statusIndicator . querySelector ( '.status-icon' ) ;
30+ const statusTitle = statusIndicator . querySelector ( '.status-title' ) ;
31+ const statusText = statusIndicator . querySelector ( '.status-text' ) ;
32+ const progressFill = statusIndicator . querySelector ( '.progress-fill' ) ;
33+
34+ statusTitle . textContent = status ;
35+ statusText . textContent = text ;
36+ progressFill . style . width = `${ progress } %` ;
37+
38+ if ( status === 'Ready' ) {
39+ statusIcon . classList . add ( 'ready' ) ;
40+ setTimeout ( ( ) => {
41+ statusIndicator . classList . add ( 'hidden' ) ;
42+ setTimeout ( ( ) => statusIndicator . remove ( ) , 300 ) ;
43+ } , 2000 ) ;
2644 }
2745}
2846
29- async function checkSiteStatus ( url ) {
47+ function addSiteToCheck ( siteName , siteUrl ) {
48+ if ( ! statusIndicator ) return ;
49+
50+ const checkingSitesContainer = statusIndicator . querySelector ( '.checking-sites' ) ;
51+ const siteElement = document . createElement ( 'div' ) ;
52+ siteElement . className = 'checking-site' ;
53+ siteElement . innerHTML = `
54+ <span class="site-name">${ siteName } </span>
55+ <div class="site-status-icon checking"></div>
56+ ` ;
57+ checkingSitesContainer . appendChild ( siteElement ) ;
58+ checkingSites . set ( siteName , siteElement ) ;
59+ }
60+
61+ function updateSiteStatus ( siteName , isOnline ) {
62+ const siteElement = checkingSites . get ( siteName ) ;
63+ if ( ! siteElement ) return ;
64+
65+ const statusIcon = siteElement . querySelector ( '.site-status-icon' ) ;
66+ statusIcon . classList . remove ( 'checking' ) ;
67+ statusIcon . classList . add ( isOnline ? 'online' : 'offline' ) ;
68+ siteElement . classList . add ( 'completed' , isOnline ? 'online' : 'offline' ) ;
69+
70+ completedSites ++ ;
71+ const progress = ( completedSites / totalSites ) * 100 ;
72+ updateStatusIndicator (
73+ 'Checking Sites...' ,
74+ `Checked ${ completedSites } /${ totalSites } sites` ,
75+ progress
76+ ) ;
77+ }
78+
79+ async function checkSiteStatus ( url , siteName ) {
3080 try {
3181 console . log ( `Checking status for: ${ url } ` ) ;
3282 const controller = new AbortController ( ) ;
@@ -46,9 +96,19 @@ async function checkSiteStatus(url) {
4696
4797 const isOnline = response . type === 'opaque' ;
4898 console . log ( `Site ${ url } is ${ isOnline ? 'online' : 'offline' } (Type: ${ response . type } )` ) ;
99+
100+ if ( siteName ) {
101+ updateSiteStatus ( siteName , isOnline ) ;
102+ }
103+
49104 return isOnline ;
50105 } catch ( error ) {
51106 console . log ( `Error checking ${ url } :` , error . message ) ;
107+
108+ if ( siteName ) {
109+ updateSiteStatus ( siteName , false ) ;
110+ }
111+
52112 return false ;
53113 }
54114}
@@ -59,9 +119,12 @@ const supabaseKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS
59119async function loadSiteData ( ) {
60120 try {
61121 console . log ( 'Starting to load site data...' ) ;
122+
123+ createStatusIndicator ( ) ;
124+ updateStatusIndicator ( 'Loading...' , 'Fetching site data from database...' , 0 ) ;
125+
62126 const siteList = document . getElementById ( 'site-list' ) ;
63- siteList . innerHTML = '<div class="loader"></div>' ;
64-
127+
65128 const headers = {
66129 'accept' : '*/*' ,
67130 'accept-language' : 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7' ,
@@ -83,29 +146,41 @@ async function loadSiteData() {
83146
84147 const data = await response . json ( ) ;
85148
86- siteList . innerHTML = '' ; if ( data && data . length > 0 ) {
87- console . log ( 'Raw data from Supabase:' , data ) ;
149+ siteList . innerHTML = '' ;
150+
151+ if ( data && data . length > 0 ) {
88152 const configSite = data [ 0 ] . data ;
89- console . log ( 'Parsed config site:' , configSite ) ;
90- let totalSites = Object . keys ( configSite ) . length ;
153+ totalSites = Object . keys ( configSite ) . length ;
154+ completedSites = 0 ;
91155 let latestUpdate = new Date ( 0 ) ;
92156
93157 document . getElementById ( 'sites-count' ) . textContent = totalSites ;
158+
159+ updateStatusIndicator ( 'Checking Sites...' , `Starting checks for ${ totalSites } sites...` , 0 ) ;
160+
161+ Object . entries ( configSite ) . forEach ( ( [ siteName , site ] ) => {
162+ addSiteToCheck ( siteName , site . full_url ) ;
163+ } ) ;
94164
95- for ( const siteName in configSite ) {
96- const site = configSite [ siteName ] ;
165+ const statusChecks = Object . entries ( configSite ) . map ( async ( [ siteName , site ] ) => {
166+ const isOnline = await checkSiteStatus ( site . full_url , siteName ) ;
167+ return { siteName, site, isOnline } ;
168+ } ) ;
169+
170+ const results = await Promise . all ( statusChecks ) ;
171+
172+ updateStatusIndicator ( 'Ready' , 'All sites checked successfully!' , 100 ) ;
173+
174+ results . forEach ( ( { siteName, site, isOnline } ) => {
97175 const siteItem = document . createElement ( 'div' ) ;
98176 siteItem . className = 'site-item' ;
99177 siteItem . style . cursor = 'pointer' ;
100178
101- // Add status indicator
102179 const statusDot = document . createElement ( 'div' ) ;
103180 statusDot . className = 'site-status' ;
104- const isOnline = await checkSiteStatus ( site . full_url ) ;
105181 if ( ! isOnline ) statusDot . classList . add ( 'offline' ) ;
106182 siteItem . appendChild ( statusDot ) ;
107183
108- // Update latest update time
109184 const updateTime = new Date ( site . time_change ) ;
110185 if ( updateTime > latestUpdate ) {
111186 latestUpdate = updateTime ;
@@ -133,7 +208,9 @@ async function loadSiteData() {
133208 oldDomain . className = 'old-domain' ;
134209 oldDomain . innerHTML = `<i class="fas fa-history"></i> ${ site . old_domain } ` ;
135210 siteInfo . appendChild ( oldDomain ) ;
136- } siteItem . addEventListener ( 'click' , function ( ) {
211+ }
212+
213+ siteItem . addEventListener ( 'click' , function ( ) {
137214 window . open ( site . full_url , '_blank' , 'noopener,noreferrer' ) ;
138215 } ) ;
139216
@@ -150,7 +227,7 @@ async function loadSiteData() {
150227 siteItem . appendChild ( siteTitle ) ;
151228 siteItem . appendChild ( siteInfo ) ;
152229 siteList . appendChild ( siteItem ) ;
153- }
230+ } ) ;
154231
155232 const formattedDate = latestUpdate . toLocaleDateString ( 'it-IT' , {
156233 year : 'numeric' ,
@@ -162,6 +239,7 @@ async function loadSiteData() {
162239 document . getElementById ( 'last-update-time' ) . textContent = formattedDate ;
163240 } else {
164241 siteList . innerHTML = '<div class="no-sites">No sites available</div>' ;
242+ updateStatusIndicator ( 'Ready' , 'No sites found in database' , 100 ) ;
165243 }
166244 } catch ( error ) {
167245 console . error ( 'Errore:' , error ) ;
@@ -171,6 +249,10 @@ async function loadSiteData() {
171249 <button onclick="loadSiteData()" class="retry-button">Riprova</button>
172250 </div>
173251 ` ;
252+ if ( statusIndicator ) {
253+ updateStatusIndicator ( 'Error' , `Failed to load: ${ error . message } ` , 0 ) ;
254+ statusIndicator . querySelector ( '.status-icon' ) . style . background = '#f44336' ;
255+ }
174256 }
175257}
176258
0 commit comments