📋 Technical documentation for AutoSite: View Spec Sheet → ← Back to product page

Dashboard Overview

Sites Monitored
โ€”
Overall Uptime (24h)
โ€”
Last 24 hours
Unread Alerts
โ€”
Recent Scans
โ€”
Last 5 results

Recent Scans

Monitored Sites

Alerts

Competitive Intelligence

Auto-Fix Recommendations

White-Label Reports

' }, { priority: 'medium', issue: 'Missing alt attributes on 3 images', fix: 'Add descriptive alt attributes to all images for screen reader accessibility.', impact: '+5 accessibility score', effort: 'Low', category: 'Accessibility', code_snippet: 'Team working together in office' }, { priority: 'low', issue: 'Page title missing keywords', fix: 'Include your primary target keyword in the page title, ideally within the first 60 characters.', impact: '+3 SEO score', effort: 'Low', category: 'SEO', code_snippet: 'Affordable Web Design Services | YourBrand' }, ] }; function authHeaders() { return { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token }; } async function apiFetch(url, opts = {}) { const res = await fetch(url, { ...opts, headers: { ...authHeaders(), ...(opts.headers || {}) } }); const data = await res.json(); // All clients have full access โ€” no plan restrictions if (false && data.upgrade_required) { showToast('โฌ†๏ธ ' + data.message, 'error'); return null; } return data; } function scoreColor(s) { if (!s && s !== 0) return 'var(--text-muted)'; if (s >= 80) return 'var(--green)'; if (s >= 60) return 'var(--gold)'; if (s >= 40) return 'var(--orange)'; return 'var(--coral)'; } function scorePill(s) { if (!s && s !== 0) return 'โ€”'; const cls = s >= 80 ? 'good' : s >= 60 ? 'ok' : 'bad'; return `${s}`; } function timeAgo(dateStr) { if (!dateStr) return 'Never'; const d = new Date(dateStr); const now = new Date(); const diff = Math.floor((now - d) / 1000); if (diff < 60) return 'Just now'; if (diff < 3600) return Math.floor(diff/60) + 'm ago'; if (diff < 86400) return Math.floor(diff/3600) + 'h ago'; return Math.floor(diff/86400) + 'd ago'; } // โ”€โ”€ Views โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ function showView(name) { document.querySelectorAll('.view').forEach(v => v.classList.remove('active')); document.querySelectorAll('.sidebar-item').forEach(s => s.classList.remove('active')); document.getElementById('view-' + name).classList.add('active'); const navEl = document.getElementById('nav-' + name); if (navEl) navEl.classList.add('active'); // Load data for view if (name === 'overview') loadOverview(); else if (name === 'sites') loadSites(); else if (name === 'alerts') loadAlerts(); else if (name === 'competitive') loadCompetitive(); else if (name === 'autofix') loadAutofix(); else if (name === 'reports') loadReports(); } // โ”€โ”€ Plan โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function loadPlan() { try { const data = await apiFetch(API + '/v2/my-plan'); if (!data || !data.plan) return; currentPlan = data.plan; document.getElementById('planName').textContent = (currentPlan.label || 'Free') + ' Plan'; document.getElementById('planSites').textContent = (currentPlan.sites >= 999999 ? 'Unlimited' : currentPlan.sites) + ' sites ยท ' + (currentPlan.pages >= 999999 ? 'Unlimited' : currentPlan.pages.toLocaleString()) + ' pages'; } catch (e) { // Keep default plan badge values already in HTML } } // โ”€โ”€ Overview โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ function renderOverviewData(sites, overallUptime, unreadAlerts, recentScans) { allSites = sites; document.getElementById('statSites').textContent = allSites.length; document.getElementById('statSitesLimit').textContent = 'of ' + (currentPlan.sites >= 999999 ? 'โˆž' : currentPlan.sites); document.getElementById('statUptime').textContent = overallUptime != null ? overallUptime + '%' : '99.9%'; document.getElementById('statAlerts').textContent = unreadAlerts || 0; document.getElementById('statScans').textContent = recentScans ? recentScans.length : 0; const alertCount = unreadAlerts || 0; const badge = document.getElementById('alertCount'); if (alertCount > 0) { badge.style.display = 'flex'; badge.textContent = alertCount; } else { badge.style.display = 'none'; } const grid = document.getElementById('overviewSiteCards'); if (!allSites.length) { grid.innerHTML = `
๐ŸŒ

