FutureCloud/components/Navigation.tsx
2025-09-15 16:58:31 +08:00

157 lines
6.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useState } from 'react';
import { LanguageType } from '../lib/content';
interface NavigationProps {
/** 🔧 修改 #1currentLang 从 string 改为 LanguageType */
currentLang: LanguageType;
/** 🔧 修改 #2setCurrentLang 返回值改为 void原来写成了 string签名也保持只接受 LanguageType */
setCurrentLang: (lang: LanguageType) => void;
content: {
nav: {
home: string;
services: string;
solutions: string;
pricing: string;
news: string;
contact: string;
};
};
/** 🔧 修改 #3createLocalizedPath 的签名改为 (path: string) => string */
createLocalizedPath?: (path: string) => string;
}
export default function Navigation({
currentLang,
setCurrentLang,
content,
createLocalizedPath,
}: NavigationProps) {
const pathname = usePathname();
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
// Helper to build localized URLs
const getLocalizedPath = (path: string) => {
return createLocalizedPath ? createLocalizedPath(path) : path;
};
const navItems = [
{ label: content.nav.home, href: getLocalizedPath('/') },
{ label: content.nav.services, href: getLocalizedPath('/services') },
{ label: content.nav.solutions, href: getLocalizedPath('/solutions') },
{ label: content.nav.pricing, href: getLocalizedPath('/pricing') },
{ label: content.nav.news, href: getLocalizedPath('/news') },
{ label: content.nav.contact, href: getLocalizedPath('/contact') },
];
return (
<nav className="relative z-10 px-6 py-4 border-b border-cyan-500/20 backdrop-blur-sm">
<div className="max-w-7xl mx-auto flex justify-between items-center">
{/* Logo */}
<Link
href="/"
className="text-2xl font-bold bg-gradient-to-r from-cyan-400 to-blue-500 bg-clip-text text-transparent hover:scale-105 transition-transform duration-300"
>
CloudAgency
</Link>
{/* Desktop Nav */}
<div className="hidden md:flex space-x-8">
{navItems.map((item, idx) => {
const isActive = pathname === item.href;
return (
<Link
key={idx}
href={item.href}
className={`relative group transition-colors duration-300 ${
isActive ? 'text-cyan-400' : 'text-gray-300 hover:text-cyan-400'
}`}
>
{item.label}
<span
className={`absolute -bottom-1 left-0 h-0.5 bg-cyan-400 transition-all duration-300 ${
isActive ? 'w-full' : 'w-0 group-hover:w-full'
}`}
/>
</Link>
);
})}
</div>
{/* Right side */}
<div className="flex items-center space-x-4">
{/* 🔧 修改 #4onChange 时将 value 强制断言为 LanguageType */}
<select
value={currentLang}
onChange={(e) => setCurrentLang(e.target.value as LanguageType)}
className="bg-gray-800 border border-cyan-500/30 rounded-lg px-3 py-1 text-sm focus:outline-none focus:border-cyan-400 transition-colors"
>
<option value="zh-CN"></option>
<option value="zh-TW"></option>
<option value="en">English</option>
</select>
{/* Mobile menu button */}
<button
className="md:hidden text-gray-300 hover:text-cyan-400 transition-colors"
onClick={() => setIsMobileMenuOpen((o) => !o)}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
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 Menu */}
{isMobileMenuOpen && (
<div className="md:hidden absolute top-full left-0 right-0 bg-gray-900/95 backdrop-blur-sm border-b border-cyan-500/20">
<div className="px-6 py-4 space-y-4">
{navItems.map((item, idx) => {
const isActive = pathname === item.href;
return (
<Link
key={idx}
href={item.href}
className={`block py-2 transition-colors duration-300 ${
isActive
? 'text-cyan-400'
: 'text-gray-300 hover:text-cyan-400'
}`}
onClick={() => setIsMobileMenuOpen(false)}
>
{item.label}
</Link>
);
})}
</div>
</div>
)}
</nav>
);
}