-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreport.js
More file actions
170 lines (149 loc) · 8.87 KB
/
report.js
File metadata and controls
170 lines (149 loc) · 8.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
document.addEventListener("DOMContentLoaded", async () => {
try {
const storage = await chrome.storage.local.get("seoReportData");
const data = storage.seoReportData;
if (!data) {
document.body.innerHTML = "<h2 style='text-align:center; padding:50px;'>Rapor verisi bulunamadı.</h2>";
return;
}
const printBtn = document.getElementById("printBtn");
if(printBtn) printBtn.addEventListener("click", () => window.print());
// 1. Header
setText("r-title", data.title || "Başlık Yok");
const rUrl = document.getElementById("r-url");
if(rUrl) { rUrl.textContent = data.domain || "-"; rUrl.href = data.url || "#"; }
setText("r-date", data.date || new Date().toLocaleDateString("tr-TR"));
// 2. SKOR GÖSTERİMİ (ÇİFT SKOR)
const scores = data.scores || { final: 0, technical: 0, penalty: 0 }; // Güvenlik
const scoreEl = document.getElementById("r-score");
if(scoreEl) {
scoreEl.textContent = scores.final;
const color = scores.final > 80 ? "#22c55e" : scores.final > 50 ? "#f59e0b" : "#ef4444";
scoreEl.style.backgroundColor = color;
scoreEl.style.color = "#fff";
scoreEl.style.borderColor = color;
}
// 3. YÖNETİCİ ÖZETİ (DETAYLI)
const execSum = document.getElementById("executive-summary");
if(execSum) {
let summaryText = "";
if(scores.final > 80) summaryText = `<strong>Mükemmel İş!</strong> Siteniz teknik açıdan çok sağlam (${scores.technical} Puan). İçerik ve altyapı modern SEO standartlarına uygun.`;
else if(scores.final > 50) summaryText = `<strong>Geliştirilmeli.</strong> Teknik altyapınız orta seviyede (${scores.technical} Puan). Ancak performans ve içerik tarafında eksikler var.`;
else summaryText = `<strong>Kritik Hatalar.</strong> Sitenin teknik SEO puanı düşük (${scores.technical} Puan). Acil müdahale gerekiyor.`;
if(scores.penalty > 0) {
summaryText += `<br><br><span style="color:#ef4444">⚠️ <strong>Yapay Zeka Uyarısı:</strong> İçeriğin robotik yapısı nedeniyle genel skordan <strong>-${scores.penalty} puan</strong> düşüldü.</span>`;
}
execSum.innerHTML = `<p class="${scores.final > 80 ? 'good-text' : 'warn-text'}">${summaryText}</p>`;
}
// 4. AKSİYON PLANI
const planList = document.getElementById("action-plan-list");
if(planList) {
planList.innerHTML = "";
if (data.solutionsLog && data.solutionsLog.length > 0) {
data.solutionsLog.forEach((item, index) => {
const row = document.createElement("div");
row.className = "action-item";
row.innerHTML = `<div class="action-num">${index + 1}</div><div class="action-content"><div class="action-title ${item.type}">${item.title}</div><div class="action-desc">${item.fix}</div></div>`;
planList.appendChild(row);
});
} else {
planList.innerHTML = "<div class='good-text' style='text-align:center'>Harika! Kritik sorun bulunamadı.</div>";
}
}
// 5. DETAYLI İÇERİK ANALİZİ (UZUN PARAGRAFLAR)
const contentBody = document.getElementById("content-analysis-body");
if(contentBody) {
let html = "";
// Title Analizi
html += generateVerboseBlock("Başlık Etiketi (Title)", data.titleLength, 30, 60,
`Mevcut: <strong>${data.titleLength} karakter</strong>.`,
"Başlık etiketi, arama motorlarının ve kullanıcıların içeriğinizi anlaması için en önemli sinyaldir. İdeal uzunluk 30-60 karakter arasındadır."
);
// Desc Analizi
html += generateVerboseBlock("Meta Açıklama", data.descLength, 110, 160,
`Durum: <strong>${data.descLength > 0 ? "Mevcut" : "Eksik"}</strong> (${data.descLength} kr).`,
"Meta açıklamalar sıralamayı doğrudan etkilemese de, Tıklama Oranını (CTR) artırmak için hayati öneme sahiptir."
);
// İçerik & AI
html += `
<div class="detail-block">
<h4>📝 İçerik Kalitesi ve Derinliği</h4>
<p>Sayfada toplam <strong>${data.wordCount}</strong> kelime tespit edildi.
${data.wordCount < 300 ? "<span style='color:red'>Bu içerik 'Zayıf' (Thin Content) kategorisine girebilir. Google, konuyu derinlemesine ele alan içerikleri (1000+ kelime) ödüllendirir.</span>" : "Kelime sayısı makul seviyede."}
Metin/Kod oranı <strong>%${data.textRatio}</strong>.</p>
</div>
<div class="detail-block">
<h4>🤖 Yapay Zeka (AI) Doğallık Testi</h4>
<p>AI Skoru: <strong>%${data.aiAnalysis?.score || 0}</strong> (${data.aiAnalysis?.label}).
<br>Varyasyon: <strong>${data.aiAnalysis?.details || "-"}</strong>.</p>
<p class="info-text">Google 'Helpful Content' güncellemesi, insan odaklı içerikleri öne çıkarır.
${(data.aiAnalysis?.score || 0) > 70 ? "<strong>Uyarı:</strong> Metninizde yüksek oranda robotik kalıplar ve monoton cümle yapıları tespit edildi. Lütfen daha doğal, deneyim odaklı bir dil kullanın." : "İçeriğiniz doğal ve insansı bir akışa sahip."}
</p>
</div>`;
contentBody.innerHTML = html;
}
// 6. TEKNİK ANALİZ
const techBody = document.getElementById("tech-analysis-body");
if(techBody) {
const stackStr = (data.techStack && data.techStack.length) ? data.techStack.join(", ") : "Standart HTML";
const lcpVal = data.cwv?.lcp > 0 ? data.cwv.lcp + " ms" : "Ölçülemedi";
const schemaStr = (data.schemaTypes && data.schemaTypes.length) ? data.schemaTypes.join(", ") : "Yok";
let html = `
<div class="detail-block">
<h4>⚡ Sayfa Performansı (Core Web Vitals)</h4>
<p><strong>LCP (Yükleme):</strong> ${lcpVal}. <strong>CLS (Kayma):</strong> ${data.cwv?.cls || 0}.</p>
<p class="info-text">${(data.cwv?.lcp || 0) > 2500 ? "⚠️ Siteniz yavaş yükleniyor (2.5s üzeri). Bu durum hemen çıkma oranını artırır." : "✅ Hız değerleriniz Google standartlarına uygun."}</p>
</div>
<div class="detail-block">
<h4>🏗️ Altyapı ve Yapısal Veri</h4>
<p>Tespit Edilen Teknolojiler: <strong>${stackStr}</strong>.</p>
<p>Schema Markup: <strong>${schemaStr}</strong>.
${data.schemaTypes?.length > 0 ? "Harika! Yapısal veriler arama sonuçlarında zengin görünüm (Rich Snippets) sağlar." : "Schema eksikliği, arama sonuçlarında sönük kalmanıza neden olabilir."}
</p>
</div>
`;
techBody.innerHTML = html;
}
// 7. LİNKLER & GÖRSELLER
const linkBody = document.getElementById("link-img-body");
if(linkBody) {
linkBody.innerHTML = `
<div class="detail-block">
<h4>🖼️ Görsel Optimizasyonu</h4>
<ul style="font-size:13px; color:#4b5563;">
<li>Toplam Görsel: <strong>${data.images?.total || 0}</strong></li>
<li style="color:${(data.images?.missingAlt||0)>0?'red':'green'}">Eksik Alt Etiketi: <strong>${data.images?.missingAlt || 0}</strong></li>
<li style="color:${(data.imgAnalysis?.notModern||0)>0?'orange':'green'}">Eski Format (JPG/PNG): <strong>${data.imgAnalysis?.notModern || 0}</strong></li>
</ul>
<p class="info-text">Görsellerinize mutlaka anahtar kelime içeren ALT etiketleri ekleyin ve WebP formatını tercih edin.</p>
</div>
<div class="detail-block">
<h4>🔗 Bağlantı Güvenliği</h4>
<p>Güvensiz Dış Linkler: <strong>${data.links?.unsafe || 0}</strong>.</p>
${(data.links?.unsafe || 0) > 0 ? "<p class='error-text'><strong>Kritik:</strong> 'Yeni sekmede açılan' linklerinizde <code>rel='noopener'</code> etiketi eksik. Bu durum sitenizi güvenlik açıklarına (Reverse Tabnabbing) karşı savunmasız bırakır.</p>" : "<p>Tüm dış bağlantılar güvenli görünüyor.</p>"}
</div>
`;
}
// 8. Google Preview
setText("r-g-title", data.title);
setText("r-g-url", data.url);
setText("r-g-desc", data.description);
} catch (err) {
console.error(err);
document.body.innerHTML += `<div style="color:red; text-align:center; padding:20px;">Rapor oluşturulurken bir hata oluştu.</div>`;
}
});
// Yardımcı: Uzun Blok Üretici
function generateVerboseBlock(title, val, min, max, statusHTML, info) {
let statusClass = "good-text";
if(val === 0 || val < min || val > max) statusClass = "warn-text";
if(val === 0) statusClass = "error-text";
return `
<div class="detail-block">
<h4>${title}</h4>
<p>${statusHTML}</p>
<p class="info-text">${info}</p>
</div>
`;
}
function setText(id, t) { const e=document.getElementById(id); if(e) e.textContent=t||"-"; }