151 lines
5.0 KiB
JavaScript
151 lines
5.0 KiB
JavaScript
import { useState, useEffect } from 'react';
|
|
import { Input, Button, Space, Dropdown, Avatar } from 'antd';
|
|
import { SearchOutlined, CameraOutlined, MenuOutlined, UserOutlined, LogoutOutlined, ShoppingOutlined } from '@ant-design/icons';
|
|
import { getCurrentUser, isLoggedIn, logout } from '../api/auth';
|
|
import LoginModal from './LoginModal';
|
|
import RegisterModal from './RegisterModal';
|
|
import './Header.css';
|
|
|
|
const Header = () => {
|
|
const [searchValue, setSearchValue] = useState('');
|
|
const [loginOpen, setLoginOpen] = useState(false);
|
|
const [registerOpen, setRegisterOpen] = useState(false);
|
|
const [user, setUser] = useState(null);
|
|
|
|
useEffect(() => {
|
|
if (isLoggedIn()) {
|
|
setUser(getCurrentUser());
|
|
}
|
|
}, []);
|
|
|
|
const menuItems = [
|
|
{ key: 'type', label: '类型', children: [
|
|
{ key: 'poster', label: '海报' },
|
|
{ key: 'banner', label: 'Banner' },
|
|
{ key: 'ecommerce', label: '电商' },
|
|
{ key: 'illustration', label: '插画' },
|
|
]},
|
|
{ key: 'theme', label: '主题', children: [
|
|
{ key: 'realestate', label: '地产' },
|
|
{ key: 'medical', label: '医美' },
|
|
{ key: 'travel', label: '旅游' },
|
|
{ key: 'tech', label: '科技' },
|
|
]},
|
|
{ key: 'style', label: '风格', children: [
|
|
{ key: 'chinese', label: '中式' },
|
|
{ key: 'premium', label: '高端' },
|
|
{ key: 'creative', label: '创意' },
|
|
{ key: 'minimalist', label: '清新' },
|
|
]},
|
|
];
|
|
|
|
const handleOpenLogin = () => {
|
|
setRegisterOpen(false);
|
|
setLoginOpen(true);
|
|
};
|
|
|
|
const handleOpenRegister = () => {
|
|
setLoginOpen(false);
|
|
setRegisterOpen(true);
|
|
};
|
|
|
|
const handleCloseLogin = () => {
|
|
setLoginOpen(false);
|
|
};
|
|
|
|
const handleCloseRegister = () => {
|
|
setRegisterOpen(false);
|
|
};
|
|
|
|
const handleLogout = () => {
|
|
logout();
|
|
};
|
|
|
|
const userMenuItems = [
|
|
{
|
|
key: 'orders',
|
|
label: '我的订单',
|
|
icon: <ShoppingOutlined />
|
|
},
|
|
{
|
|
key: 'logout',
|
|
label: '退出登录',
|
|
icon: <LogoutOutlined />,
|
|
onClick: handleLogout
|
|
}
|
|
];
|
|
|
|
return (
|
|
<>
|
|
<header className="header">
|
|
<div className="header-container">
|
|
<div className="header-left">
|
|
<a href="/" className="logo">
|
|
<svg viewBox="0 0 40 24" className="logo-icon">
|
|
<path d="M20 0c-5.5 0-10 4.5-10 10s4.5 10 10 10c2.8 0 5.3-1.1 7.1-2.9L20 10l7.1-7.1C25.3 1.1 22.8 0 20 0z" fill="#ff5a5a"/>
|
|
<path d="M30 4c-5.5 0-10 4.5-10 10s4.5 10 10 10c5.5 0 10-4.5 10-10S35.5 4 30 4zm0 16c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6z" fill="#ff5a5a"/>
|
|
</svg>
|
|
<span className="logo-text">图汇</span>
|
|
<span className="logo-domain">DESIGN006.COM</span>
|
|
</a>
|
|
</div>
|
|
|
|
<nav className="header-nav">
|
|
<Dropdown menu={{ items: menuItems }} placement="bottom">
|
|
<a className="nav-item" onClick={e => e.preventDefault()}>
|
|
<MenuOutlined /> 目录
|
|
</a>
|
|
</Dropdown>
|
|
<a href="#" className="nav-item">热门</a>
|
|
<a href="#" className="nav-item nav-new">
|
|
最新
|
|
<span className="new-dot"></span>
|
|
</a>
|
|
<a href="#" className="nav-item">图片</a>
|
|
<a href="#" className="nav-item">字体</a>
|
|
</nav>
|
|
|
|
<div className="header-search">
|
|
<Input
|
|
placeholder="搜索作品或编号"
|
|
value={searchValue}
|
|
onChange={(e) => setSearchValue(e.target.value)}
|
|
prefix={<SearchOutlined style={{ color: '#999' }} />}
|
|
suffix={<CameraOutlined style={{ color: '#999', cursor: 'pointer' }} />}
|
|
/>
|
|
</div>
|
|
|
|
<div className="header-right">
|
|
{user ? (
|
|
<Dropdown menu={{ items: userMenuItems }} placement="bottomRight">
|
|
<div style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }} data-testid="user-dropdown">
|
|
<Avatar icon={<UserOutlined />} style={{ marginRight: 8 }} className="ant-avatar" />
|
|
<span>{user.nickname || user.phone}</span>
|
|
</div>
|
|
</Dropdown>
|
|
) : (
|
|
<>
|
|
<Button className="btn-register" onClick={handleOpenRegister} data-testid="header-register-btn">注册</Button>
|
|
<Button className="btn-login" onClick={handleOpenLogin} data-testid="header-login-btn">登录</Button>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<LoginModal
|
|
open={loginOpen}
|
|
onClose={handleCloseLogin}
|
|
onSwitchToRegister={handleOpenRegister}
|
|
/>
|
|
<RegisterModal
|
|
open={registerOpen}
|
|
onClose={handleCloseRegister}
|
|
onSwitchToLogin={handleOpenLogin}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Header;
|