Sebebeb commited on
Commit
eb22aa0
·
1 Parent(s): 1fe9bcd

Update AppLayout.tsx

Browse files
client/src/components/Layout/AppLayout.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
2
  import { useAuthStore } from '../../store/authStore';
3
  import { useNavigate, useLocation } from 'react-router-dom';
4
  import {
@@ -17,6 +17,18 @@ export default function AppLayout({ children, sidebarContent, showSidebar }: App
17
  const navigate = useNavigate();
18
  const location = useLocation();
19
  const isEditor = location.pathname.startsWith('/project/');
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  return (
22
  <div className="min-h-screen bg-surface-950 flex flex-col">
@@ -46,16 +58,33 @@ export default function AppLayout({ children, sidebarContent, showSidebar }: App
46
  <span className="text-surface-300 text-sm hidden md:block">
47
  {user.username}
48
  </span>
49
- <div className="w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white text-sm font-medium">
50
- {user.username.charAt(0).toUpperCase()}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  </div>
52
- <button
53
- onClick={() => { logout(); navigate('/login'); }}
54
- className="btn-ghost p-2"
55
- title="Logout"
56
- >
57
- <LogOut className="w-4 h-4" />
58
- </button>
59
  </>
60
  )}
61
  </div>
 
1
+ import { ReactNode, useState, useRef, useEffect } from 'react';
2
  import { useAuthStore } from '../../store/authStore';
3
  import { useNavigate, useLocation } from 'react-router-dom';
4
  import {
 
17
  const navigate = useNavigate();
18
  const location = useLocation();
19
  const isEditor = location.pathname.startsWith('/project/');
20
+ const [showProfileMenu, setShowProfileMenu] = useState(false);
21
+ const profileRef = useRef<HTMLDivElement>(null);
22
+
23
+ useEffect(() => {
24
+ const handleClickOutside = (e: MouseEvent) => {
25
+ if (profileRef.current && !profileRef.current.contains(e.target as Node)) {
26
+ setShowProfileMenu(false);
27
+ }
28
+ };
29
+ document.addEventListener('mousedown', handleClickOutside);
30
+ return () => document.removeEventListener('mousedown', handleClickOutside);
31
+ }, []);
32
 
33
  return (
34
  <div className="min-h-screen bg-surface-950 flex flex-col">
 
58
  <span className="text-surface-300 text-sm hidden md:block">
59
  {user.username}
60
  </span>
61
+ <div className="relative" ref={profileRef}>
62
+ <button
63
+ onClick={() => setShowProfileMenu(!showProfileMenu)}
64
+ className="w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white text-sm font-medium hover:bg-primary-500 transition-colors"
65
+ >
66
+ {user.username.charAt(0).toUpperCase()}
67
+ </button>
68
+ {showProfileMenu && (
69
+ <div className="absolute right-0 top-full mt-2 w-48 bg-surface-800 border border-surface-700 rounded-lg shadow-xl py-1 z-50">
70
+ <button
71
+ onClick={() => { setShowProfileMenu(false); /* TODO: navigate to settings */ }}
72
+ className="w-full flex items-center gap-2 px-4 py-2 text-sm text-surface-200 hover:bg-surface-700 transition-colors"
73
+ >
74
+ <Settings className="w-4 h-4" />
75
+ Settings
76
+ </button>
77
+ <div className="border-t border-surface-700 my-1" />
78
+ <button
79
+ onClick={() => { logout(); navigate('/login'); }}
80
+ className="w-full flex items-center gap-2 px-4 py-2 text-sm text-red-400 hover:bg-surface-700 transition-colors"
81
+ >
82
+ <LogOut className="w-4 h-4" />
83
+ Logout
84
+ </button>
85
+ </div>
86
+ )}
87
  </div>
 
 
 
 
 
 
 
88
  </>
89
  )}
90
  </div>