'use client' import { motion, AnimatePresence } from 'motion/react' import { Menu, X, Globe, ChevronDown } from 'lucide-react' import Link from 'next/link' import { useLanguage } from '@/lib/i18n' import type { SupportedLanguage } from '@/lib/i18n/load-translations' import { useEffect, useRef, useState, type ReactNode } from 'react' const LANDING_LANGS: { code: SupportedLanguage; labelKey: string }[] = [ { code: 'fr', labelKey: 'languages.fr' }, { code: 'en', labelKey: 'languages.en' }, { code: 'es', labelKey: 'languages.es' }, { code: 'de', labelKey: 'languages.de' }, { code: 'it', labelKey: 'languages.it' }, { code: 'pt', labelKey: 'languages.pt' }, { code: 'nl', labelKey: 'languages.nl' }, { code: 'pl', labelKey: 'languages.pl' }, { code: 'ru', labelKey: 'languages.ru' }, { code: 'zh', labelKey: 'languages.zh' }, { code: 'ja', labelKey: 'languages.ja' }, { code: 'ko', labelKey: 'languages.ko' }, { code: 'ar', labelKey: 'languages.ar' }, { code: 'fa', labelKey: 'languages.fa' }, { code: 'hi', labelKey: 'languages.hi' }, ] export type PublicSitePage = 'home' | 'pricing' function resolvePublicHref(href: string, currentPage: PublicSitePage): string { if (!href.startsWith('#')) return href if (href === '#pricing' && currentPage === 'pricing') return '/pricing' if (currentPage === 'home') return href const id = href.replace(/^#/, '') return id === 'pricing' ? '/pricing' : `/#${id}` } export function PublicSiteChrome({ children, currentPage, onHashNavigate, }: { children: ReactNode currentPage: PublicSitePage onHashNavigate?: (hash: string) => void }) { const { t, language, setLanguage } = useLanguage() const [menuOpen, setMenuOpen] = useState(false) const [langOpen, setLangOpen] = useState(false) const langRef = useRef(null) const NAV = [ { href: '#product', label: t('landing.nav.secondBrain') }, { href: '#echo', label: t('landing.nav.echo') }, { href: '#agents', label: t('landing.nav.agents') }, { href: '#pricing', label: t('landing.nav.pricing') }, ] useEffect(() => { if (!langOpen) return const onPointer = (e: MouseEvent) => { if (langRef.current && !langRef.current.contains(e.target as Node)) setLangOpen(false) } const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setLangOpen(false) } document.addEventListener('mousedown', onPointer) document.addEventListener('keydown', onKey) return () => { document.removeEventListener('mousedown', onPointer) document.removeEventListener('keydown', onKey) } }, [langOpen]) useEffect(() => { const root = document.querySelector('[data-public-scroll-root]') if (!root) return const prev = root.style.overflow if (menuOpen) root.style.overflow = 'hidden' else root.style.overflow = prev || '' return () => { root.style.overflow = prev } }, [menuOpen]) const goSection = (event: React.MouseEvent, hash: string) => { setMenuOpen(false) if (currentPage === 'home' && onHashNavigate) { event.preventDefault() onHashNavigate(hash) window.history.replaceState(null, '', hash) } } return (
{menuOpen && (
{NAV.map((l) => ( goSection(event, l.href)} className="py-4 text-3xl font-serif border-b border-white/10" > {l.label} ))} setMenuOpen(false)} className="mt-10 py-4 text-2xl font-serif text-white/80 text-center border-b border-white/10" > {t('landing.nav.login')} setMenuOpen(false)} className="mt-4 py-4 rounded-2xl bg-[#F4F1EA] text-[#0B0A09] text-center font-semibold"> {t('landing.nav.cta')}
)}
{children}
) }