import { useState, useEffect, useRef } from 'react'; import { Link, NavLink, useLocation } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { ChevronDown, Coins, ArrowRight, Layers3, Menu, Moon, Sparkles, Sun, UserRound, X } from 'lucide-react'; import { useAuthStore } from '@/stores/authStore'; import { ensureLanguageResources } from '@/i18n'; interface LangOption { code: string; label: string; flag: string; } const languages: LangOption[] = [ { code: 'en', label: 'English', flag: '🇺🇸' }, { code: 'ar', label: 'العربية', flag: '🇸🇦' }, { code: 'fr', label: 'Français', flag: '🇫🇷' }, ]; const NAV_LINKS = [ { to: '/tools', key: 'common.allTools', fallback: 'All tools' }, { to: '/pricing', key: 'common.pricing', fallback: 'Pricing' }, { to: '/developers', key: 'common.developers', fallback: 'Developers' }, { to: '/about', key: 'common.about', fallback: 'About' }, { to: '/contact', key: 'common.contact', fallback: 'Contact' }, ] as const; function useDarkMode() { const [isDark, setIsDark] = useState(() => { if (typeof window === 'undefined') return false; const stored = localStorage.getItem('theme'); if (stored) return stored === 'dark'; return window.matchMedia('(prefers-color-scheme: dark)').matches; }); useEffect(() => { const root = document.documentElement; if (isDark) { root.classList.add('dark'); localStorage.setItem('theme', 'dark'); } else { root.classList.remove('dark'); localStorage.setItem('theme', 'light'); } }, [isDark]); return { isDark, toggle: () => setIsDark((v) => !v) }; } export default function Header() { const { t, i18n } = useTranslation(); const { isDark, toggle: toggleDark } = useDarkMode(); const location = useLocation(); const user = useAuthStore((state) => state.user); const credits = useAuthStore((state) => state.credits); const [langOpen, setLangOpen] = useState(false); const [mobileOpen, setMobileOpen] = useState(false); const langRef = useRef(null); const currentLang = languages.find((l) => l.code === i18n.language) ?? languages[0]; // Close language dropdown on outside click useEffect(() => { function handleClick(e: MouseEvent) { if (langRef.current && !langRef.current.contains(e.target as Node)) { setLangOpen(false); } } document.addEventListener('mousedown', handleClick); return () => document.removeEventListener('mousedown', handleClick); }, []); useEffect(() => { setMobileOpen(false); setLangOpen(false); }, [location.pathname]); const switchLang = async (code: string) => { const resolved = await ensureLanguageResources(code); void i18n.changeLanguage(resolved); setLangOpen(false); }; const desktopNavClassName = ({ isActive }: { isActive: boolean }) => [ 'rounded-full px-4 py-2 text-sm font-semibold transition-all duration-200', isActive ? 'bg-slate-900 text-white shadow-sm dark:bg-white dark:text-slate-950' : 'text-slate-600 hover:bg-white hover:text-slate-900 dark:text-slate-300 dark:hover:bg-slate-800 dark:hover:text-white', ].join(' '); const mobileNavClassName = ({ isActive }: { isActive: boolean }) => [ 'block rounded-2xl px-4 py-3 text-sm font-semibold transition-colors', isActive ? 'bg-primary-600 text-white shadow-sm shadow-primary-200 dark:shadow-primary-950/30' : 'text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800', ].join(' '); return (
{t('common.appName')} {t('common.siteTagline')}
{user?.email || t('common.account')} {user && credits ? ( {credits.credits_remaining} ) : null} {!user ? ( {t('home.startFree')} ) : null}
{langOpen ? (
{languages.map((lang) => ( ))}
) : null}
{mobileOpen ? ( ) : null}
); }