This commit is contained in:
108
src/components/Sidebar.jsx
Normal file
108
src/components/Sidebar.jsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { LayoutDashboard, Settings, Shield, Video, X, Palette } from 'lucide-react';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
import ThemeSelector from './ThemeSelector';
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function Sidebar({ open, onClose }) {
|
||||
const { user } = useAuth();
|
||||
const { t } = useLanguage();
|
||||
const [themeOpen, setThemeOpen] = useState(false);
|
||||
|
||||
const navItems = [
|
||||
{ to: '/dashboard', icon: LayoutDashboard, label: t('nav.dashboard') },
|
||||
{ to: '/settings', icon: Settings, label: t('nav.settings') },
|
||||
];
|
||||
|
||||
if (user?.role === 'admin') {
|
||||
navItems.push({ to: '/admin', icon: Shield, label: t('nav.admin') });
|
||||
}
|
||||
|
||||
const linkClasses = ({ isActive }) =>
|
||||
`flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-all duration-200 ${
|
||||
isActive
|
||||
? 'bg-th-accent text-th-accent-t shadow-sm'
|
||||
: 'text-th-text-s hover:text-th-text hover:bg-th-hover'
|
||||
}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<aside
|
||||
className={`fixed top-0 left-0 z-40 h-full w-64 bg-th-side border-r border-th-border
|
||||
transition-transform duration-300 ease-in-out
|
||||
${open ? 'translate-x-0' : '-translate-x-full'} lg:translate-x-0`}
|
||||
>
|
||||
<div className="flex flex-col h-full">
|
||||
{/* Logo */}
|
||||
<div className="flex items-center justify-between h-16 px-4 border-b border-th-border">
|
||||
<div className="flex items-center gap-2.5">
|
||||
<div className="w-8 h-8 gradient-bg rounded-lg flex items-center justify-center">
|
||||
<Video size={18} className="text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-lg font-bold gradient-text">Redlight</h1>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="lg:hidden p-1.5 rounded-lg hover:bg-th-hover text-th-text-s transition-colors"
|
||||
>
|
||||
<X size={18} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Navigation */}
|
||||
<nav className="flex-1 px-3 py-4 space-y-1 overflow-y-auto">
|
||||
<p className="px-3 mb-2 text-xs font-semibold text-th-text-s uppercase tracking-wider">
|
||||
{t('nav.navigation')}
|
||||
</p>
|
||||
{navItems.map(item => (
|
||||
<NavLink
|
||||
key={item.to}
|
||||
to={item.to}
|
||||
className={linkClasses}
|
||||
onClick={onClose}
|
||||
>
|
||||
<item.icon size={18} />
|
||||
{item.label}
|
||||
</NavLink>
|
||||
))}
|
||||
|
||||
<div className="pt-4">
|
||||
<p className="px-3 mb-2 text-xs font-semibold text-th-text-s uppercase tracking-wider">
|
||||
{t('nav.appearance')}
|
||||
</p>
|
||||
<button
|
||||
onClick={() => setThemeOpen(!themeOpen)}
|
||||
className="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-th-text-s hover:text-th-text hover:bg-th-hover transition-all duration-200"
|
||||
>
|
||||
<Palette size={18} />
|
||||
{t('nav.changeTheme')}
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* User info */}
|
||||
<div className="p-4 border-t border-th-border">
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className="w-9 h-9 rounded-full flex items-center justify-center text-white text-sm font-bold flex-shrink-0"
|
||||
style={{ backgroundColor: user?.avatar_color || '#6366f1' }}
|
||||
>
|
||||
{user?.name?.[0]?.toUpperCase() || '?'}
|
||||
</div>
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-medium text-th-text truncate">{user?.name}</p>
|
||||
<p className="text-xs text-th-text-s truncate">{user?.email}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{/* Theme Selector Modal */}
|
||||
{themeOpen && <ThemeSelector onClose={() => setThemeOpen(false)} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user