/** * Header.jsx — 交互式顶栏(React island,@astrojs/react 渲染 + 水合)。 * 迁自 design/ui_kits/website/index.html 的
+ site.js 的菜单/滚动毛玻璃逻辑。 * 语言切换由原型的 JS 文本替换改为「路由跳转」(zh=/, en=/en/),单显不并排(铁律 6)。 */ import { useEffect, useRef, useState } from 'react'; import { Download, Menu } from 'lucide-react'; import { SITE } from '../config/site'; function Mark() { return ( ); } export default function Header({ lang = 'zh', t = {} }) { const [open, setOpen] = useState(false); const [scrolled, setScrolled] = useState(false); const [langOpen, setLangOpen] = useState(false); const [userOpen, setUserOpen] = useState(false); const [loggedIn, setLoggedIn] = useState(false); const [email, setEmail] = useState(''); const langRef = useRef(null); const userRef = useRef(null); // 登录后回跳主页:用户中心带 ?redirect=/(配合 usercenter 登录成功后回跳)。 const loginHref = `${SITE.usercenter}?redirect=/`; // 用户名截断显示:优先邮箱 @ 前部分,缺失时回退通用词。 const displayName = (email && email.split('@')[0]) || 'Account'; // 与用户中心同源:登录后 localStorage 存 pg_uc_refresh(+ pg_uc_email)→ 显示用户名下拉。 useEffect(() => { try { setLoggedIn(!!localStorage.getItem('pg_uc_refresh')); setEmail(localStorage.getItem('pg_uc_email') || ''); } catch { setLoggedIn(false); } }, []); // 清登录态并跳转(切换用户 = 回登录页;退出 = 回主页)。 const clearSession = () => { try { localStorage.removeItem('pg_uc_refresh'); localStorage.removeItem('pg_uc_email'); } catch { /* ignore */ } }; const onSwitch = () => { clearSession(); window.location.href = loginHref; }; const onLogout = () => { clearSession(); window.location.href = '/'; }; useEffect(() => { if (!langOpen) return; const onDoc = (e) => { if (langRef.current && !langRef.current.contains(e.target)) setLangOpen(false); }; const onKey = (e) => { if (e.key === 'Escape') setLangOpen(false); }; document.addEventListener('mousedown', onDoc); document.addEventListener('keydown', onKey); return () => { document.removeEventListener('mousedown', onDoc); document.removeEventListener('keydown', onKey); }; }, [langOpen]); useEffect(() => { if (!userOpen) return; const onDoc = (e) => { if (userRef.current && !userRef.current.contains(e.target)) setUserOpen(false); }; const onKey = (e) => { if (e.key === 'Escape') setUserOpen(false); }; document.addEventListener('mousedown', onDoc); document.addEventListener('keydown', onKey); return () => { document.removeEventListener('mousedown', onDoc); document.removeEventListener('keydown', onKey); }; }, [userOpen]); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 8); onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); const nav = [ ['#product', t.product], ['#pricing', t.pricing], ['#download', t.download], ['#docs', t.docs], ]; // 6 语言:默认 en=/,其余 //。段控横排会挤,用原生下拉。 const langs = [ ['en', 'English'], ['zh', '中文'], ['ja', '日本語'], ['ko', '한국어'], ['ru', 'Русский'], ['es', 'Español'], ]; const langHref = (l) => (l === 'en' ? '/' : `/${l}/`); return (
{t.brand || 'Pangolin'}
{langOpen && (
{langs.map(([code, label]) => { const on = code === lang; return ( {label} ); })}
)}
{loggedIn ? (
{userOpen && ( )}
) : ( {t.login} )} {t.get}
); }