last_edit / frontend /ads.html
Moharek
Deploy Moharek GEO Platform
a74b879
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>إدارة الإعلانات المدفوعة — منصة محرك GEO</title>
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;500;600;700;800;900&family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<style>
:root {
--bg: #071f21;
--surface: rgba(255, 255, 255, 0.04);
--blue: #5fd4dc;
--gold: #c8f04e;
--red: #ff4d4d;
--emerald: #4ade80;
--purple: #9370db;
--orange: #fbbf24;
--cyan: #5fd4dc;
--rose: #f43f5e;
--text: #ffffff;
--muted: rgba(255, 255, 255, 0.5);
--dim: rgba(255, 255, 255, 0.3);
--border: rgba(255, 255, 255, 0.08);
--glass: rgba(255, 255, 255, 0.035);
--hero-grad: linear-gradient(135deg, #fff 0%, #c8f04e 45%, #5fd4dc 100%);
--accent-grad: linear-gradient(135deg, #c8f04e 0%, #5fd4dc 100%);
--gold-grad: linear-gradient(135deg, #c8f04e 0%, #fbbf24 100%);
--accent: #c8f04e;
}
*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--bg);color:var(--text);font-family:'Cairo',sans-serif;direction:rtl;overflow-x:hidden}
.bg-mesh{position:fixed;inset:0;z-index:-2;
background:radial-gradient(circle at 10% 10%,rgba(59,130,246,.12) 0%,transparent 40%),
radial-gradient(circle at 90% 90%,rgba(251,191,36,.1) 0%,transparent 40%),
radial-gradient(circle at 50% 50%,rgba(239,68,68,.06) 0%,transparent 60%);
filter:blur(100px);animation:meshMove 20s infinite alternate ease-in-out}
@keyframes meshMove{0%{transform:scale(1) translate(0,0)}100%{transform:scale(1.1) translate(2%,2%)}}
.bg-grid{position:fixed;inset:0;z-index:-1;background-image:radial-gradient(rgba(255,255,255,.05) 1px,transparent 1px);background-size:32px 32px;opacity:.5}
/* Navigation */
nav{position:sticky;top:0;z-index:1000;border-bottom:1px solid var(--border);background:rgba(3,7,18,.85);backdrop-filter:blur(32px);height:80px;display:flex;align-items:center}
.nav-inner{max-width:1200px;margin:0 auto;padding:0 32px;width:100%;display:flex;justify-content:space-between;align-items:center}
.nav-logo{display:flex;align-items:center;gap:12px;text-decoration:none}
.logo-box {
width: 44px;
height: 40px;
flex-shrink: 0;
position: relative;
}
.gear-motif {
position: relative;
width: 100%;
height: 100%;
}
.gear-motif i {
position: absolute;
font-size: 18px;
filter: drop-shadow(0 0 5px rgba(0,0,0,0.5));
animation: gearSpin 10s linear infinite;
}
.gear-blue {
top: 0;
left: 50%;
transform: translateX(-50%);
color: var(--blue);
z-index: 2;
}
.gear-gold {
bottom: 2px;
left: 4px;
color: var(--gold);
font-size: 14px !important;
animation-delay: -3s !important;
}
.gear-red {
bottom: 2px;
right: 4px;
color: var(--red);
font-size: 14px !important;
animation-delay: -6s !important;
}
@keyframes gearSpin {
from { transform: translateX(-50%) rotate(0deg); }
to { transform: translateX(-50%) rotate(360deg); }
}
.gear-gold, .gear-red {
animation-name: gearSpinStatic !important;
}
@keyframes gearSpinStatic {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.nav-links{display:flex;gap:28px}
.nav-link{color:var(--muted);text-decoration:none;font-weight:700;font-size:14px;transition:.3s;padding:8px;position:relative}
.nav-link:hover{color:#fff}
.nav-link.active{color:var(--text);}
.nav-link.active::after{content:'';position:absolute;bottom:-10px;left:0;right:0;height:2px;background:var(--blue);border-radius:2px}
.nav-user{display:flex;align-items:center;gap:16px}
.user-info{text-align:right}
.user-name{font-weight:900;color:#fff;font-size:14px}
.user-email{font-size:11px;color:var(--muted)}
.user-avatar{
width:40px;height:40px;border-radius:12px;
background:var(--accent-grad);
display:flex;align-items:center;justify-content:center;
font-weight:900;color:#000;font-size:18px;
box-shadow: 0 0 20px rgba(59, 130, 246, 0.3);
}
.logout-btn{padding:8px 24px;background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.3);color:var(--red);border-radius:100px;font-weight:800;font-size:13px;cursor:pointer;transition:.3s}
.logout-btn:hover{background:var(--red);color:#fff}
.wrap{max-width:1200px;margin:0 auto;padding:40px 24px}
.page-header{margin-bottom:40px;text-align:center}
.label{display:inline-flex;align-items:center;gap:6px;background:rgba(251,191,36,0.1);color:var(--gold);padding:6px 16px;border-radius:100px;font-size:12px;font-weight:700;margin-bottom:16px;border:1px solid rgba(251,191,36,0.25)}
.page-title{font-size:clamp(32px,6vw,54px);font-weight:900;margin-bottom:12px;background:var(--hero-grad);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.page-subtitle{font-size:16px;color:var(--muted);max-width:700px;margin:0 auto}
/* Tabs */
.tabbar{display:flex;flex-wrap:wrap;gap:10px;background:var(--bg-elevated);border:1px solid var(--border);padding:8px;border-radius:16px;margin-top:32px;justify-content:center;backdrop-filter:blur(10px)}
.tb{background:transparent;border:none;color:var(--muted);padding:12px 20px;border-radius:10px;font-family:'Cairo',sans-serif;font-weight:700;font-size:14px;cursor:pointer;transition:all .3s}
.tb:hover{color:#fff;background:rgba(255,255,255,0.05)}
.tb.on{background:var(--blue);color:#fff;box-shadow:0 6px 20px rgba(59,130,246,0.4)}
/* Content Area */
.tp{display:none;animation:fadeIn .5s cubic-bezier(.4,auto,.2,1)}
.tp.on{display:block}
@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
/* KPIs */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:20px;margin-bottom:32px}
.kpi{background:var(--bg-elevated);border:1px solid var(--border);padding:24px;border-radius:16px;position:relative;overflow:hidden;transition:.3s;backdrop-filter:blur(12px)}
.kpi:hover{transform:translateY(-4px);box-shadow:0 12px 30px rgba(0,0,0,0.5)}
.kpi.blue:hover{border-color:rgba(59,130,246,.4)}
.kpi.gre:hover{border-color:rgba(16,185,129,.4)}
.kpi.yel:hover{border-color:rgba(251,191,36,.4)}
.kpi.red:hover{border-color:rgba(239,68,68,.4)}
.kpi-lbl{font-size:13px;color:var(--muted);font-weight:600;margin-bottom:8px}
.kpi-val{font-size:36px;font-weight:900;color:#fff;margin-bottom:4px}
.kpi-sub{font-size:12px;color:var(--dim)}
/* Panels */
.panel{background:var(--bg-elevated);border:1px solid var(--border);border-radius:16px;padding:32px;margin-bottom:24px;backdrop-filter:blur(10px);box-shadow:0 8px 32px rgba(0,0,0,0.2)}
.reveal{opacity:0;transform:translateY(20px);transition:all .6s cubic-bezier(.16,1,.3,1)}
.reveal.show{opacity:1;transform:translateY(0)}
.panel-hd{display:flex;justify-content:space-between;align-items:center;margin-bottom:24px;flex-wrap:wrap;gap:16px}
.panel-title{font-size:18px;font-weight:800;color:#fff;display:flex;align-items:center;gap:10px}
/* Tables */
.table-container{overflow-x:auto}
table{width:100%;border-collapse:collapse;min-width:700px}
th{text-align:right;padding:16px;font-size:13px;font-weight:700;color:var(--muted);border-bottom:1px solid var(--border);white-space:nowrap}
td{padding:16px;font-size:14px;border-bottom:1px solid rgba(255,255,255,0.03);color:#e2e8f0;white-space:nowrap}
tr:hover td{background:rgba(255,255,255,0.02)}
.badge{padding:4px 10px;border-radius:6px;font-size:11px;font-weight:700}
.badge.on{background:rgba(16,185,129,0.1);color:var(--emerald);border:1px solid rgba(16,185,129,0.2)}
.badge.off{background:rgba(148,163,184,0.1);color:var(--muted);border:1px solid rgba(148,163,184,0.2)}
.qs{display:flex;align-items:center;gap:10px}
.qs-track{flex:1;height:6px;background:rgba(255,255,255,0.1);border-radius:3px;overflow:hidden;min-width:60px}
.qs-fill{height:100%;border-radius:3px}
.qs-n{font-size:13px;font-weight:700}
/* Forms */
.row2{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-bottom:20px}
.inp-grp{display:flex;flex-direction:column;gap:8px}
.inp-grp label{font-size:13px;color:var(--muted);font-weight:600}
.inp-grp input, .inp-grp select{background:rgba(0,0,0,0.3);border:1px solid var(--border);color:#fff;padding:14px 16px;border-radius:10px;font-family:'Cairo',sans-serif;font-size:14px;transition:.3s;width:100%}
.inp-grp input:focus, .inp-grp select:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(59,130,246,0.1)}
/* Buttons */
.btn{padding:12px 28px;border-radius:100px;font-family:'Cairo',sans-serif;font-weight:700;font-size:14px;cursor:pointer;transition:.3s;border:none;display:inline-flex;align-items:center;gap:8px}
.btn-p{background:var(--gold);color:#071f21;box-shadow:0 8px 24px rgba(200,240,78,0.3)}
.btn-p:hover{transform:scale(1.05);box-shadow:0 12px 32px rgba(200,240,78,0.5)}
.btn-p:disabled{opacity:0.7;cursor:not-allowed;transform:none}
.spin{display:inline-block;width:16px;height:16px;border:2px solid rgba(255,255,255,0.3);border-radius:50%;border-top-color:#fff;animation:spin 1s ease-in-out infinite}
@keyframes spin{to{transform:rotate(360deg)}}
/* Custom outputs */
.bid-card{background:rgba(255,255,255,0.02);border:1px solid var(--border);border-radius:12px;padding:16px;margin-bottom:12px;display:flex;gap:16px;align-items:center}
.bid-act{padding:6px 12px;border-radius:8px;font-size:12px;font-weight:800;white-space:nowrap}
.bid-act.inc{background:rgba(16,185,129,0.1);color:var(--emerald)}
.bid-act.dec{background:rgba(239,68,68,0.1);color:var(--red)}
.bid-act.pau{background:rgba(249,115,22,0.1);color:var(--orange)}
.bid-act.kee{background:rgba(59,130,246,0.1);color:var(--blue)}
.term-grid{display:grid;grid-template-columns:1fr 1fr;gap:24px}
.term-item{padding:12px 16px;background:rgba(0,0,0,0.2);border-radius:8px;margin-bottom:10px;border-right:3px solid transparent}
.term-cv{border-right-color:var(--emerald)}
.term-wt{border-right-color:var(--red)}
.term-name{font-weight:700;font-size:14px;color:#fff;margin-bottom:4px}
.term-meta{font-size:12px;color:var(--muted)}
.hchip{display:inline-block;background:rgba(255,255,255,0.05);border:1px solid var(--border);border-radius:6px;padding:8px 12px;margin:0 0 10px 10px;font-size:14px;color:#fff}
.hchip .chars{font-size:10px;color:var(--dim);margin-right:8px}
.desc-row{background:rgba(255,255,255,0.02);border:1px solid var(--border);border-radius:8px;padding:12px 16px;margin-bottom:10px;font-size:14px;color:#e2e8f0;line-height:1.6}
.ntag{display:inline-block;padding:6px 12px;border-radius:6px;font-size:13px;font-weight:600;margin:0 0 8px 8px}
.ntag.exact{background:rgba(239,68,68,0.1);color:var(--red);border:1px solid rgba(239,68,68,0.2)}
.ntag.phrase{background:rgba(251,191,36,0.1);color:var(--gold);border:1px solid rgba(251,191,36,0.2)}
.ntag.watch{background:rgba(148,163,184,0.1);color:var(--muted);border:1px solid rgba(148,163,184,0.2)}
.wizard{display:flex;flex-direction:column;gap:24px;margin-bottom:24px}
.wstep{display:flex;gap:16px}
.wstep-num{width:36px;height:36px;border-radius:50%;background:rgba(59,130,246,0.1);color:var(--blue);display:grid;place-items:center;font-weight:800;font-size:16px;flex-shrink:0;border:1px solid rgba(59,130,246,0.3)}
.wstep.done .wstep-num{background:var(--emerald);color:#000;border-color:var(--emerald)}
.wstep-ttl{font-size:15px;font-weight:800;color:#fff;margin-bottom:4px;padding-top:6px}
.wstep-desc{font-size:12.5px;color:var(--muted);margin-bottom:16px;line-height:1.6}
.status-bar{padding:12px 16px;border-radius:8px;font-size:13px;font-weight:600;margin-top:20px;display:none}
.status-bar.inf{background:rgba(59,130,246,0.1);color:var(--blue);border:1px solid rgba(59,130,246,0.2)}
.status-bar.ok{background:rgba(16,185,129,0.1);color:var(--emerald);border:1px solid rgba(16,185,129,0.2)}
.status-bar.err{background:rgba(239,68,68,0.1);color:var(--red);border:1px solid rgba(239,68,68,0.2)}
@media(max-width:900px){
.term-grid{grid-template-columns:1fr}
.row2{grid-template-columns:1fr}
.nav-links{display:none}
}
</style>
</head>
<body>
<div class="bg-mesh"></div>
<div class="bg-grid"></div>
<nav>
<div class="nav-inner">
<a href="/portal.html" class="nav-logo">
<div class="logo-box" style="width:40px;height:40px;display:grid;place-items:center;overflow:hidden;border-radius:10px;background:transparent">
<img src="moharek-logo-v2.svg" alt="Moharek" style="width:100%;height:100%;object-fit:contain">
</div>
<div>
<div style="font-size:15px;font-weight:900;color:#fff">محرك GEO</div>
<div style="font-size:10px;color:var(--muted);font-weight:500">BRAND IDENTITY · AI</div>
</div>
</a>
<div class="nav-links">
<a class="nav-link" href="/portal.html">لوحة التحكم</a>
<a class="nav-link" href="/jobs.html">التحليلات</a>
<a class="nav-link" href="/search.html">الذكاء</a>
<a class="nav-link" href="/recommendations.html">التوصيات</a>
<a class="nav-link active" href="/ads.html">إدارة الإعلانات</a>
</div>
<div class="nav-user">
<div class="user-info">
<div class="user-name" id="userNameNav">مستخدم</div>
<div class="user-email" id="userEmailNav">user@mohrek.com</div>
</div>
<div class="user-avatar" id="userAvatarNav">M</div>
<button class="logout-btn" onclick="logout()">خروج</button>
</div>
</div>
</nav>
<div class="wrap" id="mainWrap">
<div class="page-header reveal">
<div class="label"><i class="fas fa-chart-line"></i> وحدة استخبارات — الإعلانات المدفوعة</div>
<h1 class="page-title">إدارة <span>الإعلانات</span> بذكاء</h1>
<p class="page-subtitle">تحليلات الحملة، تحسين عروض الأسعار بالذكاء الاصطناعي، وتوليد نصوص الإعلانات جنباً إلى جنب مع استراتيجية محرك GEO المتقدمة.</p>
<!-- Demo Banner injected here if applicable -->
<div class="tabbar">
<button class="tb on" onclick="sw('dash',this)">لوحة التحكم</button>
<button class="tb" onclick="sw('kw',this)">الكلمات الرئيسية</button>
<button class="tb" onclick="sw('terms',this)">طلبات البحث</button>
<button class="tb" onclick="sw('bids',this)">عروض الأسعار الذكية</button>
<button class="tb" onclick="sw('copy',this)">نصوص الإعلانات</button>
<button class="tb" onclick="sw('neg',this)">الكلمات السلبية</button>
<button class="tb" onclick="sw('rpt',this)">التقرير الأسبوعي</button>
<button class="tb" onclick="sw('conn',this)">اتصال</button>
</div>
</div>
<!-- DASHBOARD -->
<div id="tp-dash" class="tp on">
<div class="kpis reveal">
<div class="kpi blue"><div class="kpi-lbl">إجمالي الإنفاق (30 يوم)</div><div class="kpi-val" id="kv-spend"></div><div class="kpi-sub">عبر جميع الحملات</div></div>
<div class="kpi gre"><div class="kpi-lbl">إجمالي النقرات</div><div class="kpi-val" id="kv-clicks"></div><div class="kpi-sub" id="kv-cmp">— حملات</div></div>
<div class="kpi yel"><div class="kpi-lbl">التحويلات</div><div class="kpi-val" id="kv-conv"></div><div class="kpi-sub">عملاء محتملون / مبيعات</div></div>
<div class="kpi red"><div class="kpi-lbl">متوسط تكلفة التحويل</div><div class="kpi-val" id="kv-cpa"></div><div class="kpi-sub">تكلفة كل تحويل</div></div>
</div>
<div class="panel">
<div class="panel-hd"><div class="panel-title"><i class="fas fa-chart-bar" style="color:var(--blue)"></i> أداء الحملة</div></div>
<div class="table-container">
<table>
<thead><tr><th>الحملة</th><th>الحالة</th><th>النقرات</th><th>مرات الظهور</th><th>نسبة النقر</th><th>متوسط ت.ن</th><th>التكلفة</th><th>التحويلات</th><th>ت.التحويل</th><th>حصة الظهور</th></tr></thead>
<tbody id="camp-tb"><tr><td colspan="10" style="text-align:center;color:var(--dim);padding:40px"><span class="spin"></span></td></tr></tbody>
</table>
</div>
</div>
</div>
<!-- KEYWORDS -->
<div id="tp-kw" class="tp">
<div class="panel">
<div class="panel-hd"><div class="panel-title"><i class="fas fa-key" style="color:var(--gold)"></i> أداء الكلمات الرئيسية — درجات الجودة</div></div>
<div class="table-container">
<table>
<thead><tr><th>الكلمة الرئيسية</th><th>المطابقة</th><th>درجة الجودة</th><th>النقرات</th><th>نسبة النقر</th><th>ت.ن</th><th>التكلفة</th><th>التحويلات</th></tr></thead>
<tbody id="kw-tb"><tr><td colspan="8" style="text-align:center;color:var(--dim);padding:40px"><span class="spin"></span></td></tr></tbody>
</table>
</div>
</div>
</div>
<!-- SEARCH TERMS -->
<div id="tp-terms" class="tp">
<div class="term-grid">
<div class="panel" style="margin-bottom:0">
<div class="panel-title" style="color:var(--emerald);margin-bottom:16px"><i class="fas fa-check-circle"></i> طلبات البحث المحولة</div>
<div id="cv-terms"><div style="text-align:center;color:var(--dim);padding:30px">لا يوجد بيانات للطلبات المحولة.</div></div>
</div>
<div class="panel" style="margin-bottom:0">
<div class="panel-title" style="color:var(--red);margin-bottom:16px"><i class="fas fa-exclamation-triangle"></i> الإنفاق المهدر</div>
<div id="wt-terms"><div style="text-align:center;color:var(--dim);padding:30px">لا يوجد بيانات للإنفاق المهدر.</div></div>
</div>
</div>
</div>
<!-- AI BIDS -->
<div id="tp-bids" class="tp">
<div class="panel">
<div class="panel-hd">
<div class="panel-title"><i class="fas fa-robot" style="color:var(--purple)"></i> تحسين عروض الأسعار بالذكاء الاصطناعي</div>
<button class="btn btn-p" onclick="loadBids()" id="bid-btn"><i class="fas fa-magic"></i> تحليل الكلمات</button>
</div>
<div id="bid-st" style="font-size:12px;color:var(--blue);margin-bottom:16px;background:rgba(59,130,246,0.1);padding:10px 16px;border-radius:8px;display:none"></div>
<div id="bid-out"><div style="text-align:center;color:var(--muted);padding:60px 20px;font-size:14px;background:rgba(0,0,0,0.2);border-radius:12px;border:1px dashed var(--border)">انقر فوق "تحليل الكلمات" للحصول على توصيات الذكاء الاصطناعي</div></div>
</div>
</div>
<!-- AD COPY -->
<div id="tp-copy" class="tp">
<div class="panel">
<div class="panel-hd"><div class="panel-title"><i class="fas fa-pen-nib" style="color:var(--orange)"></i> مولد نصوص الإعلانات (RSA)</div></div>
<div class="row2" style="margin-bottom:14px">
<div class="inp-grp"><label>اللغة</label><select id="cp-lang"><option value="ar">العربية</option><option value="en">الإنجليزية</option></select></div>
<div class="inp-grp"><label>الخدمة / المنتج</label><input id="cp-svc" value="خدمات المحرك الذكي" placeholder="مثال: خدمات المبيعات"></div>
</div>
<div class="row2" style="margin-bottom:24px">
<div class="inp-grp"><label>الميزة التنافسية (USP)</label><input id="cp-usp" value="تصدر نتائج محركات الذكاء الاصطناعي والمحركات التقليدية"></div>
<div class="inp-grp"><label>الجمهور المستهدف</label><input id="cp-aud" value="الشركات والمؤسسات التي تبحث عن زيادة العملاء"></div>
</div>
<button class="btn btn-p" onclick="genCopy()" id="cp-btn"><i class="fas fa-wand-magic-sparkles"></i> توليد نصوص بالذكاء الاصطناعي</button>
<div id="cp-st" style="font-size:12px;color:var(--muted);margin-top:12px"></div>
<div id="cp-out" style="display:none;margin-top:32px;background:rgba(0,0,0,0.2);padding:24px;border-radius:16px;border:1px solid var(--border)">
<div style="font-size:11px;letter-spacing:1px;color:var(--muted);font-weight:800;margin-bottom:12px">العناوين — بحد أقصى 30 حرفاً</div>
<div id="hl-out" style="margin-bottom:24px"></div>
<div style="font-size:11px;letter-spacing:1px;color:var(--muted);font-weight:800;margin-bottom:12px">الأوصاف — بحد أقصى 90 حرفاً</div>
<div id="dc-out" style="margin-bottom:24px"></div>
<div style="font-size:11px;letter-spacing:1px;color:var(--muted);font-weight:800;margin-bottom:8px">مسار العرض (Display Path)</div>
<div id="pt-out" style="font-family:'Cairo',sans-serif;font-size:15px;color:var(--emerald);font-weight:700"></div>
</div>
</div>
</div>
<!-- NEGATIVES -->
<div id="tp-neg" class="tp">
<div class="panel">
<div class="panel-hd">
<div class="panel-title"><i class="fas fa-minus-circle" style="color:var(--red)"></i> كاشف الكلمات السلبية</div>
<button class="btn btn-p" onclick="detectNeg()"><i class="fas fa-search"></i> كشف السلبيات</button>
</div>
<div id="neg-st" style="font-size:12px;color:var(--muted);margin-bottom:14px"></div>
<div id="neg-out"><div style="text-align:center;color:var(--muted);padding:60px 20px;font-size:14px;background:rgba(0,0,0,0.2);border-radius:12px;border:1px dashed var(--border)">قم بتحليل الإنفاق المهدر للعثور على الكلمات السلبية بالذكاء الاصطناعي</div></div>
</div>
</div>
<!-- REPORT -->
<div id="tp-rpt" class="tp">
<div class="panel">
<div class="panel-hd">
<div class="panel-title"><i class="fas fa-file-alt" style="color:var(--cyan)"></i> تقرير أسبوعي بالذكاء الاصطناعي</div>
<div style="display:flex;gap:12px;align-items:center">
<select id="rpt-lang" style="background:var(--bg-elevated);border:1px solid var(--border);color:#fff;padding:10px 16px;border-radius:8px;font-family:'Cairo'"><option value="ar">العربية الإفتراضية</option><option value="en">English</option></select>
<button class="btn btn-p" onclick="genRpt()"><i class="fas fa-print"></i> بناء التقرير</button>
</div>
</div>
<div id="rpt-st" style="font-size:12px;color:var(--muted);margin-bottom:16px"></div>
<pre id="rpt-out" style="display:none;background:rgba(0,0,0,0.3);padding:24px;border-radius:12px;border:1px solid var(--border);color:#e2e8f0;font-family:'Cairo',sans-serif;font-size:14px;line-height:1.8;white-space:pre-wrap"></pre>
</div>
</div>
<!-- CONNECT -->
<div id="tp-conn" class="tp">
<div style="max-width:700px;margin:0 auto">
<div class="panel">
<div class="panel-title" style="margin-bottom:24px"><i class="fas fa-link"></i> ربط حساب إعلانات جوجل</div>
<div class="wizard">
<div class="wstep">
<div class="wstep-num" id="sn1">1</div>
<div style="flex:1">
<div class="wstep-ttl">رمز المطور (Developer Token)</div>
<div class="wstep-desc">احصل عليه من حسابك الإداري في إعلانات جوجل → أدوات → مركز API.</div>
<div class="inp-grp"><input type="password" id="f-dev" placeholder="أدخل رمز المطور الخاص بـ API"></div>
</div>
</div>
<div class="wstep">
<div class="wstep-num" id="sn2">2</div>
<div style="flex:1">
<div class="wstep-ttl">بيانات اعتماد OAuth</div>
<div class="wstep-desc">تم إنشاؤها عبر مشروع Google Cloud Console (تطبيق سطح المكتب).</div>
<div class="row2">
<div class="inp-grp"><label>معرف العميل (Client ID)</label><input type="text" id="f-cid" placeholder="123456-abc.apps.googleusercontent.com"></div>
<div class="inp-grp"><label>سر العميل (Client Secret)</label><input type="password" id="f-sec" placeholder="GOCSPX-..."></div>
</div>
</div>
</div>
<div class="wstep">
<div class="wstep-num" id="sn3">3</div>
<div style="flex:1">
<div class="wstep-ttl">رمز التحديث + معرف الحساب</div>
<div class="wstep-desc">رمز مرور يخول التطبيق الدخول إلى تفاصيل حملاتك (Refresh Token).</div>
<div class="row2">
<div class="inp-grp"><label>رمز التحديث (Refresh Token)</label><input type="password" id="f-ref" placeholder="1//0ABCDE..."></div>
<div class="inp-grp"><label>معرف الحساب (Customer ID)</label><input type="text" id="f-cust" placeholder="1234567890"></div>
</div>
</div>
</div>
</div>
<div style="display:flex;gap:12px;margin-top:32px">
<button class="btn btn-p" style="flex:2;justify-content:center" onclick="doConnect()" id="conn-btn"><i class="fas fa-plug"></i> ربط الحساب</button>
<button class="btn" style="flex:1;justify-content:center;background:rgba(255,255,255,0.05);color:#fff;border:1px solid var(--border)" onclick="sw('dash',document.querySelector('.tb'));loadDash()"><i class="fas fa-play"></i> استخدام العرض التجريبي</button>
</div>
<div id="conn-st" class="status-bar"></div>
</div>
</div>
</div>
</div><!-- /wrap -->
<section style="padding:40px 0;text-align:center;border-top:1px solid var(--border)">
<p style="color:var(--dim);font-size:13px; font-weight:600">© 2025 محرك — منصة SEO &amp; GEO بالذكاء الاصطناعي</p>
</section>
<script>
const token = localStorage.getItem('token');
// if (!token) window.location.href = '/login.html';
async function loadUserInfo() {
try {
const res = await fetch('http://localhost:8001/api/users/me', { headers: { 'Authorization': `Bearer ${token}` } });
if (res.ok) {
const data = await res.json();
document.getElementById('userNameNav').textContent = data.username || 'مستخدم';
document.getElementById('userEmailNav').textContent = data.email || '';
document.getElementById('userAvatarNav').textContent = (data.username || 'M')[0].toUpperCase();
}
} catch (e) { console.error(e); }
}
function logout() {
localStorage.removeItem('token');
window.location.href = '/';
}
const A='/api/ads';
let apiKeys={};
function loadKeys(){
apiKeys = {
groq: localStorage.getItem('geo_groq_key'),
openai: localStorage.getItem('geo_openai_key'),
perplexity: localStorage.getItem('geo_perplexity_key'),
serpapi: localStorage.getItem('geo_serpapi_key')
};
}
function sw(id,btn){
document.querySelectorAll('.tp').forEach(p=>p.classList.remove('on'));
document.querySelectorAll('.tb').forEach(b=>b.classList.remove('on'));
document.getElementById('tp-'+id).classList.add('on');
if(btn)btn.classList.add('on');
if(id==='kw')loadKw();
if(id==='terms')loadTerms();
}
// DASHBOARD
async function loadDash(){
try{
const r=await fetch(`${A}/dashboard`),d=await r.json();
if(!d.ok)return;
const s=d.summary;
document.getElementById('kv-spend').textContent='$'+s.total_spend.toLocaleString();
document.getElementById('kv-clicks').textContent=s.total_clicks.toLocaleString();
document.getElementById('kv-conv').textContent=s.total_conversions;
document.getElementById('kv-cpa').textContent='$'+s.avg_cpa;
document.getElementById('kv-cmp').textContent=s.active_campaigns+' active';
// Remove old banner if exists
const existingBanner = document.getElementById('demo-banner');
if(existingBanner) existingBanner.remove();
if(s.is_demo){
let banner=document.createElement('div');
banner.id='demo-banner';
banner.style.cssText='background:rgba(251,191,36,0.1);border:1px dashed rgba(251,191,36,0.4);color:var(--gold);padding:14px 20px;font-size:13px;font-weight:700;border-radius:12px;margin:24px auto;display:flex;align-items:center;gap:10px;justify-content:center;max-width:800px;text-align:center';
banner.innerHTML='<i class="fas fa-exclamation-triangle"></i> يتم عرض بيانات الوضع التجريبي — <a href="javascript:void(0)" onclick="sw(\'conn\',document.querySelector(\'.tb:last-child\'))" style="color:#fff;text-decoration:underline;margin-right:8px;padding-right:8px;border-right:1px solid rgba(255,255,255,0.2)">اربط حسابك في إعلانات جوجل</a>';
document.querySelector('.page-header').appendChild(banner);
}
const tb=document.getElementById('camp-tb');
if(d.campaigns.length === 0){
tb.innerHTML='<tr><td colspan="10" style="text-align:center;color:var(--dim);padding:40px">لا توجد حملات مسجلة</td></tr>';
return;
}
tb.innerHTML=d.campaigns.map(c=>`<tr>
<td style="font-weight:700;color:#fff">${c.name}</td>
<td><span class="badge ${c.status==='ENABLED'?'on':'off'}">${c.status}</span></td>
<td>${c.clicks.toLocaleString()}</td>
<td style="color:var(--muted)">${c.impressions.toLocaleString()}</td>
<td style="color:var(--emerald);font-weight:700">${c.ctr}%</td>
<td>$${c.avg_cpc}</td>
<td style="font-weight:700">$${c.cost.toLocaleString()}</td>
<td style="color:var(--gold);font-weight:800">${c.conversions}</td>
<td style="color:var(--orange)">$${c.cpa}</td>
<td><div class="qs"><div class="qs-track"><div class="qs-fill" style="width:${c.impression_share}%;background:${c.impression_share>60?'var(--emerald)':c.impression_share>30?'var(--gold)':'var(--red)'}"></div></div><span class="qs-n" style="color:var(--muted)">${c.impression_share}%</span></div></td>
</tr>`).join('');
}catch(e){console.error(e)}
}
// KEYWORDS
async function loadKw(){
const tb=document.getElementById('kw-tb');
tb.innerHTML='<tr><td colspan="8" style="text-align:center;color:var(--dim);padding:30px"><span class="spin"></span></td></tr>';
try{
const r=await fetch(`${A}/keywords`),d=await r.json();
if(!d.ok) throw new Error("API failed");
if(d.keywords.length === 0) {
tb.innerHTML = '<tr><td colspan="8" style="text-align:center;color:var(--dim);padding:30px">لا توجد كلمات متاحة</td></tr>';
return;
}
function qc(s){return s>=7?'var(--emerald)':s>=5?'var(--gold)':'var(--red)'}
tb.innerHTML=d.keywords.map(k=>`<tr>
<td style="font-weight:700;font-size:15px;color:#fff">${k.keyword}</td>
<td><span style="font-size:10px;background:rgba(255,255,255,0.06);padding:4px 10px;border-radius:6px;font-family:'Inter',monospace;color:var(--muted)">${k.match_type}</span></td>
<td><div class="qs"><span class="qs-n" style="color:${qc(k.quality_score)};width:16px">${k.quality_score}</span><div class="qs-track"><div class="qs-fill" style="width:${k.quality_score*10}%;background:${qc(k.quality_score)}"></div></div></div></td>
<td style="font-weight:600">${k.clicks}</td>
<td style="color:var(--cyan)">${k.ctr}%</td>
<td>$${k.avg_cpc}</td>
<td>$${k.cost}</td>
<td style="color:${k.conversions>0?'var(--emerald)':'var(--red)'};font-weight:800">${k.conversions}</td>
</tr>`).join('');
}catch(e){tb.innerHTML='<tr><td colspan="8" style="text-align:center;color:var(--red)">فشل في تحميل الكلمات</td></tr>'}
}
// SEARCH TERMS
async function loadTerms(){
try{
const r=await fetch(`${A}/search-terms`),d=await r.json();
if(!d.ok) return;
const cv = document.getElementById('cv-terms');
if(d.data.converting_terms.length) {
cv.innerHTML=d.data.converting_terms.map(t=>`<div class="term-item term-cv"><div class="term-name">${t.term}</div><div class="term-meta">${t.campaign} &middot; ${t.clicks} clicks &middot; <span style="color:var(--emerald);font-weight:700">${t.conversions} تحويل</span></div></div>`).join('');
}
const wt = document.getElementById('wt-terms');
if(d.data.wasted_spend.length) {
wt.innerHTML=d.data.wasted_spend.map(t=>`<div class="term-item term-wt"><div class="term-name">${t.term}</div><div class="term-meta">${t.campaign} &middot; ${t.clicks} clicks &middot; <span style="color:var(--red);font-weight:700">$${(t.clicks*t.avg_cpc).toFixed(2)} مهدر</span></div></div>`).join('');
}
}catch(e){}
}
// AI BIDS
async function loadBids(){
const btn=document.getElementById('bid-btn'),st=document.getElementById('bid-st');
btn.innerHTML='<span class="spin"></span> جاري التحليل...';btn.disabled=true;
st.style.display='block';
st.innerHTML=apiKeys.groq?'<i class="fas fa-info-circle"></i> يتم استخدام Groq AI للتحليل الإستراتيجي...':'<i class="fas fa-exclamation-triangle" style="color:var(--orange)"></i> استخدام اقتراحات ديمو - أضف مفتاح Groq في الإعدادات للبيانات الحقيقية.';
try{
const r=await fetch(`${A}/ai/bid-suggestions`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({api_keys:Object.keys(apiKeys).length?apiKeys:null})});
const d=await r.json();
if(!d.ok)throw new Error(d.error);
const cls={increase:'inc',decrease:'dec',pause:'pau',keep:'kee'};
const lbl={increase:'<i class="fas fa-arrow-up"></i> زيادة',decrease:'<i class="fas fa-arrow-down"></i> تقليل',pause:'<i class="fas fa-pause"></i> مؤقت',keep:'<i class="fas fa-equals"></i> إبقاء'};
document.getElementById('bid-out').innerHTML=d.suggestions.map(s=>`
<div class="bid-card">
<div class="bid-act ${cls[s.action]||'kee'}">${lbl[s.action]||'<i class="fas fa-equals"></i> إبقاء'}</div>
<div style="flex:1">
<div style="font-weight:800;font-size:15px;color:#fff">${s.keyword}</div>
<div style="font-size:13px;color:var(--muted);margin-top:4px;line-height:1.5">${s.reason}</div>
</div>
<div style="text-align:right;min-width:140px;background:rgba(0,0,0,0.2);padding:10px 14px;border-radius:10px;border:1px solid var(--border)">
<div style="font-size:12px;color:var(--muted);font-family:'Inter',monospace">$${s.current_cpc} <i class="fas fa-long-arrow-alt-left" style="margin:0 6px"></i> <strong style="color:var(--emerald);font-size:15px">$${s.suggested_cpc||0}</strong></div>
<div style="font-size:11px;color:var(--blue);margin-top:6px;font-weight:700">${s.expected_impact||''}</div>
</div>
</div>`).join('');
}catch(e){st.innerHTML='<i class="fas fa-times-circle" style="color:var(--red)"></i> خطأ: '+e.message}
btn.innerHTML='<i class="fas fa-magic"></i> تحليل الكلمات';btn.disabled=false;
}
// AD COPY
async function genCopy(){
const btn=document.getElementById('cp-btn'),st=document.getElementById('cp-st');
btn.innerHTML='<span class="spin"></span> جاري التوليد بالإتصال...';btn.disabled=true;st.textContent='';
try{
const r=await fetch(`${A}/ai/copy`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({api_keys:Object.keys(apiKeys).length?apiKeys:null,lang:document.getElementById('cp-lang').value,service_name:document.getElementById('cp-svc').value,usp:document.getElementById('cp-usp').value,target_audience:document.getElementById('cp-aud').value})});
const d=await r.json();if(!d.ok)throw new Error(d.error);
const c=d.copy;
document.getElementById('hl-out').innerHTML=(c.headlines||[]).map(h=>`<span class="hchip">${h}<span class="chars">${h.length} حرف</span></span>`).join('');
document.getElementById('dc-out').innerHTML=(c.descriptions||[]).map(dc=>`<div class="desc-row">${dc}<span style="float:left;font-size:11px;color:var(--dim);font-family:'Inter',monospace;background:rgba(255,255,255,0.05);padding:2px 6px;border-radius:4px">${dc.length}/90</span></div>`).join('');
document.getElementById('pt-out').textContent=(c.display_path||[]).join(' / ');
document.getElementById('cp-out').style.display='block';
}catch(e){st.textContent='فشل: '+e.message}
btn.innerHTML='<i class="fas fa-wand-magic-sparkles"></i> توليد نصوص بالذكاء الاصطناعي';btn.disabled=false;
}
// NEGATIVES
async function detectNeg(){
const btn=document.querySelector('#tp-neg .btn-p');
btn.innerHTML='<span class="spin"></span> كشف بالذكاء...'; btn.disabled=true;
document.getElementById('neg-st').textContent='يجري تحليل سلوك الإنفاق وتحديد الهدر...';
try{
const r=await fetch(`${A}/ai/negatives`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({api_keys:Object.keys(apiKeys).length?apiKeys:null})});
const d=await r.json();if(!d.ok)throw new Error(d.error);
const res=d.result;
document.getElementById('neg-out').innerHTML=`
<div style="background:rgba(16,185,129,0.05);border:1px dashed rgba(16,185,129,0.3);padding:16px;border-radius:12px;margin-bottom:24px;display:flex;align-items:center;gap:12px">
<span style="font-size:14px;color:var(--emerald);font-weight:800"><i class="fas fa-piggy-bank"></i> التوفير المقدر من السلبيات:</span>
<span style="font-size:18px;font-weight:900;color:#fff">${res.estimated_savings}</span>
</div>
<div style="margin-bottom:20px;background:rgba(0,0,0,0.2);padding:20px;border-radius:12px;border:1px solid var(--border)">
<div style="font-size:12px;color:var(--red);font-weight:800;margin-bottom:12px"><i class="fas fa-times-circle"></i> سلبيات مطابقة تامّة (أضف فوراً)</div>
${(res.negatives_exact||[]).map(n=>`<span class="ntag exact">${n}</span>`).join('')}
</div>
<div style="margin-bottom:20px;background:rgba(0,0,0,0.2);padding:20px;border-radius:12px;border:1px solid var(--border)">
<div style="font-size:12px;color:var(--gold);font-weight:800;margin-bottom:12px"><i class="fas fa-exclamation-circle"></i> سلبيات عبارة التقاطيّة</div>
${(res.negatives_phrase||[]).map(n=>`<span class="ntag phrase">${n}</span>`).join('')}
</div>
<div style="background:rgba(0,0,0,0.2);padding:20px;border-radius:12px;border:1px solid var(--border)">
<div style="font-size:12px;color:var(--muted);font-weight:800;margin-bottom:12px"><i class="fas fa-eye"></i> مراقبة في الأسابيع القادمة</div>
${(res.keep_monitoring||[]).map(n=>`<span class="ntag watch">${n}</span>`).join('')}
</div>`;
document.getElementById('neg-st').textContent='';
}catch(e){document.getElementById('neg-st').innerHTML='<i class="fas fa-times-circle" style="color:var(--red)"></i> '+e.message}
btn.innerHTML='<i class="fas fa-search"></i> كشف السلبيات'; btn.disabled=false;
}
// REPORT
async function genRpt(){
const btn=document.querySelector('#tp-rpt .btn-p');
btn.innerHTML='<span class="spin"></span> بناء التقرير...';btn.disabled=true;
const st=document.getElementById('rpt-st'),out=document.getElementById('rpt-out');
st.innerHTML='<i class="fas fa-circle-notch fa-spin"></i> يتم تلخيص وتحليل البيانات...';out.style.display='none';
try{
const r=await fetch(`${A}/ai/weekly-report`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({api_keys:Object.keys(apiKeys).length?apiKeys:null,lang:document.getElementById('rpt-lang').value})});
const d=await r.json();if(!d.ok)throw new Error(d.error);
out.textContent=d.report;out.style.display='block';
st.innerHTML='<i class="fas fa-check-circle" style="color:var(--emerald)"></i> التقرير جاهز.';
}catch(e){st.innerHTML='<i class="fas fa-times-circle" style="color:var(--red)"></i> '+e.message}
btn.innerHTML='<i class="fas fa-print"></i> بناء التقرير';btn.disabled=false;
}
// CONNECT
async function doConnect(){
const btn=document.getElementById('conn-btn'),stEl=document.getElementById('conn-st');
btn.innerHTML='<span class="spin"></span> جاري الإتصال...';btn.disabled=true;
stEl.className='status-bar inf';stEl.style.display='block';stEl.innerHTML='<i class="fas fa-spinner fa-spin"></i> مصادقة...';
try{
const r=await fetch(`${A}/connect`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({developer_token:document.getElementById('f-dev').value,client_id:document.getElementById('f-cid').value,client_secret:document.getElementById('f-sec').value,refresh_token:document.getElementById('f-ref').value,customer_id:document.getElementById('f-cust').value})});
const d=await r.json();
if(d.ok){
stEl.className='status-bar ok';stEl.innerHTML='<i class="fas fa-check-circle"></i> متصل بنجاح: '+(d.account_name||d.customer_id);
['sn1','sn2','sn3'].forEach(id=>{const n=document.getElementById(id);if(n)n.parentNode.classList.add('done')});
}else{
stEl.className='status-bar err';stEl.innerHTML='<i class="fas fa-times-circle"></i> فشل: '+d.error;
}
}catch(e){stEl.className='status-bar err';stEl.innerHTML='<i class="fas fa-wifi"></i> خطأ شبكة: '+e.message}
btn.innerHTML='<i class="fas fa-plug"></i> ربط الحساب';btn.disabled=false;
}
window.addEventListener('load', () => {
loadKeys();
loadUserInfo();
loadDash();
// Reveal Animations
const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' };
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('show');
observer.unobserve(entry.target);
}
});
}, observerOptions);
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
});
</script>
</body>
</html>