90 lines
3.1 KiB
JavaScript
90 lines
3.1 KiB
JavaScript
import { NavLink } from 'react-router-dom'
|
|
import { NAV_GROUPS, ROUTES } from './routes'
|
|
import { useAuth } from '../auth/AuthContext'
|
|
import { HIRING_MANAGER_NAV, isHiringManager } from '../auth/permissions'
|
|
import Icon from '../ui/icons'
|
|
import { BrandGlyph } from '../components/BrandMark'
|
|
|
|
export default function Sidebar({ collapsed, mobileOpen, onToggleCollapse, badges }) {
|
|
const { can, user } = useAuth()
|
|
|
|
// A group heading renders only if something under it survived the permission
|
|
// filter — otherwise a low-privilege user sees orphaned section labels.
|
|
const visible = ROUTES.filter((r) => {
|
|
if (r.hidden) return false
|
|
if (!can(r.permission)) return false
|
|
if (isHiringManager(user) && !HIRING_MANAGER_NAV.has(r.path)) return false
|
|
return true
|
|
})
|
|
|
|
return (
|
|
<aside
|
|
className={`sidebar${collapsed ? ' collapsed' : ''}${mobileOpen ? ' mobile-open' : ''}`}
|
|
id="sidebar"
|
|
>
|
|
<div className="sidebar-brand">
|
|
<div className="brand-logo">
|
|
<BrandGlyph />
|
|
</div>
|
|
<div className="brand-text">
|
|
<span className="brand-name">TalentFlow</span>
|
|
<span className="brand-sub">Utopia Brands · ATS</span>
|
|
</div>
|
|
<button
|
|
className="sidebar-collapse-btn"
|
|
onClick={onToggleCollapse}
|
|
title={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
|
|
aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
|
|
>
|
|
<Icon name="chevron-left" />
|
|
</button>
|
|
</div>
|
|
|
|
<nav className="sidebar-nav" aria-label="Primary">
|
|
{NAV_GROUPS.map((group) => {
|
|
const items = visible.filter((r) => r.group === group)
|
|
if (!items.length) return null
|
|
return (
|
|
<div key={group}>
|
|
<div className="nav-section-label">{group}</div>
|
|
{items.map((r) => {
|
|
const count = r.badge ? badges?.[r.badge] : null
|
|
return (
|
|
<NavLink
|
|
key={r.path}
|
|
to={`/${r.path}`}
|
|
className={({ isActive }) => `nav-item${isActive ? ' active' : ''}`}
|
|
>
|
|
<Icon name={r.icon} />
|
|
<span>{r.title}</span>
|
|
{r.tag && <span className="nav-badge nav-badge-ai">{r.tag}</span>}
|
|
{count ? (
|
|
<span
|
|
className={`nav-badge${r.badge === 'inbox' || r.badge === 'notifications' ? ' nav-badge-alert' : ''}`}
|
|
>
|
|
{count}
|
|
</span>
|
|
) : null}
|
|
</NavLink>
|
|
)
|
|
})}
|
|
</div>
|
|
)
|
|
})}
|
|
</nav>
|
|
|
|
<div className="sidebar-footer">
|
|
<div className="usage-card">
|
|
<div className="usage-top">
|
|
<span>Seats used</span>
|
|
<span>14 / 20</span>
|
|
</div>
|
|
<div className="usage-bar">
|
|
<div className="usage-fill" style={{ width: '70%' }} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
)
|
|
}
|