261 lines
8.7 KiB
TypeScript
261 lines
8.7 KiB
TypeScript
'use client'
|
|
|
|
import Link from 'next/link'
|
|
import { useState, useEffect } from 'react'
|
|
import { usePathname, useRouter } from 'next/navigation'
|
|
import { User, ShoppingCart, Menu, X } from 'lucide-react'
|
|
|
|
interface User {
|
|
id: string
|
|
email: string
|
|
username: string
|
|
name?: string
|
|
isAdmin: boolean
|
|
}
|
|
|
|
export function Navbar() {
|
|
const [user, setUser] = useState<User | null>(null)
|
|
const [isMenuOpen, setIsMenuOpen] = useState(false)
|
|
const pathname = usePathname()
|
|
const router = useRouter()
|
|
|
|
useEffect(() => {
|
|
// 检查用户登录状态
|
|
const checkUserStatus = () => {
|
|
const token = localStorage.getItem('token')
|
|
if (token) {
|
|
const userData = localStorage.getItem('user')
|
|
if (userData) {
|
|
setUser(JSON.parse(userData))
|
|
}
|
|
} else {
|
|
setUser(null)
|
|
}
|
|
}
|
|
|
|
checkUserStatus()
|
|
|
|
// 监听localStorage变化
|
|
const handleStorageChange = (e: StorageEvent) => {
|
|
if (e.key === 'user' || e.key === 'token') {
|
|
checkUserStatus()
|
|
}
|
|
}
|
|
|
|
// 监听自定义用户更新事件
|
|
const handleUserUpdate = () => {
|
|
checkUserStatus()
|
|
}
|
|
|
|
window.addEventListener('storage', handleStorageChange)
|
|
window.addEventListener('user-updated', handleUserUpdate)
|
|
|
|
return () => {
|
|
window.removeEventListener('storage', handleStorageChange)
|
|
window.removeEventListener('user-updated', handleUserUpdate)
|
|
}
|
|
}, [])
|
|
|
|
const handleLogout = () => {
|
|
localStorage.removeItem('token')
|
|
localStorage.removeItem('user')
|
|
setUser(null)
|
|
// 触发用户更新事件
|
|
window.dispatchEvent(new Event('user-updated'))
|
|
router.push('/')
|
|
}
|
|
|
|
// 检查当前路径是否匹配
|
|
const isActive = (path: string) => {
|
|
if (path === '/') {
|
|
return pathname === '/'
|
|
}
|
|
return pathname.startsWith(path)
|
|
}
|
|
|
|
// 导航链接样式
|
|
const getLinkStyle = (path: string) => {
|
|
return isActive(path)
|
|
? 'text-blue-600 font-medium'
|
|
: 'text-gray-700 hover:text-blue-600'
|
|
}
|
|
|
|
return (
|
|
<nav className="bg-white shadow-md sticky top-0 z-50">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="flex justify-between items-center h-16">
|
|
{/* Logo */}
|
|
<Link href="/" className="text-2xl font-bold text-blue-600">
|
|
PC DIY商城
|
|
</Link> {/* Desktop Navigation */}
|
|
<div className="hidden md:flex space-x-8">
|
|
<Link href="/" className={getLinkStyle('/')}>
|
|
首页
|
|
</Link>
|
|
<Link href="/components" className={getLinkStyle('/components')}>
|
|
配件商城
|
|
</Link>
|
|
<Link href="/build" className={getLinkStyle('/build')}>
|
|
装机配置
|
|
</Link>
|
|
<Link href="/ai-assistant" className={getLinkStyle('/ai-assistant')}>
|
|
AI助手
|
|
</Link>
|
|
</div>
|
|
|
|
{/* User Actions */}
|
|
<div className="hidden md:flex items-center space-x-4">
|
|
{user ? (
|
|
<div className="flex items-center space-x-4">
|
|
<Link href="/cart" className="text-gray-700 hover:text-blue-600">
|
|
<ShoppingCart className="h-6 w-6" />
|
|
</Link>
|
|
<div className="relative group">
|
|
<button className="flex items-center space-x-2 text-gray-700 hover:text-blue-600">
|
|
<User className="h-6 w-6" />
|
|
<span>{user.name || user.username}</span>
|
|
</button>
|
|
<div className="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200">
|
|
<Link href="/profile" className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
|
|
个人资料
|
|
</Link>
|
|
<Link href="/orders" className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
|
|
我的订单
|
|
</Link>
|
|
{user.isAdmin && (
|
|
<Link href="/admin" className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
|
|
管理后台
|
|
</Link>
|
|
)}
|
|
<button
|
|
onClick={handleLogout}
|
|
className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
|
|
>
|
|
退出登录
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="flex items-center space-x-4">
|
|
<Link
|
|
href="/login"
|
|
className="text-gray-700 hover:text-blue-600"
|
|
>
|
|
登录
|
|
</Link>
|
|
<Link
|
|
href="/register"
|
|
className="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700"
|
|
>
|
|
注册
|
|
</Link>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Mobile menu button */}
|
|
<div className="md:hidden">
|
|
<button
|
|
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
|
className="text-gray-700 hover:text-blue-600"
|
|
>
|
|
{isMenuOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />}
|
|
</button>
|
|
</div>
|
|
</div> {/* Mobile Navigation */}
|
|
{isMenuOpen && (
|
|
<div className="md:hidden">
|
|
<div className="px-2 pt-2 pb-3 space-y-1 sm:px-3">
|
|
<Link
|
|
href="/"
|
|
className={`block px-3 py-2 ${getLinkStyle('/')}`}
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
首页
|
|
</Link>
|
|
<Link
|
|
href="/components"
|
|
className={`block px-3 py-2 ${getLinkStyle('/components')}`}
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
配件商城
|
|
</Link> <Link
|
|
href="/build"
|
|
className={`block px-3 py-2 ${getLinkStyle('/build')}`}
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
装机配置
|
|
</Link>
|
|
<Link
|
|
href="/ai-assistant"
|
|
className={`block px-3 py-2 ${getLinkStyle('/ai-assistant')}`}
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
AI助手
|
|
</Link>
|
|
{user ? (
|
|
<>
|
|
<Link
|
|
href="/cart"
|
|
className="block px-3 py-2 text-gray-700 hover:text-blue-600"
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
购物车
|
|
</Link>
|
|
<Link
|
|
href="/profile"
|
|
className="block px-3 py-2 text-gray-700 hover:text-blue-600"
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
个人资料
|
|
</Link>
|
|
<Link
|
|
href="/orders"
|
|
className="block px-3 py-2 text-gray-700 hover:text-blue-600"
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
我的订单
|
|
</Link>
|
|
{user.isAdmin && (
|
|
<Link
|
|
href="/admin"
|
|
className="block px-3 py-2 text-gray-700 hover:text-blue-600"
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
管理后台
|
|
</Link>
|
|
)}
|
|
<button
|
|
onClick={handleLogout}
|
|
className="block w-full text-left px-3 py-2 text-gray-700 hover:text-blue-600"
|
|
>
|
|
退出登录
|
|
</button>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Link
|
|
href="/login"
|
|
className="block px-3 py-2 text-gray-700 hover:text-blue-600"
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
登录
|
|
</Link>
|
|
<Link
|
|
href="/register"
|
|
className="block px-3 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
|
|
onClick={() => setIsMenuOpen(false)}
|
|
>
|
|
注册
|
|
</Link>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</nav>
|
|
)
|
|
}
|