Al1Abdullah commited on
Commit
1ffd5bd
·
1 Parent(s): 6bf6f54

Implement unified sidebar toggle and refine mobile UI

Browse files
Files changed (3) hide show
  1. frontend/index.html +2 -3
  2. frontend/main.js +38 -34
  3. 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="mobile-sidebar-toggle" class="mobile-toggle"><i class="fas fa-bars"></i></button>
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 desktopSidebarToggle = document.getElementById('desktop-sidebar-toggle'); // Original desktop toggle
7
- const mobileSidebarToggle = document.getElementById('mobile-sidebar-toggle'); // New mobile toggle
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 on mobile after navigation
37
- if (isMobileView()) {
38
  sidebar.classList.remove('active');
39
  overlay.classList.remove('active');
40
- // Change icon back to bars when sidebar closes
41
- mobileSidebarToggle.querySelector('i').classList.remove('fa-times');
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
- mobileSidebarToggle.style.display = 'flex'; // Ensure mobile toggle is visible
60
- desktopSidebarToggle.style.display = 'none'; // Hide desktop toggle
 
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
- mainContent.classList.remove('collapsed');
67
- mobileSidebarToggle.style.display = 'none'; // Hide mobile toggle
68
- desktopSidebarToggle.style.display = 'block'; // Show desktop toggle
 
 
 
69
  }
70
  }
71
 
72
  setupSidebarState(); // Call on initial load
73
 
74
- // Event listener for desktop sidebar toggle
75
- desktopSidebarToggle.addEventListener('click', () => {
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
- mobileSidebarToggle.querySelector('i').classList.remove('fa-times');
93
- mobileSidebarToggle.querySelector('i').classList.add('fa-bars');
 
 
 
94
  }
95
  } else {
96
- mobileSidebarToggle.querySelector('i').classList.remove('fa-times');
97
- mobileSidebarToggle.querySelector('i').classList.add('fa-bars');
 
 
 
 
 
 
 
 
 
 
 
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
- // Change icon back to bars when sidebar closes
108
- mobileSidebarToggle.querySelector('i').classList.remove('fa-times');
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
- /* Desktop sidebar toggle */
57
- #desktop-sidebar-toggle {
 
 
 
 
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
- #desktop-sidebar-toggle:hover {
67
  color: var(--hover-color);
68
  }
69
 
70
- .sidebar.collapsed #desktop-sidebar-toggle {
71
- transform: rotate(180deg);
 
 
 
 
 
 
 
 
 
 
 
 
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; /* Hide desktop toggle on mobile */
350
  }
351
 
352
- #mobile-sidebar-toggle {
353
- display: flex; /* Show mobile toggle */
 
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 {