153 lines
5.5 KiB
TypeScript
153 lines
5.5 KiB
TypeScript
import { Badge, Button, Dropdown, Layout, Space, Typography } from 'antd'
|
|
import { Link, Outlet, useNavigate } from 'react-router-dom'
|
|
import { UserOutlined } from '@ant-design/icons'
|
|
|
|
import { BrandLogo } from '@/components/BrandLogo'
|
|
import { useChatUnreadCount } from '@/features/messages/api'
|
|
import { useSessionStore } from '@/stores/session'
|
|
|
|
const { Header, Content, Footer } = Layout
|
|
|
|
export function StorefrontLayout() {
|
|
const navigate = useNavigate()
|
|
const user = useSessionStore(state => state.user)
|
|
const logout = useSessionStore(state => state.logout)
|
|
const unreadMessages = useChatUnreadCount(Boolean(user)).data ?? 0
|
|
|
|
return (
|
|
<Layout className="site-shell">
|
|
<Header className="site-header">
|
|
<div className="site-header__inner">
|
|
<Link to="/" className="site-brand" aria-label="解忧商行首页">
|
|
<BrandLogo height={42} />
|
|
</Link>
|
|
|
|
<nav className="site-nav" aria-label="主导航">
|
|
<Link to="/">首页</Link>
|
|
<a href="/#listings">商品</a>
|
|
<Link to="/orders">我的订单</Link>
|
|
<Link to="/messages">
|
|
<Badge count={unreadMessages} size="small" offset={[8, -2]}>
|
|
<span>消息</span>
|
|
</Badge>
|
|
</Link>
|
|
<Link to="/seller/listings">卖家中心</Link>
|
|
<Link to="/crash">摸红商城</Link>
|
|
<Link to="/announcements">公告</Link>
|
|
<a href="/#process">流程</a>
|
|
<a href="/#rules">规则</a>
|
|
</nav>
|
|
|
|
<Space size={12}>
|
|
{user ? (
|
|
<Dropdown
|
|
menu={{
|
|
items: [
|
|
{ key: 'phone', label: `已登录:${user.phone}`, disabled: true },
|
|
{
|
|
key: 'profile',
|
|
label: '个人中心',
|
|
onClick: () => navigate('/profile'),
|
|
},
|
|
{
|
|
key: 'realname',
|
|
label: '实名认证',
|
|
onClick: () => navigate('/realname'),
|
|
},
|
|
{
|
|
key: 'collections',
|
|
label: '我的足迹',
|
|
onClick: () => navigate('/listings/collections'),
|
|
},
|
|
{
|
|
key: 'orders',
|
|
label: '我的订单',
|
|
onClick: () => navigate('/orders'),
|
|
},
|
|
{
|
|
key: 'messages',
|
|
label: '我的消息',
|
|
onClick: () => navigate('/messages'),
|
|
},
|
|
{
|
|
key: 'notifications',
|
|
label: '我的通知',
|
|
onClick: () => navigate('/notifications'),
|
|
},
|
|
{
|
|
key: 'invitations',
|
|
label: '邀请好友',
|
|
onClick: () => navigate('/invitations'),
|
|
},
|
|
{
|
|
key: 'announcements',
|
|
label: '公告中心',
|
|
onClick: () => navigate('/announcements'),
|
|
},
|
|
{
|
|
key: 'wallet',
|
|
label: '我的钱包',
|
|
onClick: () => navigate('/wallet'),
|
|
},
|
|
{
|
|
key: 'seller-earnings',
|
|
label: '卖家收益',
|
|
onClick: () => navigate('/seller/earnings'),
|
|
},
|
|
{
|
|
key: 'seller-handoffs',
|
|
label: '号主待办',
|
|
onClick: () => navigate('/seller/handoffs'),
|
|
},
|
|
{
|
|
key: 'seller-pickups',
|
|
label: '线下提号',
|
|
onClick: () => navigate('/seller/pickups'),
|
|
},
|
|
{
|
|
key: 'seller',
|
|
label: '卖家中心',
|
|
onClick: () => navigate('/seller/listings'),
|
|
},
|
|
{
|
|
key: 'logout',
|
|
label: '退出登录',
|
|
onClick: async () => {
|
|
await logout()
|
|
navigate('/')
|
|
},
|
|
},
|
|
],
|
|
}}
|
|
>
|
|
<Button icon={<UserOutlined />}>{user.nickname || '我的商行'}</Button>
|
|
</Dropdown>
|
|
) : (
|
|
<Button type="primary" onClick={() => navigate('/login')}>
|
|
登录 / 注册
|
|
</Button>
|
|
)}
|
|
</Space>
|
|
</div>
|
|
</Header>
|
|
|
|
<Content className="site-content">
|
|
<Outlet />
|
|
</Content>
|
|
|
|
<Footer className="site-footer">
|
|
<div className="site-footer__inner">
|
|
<div>
|
|
<Typography.Text strong>解忧商行</Typography.Text>
|
|
<Typography.Text type="secondary"> · JIEYOU TRADING HOUSE</Typography.Text>
|
|
<div className="site-footer__muted">租得明白,还得安心。</div>
|
|
</div>
|
|
<div className="site-footer__muted">
|
|
© 2026 解忧商行 · 备案信息与客服信息待配置
|
|
</div>
|
|
</div>
|
|
</Footer>
|
|
</Layout>
|
|
)
|
|
}
|