TopBar.tsx 2.44 KB
import { useLocation, useNavigate } from 'react-router-dom'
import { useAppDispatch, useAppSelector } from '@/store'
import { closeTab, type TabItem } from '@/store/tabs'
import { loggedOut } from '@/store/auth'
import { IconAntler, IconBell, IconHome, IconMenu, IconSearch, IconUser } from './icons'

interface Props {
  navOpen: boolean
  onToggleNav: () => void
}

export default function TopBar({ navOpen, onToggleNav }: Props) {
  const navigate = useNavigate()
  const location = useLocation()
  const dispatch = useAppDispatch()
  const tabs = useAppSelector(s => s.tabs.items)
  const user = useAppSelector(s => s.auth.user)

  const isHome = location.pathname === '/'

  const handleTabClick = (t: TabItem) => navigate(t.path)
  const handleClose = (e: React.MouseEvent, t: TabItem) => {
    e.stopPropagation()
    const idx = tabs.findIndex(x => x.key === t.key)
    dispatch(closeTab(t.key))
    if (location.pathname === t.path) {
      const next = tabs[idx + 1] || tabs[idx - 1]
      navigate(next ? next.path : '/')
    }
  }

  const handleLogout = () => {
    dispatch(loggedOut())
    navigate('/login', { replace: true })
  }

  return (
    <div className="topbar">
      <div className="logo" title="主页" onClick={() => navigate('/')}>
        <IconAntler />
      </div>
      <div className="tabs">
        <button className={`nav-btn ${navOpen ? 'active' : ''}`} onClick={onToggleNav}>
          <IconMenu />
          全部导航
        </button>
        <div className={`tab ${isHome ? 'active' : ''}`} onClick={() => navigate('/')}>
          <span className="ic"><IconHome /></span>
          主页
        </div>
        {tabs.map(t => (
          <div
            key={t.key}
            className={`tab ${location.pathname === t.path ? 'active' : ''}`}
            onClick={() => handleTabClick(t)}
          >
            {t.title}
            <span className="close" onClick={e => handleClose(e, t)}>✕</span>
          </div>
        ))}
      </div>
      <div className="right">
        <span className="ic" title="搜索"><IconSearch /></span>
        <span className="ic" title="通知"><IconBell /></span>
        <div className="user" onClick={handleLogout} title="点击退出登录">
          <span className="ic"><IconUser /></span>
          {user ? `${user.sUserName}(${user.sUserType})` : '未登录'}
          <span style={{ fontSize: 10 }}>▾</span>
        </div>
        <span className="more">⋯</span>
      </div>
    </div>
  )
}