75ed293151
Web 用户中心(web/usercenter)尚未部署、无 URL,登录入口暂无处可去; 产品主流程为 App 内登录。先删死按钮避免公开页点了没反应,待 #30 部署 usercenter 后接上登录地址恢复(已挂 #30 子任务)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
85 lines
3.1 KiB
React
85 lines
3.1 KiB
React
/**
|
||
* Header.jsx — 交互式顶栏(React island,@astrojs/react 渲染 + 水合)。
|
||
* 迁自 design/ui_kits/website/index.html 的 <header> + site.js 的菜单/滚动毛玻璃逻辑。
|
||
* 语言切换由原型的 JS 文本替换改为「路由跳转」(zh=/, en=/en/),单显不并排(铁律 6)。
|
||
*/
|
||
import { useEffect, useState } from 'react';
|
||
import { Download, Menu } from 'lucide-react';
|
||
|
||
function Mark() {
|
||
return (
|
||
<svg width="30" height="30" viewBox="0 0 96 96" fill="none" aria-hidden="true">
|
||
<g transform="translate(96,0) scale(-1,1)">
|
||
<path
|
||
d="M16 59 Q17 51 26 50 Q34 31 45 30 Q55 30 62 37 Q69 41 75 45 Q85 49 89 44 Q92 50 84 52 Q75 53 67 53 Q66 62 60 62 L56 62 Q54 55 49 55 Q47 62 37 62 L33 62 Q31 56 26 56 Q20 59 16 59 Z"
|
||
fill="#B96A3D"
|
||
/>
|
||
<g stroke="#FAF3ED" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" fill="none" opacity="0.85">
|
||
<path d="M26 50 Q34 43 42 50" />
|
||
<path d="M36 48 Q44 41 52 48" />
|
||
<path d="M46 48 Q54 41 62 49" />
|
||
</g>
|
||
<circle cx="23" cy="55" r="2.2" fill="#FAF3ED" />
|
||
</g>
|
||
</svg>
|
||
);
|
||
}
|
||
|
||
export default function Header({ lang = 'zh', t = {} }) {
|
||
const [open, setOpen] = useState(false);
|
||
const [scrolled, setScrolled] = useState(false);
|
||
|
||
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],
|
||
];
|
||
|
||
return (
|
||
<header class={`hdr${scrolled ? ' scrolled' : ''}`}>
|
||
<div class="wrap row">
|
||
<a class="brand" href="#top">
|
||
<Mark />
|
||
<span class="nm">穿山甲</span>
|
||
</a>
|
||
<nav class="nav">
|
||
{nav.map(([href, label]) => (
|
||
<a key={href} href={href}>{label}</a>
|
||
))}
|
||
</nav>
|
||
<div class="right">
|
||
<div class="langseg">
|
||
<a data-lang="zh" class={lang === 'zh' ? 'on' : undefined} href="/">中文</a>
|
||
<a data-lang="en" class={lang === 'en' ? 'on' : undefined} href="/en/">EN</a>
|
||
</div>
|
||
{/* 「登录」暂移除:Web 用户中心(web/usercenter)未部署、无 URL;待 #30 CI/CD
|
||
部署后接上 usercenter 登录地址再恢复。 */}
|
||
<a class="btn btn-primary" href="#download">
|
||
<Download />
|
||
<span>{t.get}</span>
|
||
</a>
|
||
<button class="menu-btn" onClick={() => setOpen((v) => !v)} aria-label="menu" aria-expanded={open}>
|
||
<Menu />
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class={`mnav${open ? ' open' : ''}`} id="mnav">
|
||
{nav.map(([href, label]) => (
|
||
<a key={href} href={href} onClick={() => setOpen(false)}>{label}</a>
|
||
))}
|
||
<a class="btn btn-primary" href="#signup" onClick={() => setOpen(false)}>
|
||
<span>{t.suBtn}</span>
|
||
</a>
|
||
</div>
|
||
</header>
|
||
);
|
||
}
|