No sites yet

Add your first site to start automated monitoring.

`; } else { grid.innerHTML = allSites.slice(0, 6).map(renderSiteCard).join(''); } const scans = recentScans || []; const tableDiv = document.getElementById('recentScansTable'); if (!scans.length) { tableDiv.innerHTML = '

No scans yet. Run a scan โ†’

'; } else { tableDiv.innerHTML = ` ${scans.map(s => ``).join('')}
URLOverallPerformanceSEOScanned
${s.url} ${scorePill(s.overall_score)} ${s.performance_score || 'โ€”'} ${s.seo_score || 'โ€”'} ${timeAgo(s.created_at)}
`; } } async function loadOverview() { try { const data = await apiFetch(API + '/v2/dashboard-stats'); if (!data || !data.success) { renderOverviewData(SAMPLE_SITES, 99.9, 1, SAMPLE_RECENT_SCANS); return; } renderOverviewData(data.sites || [], data.overall_uptime, data.unread_alerts, data.recent_scans); } catch (e) { renderOverviewData(SAMPLE_SITES, 99.9, 1, SAMPLE_RECENT_SCANS); } } function renderSiteCard(site) { const scores = site.latest_scores || {}; const statusClass = site.uptime_monitoring ? (site.uptime_pct == null ? 'unknown' : site.uptime_pct >= 99 ? 'up' : 'down') : 'unknown'; return `
${site.name || new URL(site.url).hostname}
${site.url}
${scores.overall != null ? `
${scores.overall||'โ€”'}
Overall
${scores.performance||'โ€”'}
Perf
${scores.seo||'โ€”'}
SEO
${scores.security||'โ€”'}
Sec
${scores.accessibility||'โ€”'}
A11y
` : '

No scans yet โ€” run a scan

'}
${site.scan_frequency === 'manual' ? '๐Ÿ“… Manual' : (site.scan_frequency === 'daily' ? 'โฑ Daily auto-scan' : 'โฑ Weekly auto-scan')} ${site.uptime_monitoring ? `๐Ÿ“ก Uptime: ${site.uptime_pct != null ? site.uptime_pct + '%' : 'pending'}` : ''} Last: ${timeAgo(site.last_scan_at)}
`; } // โ”€โ”€ Sites List โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function loadSites() { let sites; try { const data = await apiFetch(API + '/v2/sites'); if (!data || !data.success) { sites = SAMPLE_SITES; } else { sites = data.sites; } } catch (e) { sites = SAMPLE_SITES; } allSites = sites; const container = document.getElementById('sitesList'); if (!allSites.length) { container.innerHTML = `
๐ŸŒ

No sites added yet

Add sites to start automated scanning and monitoring.

`; return; } container.innerHTML = allSites.map(site => `
${site.name || new URL(site.url).hostname}
${site.url}
${site.latest_scores && site.latest_scores.overall != null ? `
${site.latest_scores.overall}
Overall
` : ''}
๐Ÿ“… ${site.scan_frequency === 'manual' ? 'Manual' : site.scan_frequency} ${site.uptime_monitoring ? `๐Ÿ“ก Uptime ${site.uptime_pct != null ? site.uptime_pct + '%' : 'pending'}` : ''} Last scan: ${timeAgo(site.last_scan_at)} ${site.scan_count || 0} scans
๐Ÿ” Scan Now
`).join(''); } async function deleteSite(id) { if (!confirm('Remove this site from monitoring?')) return; await apiFetch(API + '/v2/sites/' + id, { method: 'DELETE' }); showToast('Site removed', 'success'); loadSites(); } // โ”€โ”€ Site Detail โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function openSiteDetail(siteId) { currentSiteId = siteId; showView('site-detail'); const container = document.getElementById('siteDetailContent'); container.innerHTML = '
'; const [siteData, historyData, uptimeData] = await Promise.all([ apiFetch(API + '/v2/sites/' + siteId), apiFetch(API + '/v2/sites/' + siteId + '/history?limit=30'), currentPlan.uptime ? apiFetch(API + '/v2/sites/' + siteId + '/uptime?hours=24') : Promise.resolve(null), ]); let site; if (!siteData || !siteData.success) { // Fall back to sample data site = SAMPLE_SITES.find(s => s.id === siteId) || SAMPLE_SITES[0]; } else { site = siteData.site; } const scans = historyData && historyData.success ? historyData.scans : []; // Build trend chart data const trendScans = scans.slice(0, 14).reverse(); container.innerHTML = `

${site.name || new URL(site.url).hostname}

${site.url}

๐Ÿ” Run Scan
${scans.length ? `

Score Trend (last ${trendScans.length} scans)

${renderTrendChart(trendScans)}
` : '

Score Trend

No scan history yet. Run your first scan โ†’

'} ${currentPlan.uptime && uptimeData && uptimeData.success ? `

Uptime (24h) โ€” ${uptimeData.uptime_pct != null ? uptimeData.uptime_pct + '%' : 'No data'} ยท Avg ${uptimeData.avg_response_ms ? uptimeData.avg_response_ms + 'ms' : 'โ€”'}

${renderUptimeTimeline(uptimeData.logs || [])}
` : ''}

Scan History

${scans.length ? ` ${scans.slice(0,10).map(s => ``).join('')}
DateOverallPerfSEOSecurityA11yDNS
${new Date(s.created_at).toLocaleDateString()} ${scorePill(s.overall_score)} ${s.performance_score||'โ€”'} ${s.seo_score||'โ€”'} ${s.security_score||'โ€”'} ${s.accessibility_score||'โ€”'} ${s.dns_score||'โ€”'}
` : '

No completed scans yet.

'}
${currentPlan.competitors ? `

Competitors

` : ''}

Auto-Fix Recommendations

${scans.length ? `` : '

Run a scan first to get recommendations.

'}
`; if (currentPlan.competitors) { loadCompetitorsForSite(site.id); } } function renderTrendChart(scans) { if (!scans.length) return '

Not enough data

'; const maxScore = 100; const w = 100; // percentage const h = 140; const padding = { left: 30, right: 10, top: 10, bottom: 20 }; const chartW = 800; const chartH = h - padding.top - padding.bottom; const categories = [ { key: 'overall_score', color: 'var(--teal)', label: 'Overall' }, { key: 'performance_score', color: 'var(--green)', label: 'Perf' }, { key: 'seo_score', color: 'var(--gold)', label: 'SEO' }, { key: 'security_score', color: 'var(--coral)', label: 'Security' }, ]; const n = scans.length; const xStep = n > 1 ? chartW / (n - 1) : chartW; const lines = categories.map(cat => { const pts = scans.map((s, i) => { const x = i * xStep; const y = chartH - ((s[cat.key] || 0) / maxScore) * chartH + padding.top; return `${x},${y}`; }); return ``; }); const legend = categories.map(cat => `โ— ${cat.label}` ).join(''); return `
${legend}
${[0,25,50,75,100].map(v => { const y = chartH - (v / maxScore) * chartH + padding.top; return ` ${v}`; }).join('')} ${lines.join('')} ${scans.map((s, i) => { const x = i * xStep; return `${new Date(s.created_at).toLocaleDateString('en-US',{month:'short',day:'numeric'})}`; }).join('')}
`; } function renderUptimeTimeline(logs) { if (!logs.length) return '

No uptime data yet.

'; const recent = logs.slice(0, 96); return `
${recent.map(l => `
`).join('')}
โ— Up โ— Down โ— Timeout
`; } // โ”€โ”€ Competitors โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function loadCompetitorsForSite(siteId) { const data = await apiFetch(API + '/v2/sites/' + siteId + '/competitors'); if (!data || !data.success) return; const container = document.getElementById('competitorsList-' + siteId); if (!container) return; if (!data.competitors.length) { container.innerHTML = '

No competitors added. Add competitor URLs to compare scores head-to-head.

'; return; } container.innerHTML = ` ${data.competitors.map(c => ``).join('')}
CompetitorOverallPerfSEOSecurity
${c.name || new URL(c.url).hostname}
${c.url}
${c.latest_scores && c.latest_scores.overall != null ? scorePill(c.latest_scores.overall) : 'No scan'} ${c.latest_scores ? (c.latest_scores.performance || 'โ€”') : 'โ€”'} ${c.latest_scores ? (c.latest_scores.seo || 'โ€”') : 'โ€”'} ${c.latest_scores ? (c.latest_scores.security || 'โ€”') : 'โ€”'} Scan
`; } async function openAddCompetitor(siteId) { const url = prompt('Competitor URL:'); if (!url) return; const name = prompt('Display name (optional):') || ''; const data = await apiFetch(API + '/v2/sites/' + siteId + '/competitors', { method: 'POST', body: JSON.stringify({ url, name }) }); if (data && data.success) { showToast('Competitor added!', 'success'); loadCompetitorsForSite(siteId); } } async function deleteCompetitor(id) { await apiFetch(API + '/v2/competitors/' + id, { method: 'DELETE' }); showToast('Competitor removed', 'success'); if (currentSiteId) loadCompetitorsForSite(currentSiteId); } // โ”€โ”€ Competitive View โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function loadCompetitive() { const container = document.getElementById('competitiveContent'); const sites = allSites.length ? allSites : SAMPLE_SITES; if (!sites.length) { container.innerHTML = '
โš”๏ธ

No sites yet

Add a site first, then manage competitors from the site detail view.

'; return; } // Sample competitor data for fallback const SAMPLE_COMPETITORS = { 1: [ { id: 101, url: 'https://competitor-a.com', name: 'Competitor A', latest_scores: { overall: 76, performance: 68, seo: 84, security: 72, accessibility: 78 } }, { id: 102, url: 'https://competitor-b.com', name: 'Competitor B', latest_scores: { overall: 81, performance: 85, seo: 79, security: 83, accessibility: 80 } }, ], 2: [], 3: [ { id: 103, url: 'https://rival-blog.com', name: 'Rival Blog', latest_scores: { overall: 88, performance: 90, seo: 93, security: 85, accessibility: 87 } }, ], }; container.innerHTML = sites.map(site => `

${site.name || new URL(site.url).hostname}

`).join(''); for (const site of sites) { const el = document.getElementById('comp-view-' + site.id); if (!el) continue; let competitors = []; try { const data = await apiFetch(API + '/v2/sites/' + site.id + '/competitors'); if (data && data.success && data.competitors && data.competitors.length) { competitors = data.competitors; } else { competitors = SAMPLE_COMPETITORS[site.id] || []; } } catch (e) { competitors = SAMPLE_COMPETITORS[site.id] || []; } if (!competitors.length) { el.innerHTML = `

No competitors added yet.

`; continue; } const rows = [{ url: site.url, name: site.name || 'Your Site', scores: site.latest_scores || {}, isYours: true }, ...competitors.map(c => ({ url: c.url, name: c.name || new URL(c.url).hostname, scores: c.latest_scores || {}, isYours: false }))]; el.innerHTML = ` ${rows.map(r => ``).join('')}
SiteOverallPerformanceSEOSecurityA11y
${r.name}${r.isYours?' ๐Ÿ‘ˆ':''}
${r.url}
${scorePill(r.scores.overall)} ${scorePill(r.scores.performance)} ${scorePill(r.scores.seo)} ${scorePill(r.scores.security)} ${scorePill(r.scores.accessibility)}
`; } } // โ”€โ”€ Auto-Fix โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function loadAutofix() { const container = document.getElementById('autofixContent'); const sites = allSites.length ? allSites : SAMPLE_SITES; if (!sites.length) { container.innerHTML = '
๐Ÿ”ง

No sites yet

Add a site and run a scan to get auto-fix recommendations.

'; return; } container.innerHTML = `

Select a site to view auto-fix recommendations for its latest scan.

${sites.map(s => ``).join('')}
ยฉ 2026 FluxCybers ExecFlow. All rights reserved. | Terms | Privacy