the-tip-top-frontend/components/Header.tsx
soufiane 510eab7794 feat: enhance homepage with animated tea icons and improve branding
Add animated tea icons background with 35 falling icons, update styling to match theme, and streamline branding across header and footer.

Changes:
- Add 35 animated tea icons with falling animation (no rotation)
- Create fallDown animation with gentle horizontal oscillation
- Add new homepage components (CountdownTimer, GamePeriod, GrandPrize, AboutContest)
- Include tea icon images (teapot-green, tea-cup, gift-box, tea-leaves, teapot-pink)
- Remove "Thé Tip Top" text branding from header and footer (keep logo only)
- Add Pinterest social media icon to footer
- Update button color scheme to match golden/beige theme (#d4a574, #c4956a)
- Increase icon opacity to 50% for better visibility

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 16:46:57 +01:00

349 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-[#f5f5f0] to-[#faf9f5] sticky top-0 z-50 shadow-lg border-b-2 border-[#e5e4dc]">
{/* 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 flex items-center gap-3">
<Logo size="md" showText={false} 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-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors"
>
Accueil
</Link>
<Link
href={ROUTES.LOTS}
className="text-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors"
>
Loto à gagner
</Link>
<Link
href="/rules"
className="text-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors"
>
Règlement
</Link>
<Link
href="/faq"
className="text-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors"
>
FAQ
</Link>
<Link
href="/contact"
className="text-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors"
>
Contact
</Link>
{/* Participer with Dropdown - Doré Button */}
{isAuthenticated ? (
<Link
href={ROUTES.GAME}
className="bg-[#d4a574] hover:bg-[#c4956a] 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-[#d4a574] hover:bg-[#c4956a] 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={getDashboardRoute()}>
<button className="flex flex-col items-center bg-white text-[#5a5a4e] hover:bg-[#d4a574] hover:text-white font-semibold px-4 py-2 rounded-lg transition-all border border-[#e5e4dc]">
<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}>
<button className="flex items-center gap-2 bg-white text-[#5a5a4e] hover:bg-[#d4a574] hover:text-white font-semibold px-4 py-2 rounded-lg transition-all border border-[#e5e4dc]">
Profil
</button>
</Link>
{user?.role === 'CLIENT' && (
<Link href={ROUTES.HISTORY}>
<button className="flex items-center gap-2 bg-white text-[#5a5a4e] hover:bg-[#d4a574] hover:text-white font-semibold px-4 py-2 rounded-lg transition-all border border-[#e5e4dc]">
Mes gains
</button>
</Link>
)}
<button
onClick={logout}
className="flex items-center gap-2 bg-white text-[#5a5a4e] hover:bg-red-600 hover:text-white font-semibold px-4 py-2 rounded-lg transition-all border border-[#e5e4dc]"
>
Déconnexion
</button>
</>
)}
</div>
{/* Mobile Menu Button */}
<button
onClick={toggleMobileMenu}
className="md:hidden p-2 text-[#5a5a4e] hover:text-[#d4a574] 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-white/20 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-[#1a4d2e] hover:bg-[#f59e0b] hover:text-white font-semibold px-4 py-3 rounded-lg transition-all">
<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-[#1a4d2e] hover:bg-[#f59e0b] hover:text-white font-semibold px-4 py-3 rounded-lg transition-all">
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-[#1a4d2e] hover:bg-[#f59e0b] hover:text-white font-semibold px-4 py-3 rounded-lg transition-all">
Mes gains
</button>
</Link>
)}
<button
onClick={() => {
logout();
setIsMobileMenuOpen(false);
}}
className="w-full flex items-center justify-center gap-2 bg-white text-[#1a4d2e] hover:bg-red-600 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all"
>
Déconnexion
</button>
</div>
)}
</nav>
</div>
)}
</div>
</header>
);
}