79 lines
3.3 KiB
TypeScript
79 lines
3.3 KiB
TypeScript
import {
|
|
BarChart3,
|
|
Home,
|
|
MessageSquare,
|
|
Users
|
|
} from 'lucide-react';
|
|
import React from 'react';
|
|
import { NavLink } from 'react-router-dom';
|
|
import { useLocalStorage } from '../../hooks/useLocalStorage';
|
|
import { useAuth } from '../../context/AuthContext';
|
|
|
|
const menuItems = [
|
|
{ id: 'dashboard', label: 'Dashboard', icon: Home, path: '/hr/dashboard' },
|
|
{ id: 'learners', label: 'Learners', icon: Users, path: '/hr/learners' },
|
|
{ id: 'reports', label: 'Reports', icon: BarChart3, path: '/hr/reports' },
|
|
{ id: 'discussions', label: 'Discussion Forums', icon: MessageSquare, path: '/hr/discussions' }
|
|
];
|
|
|
|
interface HRSidebarProps {
|
|
className?: string;
|
|
onNavigate?: () => void;
|
|
}
|
|
|
|
export const HRSidebar: React.FC<HRSidebarProps> = ({ className = '', onNavigate }) => {
|
|
const [prefersReducedMotion] = useLocalStorage('prefersReducedMotion', false);
|
|
const { user } = useAuth();
|
|
const orgName = user?.principal_organization_name?.trim() || 'Tech Solutions Pvt Ltd';
|
|
const orgInitials =
|
|
orgName
|
|
.split(/\s+/)
|
|
.filter(Boolean)
|
|
.map((part) => part[0])
|
|
.join('')
|
|
.slice(0, 2)
|
|
.toUpperCase() || 'TS';
|
|
|
|
return (
|
|
<div className={`w-64 min-w-[248px] cs-height bg-sidebar flex flex-col ${className}`}>
|
|
<div className="p-6">
|
|
<div className="flex items-center gap-2">
|
|
<div className="w-8 h-8 bg-brand-charcoal rounded-md flex items-center justify-center">
|
|
<span className="text-brand-charcoal-foreground font-bold text-sm">{orgInitials}</span>
|
|
</div>
|
|
<span className="font-semibold text-sidebar-foreground">{orgName}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<nav className="flex-1 p-4" role="navigation" aria-label="HR Portal Navigation">
|
|
<ul className="space-y-1">
|
|
{menuItems.map((item) => {
|
|
const Icon = item.icon;
|
|
|
|
return (
|
|
<li key={item.id}>
|
|
<NavLink
|
|
to={item.path}
|
|
onClick={onNavigate}
|
|
className={({ isActive }) => `
|
|
w-full flex items-center gap-3 px-3 py-2 rounded-md text-sm min-tap-44
|
|
transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-sidebar-ring focus:ring-offset-2 focus:ring-offset-sidebar
|
|
${isActive
|
|
? 'bg-sidebar-primary text-sidebar-primary-foreground shadow-sm'
|
|
: 'text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground'
|
|
}
|
|
${prefersReducedMotion ? '' : 'animate-scale-hover'}
|
|
`}
|
|
aria-label={`Navigate to ${item.label}`}
|
|
>
|
|
<Icon className="h-4 w-4" />
|
|
{item.label}
|
|
</NavLink>
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
);
|
|
}; |