feat: update AuthButton and Header for improved user experience

- Increased avatar and icon sizes in `AuthButton` for better visibility.
- Integrated session handling in `Header` to display user profile link and sign-out button when authenticated, enhancing mobile menu functionality.
- Refactored mobile menu overlay to a modal for improved usability.
This commit is contained in:
Julien Froidefond
2025-10-01 13:56:15 +02:00
parent f13ed5b8d9
commit 5b3f705689
2 changed files with 41 additions and 11 deletions

View File

@@ -41,10 +41,10 @@ export function AuthButton() {
<img <img
src={session.user.avatar} src={session.user.avatar}
alt="Avatar" alt="Avatar"
className="w-4 h-4 rounded-full object-cover" className="w-10 h-10 rounded-full object-cover"
/> />
) : ( ) : (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg> </svg>
)} )}

View File

@@ -9,6 +9,7 @@ import { Theme } from '@/lib/theme-config';
import { THEME_CONFIG, getThemeMetadata } from '@/lib/theme-config'; import { THEME_CONFIG, getThemeMetadata } from '@/lib/theme-config';
import { useKeyboardShortcutsModal } from '@/contexts/KeyboardShortcutsContext'; import { useKeyboardShortcutsModal } from '@/contexts/KeyboardShortcutsContext';
import { AuthButton } from '@/components/AuthButton'; import { AuthButton } from '@/components/AuthButton';
import { useSession, signOut } from 'next-auth/react';
interface HeaderProps { interface HeaderProps {
title?: string; title?: string;
@@ -23,6 +24,7 @@ export function Header({ title = "TowerControl", subtitle = "Task Management", s
const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [themeDropdownOpen, setThemeDropdownOpen] = useState(false); const [themeDropdownOpen, setThemeDropdownOpen] = useState(false);
const { openModal: openShortcutsModal } = useKeyboardShortcutsModal(); const { openModal: openShortcutsModal } = useKeyboardShortcutsModal();
const { data: session } = useSession();
// Liste des thèmes disponibles avec leurs labels et icônes // Liste des thèmes disponibles avec leurs labels et icônes
const themes: { value: Theme; label: string; icon: string }[] = THEME_CONFIG.allThemes.map(themeValue => { const themes: { value: Theme; label: string; icon: string }[] = THEME_CONFIG.allThemes.map(themeValue => {
@@ -76,7 +78,7 @@ export function Header({ title = "TowerControl", subtitle = "Task Management", s
]; ];
return ( return (
<header className="relative z-50 bg-[var(--card)]/80 backdrop-blur-sm border-b border-[var(--border)]/50 shadow-lg shadow-[var(--card)]/20"> <header className="relative z-50 bg-[var(--card)]/80 border-b border-[var(--border)]/50 shadow-lg shadow-[var(--card)]/20">
<div className="container mx-auto px-4 sm:px-6 py-4"> <div className="container mx-auto px-4 sm:px-6 py-4">
{/* Layout mobile/tablette */} {/* Layout mobile/tablette */}
<div className="lg:hidden"> <div className="lg:hidden">
@@ -284,17 +286,18 @@ export function Header({ title = "TowerControl", subtitle = "Task Management", s
</div> </div>
{/* Menu mobile/tablette en overlay fixe */} {/* Menu mobile/tablette en modal */}
{mobileMenuOpen && ( {mobileMenuOpen && (
<> <div className="lg:hidden fixed inset-0 z-[9999] flex items-start justify-center pt-20">
{/* Backdrop pour fermer le menu */} {/* Backdrop */}
<div <div
className="lg:hidden fixed inset-0 bg-black/20 backdrop-blur-sm z-[100]" className="absolute inset-0 bg-black/50"
onClick={() => setMobileMenuOpen(false)} onClick={() => setMobileMenuOpen(false)}
/> />
{/* Menu */}
<div className="lg:hidden fixed top-[80px] left-0 right-0 bg-[var(--card)]/98 backdrop-blur-md border-b border-[var(--border)]/50 shadow-xl z-[101]"> {/* Modal content */}
<nav className="container mx-auto px-4 py-6"> <div className="relative bg-[var(--card)] border border-[var(--border)] rounded-lg shadow-xl mx-4 w-full max-w-sm">
<nav className="p-6">
<div className="space-y-3"> <div className="space-y-3">
{navLinks.map(({ href, label }) => ( {navLinks.map(({ href, label }) => (
<Link <Link
@@ -306,10 +309,37 @@ export function Header({ title = "TowerControl", subtitle = "Task Management", s
{label} {label}
</Link> </Link>
))} ))}
{/* Séparateur */}
{session && (
<>
<div className="border-t border-[var(--border)]/30 my-4"></div>
{/* Lien profil */}
<Link
href="/profile"
className={getMobileLinkClasses('/profile')}
onClick={() => setMobileMenuOpen(false)}
>
👤 Profil
</Link>
{/* Bouton déconnexion */}
<button
onClick={() => {
signOut({ callbackUrl: '/login' });
setMobileMenuOpen(false);
}}
className="font-mono text-sm uppercase tracking-wider transition-colors px-4 py-3 rounded-md block w-full text-left text-[var(--destructive)] hover:text-[var(--destructive)] hover:bg-[var(--destructive)]/10"
>
🚪 Déconnexion
</button>
</>
)}
</div> </div>
</nav> </nav>
</div> </div>
</> </div>
)} )}
</header> </header>
); );