CoolFace
Apppublic

Islam-Ash/SVU-Forensics-System

sourceHugging Faceapache-2.0updated 8mo agoView on Hugging Face
0likes
admin.html431 linesDownload Raw Back to templates
1<!DOCTYPE html>2<html lang="ar" dir="rtl">3<head>4    <meta charset="UTF-8">5    <meta name="viewport" content="width=device-width, initial-scale=1.0">6    <title>لوحة المراقبة السيادية | SVU Admin</title>7    <link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;700;900&family=Tajawal:wght@400;500;800&display=swap" rel="stylesheet">8    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">9    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>10    11    <style>12        :root {13            --primary-color: #0f3460;14            --accent-color: #e94560;15            --sidebar-width: 260px;16            --bg-light: #f0f2f5;17            --card-bg: rgba(255, 255, 255, 0.95);18        }19 20        * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Tajawal', sans-serif; }21 22        body { background: var(--bg-light); min-height: 100vh; display: flex; overflow-x: hidden; }23        24        /* Sidebar Styling */25        .admin-sidebar { 26            width: var(--sidebar-width); 27            background: var(--primary-color); 28            color: white; 29            position: fixed; 30            top: 0; 31            right: 0; 32            height: 100vh; 33            display: flex; 34            flex-direction: column; 35            z-index: 1000; 36            box-shadow: -5px 0 15px rgba(0,0,0,0.1);37        }38 39        .sidebar-header { padding: 30px 20px; text-align: center; border-bottom: 1px solid rgba(255,255,255,0.05); }40        .sidebar-header img { width: 45px; margin-bottom: 10px; filter: brightness(0) invert(1); }41        .sidebar-header h2 { font-family: 'Cairo'; font-size: 1.1rem; }42 43        .nav-list { list-style: none; flex: 1; padding-top: 20px; }44        .nav-item { 45            padding: 15px 25px; 46            display: flex; 47            align-items: center; 48            gap: 12px; 49            cursor: pointer; 50            color: rgba(255,255,255,0.6); 51            transition: 0.3s; 52            font-weight: bold;53        }54        .nav-item:hover, .nav-item.active { 55            background: rgba(255,255,255,0.08); 56            color: white; 57            border-right: 4px solid var(--accent-color); 58        }59 60        /* Main Content Area */61        .dashboard-main { 62            flex: 1; 63            margin-right: var(--sidebar-width); 64            padding: 25px; 65            display: flex; 66            flex-direction: column; 67            gap: 25px; 68        }69 70        /* Header & Stats */71        .top-monitor { 72            background: var(--card-bg); 73            padding: 15px 25px; 74            border-radius: 15px; 75            display: flex; 76            justify-content: space-between; 77            align-items: center; 78            box-shadow: 0 4px 10px rgba(0,0,0,0.05); 79        }80 81        .pulse-dot { width: 10px; height: 10px; background: #27ae60; border-radius: 50%; animation: pulse-ring 1.5s infinite; box-shadow: 0 0 0 0 rgba(39, 174, 96, 0.7); }82        @keyframes pulse-ring { 0% { box-shadow: 0 0 0 0 rgba(39, 174, 96, 0.7); } 70% { box-shadow: 0 0 0 10px rgba(39, 174, 96, 0); } 100% { box-shadow: 0 0 0 0 rgba(39, 174, 96, 0); } }83 84        .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; }85        .stat-card { background: white; padding: 25px; border-radius: 15px; text-align: center; box-shadow: 0 4px 15px rgba(0,0,0,0.03); border: 1px solid rgba(0,0,0,0.05); transition: 0.3s; }86        .stat-card:hover { transform: translateY(-5px); }87        .stat-card h3 { font-size: 2.2rem; color: var(--primary-color); margin: 10px 0; font-family: 'Cairo'; }88        .stat-card span { font-size: 0.9rem; color: #7f8c8d; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; }89 90        /* Dashboard Content Layout */91        .content-grid { display: grid; grid-template-columns: 2fr 1.2fr; gap: 25px; }92        93        .card { 94            background: white; 95            padding: 25px; 96            border-radius: 20px; 97            box-shadow: 0 5px 20px rgba(0,0,0,0.04); 98            display: flex; 99            flex-direction: column; 100        }101 102        .card-title { 103            font-family: 'Cairo'; 104            font-size: 1.1rem; 105            margin-bottom: 20px; 106            display: flex; 107            align-items: center; 108            gap: 10px; 109            color: var(--primary-color); 110            font-weight: 800;111            border-bottom: 2px solid #f0f0f0;112            padding-bottom: 15px;113        }114 115        /* Terminal & Live Ticker */116        .terminal { 117            background: #1e1e2e; 118            color: #a6e3a1; 119            padding: 15px; 120            border-radius: 10px; 121            font-family: 'Courier New', monospace; 122            font-size: 0.8rem; 123            height: 180px; 124            overflow-y: auto; 125            margin-top: 20px; 126            border: 1px solid #333;127        }128 129        .live-stream-box { 130            background: #0d1b2a; 131            border-radius: 12px; 132            padding: 10px 20px; 133            overflow: hidden; 134            position: relative; 135            border: 1px solid #1b263b; 136            margin-bottom: 25px;137        }138        .stream-track { display: flex; gap: 50px; animation: scrollLeft 30s linear infinite; white-space: nowrap; }139        .stream-node { color: #51e2f5; font-family: monospace; font-size: 0.85rem; font-weight: bold; }140        @keyframes scrollLeft { from { transform: translateX(-100%); } to { transform: translateX(100%); } }141 142        /* Queue Items (Human-in-the-Loop) */143        .queue-container { flex: 1; overflow-y: auto; padding-right: 5px; max-height: 500px; }144        .queue-item { 145            background: #fff; 146            border: 1px solid #eee; 147            border-radius: 12px; 148            padding: 15px; 149            margin-bottom: 15px; 150            position: relative;151            transition: 0.2s;152        }153        .queue-item:hover { border-color: var(--primary-color); }154        155        .queue-header { display: flex; justify-content: space-between; margin-bottom: 10px; font-size: 0.8rem; color: #e67e22; font-weight: bold; }156        .queue-img { width: 100%; height: 160px; object-fit: cover; border-radius: 8px; margin-bottom: 12px; background: #f9f9f9; }157        158        .btn-group { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }159        .btn { padding: 10px; border: none; border-radius: 8px; cursor: pointer; font-weight: bold; font-size: 0.9rem; color: white; transition: 0.2s; display: flex; align-items: center; justify-content: center; gap: 5px; }160        .btn:hover { opacity: 0.9; transform: scale(1.02); }161        .btn-approve { background: #27ae60; }162        .btn-reject { background: #e74c3c; }163        .btn:disabled { background: #bdc3c7; cursor: not-allowed; transform: none; }164 165        /* Scrollbar */166        ::-webkit-scrollbar { width: 8px; }167        ::-webkit-scrollbar-track { background: #f1f1f1; }168        ::-webkit-scrollbar-thumb { background: #cbd5e0; border-radius: 4px; }169        ::-webkit-scrollbar-thumb:hover { background: #a0aec0; }170 171        @media (max-width: 1100px) { .content-grid { grid-template-columns: 1fr; } .admin-sidebar { width: 70px; } .dashboard-main { margin-right: 70px; } }172    </style>173</head>174<body>175 176    <!-- Sidebar -->177    <aside class="admin-sidebar">178        <div class="sidebar-header">179            <img src="https://cdn-icons-png.flaticon.com/512/2092/2092663.png" alt="Logo">180            <h2>لوحة الإدارة</h2>181        </div>182        <ul class="nav-list">183            <li class="nav-item active"><i class="fas fa-th-large"></i> <span>الرئيسية</span></li>184            <li class="nav-item" onclick="window.location.href='/'"><i class="fas fa-user-graduate"></i> <span>صفحة الطالب</span></li>185            <li class="nav-item"><i class="fas fa-chart-pie"></i> <span>التقارير والبيانات</span></li>186            <li class="nav-item"><i class="fas fa-cogs"></i> <span>إعدادات النموذج</span></li>187        </ul>188        <div class="nav-item" style="margin-top: auto; border-top: 1px solid rgba(255,255,255,0.1); color: #ff7675;">189            <i class="fas fa-sign-out-alt"></i> <span>تسجيل خروج</span>190        </div>191    </aside>192 193    <!-- Main Content -->194    <main class="dashboard-main">195        196        <!-- Top Header -->197        <header class="top-monitor">198            <div class="status-badge" style="display: flex; align-items: center; gap: 10px; font-size: 0.9rem;">199                <div class="pulse-dot"></div>200                <span>حالة النظام: نشط (Active)</span>201                <span style="color: #95a5a6; margin: 0 10px;">|</span>202                <span>التدخل البشري: مفعّل</span>203            </div>204            <div id="clock" style="font-family: 'Courier New', monospace; font-weight: bold; color: var(--primary-color);">00:00:00</div>205        </header>206 207        <!-- Live Stream Logs -->208        <div class="live-stream-box">209            <div class="stream-track">210                <div class="stream-node" id="log-stream-1">[SYSTEM] Initializing Sovereign V8 Core...</div>211                <div class="stream-node" id="log-stream-2" style="color: #f1c40f;">[MONITOR] Watching for low-confidence inputs...</div>212                <div class="stream-node" id="log-stream-3">[DB] Connected to local storage successfully.</div>213            </div>214        </div>215 216        <!-- Statistics Grid -->217        <section class="stats-grid">218            <div class="stat-card">219                <span>الطلبات الكلية</span>220                <h3 id="stat-total">0</h3>221            </div>222            <div class="stat-card">223                <span style="color: #27ae60;">نسبة الدقة</span>224                <h3 id="stat-accuracy" style="color: #27ae60;">0%</h3>225            </div>226            <div class="stat-card">227                <span>طلبات مقبولة</span>228                <h3 id="stat-accepted" style="color: #3498db;">0</h3>229            </div>230            <div class="stat-card">231                <span style="color: #e94560;">طلبات مشبوهة</span>232                <h3 id="stat-suspicious" style="color: #e94560;">0</h3>233            </div>234        </section>235 236        <!-- Main Dashboard Grid -->237        <section class="content-grid">238            239            <!-- Left: Charts & Logs -->240            <div class="card">241                <div class="card-title">242                    <i class="fas fa-chart-line"></i>243                    <span>أداء النموذج في الوقت الفعلي</span>244                </div>245                <div style="height: 280px; width: 100%;">246                    <canvas id="pulseChart"></canvas>247                </div>248                <div class="terminal" id="terminal">249                    <div>> System Ready.</div>250                    <div>> Waiting for stream...</div>251                </div>252            </div>253 254            <!-- Right: Human Audit Queue -->255            <div class="card">256                <div class="card-title">257                    <i class="fas fa-user-shield"></i>258                    <span>قائمة الانتظار للتدقيق البشري</span>259                </div>260                <div style="margin-bottom: 10px; font-size: 0.8rem; color: #7f8c8d;">261                    هذه الصور شك فيها النظام وتحتاج تأكيد بشري لتدريب الموديل.262                </div>263                <div class="queue-container" id="queueList">264                    <!-- سيتم إضافة العناصر هنا بواسطة JavaScript -->265                    <div style="text-align: center; padding: 20px; color: #bdc3c7;">266                        <i class="fas fa-check-circle fa-2x"></i>267                        <p>لا توجد حالات مشبوهة حالياً</p>268                    </div>269                </div>270            </div>271 272        </section>273 274    </main>275 276    <script>277        // Clock278        setInterval(() => {279            document.getElementById('clock').innerText = new Date().toLocaleTimeString('ar-EG');280        }, 1000);281 282        // --- إعداد الرسم البياني (Chart.js) ---283        const ctx = document.getElementById('pulseChart').getContext('2d');284        let pulseChart = new Chart(ctx, {285            type: 'line',286            data: {287                labels: Array(20).fill(''), 288                datasets: [{289                    label: 'Efficiency',290                    data: Array(20).fill(99),291                    borderColor: '#0f3460',292                    backgroundColor: 'rgba(15, 52, 96, 0.05)',293                    borderWidth: 2,294                    tension: 0.4,295                    fill: true,296                    pointRadius: 0297                }]298            },299            options: {300                responsive: true,301                maintainAspectRatio: false,302                animation: { duration: 0 }, // Disable animation for real-time performance303                plugins: { legend: { display: false } },304                scales: { 305                    x: { display: false }, 306                    y: { 307                        min: 80, max: 100, 308                        grid: { color: '#f0f0f0' } 309                    } 310                }311            }312        });313 314        // --- الاتصال بالباك إند وجلب البيانات ---315        316        // 1. جلب الإحصائيات (Stats)317        async function fetchLiveStats() {318            try {319                const res = await fetch('/api/stats');320                const data = await res.json();321 322                // تحديث الأرقام323                document.getElementById('stat-total').innerText = data.total_requests;324                document.getElementById('stat-accuracy').innerText = data.accuracy + '%';325                document.getElementById('stat-accepted').innerText = data.accepted_count;326                document.getElementById('stat-suspicious').innerText = data.suspicious_count;327 328                // تحديث الشارت329                pulseChart.data.datasets[0].data.shift();330                pulseChart.data.datasets[0].data.push(data.accuracy);331                pulseChart.update();332 333                // تحديث الـ Terminal334                if(data.logs && data.logs.length > 0) {335                    const term = document.getElementById('terminal');336                    const lastLog = data.logs[data.logs.length - 1];337                    const div = document.createElement('div');338                    div.innerText = `> ${lastLog}`;339                    div.style.color = '#fff';340                    div.style.marginBottom = '2px';341                    term.appendChild(div);342                    term.scrollTop = term.scrollHeight;343                }344 345                // تحديث شريط الأخبار العلوية346                if(data.logs.length > 0) {347                    const lastLog = data.logs[data.logs.length - 1];348                    document.getElementById('log-stream-1').innerText = `[LIVE] ${lastLog}`;349                }350 351            } catch (e) { console.log("Connection Pending..."); }352        }353 354        // 2. جلب قائمة المشبوهين (Queue)355        async function fetchQueue() {356            try {357                const res = await fetch('/api/queue');358                const queue = await res.json();359                const container = document.getElementById('queueList');360                361                container.innerHTML = ''; // تفريغ القائمة الحالية362 363                if (queue.length === 0) {364                    container.innerHTML = `365                        <div style="text-align: center; padding: 20px; color: #27ae60;">366                            <i class="fas fa-check-circle fa-2x"></i>367                            <p>النظام يعمل بكفاءة، لا توجد حالات مشبوهة</p>368                        </div>`;369                    return;370                }371 372                // عرض كل عنصر في القائمة373                queue.forEach(item => {374                    const div = document.createElement('div');375                    div.className = 'queue-item';376                    // استخدام صورة عشوائية للتجربة لأن الباك إند محاكاة377                    const imgSrc = item.img_data || `https://picsum.photos/seed/${item.id}/300/200.jpg`;378                    379                    div.innerHTML = `380                        <div class="queue-header">381                            <span><i class="fas fa-clock"></i> ${item.timestamp}</span>382                            <span><i class="fas fa-user"></i> ${item.name}</span>383                        </div>384                        <img src="${imgSrc}" class="queue-img" alt="Suspicious Document">385                        <div class="btn-group">386                            <button class="btn btn-approve" onclick="handleAudit(${item.id}, 'approve')">387                                <i class="fas fa-check"></i> أصلي388                            </button>389                            <button class="btn btn-reject" onclick="handleAudit(${item.id}, 'reject')">390                                <i class="fas fa-times"></i> مزور391                            </button>392                        </div>393                    `;394                    container.appendChild(div);395                });396 397            } catch (e) { console.log("Queue Fetch Error", e); }398        }399 400        // 3. إرسال قرار التدقيق (Audit Action)401        async function handleAudit(id, action) {402            try {403                const res = await fetch('/api/audit/fix', {404                    method: 'POST',405                    headers: { 'Content-Type': 'application/json' },406                    body: JSON.stringify({ action: action, id: id })407                });408                409                // تحديث فوري للواجهة (إزالة العنصر)410                const btn = event.currentTarget;411                btn.parentElement.parentElement.remove();412                413                // إظهار رسالة بسيطة414                alert(`تم تسجيل القرار: ${action === 'approve' ? 'أصلي' : 'مزور'}`);415 416            } catch (e) {417                alert('فشل إرسال القرار');418            }419        }420 421        // تشغيل التحديثات التلقائية422        setInterval(fetchLiveStats, 2000); // كل ثانيتين للإحصائيات423        setInterval(fetchQueue, 3000);    // كل 3 ثواني للقائمة424 425        // استدعاء فوري عند التحميل426        fetchLiveStats();427        fetchQueue();428 429    </script>430</body>431</html>