Files
sfera/src/components/dashboard/sidebar.tsx
Veronika Smirnova 6b425d075f Унификация UI раздела Партнеры и создание системы документирования
🎨 Унификация UI:
- Полная унификация визуала вкладок Рефералы и Мои контрагенты
- Исправлены React Hooks ошибки в sidebar.tsx
- Убрана лишняя обертка glass-card в partners-dashboard.tsx
- Исправлена цветовая схема (purple → yellow)
- Табличный формат вместо карточного grid-layout
- Компактные блоки статистики (4 метрики в ряд)
- Правильная прозрачность glass-morphism эффектов

📚 Документация:
- Переименован referral-system-rules.md → partners-rules.md
- Детальные UI/UX правила в partners-rules.md
- Правила унификации в visual-design-rules.md
- Обновлен current-session.md
- Создан development-diary.md

🚀 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-11 15:38:23 +03:00

693 lines
30 KiB
TypeScript
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.

'use client'
import { useQuery } from '@apollo/client'
import {
BarChart3,
ChevronLeft,
ChevronRight,
DollarSign,
Handshake,
Home,
LogOut,
MessageCircle,
Settings,
Store,
Truck,
Users,
Warehouse,
Wrench,
} from 'lucide-react'
import { usePathname, useRouter } from 'next/navigation'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Button } from '@/components/ui/button'
import { GET_CONVERSATIONS, GET_INCOMING_REQUESTS, GET_PENDING_SUPPLIES_COUNT } from '@/graphql/queries'
import { useAuth } from '@/hooks/useAuth'
import { useSidebar } from '@/hooks/useSidebar'
// Компонент для отображения логистических заявок (только для логистики)
function LogisticsOrdersNotification() {
const { data: pendingData } = useQuery(GET_PENDING_SUPPLIES_COUNT, {
pollInterval: 30000, // Обновляем каждые 30 секунд
fetchPolicy: 'cache-first',
errorPolicy: 'ignore',
})
const logisticsCount = pendingData?.pendingSuppliesCount?.logisticsOrders || 0
if (logisticsCount === 0) return null
return (
<div className="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full min-w-[18px] h-[18px] flex items-center justify-center font-bold animate-pulse">
{logisticsCount > 99 ? '99+' : logisticsCount}
</div>
)
}
// Компонент для отображения поставок фулфилмента (только поставки, не заявки на партнерство)
function FulfillmentSuppliesNotification() {
const { data: pendingData } = useQuery(GET_PENDING_SUPPLIES_COUNT, {
pollInterval: 30000, // Обновляем каждые 30 секунд
fetchPolicy: 'cache-first',
errorPolicy: 'ignore',
})
const suppliesCount = pendingData?.pendingSuppliesCount?.supplyOrders || 0
if (suppliesCount === 0) return null
return (
<div className="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full min-w-[18px] h-[18px] flex items-center justify-center font-bold animate-pulse">
{suppliesCount > 99 ? '99+' : suppliesCount}
</div>
)
}
// Компонент для отображения входящих заказов поставщика (только входящие заказы, не заявки на партнерство)
function WholesaleOrdersNotification() {
const { data: pendingData } = useQuery(GET_PENDING_SUPPLIES_COUNT, {
pollInterval: 30000, // Обновляем каждые 30 секунд
fetchPolicy: 'cache-first',
errorPolicy: 'ignore',
})
const ordersCount = pendingData?.pendingSuppliesCount?.incomingSupplierOrders || 0
if (ordersCount === 0) return null
return (
<div className="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full min-w-[18px] h-[18px] flex items-center justify-center font-bold animate-pulse">
{ordersCount > 99 ? '99+' : ordersCount}
</div>
)
}
declare global {
interface Window {
__SIDEBAR_ROOT_MOUNTED__?: boolean
}
}
export function Sidebar({ isRootInstance = false }: { isRootInstance?: boolean } = {}) {
const { user, logout } = useAuth()
const router = useRouter()
const pathname = usePathname()
const { isCollapsed, toggleSidebar } = useSidebar()
// Загружаем список чатов для подсчета непрочитанных сообщений
const { data: conversationsData } = useQuery(GET_CONVERSATIONS, {
pollInterval: 60000, // Обновляем каждую минуту в сайдбаре - этого достаточно
fetchPolicy: 'cache-first',
errorPolicy: 'ignore', // Игнорируем ошибки чтобы не ломать сайдбар
notifyOnNetworkStatusChange: false, // Плавные обновления без мерцания
})
// Загружаем входящие заявки для подсчета новых запросов
const { data: incomingRequestsData } = useQuery(GET_INCOMING_REQUESTS, {
pollInterval: 60000, // Обновляем каждую минуту
fetchPolicy: 'cache-first',
errorPolicy: 'ignore',
notifyOnNetworkStatusChange: false,
})
// Если уже есть корневой сайдбар и это не корневой экземпляр — не рендерим дубликат
if (typeof window !== 'undefined' && !isRootInstance && (window as any).__SIDEBAR_ROOT_MOUNTED__) {
return null
}
const conversations = conversationsData?.conversations || []
const incomingRequests = incomingRequestsData?.incomingRequests || []
const totalUnreadCount = conversations.reduce(
(sum: number, conv: { unreadCount?: number }) => sum + (conv.unreadCount || 0),
0,
)
const incomingRequestsCount = incomingRequests.length
const getInitials = () => {
const orgName = getOrganizationName()
return orgName.charAt(0).toUpperCase()
}
const getOrganizationName = () => {
if (user?.organization?.name) {
return user.organization.name
}
if (user?.organization?.fullName) {
return user.organization.fullName
}
return 'Организация'
}
const getCabinetType = () => {
if (!user?.organization?.type) return 'Кабинет'
switch (user.organization.type) {
case 'FULFILLMENT':
return 'Фулфилмент'
case 'SELLER':
return 'Селлер'
case 'LOGIST':
return 'Логистика'
case 'WHOLESALE':
return 'Поставщик'
default:
return 'Кабинет'
}
}
const handleSettingsClick = () => {
router.push('/settings')
}
const handleMarketClick = () => {
router.push('/market')
}
const handleMessengerClick = () => {
router.push('/messenger')
}
const handleServicesClick = () => {
router.push('/services')
}
const handleWarehouseClick = () => {
router.push('/warehouse')
}
const handleWBWarehouseClick = () => {
router.push('/wb-warehouse')
}
const handleEmployeesClick = () => {
router.push('/employees')
}
const handleSuppliesClick = () => {
// Для каждого типа кабинета свой роут
switch (user?.organization?.type) {
case 'FULFILLMENT':
router.push('/fulfillment-supplies')
break
case 'SELLER':
router.push('/supplies')
break
case 'WHOLESALE':
router.push('/supplier-orders')
break
case 'LOGIST':
router.push('/logistics-orders')
break
default:
router.push('/supplies')
}
}
const handleFulfillmentWarehouseClick = () => {
router.push('/fulfillment-warehouse')
}
const handleFulfillmentStatisticsClick = () => {
router.push('/fulfillment-statistics')
}
const handleSellerStatisticsClick = () => {
router.push('/seller-statistics')
}
const handlePartnersClick = () => {
router.push('/partners')
}
const handleHomeClick = () => {
router.push('/home')
}
const handleEconomicsClick = () => {
router.push('/economics')
}
const isHomeActive = pathname === '/home'
const isEconomicsActive = pathname === '/economics'
const isSettingsActive = pathname === '/settings'
const isMarketActive = pathname.startsWith('/market')
const isMessengerActive = pathname.startsWith('/messenger')
const isServicesActive = pathname.startsWith('/services')
const isWarehouseActive = pathname.startsWith('/warehouse')
const isWBWarehouseActive = pathname.startsWith('/wb-warehouse')
const isFulfillmentWarehouseActive = pathname.startsWith('/fulfillment-warehouse')
const isFulfillmentStatisticsActive = pathname.startsWith('/fulfillment-statistics')
const isSellerStatisticsActive = pathname.startsWith('/seller-statistics')
const isEmployeesActive = pathname.startsWith('/employees')
const isSuppliesActive =
pathname.startsWith('/supplies') ||
pathname.startsWith('/fulfillment-supplies') ||
pathname.startsWith('/logistics') ||
pathname.startsWith('/supplier-orders')
const isPartnersActive = pathname.startsWith('/partners')
// Помечаем, что корневой экземпляр смонтирован
if (typeof window !== 'undefined' && isRootInstance) {
;(window as any).__SIDEBAR_ROOT_MOUNTED__ = true
}
return (
<div className="relative">
{/* Основной сайдбар */}
<div
className={`fixed left-4 top-4 bottom-4 ${
isCollapsed ? 'w-16' : 'w-56'
} bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl ${
isCollapsed ? 'p-2' : 'p-3'
} transition-all duration-300 ease-in-out z-50`}
>
{/* ОХУЕННАЯ кнопка сворачивания - на правом краю сайдбара */}
<div className="absolute -right-6 top-1/2 -translate-y-1/2 z-[999]">
<div className="relative group">
{/* Основная кнопка с безопасными эффектами */}
<Button
variant="ghost"
size="icon"
onClick={toggleSidebar}
className="relative h-12 w-12 rounded-full bg-gradient-to-br from-white/20 to-white/5 border border-white/30 hover:from-white/30 hover:to-white/10 transition-all duration-300 ease-out hover:scale-110 active:scale-95 backdrop-blur-xl shadow-lg hover:shadow-xl hover:shadow-purple-500/20 group-hover:border-purple-300/50"
>
{/* Простая анимированная иконка */}
<div className="transition-transform duration-300 ease-out group-hover:scale-110">
{isCollapsed ? (
<ChevronRight className="h-6 w-6 text-white/80 group-hover:text-white transition-colors duration-300" />
) : (
<ChevronLeft className="h-6 w-6 text-white/80 group-hover:text-white transition-colors duration-300" />
)}
</div>
{/* Простое свечение при наведении */}
<div className="absolute inset-0 rounded-full bg-gradient-to-r from-purple-500/0 to-blue-500/0 group-hover:from-purple-500/10 group-hover:to-blue-500/10 transition-all duration-500"></div>
</Button>
{/* Убраны текстовые подсказки при наведении */}
</div>
</div>
<div className="flex flex-col h-full">
{/* Информация о пользователе */}
<div className="bg-white/5 backdrop-blur border border-white/30 rounded-xl mb-3 p-2.5 shadow-sm">
{!isCollapsed ? (
// Развернутое состояние - без карточки
<div className="flex items-center space-x-2.5">
<div className="relative flex-shrink-0">
<Avatar className="h-8 w-8 ring-2 ring-white/40">
{user?.avatar ? (
<AvatarImage src={user.avatar} alt="Аватар пользователя" className="w-full h-full object-cover" />
) : null}
<AvatarFallback className="bg-gradient-to-br from-purple-500 to-purple-600 text-white text-xs font-semibold">
{getInitials()}
</AvatarFallback>
</Avatar>
<div className="absolute -bottom-0.5 -right-0.5 w-2 h-2 bg-green-400 rounded-full border-2 border-white/40"></div>
</div>
<div className="flex-1 min-w-0">
<p className="text-white text-xs font-medium mb-0.5 break-words" title={getOrganizationName()}>
{getOrganizationName()}
</p>
<div className="flex items-center space-x-1">
<div className="w-1 h-1 bg-purple-400 rounded-full flex-shrink-0"></div>
<p className="text-white/50 text-[10px]">{getCabinetType()}</p>
</div>
</div>
</div>
) : (
// Свернутое состояние - только аватар
<div className="flex justify-center">
<div className="relative" title={`${getOrganizationName()} - ${getCabinetType()}`}>
<Avatar className="h-7 w-7 ring-2 ring-white/40">
{user?.avatar ? (
<AvatarImage src={user.avatar} alt="Аватар пользователя" className="w-full h-full object-cover" />
) : null}
<AvatarFallback className="bg-gradient-to-br from-purple-500 to-purple-600 text-white text-[10px] font-semibold">
{getInitials()}
</AvatarFallback>
</Avatar>
<div className="absolute -bottom-0.5 -right-0.5 w-1.5 h-1.5 bg-green-400 rounded-full border-2 border-white/40"></div>
</div>
</div>
)}
</div>
{/* Навигация */}
<div className="space-y-1 mb-3 flex-1">
{/* Кнопка Главная - первая для всех типов кабинетов */}
<Button
variant={isHomeActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isHomeActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleHomeClick}
title={isCollapsed ? 'Главная' : ''}
>
<Home className={`${isCollapsed ? 'h-4 w-4' : 'h-4 w-4'} flex-shrink-0`} />
{!isCollapsed && <span className="ml-3">Главная</span>}
</Button>
<Button
variant={isMarketActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isMarketActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleMarketClick}
title={isCollapsed ? 'Маркет' : ''}
>
<Store className={`${isCollapsed ? 'h-4 w-4' : 'h-4 w-4'} flex-shrink-0`} />
{!isCollapsed && <span className="ml-3">Маркет</span>}
</Button>
<Button
variant={isMessengerActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs relative ${
isMessengerActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleMessengerClick}
title={isCollapsed ? 'Мессенджер' : ''}
>
<MessageCircle className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Мессенджер</span>}
{/* Индикатор непрочитанных сообщений */}
{totalUnreadCount > 0 && (
<div
className={`absolute ${
isCollapsed ? 'top-1 right-1 w-3 h-3' : 'top-2 right-2 w-4 h-4'
} bg-red-500 text-white text-xs rounded-full flex items-center justify-center font-bold`}
>
{isCollapsed ? '' : totalUnreadCount > 99 ? '99+' : totalUnreadCount}
</div>
)}
</Button>
<Button
variant={isPartnersActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs relative ${
isPartnersActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handlePartnersClick}
title={isCollapsed ? 'Партнёры' : ''}
>
<Handshake className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Партнёры</span>}
{/* Индикатор входящих заявок */}
{incomingRequestsCount > 0 && (
<div
className={`absolute ${
isCollapsed ? 'top-1 right-1 w-3 h-3' : 'top-2 right-2 w-4 h-4'
} bg-red-500 text-white text-xs rounded-full flex items-center justify-center font-bold`}
>
{isCollapsed ? '' : incomingRequestsCount > 99 ? '99+' : incomingRequestsCount}
</div>
)}
</Button>
{/* Услуги - только для фулфилмент центров */}
{user?.organization?.type === 'FULFILLMENT' && (
<Button
variant={isServicesActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isServicesActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleServicesClick}
title={isCollapsed ? 'Услуги' : ''}
>
<Wrench className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Услуги</span>}
</Button>
)}
{/* Сотрудники - только для фулфилмент центров */}
{user?.organization?.type === 'FULFILLMENT' && (
<Button
variant={isEmployeesActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isEmployeesActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleEmployeesClick}
title={isCollapsed ? 'Сотрудники' : ''}
>
<Users className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Сотрудники</span>}
</Button>
)}
{/* Мои поставки - для селлеров */}
{user?.organization?.type === 'SELLER' && (
<Button
variant={isSuppliesActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isSuppliesActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer relative`}
onClick={handleSuppliesClick}
title={isCollapsed ? 'Мои поставки' : ''}
>
<Truck className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Мои поставки</span>}
{/* Селлеры не получают уведомления о поставках - только отслеживают статус */}
</Button>
)}
{/* Склад - для селлеров */}
{user?.organization?.type === 'SELLER' && (
<Button
variant={isWBWarehouseActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isWBWarehouseActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleWBWarehouseClick}
title={isCollapsed ? 'Склад' : ''}
>
<Warehouse className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Склад</span>}
</Button>
)}
{/* Статистика - для селлеров */}
{user?.organization?.type === 'SELLER' && (
<Button
variant={isSellerStatisticsActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isSellerStatisticsActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleSellerStatisticsClick}
title={isCollapsed ? 'Статистика' : ''}
>
<BarChart3 className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Статистика</span>}
</Button>
)}
{/* Входящие поставки - для фулфилмент */}
{user?.organization?.type === 'FULFILLMENT' && (
<Button
variant={isSuppliesActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isSuppliesActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer relative`}
onClick={handleSuppliesClick}
title={isCollapsed ? 'Входящие поставки' : ''}
>
<Truck className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Входящие поставки</span>}
{/* Уведомление только о поставках, не о заявках на партнерство */}
<FulfillmentSuppliesNotification />
</Button>
)}
{/* Склад - для фулфилмент */}
{user?.organization?.type === 'FULFILLMENT' && (
<Button
variant={isFulfillmentWarehouseActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isFulfillmentWarehouseActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleFulfillmentWarehouseClick}
title={isCollapsed ? 'Склад' : ''}
>
<Warehouse className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Склад</span>}
</Button>
)}
{/* Статистика - для фулфилмент */}
{user?.organization?.type === 'FULFILLMENT' && (
<Button
variant={isFulfillmentStatisticsActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isFulfillmentStatisticsActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleFulfillmentStatisticsClick}
title={isCollapsed ? 'Статистика' : ''}
>
<BarChart3 className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Статистика</span>}
</Button>
)}
{/* Заявки - для поставщиков */}
{user?.organization?.type === 'WHOLESALE' && (
<Button
variant={isSuppliesActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isSuppliesActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer relative`}
onClick={handleSuppliesClick}
title={isCollapsed ? 'Заявки' : ''}
>
<Truck className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Заявки</span>}
{/* Уведомление только о входящих заказах поставок, не о заявках на партнерство */}
<WholesaleOrdersNotification />
</Button>
)}
{/* Перевозки - для логистов */}
{user?.organization?.type === 'LOGIST' && (
<Button
variant={isSuppliesActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isSuppliesActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer relative`}
onClick={handleSuppliesClick}
title={isCollapsed ? 'Перевозки' : ''}
>
<Truck className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Перевозки</span>}
{/* Уведомление только о логистических заявках */}
<LogisticsOrdersNotification />
</Button>
)}
{/* Склад - только для поставщиков */}
{user?.organization?.type === 'WHOLESALE' && (
<Button
variant={isWarehouseActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isWarehouseActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleWarehouseClick}
title={isCollapsed ? 'Склад' : ''}
>
<Warehouse className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Склад</span>}
</Button>
)}
{/* Кнопка Экономика - для всех типов кабинетов, перед настройками */}
<Button
variant={isEconomicsActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isEconomicsActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleEconomicsClick}
title={isCollapsed ? 'Экономика' : ''}
>
<DollarSign className={`${isCollapsed ? 'h-4 w-4' : 'h-4 w-4'} flex-shrink-0`} />
{!isCollapsed && <span className="ml-3">Экономика</span>}
</Button>
<Button
variant={isSettingsActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isSettingsActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleSettingsClick}
title={isCollapsed ? 'Настройки профиля' : ''}
>
<Settings className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Настройки профиля</span>}
</Button>
</div>
{/* Кнопка выхода */}
<div>
<Button
variant="ghost"
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-white/80 hover:bg-red-500/20 hover:text-red-300 cursor-pointer text-xs transition-all duration-200`}
onClick={logout}
title={isCollapsed ? 'Выйти' : ''}
>
<LogOut className="h-4 w-4 flex-shrink-0" />
{!isCollapsed && <span className="ml-3">Выйти</span>}
</Button>
</div>
</div>
</div>
</div>
)
}