Skip to content

Commit b80c263

Browse files
Merge pull request #183 from Jaiminkansagara1327/fix-profile-dropdown
Fix: Profile dropdown closes smoothly and on navigation
2 parents 19255e1 + 830270a commit b80c263

2 files changed

Lines changed: 118 additions & 74 deletions

File tree

src/components/Header.css

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -133,28 +133,28 @@ body {
133133
margin-left: 1rem;
134134
}
135135

136-
.theme-toggle{
136+
.theme-toggle {
137137
margin-top: 6px;
138138
}
139139

140140
.user-dashboard {
141-
margin-top:6px;
142-
margin-left:0.5rem;
141+
margin-top: 6px;
142+
margin-left: 0.5rem;
143143
font-size: 1.75rem;
144144
cursor: pointer;
145145
}
146146

147147
.login-button {
148-
color:var(--header-text);
148+
color: var(--header-text);
149149
background-color: var(--header-hover);
150150
width: 90%;
151151
border-radius: 20px;
152152
display: flex;
153153
gap: 7px;
154-
margin:2px 5px;
154+
margin: 2px 5px;
155155
margin-top: 12px;
156-
padding:0.6rem 1.2rem;
157-
backdrop-filter: blur(12px);
156+
padding: 0.6rem 1.2rem;
157+
backdrop-filter: blur(12px);
158158
-webkit-backdrop-filter: blur(12px);
159159
text-decoration: none;
160160
transition: all 0.3s ease;
@@ -167,9 +167,9 @@ body {
167167
}
168168

169169
.user-section {
170-
border:4px soild white;
170+
border: 4px soild white;
171171
border-radius: 10px;
172-
position:absolute;
172+
position: absolute;
173173
top: 67px;
174174
right: -45px;
175175
background-color: var(--header-bg);
@@ -178,6 +178,18 @@ body {
178178
flex-direction: column;
179179
align-items: center;
180180
align-items: start;
181+
182+
/* Transition */
183+
opacity: 0;
184+
transform: translateY(-10px);
185+
pointer-events: none;
186+
transition: opacity 0.25s ease, transform 0.25s ease;
187+
}
188+
189+
.user-section.show {
190+
opacity: 1;
191+
transform: translateY(0);
192+
pointer-events: auto;
181193
}
182194

183195
.welcome-message {
@@ -188,37 +200,38 @@ body {
188200
}
189201

190202
.user-profile {
191-
color:var(--header-text);
203+
color: var(--header-text);
192204
background-color: var(--header-hover);
193205
width: 90%;
194206
border-radius: 20px;
195207
display: flex;
196208
gap: 7px;
197-
margin:2px 5px;
209+
margin: 2px 5px;
198210
margin-top: 12px;
199-
padding:0.6rem 1.2rem;
200-
backdrop-filter: blur(12px);
211+
padding: 0.6rem 1.2rem;
212+
backdrop-filter: blur(12px);
201213
-webkit-backdrop-filter: blur(12px);
202214
text-decoration: none;
203215
}
204216

205-
.user-profile:hover, .logout-button:hover {
206-
text-decoration: none;
207-
background-color: transparent;
208-
transform: scale(1.05);
217+
.user-profile:hover,
218+
.logout-button:hover {
219+
text-decoration: none;
220+
background-color: transparent;
221+
transform: scale(1.05);
209222
}
210223

211224
.logout-button {
212-
color:var(--header-text);
225+
color: var(--header-text);
213226
background-color: var(--header-hover);
214227
width: 90%;
215228
border-radius: 20px;
216229
display: flex;
217230
gap: 7px;
218-
margin:2px 5px;
231+
margin: 2px 5px;
219232
margin-top: 12px;
220-
padding:0.6rem 1.2rem;
221-
backdrop-filter: blur(12px);
233+
padding: 0.6rem 1.2rem;
234+
backdrop-filter: blur(12px);
222235
-webkit-backdrop-filter: blur(12px);
223236
text-decoration: none;
224237
}
@@ -240,7 +253,7 @@ body {
240253
/* padding: 0 1.5rem 1.5rem; */
241254
gap: 0.5rem;
242255
margin-top: 30px;
243-
height: 100%;
256+
height: 100%;
244257
}
245258

246259
.mobile-user-section {
@@ -303,15 +316,15 @@ body {
303316
display: flex;
304317
padding: 5px;
305318
position: absolute;
306-
backdrop-filter:blur(12px);
307-
-webkit-backdrop-filter: blur(10px);
308-
top: 40px;
319+
backdrop-filter: blur(12px);
320+
-webkit-backdrop-filter: blur(10px);
321+
top: 40px;
309322
right: 0px;
310323
width: 45%;
311324
flex-direction: column;
312325
height: 90vh;
313326
border-radius: 10px;
314-
transform: translateX(0);
327+
transform: translateX(0);
315328
background: var(--header-bg, #2d2b2b);
316329
transform: translateX(120%);
317330
transition: transform 0.3s ease-in-out;
@@ -332,6 +345,4 @@ body {
332345
padding: 0.8rem 1rem;
333346
width: 100%;
334347
}
335-
336348
}
337-

src/components/Header.jsx

Lines changed: 79 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import React, { useState } from "react";
1+
import React, { useState, useEffect, useRef } from "react";
22
import { Link, NavLink } from "react-router-dom";
33
import { useAuth } from "./AuthContext";
44
import { signOut } from "firebase/auth";
55
import { auth } from "./firebase";
6-
import {
6+
import {
77
LuChartLine,
88
LuLayoutDashboard,
99
LuInfo,
@@ -14,7 +14,7 @@ import {
1414
LuMenu,
1515
LuX,
1616
} from "react-icons/lu";
17-
import { FaRegUserCircle, FaUserAlt } from "react-icons/fa";
17+
import { FaRegUserCircle, FaUserAlt } from "react-icons/fa";
1818
import "./Header.css";
1919
import ThemeToggle from "./ThemeToggle";
2020

@@ -23,9 +23,26 @@ const Header = () => {
2323
const [isMenuOpen, setIsMenuOpen] = useState(false);
2424
const [dashBoardOpen, setDashBoardOpen] = useState(false);
2525

26+
const dropdownRef = useRef(null);
27+
28+
// Close dropdown when clicking outside
29+
useEffect(() => {
30+
function handleClickOutside(event) {
31+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
32+
setDashBoardOpen(false);
33+
}
34+
}
35+
36+
document.addEventListener("mousedown", handleClickOutside);
37+
return () => {
38+
document.removeEventListener("mousedown", handleClickOutside);
39+
};
40+
}, []);
41+
2642
const handleLogout = () => {
2743
signOut(auth);
2844
setIsMenuOpen(false);
45+
setDashBoardOpen(false); // close dropdown on logout
2946
};
3047

3148
const toggleMenu = () => setIsMenuOpen(!isMenuOpen);
@@ -59,35 +76,40 @@ const Header = () => {
5976
</NavLink>
6077
</div>
6178

62-
63-
{/* //User-dashboard: */}
64-
<div className="nav-actions">
65-
<ThemeToggle className='toggle-theme' />
79+
{/* User Dashboard */}
80+
<div className="nav-actions" ref={dropdownRef}>
81+
<ThemeToggle className="toggle-theme" />
6682
<div className="user-dashboard">
67-
<FaRegUserCircle onClick={() => setDashBoardOpen(prev => !prev)}/>
83+
<FaRegUserCircle onClick={() => setDashBoardOpen(prev => !prev)} />
6884
</div>
69-
{dashBoardOpen ? <>
70-
{currentUser ? (
71-
<div className="user-section">
72-
<span className="welcome-message">{getUsername(currentUser.email).toUpperCase()}</span>
73-
<NavLink to='/profile' className="user-profile">
74-
<FaUserAlt /><span>Profile</span>
75-
</NavLink>
76-
<NavLink onClick={handleLogout} className="logout-button">
77-
<LuLogOut className="logout-icon" /><span>Logout</span>
78-
</NavLink>
79-
</div>
80-
) : (
81-
<div className="user-section">
82-
<NavLink to="/login" className="login-button" onClick={closeMenu}>
85+
<div className={`user-section ${dashBoardOpen ? "show" : ""}`}>
86+
{currentUser ? (
87+
<>
88+
<span className="welcome-message">{getUsername(currentUser.email).toUpperCase()}</span>
89+
<NavLink
90+
to="/profile"
91+
className="user-profile"
92+
onClick={() => setDashBoardOpen(false)}
93+
>
94+
<FaUserAlt /><span>Profile</span>
95+
</NavLink>
96+
<NavLink
97+
onClick={handleLogout}
98+
className="logout-button"
99+
>
100+
<LuLogOut className="logout-icon" /><span>Logout</span>
101+
</NavLink>
102+
</>
103+
) : (
104+
<NavLink
105+
to="/login"
106+
className="login-button"
107+
onClick={() => { closeMenu(); setDashBoardOpen(false); }}
108+
>
83109
<LuLogIn className="login-icon" /><span>Login</span>
84-
</NavLink>
85-
</div>
86-
)}
87-
88-
</>
89-
:
90-
<>{null}</>}
110+
</NavLink>
111+
)}
112+
</div>
91113
</div>
92114
</nav>
93115

@@ -101,7 +123,9 @@ const Header = () => {
101123

102124
{/* Mobile Dropdown Menu */}
103125
<nav className={`mobile-menu ${isMenuOpen ? "mobile-menu-open" : ""}`}>
104-
{currentUser && <h1 className="nav-link-email">{getUsername(currentUser?.email).toUpperCase()}</h1>}
126+
{currentUser && (
127+
<h1 className="nav-link-email">{getUsername(currentUser?.email).toUpperCase()}</h1>
128+
)}
105129

106130
<NavLink to="/" className="nav-link" onClick={closeMenu} end>
107131
<div className="nav-icon"><LuLayoutDashboard /><span>Home</span></div>
@@ -115,27 +139,36 @@ const Header = () => {
115139
<NavLink to="/watchlist" className="nav-link" onClick={closeMenu}>
116140
<div className="nav-icon"><LuClipboardList /><span>Watchlist</span></div>
117141
</NavLink>
118-
{currentUser ?
119-
<>
120-
<NavLink to="/profile" className="nav-link" onClick={closeMenu}>
121-
<div className="nav-icon"><FaUserAlt /><span>Profile</span></div>
122-
</NavLink>
123-
<NavLink onClick={() => {handleLogout(); closeMenu()}} className="logout-button">
124-
<div className="nav-icon"><LuLogOut /><span>Logout</span></div>
125-
</NavLink>
126-
</>
127-
:
128-
<>
129-
<NavLink to="/login" className="logout-button" onClick={closeMenu}>
142+
143+
{currentUser ? (
144+
<>
145+
<NavLink
146+
to="/profile"
147+
className="nav-link"
148+
onClick={() => { closeMenu(); setDashBoardOpen(false); }}
149+
>
150+
<div className="nav-icon"><FaUserAlt /><span>Profile</span></div>
151+
</NavLink>
152+
<NavLink
153+
onClick={() => { handleLogout(); closeMenu(); setDashBoardOpen(false); }}
154+
className="logout-button"
155+
>
156+
<div className="nav-icon"><LuLogOut /><span>Logout</span></div>
157+
</NavLink>
158+
</>
159+
) : (
160+
<NavLink
161+
to="/login"
162+
className="logout-button"
163+
onClick={() => { closeMenu(); setDashBoardOpen(false); }}
164+
>
130165
<div className="nav-icon"><LuLogIn /><span>Login</span></div>
131166
</NavLink>
132-
</>}
133-
134-
167+
)}
135168
</nav>
136169
</div>
137170
</header>
138171
);
139172
};
140173

141-
export default Header;
174+
export default Header;

0 commit comments

Comments
 (0)