NeonClary Cursor commited on
Commit
99bfa7f
·
1 Parent(s): fddd8f4

Make left sidebar hideable and fix header overlap on narrow widths

Browse files
phd-advisor-frontend/src/components/Sidebar.js CHANGED
@@ -575,6 +575,19 @@ const Sidebar = ({
575
  onClick={() => onMobileToggle(false)}
576
  />
577
  )}
 
 
 
 
 
 
 
 
 
 
 
 
 
578
  </>
579
  );
580
  };
 
575
  onClick={() => onMobileToggle(false)}
576
  />
577
  )}
578
+
579
+ {/* Floating handle to bring the sidebar back once it's hidden (desktop).
580
+ The in-sidebar toggle is off-screen when hidden, so this is the way back. */}
581
+ {isCollapsed && (
582
+ <button
583
+ className="sidebar-show-handle"
584
+ onClick={() => setIsCollapsed(false)}
585
+ title="Show sidebar"
586
+ aria-label="Show sidebar"
587
+ >
588
+ <PanelLeft size={18} />
589
+ </button>
590
+ )}
591
  </>
592
  );
593
  };
phd-advisor-frontend/src/pages/ChatPage.js CHANGED
@@ -1052,7 +1052,7 @@ const handleNewChat = async (sessionId = null) => {
1052
  )}
1053
  </div>
1054
 
1055
- <div className="floating-input-area">
1056
  {replyingTo && (
1057
  <div className="reply-banner">
1058
  <div className="reply-info">
 
1052
  )}
1053
  </div>
1054
 
1055
+ <div className={`floating-input-area ${isSidebarCollapsed ? 'sidebar-collapsed' : ''}`}>
1056
  {replyingTo && (
1057
  <div className="reply-banner">
1058
  <div className="reply-info">
phd-advisor-frontend/src/styles/CanvasPage.css CHANGED
@@ -16,7 +16,7 @@
16
  display: flex;
17
  flex-direction: column;
18
  }
19
- .canvas-main-area.sidebar-collapsed { margin-left: 70px; }
20
  .canvas-app-shell {
21
  flex: 1;
22
  display: flex;
@@ -232,14 +232,14 @@
232
  }
233
  .canvas-page-with-sidebar .theme-toggle .theme-icon { display: block; }
234
 
235
- /* When the tabs sit in ChatPage's flex .floating-header, absolutely-position
236
- them so they center regardless of header-left/header-right widths. */
 
 
237
  .floating-header { position: sticky; }
238
  .floating-header > .chat-view-tabs {
239
- position: absolute;
240
- left: 50%;
241
- top: 50%;
242
- transform: translate(-50%, -50%);
243
  }
244
  .canvas-tabs-mobile { display: none; }
245
  @media (max-width: 900px) {
 
16
  display: flex;
17
  flex-direction: column;
18
  }
19
+ .canvas-main-area.sidebar-collapsed { margin-left: 0; }
20
  .canvas-app-shell {
21
  flex: 1;
22
  display: flex;
 
232
  }
233
  .canvas-page-with-sidebar .theme-toggle .theme-icon { display: block; }
234
 
235
+ /* Keep the tabs as a normal in-flow flex child so they never overlap the
236
+ brand/title on the left or the controls on the right as the window narrows.
237
+ They sit between two equal flex regions (header-left / header-right), which
238
+ keeps them roughly centered without absolute positioning. */
239
  .floating-header { position: sticky; }
240
  .floating-header > .chat-view-tabs {
241
+ position: relative;
242
+ flex: 0 0 auto;
 
 
243
  }
244
  .canvas-tabs-mobile { display: none; }
245
  @media (max-width: 900px) {
phd-advisor-frontend/src/styles/ChatPage.css CHANGED
@@ -34,6 +34,8 @@
34
  display: flex;
35
  align-items: center;
36
  gap: 16px;
 
 
37
  }
38
 
39
  .modern-home-btn {
@@ -61,6 +63,7 @@
61
  display: flex;
62
  align-items: center;
63
  gap: 12px;
 
64
  }
65
 
66
  .brand-icon {
@@ -78,6 +81,7 @@
78
  display: flex;
79
  flex-direction: column;
80
  gap: 6px;
 
81
  }
82
 
83
  .brand-text h1 {
@@ -86,6 +90,9 @@
86
  color: var(--text-primary);
87
  margin: 0;
88
  line-height: 1.2;
 
 
 
89
  }
90
 
91
  .brand-text p {
@@ -93,12 +100,20 @@
93
  color: var(--text-secondary);
94
  margin: 0;
95
  line-height: 1.35;
 
 
 
96
  }
97
 
98
  .header-right {
99
  display: flex;
100
  align-items: center;
101
  gap: 20px;
 
 
 
 
 
102
  }
103
 
104
  .header-controls {
@@ -604,7 +619,7 @@
604
  }
605
 
606
  .floating-input-area.sidebar-collapsed {
607
- left: 70px;
608
  }
609
 
610
  /* Reply Banner in ChatPage - matches input width and fixes dark mode */
@@ -674,9 +689,9 @@
674
  overflow: hidden;
675
  }
676
 
677
- /* FIXED: Chat area expansion when sidebar is collapsed */
678
  .main-chat-area.sidebar-collapsed {
679
- margin-left: 70px; /* Width of sidebar when collapsed */
680
  }
681
 
682
  /* Optional header sign out button */
 
34
  display: flex;
35
  align-items: center;
36
  gap: 16px;
37
+ flex: 1 1 0;
38
+ min-width: 0; /* allow the brand title to truncate instead of pushing the tabs */
39
  }
40
 
