112 lines
3.3 KiB
TypeScript
112 lines
3.3 KiB
TypeScript
import React from 'react';
|
|
import { useScrollEffects } from '@/lib/hooks/useScrollEffects';
|
|
import { Logo } from './navbar/Logo';
|
|
import { NavLinks } from './navbar/NavLinks';
|
|
import { ActionButtons } from './navbar/ActionButtons';
|
|
import { MobileMenuButton } from './navbar/MobileMenuButton';
|
|
import { MobileMenu } from './MobileMenu';
|
|
import type { Translation } from '@/types/i18n';
|
|
|
|
// Fonction utilitaire simple pour combiner les classes
|
|
const mergeClasses = (...classes: (string | undefined | null | false)[]): string => {
|
|
return classes.filter(Boolean).join(' ');
|
|
};
|
|
|
|
interface ModernNavigationProps {
|
|
translations: Translation['navigation'];
|
|
languageSwitcher: React.ReactElement;
|
|
}
|
|
|
|
export const ModernNavigation: React.FC<ModernNavigationProps> = ({
|
|
translations,
|
|
languageSwitcher
|
|
}) => {
|
|
const { scrolled } = useScrollEffects();
|
|
const [mobileMenuOpen, setMobileMenuOpen] = React.useState(false);
|
|
|
|
// Fermer le menu mobile lors du redimensionnement
|
|
React.useEffect(() => {
|
|
const handleResize = () => {
|
|
if (window.innerWidth >= 768) {
|
|
setMobileMenuOpen(false);
|
|
}
|
|
};
|
|
|
|
window.addEventListener('resize', handleResize);
|
|
return () => window.removeEventListener('resize', handleResize);
|
|
}, []);
|
|
|
|
// Empêcher le scroll du body quand le menu mobile est ouvert
|
|
React.useEffect(() => {
|
|
if (mobileMenuOpen) {
|
|
document.body.style.overflow = 'hidden';
|
|
} else {
|
|
document.body.style.overflow = 'unset';
|
|
}
|
|
|
|
return () => {
|
|
document.body.style.overflow = 'unset';
|
|
};
|
|
}, [mobileMenuOpen]);
|
|
|
|
return (
|
|
<>
|
|
{/* Navigation moderne épurée */}
|
|
<nav className={mergeClasses(
|
|
// Position et z-index
|
|
'fixed top-0 left-0 right-0 z-50',
|
|
|
|
// Style de fond moderne
|
|
'bg-blue-700/95 backdrop-blur-md border-b border-blue-600/30',
|
|
|
|
// Transition fluide
|
|
'transition-all duration-200 ease-in-out',
|
|
|
|
// Effet de scroll
|
|
scrolled && 'shadow-lg'
|
|
)}>
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="flex justify-between items-center px-4 sm:px-6 lg:px-8 h-16">
|
|
|
|
{/* Logo Section */}
|
|
<Logo scrolled={scrolled} />
|
|
|
|
{/* Navigation Links (Desktop) - Centré */}
|
|
<div className="flex-1 flex justify-center">
|
|
<NavLinks
|
|
translations={translations}
|
|
scrolled={scrolled}
|
|
/>
|
|
</div>
|
|
|
|
{/* Action Buttons (Desktop) */}
|
|
<ActionButtons
|
|
scrolled={scrolled}
|
|
languageSwitcher={languageSwitcher}
|
|
/>
|
|
|
|
{/* Mobile Menu Button */}
|
|
<MobileMenuButton
|
|
isOpen={mobileMenuOpen}
|
|
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Ligne de séparation moderne */}
|
|
<div className="absolute bottom-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-blue-400/40 to-transparent" />
|
|
</nav>
|
|
|
|
{/* Spacer pour compenser la navbar fixed */}
|
|
<div className="h-16" />
|
|
|
|
{/* Menu Mobile */}
|
|
<MobileMenu
|
|
isOpen={mobileMenuOpen}
|
|
onClose={() => setMobileMenuOpen(false)}
|
|
translations={translations}
|
|
/>
|
|
</>
|
|
);
|
|
};
|