Skip to content

Commit de1c733

Browse files
committed
feat: implement user dropdown functionality with click outside detection
1 parent 591fa06 commit de1c733

File tree

1 file changed

+60
-20
lines changed

1 file changed

+60
-20
lines changed

src/routes/(app)/Sidebar.svelte

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
3333
let isDark = $state(false);
3434
let userDropdownOpen = $state(false);
35+
let dropdownRef = $state();
3536
3637
const closeDrawer = () => {
3738
drawerHidden = true;
@@ -46,6 +47,38 @@
4647
userDropdownOpen = !userDropdownOpen;
4748
};
4849
50+
const handleSettingsLinkClick = (event, href) => {
51+
event.preventDefault();
52+
event.stopPropagation();
53+
54+
// Close the dropdown
55+
userDropdownOpen = false;
56+
57+
// Navigate to the intended URL
58+
window.location.href = href;
59+
};
60+
61+
const handleDropdownClick = (event) => {
62+
// Prevent clicks inside dropdown from bubbling up
63+
event.stopPropagation();
64+
};
65+
66+
const handleClickOutside = (event) => {
67+
if (userDropdownOpen && dropdownRef && !dropdownRef.contains(event.target)) {
68+
userDropdownOpen = false;
69+
}
70+
};
71+
72+
// Add click outside listener
73+
$effect(() => {
74+
if (typeof document !== 'undefined') {
75+
document.addEventListener('click', handleClickOutside);
76+
return () => {
77+
document.removeEventListener('click', handleClickOutside);
78+
};
79+
}
80+
});
81+
4982
let mainSidebarUrl = $derived($page.url.pathname);
5083
let openDropdowns = $state({});
5184
@@ -209,8 +242,8 @@
209242
</nav>
210243
</div>
211244
212-
<!-- User profile section - moved to bottom -->
213-
<div class="p-4 border-t border-gray-200 dark:border-gray-700">
245+
<!-- settings section -->
246+
<div class="p-4 border-t border-gray-200 dark:border-gray-700" bind:this={dropdownRef}>
214247
<div class="flex items-center gap-3 mb-3">
215248
<img class="w-10 h-10 rounded-lg object-cover" src={user.profilePhoto} alt="User avatar" />
216249
<div class="flex-1 min-w-0">
@@ -242,38 +275,45 @@
242275
</button>
243276
</div>
244277
245-
<!-- User dropdown menu -->
278+
<!-- settings dropdown menu -->
246279
{#if userDropdownOpen}
247-
<div class="mt-3 p-1 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
248-
<a
249-
href="/app/profile"
250-
class="flex items-center gap-3 px-3 py-2 text-sm text-gray-700 hover:bg-white dark:text-gray-300 dark:hover:bg-gray-700 rounded transition-colors"
280+
<div
281+
class="mt-3 p-1 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700"
282+
onclick={handleDropdownClick}
283+
>
284+
<button
285+
type="button"
286+
onclick={(e) => handleSettingsLinkClick(e, '/app/profile')}
287+
class="flex items-center gap-3 px-3 py-2 text-sm text-gray-700 hover:bg-white dark:text-gray-300 dark:hover:bg-gray-700 rounded transition-colors w-full text-left"
251288
>
252289
<User class="w-4 h-4" />
253290
Profile
254-
</a>
255-
<a
256-
href="/app/users"
257-
class="flex items-center gap-3 px-3 py-2 text-sm text-gray-700 hover:bg-white dark:text-gray-300 dark:hover:bg-gray-700 rounded transition-colors"
291+
</button>
292+
<button
293+
type="button"
294+
onclick={(e) => handleSettingsLinkClick(e, '/app/users')}
295+
class="flex items-center gap-3 px-3 py-2 text-sm text-gray-700 hover:bg-white dark:text-gray-300 dark:hover:bg-gray-700 rounded transition-colors w-full text-left"
258296
>
259297
<Users class="w-4 h-4" />
260298
Users
261-
</a>
262-
<a
263-
href="/org"
264-
class="flex items-center gap-3 px-3 py-2 text-sm text-gray-700 hover:bg-white dark:text-gray-300 dark:hover:bg-gray-700 rounded transition-colors"
299+
</button>
300+
<button
301+
type="button"
302+
onclick={(e) => handleSettingsLinkClick(e, '/org')}
303+
class="flex items-center gap-3 px-3 py-2 text-sm text-gray-700 hover:bg-white dark:text-gray-300 dark:hover:bg-gray-700 rounded transition-colors w-full text-left"
265304
>
266305
<Building class="w-4 h-4" />
267306
Organizations
268-
</a>
307+
</button>
269308
<hr class="my-1 border-gray-200 dark:border-gray-600" />
270-
<a
271-
href="/logout"
272-
class="flex items-center gap-3 px-3 py-2 text-sm text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900/20 rounded transition-colors"
309+
<button
310+
type="button"
311+
onclick={(e) => handleSettingsLinkClick(e, '/logout')}
312+
class="flex items-center gap-3 px-3 py-2 text-sm text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900/20 rounded transition-colors w-full text-left"
273313
>
274314
<LogOut class="w-4 h-4" />
275315
Sign out
276-
</a>
316+
</button>
277317
</div>
278318
{/if}
279319
</div>

0 commit comments

Comments
 (0)