SEO Performance Monitoring Dashboard

Organic Sessions

0

Avg. Keyword Rank

0

Keywords in Top 3

0

Total Backlinks

Performance Trends (Last 30 Days)

Keyword Ranking Distribution

Technical Health

Site Speed

0

/ 100

Mobile Friendliness

0

/ 100

Crawl Errors

0

SSL Status

Secure

Tracked Keywords

KeywordSearch VolumeCurrent RankLanding Page

Add Keyword to Track

Manage All Tracked Keywords

KeywordRankAction

Error: A required library is missing.

'; return; } // --- DATA MANAGEMENT --- let keywords = JSON.parse(localStorage.getItem('seo_keywords')) || []; const getSampleData = () => [ { id: 1, keyword: 'best running shoes for men', volume: 74000, rank: 2, page: '/running-shoes/men' }, { id: 2, keyword: 'womens yoga pants', volume: 49500, rank: 5, page: '/apparel/yoga-pants' }, { id: 3, keyword: 'smart fitness watch reviews', volume: 33100, rank: 8, page: '/blog/fitness-watch-review' }, { id: 4, keyword: 'buy protein powder online', volume: 22200, rank: 12, page: '/supplements' }, { id: 5, keyword: 'lightweight gym t-shirt', volume: 9900, rank: 4, page: '/apparel/shirts' }, { id: 6, keyword: 'high support sports bra', volume: 14800, rank: 25, page: '/apparel/sports-bras' }, { id: 7, keyword: 'noise cancelling earbuds for gym', volume: 8100, rank: 52, page: '/electronics/earbuds' }, ]; if (keywords.length === 0) keywords = getSampleData(); const saveState = () => localStorage.setItem('seo_keywords', JSON.stringify(keywords)); // --- CHART INSTANCES & UTILITIES --- let trendChart, distributionChart; const tabButtons = document.querySelectorAll('.seo-tab-button'); const tabContents = document.querySelectorAll('.seo-tab-content'); const nextBtn = document.getElementById('seo-next-btn'); const prevBtn = document.getElementById('seo-prev-btn'); // --- RENDER FUNCTIONS --- const renderAll = () => { try { renderKPIs(); renderTrendChart(); renderDistributionChart(); renderTechHealth(); renderKeywordsTable(); renderManageTable(); updateNavButtons(); } catch(error) { console.error("Dashboard rendering failed:", error); } }; const renderKPIs = () => { const avgRank = keywords.length > 0 ? keywords.reduce((sum, k) => sum + k.rank, 0) / keywords.length : 0; document.getElementById('seo-sessions-kpi').textContent = (12450).toLocaleString(); // Static sample document.getElementById('seo-avg-rank-kpi').textContent = avgRank.toFixed(1); document.getElementById('seo-top3-kpi').textContent = keywords.filter(k => k.rank <= 3).length; document.getElementById('seo-backlinks-kpi').textContent = (5280).toLocaleString(); // Static sample }; const renderTrendChart = () => { const options = { chart: { type: 'line', height: 350, toolbar: { show: false } }, series: [ { name: 'Organic Sessions', data: [9800, 10500, 11200, 12450] }, { name: 'Avg. Rank', data: [15.2, 13.1, 11.8, 10.5] } ], xaxis: { categories: ['Apr 2025', 'May 2025', 'Jun 2025', 'Jul 2025'] }, yaxis: [ { title: { text: 'Sessions' } }, { opposite: true, reversed: true, title: { text: 'Avg. Rank' } } ], stroke: { curve: 'smooth', width: 3 }, colors: ['var(--seo-primary-color)', 'var(--seo-success-color)'] }; if(trendChart) trendChart.destroy(); document.querySelector("#seo-trend-chart").innerHTML = ''; trendChart = new ApexCharts(document.querySelector("#seo-trend-chart"), options); trendChart.render(); }; const renderDistributionChart = () => { const distribution = { 'Top 3': keywords.filter(k => k.rank <= 3).length, 'Rank 4-10': keywords.filter(k => k.rank > 3 && k.rank <= 10).length, 'Rank 11-50': keywords.filter(k => k.rank > 10 && k.rank <= 50).length, 'Rank 51+': keywords.filter(k => k.rank > 50).length }; const options = { chart: { type: 'donut', height: 350 }, series: Object.values(distribution), labels: Object.keys(distribution), legend: { position: 'bottom' }, colors: ['var(--seo-success-color)', '#5dade2', 'var(--seo-warning-color)', 'var(--seo-danger-color)'] }; if(distributionChart) distributionChart.destroy(); document.querySelector("#seo-distribution-chart").innerHTML = ''; distributionChart = new ApexCharts(document.querySelector("#seo-distribution-chart"), options); distributionChart.render(); }; const renderTechHealth = () => { document.getElementById('seo-speed-score').textContent = '92'; document.getElementById('seo-mobile-score').textContent = '100'; const crawlErrorsEl = document.getElementById('seo-crawl-errors'); crawlErrorsEl.textContent = '3'; crawlErrorsEl.className = 'value negative'; // Make it red as it's bad }; const renderKeywordsTable = () => { const tbody = document.getElementById('seo-keywords-tbody'); tbody.innerHTML = ''; keywords.sort((a,b) => a.rank - b.rank).forEach(k => { tbody.innerHTML += `${k.keyword}${k.volume.toLocaleString()}${k.rank}${k.page}`; }); }; const renderManageTable = () => { const tbody = document.getElementById('seo-manage-tbody'); tbody.innerHTML = ''; keywords.forEach(k => { tbody.innerHTML += `${k.keyword}${k.rank}`; }); }; // --- EVENT HANDLING --- const switchTab = (tabId) => { tabContents.forEach(c => c.style.display = 'none'); tabButtons.forEach(b => b.classList.remove('active')); const activeContent = document.getElementById(tabId); const activeButton = document.querySelector(`.seo-tab-button[data-tab="${tabId}"]`); if (activeContent && activeButton) { activeContent.style.display = 'block'; activeButton.classList.add('active'); } updateNavButtons(); }; const updateNavButtons = () => { const i = [...tabButtons].findIndex(b => b.classList.contains('active')); prevBtn.disabled = i === 0; nextBtn.disabled = i === tabButtons.length - 1; }; tabButtons.forEach(b => b.addEventListener('click', () => switchTab(b.dataset.tab))); nextBtn.addEventListener('click', () => { const i = [...tabButtons].findIndex(b=>b.classList.contains('active')); if (i < tabButtons.length - 1) switchTab(tabButtons[i+1].dataset.tab); }); prevBtn.addEventListener('click', () => { const i = [...tabButtons].findIndex(b=>b.classList.contains('active')); if (i > 0) switchTab(tabButtons[i-1].dataset.tab); }); document.getElementById('seo-keyword-form').addEventListener('submit', e => { e.preventDefault(); keywords.push({ id: (keywords.length > 0 ? Math.max(...keywords.map(k=>k.id)) : 0) + 1, keyword: document.getElementById('seo-form-keyword').value, volume: parseInt(document.getElementById('seo-form-volume').value), rank: parseInt(document.getElementById('seo-form-rank').value), page: document.getElementById('seo-form-page').value }); saveState(); renderAll(); e.target.reset(); switchTab('seo-dashboard-tab'); }); document.getElementById('seo-manage-tbody').addEventListener('click', e => { if(e.target.tagName === 'BUTTON') { const id = e.target.dataset.id; if(confirm('Are you sure you want to delete this keyword?')) { keywords = keywords.filter(k => k.id != id); saveState(); renderAll(); } } }); // --- PDF EXPORT --- document.getElementById('seo-download-pdf-btn').addEventListener('click', function() { const btn = this; btn.textContent = 'Generating...'; btn.disabled = true; const pdfCaptureArea = document.getElementById('seo-pdf-capture-area'); html2canvas(pdfCaptureArea, { scale: 2 }).then(canvas => { const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const imgData = canvas.toDataURL('image/png'); doc.setFontSize(18); doc.text('SEO Performance Report', 14, 22); doc.setFontSize(11); doc.setTextColor(100); doc.text(`Generated on: ${new Date().toLocaleDateString('en-US')}`, 14, 29); const imgWidth = doc.internal.pageSize.getWidth() - 28; const imgHeight = (canvas.height * imgWidth) / canvas.width; doc.addImage(imgData, 'PNG', 14, 40, imgWidth, imgHeight); doc.addPage(); doc.autoTable({ html: '.seo-table', startY: 15, theme: 'striped', headStyles: { fillColor: [44, 62, 80] } }); doc.save('SEO_Performance_Report.pdf'); }).finally(() => { btn.textContent = 'Download Report'; btn.disabled = false; }); }); // --- INITIALIZATION --- renderAll(); });
Scroll to Top