179 lines
7.2 KiB
TypeScript
179 lines
7.2 KiB
TypeScript
|
|
'use client';
|
||
|
|
|
||
|
|
import { useState, useEffect } from 'react';
|
||
|
|
import Image from 'next/image';
|
||
|
|
import ProductMenu from './ProductMenu';
|
||
|
|
import ResourceMenu from './ResourceMenu';
|
||
|
|
|
||
|
|
export default function Navbar() {
|
||
|
|
const [scrolled, setScrolled] = useState(false);
|
||
|
|
const [language, setLanguage] = useState<'zh' | 'en'>('zh');
|
||
|
|
const [showLangMenu, setShowLangMenu] = useState(false);
|
||
|
|
const [showProductMenu, setShowProductMenu] = useState(false);
|
||
|
|
const [showResourceMenu, setShowResourceMenu] = useState(false);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const handleScroll = () => {
|
||
|
|
setScrolled(window.scrollY > 50);
|
||
|
|
};
|
||
|
|
|
||
|
|
window.addEventListener('scroll', handleScroll);
|
||
|
|
return () => window.removeEventListener('scroll', handleScroll);
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const handleClickOutside = (e: MouseEvent) => {
|
||
|
|
const target = e.target as Element;
|
||
|
|
if (showLangMenu && !target.closest('.language-selector')) {
|
||
|
|
setShowLangMenu(false);
|
||
|
|
}
|
||
|
|
if (showProductMenu && !target.closest('.product-menu-container')) {
|
||
|
|
setShowProductMenu(false);
|
||
|
|
}
|
||
|
|
if (showResourceMenu && !target.closest('.resource-menu-container')) {
|
||
|
|
setShowResourceMenu(false);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
document.addEventListener('click', handleClickOutside);
|
||
|
|
return () => document.removeEventListener('click', handleClickOutside);
|
||
|
|
}, [showLangMenu, showProductMenu, showResourceMenu]);
|
||
|
|
|
||
|
|
const toggleLanguage = (lang: 'zh' | 'en') => {
|
||
|
|
setLanguage(lang);
|
||
|
|
setShowLangMenu(false);
|
||
|
|
};
|
||
|
|
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<nav className={`fixed top-0 left-0 right-0 z-50 px-10 py-5 flex items-center justify-between transition-all duration-300 ${
|
||
|
|
scrolled
|
||
|
|
? 'bg-white/70 backdrop-blur-[50px] shadow-sm'
|
||
|
|
: 'bg-white/90 backdrop-blur-[50px]'
|
||
|
|
}`}>
|
||
|
|
{/* Logo Section */}
|
||
|
|
<div className="flex-1">
|
||
|
|
<Image
|
||
|
|
src="/logo0.svg"
|
||
|
|
alt="Logo"
|
||
|
|
width={160}
|
||
|
|
height={40}
|
||
|
|
priority
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Navigation Menu */}
|
||
|
|
<div className="flex items-center gap-12">
|
||
|
|
<div className="flex items-center gap-6">
|
||
|
|
{/* Product - Active */}
|
||
|
|
<div className="product-menu-container">
|
||
|
|
<div
|
||
|
|
className={`rounded-lg px-4 py-2 h-9 flex items-center justify-center cursor-pointer transition-colors ${
|
||
|
|
showProductMenu ? 'bg-[#f3f4f6]' : 'bg-transparent hover:bg-[#f3f4f6]'
|
||
|
|
}`}
|
||
|
|
onClick={() => {
|
||
|
|
setShowProductMenu(!showProductMenu);
|
||
|
|
setShowResourceMenu(false);
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<span className={`font-bold text-sm leading-[150%] font-inter ${
|
||
|
|
showProductMenu ? 'text-[#111827]' : 'text-[#4b5563]'
|
||
|
|
}`}>
|
||
|
|
{language === 'zh' ? '产品' : 'Product'}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Ecosystem */}
|
||
|
|
<div className="bg-transparent rounded-lg px-4 py-2 h-9 flex items-center justify-center hover:bg-[#f3f4f6] transition-colors cursor-pointer">
|
||
|
|
<span className="text-[#4b5563] font-bold text-sm leading-[150%] font-inter">
|
||
|
|
{language === 'zh' ? '生态' : 'Ecosystem'}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Resource */}
|
||
|
|
<div className="resource-menu-container">
|
||
|
|
<div
|
||
|
|
className={`rounded-lg px-4 py-2 h-9 flex items-center justify-center cursor-pointer transition-colors ${
|
||
|
|
showResourceMenu ? 'bg-[#f3f4f6]' : 'bg-transparent hover:bg-[#f3f4f6]'
|
||
|
|
}`}
|
||
|
|
onClick={() => {
|
||
|
|
setShowResourceMenu(!showResourceMenu);
|
||
|
|
setShowProductMenu(false);
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<span className={`font-bold text-sm leading-[150%] font-inter ${
|
||
|
|
showResourceMenu ? 'text-[#111827]' : 'text-[#4b5563]'
|
||
|
|
}`}>
|
||
|
|
{language === 'zh' ? '资源' : 'Resource'}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Launch App Button & Language Selector */}
|
||
|
|
<div className="flex-1 flex justify-end items-center gap-4">
|
||
|
|
<div className="bg-[#111827] rounded-lg px-5 py-2.5 h-10 flex items-center justify-center overflow-hidden cursor-pointer hover:opacity-90 transition-opacity">
|
||
|
|
<span className="text-[#fcfcfd] font-bold text-sm leading-[150%] font-inter">
|
||
|
|
{language === 'zh' ? '启动应用' : 'Launch App'}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Language Selector */}
|
||
|
|
<div className="relative language-selector">
|
||
|
|
<div
|
||
|
|
className="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-[#f3f4f6] transition-colors cursor-pointer"
|
||
|
|
onClick={() => setShowLangMenu(!showLangMenu)}
|
||
|
|
>
|
||
|
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
|
|
<path d="M10 18.3333C14.6024 18.3333 18.3333 14.6024 18.3333 10C18.3333 5.39763 14.6024 1.66667 10 1.66667C5.39763 1.66667 1.66667 5.39763 1.66667 10C1.66667 14.6024 5.39763 18.3333 10 18.3333Z" stroke="#4B5563" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
||
|
|
<path d="M1.66667 10H18.3333" stroke="#4B5563" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
||
|
|
<path d="M10 1.66667C12.0844 3.94863 13.269 6.91003 13.3333 10C13.269 13.09 12.0844 16.0514 10 18.3333C7.91561 16.0514 6.73104 13.09 6.66667 10C6.73104 6.91003 7.91561 3.94863 10 1.66667Z" stroke="#4B5563" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
||
|
|
</svg>
|
||
|
|
<span className="text-[#4b5563] font-inter text-sm font-bold">
|
||
|
|
{language === 'zh' ? '中文' : 'EN'}
|
||
|
|
</span>
|
||
|
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
|
|
<path d="M3 4.5L6 7.5L9 4.5" stroke="#4B5563" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
||
|
|
</svg>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Dropdown Menu */}
|
||
|
|
{showLangMenu && (
|
||
|
|
<div className="absolute right-0 mt-2 w-32 bg-white rounded-lg shadow-lg border border-[#e5e7eb] overflow-hidden z-50">
|
||
|
|
<div
|
||
|
|
className={`px-4 py-2.5 hover:bg-[#f3f4f6] cursor-pointer transition-colors ${
|
||
|
|
language === 'zh' ? 'bg-[#f3f4f6]' : ''
|
||
|
|
}`}
|
||
|
|
onClick={() => toggleLanguage('zh')}
|
||
|
|
>
|
||
|
|
<span className="text-[#111827] font-inter text-sm font-medium">中文</span>
|
||
|
|
</div>
|
||
|
|
<div
|
||
|
|
className={`px-4 py-2.5 hover:bg-[#f3f4f6] cursor-pointer transition-colors ${
|
||
|
|
language === 'en' ? 'bg-[#f3f4f6]' : ''
|
||
|
|
}`}
|
||
|
|
onClick={() => toggleLanguage('en')}
|
||
|
|
>
|
||
|
|
<span className="text-[#111827] font-inter text-sm font-medium">English</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</nav>
|
||
|
|
<ProductMenu
|
||
|
|
isOpen={showProductMenu}
|
||
|
|
onClose={() => setShowProductMenu(false)}
|
||
|
|
language={language}
|
||
|
|
/>
|
||
|
|
<ResourceMenu
|
||
|
|
isOpen={showResourceMenu}
|
||
|
|
onClose={() => setShowResourceMenu(false)}
|
||
|
|
language={language}
|
||
|
|
/>
|
||
|
|
</>
|
||
|
|
);
|
||
|
|
}
|