Files
department-web/src/components/Navbar.js
2025-12-09 14:23:22 +08:00

278 lines
8.6 KiB
JavaScript
Executable File
Raw 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.
import React, { useState, useRef, useEffect } from 'react';
import { useNavigate, Link } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import './Navbar.css';
const productMenu = [
{
key: 'smart',
label: '智能系列',
subs: [
{
key: 'N96',
label: 'N96',
products: [
{ name: 'N96', desc: 'Android11高性能适配复杂场景', image: '/uploads/menu/menu_n96.png' }
]
},
{
key: 'N96P',
label: 'N96P',
products: [
{ name: 'N96P', desc: 'Android14高性能适配复杂场景', image: '/uploads/menu/menu_n96p.png' }
]
},
{
key: 'N92',
label: 'N92',
products: [
{ name: 'N92', desc: 'Android13高性能适配复杂场景', image: '/uploads/menu/menu_n92.png' }
]
},
{
key: 'N86P',
label: 'N86P',
products: [
{ name: 'N86P', desc: 'Android13高性能适配复杂场景', image: '/uploads/menu/menu_n86p.png' }
]
},
{
key: 'N86',
label: 'N86',
products: [
{ name: 'N86', desc: 'Android9高性能适配复杂场景', image: '/uploads/menu/menu_n86.png' }
]
},
{
key: 'N82',
label: 'N82',
products: [
{ name: 'N82', desc: 'Android10高性能适配复杂场景', image: '/uploads/menu/menu_n82.png' }
]
},
{
key: 'N80',
label: 'N80',
products: [
{ name: 'N80', desc: 'Android13高性能适配复杂场景', image: '/uploads/menu/menu_n80.png' }
]
},
{
key: 'N62',
label: 'N62',
products: [
{ name: 'N62', desc: 'Android11高性能适配复杂场景', image: '/uploads/menu/menu_n62.png' }
]
},
{
key: 'N6P',
label: 'N6P',
products: [
{ name: 'N6P', desc: 'Android13高性能适配复杂场景', image: '/uploads/menu/menu_n6p.png' }
]
},
{
key: 'N6',
label: 'N6',
products: [
{ name: 'N6', desc: 'Android7高性能适配复杂场景', image: '/uploads/menu/menu_n6.png' }
]
},
]
},
{
key: 'traditional',
label: '传统系列',
subs: [
{
key: 'k300',
label: 'K300',
products: [
{ name: 'K300', desc: '标准版,覆盖主流需求', image: '/uploads/menu/menu_k300.png' }
]
},
]
},
{
key: 'basic',
label: '基础系列',
subs: [
{
key: 'kd69',
label: 'KD69',
products: [
{ name: 'KD69', desc: '专业场景,扩展性强', image: '/uploads/menu/menu_kd69.png' },
]
},
]
}
];
const Navbar = () => {
const navigate = useNavigate();
const { user, logout } = useAuth();
const [search, setSearch] = useState('');
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);
useEffect(() => {
const handleClickOutside = (e) => {
if (productsRef.current && !productsRef.current.contains(e.target)) {
setProductsOpen(false);
setProductsSelected(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
const handleLoginClick = () => {
navigate('/login');
};
const handleLogoutClick = () => {
logout();
navigate('/');
};
const handleSearchKeyDown = (e) => {
if (e.key === 'Enter') {
navigate('/');
}
};
return (
<nav className="navbar">
<div className="navbar-inner">
<div className="navbar-left">
<Link to="/" className="logo">
<img
src="/uploads/menu/logo.svg"
alt="Logo"
className="logo-img"
/>
</Link>
<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>
<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>
</div>
</div>
{/* <div className="nav-item">
<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> */}
{/* <div className="nav-item">
<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> */}
</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;