decentralized crowd-sourced service status tracker on ATProto
at main 1.7 kB view raw
1 <h1>Known Services</h1> 2 <p>Real-time crowd-sourced status from the AT Protocol network.</p> 3 4 <div id="services-grid" class="grid"> 5 <% services.forEach(s => { %> 6 <div class="service-card" data-domain="<%= s.domain %>"> 7 <div class="service-name"><%= s.name %></div> 8 <div class="service-domain">@<%= s.domain %></div> 9 <div class="service-status" id="status-<%= s.domain.replace(/\./g,'-') %>"> 10 <span class="status-text">Checking…</span> 11 <span class="status-count"></span> 12 </div> 13 <button class="issue-btn" onclick="reportIssue('<%= s.domain %>')"> 14 Having issues 15 </button> 16 </div> 17 <% }) %> 18 </div> 19 20 <p style="margin-top: 3rem; opacity: 0.6; font-size: 0.9rem;"> 21 Reports are pulled live from the decentralized network • no central database 22 </p> 23 24<script> 25// Auto-refresh every 15 seconds + on load 26async function updateStatuses() { 27 const res = await fetch('/api/status'); 28 const data = await res.json(); 29 for (const [domain, info] of Object.entries(data)) { 30 const el = document.getElementById('status-' + domain.replace(/\./g,'-')); 31 if (!el) continue; 32 el.innerHTML = ` 33 <span class="status-${info.current}">● ${info.current.toUpperCase()}</span> 34 ${info.reports > 0 ? `<span class="status-count">(${info.reports} reports)</span>` : ''} 35 `; 36 } 37} 38updateStatuses(); 39setInterval(updateStatuses, 15000); 40 41// Fake report button (we’ll make real later) 42function reportIssue(domain) { 43 if (confirm(`Report issue with ${domain}? (Login coming soon)`)) { 44 alert(`Reported issue with ${domain} — thanks!`); 45 } 46} 47</script>