import { useState, useCallback, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import type { AuthUser } from '../../hooks/useAuth'; import { shortenUrl, prewarmScreenshot } from '../../lib/api'; import { copyToClipboard } from '../../lib/clipboard'; import { DownloadIcon } from './icons/DownloadIcon'; import { BookmarkIcon } from './icons/BookmarkIcon'; import { LogoIcon } from './icons/LogoIcon'; import { CheckIcon } from './icons/CheckIcon'; import { ClipboardIcon } from './icons/ClipboardIcon'; import { MenuIcon } from './icons/MenuIcon'; import { SunIcon } from './icons/SunIcon'; import { MoonIcon } from './icons/MoonIcon'; import { SpinnerIcon } from './icons/SpinnerIcon'; import UserMenu from './UserMenu'; import MobileMenu from './MobileMenu'; import LanguageDropdown from './LanguageDropdown'; export type Page = | 'home' | 'dashboard' | 'learn' | 'pricing' | 'property-price-map' | 'postcode-property-search' | 'commute-property-search' | 'school-property-search' | 'postcode-checker' | 'birmingham-property-search' | 'manchester-property-search' | 'bristol-property-search' | 'data-sources' | 'methodology' | 'privacy-security' | 'account' | 'saved' | 'invites' | 'invite'; export const PAGE_PATHS: Record = { home: '/', dashboard: '/dashboard', learn: '/learn', pricing: '/pricing', 'property-price-map': '/property-price-map', 'postcode-property-search': '/postcode-property-search', 'commute-property-search': '/commute-property-search', 'school-property-search': '/school-property-search', 'postcode-checker': '/postcode-checker', 'birmingham-property-search': '/property-search/birmingham', 'manchester-property-search': '/property-search/manchester', 'bristol-property-search': '/property-search/bristol', 'data-sources': '/data-sources', methodology: '/methodology', 'privacy-security': '/privacy-security', saved: '/saved', invites: '/invites', account: '/account', invite: '/invite', }; export default function Header({ activePage, onPageChange, theme, onToggleTheme, onExport, exporting, onSaveSearch, savingSearch, user, onLoginClick, onRegisterClick, onLogout, isMobile, }: { activePage: Page; onPageChange: (page: Page) => void; theme: 'light' | 'dark'; onToggleTheme: () => void; onExport: (() => void) | null; exporting: boolean; onSaveSearch: (() => void) | null; savingSearch: boolean; user: AuthUser | null; onLoginClick: () => void; onRegisterClick: () => void; onLogout: () => void; isMobile: boolean; }) { const { t } = useTranslation(); const [copied, setCopied] = useState(false); const [sharing, setSharing] = useState(false); const [menuOpen, setMenuOpen] = useState(false); // Close menu on Escape useEffect(() => { if (!menuOpen) return; const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') setMenuOpen(false); }; window.addEventListener('keydown', handler); return () => window.removeEventListener('keydown', handler); }, [menuOpen]); // Close menu when switching away from mobile useEffect(() => { if (!isMobile) setMenuOpen(false); }, [isMobile]); const doCopy = useCallback((text: string) => { copyToClipboard(text, () => { setCopied(true); setTimeout(() => setCopied(false), 2000); }); }, []); const handleShare = useCallback(async () => { const params = window.location.search.replace(/^\?/, ''); if (!params) { doCopy(window.location.href); return; } prewarmScreenshot(params); setSharing(true); try { const shortUrl = await shortenUrl(params); doCopy(shortUrl); } catch { doCopy(window.location.href); } finally { setSharing(false); } }, [doCopy]); const navLink = (page: Page, e: React.MouseEvent) => { if (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0) return; e.preventDefault(); onPageChange(page); }; const tabClass = (page: Page) => `px-3 py-1.5 rounded text-sm font-medium transition-colors ${ activePage === page ? 'bg-navy-700 text-white' : 'text-warm-300 hover:bg-navy-800 hover:text-white' }`; return (
{/* Left: Logo + nav */}
navLink('home', e)} > {t('header.appName')} {/* Desktop nav */} {!isMobile && ( )}
{/* Right side */}
{/* Desktop-only dashboard actions */} {!isMobile && activePage === 'dashboard' && ( <> {onSaveSearch && ( )} )} {!isMobile && user && ( navLink('saved', e)} > {t('header.saved')} )} {/* Desktop-only auth */} {!isMobile && ( <> {user ? ( ) : ( <> )} )} {/* Mobile auth CTA (logged out only) */} {isMobile && !user && ( )} {/* Language selector (desktop) */} {!isMobile && } {/* Theme toggle (desktop, logged-out only — logged-in users use UserMenu) */} {!isMobile && !user && ( )} {/* Mobile hamburger */} {isMobile && ( )}
{/* Mobile slide-in menu */} {isMobile && menuOpen && ( setMenuOpen(false)} onShare={handleShare} copied={copied} /> )} {/* Mobile "Copied" toast */} {isMobile && copied && (
{t('common.copiedToClipboard')}
)}
); }