admin_dashboard.html 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <!DOCTYPE html>
  2. <html lang="el">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Dashboard - WiSearch</title>
  7. <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  8. <style>
  9. body { background-color: #121212; color: #e0e0e0; font-family: 'Segoe UI', Tahoma, sans-serif; margin: 0; padding: 20px; }
  10. .header { display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid #333; padding-bottom: 15px; margin-bottom: 20px; }
  11. .title { color: #bb86fc; margin: 0; }
  12. .nav-links a { color: #03dac6; text-decoration: none; margin-left: 15px; font-weight: bold; }
  13. .tab-buttons { display: flex; gap: 10px; margin-bottom: 15px; }
  14. .tab-btn { background: #1e1e1e; color: #e0e0e0; border: 1px solid #333; padding: 10px 20px; cursor: pointer; border-radius: 4px; font-weight: bold; }
  15. .tab-btn.active { background: #bb86fc; color: #121212; }
  16. .tab-content { display: none; background: #1e1e1e; padding: 20px; border-radius: 8px; border: 1px solid #333; }
  17. .tab-content.active { display: block; }
  18. h3 { color: #bb86fc; border-bottom: 1px solid #333; padding-bottom: 10px; margin-top:0; }
  19. table { width: 100%; border-collapse: collapse; margin-bottom: 20px; font-size: 14px; }
  20. th, td { padding: 10px; text-align: left; border-bottom: 1px solid #333; }
  21. th { background-color: #2d2d2d; color: #03dac6; }
  22. input, select, textarea { width: 100%; max-width: 500px; padding: 10px; background: #121212; border: 1px solid #333; color: #e0e0e0; border-radius: 4px; margin-bottom: 15px; }
  23. .btn { padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; color: #000; background: #03dac6; }
  24. .btn-danger { background: #cf6679; color: #fff; text-decoration: none; padding: 6px 12px; border-radius: 4px; font-size: 12px; }
  25. .chart-container { display: flex; gap: 20px; justify-content: space-around; flex-wrap: wrap; margin-top:20px; }
  26. .chart-box { background: #2d2d2d; padding: 15px; border-radius: 8px; flex: 1; min-width: 300px; }
  27. </style>
  28. </head>
  29. <body>
  30. <div class="header">
  31. <h1 class="title">WiSearch <span>Panel</span></h1>
  32. <div class="nav-links">
  33. <a href="/">🏠 Αναζήτηση</a>
  34. {% if session.get('user_role') == 'admin' %}
  35. <a href="/admin/logs">📜 Logs</a>
  36. <a href="/admin/users">👥 Χρήστες</a>
  37. {% endif %}
  38. <a href="/logout" style="color: #cf6679;">🚪 Έξοδος</a>
  39. </div>
  40. </div>
  41. <div class="tab-buttons">
  42. <button class="tab-btn active" onclick="openTab('tab-sponsored', this)">📢 Sponsored Links</button>
  43. {% if session.get('user_role') == 'admin' %}
  44. <button class="tab-btn" onclick="openTab('tab-analytics', this)">📊 Γραφήματα</button>
  45. <button class="tab-btn" onclick="openTab('tab-ai', this)">🤖 Cloudflare AI</button>
  46. <button class="tab-btn" onclick="openTab('tab-blacklist', this)">🚫 Blacklist</button>
  47. {% endif %}
  48. </div>
  49. <div id="tab-sponsored" class="tab-content active">
  50. <h3>Οι Διαφημίσεις σας</h3>
  51. <table>
  52. <tr><th>Τίτλος</th><th>URL</th><th>Ενέργειες</th></tr>
  53. {% for link in sponsored %}
  54. <tr>
  55. <td><b>{{ link.title }}</b></td>
  56. <td><a href="{{ link.url }}" style="color: #8ab4f8;">{{ link.url }}</a></td>
  57. <td><a href="/admin/sponsored/delete/{{ link.id }}" class="btn-danger">Διαγραφή</a></td>
  58. </tr>
  59. {% endfor %}
  60. </table>
  61. <form action="/admin/sponsored/add" method="POST">
  62. <input type="text" name="title" required placeholder="Τίτλος"><br>
  63. <input type="text" name="url" required placeholder="URL Προορισμού"><br>
  64. <textarea name="description" rows="2" required placeholder="Περιγραφή"></textarea><br>
  65. <input type="text" name="keywords" required placeholder="Λέξεις κλειδιά"><br>
  66. <button type="submit" class="btn">Προσθήκη</button>
  67. </form>
  68. </div>
  69. {% if session.get('user_role') == 'admin' %}
  70. <div id="tab-analytics" class="tab-content">
  71. <h3>Στατιστικά Συστήματος</h3>
  72. <div class="chart-container">
  73. <div class="chart-box">
  74. <h4 style="text-align:center; color:#e0e0e0;">Top 10 Αναζητήσεις</h4>
  75. <canvas id="searchChart"></canvas>
  76. </div>
  77. <div class="chart-box">
  78. <h4 style="text-align:center; color:#e0e0e0;">Κατανομή Κατηγοριών (AI)</h4>
  79. <canvas id="catChart"></canvas>
  80. </div>
  81. </div>
  82. </div>
  83. <div id="tab-ai" class="tab-content">
  84. <h3>Cloudflare AI Accounts</h3>
  85. <table>
  86. <tr><th>Email/Tag</th><th>Account ID</th><th>Ενέργειες</th></tr>
  87. {% for cred in cf_creds %}
  88. <tr>
  89. <td>{{ cred.comment }}</td><td>{{ cred.account_id[:10] }}...</td>
  90. <td><a href="/admin/cf/delete/{{ loop.index0 }}" class="btn-danger">Διαγραφή</a></td>
  91. </tr>
  92. {% endfor %}
  93. </table>
  94. <form action="/admin/cf/add" method="POST">
  95. <input type="text" name="comment" placeholder="Tag (π.χ. email)"><br>
  96. <input type="text" name="account_id" required placeholder="Account ID"><br>
  97. <input type="password" name="api_token" required placeholder="API Token"><br>
  98. <select name="model">
  99. <option value="@cf/meta/llama-3-8b-instruct">LLaMA-3 8B</option>
  100. <option value="@cf/meta/llama-2-7b-chat-int8">LLaMA-2 7B</option>
  101. <option value="@cf/mistral/mistral-7b-instruct-v0.1">Mistral 7B</option>
  102. </select><br>
  103. <button type="submit" class="btn" style="background:#bb86fc;">Προσθήκη Account</button>
  104. </form>
  105. <hr style="border-color:#333; margin:20px 0;">
  106. <form action="/admin/cf/prompt" method="POST">
  107. <label>AI System Prompt</label>
  108. <textarea name="ai_prompt" rows="6">{{ ai_prompt }}</textarea><br>
  109. <button type="submit" class="btn" style="background:#bb86fc;">Αποθήκευση Prompt</button>
  110. </form>
  111. </div>
  112. <div id="tab-blacklist" class="tab-content">
  113. <h3>Αποκλεισμένα Domains (Blacklist)</h3>
  114. <p style="font-size:13px; color:#9e9e9e;">Τα domains αυτά δεν θα εμφανίζονται ποτέ στην αναζήτηση.</p>
  115. <table>
  116. <tr><th>Domain</th><th>Ενέργειες</th></tr>
  117. {% for b in analytics.blacklists %}
  118. <tr>
  119. <td style="color:#cf6679; font-family:monospace;">{{ b.domain }}</td>
  120. <td><a href="/admin/blacklist/delete/{{ b.id }}" class="btn-danger">Αφαίρεση</a></td>
  121. </tr>
  122. {% endfor %}
  123. </table>
  124. <form action="/admin/blacklist/add" method="POST">
  125. <input type="text" name="domain" required placeholder="π.χ. spam.awmn">
  126. <button type="submit" class="btn" style="background:#cf6679; color:#fff;">Προσθήκη στη Blacklist</button>
  127. </form>
  128. </div>
  129. <script>
  130. function openTab(tabId, btn) {
  131. document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
  132. document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
  133. document.getElementById(tabId).classList.add('active');
  134. btn.classList.add('active');
  135. }
  136. // Γραφήματα
  137. const queries = {{ analytics.top_queries | tojson | safe }};
  138. const categories = {{ analytics.categories | tojson | safe }};
  139. if (queries.length > 0) {
  140. new Chart(document.getElementById('searchChart'), {
  141. type: 'bar',
  142. data: {
  143. labels: queries.map(q => q.search_query),
  144. datasets: [{ label: 'Αναζητήσεις', data: queries.map(q => q.count), backgroundColor: '#03dac6' }]
  145. },
  146. options: { scales: { y: { beginAtZero: true, ticks: {color: '#9e9e9e'} }, x: { ticks: {color: '#9e9e9e'} } }, plugins: { legend: { labels: {color: '#e0e0e0'} } } }
  147. });
  148. }
  149. if (categories.length > 0) {
  150. new Chart(document.getElementById('catChart'), {
  151. type: 'doughnut',
  152. data: {
  153. labels: categories.map(c => c.category),
  154. datasets: [{ data: categories.map(c => c.count), backgroundColor: ['#bb86fc', '#03dac6', '#cf6679', '#ffb86c', '#f1fa8c', '#8be9fd'] }]
  155. },
  156. options: { plugins: { legend: { position: 'right', labels: {color: '#e0e0e0'} } } }
  157. });
  158. }
  159. </script>
  160. {% endif %}
  161. </body>
  162. </html>