/
kreyndelHam
/
Konstructorium
Обзор
Документация
Войти
/
kreyndelHam
/
Konstructorium
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
1
CI/CD
Аналитика
Безопасность
dev
frontend/src/components/admin/AdminSidebar.jsx
122 строки
4 KB
MihahamYT
New models added
25 май 2026, 17:43
25 май 2026, 17:43
1d72a4d
Код
Авторство
О чём код?
import { Link, useLocation } from 'react-router-dom' import { useEffect, useState } from 'react' import { adminService } from '../../services/api' import { useTranslation } from '../../hooks/useTranslation' /** * Sidebar navigation groups for the admin panel. * * @param {Function} t * @returns {Array} */ function buildNavSections(t) { return [ { items: [{ to: '/admin/dashboard', label: t('adminNav.dashboard') }], }, { title: t('adminNav.sectionCatalog'), items: [ { to: '/admin/products', label: t('adminNav.products') }, { to: '/admin/listing-types', label: t('adminNav.listingTypes') }, { to: '/admin/reviews', label: t('adminNav.reviews') }, ], }, { items: [ { to: '/admin/orders', label: t('adminNav.orders') }, { to: '/admin/users', label: t('adminNav.users') }, ], }, { title: t('adminNav.sectionSupport'), items: [ { to: '/admin/chat', label: t('adminNav.chat') }, { to: '/admin/notifications', label: t('adminNav.notifications'), showBadge: true }, ], }, { items: [{ to: '/admin/analytics', label: t('adminNav.analytics') }], }, ] } /** * Left sidebar for admin navigation. * * @param {object} props * @param {boolean} props.isOpen * @param {Function} props.onClose * @returns {JSX.Element} */ function AdminSidebar({ isOpen, onClose }) { const { t } = useTranslation() const location = useLocation() const [unreadCount, setUnreadCount] = useState(0) const sections = buildNavSections(t) useEffect(() => { const loadCount = async () => { try { const response = await adminService.getUnreadNotificationCount() setUnreadCount(response.data.count || 0) } catch { setUnreadCount(0) } } loadCount() const interval = setInterval(loadCount, 30000) return () => clearInterval(interval) }, []) const isActive = (path) => location.pathname === path || location.pathname.startsWith(`${path}/`) return ( <aside className={`fixed inset-y-0 left-0 z-40 w-64 bg-indigo-900 text-white transform transition-transform duration-200 ease-in-out md:translate-x-0 ${ isOpen ? 'translate-x-0' : '-translate-x-full' }`} > <div className="flex flex-col h-full"> <div className="px-4 py-5 border-b border-indigo-800"> <Link to="/admin/dashboard" className="text-lg font-bold" onClick={onClose}> {t('adminNav.panel')} </Link> </div> <nav className="flex-1 overflow-y-auto px-3 py-4 space-y-5"> {sections.map((section) => ( <div key={section.title || section.items[0]?.to}> {section.title && ( <p className="px-3 mb-2 text-xs font-semibold uppercase tracking-wide text-indigo-300"> {section.title} </p> )} <ul className="space-y-1"> {section.items.map((item) => ( <li key={item.to}> <Link to={item.to} onClick={onClose} className={`flex items-center justify-between px-3 py-2 rounded-md text-sm font-medium transition ${ isActive(item.to) ? 'bg-indigo-800 text-white' : 'text-indigo-100 hover:bg-indigo-800/70' }`} > <span>{item.label}</span> {item.showBadge && unreadCount > 0 && ( <span className="bg-red-500 text-white text-xs font-bold rounded-full min-w-[1.25rem] h-5 px-1 flex items-center justify-center"> {unreadCount > 9 ? '9+' : unreadCount} </span> )} </Link> </li> ))} </ul> </div> ))} </nav> </div> </aside> ) } export default AdminSidebar