Spaces:
Sleeping
Sleeping
Commit
·
1ffd5bd
1
Parent(s):
6bf6f54
Implement unified sidebar toggle and refine mobile UI
Browse files- frontend/index.html +2 -3
- frontend/main.js +38 -34
- frontend/style.css +39 -27
frontend/index.html
CHANGED
|
@@ -12,17 +12,16 @@
|
|
| 12 |
<aside class="sidebar">
|
| 13 |
<div class="sidebar-header">
|
| 14 |
<h2>AutoML</h2>
|
| 15 |
-
<button id="desktop-sidebar-toggle"><i class="fas fa-angle-left"></i></button>
|
| 16 |
</div>
|
| 17 |
<nav class="sidebar-nav">
|
| 18 |
<a href="#" class="nav-link active" data-page="load-dataset"><i class="fas fa-upload"></i><span class="nav-text">Load Dataset</span></a>
|
| 19 |
-
<a href="#" class="nav-link" data-page="train"><i class="fas fa-cogs"></i><span class="nav-text">Model Trainer</span></a>
|
| 20 |
<a href="#" class="nav-link" data-page="visualize"><i class="fas fa-chart-bar"></i><span class="nav-text">Visualize</span></a>
|
| 21 |
<a href="#" class="nav-link" data-page="ask"><i class="fas fa-question-circle"></i><span class="nav-text">Ask AI</span></a>
|
| 22 |
</nav>
|
| 23 |
</aside>
|
| 24 |
<main class="main-content">
|
| 25 |
-
<button id="
|
| 26 |
<div class="overlay"></div>
|
| 27 |
<div class="container">
|
| 28 |
<div id="load-dataset" class="page active">
|
|
|
|
| 12 |
<aside class="sidebar">
|
| 13 |
<div class="sidebar-header">
|
| 14 |
<h2>AutoML</h2>
|
|
|
|
| 15 |
</div>
|
| 16 |
<nav class="sidebar-nav">
|
| 17 |
<a href="#" class="nav-link active" data-page="load-dataset"><i class="fas fa-upload"></i><span class="nav-text">Load Dataset</span></a>
|
| 18 |
+
<a href="#" class="#nav-link" data-page="train"><i class="fas fa-cogs"></i><span class="nav-text">Model Trainer</span></a>
|
| 19 |
<a href="#" class="nav-link" data-page="visualize"><i class="fas fa-chart-bar"></i><span class="nav-text">Visualize</span></a>
|
| 20 |
<a href="#" class="nav-link" data-page="ask"><i class="fas fa-question-circle"></i><span class="nav-text">Ask AI</span></a>
|
| 21 |
</nav>
|
| 22 |
</aside>
|
| 23 |
<main class="main-content">
|
| 24 |
+
<button id="sidebar-toggle" class="mobile-toggle"><i class="fas fa-bars"></i></button>
|
| 25 |
<div class="overlay"></div>
|
| 26 |
<div class="container">
|
| 27 |
<div id="load-dataset" class="page active">
|
frontend/main.js
CHANGED
|
@@ -3,9 +3,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
| 3 |
const pages = document.querySelectorAll('.page');
|
| 4 |
const sidebar = document.querySelector('.sidebar');
|
| 5 |
const mainContent = document.querySelector('.main-content');
|
| 6 |
-
const
|
| 7 |
-
const
|
| 8 |
-
const overlay = document.querySelector('.overlay'); // New overlay
|
| 9 |
const loader = document.querySelector('.loader');
|
| 10 |
|
| 11 |
function animateNavText() {
|
|
@@ -33,13 +32,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
| 33 |
document.getElementById(pageId).classList.add('active');
|
| 34 |
link.classList.add('active');
|
| 35 |
|
| 36 |
-
// Close sidebar
|
| 37 |
-
if (isMobileView()) {
|
| 38 |
sidebar.classList.remove('active');
|
| 39 |
overlay.classList.remove('active');
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
mobileSidebarToggle.querySelector('i').classList.add('fa-bars');
|
| 43 |
}
|
| 44 |
});
|
| 45 |
});
|
|
@@ -56,45 +54,52 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
| 56 |
sidebar.classList.remove('active'); // Start hidden on mobile
|
| 57 |
overlay.classList.remove('active');
|
| 58 |
mainContent.classList.remove('collapsed'); // Main content always full width on mobile
|
| 59 |
-
|
| 60 |
-
|
|
|
|
| 61 |
} else {
|
| 62 |
// Desktop default state
|
| 63 |
-
sidebar.classList.remove('collapsed');
|
| 64 |
sidebar.classList.remove('active'); // Ensure mobile active state is removed
|
| 65 |
overlay.classList.remove('active');
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
| 69 |
}
|
| 70 |
}
|
| 71 |
|
| 72 |
setupSidebarState(); // Call on initial load
|
| 73 |
|
| 74 |
-
//
|
| 75 |
-
|
| 76 |
-
if (!isMobileView()) {
|
| 77 |
-
sidebar.classList.toggle('collapsed');
|
| 78 |
-
mainContent.classList.toggle('collapsed');
|
| 79 |
-
if (!sidebar.classList.contains('collapsed')) {
|
| 80 |
-
animateNavText();
|
| 81 |
-
}
|
| 82 |
-
}
|
| 83 |
-
});
|
| 84 |
-
|
| 85 |
-
// Event listener for mobile sidebar toggle
|
| 86 |
-
mobileSidebarToggle.addEventListener('click', () => {
|
| 87 |
if (isMobileView()) {
|
|
|
|
| 88 |
sidebar.classList.toggle('active');
|
| 89 |
overlay.classList.toggle('active');
|
| 90 |
// Change icon based on sidebar state
|
| 91 |
if (sidebar.classList.contains('active')) {
|
| 92 |
-
|
| 93 |
-
|
|
|
|
|
|
|
|
|
|
| 94 |
}
|
| 95 |
} else {
|
| 96 |
-
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
}
|
| 99 |
}
|
| 100 |
});
|
|
@@ -104,9 +109,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
| 104 |
if (isMobileView() && sidebar.classList.contains('active')) {
|
| 105 |
sidebar.classList.remove('active');
|
| 106 |
overlay.classList.remove('active');
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
mobileSidebarToggle.querySelector('i').classList.add('fa-bars');
|
| 110 |
}
|
| 111 |
});
|
| 112 |
|
|
|
|
| 3 |
const pages = document.querySelectorAll('.page');
|
| 4 |
const sidebar = document.querySelector('.sidebar');
|
| 5 |
const mainContent = document.querySelector('.main-content');
|
| 6 |
+
const sidebarToggle = document.getElementById('sidebar-toggle'); // Unified toggle button
|
| 7 |
+
const overlay = document.querySelector('.overlay');
|
|
|
|
| 8 |
const loader = document.querySelector('.loader');
|
| 9 |
|
| 10 |
function animateNavText() {
|
|
|
|
| 32 |
document.getElementById(pageId).classList.add('active');
|
| 33 |
link.classList.add('active');
|
| 34 |
|
| 35 |
+
// Close sidebar and overlay after navigation on mobile
|
| 36 |
+
if (isMobileView() && sidebar.classList.contains('active')) {
|
| 37 |
sidebar.classList.remove('active');
|
| 38 |
overlay.classList.remove('active');
|
| 39 |
+
sidebarToggle.querySelector('i').classList.remove('fa-times');
|
| 40 |
+
sidebarToggle.querySelector('i').classList.add('fa-bars');
|
|
|
|
| 41 |
}
|
| 42 |
});
|
| 43 |
});
|
|
|
|
| 54 |
sidebar.classList.remove('active'); // Start hidden on mobile
|
| 55 |
overlay.classList.remove('active');
|
| 56 |
mainContent.classList.remove('collapsed'); // Main content always full width on mobile
|
| 57 |
+
sidebarToggle.classList.add('mobile-toggle'); // Ensure mobile toggle styles are applied
|
| 58 |
+
sidebarToggle.querySelector('i').classList.remove('fa-times'); // Ensure bars icon
|
| 59 |
+
sidebarToggle.querySelector('i').classList.add('fa-bars');
|
| 60 |
} else {
|
| 61 |
// Desktop default state
|
|
|
|
| 62 |
sidebar.classList.remove('active'); // Ensure mobile active state is removed
|
| 63 |
overlay.classList.remove('active');
|
| 64 |
+
sidebarToggle.classList.remove('mobile-toggle'); // Remove mobile toggle styles
|
| 65 |
+
sidebarToggle.querySelector('i').classList.remove('fa-bars'); // Ensure arrow icon
|
| 66 |
+
sidebarToggle.querySelector('i').classList.add('fa-angle-left');
|
| 67 |
+
// Set initial desktop collapsed state if desired, or leave expanded
|
| 68 |
+
// sidebar.classList.add('collapsed');
|
| 69 |
+
// mainContent.classList.add('collapsed');
|
| 70 |
}
|
| 71 |
}
|
| 72 |
|
| 73 |
setupSidebarState(); // Call on initial load
|
| 74 |
|
| 75 |
+
// Unified event listener for sidebar toggle
|
| 76 |
+
sidebarToggle.addEventListener('click', () => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
if (isMobileView()) {
|
| 78 |
+
// Mobile behavior: sidebar as overlay
|
| 79 |
sidebar.classList.toggle('active');
|
| 80 |
overlay.classList.toggle('active');
|
| 81 |
// Change icon based on sidebar state
|
| 82 |
if (sidebar.classList.contains('active')) {
|
| 83 |
+
sidebarToggle.querySelector('i').classList.remove('fa-bars');
|
| 84 |
+
sidebarToggle.querySelector('i').classList.add('fa-times');
|
| 85 |
+
} else {
|
| 86 |
+
sidebarToggle.querySelector('i').classList.remove('fa-times');
|
| 87 |
+
sidebarToggle.querySelector('i').classList.add('fa-bars');
|
| 88 |
}
|
| 89 |
} else {
|
| 90 |
+
// Desktop behavior: sidebar collapses/expands
|
| 91 |
+
sidebar.classList.toggle('collapsed');
|
| 92 |
+
mainContent.classList.toggle('collapsed');
|
| 93 |
+
// Change icon based on sidebar state
|
| 94 |
+
if (sidebar.classList.contains('collapsed')) {
|
| 95 |
+
sidebarToggle.querySelector('i').classList.remove('fa-angle-left');
|
| 96 |
+
sidebarToggle.querySelector('i').classList.add('fa-angle-right');
|
| 97 |
+
} else {
|
| 98 |
+
sidebarToggle.querySelector('i').classList.remove('fa-angle-right');
|
| 99 |
+
sidebarToggle.querySelector('i').classList.add('fa-angle-left');
|
| 100 |
+
}
|
| 101 |
+
if (!sidebar.classList.contains('collapsed')) {
|
| 102 |
+
animateNavText();
|
| 103 |
}
|
| 104 |
}
|
| 105 |
});
|
|
|
|
| 109 |
if (isMobileView() && sidebar.classList.contains('active')) {
|
| 110 |
sidebar.classList.remove('active');
|
| 111 |
overlay.classList.remove('active');
|
| 112 |
+
sidebarToggle.querySelector('i').classList.remove('fa-times');
|
| 113 |
+
sidebarToggle.querySelector('i').classList.add('fa-bars');
|
|
|
|
| 114 |
}
|
| 115 |
});
|
| 116 |
|
frontend/style.css
CHANGED
|
@@ -29,7 +29,7 @@ body {
|
|
| 29 |
top: 0;
|
| 30 |
left: 0;
|
| 31 |
padding: 1.5rem;
|
| 32 |
-
transition: width 0.3s ease;
|
| 33 |
z-index: 10;
|
| 34 |
box-shadow: 2px 0 10px rgba(0,0,0,0.1);
|
| 35 |
}
|
|
@@ -53,22 +53,50 @@ body {
|
|
| 53 |
transition: opacity 0.3s ease;
|
| 54 |
}
|
| 55 |
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
background: transparent;
|
| 59 |
border: none;
|
| 60 |
color: var(--text-color-light);
|
| 61 |
font-size: 1.2rem;
|
| 62 |
cursor: pointer;
|
| 63 |
transition: transform 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
}
|
| 65 |
|
| 66 |
-
#
|
| 67 |
color: var(--hover-color);
|
| 68 |
}
|
| 69 |
|
| 70 |
-
|
| 71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
}
|
| 73 |
|
| 74 |
.sidebar-nav {
|
|
@@ -309,24 +337,6 @@ button:hover {
|
|
| 309 |
animation: none;
|
| 310 |
}
|
| 311 |
|
| 312 |
-
/* Mobile toggle button (hamburger) */
|
| 313 |
-
#mobile-sidebar-toggle {
|
| 314 |
-
display: none; /* Hidden by default on desktop */
|
| 315 |
-
position: fixed;
|
| 316 |
-
top: 1rem;
|
| 317 |
-
left: 1rem;
|
| 318 |
-
z-index: 1001; /* Ensure it's above other content */
|
| 319 |
-
background-color: var(--primary-color);
|
| 320 |
-
color: var(--text-color-light);
|
| 321 |
-
border-radius: 50%;
|
| 322 |
-
width: 40px;
|
| 323 |
-
height: 40px;
|
| 324 |
-
display: flex;
|
| 325 |
-
align-items: center;
|
| 326 |
-
justify-content: center;
|
| 327 |
-
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
| 328 |
-
}
|
| 329 |
-
|
| 330 |
/* Overlay for when sidebar is active */
|
| 331 |
.overlay {
|
| 332 |
display: none;
|
|
@@ -345,12 +355,14 @@ button:hover {
|
|
| 345 |
|
| 346 |
/* Responsive adjustments for smaller screens */
|
| 347 |
@media (max-width: 768px) {
|
|
|
|
| 348 |
#desktop-sidebar-toggle {
|
| 349 |
-
display: none;
|
| 350 |
}
|
| 351 |
|
| 352 |
-
|
| 353 |
-
|
|
|
|
| 354 |
}
|
| 355 |
|
| 356 |
.app-layout {
|
|
|
|
| 29 |
top: 0;
|
| 30 |
left: 0;
|
| 31 |
padding: 1.5rem;
|
| 32 |
+
transition: width 0.3s ease, transform 0.3s ease;
|
| 33 |
z-index: 10;
|
| 34 |
box-shadow: 2px 0 10px rgba(0,0,0,0.1);
|
| 35 |
}
|
|
|
|
| 53 |
transition: opacity 0.3s ease;
|
| 54 |
}
|
| 55 |
|
| 56 |
+
.sidebar.collapsed .sidebar-header h2 {
|
| 57 |
+
opacity: 0;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
/* Unified sidebar toggle button */
|
| 61 |
+
#sidebar-toggle {
|
| 62 |
background: transparent;
|
| 63 |
border: none;
|
| 64 |
color: var(--text-color-light);
|
| 65 |
font-size: 1.2rem;
|
| 66 |
cursor: pointer;
|
| 67 |
transition: transform 0.3s ease;
|
| 68 |
+
position: fixed; /* Fixed position for both desktop and mobile */
|
| 69 |
+
top: 1rem;
|
| 70 |
+
left: 1rem;
|
| 71 |
+
z-index: 1001; /* Ensure it's above other content */
|
| 72 |
+
background-color: var(--primary-color);
|
| 73 |
+
border-radius: 50%;
|
| 74 |
+
width: 40px;
|
| 75 |
+
height: 40px;
|
| 76 |
+
display: flex;
|
| 77 |
+
align-items: center;
|
| 78 |
+
justify-content: center;
|
| 79 |
+
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
| 80 |
}
|
| 81 |
|
| 82 |
+
#sidebar-toggle:hover {
|
| 83 |
color: var(--hover-color);
|
| 84 |
}
|
| 85 |
|
| 86 |
+
/* Desktop specific toggle behavior */
|
| 87 |
+
@media (min-width: 769px) {
|
| 88 |
+
#sidebar-toggle {
|
| 89 |
+
position: absolute; /* Position relative to sidebar on desktop */
|
| 90 |
+
top: 1.5rem;
|
| 91 |
+
right: 1.5rem;
|
| 92 |
+
left: auto; /* Reset left position */
|
| 93 |
+
background: transparent; /* Reset background */
|
| 94 |
+
box-shadow: none; /* Reset shadow */
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
.sidebar.collapsed #sidebar-toggle {
|
| 98 |
+
transform: rotate(180deg);
|
| 99 |
+
}
|
| 100 |
}
|
| 101 |
|
| 102 |
.sidebar-nav {
|
|
|
|
| 337 |
animation: none;
|
| 338 |
}
|
| 339 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
/* Overlay for when sidebar is active */
|
| 341 |
.overlay {
|
| 342 |
display: none;
|
|
|
|
| 355 |
|
| 356 |
/* Responsive adjustments for smaller screens */
|
| 357 |
@media (max-width: 768px) {
|
| 358 |
+
/* Hide desktop toggle on mobile */
|
| 359 |
#desktop-sidebar-toggle {
|
| 360 |
+
display: none;
|
| 361 |
}
|
| 362 |
|
| 363 |
+
/* Show mobile toggle */
|
| 364 |
+
#sidebar-toggle {
|
| 365 |
+
display: flex;
|
| 366 |
}
|
| 367 |
|
| 368 |
.app-layout {
|