the-tip-top-frontend/components/Header.tsx
soufiane 6d95f02dee feat: redesign header and footer with green/orange theme
Updated Header:
- Dark green gradient background (#1a4d2e to #2d5a3d)
- White text with orange hover (#f59e0b)
- Orange "Participer" button instead of green
- Updated menu labels to match homepage design

Updated Footer:
- Dark green gradient background matching header
- Orange section titles (#f59e0b)
- Added trust badges (Paiement sécurisé, Livraison rapide, RGPD)
- Consistent branding with homepage

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:49:25 +01:00

339 lines
13 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-[#1a4d2e] to-[#2d5a3d] sticky top-0 z-50 shadow-lg">
{/* Main Header */}
<div className="container mx-auto px-4">
<div className="flex items-center justify-between h-18">
{/* Logo */}
<Link href={ROUTES.HOME} className="group">
<Logo size="md" showText={true} className="group-hover:scale-105 transition-transform" />
</Link>
{/* Desktop Navigation */}
<nav className="hidden md:flex items-center gap-6">
<Link
href={ROUTES.HOME}
className="text-white hover:text-[#f59e0b] font-medium transition-colors"
>
Accueil
</Link>
<Link
href={ROUTES.GAME}
className="text-white hover:text-[#f59e0b] font-medium transition-colors"
>
Loto à gagner
</Link>
<Link
href={ROUTES.LOTS}
className="text-white hover:text-[#f59e0b] font-medium transition-colors"
>
Règlement
</Link>
<Link
href="/faq"
className="text-white hover:text-[#f59e0b] font-medium transition-colors"
>
FAQ
</Link>
<Link
href="/about"
className="text-white hover:text-[#f59e0b] font-medium transition-colors"
>
Gagnants
</Link>
<Link
href="/contact"
className="text-white hover:text-[#f59e0b] font-medium transition-colors"
>
Contact
</Link>
{/* Participer with Dropdown - Orange Button */}
{isAuthenticated ? (
<Link
href={ROUTES.GAME}
className="bg-[#f59e0b] hover:bg-[#d97706] text-white font-bold px-6 py-2 rounded-lg transition-all hover:shadow-xl"
>
Participer
</Link>
) : (
<div className="relative" ref={dropdownRef}>
<button
onClick={() => setIsParticiperDropdownOpen(!isParticiperDropdownOpen)}
className="bg-[#f59e0b] hover:bg-[#d97706] text-white font-bold px-6 py-2 rounded-lg transition-all hover:shadow-xl flex items-center gap-2"
>
Participer
<svg
className={`w-4 h-4 transition-transform ${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-lg shadow-xl border border-gray-200 py-2 z-50 animate-fadeIn">
<Link
href={ROUTES.LOGIN}
onClick={() => setIsParticiperDropdownOpen(false)}
className="block px-4 py-3 text-gray-700 hover:bg-green-50 hover:text-green-700 transition-colors"
>
<span className="font-medium 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-gray-100 my-1"></div>
<Link
href={ROUTES.REGISTER}
onClick={() => setIsParticiperDropdownOpen(false)}
className="block px-4 py-3 text-gray-700 hover:bg-green-50 hover:text-green-700 transition-colors"
>
<span className="font-medium 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">
{isAuthenticated && (
<>
<Link href={ROUTES.PROFILE}>
<Button variant="outline" size="sm">
👤 {user?.firstName}
</Button>
</Link>
{user?.role === 'CLIENT' && (
<Link href={ROUTES.HISTORY}>
<Button variant="outline" size="sm">
🏆 Mes gains
</Button>
</Link>
)}
<Button variant="outline" size="sm" onClick={logout}>
Déconnexion
</Button>
</>
)}
</div>
{/* Mobile Menu Button */}
<button
onClick={toggleMobileMenu}
className="md:hidden p-2 text-gray-600 hover:text-gray-900 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-gray-200 animate-fadeIn">
<nav className="flex flex-col gap-3">
<Link
href={ROUTES.HOME}
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Accueil
</Link>
<Link
href={ROUTES.GAME}
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Jeu
</Link>
<Link
href={ROUTES.LOTS}
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Gains
</Link>
<Link
href="/about"
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
À propos
</Link>
<Link
href="/contact"
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Contact
</Link>
{/* Participer Mobile - Green Button */}
{isAuthenticated ? (
<Link
href={ROUTES.GAME}
className="bg-green-600 hover:bg-green-700 text-white font-semibold px-4 py-3 rounded-lg transition-all hover:shadow-lg text-center block"
onClick={() => setIsMobileMenuOpen(false)}
>
🎯 Participer
</Link>
) : (
<div>
<button
onClick={() => setIsParticiperDropdownOpen(!isParticiperDropdownOpen)}
className="bg-green-600 hover:bg-green-700 text-white font-semibold px-4 py-3 rounded-lg transition-all hover:shadow-lg flex items-center justify-center gap-2 w-full"
>
🎯 Participer
<svg
className={`w-4 h-4 transition-transform ${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="mt-2 space-y-2 animate-fadeIn bg-green-50 rounded-lg p-3">
<Link
href={ROUTES.LOGIN}
onClick={() => {
setIsMobileMenuOpen(false);
setIsParticiperDropdownOpen(false);
}}
className="block text-green-800 hover:text-green-900 font-medium py-2 px-3 bg-white rounded-md hover:bg-green-100 transition-colors"
>
→ Connexion
</Link>
<Link
href={ROUTES.REGISTER}
onClick={() => {
setIsMobileMenuOpen(false);
setIsParticiperDropdownOpen(false);
}}
className="block text-green-800 hover:text-green-900 font-medium py-2 px-3 bg-white rounded-md hover:bg-green-100 transition-colors"
>
→ Inscription
</Link>
</div>
)}
</div>
)}
{isAuthenticated && (
<div className="border-t border-gray-200 pt-3 mt-3 space-y-2">
<Link
href={ROUTES.PROFILE}
onClick={() => setIsMobileMenuOpen(false)}
>
<Button variant="outline" size="sm" fullWidth>
👤 {user?.firstName}
</Button>
</Link>
{user?.role === 'CLIENT' && (
<Link
href={ROUTES.HISTORY}
onClick={() => setIsMobileMenuOpen(false)}
>
<Button variant="outline" size="sm" fullWidth>
🏆 Mes gains
</Button>
</Link>
)}
<Button
variant="outline"
size="sm"
fullWidth
onClick={() => {
logout();
setIsMobileMenuOpen(false);
}}
>
Déconnexion
</Button>
</div>
)}
</nav>
</div>
)}
</div>
</header>
);
}