| <!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@400;600;700;800&display=swap" rel="stylesheet"> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"> |
| <link rel="stylesheet" href="/theme.css"> |
| <style> |
| .reveal{opacity:0;transform:translateY(20px);transition:all .6s cubic-bezier(.16,1,.3,1)} |
| .reveal.show{opacity:1;transform:translateY(0)} |
| 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} |
| .wrap{max-width:1200px;margin:0 auto;padding:40px 24px} |
| |
| .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} |
|
|
| /* Header */ |
| .page-header{margin-bottom:0;text-align:center;position:relative} |
| .header-card{background:var(--bg-elevated);border:1px solid var(--border);border-top:3px solid var(--purple);border-radius:20px;padding:40px;backdrop-filter:blur(16px);box-shadow:0 10px 40px rgba(0,0,0,0.3);position:relative;overflow:hidden;margin-bottom:32px} |
| .header-card::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at top right,rgba(168,85,247,0.1),transparent);pointer-events:none} |
| |
| .label{display:inline-flex;align-items:center;gap:6px;background:rgba(168,85,247,0.1);color:var(--purple);padding:6px 16px;border-radius:100px;font-size:12px;font-weight:700;margin-bottom:16px;border:1px solid rgba(168,85,247,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;line-height:1.6} |
|
|
| /* Stats */ |
| .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.red:hover{border-color:rgba(239,68,68,.4)} |
| .kpi.yel:hover{border-color:rgba(251,191,36,.4)} |
| .kpi.pur:hover{border-color:rgba(168,85,247,.4)} |
| .kpi-lbl{font-size:13px;color:var(--muted);font-weight:600;margin-bottom:8px} |
| .kpi-val{font-size:36px;font-weight:900;background:var(--hero-grad);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:4px} |
| .kpi-sub{font-size:12px;color:var(--dim)} |
|
|
| /* Controls Bar */ |
| .controls-bar{display:flex;gap:12px;align-items:center;margin-bottom:32px;flex-wrap:wrap;background:var(--bg-elevated);border:1px solid var(--border);padding:16px;border-radius:16px;backdrop-filter:blur(10px)} |
| |
| .filter-btn{background:transparent;border:1px solid transparent;color:var(--muted);padding:10px 24px;border-radius:100px;cursor:pointer;font-family:'Cairo',sans-serif;font-weight:700;transition:all 0.3s;font-size:13px;display:flex;align-items:center;gap:6px} |
| .filter-btn.active{background:var(--blue);color:#fff;border-color:var(--blue);box-shadow:0 6px 16px rgba(59,130,246,0.3)} |
| .filter-btn:hover:not(.active){background:rgba(255,255,255,0.05);color:#fff;border-color:rgba(255,255,255,0.1)} |
|
|
| .btn-secondary{background:rgba(255,255,255,.04);border:1px solid var(--border);color:#fff;padding:12px 24px;border-radius:100px;font-weight:700;font-size:13px;cursor:pointer;font-family:'Cairo',sans-serif;transition:.3s;display:inline-flex;align-items:center;gap:6px} |
| .btn-secondary:hover{background:rgba(255,255,255,.09);transform:scale(1.05)} |
|
|
| /* Recommendation Cards */ |
| .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(500px,1fr));gap:24px;margin-bottom:60px} |
| .rec-item{background:linear-gradient(135deg,rgba(15,20,25,0.95),rgba(30,41,59,0.85));border:1px solid rgba(255,255,255,0.08);border-right:3px solid transparent;border-radius:16px;padding:28px;transition:all 0.4s cubic-bezier(.16,1,.3,1);display:flex;flex-direction:column;position:relative;overflow:hidden;backdrop-filter:blur(10px)} |
| .rec-item::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at top right,rgba(255,255,255,0.02),transparent);pointer-events:none;transition:all 0.4s} |
| .rec-item:hover{transform:translateY(-6px);box-shadow:0 20px 40px rgba(0,0,0,0.3)} |
| |
| .rec-item.priority-high{border-right-color:var(--red)} |
| .rec-item.priority-high:hover{border-color:rgba(239,68,68,0.5);box-shadow:0 20px 40px rgba(239,68,68,0.2)} |
| .rec-item.priority-medium{border-right-color:var(--gold)} |
| .rec-item.priority-medium:hover{border-color:rgba(251,191,36,0.5);box-shadow:0 20px 40px rgba(251,191,36,0.2)} |
| .rec-item.priority-low{border-right-color:var(--emerald)} |
| .rec-item.priority-low:hover{border-color:rgba(16,185,129,0.5);box-shadow:0 20px 40px rgba(16,185,129,0.2)} |
|
|
| .rec-head-row{display:flex;gap:16px;align-items:flex-start;margin-bottom:12px;position:relative;z-index:1} |
| .rec-number{display:flex;align-items:center;justify-content:center;width:44px;height:44px;background:var(--bg-elevated);border:1px solid var(--border);color:var(--text);font-weight:800;border-radius:12px;font-size:18px;flex-shrink:0;box-shadow:0 4px 12px rgba(0,0,0,0.2)} |
| .rec-content{flex:1} |
| .rec-title{font-weight:800;color:#fff;margin-bottom:6px;font-size:18px;line-height:1.4} |
| .rec-desc{font-size:14px;color:var(--muted);margin-bottom:20px;line-height:1.6} |
| |
| .rec-meta{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:20px} |
| .badge{padding:6px 12px;border-radius:8px;font-weight:700;font-size:12px;border:1px solid transparent;display:inline-flex;align-items:center;gap:6px} |
| .badge-high{background:rgba(239,68,68,0.15);color:var(--red);border-color:rgba(239,68,68,0.3)} |
| .badge-medium{background:rgba(251,191,36,0.15);color:var(--gold);border-color:rgba(251,191,36,0.3)} |
| .badge-low{background:rgba(16,185,129,0.15);color:var(--emerald);border-color:rgba(16,185,129,0.3)} |
| .badge-impact{background:rgba(59,130,246,0.15);color:var(--blue);border-color:rgba(59,130,246,0.3)} |
| .badge-time{background:rgba(168,85,247,0.15);color:var(--purple);border-color:rgba(168,85,247,0.3)} |
|
|
| .progress-section{position:relative;z-index:1;margin-bottom:20px} |
| .progress-label{font-size:12px;color:var(--muted);margin-bottom:8px;display:flex;justify-content:space-between;font-weight:600} |
| .progress-bar{width:100%;height:8px;background:rgba(0,0,0,0.3);border-radius:4px;overflow:hidden;border:1px solid rgba(255,255,255,0.05)} |
| .progress-fill{height:100%;border-radius:4px;transition:width 1s cubic-bezier(.16,1,.3,1)} |
|
|
| .btn-action{background:var(--accent-grad);color:#fff;border:none;padding:12px 24px;border-radius:10px;font-weight:800;cursor:pointer;font-size:13px;font-family:'Cairo',sans-serif;transition:.3s;display:inline-flex;align-items:center;justify-content:center;gap:8px;width:100%} |
| .btn-action:hover{transform:translateY(-2px);box-shadow:0 12px 32px rgba(59,130,246,.4)} |
|
|
| .empty-state{text-align:center;padding:80px 20px;background:var(--bg-elevated);border:1px dashed var(--border);border-radius:20px;grid-column:1/-1} |
| .empty-state-icon{font-size:54px;margin-bottom:16px;opacity:0.8} |
| .empty-state-text{color:var(--muted);font-size:15px;font-weight:600;line-height:1.6} |
|
|
| .reveal{opacity:0;transform:translateY(30px);transition:all .7s cubic-bezier(.16,1,.3,1)} |
| .reveal.show{opacity:1;transform:translateY(0)} |
|
|
| @media(max-width:900px){ |
| .wrap{padding:20px} |
| .nav-inner{padding:0 20px} |
| .page-title{font-size:36px} |
| .controls-bar{flex-direction:column;align-items:stretch} |
| .filter-btn{justify-content:center} |
| .grid{grid-template-columns:1fr} |
| } |
| </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 active" href="/recommendations.html">التوصيات</a> |
| <a class="nav-link" 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"> |
| <div class="header-card reveal"> |
| <div class="page-header"> |
| <div class="label"><i class="fas fa-lightbulb"></i> التوصيات الذكية</div> |
| <h1 class="page-title">التوصيات الاستراتيجية</h1> |
| <p class="page-subtitle">توصيات مرتبة حسب الأولوية وتطبيقات عملية بخطوات مبنية على الذكاء الاصطناعي لتحسين ظهورك في محركات الذكاء الاصطناعي</p> |
| </div> |
| </div> |
|
|
| <div class="kpis reveal" style="animation-delay:0.1s"> |
| <div class="kpi blue"> |
| <div class="kpi-lbl"><i class="fas fa-tasks" style="color:var(--blue);margin-left:6px"></i>إجمالي التوصيات</div> |
| <div class="kpi-val" id="totalRec">0</div> |
| <div class="kpi-sub">تطبيقات معلقة</div> |
| </div> |
| <div class="kpi red"> |
| <div class="kpi-lbl"><i class="fas fa-exclamation-circle" style="color:var(--red);margin-left:6px"></i>عالية الأولوية</div> |
| <div class="kpi-val" id="highPriority" style="background:linear-gradient(135deg,#ef4444,#f97316);-webkit-background-clip:text;background-clip:text;color:transparent">0</div> |
| <div class="kpi-sub">تتطلب تنفيذ عاجل</div> |
| </div> |
| <div class="kpi yel"> |
| <div class="kpi-lbl"><i class="fas fa-chart-line" style="color:var(--gold);margin-left:6px"></i>% محتمل الكسب</div> |
| <div class="kpi-val" id="potentialGain" style="background:var(--gold-grad);-webkit-background-clip:text;background-clip:text;color:transparent">0</div> |
| <div class="kpi-sub">زيادة الرؤية المقدرة</div> |
| </div> |
| <div class="kpi pur"> |
| <div class="kpi-lbl"><i class="fas fa-clock" style="color:var(--purple);margin-left:6px"></i>أيام التنفيذ</div> |
| <div class="kpi-val" id="estimatedTime">0</div> |
| <div class="kpi-sub">متوسط وقت الإنجاز</div> |
| </div> |
| </div> |
|
|
| <div class="controls-bar reveal" style="animation-delay:0.2s"> |
| <div style="display:flex;gap:4px;flex-wrap:wrap"> |
| <button class="filter-btn active" data-priority="all" onclick="filterByPriority('all', event)"><i class="fas fa-layer-group"></i> كل التوصيات</button> |
| <button class="filter-btn" data-priority="high" onclick="filterByPriority('high', event)"><i class="fas fa-circle" style="color:var(--red);font-size:10px"></i> عالية</button> |
| <button class="filter-btn" data-priority="medium" onclick="filterByPriority('medium', event)"><i class="fas fa-circle" style="color:var(--gold);font-size:10px"></i> متوسطة</button> |
| <button class="filter-btn" data-priority="low" onclick="filterByPriority('low', event)"><i class="fas fa-circle" style="color:var(--emerald);font-size:10px"></i> منخفضة</button> |
| </div> |
| <div style="flex:1"></div> |
| <div style="display:flex;gap:12px"> |
| <button class="btn-secondary" onclick="loadRecommendations()"><i class="fas fa-sync-alt"></i> تحديث</button> |
| <button class="btn-secondary" onclick="location.href='/portal.html'"><i class="fas fa-arrow-left"></i> العودة</button> |
| </div> |
| </div> |
|
|
| <div id="recContainer" class="grid"> |
| <div class="empty-state reveal" style="animation-delay:0.3s"> |
| <div class="empty-state-icon"><i class="fas fa-circle-notch fa-spin" style="color:var(--blue)"></i></div> |
| <p class="empty-state-text">جارٍ تحليل بيانتك وتوليد التوصيات الذكية...</p> |
| </div> |
| </div> |
| </div> |
|
|
| <section style="padding:40px 0;text-align:center;border-top:1px solid var(--border);margin-top:40px"> |
| <p style="color:var(--dim);font-size:13px;font-weight:600">© 2025 محرك — منصة SEO & GEO بالذكاء الاصطناعي</p> |
| </section> |
|
|
| <script> |
| const token = localStorage.getItem('token'); |
| let allRecommendations = []; |
| let currentPriority = 'all'; |
| |
| |
| |
| 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); } |
| } |
| |
| async function loadRecommendations() { |
| const container = document.getElementById('recContainer'); |
| container.innerHTML = '<div class="empty-state"><div class="empty-state-icon"><i class="fas fa-circle-notch fa-spin" style="color:var(--blue)"></i></div><p class="empty-state-text">جارٍ مراجعة مصادر البيانات وتحليل التوصيات...</p></div>'; |
| try { |
| const jobsRes = await fetch('http://localhost:8001/api/jobs', { headers: { 'Authorization': `Bearer ${token}` } }); |
| const jobsData = await jobsRes.json(); |
| const jobs = jobsData.jobs || []; |
| const params = new URLSearchParams(location.search); |
| const jobIdParam = params.get('job_id') ? parseInt(params.get('job_id')) : null; |
| const latestCompleted = jobIdParam |
| ? jobs.find(j => j.id === jobIdParam) |
| : jobs.find(j => j.status === 'completed' && j.result_path); |
| |
| const body = { api_keys: { groq: localStorage.getItem('geo_groq_key'), openai: localStorage.getItem('geo_openai_key') } }; |
| if (latestCompleted) body.job_id = latestCompleted.id; |
| |
| const res = await fetch('http://localhost:8001/api/recommendations', { |
| method: 'POST', |
| headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, |
| body: JSON.stringify(body) |
| }); |
| const data = await res.json(); |
| |
| if (!data.ok) { |
| container.innerHTML = `<div class="empty-state"><div class="empty-state-icon"><i class="fas fa-exclamation-triangle" style="color:var(--orange)"></i></div><p class="empty-state-text" style="color:var(--text);font-size:16px">${data.error || 'خطأ في تحميل التوصيات'}</p><p style="color:var(--muted);font-size:13px;margin-top:12px">يجب تحليل موقع أولاً من <a href="/jobs.html" style="color:var(--blue);text-decoration:underline">صفحة المهام</a></p></div>`; |
| return; |
| } |
| |
| const recs = data.recommendations || {}; |
| allRecommendations = []; |
| |
| const rawActions = Array.isArray(recs) ? recs : (recs.actions || []); |
| const perPage = recs.per_page || []; |
| |
| rawActions.forEach((a, i) => { |
| const text = typeof a === 'object' ? (a.text || a.title || JSON.stringify(a)) : a; |
| const priority = typeof a === 'object' ? (a.priority || 'medium') : 'medium'; |
| allRecommendations.push({ title: text, desc: typeof a === 'object' ? (a.description || a.why || '') : '', priority: priority.toLowerCase(), impact: typeof a === 'object' ? (a.impact || 20) : 20, days: typeof a === 'object' ? (a.days || 3) : 3, idx: i }); |
| }); |
| |
| perPage.forEach((p, i) => { |
| const issues = (p.issues || []).join(' • '); |
| const suggestions = (p.suggestions || []).map(s => typeof s === 'object' ? s.label || s.rewrite || '' : s).join(' | '); |
| allRecommendations.push({ title: `صفحة: ${p.title || p.url}`, desc: `${issues}${suggestions ? ' — ' + suggestions.substring(0, 120) : ''}`, priority: (p.issues && p.issues.length > 2) ? 'high' : 'medium', impact: 15, days: 2, idx: rawActions.length + i }); |
| }); |
| |
| if (allRecommendations.length === 0) { |
| container.innerHTML = '<div class="empty-state"><div class="empty-state-icon"><i class="fas fa-check-circle" style="color:var(--emerald)"></i></div><p class="empty-state-text">موقعك في حالة جيدة جداً، لا توجد توصيات حالياً.</p></div>'; |
| return; |
| } |
| |
| updateStats(); |
| |
| filterByPriority('all'); |
| } catch (e) { |
| console.error(e); |
| document.getElementById('recContainer').innerHTML = `<div class="empty-state"><div class="empty-state-icon"><i class="fas fa-times-circle" style="color:var(--red)"></i></div><p class="empty-state-text">خطأ أو فصل في الاتصال: ${e.message}</p></div>`; |
| } |
| } |
| |
| function updateStats() { |
| const high = allRecommendations.filter(r => r.priority === 'high').length; |
| const totalGain = Math.round(allRecommendations.reduce((sum, r) => sum + r.impact, 0) / allRecommendations.length) || 0; |
| const maxDays = allRecommendations.length > 0 ? Math.max(...allRecommendations.map(r => r.days)) : 0; |
| |
| document.getElementById('totalRec').textContent = allRecommendations.length; |
| document.getElementById('highPriority').textContent = high; |
| document.getElementById('potentialGain').textContent = totalGain; |
| document.getElementById('estimatedTime').textContent = maxDays; |
| } |
| |
| function getPriorityClass(priority) { |
| if(priority === 'high') return 'badge-high'; |
| if(priority === 'medium') return 'badge-medium'; |
| return 'badge-low'; |
| } |
| |
| function getPriorityIcon(priority) { |
| if(priority === 'high') return '<i class="fas fa-circle" style="font-size:10px"></i>'; |
| if(priority === 'medium') return '<i class="fas fa-circle" style="font-size:10px"></i>'; |
| return '<i class="fas fa-circle" style="font-size:10px"></i>'; |
| } |
| |
| function filterByPriority(priority, event) { |
| currentPriority = priority; |
| document.querySelectorAll('.filter-btn').forEach(btn => btn.classList.remove('active')); |
| |
| if (event && event.currentTarget) { |
| event.currentTarget.classList.add('active'); |
| } else { |
| |
| const btn = document.querySelector(`.filter-btn[data-priority="${priority}"]`); |
| if(btn) btn.classList.add('active'); |
| } |
| displayRecommendations(); |
| } |
| |
| function displayRecommendations() { |
| let filtered = allRecommendations; |
| |
| if (currentPriority !== 'all') { |
| filtered = filtered.filter(r => r.priority === currentPriority); |
| } |
| |
| if (filtered.length === 0) { |
| document.getElementById('recContainer').innerHTML = `<div class="empty-state"><div class="empty-state-icon"><i class="fas fa-check-double" style="color:var(--dim)"></i></div><p class="empty-state-text">لا توجد توصيات مطابقة لهذه الفئة</p></div>`; |
| return; |
| } |
| |
| let html = ''; |
| filtered.forEach((rec, idx) => { |
| const priorityLabel = rec.priority === 'high' ? 'عالية' : rec.priority === 'medium' ? 'متوسطة' : 'منخفضة'; |
| const pColor = rec.priority === 'high' ? 'var(--red)' : rec.priority === 'medium' ? 'var(--gold)' : 'var(--emerald)'; |
| const progressGradient = rec.priority === 'high' ? 'linear-gradient(90deg, var(--red), var(--orange))' : rec.priority === 'medium' ? 'var(--gold-grad)' : 'linear-gradient(90deg, var(--emerald), var(--cyan))'; |
| |
| html += ` |
| <div class="rec-item priority-${rec.priority} reveal" style="animation-delay:${(idx%10) * 0.05}s"> |
| <div class="rec-head-row"> |
| <div class="rec-number" style="box-shadow:inset 0 0 0 1px ${pColor}33">${rec.idx + 1}</div> |
| <div class="rec-content"> |
| <div class="rec-title">${rec.title}</div> |
| <div class="rec-desc">${rec.desc}</div> |
| </div> |
| </div> |
| |
| <div class="rec-meta"> |
| <span class="badge ${getPriorityClass(rec.priority)}">${getPriorityIcon(rec.priority)} أولوية ${priorityLabel}</span> |
| <span class="badge badge-impact"><i class="fas fa-chart-line"></i> ${rec.impact}% احتمال كسب</span> |
| <span class="badge badge-time"><i class="far fa-clock"></i> ${rec.days} أيام تنفيذ</span> |
| </div> |
| |
| <div class="progress-section"> |
| <div class="progress-label"> |
| <span><i class="fas fa-tachometer-alt" style="margin-left:4px"></i> درجة التأثير:</span> |
| <span>${rec.impact}%</span> |
| </div> |
| <div class="progress-bar"> |
| <div class="progress-fill" style="width:${rec.impact}%;background:${progressGradient}"></div> |
| </div> |
| </div> |
| |
| <button class="btn-action" onclick="implementRecommendation('${encodeURIComponent(rec.title)}')"><i class="fas fa-cogs"></i> التطبيق والدراسة</button> |
| </div> |
| `; |
| }); |
| |
| document.getElementById('recContainer').innerHTML = html; |
| revealOnScroll(); |
| } |
| |
| function implementRecommendation(encodedTitle) { |
| window.location.href = '/content_v2.html'; |
| } |
| |
| function logout() { |
| localStorage.removeItem('token'); |
| window.location.href = '/'; |
| } |
| |
| function revealOnScroll() { |
| const reveals = document.querySelectorAll('.reveal'); |
| reveals.forEach(el => { |
| const windowHeight = window.innerHeight; |
| const elementTop = el.getBoundingClientRect().top; |
| if (elementTop < windowHeight - 50) { |
| el.classList.add('show'); |
| } |
| }); |
| } |
| |
| window.addEventListener('scroll', revealOnScroll); |
| window.addEventListener('load', () => { |
| revealOnScroll(); |
| loadUserInfo(); |
| loadRecommendations(); |
| }); |
| </script> |
| </body> |
| </html> |
|
|