import { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import { Link } from 'react-router-dom'; import ThemeToggle from './ThemeToggle.jsx'; import DynamicIcon from './DynamicIcon.jsx'; import { useAuth } from '../context/AuthContext.jsx'; import { useSiteSettings } from '../context/SiteSettingsContext.jsx'; import logo from '../assets/logo.png'; const SHOP_URL = 'https://www.audio4cars.de/'; const digitsOnly = (value) => (value || '').replace(/[^\d+]/g, ''); const ITEM_DELAY_MS = 70; const FLY_DURATION_MS = 500; export default function Navbar() { const [open, setOpen] = useState(false); const [mounted, setMounted] = useState(false); const [menuVisible, setMenuVisible] = useState(false); const { user } = useAuth(); const { phone, whatsapp } = useSiteSettings(); const totalItems = whatsapp ? 8 : 7; useEffect(() => { if (open) { setMounted(true); // Doppeltes rAF: nach dem Mounten braucht der Browser einen echten Paint mit der // "versteckten" Ausgangsposition, bevor wir auf "sichtbar" umschalten - sonst // fasst er beide Zustandsänderungen in einem Frame zusammen und es gibt keinen // sichtbaren Übergang (kein Fade-in). let rafInner; const rafOuter = requestAnimationFrame(() => { rafInner = requestAnimationFrame(() => setMenuVisible(true)); }); return () => { cancelAnimationFrame(rafOuter); if (rafInner) cancelAnimationFrame(rafInner); }; } setMenuVisible(false); const closeDuration = FLY_DURATION_MS + (totalItems - 1) * ITEM_DELAY_MS; const id = setTimeout(() => setMounted(false), closeDuration); return () => clearTimeout(id); }, [open, totalItems]); const flyIn = () => `transition-all duration-500 ease-out ${menuVisible ? 'opacity-100' : 'opacity-0'}`; const flyInStyle = (index) => { const delayIndex = menuVisible ? index : totalItems - 1 - index; return { transitionDelay: `${delayIndex * ITEM_DELAY_MS}ms`, transform: menuVisible ? 'translateY(0)' : 'translateY(-140px)', }; }; const AdminIcon = user && ( ); return (
{/* Schmale Kontakt-Leiste (Telefon/WhatsApp/Shop) - auf kleinen Screens ausgeblendet, steht dort stattdessen im aufklappbaren mobilen Menü. */}
{phone && ( {phone} )} {whatsapp && ( WhatsApp )} Zum Shop
HifiPlanet
{AdminIcon}
{mounted && createPortal(
setOpen(false)} className={`text-3xl font-extrabold tracking-tight text-neutral-900 hover:text-brand-600 ${flyIn()}`} style={flyInStyle(0)}> Fahrzeuge setOpen(false)} className={`text-3xl font-extrabold tracking-tight text-neutral-900 hover:text-brand-600 ${flyIn()}`} style={flyInStyle(1)}> Leistungen setOpen(false)} className={`text-3xl font-extrabold tracking-tight text-neutral-900 hover:text-brand-600 ${flyIn()}`} style={flyInStyle(2)}> Galerie setOpen(false)} className={`text-3xl font-extrabold tracking-tight text-neutral-900 hover:text-brand-600 ${flyIn()}`} style={flyInStyle(3)}> Kontakt
{phone && ( {phone} )} {whatsapp && ( WhatsApp )} Zum Shop
, document.body )}
); }