KnowledgeBase_frontend/src/layouts/HeaderWithNav.jsx

160 lines
7.8 KiB
JavaScript
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 } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Link, useNavigate, useLocation } from 'react-router-dom';
import { logoutThunk } from '../store/auth/auth.thunk';
import UserSettingsModal from '../components/UserSettingsModal';
import NotificationCenter from '../components/NotificationCenter';
import SvgIcon from '../components/SvgIcon';
export default function HeaderWithNav() {
const dispatch = useDispatch();
const navigate = useNavigate();
const location = useLocation();
const { user } = useSelector((state) => state.auth);
const [showSettings, setShowSettings] = useState(false);
const [showNotifications, setShowNotifications] = useState(false);
const { notifications } = useSelector((state) => state.notificationCenter);
const handleLogout = async () => {
try {
await dispatch(logoutThunk()).unwrap();
sessionStorage.removeItem('token');
navigate('/login');
} catch (error) {}
};
// Check if the current path starts with the given path
const isActive = (path) => {
return location.pathname.startsWith(path);
};
console.log('user', user);
// 检查用户是否有管理权限leader 或 admin
const hasManagePermission = user && (user.role === 'leader' || user.role === 'admin');
return (
<header>
<nav className='navbar navbar-expand-lg bg-white shadow-sm'>
<div className='container-fluid'>
<Link className='navbar-brand' to='/'>
OOIN 智能知识库
</Link>
<button
className='navbar-toggler'
type='button'
data-bs-toggle='collapse'
data-bs-target='#navbarText'
aria-controls='navbarText'
aria-expanded='false'
aria-label='Toggle navigation'
>
<span className='navbar-toggler-icon'></span>
</button>
<div className='collapse navbar-collapse' id='navbarText'>
<ul className='navbar-nav me-auto mb-lg-0'>
<li className='nav-item'>
<Link
className={`nav-link ${
isActive('/') && !isActive('/chat') && !isActive('/permissions') ? 'active' : ''
}`}
aria-current='page'
to='/'
>
知识库
</Link>
</li>
<li className='nav-item'>
<Link className={`nav-link ${isActive('/chat') ? 'active' : ''}`} to='/chat'>
Chat
</Link>
</li>
{hasManagePermission && (
<li className='nav-item'>
<Link
className={`nav-link ${isActive('/permissions') ? 'active' : ''}`}
to='/permissions'
>
权限管理
</Link>
</li>
)}
</ul>
{!!user ? (
<div className='d-flex align-items-center gap-3'>
<div className='position-relative'>
<button
className='btn btn-link text-dark p-0'
onClick={() => setShowNotifications(!showNotifications)}
>
<SvgIcon className={'bell'} />
{notifications.length > 0 && (
<span className='position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger'>
{notifications.length}
</span>
)}
</button>
</div>
<div className='flex-shrink-0 dropdown'>
<a
href='#'
className='d-block link-dark text-decoration-none dropdown-toggle'
data-bs-toggle='dropdown'
aria-expanded='false'
>
Hi, {user.username}
</a>
<ul
className='dropdown-menu text-small shadow'
style={{
position: 'absolute',
inset: '0px 0px auto auto',
margin: '0px',
transform: 'translate(0px, 34px)',
}}
>
<li>
<Link
className='dropdown-item'
to='#'
onClick={() => setShowSettings(true)}
>
个人设置
</Link>
</li>
<li>
<hr className='dropdown-divider' />
</li>
<li>
<Link className='dropdown-item' to='#' onClick={handleLogout}>
退出登录
</Link>
</li>
</ul>
</div>
</div>
) : (
<>
<hr className='d-lg-none' />
<ul className='navbar-nav mb-2 mb-lg-0'>
<li className='nav-item'>
<Link className='nav-link text-dark' to='/login'>
Log in
</Link>
</li>
<li className='nav-item'>
<Link className='nav-link text-dark' to='/signup'>
Sign up
</Link>
</li>
</ul>
</>
)}
</div>
</div>
</nav>
<UserSettingsModal show={showSettings} onClose={() => setShowSettings(false)} />
<NotificationCenter show={showNotifications} onClose={() => setShowNotifications(false)} />
</header>
);
}