'use client'; import { useState, useEffect, useMemo, useRef } from 'react'; import useTranslation from '../hooks/useTranslation'; import Link from 'next/link'; import { Menu, X, BarChart3, LogOut, Zap, Users, Settings, Calendar, User, HelpCircle, Globe, ChevronDown } from 'lucide-react'; import { useUserSettings } from '@/src/contexts/UserSettingsContext'; import { motion, AnimatePresence } from 'framer-motion'; import { useSwissOIDAuth } from 'swissoid-front'; import PartnerSearchModal from './PartnerSearchModal'; import ClaimCredentialsModal from './ClaimCredentialsModal'; import { getClaimedRemoteMember } from '@/src/utils/hasClaimedAnyCredentials'; import { useLocalizedLink } from '@/src/hooks/useLocalizedLink'; import { cleanName } from '@/src/utils/bookingUtils'; import { useRouter, usePathname } from 'next/navigation'; import { i18n } from '@/i18n-config'; interface NavigationProps { pageTitle?: string; } export default function Navigation({ pageTitle }: NavigationProps) { const { user, login, logout } = useSwissOIDAuth(); const isLoggedIn = !!user; const { t } = useTranslation(); const [isMenuOpen, setIsMenuOpen] = useState(false); const { settings, appUser, remoteMembers } = useUserSettings(); const [showPartnerModal, setShowPartnerModal] = useState(false); const [showClaimModal, setShowClaimModal] = useState(false); const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = useState(false); const { locale, localizedLink } = useLocalizedLink(); const router = useRouter(); const pathname = usePathname(); const menuScrollContainerRef = useRef(null); // Get the current user's name from remote members const currentUserData = useMemo(() => { if (!settings || !remoteMembers) return null; const claimedMember = getClaimedRemoteMember(settings); if (!claimedMember) return null; const member = remoteMembers.find(m => m.remote_member_id === claimedMember.remote_member_id); if (!member) return null; return { name: cleanName(member.full_account_str), initials: cleanName(member.full_account_str).split(' ').map(n => n[0]?.toUpperCase()).filter(Boolean).slice(0, 2).join('') }; }, [settings, remoteMembers]); const toggleMenu = () => setIsMenuOpen(!isMenuOpen); const closeMenu = () => { setIsMenuOpen(false); // Multiple fallbacks to ensure menu closes even on fast navigation setTimeout(() => setIsMenuOpen(false), 0); setTimeout(() => setIsMenuOpen(false), 50); setTimeout(() => setIsMenuOpen(false), 100); }; // Language options const languages = [ { code: 'en-US', label: 'English', flag: '🇺🇸' }, { code: 'de-DE', label: 'Deutsch', flag: '🇩🇪' }, { code: 'fr-CH', label: 'Français', flag: '🇨🇭' } ]; // Handle language change const handleLanguageChange = (newLocale: string) => { // Get the current pathname without the locale const segments = pathname.split('/'); const currentLocale = segments[1]; // Check if the first segment is a locale if (i18n.locales.includes(currentLocale as any)) { segments[1] = newLocale; } else { // If no locale in path, add it segments.unshift('', newLocale); } const newPath = segments.join('/').replace(/\/+/g, '/'); router.push(newPath); }; // Handle language dropdown toggle with scroll const handleLanguageDropdownToggle = () => { const newState = !isLanguageDropdownOpen; setIsLanguageDropdownOpen(newState); // If opening the dropdown, scroll to bottom of menu if (newState && menuScrollContainerRef.current) { setTimeout(() => { const container = menuScrollContainerRef.current; if (container) { container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' }); } }, 300); } }; // Prevent body scrolling when menu is open useEffect(() => { if (isMenuOpen) { // Save current scroll position const scrollY = window.scrollY; // Add styles to prevent scrolling document.body.style.position = 'fixed'; document.body.style.top = `-${scrollY}px`; document.body.style.width = '100%'; document.body.style.overflow = 'hidden'; return () => { // Restore scroll position when menu closes document.body.style.position = ''; document.body.style.top = ''; document.body.style.width = ''; document.body.style.overflow = ''; window.scrollTo(0, scrollY); }; } }, [isMenuOpen]); const menuVariants = { closed: { x: '100%', transition: { type: 'spring' as const, stiffness: 400, damping: 40 } }, open: { x: 0, transition: { type: 'spring' as const, stiffness: 400, damping: 40 } } }; const overlayVariants = { closed: { opacity: 0 }, open: { opacity: 1 } }; const menuItemVariants = { closed: { x: 50, opacity: 0 }, open: (i: number) => ({ x: 0, opacity: 1, transition: { delay: i * 0.1, type: 'spring' as const, stiffness: 400, damping: 25 } }) }; const bookingLink = localizedLink( settings?.default_remote_sport.facility_slug && settings?.default_remote_sport.sport_slug ? `/booking/${encodeURIComponent(settings.default_remote_sport.facility_slug)}/${encodeURIComponent(settings.default_remote_sport.sport_slug)}/today` : '/select-remote' ); return ( <>
{/* Logo */}

Playchoo

{pageTitle && ( {pageTitle} )}
{/* Right side navigation */}
{/* Always show hamburger on mobile, show login/register on desktop when logged out */}
{!isLoggedIn && ( <> )}
{/* Hamburger menu button - always visible on mobile, only for logged-in users on desktop */}
{/* Mobile/Desktop Side Menu */} {isMenuOpen && ( <> {/* Overlay */} {/* Side Menu */}
{/* Header */}
{isLoggedIn && appUser && currentUserData ? (
{currentUserData.initials}
{currentUserData.name}
{t('View Profile')}
) : (

{t('Menu')}

{t('Navigate your game')}

)}
{/* Menu Items */}
{!isLoggedIn ? ( <> ) : ( <>
{t('Venue Management')}
)} {/* Language Selector - Available for all users */}
{/* Language Dropdown Header */} {/* Language Dropdown Options */} {isLanguageDropdownOpen && (
{languages.filter(lang => lang.code !== locale).map((lang) => ( ))}
)}
{/* Footer */}
{isLoggedIn && (
{t('Logout')}
)}
Version {process.env.NEXT_PUBLIC_APP_VERSION}
{t('Powered by passion')}
)}
setShowPartnerModal(false)} onSelectPartner={() => {}} remoteSlug={settings?.default_remote_sport.facility_slug || ''} sportSlug={settings?.default_remote_sport.sport_slug || ''} selectedPartners={[]} context="lookup" /> setShowClaimModal(false)} /> ); }