41
  .modern-home-btn {
 
63
  display: flex;
64
  align-items: center;
65
  gap: 12px;
66
+ min-width: 0; /* let the text column shrink so it can truncate */
67
  }
68
 
69
  .brand-icon {
 
81
  display: flex;
82
  flex-direction: column;
83
  gap: 6px;
84
+ min-width: 0; /* enables text-overflow ellipsis on the children */
85
  }
86
 
87
  .brand-text h1 {
 
90
  color: var(--text-primary);
91
  margin: 0;
92
  line-height: 1.2;
93
+ white-space: nowrap;
94
+ overflow: hidden;
95
+ text-overflow: ellipsis;
96
  }
97
 
98
  .brand-text p {
 
100
  color: var(--text-secondary);
101
  margin: 0;
102
  line-height: 1.35;
103
+ white-space: nowrap;
104
+ overflow: hidden;
105
+ text-overflow: ellipsis;
106
  }
107
 
108
  .header-right {
109
  display: flex;
110
  align-items: center;
111
  gap: 20px;
112
+ /* Grow to balance header-left (keeping the tabs centered), but the default
113
+ min-width:auto means the controls never shrink below their content and so
114
+ never overlap the tabs. header-left truncates its title first. */
115
+ flex: 1 1 0;
116
+ justify-content: flex-end;
117
  }
118
 
119
  .header-controls {
 
619
  }
620
 
621
  .floating-input-area.sidebar-collapsed {
622
+ left: 0;
623
  }
624
 
625
  /* Reply Banner in ChatPage - matches input width and fixes dark mode */
 
689
  overflow: hidden;
690
  }
691
 
692
+ /* Chat area reclaims full width when the sidebar is hidden */
693
  .main-chat-area.sidebar-collapsed {
694
+ margin-left: 0;
695
  }
696
 
697
  /* Optional header sign out button */
phd-advisor-frontend/src/styles/Sidebar.css CHANGED
@@ -11,12 +11,15 @@
11
  top: 0;
12
  z-index: 100;
13
  overflow: hidden;
14
- transition: width 0.3s ease;
15
  }
16
 
17
- /* Collapsed state */
 
 
18
  .sidebar.collapsed {
19
- width: 70px;
 
20
  }
21
 
22
  /* Dark theme support */
@@ -25,6 +28,46 @@
25
  border-right-color: var(--border-dark, #374151);
26
  }
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  /* Toggle Button - Matches User Menu Style */
29
  .sidebar-toggle {
30
  display: flex;
@@ -842,7 +885,6 @@
842
  }
843
 
844
  .sidebar.collapsed {
845
- width: 70px;
846
  transform: translateX(-100%); /* Keep hidden when collapsed on mobile */
847
  }
848
 
@@ -853,4 +895,10 @@
853
  .mobile-sidebar-overlay.visible {
854
  display: block;
855
  }
 
 
 
 
 
 
856
  }
 
11
  top: 0;
12
  z-index: 100;
13
  overflow: hidden;
14
+ transition: transform 0.3s ease, width 0.3s ease;
15
  }
16
 
17
+ /* Collapsed state — fully hide the sidebar off-canvas (desktop) so the main
18
+ content reclaims the full width. A floating handle (.sidebar-show-handle)
19
+ brings it back. */
20
  .sidebar.collapsed {
21
+ transform: translateX(-100%);
22
+ box-shadow: none;
23
  }
24
 
25
  /* Dark theme support */
 
28
  border-right-color: var(--border-dark, #374151);
29
  }
30
 
31
+ /* Floating handle shown when the sidebar is hidden, to reopen it */
32
+ .sidebar-show-handle {
33
+ position: fixed;
34
+ left: 0;
35
+ top: 50%;
36
+ transform: translateY(-50%);
37
+ z-index: 120;
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: center;
41
+ width: 26px;
42
+ height: 54px;
43
+ padding: 0;
44
+ border: 1px solid var(--border-light, #e5e7eb);
45
+ border-left: none;
46
+ border-radius: 0 10px 10px 0;
47
+ background: var(--bg-primary, #ffffff);
48
+ color: var(--text-secondary, #6b7280);
49
+ cursor: pointer;
50
+ box-shadow: 2px 0 10px rgba(0, 0, 0, 0.08);
51
+ transition: width 0.2s ease, background 0.2s ease, color 0.2s ease;
52
+ }
53
+
54
+ .sidebar-show-handle:hover {
55
+ width: 32px;
56
+ background: var(--bg-secondary, #f3f4f6);
57
+ color: var(--text-primary, #111827);
58
+ }
59
+
60
+ .dark .sidebar-show-handle {
61
+ background: var(--bg-primary-dark, #1f2937);
62
+ border-color: var(--border-dark, #374151);
63
+ color: var(--text-secondary, #9ca3af);
64
+ }
65
+
66
+ .dark .sidebar-show-handle:hover {
67
+ background: var(--bg-secondary-dark, #374151);
68
+ color: var(--text-primary-dark, #f9fafb);
69
+ }
70
+
71
  /* Toggle Button - Matches User Menu Style */
72
  .sidebar-toggle {
73
  display: flex;
 
885
  }
886
 
887
  .sidebar.collapsed {
 
888
  transform: translateX(-100%); /* Keep hidden when collapsed on mobile */
889
  }
890
 
 
895
  .mobile-sidebar-overlay.visible {
896
  display: block;
897
  }
898
+
899
+ /* On mobile the header hamburger opens the sidebar, so the desktop
900
+ reopen handle is redundant. */
901
+ .sidebar-show-handle {
902
+ display: none;
903
+ }
904
  }