Simulated Recommendations
${result.recommendations.map(r => `- ${r}
`).join('')}
`;
renderChart(result.categoryScores);
};
const renderChart = (scores) => {
const ctx = document.getElementById('seo-chart').getContext('2d');
if(seoChart) seoChart.destroy();
seoChart = new Chart(ctx, {
type: 'radar',
data: {
labels: ['On-Page SEO', 'Technical SEO', 'Off-Page SEO'],
datasets: [{
label: 'Score',
data: [scores.onPage, scores.technical, scores.offPage],
backgroundColor: 'rgba(59, 130, 246, 0.2)',
borderColor: 'rgba(59, 130, 246, 1)',
borderWidth: 2,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: { r: { beginAtZero: true, max: 100 } }
}
});
};
// --- CORE LOGIC ---
const handleCalculation = () => {
calculateBtnSpinner.classList.remove('hidden');
calculateBtnText.textContent = 'Analyzing...';
calculateBtn.disabled = true;
setTimeout(() => {
const totalWeight = Object.values(weights).reduce((s, v) => s + v, 0);
if (totalWeight !== 100) {
alert('Total weight must be 100%. Please adjust the sliders in the Configuration tab.');
calculateBtnSpinner.classList.add('hidden');
calculateBtnText.textContent = 'Calculate SEO Grade';
calculateBtn.disabled = false;
return;
}
// Simulate SEO data
const sim = {
onPage: Math.random() * 30 + 65, // 65-95
technical: Math.random() * 40 + 50, // 50-90
offPage: Math.random() * 50 + 30, // 30-80
};
const finalScore = (sim.onPage * (weights.onPage / 100)) +
(sim.technical * (weights.technical / 100)) +
(sim.offPage * (weights.offPage / 100));
const scoreToGrade = (score) => {
if (score >= 97) return 'A+'; if (score >= 93) return 'A'; if (score >= 90) return 'A-';
if (score >= 87) return 'B+'; if (score >= 83) return 'B'; if (score >= 80) return 'B-';
if (score >= 77) return 'C+'; if (score >= 73) return 'C'; if (score >= 70) return 'C-';
if (score >= 60) return 'D'; return 'F';
};
const recommendations = [];
if (sim.onPage < 75) recommendations.push('Improve on-page elements like title tags and meta descriptions.');
if (sim.technical < 70) recommendations.push('Focus on technical SEO: improve site speed and mobile friendliness.');
if (sim.offPage < 60) recommendations.push('Build more high-quality backlinks to increase domain authority.');
if (recommendations.length === 0) recommendations.push('Overall SEO health is strong. Keep up the great work!');
const result = {
finalScore,
grade: scoreToGrade(finalScore),
categoryScores: sim,
recommendations
};
renderDashboard(result);
downloadPdfBtn.disabled = false;
calculateBtnSpinner.classList.add('hidden');
calculateBtnText.textContent = 'Calculate SEO Grade';
calculateBtn.disabled = false;
}, 800);
};
// --- UI & EVENT HANDLERS ---
const switchTab = (tabId) => {
currentTab = tabId;
Object.values(tabPanes).forEach(pane => pane.classList.add('hidden'));
tabPanes[tabId].classList.remove('hidden');
Object.values(tabButtons).forEach(btn => btn.classList.replace('tab-active', 'tab-inactive'));
tabButtons[tabId].classList.replace('tab-inactive', 'tab-active');
updateNavButtons();
};
const navigateTabs = (direction) => {
const currentIndex = tabs.indexOf(currentTab);
const newIndex = direction === 'next' ? currentIndex + 1 : currentIndex - 1;
if (newIndex >= 0 && newIndex < tabs.length) switchTab(tabs[newIndex]);
};
const updateNavButtons = () => {
const currentIndex = tabs.indexOf(currentTab);
prevBtn.disabled = currentIndex === 0;
nextBtn.disabled = currentIndex === tabs.length - 1;
prevBtn.classList.toggle('opacity-50', prevBtn.disabled);
nextBtn.classList.toggle('opacity-50', nextBtn.disabled);
};
const handlePdfDownload = () => {
const pdfRenderContainer = document.getElementById('pdf-render-content');
const pdfContent = document.getElementById('pdf-content').innerHTML;
const url = document.getElementById('url-input').value || 'yourwebsite.com';
const header = `
SEO Analysis for ${url}
`;
pdfRenderContainer.innerHTML = header + pdfContent + '';
html2canvas(pdfRenderContainer, { scale: 2 }).then(canvas => {
const imgData = canvas.toDataURL('image/png');
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth(), margin = 40;
const contentWidth = pdfWidth - margin * 2;
const pdfHeight = (canvas.height * contentWidth) / canvas.width;
pdf.addImage(imgData, 'PNG', margin, margin, contentWidth, pdfHeight);
pdf.save(`SEO-Report-${url}.pdf`);
});
};
// --- EVENT LISTENERS ---
window.switchTab = switchTab;
window.navigateTabs = navigateTabs;
calculateBtn.addEventListener('click', handleCalculation);
downloadPdfBtn.addEventListener('click', handlePdfDownload);
weightsContainer.addEventListener('input', e => {
if (e.target.type === 'range') {
const key = e.target.dataset.key;
weights[key] = parseInt(e.target.value);
document.getElementById(`label-${key}`).textContent = `${weights[key]}%`;
updateWeightsTotal();
}
});
// --- INITIALIZATION ---
renderWeights();
updateNavButtons();
switchTab('dashboard');
});