// Utilitaires centralisés pour éviter la duplication /** * Combine les classes CSS en filtrant les valeurs falsy * Remplace les fonctions mergeClasses et cn dupliquées */ export const cn = (...classes: (string | undefined | null | false)[]): string => { return classes.filter(Boolean).join(' '); }; /** * Hook personnalisé pour gérer le scroll du body * Factorisation de la logique répétée dans plusieurs composants */ export const useBodyScrollLock = (isLocked: boolean) => { const originalStyle = document.body.style.overflow; if (isLocked) { document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = originalStyle || 'unset'; } // Cleanup function return () => { document.body.style.overflow = originalStyle || 'unset'; }; }; /** * Configuration de navigation centralisée */ export const createNavClickHandler = (onClose?: () => void) => { return (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) { element.scrollIntoView({ behavior: 'smooth', block: 'start' }); } } onClose?.(); }; }; /** * Gestionnaire d'événements de redimensionnement optimisé */ export const useResizeHandler = (callback: () => void, breakpoint: number = 768) => { const handleResize = () => { if (window.innerWidth >= breakpoint) { callback(); } }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }; /** * Classes CSS communes pour éviter la répétition */ export const commonClasses = { // Transitions transition: 'transition-all duration-300 ease-in-out', transitionFast: 'transition-all duration-200 ease-in-out', // Hover effects communs hoverLift: 'hover:-translate-y-1 hover:shadow-xl hover:scale-105', hoverScale: 'hover:scale-105 active:scale-95', // Boutons communs buttonBase: 'inline-flex items-center justify-center font-semibold rounded-xl transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-blue-400/50', // Navigation navLink: 'px-4 py-2.5 text-white/90 hover:text-white font-medium rounded-xl transition-all duration-300 hover:bg-white/10', // Cards cardBase: 'backdrop-blur-lg rounded-2xl border transition-all duration-300', cardHover: 'hover:shadow-xl hover:-translate-y-1', // Mobile menu items mobileMenuItem: 'group flex items-center justify-between p-4 rounded-xl transition-all duration-300 bg-white/5 hover:bg-white/10 border border-white/10 hover:border-white/20', } as const;