NebulaCloud/components/Navigation.tsx
2025-09-15 17:28:58 +08:00

131 lines
5.6 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import { Locale } from '../lib/i18n';
import { getTranslations } from '../lib/translations';
interface NavigationProps {
locale?: Locale;
}
export default function Navigation({ locale = 'en' }: NavigationProps) {
const [isScrolled, setIsScrolled] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const t = getTranslations(locale);
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 50);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const navItems = [
{ href: `/${locale}#hero`, label: t.nav.heroSection },
{ href: `/${locale}#about`, label: t.nav.aboutEcoLife },
{ href: `/${locale}/products`, label: t.nav.products },
{ href: `/${locale}/blog`, label: t.nav.blog },
{ href: `/${locale}/contact`, label: t.nav.contact },
];
return (
<nav
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
isScrolled
? 'bg-slate-900/95 backdrop-blur-md border-b border-white/10'
: 'bg-transparent'
}`}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16">
{/* Logo */}
<div className="flex-shrink-0">
<a
href={`/${locale}`}
className="text-2xl font-bold text-white hover:text-green-400 transition-colors duration-200"
>
Nebula <span className="text-green-400">Cloud</span>
</a>
</div>
{/* Desktop Navigation */}
<div className="hidden md:block">
<div className="ml-10 flex items-baseline space-x-8">
{navItems.map((item) => (
<a
key={item.href}
href={item.href}
className="text-white/90 hover:text-green-400 px-3 py-2 rounded-md text-sm font-medium transition-colors duration-200"
>
{item.label}
</a>
))}
</div>
</div>
{/* Download Button */}
<div className="hidden md:block">
<button className="bg-green-500 hover:bg-green-600 text-white px-6 py-2 rounded-full font-medium transition-all duration-200 transform hover:scale-105">
{t.nav.download}
</button>
</div>
{/* Mobile menu button */}
<div className="md:hidden">
<button
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
className="text-white hover:text-green-400 p-2"
>
<svg
className="h-6 w-6"
stroke="currentColor"
fill="none"
viewBox="0 0 24 24"
>
{isMobileMenuOpen ? (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
) : (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
/>
)}
</svg>
</button>
</div>
</div>
{/* Mobile Navigation */}
{isMobileMenuOpen && (
<div className="md:hidden">
<div className="px-2 pt-2 pb-3 space-y-1 bg-slate-900/95 backdrop-blur-md rounded-lg mt-2">
{navItems.map((item) => (
<a
key={item.href}
href={item.href}
className="text-white/90 hover:text-green-400 block px-3 py-2 rounded-md text-base font-medium transition-colors duration-200"
onClick={() => setIsMobileMenuOpen(false)}
>
{item.label}
</a>
))}
<button className="w-full bg-green-500 hover:bg-green-600 text-white px-6 py-2 rounded-full font-medium transition-all duration-200 mt-4">
{t.nav.download}
</button>
</div>
</div>
)}
</div>
</nav>
);
}