layout.html 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>BIND9 Pro Command Center</title>
  7. <script src="https://cdn.tailwindcss.com"></script>
  8. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  9. <style>
  10. body { background-color: #0b0e14; color: #ffffff; }
  11. .custom-scroll::-webkit-scrollbar { width: 6px; height: 6px; }
  12. .custom-scroll::-webkit-scrollbar-track { background: transparent; }
  13. .custom-scroll::-webkit-scrollbar-thumb { background: #374151; border-radius: 10px; }
  14. .custom-scroll::-webkit-scrollbar-thumb:hover { background: #4b5563; }
  15. /* Αποτρέπει το text selection στα διπλά κλικ */
  16. .no-select { user-select: none; }
  17. </style>
  18. </head>
  19. <body class="flex h-screen overflow-hidden font-sans">
  20. <aside class="w-64 bg-[#12161f] border-r border-gray-800 flex flex-col shadow-2xl z-20">
  21. <div class="p-6 border-b border-gray-800 flex items-center justify-center">
  22. <h1 class="text-3xl font-black text-blue-500 italic tracking-tighter">BIND<span class="text-white">PRO</span></h1>
  23. </div>
  24. <div class="mt-auto pt-6 border-t border-gray-800">
  25. <div class="flex items-center justify-center gap-2 text-gray-500 opacity-50 hover:opacity-100 transition-opacity">
  26. <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
  27. <span class="text-[9px] font-mono font-black uppercase tracking-widest">{{ app_version }}</span>
  28. </div>
  29. </div>
  30. <nav class="flex-1 p-4 space-y-2 overflow-y-auto custom-scroll mt-4">
  31. <p class="px-4 text-[10px] font-black text-gray-600 uppercase tracking-widest mb-2">Main Menu</p>
  32. <a href="/" class="flex items-center gap-3 px-4 py-3 text-sm font-bold text-gray-400 rounded-xl hover:bg-blue-600 hover:text-white transition group">
  33. <svg class="w-5 h-5 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"></path></svg>
  34. Dashboard
  35. </a>
  36. {% if session.get('role') == 'admin' %}
  37. <a href="/analytics" class="flex items-center gap-3 px-4 py-3 text-sm font-bold text-gray-400 rounded-xl hover:bg-purple-600 hover:text-white transition group">
  38. <svg class="w-5 h-5 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path></svg>
  39. Analytics
  40. </a>
  41. <a href="/settings" class="flex items-center gap-3 px-4 py-3 text-sm font-bold text-gray-400 rounded-xl hover:bg-gray-700 hover:text-white transition group">
  42. <svg class="w-5 h-5 group-hover:rotate-90 transition-transform duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
  43. Settings
  44. </a>
  45. <a href="/users" class="flex items-center gap-3 px-4 py-3 text-sm font-bold text-gray-400 rounded-xl hover:bg-gray-700 hover:text-white transition group">
  46. <svg class="w-5 h-5 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>
  47. Users
  48. </a>
  49. <a href="/adblock" class="flex items-center gap-3 px-4 py-3 text-sm font-bold text-gray-400 rounded-xl hover:bg-gray-700 hover:text-white transition group">
  50. <svg class="w-5 h-5 group-hover:scale-110 transition-transform group-hover:text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  51. <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.618 5.984A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016zM12 9v2m0 4h.01"></path>
  52. </svg>
  53. AdBlock Engine
  54. </a>
  55. <a href="/adanalytics" class="flex items-center gap-3 px-4 py-3 text-sm font-bold text-gray-400 rounded-xl hover:bg-gray-700 hover:text-white transition group">
  56. <svg class="w-5 h-5 group-hover:scale-110 transition-transform group-hover:text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  57. <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
  58. </svg>
  59. AdBlock Analytics
  60. </a>
  61. <a href="/cluster" class="flex items-center gap-3 px-4 py-3 text-sm font-bold text-gray-400 rounded-xl hover:bg-blue-600 hover:text-white transition group">
  62. <svg class="w-5 h-5 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"></path></svg>
  63. Cluster Nodes
  64. </a>
  65. <a href="/profile" class="flex items-center gap-3 px-4 py-2 text-gray-400 hover:text-white transition">
  66. <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path></svg>
  67. <span class="text-xs font-black uppercase tracking-widest">My API</span>
  68. </a>
  69. {% endif %}
  70. </nav>
  71. <div class="p-6 border-t border-gray-800 bg-gray-900/30">
  72. <div class="flex items-center justify-between">
  73. <div>
  74. <p class="text-[10px] text-gray-500 uppercase font-black tracking-widest">Logged in as</p>
  75. <p class="text-sm font-bold text-white">{{ session.get('username') }}</p>
  76. </div>
  77. <a href="/logout" title="Logout" class="bg-red-500/10 text-red-500 hover:bg-red-500 hover:text-white p-2 rounded-xl transition">
  78. <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"></path></svg>
  79. </a>
  80. </div>
  81. </div>
  82. </aside>
  83. <main class="flex-1 overflow-y-auto custom-scroll relative bg-[#0b0e14]">
  84. <div class="p-10 max-w-[1600px] mx-auto">
  85. {% with messages = get_flashed_messages(with_categories=true) %}
  86. {% if messages %}
  87. <script>
  88. document.addEventListener('DOMContentLoaded', function() {
  89. const Toast = Swal.mixin({ toast: true, position: 'bottom-end', showConfirmButton: false, timer: 4000, timerProgressBar: true, background: '#1f2937', color: '#fff' });
  90. {% for category, message in messages %}
  91. Toast.fire({ icon: '{{ "success" if category == "success" else "error" }}', title: '{{ message }}' });
  92. {% endfor %}
  93. });
  94. </script>
  95. {% endif %}
  96. {% endwith %}
  97. {% block content %}{% endblock %}
  98. </div>
  99. </main>
  100. <script>
  101. const AppToast = Swal.mixin({
  102. toast: true, position: 'bottom-end', showConfirmButton: false,
  103. timer: 3000, timerProgressBar: true, background: '#12161f', color: '#fff',
  104. customClass: { popup: 'border border-gray-700 rounded-xl shadow-2xl' }
  105. });
  106. // Loader Spinner SVG
  107. const spinnerSvg = `<svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>`;
  108. </script>
  109. </body>
  110. </html>