feat: add src/components/Header.tsx
This commit is contained in:
parent
18abd70301
commit
522fa79e22
|
|
@ -0,0 +1,114 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Menu, X, Anchor } from 'lucide-react';
|
||||||
|
|
||||||
|
interface HeaderProps {
|
||||||
|
scrolled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const navLinks = [
|
||||||
|
{ label: 'Accueil', href: '#accueil' },
|
||||||
|
{ label: 'À Propos', href: '#apropos' },
|
||||||
|
{ label: 'Histoire', href: '#histoire' },
|
||||||
|
{ label: 'Galerie', href: '#galerie' },
|
||||||
|
{ label: 'Événements', href: '#evenements' },
|
||||||
|
{ label: 'Contact', href: '#contact' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const Header: React.FC<HeaderProps> = ({ scrolled }) => {
|
||||||
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
|
|
||||||
|
const handleNavClick = (href: string) => {
|
||||||
|
setMenuOpen(false);
|
||||||
|
const el = document.querySelector(href);
|
||||||
|
if (el) el.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header
|
||||||
|
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-400 ${
|
||||||
|
scrolled
|
||||||
|
? 'bg-marine-900 shadow-xl py-2'
|
||||||
|
: 'bg-marine-900/80 backdrop-blur-sm py-4'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between">
|
||||||
|
{/* Logo */}
|
||||||
|
<a
|
||||||
|
href="#accueil"
|
||||||
|
onClick={(e) => { e.preventDefault(); handleNavClick('#accueil'); }}
|
||||||
|
className="flex items-center gap-3 group"
|
||||||
|
aria-label="Accueil AATMTC"
|
||||||
|
>
|
||||||
|
<div className="bg-gold-500 group-hover:bg-gold-400 transition-colors p-2 rounded-sm">
|
||||||
|
<Anchor className="w-6 h-6 text-white" />
|
||||||
|
</div>
|
||||||
|
<div className="leading-tight">
|
||||||
|
<div className="text-white font-bold text-sm tracking-widest uppercase">AATMTC</div>
|
||||||
|
<div className="text-gold-400 text-xs tracking-wide hidden sm:block">Troupes de Marine · Télégraphistes</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{/* Desktop Nav */}
|
||||||
|
<nav className="hidden lg:flex items-center gap-1" role="navigation" aria-label="Navigation principale">
|
||||||
|
{navLinks.map((link) => (
|
||||||
|
<a
|
||||||
|
key={link.href}
|
||||||
|
href={link.href}
|
||||||
|
onClick={(e) => { e.preventDefault(); handleNavClick(link.href); }}
|
||||||
|
className="text-gray-200 hover:text-gold-400 transition-colors px-4 py-2 text-sm font-medium tracking-wide uppercase relative group"
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
<span className="absolute bottom-1 left-4 right-4 h-0.5 bg-gold-400 scale-x-0 group-hover:scale-x-100 transition-transform origin-left duration-300" />
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
<a
|
||||||
|
href="#contact"
|
||||||
|
onClick={(e) => { e.preventDefault(); handleNavClick('#contact'); }}
|
||||||
|
className="ml-4 bg-gold-500 hover:bg-gold-400 text-white text-sm font-semibold px-5 py-2 rounded-sm transition-colors tracking-wide uppercase"
|
||||||
|
>
|
||||||
|
Nous rejoindre
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{/* Mobile Hamburger */}
|
||||||
|
<button
|
||||||
|
className="lg:hidden text-white p-2 focus:outline-none focus:ring-2 focus:ring-gold-400 rounded"
|
||||||
|
onClick={() => setMenuOpen(!menuOpen)}
|
||||||
|
aria-label={menuOpen ? 'Fermer le menu' : 'Ouvrir le menu'}
|
||||||
|
aria-expanded={menuOpen}
|
||||||
|
>
|
||||||
|
{menuOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Menu */}
|
||||||
|
<div
|
||||||
|
className={`lg:hidden overflow-hidden transition-all duration-300 ${
|
||||||
|
menuOpen ? 'max-h-screen opacity-100' : 'max-h-0 opacity-0'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<nav className="bg-marine-900 border-t border-marine-700 px-4 pb-4 pt-2 flex flex-col gap-1">
|
||||||
|
{navLinks.map((link) => (
|
||||||
|
<a
|
||||||
|
key={link.href}
|
||||||
|
href={link.href}
|
||||||
|
onClick={(e) => { e.preventDefault(); handleNavClick(link.href); }}
|
||||||
|
className="text-gray-200 hover:text-gold-400 hover:bg-marine-800 transition-colors px-4 py-3 text-sm font-medium uppercase tracking-wide rounded"
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
<a
|
||||||
|
href="#contact"
|
||||||
|
onClick={(e) => { e.preventDefault(); handleNavClick('#contact'); }}
|
||||||
|
className="mt-2 bg-gold-500 hover:bg-gold-400 text-white text-sm font-semibold px-4 py-3 rounded-sm text-center uppercase tracking-wide"
|
||||||
|
>
|
||||||
|
Nous rejoindre
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Header;
|
||||||
Loading…
Reference in New Issue