sidebar.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <div class="w-64 tech-panel flex flex-col transition-all duration-300 transform -translate-x-full md:translate-x-0 fixed md:relative z-30 h-full border-r-0 md:border-r border-blue-900/30" id="sidebar">
  2. <div class="p-6 flex items-center justify-between transition-all duration-300" id="sidebar-header">
  3. <span class="text-xl font-bold tech-title tracking-wider flex items-center gap-2 whitespace-nowrap overflow-hidden" id="sidebar-brand">
  4. <i class="fas fa-globe-asia text-blue-500 min-w-[1.5rem] text-center"></i>
  5. <span class="sidebar-text transition-opacity duration-300">{{ app_name }}</span>
  6. </span>
  7. <button class="md:hidden text-gray-300 hover:text-white focus:outline-none" id="close-sidebar">
  8. <i class="fas fa-times"></i>
  9. </button>
  10. <button class="hidden md:block text-gray-400 hover:text-white focus:outline-none transition-transform duration-300" id="toggle-sidebar">
  11. <i class="fas fa-chevron-left"></i>
  12. </button>
  13. </div>
  14. <nav class="flex-1 overflow-y-auto px-3 py-2">
  15. <ul class="space-y-1">
  16. <li>
  17. <a class="flex items-center px-4 py-3 rounded-lg {% if request.endpoint == 'main.dashboard' %}bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg{% else %}text-gray-400 hover:bg-gray-800 hover:text-white{% endif %} transition-all duration-200 group" href="{{ url_for('main.dashboard') }}">
  18. <i class="fas fa-tachometer-alt w-6 text-center {% if request.endpoint == 'main.dashboard' %}text-white{% else %}text-gray-500 group-hover:text-blue-400{% endif %} transition-colors"></i>
  19. <span class="ml-2 font-medium sidebar-text whitespace-nowrap">后台主页</span>
  20. </a>
  21. </li>
  22. <li>
  23. <a class="flex items-center px-4 py-3 rounded-lg {% if request.endpoint == 'collection.dashboard' %}bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg{% else %}text-gray-400 hover:bg-gray-800 hover:text-white{% endif %} transition-all duration-200 group" href="{{ url_for('collection.dashboard') }}">
  24. <i class="fas fa-tasks w-6 text-center {% if request.endpoint == 'collection.dashboard' %}text-white{% else %}text-gray-500 group-hover:text-blue-400{% endif %} transition-colors"></i>
  25. <span class="ml-2 font-medium sidebar-text whitespace-nowrap">采集管理</span>
  26. </a>
  27. </li>
  28. <li>
  29. <a class="flex items-center px-4 py-3 rounded-lg {% if request.endpoint == 'source.dashboard' %}bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg{% else %}text-gray-400 hover:bg-gray-800 hover:text-white{% endif %} transition-all duration-200 group" href="{{ url_for('source.dashboard') }}">
  30. <i class="fas fa-spider w-6 text-center {% if request.endpoint == 'source.dashboard' %}text-white{% else %}text-gray-500 group-hover:text-blue-400{% endif %} transition-colors"></i>
  31. <span class="ml-2 font-medium sidebar-text whitespace-nowrap">爬虫管理</span>
  32. </a>
  33. </li>
  34. <li>
  35. <a class="flex items-center px-4 py-3 rounded-lg {% if request.endpoint == 'data.dashboard' %}bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg{% else %}text-gray-400 hover:bg-gray-800 hover:text-white{% endif %} transition-all duration-200 group" href="{{ url_for('data.dashboard') }}">
  36. <i class="fas fa-database w-6 text-center {% if request.endpoint == 'data.dashboard' %}text-white{% else %}text-gray-500 group-hover:text-blue-400{% endif %} transition-colors"></i>
  37. <span class="ml-2 font-medium sidebar-text whitespace-nowrap">数据管理</span>
  38. </a>
  39. </li>
  40. <li>
  41. <a class="flex items-center px-4 py-3 rounded-lg {% if request.endpoint == 'deep.dashboard' %}bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg{% else %}text-gray-400 hover:bg-gray-800 hover:text-white{% endif %} transition-all duration-200 group" href="{{ url_for('deep.dashboard') }}">
  42. <i class="fas fa-search-plus w-6 text-center {% if request.endpoint == 'deep.dashboard' %}text-white{% else %}text-gray-500 group-hover:text-blue-400{% endif %} transition-colors"></i>
  43. <span class="ml-2 font-medium sidebar-text whitespace-nowrap">深采管理</span>
  44. </a>
  45. </li>
  46. <li>
  47. <a class="flex items-center px-4 py-3 rounded-lg {% if request.endpoint == 'ai.dashboard' %}bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg{% else %}text-gray-400 hover:bg-gray-800 hover:text-white{% endif %} transition-all duration-200 group" href="{{ url_for('ai.dashboard') }}">
  48. <i class="fas fa-robot w-6 text-center {% if request.endpoint == 'ai.dashboard' %}text-white{% else %}text-gray-500 group-hover:text-blue-400{% endif %} transition-colors"></i>
  49. <span class="ml-2 font-medium sidebar-text whitespace-nowrap">AI模型管理</span>
  50. </a>
  51. </li>
  52. <li>
  53. <a class="flex items-center px-4 py-3 rounded-lg {% if request.endpoint == 'ai.analysis' %}bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg{% else %}text-gray-400 hover:bg-gray-800 hover:text-white{% endif %} transition-all duration-200 group" href="{{ url_for('ai.analysis') }}">
  54. <i class="fas fa-chart-line w-6 text-center {% if request.endpoint == 'ai.analysis' %}text-white{% else %}text-gray-500 group-hover:text-blue-400{% endif %} transition-colors"></i>
  55. <span class="ml-2 font-medium sidebar-text whitespace-nowrap">AI分析报告</span>
  56. </a>
  57. </li>
  58. <li>
  59. <a class="flex items-center px-4 py-3 rounded-lg {% if request.endpoint == 'main.screen_page' %}bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg{% else %}text-gray-400 hover:bg-gray-800 hover:text-white{% endif %} transition-all duration-200 group" href="{{ url_for('main.screen_page') }}">
  60. <i class="fas fa-tv w-6 text-center {% if request.endpoint == 'main.screen_page' %}text-white{% else %}text-gray-500 group-hover:text-blue-400{% endif %} transition-colors"></i>
  61. <span class="ml-2 font-medium sidebar-text whitespace-nowrap">AI数智大屏</span>
  62. </a>
  63. </li>
  64. <li>
  65. <a class="flex items-center px-4 py-3 rounded-lg {% if request.endpoint == 'knowledge.knowledge_page' %}bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg{% else %}text-gray-400 hover:bg-gray-800 hover:text-white{% endif %} transition-all duration-200 group" href="{{ url_for('knowledge.knowledge_page') }}">
  66. <i class="fas fa-book w-6 text-center {% if request.endpoint == 'knowledge.knowledge_page' %}text-white{% else %}text-gray-500 group-hover:text-blue-400{% endif %} transition-colors"></i>
  67. <span class="ml-2 font-medium sidebar-text whitespace-nowrap">样本中心</span>
  68. </a>
  69. </li>
  70. </ul>
  71. </nav>
  72. <div class="p-4 mx-3 mb-4 mt-auto rounded-xl bg-gray-800/50 backdrop-blur-sm transition-all duration-300">
  73. <a href="{{ url_for('main.logout') }}" class="flex items-center justify-center text-gray-400 hover:text-red-400 transition duration-200 group">
  74. <i class="fas fa-sign-out-alt w-5 text-center group-hover:scale-110 transition-transform"></i>
  75. <span class="ml-2 text-sm font-medium sidebar-text whitespace-nowrap">退出登录</span>
  76. </a>
  77. </div>
  78. </div>
  79. <script>
  80. document.addEventListener('DOMContentLoaded', function() {
  81. const sidebar = document.getElementById('sidebar');
  82. const sidebarHeader = document.getElementById('sidebar-header');
  83. const toggleBtn = document.getElementById('toggle-sidebar');
  84. const toggleIcon = toggleBtn.querySelector('i');
  85. const sidebarTexts = document.querySelectorAll('.sidebar-text');
  86. const sidebarBrand = document.getElementById('sidebar-brand');
  87. const brandText = sidebarBrand.querySelector('.sidebar-text');
  88. // Load state
  89. const isCollapsed = localStorage.getItem('sidebar-collapsed') === 'true';
  90. if (isCollapsed) {
  91. collapseSidebar(false);
  92. }
  93. toggleBtn.addEventListener('click', function() {
  94. const collapsed = sidebar.classList.contains('w-20');
  95. if (collapsed) {
  96. expandSidebar();
  97. } else {
  98. collapseSidebar(true);
  99. }
  100. });
  101. function collapseSidebar(animate) {
  102. if(animate) sidebar.classList.add('transition-all', 'duration-300');
  103. sidebar.classList.remove('w-64');
  104. sidebar.classList.add('w-20');
  105. // Adjust Header Layout
  106. sidebarHeader.classList.remove('p-6', 'justify-between');
  107. sidebarHeader.classList.add('p-4', 'flex-col', 'justify-center', 'gap-4');
  108. sidebarTexts.forEach(text => {
  109. text.classList.add('opacity-0', 'w-0', 'ml-0', 'overflow-hidden');
  110. text.classList.remove('ml-2');
  111. });
  112. toggleIcon.classList.add('rotate-180');
  113. localStorage.setItem('sidebar-collapsed', 'true');
  114. }
  115. function expandSidebar() {
  116. sidebar.classList.add('transition-all', 'duration-300');
  117. sidebar.classList.remove('w-20');
  118. sidebar.classList.add('w-64');
  119. // Restore Header Layout
  120. sidebarHeader.classList.add('p-6', 'justify-between');
  121. sidebarHeader.classList.remove('p-4', 'flex-col', 'justify-center', 'gap-4');
  122. sidebarTexts.forEach(text => {
  123. text.classList.remove('opacity-0', 'w-0', 'ml-0', 'overflow-hidden');
  124. text.classList.add('ml-2');
  125. });
  126. toggleIcon.classList.remove('rotate-180');
  127. localStorage.setItem('sidebar-collapsed', 'false');
  128. }
  129. });
  130. </script>