Files
animexe/resources/views/admin/seo/index.blade.php
T
2026-07-14 00:01:48 +03:00

2430 lines
142 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('admin.layouts.app')
@section('title','SEO Paneli')
@section('page-title','SEO Paneli')
@push('styles')
<style>
/* ── Score ring ─────────────────────────────── */
.seo-score-ring { position:relative; display:inline-flex; align-items:center; justify-content:center; }
.seo-score-ring svg { transform:rotate(-90deg); }
.seo-score-ring .score-text { position:absolute; text-align:center; }
.seo-score-ring .score-num { font-size:2.4rem; font-weight:800; line-height:1; }
.seo-score-ring .score-lbl { font-size:.7rem; text-transform:uppercase; letter-spacing:.1em; color:var(--text2); }
/* ── Tab nav ────────────────────────────────── */
.seo-tab-nav { display:flex; gap:4px; flex-wrap:wrap; border-bottom:1px solid var(--border); margin-bottom:24px; }
.seo-tab-btn { padding:8px 14px; border:none; background:transparent; color:var(--text2); font-size:.82rem;
border-bottom:2px solid transparent; cursor:pointer; border-radius:6px 6px 0 0; transition:.15s; white-space:nowrap; }
.seo-tab-btn:hover { background:var(--border); color:var(--text); }
.seo-tab-btn.active { color:var(--accent); border-bottom-color:var(--accent); background:var(--border); }
.seo-tab-pane { display:none; }
.seo-tab-pane.active { display:block; }
/* ── Check items ────────────────────────────── */
.check-item { display:flex; align-items:flex-start; gap:10px; padding:10px 14px; border-radius:8px; margin-bottom:6px; }
.check-item.pass { background:rgba(35,134,54,.1); border:1px solid rgba(35,134,54,.25); }
.check-item.fail { background:rgba(248,81,73,.08); border:1px solid rgba(248,81,73,.2); }
.check-icon { font-size:1.1rem; flex-shrink:0; margin-top:1px; }
.check-item.pass .check-icon { color:var(--success); }
.check-item.fail .check-icon { color:var(--danger); }
.check-msg { font-size:.85rem; }
.check-weight { margin-left:auto; font-size:.72rem; color:var(--text2); white-space:nowrap; flex-shrink:0; }
/* ── Cards ──────────────────────────────────── */
.section-card { background:var(--bg2); border:1px solid var(--border); border-radius:12px; margin-bottom:20px; overflow:hidden; }
.section-card-header { padding:14px 20px; border-bottom:1px solid var(--border); display:flex; align-items:center; gap:8px; }
.section-card-header h6 { margin:0; font-size:.88rem; font-weight:600; }
.section-card-body { padding:20px; }
.stat-mini { background:var(--bg2); border:1px solid var(--border); border-radius:10px; padding:14px 18px; }
.stat-mini .sm-val { font-size:1.8rem; font-weight:800; }
.stat-mini .sm-lbl { font-size:.75rem; color:var(--text2); }
/* ── Preview ────────────────────────────────── */
.preview-card { background:#010409; border:1px solid var(--border); border-radius:8px; padding:16px 20px; font-family:'Arial',sans-serif; }
.preview-url { color:#8ab4f8; font-size:.75rem; }
.preview-title { color:#8ab4f8; font-size:1.05rem; font-weight:400; margin:4px 0 2px; }
.preview-desc { color:#bdc1c6; font-size:.82rem; line-height:1.5; }
/* ── Misc ───────────────────────────────────── */
.robots-editor { font-family:'Courier New',monospace; font-size:.82rem; background:#010409; border-color:var(--border2); color:var(--text); resize:vertical; min-height:280px; }
.seo-field-help { font-size:.75rem; color:var(--text2); margin-top:4px; }
.char-counter { font-size:.72rem; text-align:right; margin-top:2px; }
.char-counter.ok { color:var(--success); } .char-counter.warn { color:#d29922; } .char-counter.bad { color:var(--danger); }
.ping-badge { display:inline-block; padding:2px 8px; border-radius:10px; font-size:.7rem; font-weight:600; }
.ping-badge.success { background:rgba(35,134,54,.25); color:var(--success); border:1px solid rgba(35,134,54,.3); }
.ping-badge.error { background:rgba(248,81,73,.15); color:var(--danger); border:1px solid rgba(248,81,73,.25); }
/* ── Keyword tag ────────────────────────────── */
.kwd-tag { display:inline-flex; align-items:center; gap:6px; background:var(--border); border:1px solid var(--border2); border-radius:20px; padding:4px 10px; font-size:.78rem; }
.kwd-diff-bar { height:4px; border-radius:2px; background:var(--border2); position:relative; }
.kwd-diff-fill { height:100%; border-radius:2px; }
/* ── Anime SEO table ────────────────────────── */
.seo-coverage-bar { height:6px; border-radius:3px; background:var(--border); overflow:hidden; }
.seo-coverage-fill { height:100%; border-radius:3px; background:linear-gradient(90deg,var(--accent),#f59e0b); }
/* ── PageSpeed score circles ─────────────────── */
.psi-score { display:inline-flex; flex-direction:column; align-items:center; justify-content:center; width:80px; height:80px; border-radius:50%; font-size:1.4rem; font-weight:800; }
.psi-score.good { border:4px solid var(--success); color:var(--success); }
.psi-score.average { border:4px solid #d29922; color:#d29922; }
.psi-score.poor { border:4px solid var(--danger); color:var(--danger); }
/* ── Redirect table ─────────────────────────── */
.redirect-row td { font-size:.82rem; vertical-align:middle; }
.redirect-row.inactive td { opacity:.5; }
/* ── AI Chat ─────────────────────────────────── */
.ai-msg { display:flex; gap:10px; }
.ai-msg.user { flex-direction:row-reverse; }
.ai-bubble { max-width:88%; padding:10px 14px; border-radius:12px; font-size:.84rem; line-height:1.55; }
.ai-msg.assistant .ai-bubble { background:var(--surface); border:1px solid var(--border); color:var(--text); border-radius:4px 12px 12px 12px; }
.ai-msg.user .ai-bubble { background:var(--accent); color:#fff; border-radius:12px 4px 12px 12px; }
.ai-msg .ai-avatar { width:28px; height:28px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:.75rem; flex-shrink:0; }
.ai-msg.assistant .ai-avatar { background:var(--border); color:var(--accent); }
.ai-msg.user .ai-avatar { background:var(--accent); color:#fff; }
.ai-typing span { width:6px; height:6px; border-radius:50%; background:var(--text2); display:inline-block; animation:typing 1.2s infinite; }
.ai-typing span:nth-child(2) { animation-delay:.2s; } .ai-typing span:nth-child(3) { animation-delay:.4s; }
@keyframes typing { 0%,60%,100%{transform:translateY(0);opacity:.6} 30%{transform:translateY(-5px);opacity:1} }
.ai-bubble strong { color:var(--text); } .ai-bubble b { color:var(--accent); }
.ai-bubble code { background:var(--bg2); padding:1px 5px; border-radius:3px; font-size:.78rem; color:var(--info); }
.ai-bubble ul,.ai-bubble ol { padding-left:18px; margin:6px 0; } .ai-bubble li { margin-bottom:2px; }
.ai-bubble h3,.ai-bubble h4 { color:var(--text); font-size:.9rem; margin:10px 0 4px; }
.ai-kw-badge { display:inline-flex; align-items:center; gap:4px; background:var(--border); border:1px solid var(--border2); border-radius:16px; padding:3px 10px; font-size:.75rem; margin:2px; cursor:pointer; transition:.15s; }
.ai-kw-badge:hover { background:var(--border2); border-color:var(--accent); }
/* ── Analytics Tab ───────────────────────────── */
/* Integration status bar */
.analytics-status-bar { background:var(--bg2); border:1px solid var(--border); border-radius:12px; padding:14px 20px; display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.asb-label { font-size:.75rem; font-weight:700; text-transform:uppercase; letter-spacing:.08em; color:var(--text2); white-space:nowrap; }
.asb-items { display:flex; gap:8px; flex-wrap:wrap; }
.asb-item { display:flex; align-items:center; gap:6px; background:var(--surface); border:1px solid var(--border); border-radius:20px; padding:4px 12px 4px 8px; font-size:.78rem; }
.asb-item.connected .asb-dot { width:8px;height:8px;border-radius:50%;background:var(--success);flex-shrink:0;box-shadow:0 0 6px rgba(63,185,80,.6); }
.asb-item.disconnected .asb-dot { width:8px;height:8px;border-radius:50%;background:var(--border2);flex-shrink:0; }
.asb-item.connected .asb-name { color:var(--text);font-weight:500; }
.asb-item.disconnected .asb-name { color:var(--text2); }
.asb-tag { color:var(--text2); font-size:.72rem; max-width:100px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.asb-item.connected .asb-tag { color:var(--success); }
/* KPI Cards */
.analytics-kpi-card { background:var(--bg2); border:1px solid var(--border); border-radius:12px; padding:16px; display:flex; align-items:flex-start; gap:14px; height:100%; transition:.15s; }
.analytics-kpi-card:hover { border-color:var(--border2); transform:translateY(-1px); }
.kpi-icon { width:44px;height:44px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:1.2rem;flex-shrink:0; }
.kpi-body { flex:1; min-width:0; }
.kpi-val { font-size:1.8rem; font-weight:800; line-height:1.1; color:var(--text); }
.kpi-lbl { font-size:.73rem; color:var(--text2); margin-top:2px; text-transform:uppercase; letter-spacing:.06em; }
.kpi-trend { font-size:.72rem; margin-top:5px; display:inline-flex; align-items:center; gap:1px; padding:2px 7px; border-radius:10px; }
.kpi-trend.up { background:rgba(63,185,80,.1); color:var(--success); }
.kpi-trend.down { background:rgba(248,81,73,.08); color:var(--danger); }
/* Mini stats */
.analytics-mini-stat { background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:10px 14px; text-align:center; }
.ams-val { font-size:1.4rem; font-weight:800; }
.ams-lbl { font-size:.7rem; color:var(--text2); text-transform:uppercase; letter-spacing:.05em; margin-top:2px; }
/* Redirect stats grid */
.redirect-stat-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.rsg-item { background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:14px; text-align:center; }
.rsg-val { font-size:2rem; font-weight:800; }
.rsg-lbl { font-size:.72rem; color:var(--text2); margin-top:3px; }
/* Quick tools grid */
.quick-tools-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); gap:10px; }
.qt-card { display:flex; align-items:center; gap:12px; background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:12px 14px; text-decoration:none; transition:.15s; }
.qt-card:hover { border-color:var(--border2); background:#1c2128; transform:translateX(2px); text-decoration:none; }
.qt-icon { width:40px;height:40px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:1.1rem;flex-shrink:0; }
.qt-body { flex:1; min-width:0; }
.qt-name { font-size:.84rem; font-weight:600; color:var(--text); }
.qt-desc { font-size:.73rem; color:var(--text2); margin-top:1px; }
.qt-status { font-size:.68rem; font-weight:600; padding:3px 8px; border-radius:10px; white-space:nowrap; }
.qt-status.on { background:rgba(63,185,80,.12); color:var(--success); border:1px solid rgba(63,185,80,.2); }
.qt-status.off { background:rgba(139,148,158,.08); color:var(--text2); border:1px solid var(--border); }
/* GSC guide box */
.gsc-guide-box { background:#010409; border:1px solid var(--border); border-radius:8px; padding:14px; }
.ggb-title { font-size:.8rem; font-weight:600; color:var(--text); margin-bottom:8px; }
.ggb-steps { padding-left:18px; margin:0; }
.ggb-steps li { font-size:.78rem; color:var(--text2); margin-bottom:5px; line-height:1.5; }
.ggb-steps a { color:var(--info); text-decoration:none; }
.ggb-steps a:hover { text-decoration:underline; }
.ggb-steps code { background:var(--surface); padding:1px 5px; border-radius:3px; font-size:.73rem; color:var(--info); word-break:break-all; }
</style>
@endpush
@section('content')
<div>
{{-- Header --}}
<div class="d-flex align-items-center justify-content-between mb-4">
<div>
<h4 class="mb-1 fw-bold">SEO Paneli</h4>
<p class="text-muted mb-0" style="font-size:.85rem">Arama motoru optimizasyonu · Anahtar kelimeler · Yönlendirmeler · PageSpeed</p>
</div>
<div class="d-flex gap-2">
<a href="{{ route('home') }}" target="_blank" class="btn btn-outline-secondary btn-sm"><i class="bi bi-box-arrow-up-right me-1"></i>Siteyi Gör</a>
<a href="/sitemap.xml" target="_blank" class="btn btn-outline-info btn-sm"><i class="bi bi-diagram-3 me-1"></i>Sitemap</a>
</div>
</div>
@if(session('success'))
<div class="alert alert-success d-flex align-items-center gap-2 mb-4"><i class="bi bi-check-circle-fill"></i>{{ session('success') }}</div>
@endif
{{-- SEO Score Summary --}}
<div class="row g-3 mb-4">
<div class="col-md-3">
<div class="section-card h-100">
<div class="section-card-body d-flex flex-column align-items-center justify-content-center py-4">
<div class="seo-score-ring mb-3">
@php $sc = $audit['score']; $color = $sc>=80?'var(--success)':($sc>=60?'#d29922':'var(--danger)'); $circ = round(2*pi()*52*$sc/100,1); @endphp
<svg width="120" height="120" viewBox="0 0 120 120">
<circle cx="60" cy="60" r="52" fill="none" stroke="var(--border)" stroke-width="10"/>
<circle cx="60" cy="60" r="52" fill="none" stroke="{{ $color }}" stroke-width="10" stroke-dasharray="{{ $circ }} 999" stroke-linecap="round"/>
</svg>
<div class="score-text">
<div class="score-num" style="color:{{ $color }}">{{ $sc }}</div>
<div class="score-lbl">/ 100</div>
</div>
</div>
<div class="fw-semibold" style="font-size:.9rem">SEO Skoru</div>
<div style="font-size:.75rem;color:var(--text2)">@if($sc>=80)Mükemmel @elseif($sc>=60)Geliştirilmeli @else Kritik Sorunlar @endif</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-mini h-100 d-flex flex-column justify-content-center">
<div class="sm-val text-success">{{ $audit['pass_count'] }}</div>
<div class="sm-lbl">Geçen Kontrol</div>
<div class="mt-2" style="font-size:.75rem;color:var(--text2)">{{ $audit['totals']['total'] }} anime yayında</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-mini h-100 d-flex flex-column justify-content-center">
<div class="sm-val text-danger">{{ $audit['fail_count'] }}</div>
<div class="sm-lbl">Başarısız Kontrol</div>
<div class="mt-2" style="font-size:.75rem;color:var(--text2)">{{ $audit['totals']['noSeoTitle'] ?? 0 }} animede SEO başlık eksik</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-mini h-100 d-flex flex-column justify-content-center">
@php $cov = $animeSeoCoverage; $pct = $cov['total']>0?round($cov['has_seo_title']/$cov['total']*100):0; @endphp
<div class="sm-val" style="color:var(--info)">{{ $pct }}%</div>
<div class="sm-lbl">Anime SEO Kapsama</div>
<div class="mt-2 seo-coverage-bar"><div class="seo-coverage-fill" style="width:{{ $pct }}%"></div></div>
<div class="mt-1" style="font-size:.72rem;color:var(--text2)">{{ $cov['has_seo_title'] }}/{{ $cov['total'] }} başlık · {{ $cov['has_seo_desc'] }}/{{ $cov['total'] }} açıklama</div>
</div>
</div>
</div>
{{-- Tab Nav --}}
<div class="seo-tab-nav">
<button class="seo-tab-btn active" data-tab="meta"> <i class="bi bi-tags me-1"></i>Meta</button>
<button class="seo-tab-btn" data-tab="keywords"> <i class="bi bi-search me-1"></i>Anahtar Kelimeler</button>
<button class="seo-tab-btn" data-tab="anime-seo"> <i class="bi bi-collection-play me-1"></i>Anime SEO</button>
<button class="seo-tab-btn" data-tab="social"> <i class="bi bi-share me-1"></i>Sosyal Medya</button>
<button class="seo-tab-btn" data-tab="schema"> <i class="bi bi-braces me-1"></i>Yapısal Veri</button>
<button class="seo-tab-btn" data-tab="sitemap"> <i class="bi bi-diagram-3 me-1"></i>Sitemap</button>
<button class="seo-tab-btn" data-tab="robots"> <i class="bi bi-robot me-1"></i>Robots.txt</button>
<button class="seo-tab-btn" data-tab="redirects"> <i class="bi bi-signpost-split me-1"></i>Yönlendirmeler</button>
<button class="seo-tab-btn" data-tab="google"> <i class="bi bi-google me-1"></i>Google Araçları</button>
<button class="seo-tab-btn" data-tab="pagespeed"> <i class="bi bi-speedometer2 me-1"></i>PageSpeed</button>
<button class="seo-tab-btn" data-tab="audit"> <i class="bi bi-clipboard-check me-1"></i>Denetim</button>
<button class="seo-tab-btn" data-tab="ai"> <i class="bi bi-stars me-1"></i>AI Asistan</button>
</div>
{{-- ═══════ TAB 1: META ═══════ --}}
<form method="POST" action="{{ route('admin.seo.update') }}" id="seo-meta-form">
@csrf
<div class="seo-tab-pane active" id="tab-meta">
<div class="row g-4">
<div class="col-lg-7">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-type"></i><h6>Başlık Ayarları</h6></div>
<div class="section-card-body">
<div class="mb-3">
<label class="form-label">Site Adı</label>
<input type="text" name="seo_site_name" class="form-control" value="{{ $settings['seo_site_name'] ?? 'Animexe' }}">
<div class="seo-field-help">OG etiketlerinde ve sayfa başlıklarında kullanılır.</div>
</div>
<div class="mb-3">
<label class="form-label">Başlık Şablonu</label>
<input type="text" name="seo_title_template" class="form-control" value="{{ $settings['seo_title_template'] ?? '%s — Animexe' }}">
<div class="seo-field-help"><code>%s</code> = sayfa adı. Örn: <em>Naruto Animexe | Türkçe Anime İzle</em></div>
</div>
<div class="mb-3">
<label class="form-label">Anasayfa Başlığı</label>
<input type="text" name="seo_home_title" class="form-control" value="{{ html_entity_decode($settings['seo_home_title'] ?? '', ENT_QUOTES) }}" id="inp_home_title" maxlength="70" oninput="updateCounter(this,'ctr_home_title',50,60,70); updatePreview()">
<div class="d-flex justify-content-between">
<div class="seo-field-help">5060 karakter ideal.</div>
<div class="char-counter" id="ctr_home_title">{{ strlen($settings['seo_home_title'] ?? '') }}/70</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Anasayfa Meta Açıklaması</label>
<textarea name="seo_home_description" class="form-control" rows="3" id="inp_home_desc" maxlength="320" oninput="updateCounter(this,'ctr_home_desc',120,160,320); updatePreview()">{{ $settings['seo_home_description'] ?? '' }}</textarea>
<div class="d-flex justify-content-between">
<div class="seo-field-help">120160 karakter ideal.</div>
<div class="char-counter" id="ctr_home_desc">{{ strlen($settings['seo_home_description'] ?? '') }}/320</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Anasayfa Anahtar Kelimeler</label>
<textarea name="seo_home_keywords" class="form-control" rows="2">{{ $settings['seo_home_keywords'] ?? '' }}</textarea>
<div class="seo-field-help">Virgülle ayrılmış. Ör: <em>anime izle, türkçe anime</em></div>
</div>
<div class="mb-3">
<label class="form-label">Canonical Domain</label>
<input type="url" name="seo_canonical_domain" class="form-control" value="{{ $settings['seo_canonical_domain'] ?? '' }}" placeholder="https://animexe.com">
<div class="seo-field-help">Trailing slash olmadan. Canonical URL'ler için kullanılır.</div>
</div>
</div>
</div>
<div class="section-card">
<div class="section-card-header"><i class="bi bi-eye-slash text-warning"></i><h6>Noindex Kuralları</h6></div>
<div class="section-card-body">
<div class="mb-2 d-flex align-items-center gap-3">
<div class="form-check form-switch mb-0">
<input type="checkbox" class="form-check-input" role="switch" name="seo_noindex_search" id="ni_search" value="1" {{ ($settings['seo_noindex_search']??'1')==='1'?'checked':'' }}>
<label class="form-check-label" for="ni_search">Arama Sayfası noindex</label>
</div>
<span class="badge bg-warning text-dark" style="font-size:.68rem">Önerilen</span>
</div>
<div class="mb-2 form-check form-switch">
<input type="checkbox" class="form-check-input" role="switch" name="seo_noindex_profile" id="ni_profile" value="1" {{ ($settings['seo_noindex_profile']??'1')==='1'?'checked':'' }}>
<label class="form-check-label" for="ni_profile">Profil & Kişisel Sayfalar noindex</label>
</div>
<div class="mb-2 form-check form-switch">
<input type="checkbox" class="form-check-input" role="switch" name="seo_noindex_watch" id="ni_watch" value="1" {{ ($settings['seo_noindex_watch']??'0')==='1'?'checked':'' }}>
<label class="form-check-label" for="ni_watch">İzleme (Player) Sayfaları noindex</label>
</div>
</div>
</div>
</div>
<div class="col-lg-5">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-google me-1"></i><h6>Google Arama Önizlemesi</h6></div>
<div class="section-card-body">
<div class="preview-card">
<div class="preview-url">animexe.com</div>
<div class="preview-title" id="prev_title">{{ $settings['seo_home_title'] ?? 'Animexe Türkçe Anime İzle' }}</div>
<div class="preview-desc" id="prev_desc">{{ Str::limit($settings['seo_home_description']??'',155) }}</div>
</div>
</div>
</div>
<div class="section-card">
<div class="section-card-header"><i class="bi bi-phone me-1"></i><h6>Mobil Snippet</h6></div>
<div class="section-card-body">
<div class="preview-card" style="max-width:300px">
<div style="font-size:.65rem;color:var(--text2)">animexe.com </div>
<div class="preview-title" style="font-size:.9rem" id="prev_title_mob">{{ $settings['seo_home_title']??'' }}</div>
<div class="preview-desc" style="font-size:.75rem" id="prev_desc_mob">{{ Str::limit($settings['seo_home_description']??'',100) }}</div>
</div>
</div>
</div>
<div class="section-card">
<div class="section-card-header"><i class="bi bi-bar-chart me-1"></i><h6>Karakter Kılavuzu</h6></div>
<div class="section-card-body">
@foreach(['Sayfa Başlığı'=>['guide_title','bar_title',50,60,70],'Meta Açıklama'=>['guide_desc','bar_desc',120,160,320]] as $lbl=>$cfg)
<div class="mb-3">
<div class="d-flex justify-content-between mb-1" style="font-size:.78rem">
<span>{{ $lbl }}</span><span id="{{ $cfg[0] }}" class="text-muted">0/{{ $cfg[4] }}</span>
</div>
<div class="progress" style="height:6px"><div class="progress-bar bg-success" id="{{ $cfg[1] }}" style="width:0%"></div></div>
</div>
@endforeach
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary px-4"><i class="bi bi-save me-2"></i>Meta Ayarlarını Kaydet</button>
</div>
</form>{{-- #seo-meta-form --}}
{{-- ═══════ TAB 2: ANAHTAR KELİMELER ═══════ --}}
<div class="seo-tab-pane" id="tab-keywords">
<div class="row g-4">
<div class="col-lg-5">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-plus-circle text-success"></i><h6>Yeni Anahtar Kelime Ekle</h6></div>
<div class="section-card-body">
<form method="POST" action="{{ route('admin.seo.keywords.store') }}">
@csrf
<div class="mb-3">
<label class="form-label">Anahtar Kelime <span class="text-danger">*</span></label>
<input type="text" name="keyword" class="form-control" placeholder="anime izle türkçe" required>
</div>
<div class="mb-3">
<label class="form-label">Hedef URL</label>
<input type="text" name="target_url" class="form-control" placeholder="/anime/naruto">
<div class="seo-field-help">Bu kelimeyi optimize etmek istediğiniz sayfa</div>
</div>
<div class="row g-2 mb-3">
<div class="col">
<label class="form-label">Aylık Arama Hacmi</label>
<input type="number" name="search_volume" class="form-control" placeholder="10000" min="0">
</div>
<div class="col">
<label class="form-label">Rekabet (0100)</label>
<input type="number" name="difficulty" class="form-control" placeholder="45" min="0" max="100">
<div class="seo-field-help">0=kolay, 100=çok zor</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Notlar</label>
<textarea name="notes" class="form-control" rows="2" placeholder="Bu kelime için stratejik notlar..."></textarea>
</div>
<button type="submit" class="btn btn-success w-100"><i class="bi bi-plus me-1"></i>Ekle</button>
</form>
</div>
</div>
</div>
<div class="col-lg-7">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-table"></i><h6>Anahtar Kelime Listesi ({{ $keywords->count() }})</h6></div>
@if($keywords->isEmpty())
<div class="section-card-body text-center text-muted py-5">
<i class="bi bi-search" style="font-size:2rem;opacity:.3;display:block;margin-bottom:8px"></i>
Henüz anahtar kelime eklenmedi. Sol taraftan ekleyin.
</div>
@else
<div class="table-responsive">
<table class="table table-sm mb-0">
<thead class="table-dark">
<tr>
<th>Kelime</th>
<th>Hedef URL</th>
<th style="width:90px">Hacim</th>
<th style="width:80px">Rekabet</th>
<th style="width:60px"></th>
</tr>
</thead>
<tbody>
@foreach($keywords as $kw)
<tr>
<td>
<div class="fw-semibold" style="font-size:.85rem">{{ $kw->keyword }}</div>
@if($kw->notes)<div style="font-size:.72rem;color:var(--text2)">{{ Str::limit($kw->notes,60) }}</div>@endif
</td>
<td>
@if($kw->target_url)
<a href="{{ $kw->target_url }}" target="_blank" style="font-size:.78rem;color:var(--info)">{{ Str::limit($kw->target_url,30) }}</a>
@else<span class="text-muted small">—</span>@endif
</td>
<td>
@if($kw->search_volume !== null)
<span class="badge bg-info text-dark" style="font-size:.72rem">{{ number_format($kw->search_volume) }}</span>
@else<span class="text-muted small">—</span>@endif
</td>
<td>
@if($kw->difficulty !== null)
@php $dc = $kw->difficulty<=33?'var(--success)':($kw->difficulty<=66?'#d29922':'var(--danger)'); @endphp
<div style="font-size:.8rem;color:{{ $dc }};font-weight:600">{{ $kw->difficulty }}</div>
<div class="kwd-diff-bar mt-1"><div class="kwd-diff-fill" style="width:{{ $kw->difficulty }}%;background:{{ $dc }}"></div></div>
@else<span class="text-muted small"></span>@endif
</td>
<td>
<form method="POST" action="{{ route('admin.seo.keywords.destroy', $kw) }}" onsubmit="return confirm('Sil?')">
@csrf @method('DELETE')
<button class="btn btn-sm btn-outline-danger p-1"><i class="bi bi-trash" style="font-size:.75rem"></i></button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
</div>
<div class="section-card">
<div class="section-card-header"><i class="bi bi-lightbulb text-warning"></i><h6>Sıralama İpuçları</h6></div>
<div class="section-card-body">
<div class="row g-3">
@foreach([
['bi-1-circle','Anime Türkiye Odaklı','anime izle, türkçe anime, ücretsiz anime gibi yerel arama kelimelerine odaklanın'],
['bi-2-circle','Long-tail Kelimeler','naruto türkçe altyazılı izle, attack on titan dublaj gibi uzun kuyruklu kelimeler daha az rekabetçi'],
['bi-3-circle','İçerik Sıklığı','Popüler animeler için haftada en az 1 bölüm ekleyin. Google taze içeriği sever'],
['bi-4-circle','Internal Linking','Anime sayfalarında benzer türlere link verin. Dahili bağlantı SEO skorunu artırır'],
] as $tip)
<div class="col-md-6">
<div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px">
<div class="d-flex align-items-center gap-2 mb-1">
<i class="bi {{ $tip[0] }}" style="color:var(--accent)"></i>
<span style="font-size:.82rem;font-weight:600">{{ $tip[1] }}</span>
</div>
<div style="font-size:.75rem;color:var(--text2)">{{ $tip[2] }}</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
{{-- ═══════ TAB 3: ANİME SEO ═══════ --}}
<div class="seo-tab-pane" id="tab-anime-seo">
{{-- ── Toplu Doldurma Paneli ── --}}
<div class="section-card mb-4" id="bulk-fill-panel">
<div class="card-header d-flex align-items-center gap-2">
<i class="bi bi-lightning-fill" style="color:var(--warning)"></i>
<h6 class="mb-0">Toplu AI Doldurma</h6>
<span class="badge bg-secondary ms-auto" id="bf-coverage-badge">Yükleniyor...</span>
</div>
<div class="card-body">
{{-- Coverage istatistikleri --}}
<div id="bf-stats" style="display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:16px">
<div class="text-center p-2" style="background:var(--bg);border:1px solid var(--border);border-radius:8px">
<div style="font-size:22px;font-weight:700;color:var(--success)" id="bf-pct-seo"></div>
<div style="font-size:11px;color:var(--text2)">SEO Başlığı Var</div>
</div>
<div class="text-center p-2" style="background:var(--bg);border:1px solid var(--border);border-radius:8px">
<div style="font-size:22px;font-weight:700;color:var(--info)" id="bf-pct-desc"></div>
<div style="font-size:11px;color:var(--text2)">Açıklama Var</div>
</div>
<div class="text-center p-2" style="background:var(--bg);border:1px solid var(--border);border-radius:8px">
<div style="font-size:22px;font-weight:700" id="bf-needs-seo"></div>
<div style="font-size:11px;color:var(--text2)">SEO Eksik Anime</div>
</div>
<div class="text-center p-2" style="background:var(--bg);border:1px solid var(--border);border-radius:8px">
<div style="font-size:22px;font-weight:700" id="bf-needs-meta"></div>
<div style="font-size:11px;color:var(--text2)">Meta Eksik Anime</div>
</div>
</div>
{{-- Aksiyon butonları --}}
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:14px">
<div style="border:1px solid var(--border);border-radius:8px;padding:12px">
<div style="font-weight:600;font-size:13px;margin-bottom:4px">
<i class="bi bi-lightning" style="color:var(--warning)"></i> Hızlı SEO
</div>
<div style="font-size:11px;color:var(--text2);margin-bottom:8px">Template kullanır, AI çağrısı yok. Tüm anime birkaç saniyede tamamlanır.</div>
<button class="btn btn-sm btn-outline-warning w-100" onclick="startBulkFill('template_seo')">
<i class="bi bi-stars me-1"></i>Tümüne Uygula
</button>
</div>
<div style="border:1px solid var(--border);border-radius:8px;padding:12px">
<div style="font-weight:600;font-size:13px;margin-bottom:4px">
<i class="bi bi-robot" style="color:var(--info)"></i> AI SEO
</div>
<div style="font-size:11px;color:var(--text2);margin-bottom:8px">DeepSeek ile her anime için özgün SEO başlığı ve açıklama üretir.</div>
<button class="btn btn-sm btn-outline-info w-100" onclick="startBulkFill('ai_seo')">
<i class="bi bi-robot me-1"></i>AI ile Uygula
</button>
</div>
<div style="border:1px solid var(--border);border-radius:8px;padding:12px">
<div style="font-weight:600;font-size:13px;margin-bottom:4px">
<i class="bi bi-magic" style="color:var(--success)"></i> Tam Doldurma
</div>
<div style="font-size:11px;color:var(--text2);margin-bottom:8px">Açıklama + Yıl + Stüdyo + Türler + SEO başlığı her şeyi AI ile doldurur.</div>
<button class="btn btn-sm btn-outline-success w-100" onclick="startBulkFill('ai_all')">
<i class="bi bi-magic me-1"></i>Hepsini Doldur
</button>
</div>
</div>
<div class="d-flex gap-2 mb-2">
<label class="d-flex align-items-center gap-2" style="font-size:12px;cursor:pointer">
<input type="checkbox" id="bf-force"> Dolu alanları da üzerine yaz (force)
</label>
<button class="btn btn-sm btn-danger ms-auto d-none" id="bf-stop-btn" onclick="stopBulkFill()">
<i class="bi bi-stop-fill me-1"></i>Durdur
</button>
</div>
{{-- Progress alanı --}}
<div id="bf-progress-area" style="display:none">
<div style="display:flex;justify-content:space-between;font-size:12px;color:var(--text2);margin-bottom:4px">
<span id="bf-progress-label">İşleniyor...</span>
<span id="bf-progress-count">0 / 0</span>
</div>
<div style="height:10px;background:var(--bg);border-radius:5px;overflow:hidden">
<div id="bf-progress-bar" style="height:100%;background:var(--accent);border-radius:5px;transition:width .3s;width:0%"></div>
</div>
<div id="bf-log" style="margin-top:8px;font-size:11px;color:var(--text2);font-family:monospace;max-height:80px;overflow-y:auto"></div>
</div>
</div>
</div>
{{-- ── Tablo başlığı ── --}}
<div class="d-flex align-items-center justify-content-between mb-3">
<div>
<h6 class="mb-1">Anime SEO Başlıkları & Açıklamaları</h6>
<p class="text-muted mb-0" style="font-size:.8rem">Tek tek anime için düzenle ve kaydet. Toplu işlem için yukarıdaki paneli kullan.</p>
</div>
</div>
<form method="POST" action="{{ route('admin.seo.anime-bulk') }}" id="anime-seo-form">
@csrf
<div class="section-card">
<div class="table-responsive">
<table class="table table-sm mb-0">
<thead class="table-dark">
<tr>
<th style="width:200px">Anime</th>
<th>SEO Başlığı <small class="text-muted">(max 70 karakter)</small></th>
<th>Meta Açıklaması <small class="text-muted">(max 160 karakter)</small></th>
<th style="width:80px">Anahtar Kelimeler</th>
<th style="width:50px"></th>
</tr>
</thead>
<tbody>
@foreach($animes as $a)
<tr id="anime-row-{{ $a->id }}">
<input type="hidden" name="animes[{{ $loop->index }}][id]" value="{{ $a->id }}">
<td>
<div class="fw-semibold" style="font-size:.82rem">{{ Str::limit($a->title,30) }}</div>
<div style="font-size:.7rem;color:var(--text2)">/anime/{{ $a->slug }}</div>
@if(!$a->seo_title)
<span class="badge bg-danger" style="font-size:.65rem">SEO eksik</span>
@else
<span class="badge bg-success" style="font-size:.65rem">SEO var</span>
@endif
</td>
<td>
<input type="text" name="animes[{{ $loop->index }}][seo_title]"
class="form-control form-control-sm seo-title-inp"
data-id="{{ $a->id }}"
value="{{ $a->seo_title ?? '' }}"
maxlength="100"
placeholder="{{ Str::limit($a->title.' — Türkçe Anime | Animexe',70) }}">
</td>
<td>
<textarea name="animes[{{ $loop->index }}][seo_meta_desc]"
class="form-control form-control-sm"
rows="2"
maxlength="320"
placeholder="Bu anime hakkında kısa açıklama...">{{ $a->seo_meta_desc ?? '' }}</textarea>
</td>
<td>
<input type="text" name="animes[{{ $loop->index }}][seo_keywords]"
class="form-control form-control-sm"
value="{{ $a->seo_keywords ?? '' }}"
placeholder="anahtar,kelimeler">
</td>
<td>
<button type="button" class="btn btn-sm btn-outline-secondary p-1 btn-auto-seo" data-id="{{ $a->id }}" title="Otomatik Oluştur">
<i class="bi bi-stars" style="font-size:.75rem"></i>
</button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="p-3 border-top border-secondary d-flex align-items-center justify-content-between">
<div>{{ $animes->links() }}</div>
<button type="submit" class="btn btn-primary"><i class="bi bi-save me-1"></i>Bu Sayfayı Kaydet</button>
</div>
</div>
</form>
</div>
{{-- ═══════ TAB 4: SOSYAL MEDYA ═══════ --}}
<form method="POST" action="{{ route('admin.seo.update') }}">
@csrf
<div class="seo-tab-pane" id="tab-social">
<div class="row g-4">
<div class="col-lg-6">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-facebook text-primary me-1"></i><h6>Open Graph (Facebook / WhatsApp / LinkedIn)</h6></div>
<div class="section-card-body">
<div class="mb-3">
<label class="form-label">Varsayılan OG Görseli</label>
<input type="text" name="seo_og_image" class="form-control" value="{{ $settings['seo_og_image'] ?? '' }}" placeholder="/images/og-animexe.jpg">
<div class="seo-field-help">1200×630px önerilir. HTTPS URL veya /public altı yol.</div>
</div>
<div class="mb-3">
<label class="form-label">Facebook App ID</label>
<input type="text" name="seo_facebook_app_id" class="form-control" value="{{ $settings['seo_facebook_app_id'] ?? '' }}" placeholder="123456789012345">
</div>
</div>
</div>
<div class="section-card">
<div class="section-card-header"><i class="bi bi-twitter-x me-1"></i><h6>Twitter / X Card</h6></div>
<div class="section-card-body">
<div class="mb-3">
<label class="form-label">Twitter Kullanıcı Adı</label>
<div class="input-group">
<span class="input-group-text">@</span>
<input type="text" name="seo_twitter_site" class="form-control" value="{{ ltrim($settings['seo_twitter_site'] ?? '', '@') }}" placeholder="animexecom">
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-building me-1"></i><h6>Organizasyon Bilgileri (Schema)</h6></div>
<div class="section-card-body">
<div class="mb-3">
<label class="form-label">Logo URL</label>
<input type="text" name="seo_org_logo" class="form-control" value="{{ $settings['seo_org_logo'] ?? '' }}">
</div>
<div class="mb-3">
<label class="form-label">Twitter URL</label>
<input type="text" name="seo_org_twitter" class="form-control" value="{{ $settings['seo_org_twitter'] ?? '' }}" placeholder="https://twitter.com/animexecom">
</div>
<div class="mb-3">
<label class="form-label">Facebook URL</label>
<input type="text" name="seo_org_facebook" class="form-control" value="{{ $settings['seo_org_facebook'] ?? '' }}" placeholder="https://facebook.com/animexecom">
</div>
<div class="mb-3">
<label class="form-label">Instagram URL</label>
<input type="text" name="seo_org_instagram" class="form-control" value="{{ $settings['seo_org_instagram'] ?? '' }}" placeholder="https://instagram.com/animexecom">
</div>
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary px-4"><i class="bi bi-save me-2"></i>Sosyal Medya Ayarlarını Kaydet</button>
</div>
</form>{{-- social form --}}
{{-- ═══════ TAB 5: YAPISAL VERİ ═══════ --}}
<form method="POST" action="{{ route('admin.seo.update') }}">
@csrf
<input type="hidden" name="_seo_section" value="schema">
<div class="seo-tab-pane" id="tab-schema">
<div class="row g-4">
<div class="col-lg-6">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-braces"></i><h6>Schema.org Ayarları</h6></div>
<div class="section-card-body">
<div class="mb-3 d-flex align-items-center gap-3">
<div class="form-check form-switch mb-0">
<input type="checkbox" class="form-check-input" role="switch" name="seo_enable_schema" id="sch_main" value="1" {{ ($settings['seo_enable_schema']??'1')==='1'?'checked':'' }}>
<label class="form-check-label" for="sch_main">Schema.org İşaretleme Aktif</label>
</div>
<span class="badge bg-success" style="font-size:.68rem">Önerilen</span>
</div>
<div class="mb-3 form-check form-switch">
<input type="checkbox" class="form-check-input" role="switch" name="seo_enable_breadcrumb" id="sch_bc" value="1" {{ ($settings['seo_enable_breadcrumb']??'1')==='1'?'checked':'' }}>
<label class="form-check-label" for="sch_bc">BreadcrumbList Schema</label>
</div>
<div class="mb-3 d-flex align-items-center gap-3">
<div class="form-check form-switch mb-0">
<input type="checkbox" class="form-check-input" role="switch" name="seo_enable_faq_schema" id="sch_faq" value="1" {{ ($settings['seo_enable_faq_schema']??'1')==='1'?'checked':'' }}>
<label class="form-check-label" for="sch_faq">FAQ Schema (Rich Snippet)</label>
</div>
<span class="badge bg-info text-dark" style="font-size:.68rem">Rich Snippet</span>
</div>
<div class="mb-3 d-flex align-items-center gap-3">
<div class="form-check form-switch mb-0">
<input type="checkbox" class="form-check-input" role="switch" name="seo_enable_video_schema" id="sch_vid" value="1" {{ ($settings['seo_enable_video_schema']??'1')==='1'?'checked':'' }}>
<label class="form-check-label" for="sch_vid">VideoObject Schema</label>
</div>
<span class="badge bg-info text-dark" style="font-size:.68rem">Rich Snippet</span>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-info-circle text-info"></i><h6>Schema Türleri Hakkında</h6></div>
<div class="section-card-body">
@foreach([
['Organization','Site kimliği için. Google\'ın sitenizi tanımasını sağlar.','bg-success'],
['TVSeries / Movie','Her anime için. IMDB benzeri rich snippet\'ler oluşturur.','bg-success'],
['BreadcrumbList','Navigasyon yolu. Arama sonuçlarında alt bağlantılar gösterir.','bg-info text-dark'],
['VideoObject','Bölüm sayfaları için. Video thumbnails arama sonuçlarında çıkar.','bg-warning text-dark'],
['FAQPage','Anime SSS bölümü. Arama sonuçlarında soru-cevap kutucukları gösterir.','bg-warning text-dark'],
] as $s)
<div class="d-flex align-items-start gap-2 mb-3">
<span class="badge {{ $s[2] }}" style="font-size:.72rem;white-space:nowrap;margin-top:2px">{{ $s[0] }}</span>
<span style="font-size:.8rem;color:var(--text2)">{{ $s[1] }}</span>
</div>
@endforeach
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary px-4"><i class="bi bi-save me-2"></i>Yapısal Veri Ayarlarını Kaydet</button>
</div>
{{-- ═══════ TAB 6: SİTEMAP ═══════ --}}
<div class="seo-tab-pane" id="tab-sitemap">
<div class="row g-4">
<div class="col-lg-5">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-diagram-3"></i><h6>Sitemap İstatistikleri</h6></div>
<div class="section-card-body">
<div class="row g-2 mb-3">
@foreach([['Anime','bi-play-circle',$sitemapStats['anime_count'],'#58a6ff'],['Tür','bi-tags',$sitemapStats['genre_count'],'var(--success)'],['Statik','bi-file-text',2,'var(--text2)']] as $s)
<div class="col-4 text-center">
<div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 8px">
<i class="bi {{ $s[1] }}" style="font-size:1.2rem;color:{{ $s[3] }}"></i>
<div style="font-size:1.4rem;font-weight:800;color:{{ $s[3] }}">{{ $s[2] }}</div>
<div style="font-size:.72rem;color:var(--text2)">{{ $s[0] }}</div>
</div>
</div>
@endforeach
</div>
@if($sitemapStats['last_updated'])
<div class="text-muted" style="font-size:.78rem"><i class="bi bi-clock me-1"></i>Son güncelleme: {{ $sitemapStats['last_updated'] }}</div>
@endif
</div>
</div>
<div class="section-card">
<div class="section-card-header"><i class="bi bi-send"></i><h6>Arama Motorlarına Bildir</h6></div>
<div class="section-card-body">
@if(session('ping_results'))
<div class="d-flex gap-2 mb-3">
@foreach(session('ping_results') as $e=>$r)
<span class="ping-badge {{ $r }}"><i class="bi bi-{{ $r==='success'?'check':'x' }}-circle me-1"></i>{{ ucfirst($e) }}</span>
@endforeach
</div>
@endif
<form method="POST" action="{{ route('admin.seo.ping') }}">
@csrf
<button type="submit" class="btn btn-outline-info w-100">
<i class="bi bi-broadcast me-1"></i>Google & Bing'e Bildirim Gönder
</button>
</form>
<div class="seo-field-help mt-2">sitemap.xml güncellendiğinde arama motorlarını haberdar eder.</div>
</div>
</div>
</div>
<div class="col-lg-7">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-file-earmark-code"></i><h6>Sitemap Önizleme</h6></div>
<div class="section-card-body">
<div class="sitemap-url-list" style="max-height:400px;overflow-y:auto;background:#010409;border:1px solid var(--border);border-radius:8px">
@php $previewAnimes = \App\Models\Anime::where('is_published',true)->orderByDesc('updated_at')->take(15)->get(['title','slug','updated_at']); @endphp
@foreach($previewAnimes as $pa)
<div style="padding:8px 14px;border-bottom:1px solid var(--border);font-size:.78rem;display:flex;justify-content:space-between">
<span style="color:var(--info)">/anime/{{ $pa->slug }}</span>
<span style="color:var(--text2)">{{ $pa->updated_at?->format('Y-m-d') }}</span>
</div>
@endforeach
<div style="padding:8px 14px;border-bottom:1px solid var(--border);font-size:.78rem;color:var(--text2)">... ve daha fazlası</div>
</div>
<div class="mt-2 text-end">
<a href="/sitemap.xml" target="_blank" class="btn btn-sm btn-outline-secondary">
<i class="bi bi-box-arrow-up-right me-1"></i>Tüm Sitemap'ı Gör
</a>
</div>
</div>
</div>
</div>
</div>
</div>
{{-- ═══════ TAB 7: ROBOTS.TXT ═══════ --}}
<div class="seo-tab-pane" id="tab-robots">
</form>{{-- ana form burada biter --}}
<div class="row g-4">
<div class="col-lg-7">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-robot"></i><h6>robots.txt Düzenle</h6></div>
<div class="section-card-body">
<form method="POST" action="{{ route('admin.seo.robots') }}">
@csrf
<textarea name="robots_txt" class="form-control robots-editor">{{ $robotsTxt ?: "User-agent: *\nDisallow: /admin\nDisallow: /api\nDisallow: /storage\n\nSitemap: https://animexe.com/sitemap.xml" }}</textarea>
<div class="mt-3 d-flex gap-2">
<button type="submit" class="btn btn-primary"><i class="bi bi-save me-1"></i>Kaydet</button>
<button type="button" class="btn btn-outline-secondary" onclick="resetRobots()"><i class="bi bi-arrow-counterclockwise me-1"></i>Sıfırla</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-lg-5">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-info-circle text-info"></i><h6>robots.txt Rehberi</h6></div>
<div class="section-card-body">
@foreach([
['Disallow: /admin','Admin panelini tara engelleyin. Güvenlik ve bant genişliği.'],
['Disallow: /api','API rotaları indexlenmemeli.'],
['Allow: /','Her şeye izin ver (varsayılan).'],
['Sitemap: https://...','Sitemap konumunu belirtin. Mecburi değil ama önerilir.'],
['User-agent: Googlebot','Sadece Google botu için kural yazın.'],
['Crawl-delay: 5','Bot tarama hızını saniye cinsinden sınırlayın.'],
] as $r)
<div class="mb-2" style="font-size:.8rem">
<code style="color:var(--info)">{{ $r[0] }}</code>
<div style="color:var(--text2);font-size:.73rem">{{ $r[1] }}</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
<form method="POST" action="{{ route('admin.seo.update') }}" style="display:none" id="seo-reopen-form">@csrf</form>
{{-- ═══════ TAB 8: YÖNLENDİRMELER ═══════ --}}
</div>
<div class="seo-tab-pane" id="tab-redirects">
<div class="row g-4">
<div class="col-lg-4">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-plus-circle text-success"></i><h6>Yeni Yönlendirme Ekle</h6></div>
<div class="section-card-body">
<form method="POST" action="{{ route('admin.seo.redirects.store') }}">
@csrf
<div class="mb-3">
<label class="form-label">Kaynak URL <span class="text-danger">*</span></label>
<input type="text" name="from_path" class="form-control" placeholder="/eski-anime-sayfasi" required>
<div class="seo-field-help">Tam yol girin (/ile başlayan)</div>
</div>
<div class="mb-3">
<label class="form-label">Hedef URL <span class="text-danger">*</span></label>
<input type="text" name="to_path" class="form-control" placeholder="/anime/naruto" required>
</div>
<div class="mb-3">
<label class="form-label">Tür</label>
<select name="type" class="form-select">
<option value="301">301 Kalıcı (SEO değerini devreder)</option>
<option value="302">302 Geçici</option>
</select>
</div>
<button type="submit" class="btn btn-success w-100"><i class="bi bi-plus me-1"></i>Ekle</button>
</form>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-table"></i><h6>Aktif Yönlendirmeler ({{ $redirects->total() }})</h6></div>
@if($redirects->isEmpty())
<div class="section-card-body text-center text-muted py-5">
<i class="bi bi-signpost-split" style="font-size:2rem;opacity:.3;display:block;margin-bottom:8px"></i>
Henüz yönlendirme eklenmedi.
</div>
@else
<div class="table-responsive">
<table class="table table-sm mb-0">
<thead class="table-dark">
<tr><th>Kaynak</th><th>Hedef</th><th style="width:60px">Tür</th><th style="width:70px">İsabet</th><th style="width:100px">Durum</th><th style="width:50px"></th></tr>
</thead>
<tbody>
@foreach($redirects as $rd)
<tr class="redirect-row {{ $rd->is_active?'':'inactive' }}">
<td><code style="font-size:.75rem;color:var(--info)">{{ $rd->from_path }}</code></td>
<td><code style="font-size:.75rem;color:var(--info)">{{ Str::limit($rd->to_path,40) }}</code></td>
<td><span class="badge {{ $rd->type===301?'bg-success':'bg-warning text-dark' }}" style="font-size:.7rem">{{ $rd->type }}</span></td>
<td><span class="text-muted" style="font-size:.8rem">{{ number_format($rd->hits) }}</span></td>
<td>
<button type="button" class="btn btn-sm {{ $rd->is_active?'btn-success':'btn-secondary' }} btn-toggle-redirect" data-id="{{ $rd->id }}" style="font-size:.72rem;padding:2px 8px">
{{ $rd->is_active?'Aktif':'Pasif' }}
</button>
</td>
<td>
<form method="POST" action="{{ route('admin.seo.redirects.destroy', $rd) }}" onsubmit="return confirm('Sil?')">
@csrf @method('DELETE')
<button class="btn btn-sm btn-outline-danger p-1"><i class="bi bi-trash" style="font-size:.75rem"></i></button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="p-3 border-top border-secondary">{{ $redirects->links() }}</div>
@endif
</div>
</div>
</div>
</div>
{{-- ═══════ TAB 9: ANALİTİK & ARAÇLAR ═══════ --}}
<div class="seo-tab-pane" id="tab-google">
{{-- ── Integration Status Banner ─────────────────────────────────────── --}}
<div class="analytics-status-bar mb-4">
<div class="asb-label"><i class="bi bi-plug-fill me-1"></i>Entegrasyon Durumu</div>
<div class="asb-items">
<div class="asb-item {{ $integrations['ga4'] ? 'connected' : 'disconnected' }}">
<span class="asb-dot"></span>
<span class="asb-name">Google Analytics 4</span>
<span class="asb-tag">{{ $integrations['ga4'] ? ($settings['seo_google_analytics']??'') : 'Bağlı değil' }}</span>
</div>
<div class="asb-item {{ $integrations['gtm'] ? 'connected' : 'disconnected' }}">
<span class="asb-dot"></span>
<span class="asb-name">Tag Manager</span>
<span class="asb-tag">{{ $integrations['gtm'] ? ($settings['seo_gtm_id']??'') : 'Bağlı değil' }}</span>
</div>
<div class="asb-item {{ $integrations['gsc'] ? 'connected' : 'disconnected' }}">
<span class="asb-dot"></span>
<span class="asb-name">Search Console</span>
<span class="asb-tag">{{ $integrations['gsc'] ? 'Doğrulandı' : 'Bağlı değil' }}</span>
</div>
<div class="asb-item {{ $integrations['bing'] ? 'connected' : 'disconnected' }}">
<span class="asb-dot"></span>
<span class="asb-name">Bing Webmaster</span>
<span class="asb-tag">{{ $integrations['bing'] ? 'Doğrulandı' : 'Bağlı değil' }}</span>
</div>
<div class="asb-item {{ $integrations['yandex'] ? 'connected' : 'disconnected' }}">
<span class="asb-dot"></span>
<span class="asb-name">Yandex</span>
<span class="asb-tag">{{ $integrations['yandex'] ? 'Doğrulandı' : 'Bağlı değil' }}</span>
</div>
</div>
</div>
{{-- ── KPI Cards Row ─────────────────────────────────────────────────── --}}
<div class="row g-3 mb-4">
<div class="col-6 col-md-3 col-xl">
<div class="analytics-kpi-card">
<div class="kpi-icon" style="background:rgba(88,166,255,.12);color:var(--info)"><i class="bi bi-film"></i></div>
<div class="kpi-body">
<div class="kpi-val">{{ number_format($analyticsStats['total_anime']) }}</div>
<div class="kpi-lbl">Toplam Anime</div>
@if($analyticsStats['new_anime_this_month'] > 0)
<div class="kpi-trend up"><i class="bi bi-arrow-up-short"></i>+{{ $analyticsStats['new_anime_this_month'] }} bu ay</div>
@endif
</div>
</div>
</div>
<div class="col-6 col-md-3 col-xl">
<div class="analytics-kpi-card">
<div class="kpi-icon" style="background:rgba(63,185,80,.12);color:var(--success)"><i class="bi bi-people-fill"></i></div>
<div class="kpi-body">
<div class="kpi-val">{{ number_format($analyticsStats['total_users']) }}</div>
<div class="kpi-lbl">Toplam Üye</div>
@if($analyticsStats['new_users_this_month'] > 0)
<div class="kpi-trend up"><i class="bi bi-arrow-up-short"></i>+{{ $analyticsStats['new_users_this_month'] }} bu ay</div>
@endif
</div>
</div>
</div>
<div class="col-6 col-md-3 col-xl">
<div class="analytics-kpi-card">
<div class="kpi-icon" style="background:rgba(210,153,34,.12);color:#d29922"><i class="bi bi-collection-play-fill"></i></div>
<div class="kpi-body">
<div class="kpi-val">{{ number_format($analyticsStats['total_episodes']) }}</div>
<div class="kpi-lbl">Toplam Bölüm</div>
</div>
</div>
</div>
<div class="col-6 col-md-3 col-xl">
<div class="analytics-kpi-card">
<div class="kpi-icon" style="background:rgba(240,81,51,.12);color:#f05133"><i class="bi bi-chat-dots-fill"></i></div>
<div class="kpi-body">
<div class="kpi-val">{{ number_format($analyticsStats['total_comments']) }}</div>
<div class="kpi-lbl">Toplam Yorum</div>
</div>
</div>
</div>
<div class="col-6 col-md-3 col-xl">
<div class="analytics-kpi-card">
<div class="kpi-icon" style="background:rgba(163,113,247,.12);color:#a371f7"><i class="bi bi-bookmark-heart-fill"></i></div>
<div class="kpi-body">
<div class="kpi-val">{{ number_format($analyticsStats['total_watchlists']) }}</div>
<div class="kpi-lbl">İzleme Listesi</div>
</div>
</div>
</div>
<div class="col-6 col-md-3 col-xl">
<div class="analytics-kpi-card">
<div class="kpi-icon" style="background:rgba(255,107,53,.12);color:#ff6b35"><i class="bi bi-star-fill"></i></div>
<div class="kpi-body">
<div class="kpi-val">{{ number_format($analyticsStats['total_ratings']) }}</div>
<div class="kpi-lbl">Toplam Rating</div>
</div>
</div>
</div>
</div>
{{-- ── SEO Coverage + Redirect Stats ───────────────────────────────────── --}}
<div class="row g-3 mb-4">
<div class="col-lg-8">
<div class="section-card h-100">
<div class="section-card-header"><i class="bi bi-graph-up-arrow text-success me-1"></i><h6>SEO Kapsama & Sağlık Skoru</h6></div>
<div class="section-card-body">
<div class="row g-4">
<div class="col-md-4 text-center">
@php
$overallScore = round(($analyticsStats['seo_title_pct'] + $analyticsStats['seo_desc_pct']) / 2);
$scoreColor = $overallScore >= 80 ? 'var(--success)' : ($overallScore >= 50 ? '#d29922' : 'var(--danger)');
$circumference = 2 * pi() * 52;
$dashOffset = $circumference * (1 - $overallScore / 100);
@endphp
<div class="seo-score-ring" style="width:130px;height:130px">
<svg width="130" height="130" viewBox="0 0 130 130">
<circle cx="65" cy="65" r="52" fill="none" stroke="var(--border)" stroke-width="10"/>
<circle cx="65" cy="65" r="52" fill="none" stroke="{{ $scoreColor }}" stroke-width="10"
stroke-dasharray="{{ $circumference }}"
stroke-dashoffset="{{ $dashOffset }}"
stroke-linecap="round"/>
</svg>
<div class="score-text">
<div class="score-num" style="color:{{ $scoreColor }}">{{ $overallScore }}</div>
<div class="score-lbl">SEO Skoru</div>
</div>
</div>
<div class="mt-2" style="font-size:.78rem;color:var(--text2)">{{ $analyticsStats['total_anime'] }} anime üzerinden</div>
</div>
<div class="col-md-8">
<div class="mb-3">
<div class="d-flex justify-content-between mb-1" style="font-size:.82rem">
<span>SEO Başlık Kapsama</span>
<span class="fw-bold" style="color:{{ $analyticsStats['seo_title_pct'] >= 80 ? 'var(--success)' : '#d29922' }}">{{ $analyticsStats['seo_title_pct'] }}%</span>
</div>
<div class="seo-coverage-bar">
<div class="seo-coverage-fill" style="width:{{ $analyticsStats['seo_title_pct'] }}%"></div>
</div>
<div style="font-size:.73rem;color:var(--text2);margin-top:3px">{{ $animeSeoCoverage['has_seo_title'] }} / {{ $animeSeoCoverage['total'] }} anime</div>
</div>
<div class="mb-3">
<div class="d-flex justify-content-between mb-1" style="font-size:.82rem">
<span>SEO Açıklama Kapsama</span>
<span class="fw-bold" style="color:{{ $analyticsStats['seo_desc_pct'] >= 80 ? 'var(--success)' : '#d29922' }}">{{ $analyticsStats['seo_desc_pct'] }}%</span>
</div>
<div class="seo-coverage-bar">
<div class="seo-coverage-fill" style="width:{{ $analyticsStats['seo_desc_pct'] }}%"></div>
</div>
<div style="font-size:.73rem;color:var(--text2);margin-top:3px">{{ $animeSeoCoverage['has_seo_desc'] }} / {{ $animeSeoCoverage['total'] }} anime</div>
</div>
<div class="row g-2 mt-2">
<div class="col-6">
<div class="analytics-mini-stat">
<div class="ams-val" style="color:var(--info)">{{ $analyticsStats['total_genres'] }}</div>
<div class="ams-lbl">Aktif Tür</div>
</div>
</div>
<div class="col-6">
<div class="analytics-mini-stat">
<div class="ams-val" style="color:#a371f7">{{ $analyticsStats['total_blog_posts'] }}</div>
<div class="ams-lbl">Blog Yazısı</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="section-card h-100">
<div class="section-card-header"><i class="bi bi-signpost-split text-info me-1"></i><h6>Yönlendirme İstatistikleri</h6></div>
<div class="section-card-body">
<div class="redirect-stat-grid">
<div class="rsg-item">
<div class="rsg-val" style="color:var(--info)">{{ $analyticsStats['total_redirects'] }}</div>
<div class="rsg-lbl">Aktif Yönlendirme</div>
</div>
<div class="rsg-item">
<div class="rsg-val" style="color:var(--success)">{{ number_format($analyticsStats['total_redirect_hits']) }}</div>
<div class="rsg-lbl">Toplam Tıklama</div>
</div>
</div>
<hr style="border-color:var(--border)">
<div style="font-size:.82rem;color:var(--text2);line-height:1.8">
<div><i class="bi bi-check-circle-fill text-success me-1"></i>301 Kalıcı yönlendirmeler SEO güçlendirir</div>
<div><i class="bi bi-exclamation-triangle-fill text-warning me-1"></i>302 Geçici yönlendirmeler juice aktarmaz</div>
<div><i class="bi bi-info-circle-fill text-info me-1"></i>Redirect zinciri oluşturmaktan kaçının</div>
</div>
</div>
</div>
</div>
</div>
{{-- ── Quick Tool Links ─────────────────────────────────────────────────── --}}
<div class="section-card mb-4">
<div class="section-card-header"><i class="bi bi-grid-3x3-gap-fill me-1"></i><h6>Hızlı Araç Erişimi</h6></div>
<div class="section-card-body">
<div class="quick-tools-grid">
<a href="https://analytics.google.com" target="_blank" class="qt-card">
<div class="qt-icon" style="background:#e37400;color:#fff"><i class="bi bi-bar-chart-line-fill"></i></div>
<div class="qt-body">
<div class="qt-name">Google Analytics 4</div>
<div class="qt-desc">Trafik, kullanıcı davranışı, dönüşümler</div>
</div>
<div class="qt-status {{ $integrations['ga4'] ? 'on' : 'off' }}">{{ $integrations['ga4'] ? 'Aktif' : 'Kurulmadı' }}</div>
</a>
<a href="https://search.google.com/search-console" target="_blank" class="qt-card">
<div class="qt-icon" style="background:#4285f4;color:#fff"><i class="bi bi-search"></i></div>
<div class="qt-body">
<div class="qt-name">Search Console</div>
<div class="qt-desc">Arama sıralamaları, tıklamalar, hatalar</div>
</div>
<div class="qt-status {{ $integrations['gsc'] ? 'on' : 'off' }}">{{ $integrations['gsc'] ? 'Doğrulandı' : 'Doğrulanmadı' }}</div>
</a>
<a href="https://tagmanager.google.com" target="_blank" class="qt-card">
<div class="qt-icon" style="background:#346beb;color:#fff"><i class="bi bi-tags-fill"></i></div>
<div class="qt-body">
<div class="qt-name">Tag Manager</div>
<div class="qt-desc">Kod snippet yönetimi, etkinlikler</div>
</div>
<div class="qt-status {{ $integrations['gtm'] ? 'on' : 'off' }}">{{ $integrations['gtm'] ? 'Aktif' : 'Kurulmadı' }}</div>
</a>
<a href="https://www.bing.com/webmasters" target="_blank" class="qt-card">
<div class="qt-icon" style="background:#008373;color:#fff"><i class="bi bi-microsoft"></i></div>
<div class="qt-body">
<div class="qt-name">Bing Webmaster</div>
<div class="qt-desc">Bing arama görünürlüğü ve indexleme</div>
</div>
<div class="qt-status {{ $integrations['bing'] ? 'on' : 'off' }}">{{ $integrations['bing'] ? 'Doğrulandı' : 'Doğrulanmadı' }}</div>
</a>
<a href="https://webmaster.yandex.com" target="_blank" class="qt-card">
<div class="qt-icon" style="background:#fc3f1d;color:#fff"><i class="bi bi-globe"></i></div>
<div class="qt-body">
<div class="qt-name">Yandex Webmaster</div>
<div class="qt-desc">Yandex arama indexleme ve istatistikleri</div>
</div>
<div class="qt-status {{ $integrations['yandex'] ? 'on' : 'off' }}">{{ $integrations['yandex'] ? 'Doğrulandı' : 'Doğrulanmadı' }}</div>
</a>
<a href="https://pagespeed.web.dev" target="_blank" class="qt-card">
<div class="qt-icon" style="background:#34a853;color:#fff"><i class="bi bi-speedometer2"></i></div>
<div class="qt-body">
<div class="qt-name">PageSpeed Insights</div>
<div class="qt-desc">Core Web Vitals ve performans testi</div>
</div>
<div class="qt-status off">Web Aracı</div>
</a>
<a href="https://schema.org/docs/gs.html" target="_blank" class="qt-card">
<div class="qt-icon" style="background:#5f6368;color:#fff"><i class="bi bi-braces-asterisk"></i></div>
<div class="qt-body">
<div class="qt-name">Schema.org Validator</div>
<div class="qt-desc">Yapısal veri test ve doğrulama aracı</div>
</div>
<div class="qt-status off">Dış Araç</div>
</a>
<a href="https://ahrefs.com/backlink-checker" target="_blank" class="qt-card">
<div class="qt-icon" style="background:#1f7ae0;color:#fff"><i class="bi bi-link-45deg"></i></div>
<div class="qt-body">
<div class="qt-name">Ahrefs Backlink</div>
<div class="qt-desc">Geri bağlantı analizi ve rakip araştırma</div>
</div>
<div class="qt-status off">Dış Araç</div>
</a>
</div>
</div>
</div>
{{-- ── Embed Dashboard ─────────────────────────────────────────────────── --}}
<div class="section-card mb-4">
<div class="section-card-header">
<i class="bi bi-easel2 text-warning me-1"></i><h6>Gömülü Rapor Paneli (Looker Studio)</h6>
<span class="ms-auto" style="font-size:.75rem;color:var(--text2)">Looker Studio embed URL'sini girin</span>
</div>
<div class="section-card-body">
<div class="row g-3 align-items-end mb-3">
<div class="col">
<input type="text" id="embedUrl" class="form-control" placeholder="https://lookerstudio.google.com/embed/reporting/xxx/page/xxx" value="{{ $settings['seo_looker_embed_url'] ?? '' }}">
<div class="seo-field-help">Looker Studio → Dosya → Raporu göm → URL kopyala</div>
</div>
<div class="col-auto">
<button class="btn btn-outline-primary" onclick="loadEmbed()"><i class="bi bi-play-fill me-1"></i>Yükle</button>
<button class="btn btn-outline-secondary ms-1" onclick="saveEmbedUrl()"><i class="bi bi-save me-1"></i>Kaydet</button>
</div>
</div>
<div id="embedContainer" style="border-radius:10px;overflow:hidden;background:#010409;border:1px solid var(--border);min-height:160px;display:flex;align-items:center;justify-content:center">
@if(!empty($settings['seo_looker_embed_url'] ?? ''))
<iframe id="embedFrame" src="{{ $settings['seo_looker_embed_url'] }}"
style="width:100%;height:600px;border:0" allowfullscreen></iframe>
@else
<div id="embedPlaceholder" class="text-center py-5 text-muted">
<i class="bi bi-easel2" style="font-size:3rem;display:block;margin-bottom:12px;opacity:.3"></i>
<div style="font-size:.88rem">Looker Studio URL giriniz ve <strong>Yükle</strong>'ye tıklayın</div>
<div style="font-size:.78rem;margin-top:6px">Ya da doğrudan GA4 Analytics panelini kullanın</div>
<a href="https://analytics.google.com" target="_blank" class="btn btn-sm btn-outline-primary mt-3">
<i class="bi bi-box-arrow-up-right me-1"></i>Google Analytics'i Aç
</a>
</div>
@endif
</div>
</div>
</div>
{{-- ── Settings Form ─────────────────────────────────────────────────── --}}
<form method="POST" action="{{ route('admin.seo.update') }}">
@csrf
<div class="row g-4">
<div class="col-lg-6">
<div class="section-card">
<div class="section-card-header">
<i class="bi bi-bar-chart-line text-warning me-1"></i><h6>Tracking Kodları</h6>
</div>
<div class="section-card-body">
<div class="mb-4">
<div class="d-flex align-items-center justify-content-between mb-1">
<label class="form-label mb-0">Google Analytics 4 (Measurement ID)</label>
@if($integrations['ga4'])
<span class="badge" style="background:rgba(63,185,80,.15);color:var(--success);font-size:.7rem">
<i class="bi bi-check-circle me-1"></i>Aktif
</span>
@else
<span class="badge" style="background:rgba(248,81,73,.1);color:var(--danger);font-size:.7rem">
<i class="bi bi-x-circle me-1"></i>Kurulmadı
</span>
@endif
</div>
<div class="input-group">
<span class="input-group-text" style="background:var(--surface);border-color:var(--border2);color:var(--text2)">
<i class="bi bi-bar-chart-line"></i>
</span>
<input type="text" name="seo_google_analytics" class="form-control" value="{{ $settings['seo_google_analytics']??'' }}" placeholder="G-XXXXXXXXXX">
</div>
<div class="seo-field-help">GA4 ölçüm kimliği. &lt;head&gt; içine otomatik eklenir.</div>
</div>
<div class="mb-4">
<div class="d-flex align-items-center justify-content-between mb-1">
<label class="form-label mb-0">Google Tag Manager</label>
@if($integrations['gtm'])
<span class="badge" style="background:rgba(63,185,80,.15);color:var(--success);font-size:.7rem">
<i class="bi bi-check-circle me-1"></i>Aktif
</span>
@else
<span class="badge" style="background:rgba(139,148,158,.1);color:var(--text2);font-size:.7rem">
<i class="bi bi-dash-circle me-1"></i>Opsiyonel
</span>
@endif
</div>
<div class="input-group">
<span class="input-group-text" style="background:var(--surface);border-color:var(--border2);color:var(--text2)">
<i class="bi bi-tags-fill"></i>
</span>
<input type="text" name="seo_gtm_id" class="form-control" value="{{ $settings['seo_gtm_id']??'' }}" placeholder="GTM-XXXXXXX">
</div>
<div class="seo-field-help">GA4 ile birlikte kullanılabilir veya alternatif olarak.</div>
</div>
<div>
<label class="form-label">Looker Studio Embed URL</label>
<div class="input-group">
<span class="input-group-text" style="background:var(--surface);border-color:var(--border2);color:var(--text2)">
<i class="bi bi-easel2"></i>
</span>
<input type="text" name="seo_looker_embed_url" class="form-control" value="{{ $settings['seo_looker_embed_url']??'' }}" placeholder="https://lookerstudio.google.com/embed/...">
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="section-card">
<div class="section-card-header">
<i class="bi bi-patch-check text-success me-1"></i><h6>Webmaster Doğrulama Kodları</h6>
</div>
<div class="section-card-body">
<div class="mb-3">
<div class="d-flex align-items-center justify-content-between mb-1">
<label class="form-label mb-0">Google Search Console</label>
@if($integrations['gsc'])
<span class="badge" style="background:rgba(63,185,80,.15);color:var(--success);font-size:.7rem"><i class="bi bi-check-circle me-1"></i>Doğrulandı</span>
@else
<span class="badge" style="background:rgba(248,81,73,.1);color:var(--danger);font-size:.7rem"><i class="bi bi-exclamation-circle me-1"></i>Doğrulanmadı</span>
@endif
</div>
<div class="input-group">
<span class="input-group-text" style="background:var(--surface);border-color:var(--border2);color:#4285f4"><i class="bi bi-google"></i></span>
<input type="text" name="seo_gsc_verification" class="form-control" value="{{ $settings['seo_gsc_verification']??'' }}" placeholder="google-site-verification=abc123">
</div>
<div class="seo-field-help">Search Console → Ayarlar → Site doğrulama → HTML etiketi yöntemi</div>
</div>
<div class="mb-3">
<div class="d-flex align-items-center justify-content-between mb-1">
<label class="form-label mb-0">Bing Webmaster</label>
@if($integrations['bing'])
<span class="badge" style="background:rgba(63,185,80,.15);color:var(--success);font-size:.7rem"><i class="bi bi-check-circle me-1"></i>Doğrulandı</span>
@else
<span class="badge" style="background:rgba(139,148,158,.1);color:var(--text2);font-size:.7rem"><i class="bi bi-dash-circle me-1"></i>Kurulmadı</span>
@endif
</div>
<div class="input-group">
<span class="input-group-text" style="background:var(--surface);border-color:var(--border2);color:#008373"><i class="bi bi-microsoft"></i></span>
<input type="text" name="seo_bing_verification" class="form-control" value="{{ $settings['seo_bing_verification']??'' }}" placeholder="msvalidate.01 içeriği">
</div>
</div>
<div class="mb-4">
<div class="d-flex align-items-center justify-content-between mb-1">
<label class="form-label mb-0">Yandex Webmaster</label>
@if($integrations['yandex'])
<span class="badge" style="background:rgba(63,185,80,.15);color:var(--success);font-size:.7rem"><i class="bi bi-check-circle me-1"></i>Doğrulandı</span>
@else
<span class="badge" style="background:rgba(139,148,158,.1);color:var(--text2);font-size:.7rem"><i class="bi bi-dash-circle me-1"></i>Kurulmadı</span>
@endif
</div>
<div class="input-group">
<span class="input-group-text" style="background:var(--surface);border-color:var(--border2);color:#fc3f1d"><i class="bi bi-globe"></i></span>
<input type="text" name="seo_yandex_verification" class="form-control" value="{{ $settings['seo_yandex_verification']??'' }}" placeholder="yandex-verification içeriği">
</div>
</div>
{{-- GSC Setup Guide --}}
<div class="gsc-guide-box">
<div class="ggb-title"><i class="bi bi-lightbulb-fill text-warning me-1"></i>Search Console Kurulum Adımları</div>
<ol class="ggb-steps">
<li><a href="https://search.google.com/search-console" target="_blank">Search Console</a>'u açın ve sitenizi ekleyin</li>
<li>"HTML etiketi" doğrulama yöntemini seçin</li>
<li>Verification içeriğini buraya yapıştırın ve kaydedin</li>
<li>Search Console'a dönüp "Doğrula" butonuna basın</li>
<li>Sitemap gönderin: <code>{{ config('app.url') }}/sitemap.xml</code></li>
</ol>
</div>
</div>
</div>
</div>
</div>
<div class="d-flex gap-2 mt-2">
<button type="submit" class="btn btn-primary px-4"><i class="bi bi-save me-2"></i>Entegrasyon Ayarlarını Kaydet</button>
@if($integrations['ga4'])
<a href="https://analytics.google.com" target="_blank" class="btn btn-outline-warning">
<i class="bi bi-box-arrow-up-right me-1"></i>GA4'ü
</a>
@endif
@if($integrations['gsc'])
<a href="https://search.google.com/search-console" target="_blank" class="btn btn-outline-primary">
<i class="bi bi-search me-1"></i>Search Console'u Aç
</a>
@endif
</div>
</form>
</div>
{{-- ═══════ TAB 10: PAGESPEED ═══════ --}}
<div class="seo-tab-pane" id="tab-pagespeed">
<div class="row g-4">
<div class="col-lg-5">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-speedometer2"></i><h6>PageSpeed Insights Testi</h6></div>
<div class="section-card-body">
<form method="POST" action="{{ route('admin.seo.update') }}" class="mb-3">
@csrf
<label class="form-label">PageSpeed API Anahtarı</label>
<div class="input-group mb-1">
<input type="text" name="seo_pagespeed_api_key" class="form-control" value="{{ $settings['seo_pagespeed_api_key']??'' }}" placeholder="AIzaSy...">
<button type="submit" class="btn btn-outline-secondary">Kaydet</button>
</div>
<div class="seo-field-help">Google Cloud Console'dan API anahtarı alın. PageSpeed Insights API'yi etkinleştirin.</div>
</form>
<hr style="border-color:var(--border)">
<div class="mb-3">
<label class="form-label">Test Edilecek URL</label>
<input type="url" id="psi-url" class="form-control" value="{{ $settings['seo_canonical_domain']??'' }}" placeholder="https://animexe.com">
</div>
<div class="mb-3">
<label class="form-label">Cihaz</label>
<div class="d-flex gap-2">
<button type="button" class="btn btn-outline-secondary btn-sm psi-strat active" data-strat="mobile"><i class="bi bi-phone me-1"></i>Mobil</button>
<button type="button" class="btn btn-outline-secondary btn-sm psi-strat" data-strat="desktop"><i class="bi bi-laptop me-1"></i>Masaüstü</button>
</div>
</div>
<button type="button" id="btn-psi-run" class="btn btn-primary w-100">
<i class="bi bi-play-circle me-1"></i>Testi Çalıştır
</button>
</div>
</div>
</div>
<div class="col-lg-7">
<div id="psi-results" style="display:none">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-bar-chart me-1"></i><h6>Sonuçlar</h6></div>
<div class="section-card-body">
<div class="d-flex justify-content-around mb-4" id="psi-scores"></div>
<div class="row g-2 mb-3" id="psi-vitals"></div>
<div id="psi-opportunities"></div>
</div>
</div>
</div>
<div id="psi-loading" style="display:none" class="text-center py-5">
<div class="spinner-border text-info" style="width:3rem;height:3rem"></div>
<div class="mt-3 text-muted">PageSpeed analiz ediliyor... (1020 saniye)</div>
</div>
<div id="psi-placeholder" class="section-card">
<div class="section-card-body text-center py-5 text-muted">
<i class="bi bi-speedometer2" style="font-size:3rem;opacity:.2;display:block;margin-bottom:12px"></i>
<div>API anahtarınızı girin ve test başlatın.</div>
<div style="font-size:.78rem;margin-top:4px">Core Web Vitals, skor ve optimizasyon önerileri gösterilecek.</div>
</div>
</div>
</div>
</div>
</div>
{{-- ═══════ TAB 11: DENETİM ═══════ --}}
<div class="seo-tab-pane" id="tab-audit">
<div class="row g-4">
<div class="col-lg-6">
<div class="section-card">
<div class="section-card-header d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center gap-2"><i class="bi bi-clipboard-check"></i><h6 class="mb-0">SEO Kontrol Listesi ({{ count($audit['checks']) }} kontrol)</h6></div>
<button type="button" class="btn btn-sm btn-outline-info" id="btn-reaudit"><i class="bi bi-arrow-clockwise me-1"></i>Yenile</button>
</div>
<div class="section-card-body">
@foreach($audit['checks'] as $c)
<div class="check-item {{ $c['pass']?'pass':'fail' }}">
<span class="check-icon"><i class="bi bi-{{ $c['pass']?'check-circle-fill':'x-circle-fill' }}"></i></span>
<span class="check-msg">{{ $c['pass']?$c['passMsg']:$c['failMsg'] }}</span>
<span class="check-weight">+{{ $c['weight'] }}p</span>
</div>
@endforeach
</div>
</div>
</div>
<div class="col-lg-6">
<div class="section-card">
<div class="section-card-header"><i class="bi bi-copy text-warning"></i><h6>Yinelenen İçerik Denetimi</h6></div>
<div class="section-card-body">
@if($dupDesc > 0)
<div class="alert alert-warning d-flex align-items-center gap-2">
<i class="bi bi-exclamation-triangle-fill"></i>
<span><strong>{{ $dupDesc }} grup</strong> tekrarlayan anime açıklaması tespit edildi.</span>
</div>
@else
<div class="alert alert-success d-flex align-items-center gap-2">
<i class="bi bi-check-circle-fill"></i>Tekrarlayan içerik tespit edilmedi.
</div>
@endif
<button type="button" id="btn-dup-check" class="btn btn-outline-warning w-100">
<i class="bi bi-search me-1"></i>Tekrarlayan İçerikleri Listele
</button>
<div id="dup-results" class="mt-3" style="display:none"></div>
</div>
</div>
<div class="section-card">
<div class="section-card-header"><i class="bi bi-link-45deg text-info"></i><h6>Dahili Bağlantı Analizi</h6></div>
<div class="section-card-body">
<p class="text-muted" style="font-size:.82rem">Hangi animeler diğer animelerin açıklamalarında hiç atıflanmıyor? (Orphaned pages)</p>
<button type="button" id="btn-internal-links" class="btn btn-outline-info w-100">
<i class="bi bi-diagram-2 me-1"></i>Dahili Bağlantı Analizini Çalıştır
</button>
<div id="link-loading" style="display:none" class="text-center mt-3 text-muted"><div class="spinner-border spinner-border-sm me-2"></div>Analiz ediliyor...</div>
<div id="link-results" class="mt-3" style="display:none;max-height:300px;overflow-y:auto"></div>
</div>
</div>
<div class="section-card">
<div class="section-card-header"><i class="bi bi-stars text-success"></i><h6>Hızlı Aksiyon</h6></div>
<div class="section-card-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-outline-success" onclick="document.querySelector('[data-tab=anime-seo]').click()">
<i class="bi bi-collection-play me-1"></i>Anime SEO Başlıklarını Düzenle
</button>
<button type="button" class="btn btn-outline-info" onclick="document.querySelector('[data-tab=keywords]').click()">
<i class="bi bi-search me-1"></i>Anahtar Kelime Ekle
</button>
<button type="button" class="btn btn-outline-warning" onclick="document.querySelector('[data-tab=redirects]').click()">
<i class="bi bi-signpost-split me-1"></i>Yönlendirme Ekle
</button>
</div>
</div>
</div>
</div>
</div>
</div>
{{-- ═══════ TAB 12: AI ASISTAN ═══════ --}}
<div class="seo-tab-pane" id="tab-ai">
@php $aiConfigured = !empty(\App\Models\Setting::get('deepseek_api_key','')); @endphp
@if(!$aiConfigured)
<div class="alert alert-warning d-flex align-items-center gap-3 mb-4">
<i class="bi bi-exclamation-triangle-fill" style="font-size:1.3rem"></i>
<div>
<strong>DeepSeek API Anahtarı Gerekli</strong><br>
<span style="font-size:.85rem">AI özelliklerini kullanmak için <a href="{{ route('admin.settings.index') }}" class="alert-link">Ayarlar</a> sayfasından DeepSeek API anahtarını ekleyin.</span>
</div>
</div>
@endif
<div class="row g-4">
{{-- Sol: Chat + Hızlı Araçlar --}}
<div class="col-lg-5">
{{-- AI Chat --}}
<div class="section-card" style="height:580px;display:flex;flex-direction:column">
<div class="section-card-header" style="flex-shrink:0">
<i class="bi bi-stars" style="color:var(--accent)"></i>
<h6>AI SEO Danışmanı</h6>
<span class="badge bg-success ms-auto" style="font-size:.68rem">DeepSeek</span>
</div>
<div id="ai-chat-messages" style="flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px">
<div class="ai-msg assistant">
<div class="ai-bubble">
<strong>Merhaba! Ben Animexe'nin AI SEO danışmanıyım.</strong><br><br>
Size şu konularda yardımcı olabilirim:<br>
Anahtar kelime stratejisi<br>
Meta başlık/açıklama optimizasyonu<br>
Teknik SEO sorunları<br>
İçerik stratejisi ve rakip analizi<br>
Schema.org ve yapısal veri<br><br>
Ne öğrenmek istersiniz?
</div>
</div>
</div>
<div style="flex-shrink:0;padding:12px;border-top:1px solid var(--border)">
<div class="d-flex gap-2">
<textarea id="ai-chat-input" class="form-control form-control-sm" rows="2" placeholder="SEO sorunuzu yazın..." style="resize:none" {{ !$aiConfigured?'disabled':'' }}></textarea>
<button id="btn-ai-send" class="btn btn-primary" style="min-width:44px" {{ !$aiConfigured?'disabled':'' }}>
<i class="bi bi-send"></i>
</button>
</div>
<div class="d-flex gap-1 mt-2 flex-wrap" id="ai-quick-prompts">
@foreach(['Anahtar kelime stratejisi öner','Teknik SEO sorunlarım neler?','Rakip analizi yap','Core Web Vitals nedir?','Schema nasıl eklenir?'] as $qp)
<button type="button" class="btn btn-outline-secondary btn-quick-prompt" style="font-size:.7rem;padding:2px 8px" {{ !$aiConfigured?'disabled':'' }}>{{ $qp }}</button>
@endforeach
</div>
</div>
</div>
</div>
{{-- Sağ: AI Araçlar --}}
<div class="col-lg-7">
{{-- Anime AI SEO Üretici --}}
<div class="section-card">
<div class="section-card-header">
<i class="bi bi-collection-play" style="color:var(--accent)"></i>
<h6>AI Anime SEO Üretici</h6>
<span class="badge bg-info text-dark ms-auto" style="font-size:.68rem">Kaliteli / AI Destekli</span>
</div>
<div class="section-card-body">
<p style="font-size:.82rem;color:var(--text2)">Seçtiğiniz anime için DeepSeek AI gerçek anahtar kelime araştırması yaparak CTR-optimize edilmiş SEO başlığı ve meta açıklaması üretir.</p>
<div class="d-flex gap-2 mb-3">
<select id="ai-anime-select" class="form-select form-select-sm" {{ !$aiConfigured?'disabled':'' }}>
<option value=""> Anime seçin </option>
@foreach(\App\Models\Anime::where('is_published',true)->orderBy('title')->get(['id','title','seo_title']) as $a)
<option value="{{ $a->id }}" data-has-seo="{{ $a->seo_title?1:0 }}">
{{ $a->title }}{{ $a->seo_title ? ' ✓' : '' }}
</option>
@endforeach
</select>
<button id="btn-ai-anime-gen" class="btn btn-primary btn-sm" style="white-space:nowrap" {{ !$aiConfigured?'disabled':'' }}>
<i class="bi bi-stars me-1"></i>AI ile Oluştur
</button>
</div>
<div id="ai-anime-result" style="display:none">
<div class="row g-2">
<div class="col-12">
<label style="font-size:.75rem;color:var(--text2)">SEO Başlığı</label>
<input type="text" id="ai-anime-title-out" class="form-control form-control-sm" readonly>
<div id="ai-anime-title-len" style="font-size:.7rem;text-align:right;color:var(--text2)"></div>
</div>
<div class="col-12">
<label style="font-size:.75rem;color:var(--text2)">Meta Açıklaması</label>
<textarea id="ai-anime-desc-out" class="form-control form-control-sm" rows="3" readonly></textarea>
<div id="ai-anime-desc-len" style="font-size:.7rem;text-align:right;color:var(--text2)"></div>
</div>
<div class="col-12">
<label style="font-size:.75rem;color:var(--text2)">Anahtar Kelimeler</label>
<input type="text" id="ai-anime-kw-out" class="form-control form-control-sm" readonly>
</div>
<div class="col-6">
<label style="font-size:.75rem;color:var(--text2)">Ana Kelime</label>
<input type="text" id="ai-anime-primary-kw" class="form-control form-control-sm" readonly>
</div>
<div class="col-6">
<label style="font-size:.75rem;color:var(--text2)">Arama Niyeti</label>
<input type="text" id="ai-anime-intent" class="form-control form-control-sm" readonly>
</div>
</div>
<div class="mt-2 text-end">
<button id="btn-ai-anime-save" class="btn btn-success btn-sm"><i class="bi bi-check2 me-1"></i>Kaydet</button>
</div>
</div>
</div>
</div>
{{-- Keyword Araştırması --}}
<div class="section-card">
<div class="section-card-header">
<i class="bi bi-search" style="color:var(--info)"></i>
<h6>AI Anahtar Kelime Araştırması</h6>
</div>
<div class="section-card-body">
<div class="d-flex gap-2 mb-3">
<input type="text" id="ai-kw-topic" class="form-control form-control-sm" placeholder="Konu girin (ör: naruto, isekai, shounen)" {{ !$aiConfigured?'disabled':'' }}>
<button id="btn-ai-kw-suggest" class="btn btn-info btn-sm text-dark" style="white-space:nowrap" {{ !$aiConfigured?'disabled':'' }}>
<i class="bi bi-search me-1"></i>Araştır
</button>
</div>
<div id="ai-kw-results" style="display:none"></div>
<div id="ai-kw-loading" style="display:none" class="text-center py-3 text-muted">
<div class="spinner-border spinner-border-sm me-2"></div>AI araştırıyor...
</div>
</div>
</div>
{{-- Sayfa Analizi --}}
<div class="section-card">
<div class="section-card-header">
<i class="bi bi-file-earmark-search" style="color:var(--success)"></i>
<h6>AI Sayfa SEO Analizi</h6>
</div>
<div class="section-card-body">
<div class="row g-2 mb-2">
<div class="col-8">
<input type="url" id="ai-page-url" class="form-control form-control-sm" placeholder="https://animexe.com/anime/naruto" {{ !$aiConfigured?'disabled':'' }}>
</div>
<div class="col-4">
<button id="btn-ai-page-analyze" class="btn btn-success btn-sm w-100" {{ !$aiConfigured?'disabled':'' }}>
<i class="bi bi-magnifying-glass me-1"></i>Analiz Et
</button>
</div>
</div>
<div id="ai-page-results" style="display:none"></div>
<div id="ai-page-loading" style="display:none" class="text-center py-3 text-muted">
<div class="spinner-border spinner-border-sm me-2"></div>Sayfa analiz ediliyor...
</div>
</div>
</div>
{{-- FAQ Schema + İçerik Stratejisi --}}
<div class="row g-3">
<div class="col-md-6">
<div class="section-card h-100">
<div class="section-card-header">
<i class="bi bi-question-circle" style="color:#d29922"></i>
<h6 style="font-size:.82rem">FAQ Schema Üretici</h6>
</div>
<div class="section-card-body">
<select id="ai-faq-anime" class="form-select form-select-sm mb-2" {{ !$aiConfigured?'disabled':'' }}>
<option value=""> Anime seçin </option>
@foreach(\App\Models\Anime::where('is_published',true)->orderBy('title')->take(100)->get(['id','title']) as $a)
<option value="{{ $a->id }}">{{ $a->title }}</option>
@endforeach
</select>
<button id="btn-ai-faq" class="btn btn-warning btn-sm w-100 text-dark" {{ !$aiConfigured?'disabled':'' }}>
<i class="bi bi-stars me-1"></i>FAQ Üret
</button>
<div id="ai-faq-results" class="mt-2" style="display:none"></div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="section-card h-100">
<div class="section-card-header">
<i class="bi bi-map" style="color:#f59e0b"></i>
<h6 style="font-size:.82rem">90 Günlük İçerik Stratejisi</h6>
</div>
<div class="section-card-body">
<p style="font-size:.78rem;color:var(--text2)">Mevcut SEO durumunuza göre 90 günlük detaylı bir SEO eylem planı oluşturun.</p>
<button id="btn-ai-strategy" class="btn btn-outline-warning btn-sm w-100" {{ !$aiConfigured?'disabled':'' }}>
<i class="bi bi-lightning me-1"></i>Strateji Oluştur
</button>
<div id="ai-strategy-result" class="mt-2" style="display:none;max-height:300px;overflow-y:auto;background:#010409;border:1px solid var(--border);border-radius:6px;padding:12px;font-size:.8rem;line-height:1.6"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>{{-- /content --}}
@endsection
@push('scripts')
<script>
// ── Tab System ─────────────────────────────────────────────────────────────
document.querySelectorAll('.seo-tab-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.seo-tab-btn').forEach(b => b.classList.remove('active'));
document.querySelectorAll('.seo-tab-pane').forEach(p => p.classList.remove('active'));
btn.classList.add('active');
document.getElementById('tab-' + btn.dataset.tab).classList.add('active');
if (window.location.hash !== '#' + btn.dataset.tab) {
history.replaceState(null, '', '#' + btn.dataset.tab);
}
});
});
// Open tab from URL hash
const hash = window.location.hash.replace('#','');
if (hash) { const btn = document.querySelector(`.seo-tab-btn[data-tab="${hash}"]`); if (btn) btn.click(); }
// ── Char Counters ──────────────────────────────────────────────────────────
function updateCounter(el, ctrId, okMin, okMax, max) {
const len = el.value.length;
const ctr = document.getElementById(ctrId);
if (!ctr) return;
ctr.textContent = len + '/' + max;
ctr.className = 'char-counter ' + (len < okMin ? 'warn' : len <= okMax ? 'ok' : 'bad');
}
// Init counters on load
document.addEventListener('DOMContentLoaded', () => {
const ht = document.getElementById('inp_home_title');
const hd = document.getElementById('inp_home_desc');
if (ht) updateCounter(ht, 'ctr_home_title', 50, 60, 70);
if (hd) updateCounter(hd, 'ctr_home_desc', 120, 160, 320);
updatePreview();
updateGuide();
});
// ── Preview ────────────────────────────────────────────────────────────────
function updatePreview() {
const title = document.getElementById('inp_home_title')?.value || '';
const desc = document.getElementById('inp_home_desc')?.value || '';
const dt = desc.substring(0, 155) + (desc.length > 155 ? '...' : '');
const dm = desc.substring(0, 100) + (desc.length > 100 ? '...' : '');
['prev_title','prev_title_mob'].forEach(id => { const el = document.getElementById(id); if (el) el.textContent = title; });
['prev_desc','prev_desc_mob'].forEach((id,i) => { const el = document.getElementById(id); if (el) el.textContent = i===0?dt:dm; });
updateGuide();
}
function updateGuide() {
const tl = document.getElementById('inp_home_title')?.value.length || 0;
const dl = document.getElementById('inp_home_desc')?.value.length || 0;
const setGuide = (txtId, barId, len, max, ok1, ok2) => {
const txt = document.getElementById(txtId); const bar = document.getElementById(barId);
if (txt) txt.textContent = len + '/' + max;
if (bar) { bar.style.width = Math.min(len/max*100,100)+'%'; bar.className = 'progress-bar ' + (len<ok1?'bg-warning':len<=ok2?'bg-success':'bg-danger'); }
};
setGuide('guide_title','bar_title',tl,70,50,60);
setGuide('guide_desc','bar_desc',dl,320,120,160);
}
function resetRobots() {
document.querySelector('.robots-editor').value = `User-agent: *\nDisallow: /admin\nDisallow: /api\nDisallow: /storage\n\nSitemap: https://animexe.com/sitemap.xml`;
}
// ── Redirect toggle ────────────────────────────────────────────────────────
document.querySelectorAll('.btn-toggle-redirect').forEach(btn => {
btn.addEventListener('click', async () => {
const id = btn.dataset.id;
const r = await fetch(`{{ url('admin/seo/redirects') }}/${id}/toggle`, {
method: 'POST',
headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content }
});
const d = await r.json();
btn.textContent = d.is_active ? 'Aktif' : 'Pasif';
btn.className = 'btn btn-sm btn-toggle-redirect ' + (d.is_active ? 'btn-success' : 'btn-secondary');
btn.closest('tr').className = 'redirect-row' + (d.is_active ? '' : ' inactive');
});
});
// ── Auto SEO per anime ─────────────────────────────────────────────────────
document.querySelectorAll('.btn-auto-seo').forEach(btn => {
btn.addEventListener('click', async () => {
const id = btn.dataset.id;
const row = document.getElementById('anime-row-' + id);
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span>';
try {
const r = await fetch(`{{ url('admin/seo/anime') }}/${id}/generate`, {
method: 'POST',
headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content }
});
const d = await r.json();
if (d.seo_title) row.querySelector('[name$="[seo_title]"]').value = d.seo_title;
if (d.seo_meta_desc) row.querySelector('[name$="[seo_meta_desc]"]').value = d.seo_meta_desc;
if (d.seo_keywords) row.querySelector('[name$="[seo_keywords]"]').value = d.seo_keywords;
btn.innerHTML = '<i class="bi bi-check" style="font-size:.75rem;color:var(--success)"></i>';
} catch(e) { btn.innerHTML = '<i class="bi bi-x" style="font-size:.75rem;color:var(--danger)"></i>'; }
});
});
// ── Toplu Doldurma (Batch + Polling) ─────────────────────────────────────────
const BF_BATCH_SIZES = { template_seo: 50, ai_seo: 5, ai_meta: 5, ai_all: 3 };
const BF_ROUTE = '{{ route("admin.seo.bulk-fill-batch") }}';
const BF_STATS_ROUTE = '{{ route("admin.seo.bulk-fill-stats") }}';
const BF_CSRF = document.querySelector('meta[name=csrf-token]')?.content || '';
let bfRunning = false;
let bfShouldStop = false;
async function loadBulkFillStats() {
try {
const d = await (await fetch(BF_STATS_ROUTE)).json();
document.getElementById('bf-pct-seo').textContent = d.pct_seo + '%';
document.getElementById('bf-pct-desc').textContent = d.pct_desc + '%';
document.getElementById('bf-needs-seo').textContent = d.needs_seo;
document.getElementById('bf-needs-meta').textContent = d.needs_meta;
document.getElementById('bf-coverage-badge').textContent = `${d.total} anime`;
const pSeo = d.pct_seo;
document.getElementById('bf-pct-seo').style.color = pSeo >= 90 ? 'var(--success)' : pSeo >= 50 ? 'var(--warning)' : 'var(--danger)';
} catch(e) {}
}
loadBulkFillStats();
function stopBulkFill() {
bfShouldStop = true;
document.getElementById('bf-progress-label').textContent = 'Durduruluyor...';
}
async function startBulkFill(mode) {
if (bfRunning) { alert('Zaten çalışıyor!'); return; }
const modeLabels = {
template_seo: 'Hızlı SEO (template)',
ai_seo: 'AI SEO',
ai_meta: 'AI Meta Doldurma',
ai_all: 'Tam Doldurma (Meta + SEO)',
};
if (!confirm(`${modeLabels[mode]} — tüm yayındaki animelere uygulanacak.\n\nBu işlem birkaç dakika sürebilir. Devam edilsin mi?`)) return;
bfRunning = true;
bfShouldStop = false;
const force = document.getElementById('bf-force').checked;
const batchSize = BF_BATCH_SIZES[mode] || 5;
const area = document.getElementById('bf-progress-area');
const bar = document.getElementById('bf-progress-bar');
const label = document.getElementById('bf-progress-label');
const count = document.getElementById('bf-progress-count');
const log = document.getElementById('bf-log');
const stopBtn = document.getElementById('bf-stop-btn');
area.style.display = 'block';
stopBtn.classList.remove('d-none');
bar.style.width = '0%';
log.innerHTML = '';
let totalDone = 0, totalErrors = 0, lastId = 0, total = 0;
const addLog = (msg) => {
const line = document.createElement('div');
line.textContent = new Date().toLocaleTimeString('tr-TR') + ' — ' + msg;
log.prepend(line);
};
addLog(`${modeLabels[mode]} başlatıldı (batch: ${batchSize})`);
while (!bfShouldStop) {
try {
const r = await fetch(BF_ROUTE, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': BF_CSRF },
body: JSON.stringify({ mode, last_id: lastId, batch_size: batchSize, force }),
});
if (!r.ok) {
const err = await r.json().catch(() => ({}));
addLog('❌ Hata: ' + (err.error || r.status));
break;
}
const d = await r.json();
totalDone += d.done || 0;
totalErrors += d.errors || 0;
lastId = d.last_id || lastId;
total = (totalDone + totalErrors + (d.remaining || 0));
const pct = total > 0 ? Math.min(100, Math.round(totalDone / total * 100)) : 100;
bar.style.width = pct + '%';
count.textContent = `${totalDone} / ${total}`;
label.textContent = `${modeLabels[mode]} — %${pct} tamamlandı`;
if (d.done > 0 || d.errors > 0) {
addLog(`${d.done} işlendi${d.errors ? ', ' + d.errors + ' hata' : ''} (last_id: ${lastId})`);
}
if (d.finished || d.remaining <= 0) {
label.textContent = `✅ Tamamlandı! ${totalDone} anime işlendi${totalErrors ? ', ' + totalErrors + ' hata' : ''}.`;
bar.style.background = 'var(--success)';
addLog('Tamamlandı!');
break;
}
// Sonraki batch için kısa bekleme
if (mode !== 'template_seo') {
await new Promise(res => setTimeout(res, 500));
}
} catch(e) {
addLog('❌ Bağlantı hatası: ' + e.message);
break;
}
}
if (bfShouldStop) {
addLog('⏹ Durduruldu.');
label.textContent = `Durduruldu. ${totalDone} anime işlendi.`;
}
bfRunning = false;
bfShouldStop = false;
stopBtn.classList.add('d-none');
// İstatistikleri yenile
await loadBulkFillStats();
// Tablo 1.5s sonra yenile (sayfa yenileme yerine soft)
if (totalDone > 0) setTimeout(() => location.reload(), 2000);
}
// ── Analytics embed ────────────────────────────────────────────────────────
function loadEmbed() {
const url = document.getElementById('embedUrl').value.trim();
const container = document.getElementById('embedContainer');
if (!url) return;
container.innerHTML = '<iframe src="' + url + '" style="width:100%;height:600px;border:0" allowfullscreen></iframe>';
}
async function saveEmbedUrl() {
const url = document.getElementById('embedUrl').value.trim();
const btn = event.target;
btn.innerHTML = '<i class="bi bi-hourglass-split me-1"></i>Kaydediliyor...';
btn.disabled = true;
try {
const form = new FormData();
form.append('_token', document.querySelector('meta[name=csrf-token]').content);
form.append('seo_looker_embed_url', url);
await fetch('{{ route("admin.seo.update") }}', { method:'POST', body: form });
btn.innerHTML = '<i class="bi bi-check-lg me-1"></i>Kaydedildi';
setTimeout(() => { btn.innerHTML = '<i class="bi bi-save me-1"></i>Kaydet'; btn.disabled = false; }, 2000);
} catch(e) { btn.innerHTML = '<i class="bi bi-save me-1"></i>Kaydet'; btn.disabled = false; }
}
// ── PageSpeed ──────────────────────────────────────────────────────────────
let psiStrategy = 'mobile';
document.querySelectorAll('.psi-strat').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.psi-strat').forEach(b => b.classList.remove('active','btn-primary'));
btn.classList.add('active','btn-primary');
psiStrategy = btn.dataset.strat;
});
});
document.getElementById('btn-psi-run')?.addEventListener('click', async () => {
const url = document.getElementById('psi-url').value.trim();
if (!url) { alert('URL girin'); return; }
document.getElementById('psi-placeholder').style.display = 'none';
document.getElementById('psi-results').style.display = 'none';
document.getElementById('psi-loading').style.display = 'block';
try {
const r = await fetch('{{ route("admin.seo.pagespeed") }}', {
method: 'POST',
headers: { 'Content-Type':'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content },
body: JSON.stringify({ url, strategy: psiStrategy })
});
const d = await r.json();
document.getElementById('psi-loading').style.display = 'none';
if (d.error) { alert(d.error); document.getElementById('psi-placeholder').style.display='block'; return; }
// Scores
const scoreLabels = { performance:'Performans', accessibility:'Erişilebilirlik', seo:'SEO', best_practices:'En İyi Uyg.' };
document.getElementById('psi-scores').innerHTML = Object.entries(d.scores).map(([k,v]) => {
const cls = v>=90?'good':v>=50?'average':'poor';
return `<div class="text-center"><div class="psi-score ${cls}">${v}</div><div style="font-size:.72rem;color:var(--text2);margin-top:6px">${scoreLabels[k]||k}</div></div>`;
}).join('');
// Vitals
const vitLabels = { fcp:'FCP (First Paint)', lcp:'LCP (Largest Paint)', cls:'CLS (Layout Shift)', tbt:'TBT (Blocking Time)' };
document.getElementById('psi-vitals').innerHTML = Object.entries(d.vitals).filter(([,v])=>v).map(([k,v]) =>
`<div class="col-6"><div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:10px 14px"><div style="font-size:1.1rem;font-weight:700;color:var(--text)">${v}</div><div style="font-size:.72rem;color:var(--text2)">${vitLabels[k]||k}</div></div></div>`
).join('');
// Opportunities
if (d.opportunities?.length) {
document.getElementById('psi-opportunities').innerHTML = '<div style="font-size:.82rem;font-weight:600;margin-bottom:8px;color:var(--text2)">İyileştirme Fırsatları</div>' +
d.opportunities.map(o =>
`<div style="background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:10px 14px;margin-bottom:6px">
<div style="font-size:.83rem;font-weight:600">${o.title}</div>
${o.savings ? `<span class="badge bg-warning text-dark" style="font-size:.7rem">~${Math.round(o.savings)}ms tasarruf</span>` : ''}
</div>`
).join('');
}
document.getElementById('psi-results').style.display = 'block';
} catch(e) {
document.getElementById('psi-loading').style.display = 'none';
document.getElementById('psi-placeholder').style.display = 'block';
alert('Hata: ' + e.message);
}
});
// ── Duplicate content check ────────────────────────────────────────────────
document.getElementById('btn-dup-check')?.addEventListener('click', async () => {
const btn = document.getElementById('btn-dup-check');
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Kontrol ediliyor...';
btn.disabled = true;
try {
const r = await fetch('{{ route("admin.seo.duplicate-content") }}');
const d = await r.json();
const box = document.getElementById('dup-results');
if (!d.length) {
box.innerHTML = '<div class="alert alert-success"><i class="bi bi-check-circle me-1"></i>Tekrarlayan içerik yok.</div>';
} else {
box.innerHTML = d.map(g =>
`<div style="background:var(--surface);border:1px solid var(--border2);border-radius:6px;padding:10px;margin-bottom:6px">
<div style="font-size:.78rem;font-weight:600;color:var(--danger)">${g.cnt} anime aynı açıklamayı paylaşıyor</div>
<div style="font-size:.75rem;color:var(--text2)">${g.titles}</div>
<div style="font-size:.72rem;color:var(--info);margin-top:4px">"${(g.description||'').substring(0,80)}..."</div>
</div>`
).join('');
}
box.style.display = 'block';
btn.innerHTML = '<i class="bi bi-search me-1"></i>Tekrarlayan İçerikleri Listele';
btn.disabled = false;
} catch(e) { btn.innerHTML = '<i class="bi bi-search me-1"></i>Tekrarlayan İçerikleri Listele'; btn.disabled = false; }
});
// ── Internal links ─────────────────────────────────────────────────────────
document.getElementById('btn-internal-links')?.addEventListener('click', async () => {
const btn = document.getElementById('btn-internal-links');
btn.disabled = true;
document.getElementById('link-loading').style.display = 'block';
document.getElementById('link-results').style.display = 'none';
try {
const r = await fetch('{{ route("admin.seo.internal-links") }}');
const d = await r.json();
const box = document.getElementById('link-results');
box.innerHTML = '<div style="font-size:.78rem;font-weight:600;color:var(--text2);margin-bottom:6px">Hiç atıflanmayan animeler (Orphaned Pages)</div>' +
d.filter(a => a.mentioned_in === 0).slice(0,20).map(a =>
`<div style="display:flex;justify-content:space-between;padding:6px 10px;background:var(--surface);border:1px solid var(--border);border-radius:4px;margin-bottom:4px;font-size:.78rem">
<span><a href="/anime/${a.slug}" target="_blank" style="color:var(--info)">${a.title}</a></span>
<span class="badge bg-danger" style="font-size:.65rem">0 atıf</span>
</div>`
).join('') || '<div class="text-muted text-center">Tüm animeler atıflanıyor!</div>';
box.style.display = 'block';
document.getElementById('link-loading').style.display = 'none';
btn.disabled = false;
} catch(e) { document.getElementById('link-loading').style.display = 'none'; btn.disabled = false; }
});
// ── Re-audit ───────────────────────────────────────────────────────────────
document.getElementById('btn-reaudit')?.addEventListener('click', async () => {
const btn = document.getElementById('btn-reaudit');
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>';
btn.disabled = true;
try {
const r = await fetch('{{ route("admin.seo.audit") }}');
const d = await r.json();
const scoreEl = document.querySelector('.score-num');
if (scoreEl) scoreEl.textContent = d.score;
btn.innerHTML = '<i class="bi bi-arrow-clockwise me-1"></i>Yenile';
btn.disabled = false;
setTimeout(() => location.reload(), 500);
} catch(e) { btn.disabled = false; btn.innerHTML = '<i class="bi bi-arrow-clockwise me-1"></i>Yenile'; }
});
// ══════════════════════════════════════════════════════════════════════════
// AI ASISTAN
// ══════════════════════════════════════════════════════════════════════════
const CSRF = document.querySelector('meta[name=csrf-token]')?.content || '';
const aiChatUrl = '{{ route("admin.seo.ai.chat") }}';
const aiAnimeGenUrl = '{{ url("admin/seo/ai/anime") }}';
const aiKwSuggestUrl = '{{ route("admin.seo.ai.keyword-suggest") }}';
const aiPageUrl = '{{ route("admin.seo.ai.page-analysis") }}';
const aiFaqUrl = '{{ route("admin.seo.ai.faq-schema") }}';
const aiStrategyUrl = '{{ route("admin.seo.ai.content-strategy") }}';
// ── Chat ──────────────────────────────────────────────────────────────────
let chatHistory = [];
function addChatMessage(role, html, isTyping = false) {
const box = document.getElementById('ai-chat-messages');
const wrap = document.createElement('div');
wrap.className = 'ai-msg ' + role;
const avatar = role === 'assistant'
? '<div class="ai-avatar"><i class="bi bi-stars"></i></div>'
: '<div class="ai-avatar">A</div>';
const bubble = isTyping
? `<div class="ai-bubble ai-typing"><span></span><span></span><span></span></div>`
: `<div class="ai-bubble">${html}</div>`;
wrap.innerHTML = avatar + bubble;
box.appendChild(wrap);
box.scrollTop = box.scrollHeight;
return wrap;
}
function mdToHtml(text) {
return text
.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>')
.replace(/\*(.*?)\*/g, '<em>$1</em>')
.replace(/`([^`]+)`/g, '<code>$1</code>')
.replace(/^### (.+)$/gm, '<h4>$1</h4>')
.replace(/^## (.+)$/gm, '<h3>$1</h3>')
.replace(/^• (.+)$/gm, '• $1<br>')
.replace(/^- (.+)$/gm, '• $1<br>')
.replace(/\n\n/g, '<br><br>')
.replace(/\n/g, '<br>');
}
async function sendAiChat(message) {
chatHistory.push({ role: 'user', content: message });
addChatMessage('user', escapeHtml(message));
const typingEl = addChatMessage('assistant', '', true);
try {
const r = await fetch(aiChatUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF },
body: JSON.stringify({ messages: chatHistory })
});
const d = await r.json();
typingEl.remove();
if (d.error) { addChatMessage('assistant', `<span style="color:var(--danger)">${escapeHtml(d.error)}</span>`); return; }
chatHistory.push({ role: 'assistant', content: d.reply });
addChatMessage('assistant', mdToHtml(d.reply));
} catch(e) {
typingEl.remove();
addChatMessage('assistant', `<span style="color:var(--danger)">Bağlantı hatası: ${escapeHtml(e.message)}</span>`);
}
}
document.getElementById('btn-ai-send')?.addEventListener('click', () => {
const inp = document.getElementById('ai-chat-input');
const msg = inp.value.trim();
if (!msg) return;
inp.value = '';
inp.style.height = '';
sendAiChat(msg);
});
document.getElementById('ai-chat-input')?.addEventListener('keydown', e => {
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); document.getElementById('btn-ai-send').click(); }
});
document.querySelectorAll('.btn-quick-prompt').forEach(btn => {
btn.addEventListener('click', () => sendAiChat(btn.textContent.trim()));
});
// ── AI Anime SEO Üretici ──────────────────────────────────────────────────
let aiAnimeCurrentId = null;
let aiAnimeResult = null;
document.getElementById('btn-ai-anime-gen')?.addEventListener('click', async () => {
const sel = document.getElementById('ai-anime-select');
const id = sel.value;
if (!id) { alert('Lütfen bir anime seçin.'); return; }
aiAnimeCurrentId = id;
const btn = document.getElementById('btn-ai-anime-gen');
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>AI çalışıyor...';
btn.disabled = true;
document.getElementById('ai-anime-result').style.display = 'none';
try {
const r = await fetch(`${aiAnimeGenUrl}/${id}/generate`, {
method: 'POST',
headers: { 'X-CSRF-TOKEN': CSRF }
});
const d = await r.json();
if (d.error) { alert(d.error); return; }
aiAnimeResult = d;
document.getElementById('ai-anime-title-out').value = d.seo_title || '';
document.getElementById('ai-anime-desc-out').value = d.seo_meta_desc || '';
document.getElementById('ai-anime-kw-out').value = d.seo_keywords || '';
document.getElementById('ai-anime-primary-kw').value = d.primary_keyword || '';
document.getElementById('ai-anime-intent').value = d.search_intent || '';
const tl = (d.seo_title||'').length;
const dl = (d.seo_meta_desc||'').length;
document.getElementById('ai-anime-title-len').textContent = `${tl} karakter ${tl>=50&&tl<=65?'✓ İdeal':'(ideal: 50-65)'}`;
document.getElementById('ai-anime-title-len').style.color = tl>=50&&tl<=65?'var(--success)':'#d29922';
document.getElementById('ai-anime-desc-len').textContent = `${dl} karakter ${dl>=145&&dl<=158?'✓ İdeal':'(ideal: 145-158)'}`;
document.getElementById('ai-anime-desc-len').style.color = dl>=145&&dl<=158?'var(--success)':'#d29922';
document.getElementById('ai-anime-result').style.display = 'block';
} catch(e) { alert('Hata: ' + e.message); }
finally { btn.innerHTML = '<i class="bi bi-stars me-1"></i>AI ile Oluştur'; btn.disabled = false; }
});
document.getElementById('btn-ai-anime-save')?.addEventListener('click', async () => {
if (!aiAnimeCurrentId || !aiAnimeResult) return;
const btn = document.getElementById('btn-ai-anime-save');
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>';
btn.disabled = true;
try {
// Already saved by the generate endpoint — just show success
btn.innerHTML = '<i class="bi bi-check2 me-1"></i>Kaydedildi!';
btn.className = 'btn btn-success btn-sm';
// Update the select option label
const opt = document.querySelector(`#ai-anime-select option[value="${aiAnimeCurrentId}"]`);
if (opt && !opt.textContent.includes('✓')) opt.textContent += ' ✓';
setTimeout(() => { btn.innerHTML = '<i class="bi bi-check2 me-1"></i>Kaydet'; btn.disabled = false; btn.className = 'btn btn-success btn-sm'; }, 2000);
} catch(e) { btn.innerHTML = '<i class="bi bi-check2 me-1"></i>Kaydet'; btn.disabled = false; }
});
// ── Keyword Araştırması ───────────────────────────────────────────────────
document.getElementById('btn-ai-kw-suggest')?.addEventListener('click', async () => {
const topic = document.getElementById('ai-kw-topic').value.trim();
if (!topic) return;
const btn = document.getElementById('btn-ai-kw-suggest');
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span>';
btn.disabled = true;
document.getElementById('ai-kw-loading').style.display = 'block';
document.getElementById('ai-kw-results').style.display = 'none';
try {
const r = await fetch(aiKwSuggestUrl, {
method: 'POST',
headers: { 'Content-Type':'application/json', 'X-CSRF-TOKEN': CSRF },
body: JSON.stringify({ topic })
});
const d = await r.json();
document.getElementById('ai-kw-loading').style.display = 'none';
if (d.error) { alert(d.error); return; }
const kwGroups = [
['head', '🔥 Head Keywords (Yüksek Hacim)', 'var(--danger)'],
['body', '⚡ Body Keywords (Orta Hacim)', '#d29922'],
['long_tail', '🎯 Long-tail (Düşük Rekabet)', 'var(--success)'],
['questions', '❓ Soru Formatları (Featured Snippet)','#58a6ff'],
];
let html = '';
for (const [key, label, color] of kwGroups) {
if (!d[key]?.length) continue;
html += `<div class="mb-3"><div style="font-size:.78rem;font-weight:600;color:${color};margin-bottom:6px">${label}</div><div>`;
for (const kw of d[key]) {
const diff = kw.difficulty ?? '?';
const diffC = diff<=33?'var(--success)':diff<=66?'#d29922':'var(--danger)';
html += `<span class="ai-kw-badge" onclick="addKwToTracker(this)" data-kw="${escapeHtml(kw.keyword)}" data-vol="${kw.volume||''}" data-diff="${diff}">
${escapeHtml(kw.keyword)}
<span class="kw-vol">${kw.volume||''}</span>
<span class="kw-diff" style="color:${diffC}">${diff}</span>
</span>`;
}
html += '</div></div>';
}
if (d.content_ideas?.length) {
html += `<div class="mt-2" style="background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:10px">
<div style="font-size:.75rem;font-weight:600;color:var(--text2);margin-bottom:6px">💡 İçerik Fikirleri</div>`;
for (const idea of d.content_ideas) {
html += `<div style="font-size:.78rem;color:var(--text);margin-bottom:4px">• ${escapeHtml(idea)}</div>`;
}
html += '</div>';
}
const box = document.getElementById('ai-kw-results');
box.innerHTML = html + '<div style="font-size:.7rem;color:var(--text2);margin-top:6px">Rozete tıklayarak anahtar kelime takip listesine ekleyin.</div>';
box.style.display = 'block';
} catch(e) { document.getElementById('ai-kw-loading').style.display = 'none'; alert(e.message); }
finally { btn.innerHTML = '<i class="bi bi-search me-1"></i>Araştır'; btn.disabled = false; }
});
document.getElementById('ai-kw-topic')?.addEventListener('keydown', e => {
if (e.key === 'Enter') document.getElementById('btn-ai-kw-suggest').click();
});
async function addKwToTracker(el) {
const kw = el.dataset.kw;
try {
await fetch('{{ route("admin.seo.keywords.store") }}', {
method: 'POST',
headers: { 'Content-Type':'application/json', 'X-CSRF-TOKEN': CSRF },
body: JSON.stringify({ keyword: kw })
});
el.style.background = '#238636'; el.style.borderColor = '#238636'; el.style.color = '#fff';
el.setAttribute('title', 'Listeye eklendi!');
} catch(e) {}
}
// ── Sayfa Analizi ─────────────────────────────────────────────────────────
document.getElementById('btn-ai-page-analyze')?.addEventListener('click', async () => {
const url = document.getElementById('ai-page-url').value.trim();
if (!url) return;
const btn = document.getElementById('btn-ai-page-analyze');
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span>';
btn.disabled = true;
document.getElementById('ai-page-loading').style.display = 'block';
document.getElementById('ai-page-results').style.display = 'none';
try {
const r = await fetch(aiPageUrl, {
method: 'POST',
headers: { 'Content-Type':'application/json', 'X-CSRF-TOKEN': CSRF },
body: JSON.stringify({ url })
});
const d = await r.json();
document.getElementById('ai-page-loading').style.display = 'none';
if (d.error) { alert(d.error); return; }
const scoreColor = s => s>=80?'var(--success)':s>=60?'#d29922':'var(--danger)';
let html = `<div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:14px;margin-bottom:8px">
<div class="d-flex align-items-center gap-3 mb-3">
<div style="font-size:2rem;font-weight:800;color:${scoreColor(d.overall_score)}">${d.overall_score}</div>
<div><div style="font-size:.82rem;font-weight:600">Genel SEO Skoru</div><div style="font-size:.72rem;color:var(--text2)">${url}</div></div>
</div>`;
if (d.quick_wins?.length) {
html += `<div style="font-size:.78rem;font-weight:600;color:var(--success);margin-bottom:4px">⚡ Hızlı Kazançlar</div>`;
for (const win of d.quick_wins) html += `<div style="font-size:.78rem;color:var(--text);margin-bottom:2px">✓ ${escapeHtml(win)}</div>`;
}
if (d.priority_actions?.length) {
html += `<div style="font-size:.78rem;font-weight:600;color:var(--danger);margin:8px 0 4px">🎯 Öncelikli Aksiyonlar</div>`;
d.priority_actions.forEach((a,i) => { html += `<div style="font-size:.78rem;color:var(--text);margin-bottom:2px">${i+1}. ${escapeHtml(a)}</div>`; });
}
if (d.technical_issues?.length) {
html += `<div style="font-size:.78rem;font-weight:600;color:#d29922;margin:8px 0 4px">⚠ Teknik Sorunlar</div>`;
for (const issue of d.technical_issues) html += `<div style="font-size:.78rem;color:var(--text2);margin-bottom:2px">• ${escapeHtml(issue)}</div>`;
}
html += '</div>';
const box = document.getElementById('ai-page-results');
box.innerHTML = html;
box.style.display = 'block';
} catch(e) { document.getElementById('ai-page-loading').style.display = 'none'; alert(e.message); }
finally { btn.innerHTML = '<i class="bi bi-magnifying-glass me-1"></i>Analiz Et'; btn.disabled = false; }
});
// ── FAQ Schema ────────────────────────────────────────────────────────────
document.getElementById('btn-ai-faq')?.addEventListener('click', async () => {
const animeId = document.getElementById('ai-faq-anime').value;
if (!animeId) { alert('Bir anime seçin.'); return; }
const btn = document.getElementById('btn-ai-faq');
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Üretiliyor...';
btn.disabled = true;
try {
const r = await fetch(aiFaqUrl, {
method: 'POST',
headers: { 'Content-Type':'application/json', 'X-CSRF-TOKEN': CSRF },
body: JSON.stringify({ anime_id: animeId })
});
const d = await r.json();
if (d.error) { alert(d.error); return; }
const faqs = d.faqs || [];
const schemaJson = JSON.stringify({
"@@context":"https://schema.org",
"@@type":"FAQPage",
"mainEntity": faqs.map(f=>({ "@@type":"Question","name":f.question,"acceptedAnswer":{"@@type":"Answer","text":f.answer} }))
}, null, 2);
let html = '<div style="font-size:.75rem;font-weight:600;color:var(--text2);margin-bottom:6px">Üretilen FAQ\'lar:</div>';
for (const faq of faqs) {
html += `<div style="background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:8px 12px;margin-bottom:6px">
<div style="font-size:.78rem;font-weight:600;color:var(--text)">${escapeHtml(faq.question)}</div>
<div style="font-size:.75rem;color:var(--text2);margin-top:3px">${escapeHtml(faq.answer)}</div>
</div>`;
}
html += `<details style="margin-top:8px"><summary style="font-size:.75rem;color:var(--info);cursor:pointer">JSON-LD Schema Kodu</summary>
<pre style="font-size:.7rem;background:#010409;border:1px solid var(--border);border-radius:6px;padding:8px;overflow-x:auto;white-space:pre-wrap;color:var(--info)">${escapeHtml(schemaJson)}</pre>
</details>`;
const box = document.getElementById('ai-faq-results');
box.innerHTML = html;
box.style.display = 'block';
} catch(e) { alert(e.message); }
finally { btn.innerHTML = '<i class="bi bi-stars me-1"></i>FAQ Üret'; btn.disabled = false; }
});
// ── İçerik Stratejisi ─────────────────────────────────────────────────────
document.getElementById('btn-ai-strategy')?.addEventListener('click', async () => {
const btn = document.getElementById('btn-ai-strategy');
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Strateji oluşturuluyor...';
btn.disabled = true;
document.getElementById('ai-strategy-result').style.display = 'none';
try {
const r = await fetch(aiStrategyUrl, {
method: 'POST',
headers: { 'X-CSRF-TOKEN': CSRF }
});
const d = await r.json();
if (d.error) { alert(d.error); return; }
const box = document.getElementById('ai-strategy-result');
box.innerHTML = mdToHtml(d.strategy || '');
box.style.display = 'block';
} catch(e) { alert(e.message); }
finally { btn.innerHTML = '<i class="bi bi-lightning me-1"></i>Strateji Oluştur'; btn.disabled = false; }
});
// ── Yardımcılar ───────────────────────────────────────────────────────────
function escapeHtml(str) {
return String(str||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
</script>
@endpush