Sacha VAUDEY 30fd66f2c9
Some checks failed
Build / build-check (pull_request) Failing after 1m33s
Major UI update
2025-09-13 22:55:24 +02:00

145 lines
3.9 KiB
TypeScript

import React from 'react';
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 NavLinksProps {
translations: Translation['navigation'];
scrolled?: boolean;
className?: string;
}
interface NavLinkProps {
href: string;
children: React.ReactNode;
isActive?: boolean;
onClick?: () => void;
}
const NavLink: React.FC<NavLinkProps> = ({ href, children, isActive = false, onClick }) => {
return (
<a
href={href}
onClick={(e) => {
e.preventDefault();
onClick?.();
}}
className={mergeClasses(
// Base styles
'relative px-4 py-2.5 text-sm font-medium transition-all duration-200 rounded-xl',
'focus:outline-none focus:ring-2 focus:ring-blue-400/50',
// États conditionnels
isActive
? 'text-white bg-white/15 shadow-sm backdrop-blur-sm border border-white/20'
: 'text-white/80 hover:text-white hover:bg-white/10'
)}
>
<span className="relative z-10">{children}</span>
{/* Indicateur actif moderne */}
{isActive && (
<div className="absolute bottom-0 left-1/2 transform -translate-x-1/2 w-1 h-1 bg-blue-300 rounded-full" />
)}
</a>
);
};
export const NavLinks: React.FC<NavLinksProps> = ({ translations, className }) => {
const [activeSection, setActiveSection] = React.useState<string>('home');
// Observer pour détecter la section active (simplifié)
React.useEffect(() => {
const handleScroll = () => {
const scrollPosition = window.scrollY;
// Si on est en haut de la page
if (scrollPosition < 200) {
setActiveSection('home');
return;
}
// Détection des sections
const sections = ['services', 'about'];
let currentSection = 'home';
sections.forEach((sectionId) => {
const element = document.getElementById(sectionId);
if (element) {
const rect = element.getBoundingClientRect();
if (rect.top <= 200 && rect.bottom >= 200) {
currentSection = sectionId;
}
}
});
setActiveSection(currentSection);
};
window.addEventListener('scroll', handleScroll, { passive: true });
handleScroll();
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const handleNavClick = (sectionId: string) => {
if (sectionId === 'home') {
window.scrollTo({ top: 0, behavior: 'smooth' });
} else if (sectionId === 'contact') {
window.location.href = 'mailto:contact@la-banquise.fr';
} else {
const element = document.getElementById(sectionId);
if (element) {
const navHeight = 64; // Hauteur de la navbar
const elementPosition = element.offsetTop - navHeight;
window.scrollTo({
top: elementPosition,
behavior: 'smooth'
});
}
}
};
return (
<nav className={mergeClasses(
'hidden md:flex items-center space-x-2',
className
)}>
<NavLink
href="#home"
isActive={activeSection === 'home'}
onClick={() => handleNavClick('home')}
>
{translations.home}
</NavLink>
<NavLink
href="#services"
isActive={activeSection === 'services'}
onClick={() => handleNavClick('services')}
>
{translations.services}
</NavLink>
<NavLink
href="#about"
isActive={activeSection === 'about'}
onClick={() => handleNavClick('about')}
>
{translations.about}
</NavLink>
<NavLink
href="mailto:contact@la-banquise.fr"
isActive={false}
onClick={() => handleNavClick('contact')}
>
{translations.contact}
</NavLink>
</nav>
);
};