Files
department-web/src/components/Navbar.js

278 lines
8.6 KiB
JavaScript
Raw Normal View History

2025-12-08 18:24:13 +08:00
import React, { useState, useRef, useEffect } from 'react';
2025-12-08 10:49:49 +08:00
import { useNavigate, Link } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import './Navbar.css';
2025-12-08 18:24:13 +08:00
const productMenu = [
{
key: 'smart',
label: '智能系列',
subs: [
{
key: 'N96',
label: 'N96',
products: [
{ name: 'N96', desc: 'Android11高性能适配复杂场景', image: '/uploads/menu/menu_n96.png' }
2025-12-08 18:24:13 +08:00
]
},
{
key: 'N96P',
label: 'N96P',
products: [
{ name: 'N96P', desc: 'Android14高性能适配复杂场景', image: '/uploads/menu/menu_n96p.png' }
2025-12-08 18:24:13 +08:00
]
},
{
key: 'N92',
label: 'N92',
products: [
{ name: 'N92', desc: 'Android13高性能适配复杂场景', image: '/uploads/menu/menu_n92.png' }
2025-12-08 18:24:13 +08:00
]
},
{
key: 'N86P',
label: 'N86P',
products: [
{ name: 'N86P', desc: 'Android13高性能适配复杂场景', image: '/uploads/menu/menu_n86p.png' }
2025-12-08 18:24:13 +08:00
]
},
{
key: 'N86',
label: 'N86',
products: [
{ name: 'N86', desc: 'Android9高性能适配复杂场景', image: '/uploads/menu/menu_n86.png' }
2025-12-08 18:24:13 +08:00
]
},
{
key: 'N82',
label: 'N82',
products: [
{ name: 'N82', desc: 'Android10高性能适配复杂场景', image: '/uploads/menu/menu_n82.png' }
2025-12-08 18:24:13 +08:00
]
},
{
key: 'N80',
label: 'N80',
products: [
{ name: 'N80', desc: 'Android13高性能适配复杂场景', image: '/uploads/menu/menu_n80.png' }
2025-12-08 18:24:13 +08:00
]
},
{
key: 'N62',
label: 'N62',
products: [
{ name: 'N62', desc: 'Android11高性能适配复杂场景', image: '/uploads/menu/menu_n62.png' }
2025-12-08 18:24:13 +08:00
]
},
{
key: 'N6P',
label: 'N6P',
products: [
{ name: 'N6P', desc: 'Android13高性能适配复杂场景', image: '/uploads/menu/menu_n6p.png' }
2025-12-08 18:24:13 +08:00
]
},
{
key: 'N6',
label: 'N6',
products: [
{ name: 'N6', desc: 'Android7高性能适配复杂场景', image: '/uploads/menu/menu_n6.png' }
2025-12-08 18:24:13 +08:00
]
},
]
},
{
key: 'traditional',
label: '传统系列',
subs: [
{
key: 'k300',
label: 'K300',
products: [
{ name: 'K300', desc: '标准版,覆盖主流需求', image: '/uploads/menu/menu_k300.png' }
2025-12-08 18:24:13 +08:00
]
},
]
},
{
key: 'basic',
label: '基础系列',
subs: [
{
key: 'kd69',
label: 'KD69',
products: [
{ name: 'KD69', desc: '专业场景,扩展性强', image: '/uploads/menu/menu_kd69.png' },
2025-12-08 18:24:13 +08:00
]
},
]
}
];
2025-12-08 10:49:49 +08:00
const Navbar = () => {
const navigate = useNavigate();
const { user, logout } = useAuth();
const [search, setSearch] = useState('');
2025-12-08 18:24:13 +08:00
const [activeSeries, setActiveSeries] = useState(productMenu[0].key);
const [activeSub, setActiveSub] = useState(productMenu[0].subs[0].key);
const productsRef = useRef(null);
const [productsOpen, setProductsOpen] = useState(false);
const [productsSelected, setProductsSelected] = useState(false);
2025-12-08 18:24:13 +08:00
useEffect(() => {
const handleClickOutside = (e) => {
if (productsRef.current && !productsRef.current.contains(e.target)) {
setProductsOpen(false);
setProductsSelected(false);
2025-12-08 18:24:13 +08:00
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
2025-12-08 10:49:49 +08:00
const handleLoginClick = () => {
navigate('/login');
};
const handleLogoutClick = () => {
logout();
navigate('/');
};
const handleSearchKeyDown = (e) => {
if (e.key === 'Enter') {
navigate('/');
2025-12-08 10:49:49 +08:00
}
};
return (
<nav className="navbar">
<div className="navbar-inner">
<div className="navbar-left">
2025-12-08 13:48:54 +08:00
<Link to="/" className="logo">
<img
src="/uploads/menu/logo.svg"
2025-12-08 13:48:54 +08:00
alt="Logo"
className="logo-img"
/>
</Link>
2025-12-08 10:49:49 +08:00
<div className={`nav-item ${productsOpen ? 'open' : ''} ${productsSelected ? 'selected' : ''}`} ref={productsRef}>
<span
className="nav-label"
onClick={() => {
setProductsOpen((prev) => {
const next = !prev;
setProductsSelected(next);
return next;
});
}}
>产品</span>
2025-12-08 18:24:13 +08:00
<div className="dropdown mega">
<div className="mega-col">
<div className="mega-title">系列</div>
<div className="mega-list">
{productMenu.map((series) => (
<button
key={series.key}
className={`mega-item ${series.key === activeSeries ? 'active' : ''}`}
onClick={() => {
setActiveSeries(series.key);
setActiveSub(series.subs[0]?.key || '');
}}
>
{series.label}
</button>
))}
</div>
</div>
<div className="mega-col">
<div className="mega-title">型号</div>
<div className="mega-list">
{productMenu.find(s => s.key === activeSeries)?.subs.map((sub) => (
<button
key={sub.key}
className={`mega-item ${sub.key === activeSub ? 'active' : ''}`}
onClick={() => setActiveSub(sub.key)}
>
{sub.label}
</button>
))}
</div>
</div>
<div className="mega-col mega-wide">
<div className="mega-title">介绍</div>
<div className="mega-products">
{productMenu
.find(s => s.key === activeSeries)
?.subs.find(sub => sub.key === activeSub)
?.products.map((p, idx) => (
<div
key={idx}
className="mega-product"
onClick={() => {
setProductsOpen(false);
navigate(`/product/${activeSeries}/${activeSub}/${idx}`, {
state: { product: p, series: activeSeries, sub: activeSub }
});
}}
style={{ cursor: 'pointer' }}
>
<img src={p.image} alt={p.name} />
<div className="mega-product-info">
<div className="name">{p.name}</div>
<div className="desc">{p.desc}</div>
</div>
</div>
))}
</div>
</div>
2025-12-08 10:49:49 +08:00
</div>
</div>
{/* <div className="nav-item">
2025-12-08 10:49:49 +08:00
<span className="nav-label">解决方案</span>
<div className="dropdown">
<Link to="/" className="dropdown-item">解决方案A</Link>
<Link to="/" className="dropdown-item">解决方案B</Link>
<Link to="/" className="dropdown-item">解决方案C</Link>
</div>
</div> */}
2025-12-08 10:49:49 +08:00
{/* <div className="nav-item">
2025-12-08 10:49:49 +08:00
<span className="nav-label">行业</span>
<div className="dropdown">
<Link to="/" className="dropdown-item">民航</Link>
<Link to="/" className="dropdown-item">通航</Link>
<Link to="/" className="dropdown-item">研发制造</Link>
</div>
</div> */}
2025-12-08 10:49:49 +08:00
</div>
<div className="navbar-right">
<input
type="text"
className="search-input"
placeholder="搜索..."
value={search}
onChange={(e) => setSearch(e.target.value)}
onKeyDown={handleSearchKeyDown}
/>
{user ? (
<div className="user-area">
<span className="username">{user.name || user.username}</span>
<button className="btn btn-secondary" onClick={handleLogoutClick}>退出</button>
</div>
) : (
<button className="btn btn-primary" onClick={handleLoginClick}>登录</button>
)}
</div>
</div>
</nav>
);
};
export default Navbar;