'use client'; import * as React from 'react'; import Link from 'next/link'; import Image from 'next/image'; import { usePathname } from 'next/navigation'; import { motion, AnimatePresence } from 'framer-motion'; import { LanguageSwitcher } from './LanguageSwitcher'; import { Button } from '@/components/ui/Button'; export interface NavLink { label: string; url: string; } interface HeaderProps { navLinks: NavLink[]; } export function Header({ navLinks }: HeaderProps) { const [isScrolled, setIsScrolled] = React.useState(false); const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false); const [forceSolid, setForceSolid] = React.useState(false); const pathname = usePathname() || '/'; // Determine current locale from pathname const currentLocale = pathname.startsWith('/en') ? 'en' : 'de'; // Helper to switch languages const getSwitchedUrl = (newLocale: string) => { if (!pathname) return `/${newLocale}`; const pathWithoutLocale = pathname.replace(/^\/(en|de)/, ''); return `/${newLocale}${pathWithoutLocale === '' ? '' : pathWithoutLocale}`; }; React.useEffect(() => { const handleScroll = () => { setIsScrolled(window.scrollY > 20); }; window.addEventListener('scroll', handleScroll); // Check for forced solid header (used by error pages, legal pages without hero, etc.) const checkSolid = () => { setForceSolid(document.body.getAttribute('data-force-solid-header') === 'true'); }; checkSolid(); // Set up observer for client-side navigation changes const observer = new MutationObserver(checkSolid); observer.observe(document.body, { attributes: true, attributeFilter: ['data-force-solid-header'] }); // Re-check when pathname changes checkSolid(); return () => { window.removeEventListener('scroll', handleScroll); observer.disconnect(); }; }, [pathname]); // Close mobile menu on route change React.useEffect(() => { setIsMobileMenuOpen(false); }, [pathname]); const isSolidMode = isScrolled || forceSolid; return ( <> {/* Scroll triggered shine effect */} {isScrolled && ( )} {navLinks && navLinks.length > 0 && navLinks.map((link) => { const mappedUrl = link.url.startsWith('/') && !link.url.match(/^\/(en|de)/) ? `/${currentLocale}${link.url}` : link.url; const isActive = pathname === mappedUrl || (mappedUrl !== `/${currentLocale}` && pathname?.startsWith(`${mappedUrl}/`)); return ( {link.label} {/* Framer Motion Active Indicator */} {isActive && ( )} {/* Subtle hover underline */} ); })} {currentLocale === 'de' ? 'Kontakt' : 'Contact'} {/* Sleek shine sweep effect */} {/* Mobile Nav Button */} setIsMobileMenuOpen(!isMobileMenuOpen)} aria-label="Toggle menu" > {isMobileMenuOpen ? ( <> > ) : ( <> > )} {/* Mobile Menu Overlay */} {isMobileMenuOpen && ( {navLinks && navLinks.length > 0 && navLinks.map((link) => { const mappedUrl = link.url.startsWith('/') && !link.url.match(/^\/(en|de)/) ? `/${currentLocale}${link.url}` : link.url; return ( {link.label} ); })} {currentLocale === 'de' ? 'Kontakt' : 'Contact'} Sprache wählen )} > ); }
Sprache wählen