the-tip-top-frontend/components/Header.tsx
soufiane 33b9b05e2f fix: simplify mobile navigation
- Remove Inscription/Connexion buttons from hero on mobile
- Simplify Participer button on mobile menu (direct link instead of dropdown)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 14:08:17 +01:00

314 lines
14 KiB
TypeScript

'use client';
import Link from 'next/link';
import { useAuth } from '@/contexts/AuthContext';
import Button from './Button';
import Logo from './Logo';
import { ROUTES } from '@/utils/constants';
import { useState, useRef, useEffect } from 'react';
export default function Header() {
const { user, isAuthenticated, logout } = useAuth();
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [isParticiperDropdownOpen, setIsParticiperDropdownOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
const toggleMobileMenu = () => {
setIsMobileMenuOpen(!isMobileMenuOpen);
};
// Close dropdown when clicking outside
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsParticiperDropdownOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
const getDashboardRoute = () => {
if (!user) return ROUTES.HOME;
switch (user.role) {
case 'ADMIN':
return ROUTES.ADMIN_DASHBOARD;
case 'EMPLOYEE':
return ROUTES.EMPLOYEE_DASHBOARD;
default:
return ROUTES.CLIENT_DASHBOARD;
}
};
return (
<header className="bg-gradient-to-r from-beige-100 to-beige-50 sticky top-0 z-50 shadow-lg border-b-2 border-beige-300">
{/* Main Header */}
<div className="container mx-auto px-4">
<div className="flex items-center justify-between h-18 gap-4">
{/* Logo */}
<Link href={ROUTES.HOME} className="group flex items-center gap-3 flex-shrink-0">
<Logo size="md" showText={false} className="group-hover:scale-105 transition-transform" />
</Link>
{/* Desktop Navigation */}
<nav className="hidden md:flex items-center gap-6 flex-shrink-0">
<Link
href={ROUTES.HOME}
className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
>
Accueil
</Link>
<Link
href={ROUTES.LOTS}
className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
>
Lots à gagner
</Link>
<Link
href="/rules"
className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
>
Règlement
</Link>
<Link
href="/about"
className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
>
À propos
</Link>
<Link
href="/contact"
className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
>
Contact
</Link>
{/* Participer with Dropdown - Green Button */}
{isAuthenticated ? (
<Link
href={ROUTES.GAME}
className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-2 rounded-lg transition-all duration-300 hover:shadow-[0_0_20px_rgba(11,96,41,0.4)] shadow-lg whitespace-nowrap"
>
Participer
</Link>
) : (
<div className="relative" ref={dropdownRef}>
<button
onClick={() => setIsParticiperDropdownOpen(!isParticiperDropdownOpen)}
className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-2 rounded-lg transition-all duration-300 hover:shadow-[0_0_20px_rgba(11,96,41,0.4)] shadow-lg flex items-center justify-center gap-2 whitespace-nowrap"
>
Participer
<svg
className={`w-4 h-4 flex-shrink-0 transition-transform duration-300 ${isParticiperDropdownOpen ? 'rotate-180' : ''}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
{isParticiperDropdownOpen && (
<div className="absolute right-0 mt-2 w-56 bg-white rounded-xl shadow-2xl border-2 border-primary-200 py-2 z-50 animate-fadeIn overflow-hidden">
<Link
href={ROUTES.LOGIN}
onClick={() => setIsParticiperDropdownOpen(false)}
className="block px-4 py-3 text-gray-700 hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 hover:text-primary-600 transition-all duration-300 hover:pl-6 hover:shadow-inner"
>
<span className="font-bold block">Connexion</span>
<p className="text-xs text-gray-500 mt-0.5">J'ai déjà un compte</p>
</Link>
<div className="border-t border-primary-100 my-1"></div>
<Link
href={ROUTES.REGISTER}
onClick={() => setIsParticiperDropdownOpen(false)}
className="block px-4 py-3 text-gray-700 hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 hover:text-primary-600 transition-all duration-300 hover:pl-6 hover:shadow-inner"
>
<span className="font-bold block">Inscription</span>
<p className="text-xs text-gray-500 mt-0.5">Créer un nouveau compte</p>
</Link>
</div>
)}
</div>
)}
</nav>
{/* Desktop Auth Buttons */}
<div className="hidden md:flex items-center gap-3 flex-shrink-0">
{isAuthenticated && (
<>
<Link href={getDashboardRoute()}>
<div className="flex flex-col items-start bg-gradient-to-br from-white to-beige-100 text-beige-800 hover:shadow-lg px-4 py-2.5 rounded-xl transition-all border-2 border-beige-300 hover:border-primary-400 group min-w-0 flex-shrink-0">
<span className="text-sm font-bold group-hover:text-primary-500 transition-colors whitespace-nowrap overflow-hidden text-ellipsis max-w-[200px]">{user?.firstName} {user?.lastName}</span>
<span className="text-xs text-beige-600 whitespace-nowrap overflow-hidden text-ellipsis max-w-[200px]">{user?.email}</span>
</div>
</Link>
<Link href={ROUTES.PROFILE}>
<button className="flex items-center justify-center gap-2 bg-white hover:bg-gradient-to-r hover:from-primary-500 hover:to-primary-600 text-beige-800 hover:text-white font-semibold px-5 py-2.5 rounded-xl transition-all duration-300 border-2 border-beige-300 hover:border-primary-500 hover:shadow-lg whitespace-nowrap">
<svg className="w-5 h-5 flex-shrink-0" 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" />
</svg>
Profil
</button>
</Link>
{user?.role === 'CLIENT' && (
<Link href={ROUTES.HISTORY}>
<button className="flex items-center justify-center gap-2 bg-white hover:bg-gradient-to-r hover:from-primary-500 hover:to-primary-600 text-beige-800 hover:text-white font-semibold px-5 py-2.5 rounded-xl transition-all duration-300 border-2 border-beige-300 hover:border-primary-500 hover:shadow-lg whitespace-nowrap">
<svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" />
</svg>
Mes gains
</button>
</Link>
)}
<button
onClick={logout}
className="flex items-center justify-center gap-2 bg-white hover:bg-gradient-to-r hover:from-red-500 hover:to-red-600 text-beige-800 hover:text-white font-semibold px-5 py-2.5 rounded-xl transition-all duration-300 border-2 border-beige-300 hover:border-red-500 hover:shadow-lg whitespace-nowrap"
>
<svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg>
Déconnexion
</button>
</>
)}
</div>
{/* Mobile Menu Button */}
<button
onClick={toggleMobileMenu}
className="md:hidden p-2 text-beige-800 hover:text-primary-500 focus:outline-none"
aria-label="Toggle menu"
>
{isMobileMenuOpen ? (
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
) : (
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
)}
</button>
</div>
{/* Mobile Menu */}
{isMobileMenuOpen && (
<div className="md:hidden py-4 border-t border-beige-300 animate-fadeIn">
<nav className="flex flex-col gap-3">
<Link
href={ROUTES.HOME}
className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Accueil
</Link>
<Link
href={ROUTES.GAME}
className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Jeu
</Link>
<Link
href={ROUTES.LOTS}
className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Lots
</Link>
<Link
href="/about"
className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
À propos
</Link>
<Link
href="/contact"
className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Contact
</Link>
{/* Participer Mobile - Green Button */}
<Link
href={isAuthenticated ? ROUTES.GAME : ROUTES.REGISTER}
className="bg-primary-500 hover:bg-primary-600 text-white font-semibold px-4 py-3 rounded-lg transition-all hover:shadow-lg text-center block whitespace-nowrap"
onClick={() => setIsMobileMenuOpen(false)}
>
Participer
</Link>
{isAuthenticated && (
<div className="border-t border-beige-300 pt-3 mt-3 space-y-2">
<Link
href={getDashboardRoute()}
onClick={() => setIsMobileMenuOpen(false)}
>
<button className="w-full flex flex-col items-center bg-white text-primary-700 hover:bg-secondary-400 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap">
<span className="text-sm">{user?.firstName} {user?.lastName}</span>
<span className="text-xs font-normal opacity-80">{user?.email}</span>
</button>
</Link>
<Link
href={ROUTES.PROFILE}
onClick={() => setIsMobileMenuOpen(false)}
>
<button className="w-full flex items-center justify-center gap-2 bg-white text-primary-700 hover:bg-secondary-400 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap">
Profil
</button>
</Link>
{user?.role === 'CLIENT' && (
<Link
href={ROUTES.HISTORY}
onClick={() => setIsMobileMenuOpen(false)}
>
<button className="w-full flex items-center justify-center gap-2 bg-white text-primary-700 hover:bg-secondary-400 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap">
Mes gains
</button>
</Link>
)}
<button
onClick={() => {
logout();
setIsMobileMenuOpen(false);
}}
className="w-full flex items-center justify-center gap-2 bg-white text-primary-700 hover:bg-red-600 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap"
>
Déconnexion
</button>
</div>
)}
</nav>
</div>
)}
</div>
</header>
);
}