Files
sfera-new/src/components/dashboard/sidebar.tsx
Veronika Smirnova 0e3ffc179c feat(fulfillment-supplies): миграция формы создания поставок расходников на v2 систему
- Обновлена форма создания поставок расходников фулфилмента для использования v2 GraphQL API
- Заменена мутация CREATE_SUPPLY_ORDER на CREATE_FULFILLMENT_CONSUMABLE_SUPPLY
- Обновлена структура input данных под новый формат v2
- Сделано поле логистики опциональным
- Добавлено поле notes для комментариев к поставке
- Обновлены refetchQueries на новые v2 запросы
- Исправлены TypeScript ошибки в интерфейсах
- Удалена дублирующая страница consumables-v2
- Сохранен оригинальный богатый UI интерфейс формы (819 строк)
- Подтверждена работа с новой таблицей FulfillmentConsumableSupplyOrder

Технические изменения:
- src/components/fulfillment-supplies/create-fulfillment-consumables-supply-v2.tsx - основная форма
- src/components/fulfillment-supplies/fulfillment-supplies-layout.tsx - обновлена навигация
- Добавлены недостающие поля quantity и ordered в интерфейсы продуктов
- Исправлены импорты и зависимости

Результат: форма полностью интегрирована с v2 системой поставок, которая использует отдельные таблицы для каждого типа поставок согласно новой архитектуре.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-25 07:52:46 +03:00

741 lines
32 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,
TrendingUp,
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 { useRealtime } from '@/hooks/useRealtime'
import { useSidebar } from '@/hooks/useSidebar'
// Компонент для отображения логистических заявок (только для логистики)
function LogisticsOrdersNotification() {
const { data: pendingData, refetch: _refetchPending } = useQuery(GET_PENDING_SUPPLIES_COUNT, {
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, refetch: _refetchPending } = useQuery(GET_PENDING_SUPPLIES_COUNT, {
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, refetch: _refetchPending } = useQuery(GET_PENDING_SUPPLIES_COUNT, {
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, refetch: refetchConversations } = useQuery(GET_CONVERSATIONS, {
fetchPolicy: 'cache-first',
errorPolicy: 'ignore', // Игнорируем ошибки чтобы не ломать сайдбар
notifyOnNetworkStatusChange: false, // Плавные обновления без мерцания
})
// Загружаем входящие заявки для подсчета новых запросов
const { data: incomingRequestsData, refetch: refetchIncoming } = useQuery(GET_INCOMING_REQUESTS, {
fetchPolicy: 'cache-first',
errorPolicy: 'ignore',
notifyOnNetworkStatusChange: false,
})
// Загружаем данные для подсчета поставок
const { refetch: refetchPending } = useQuery(GET_PENDING_SUPPLIES_COUNT, {
fetchPolicy: 'cache-first',
errorPolicy: 'ignore',
notifyOnNetworkStatusChange: false,
})
// Реалтайм обновления бейджей
useRealtime({
onEvent: (evt) => {
switch (evt.type) {
case 'message:new':
refetchConversations()
break
case 'counterparty:request:new':
case 'counterparty:request:updated':
refetchIncoming()
break
case 'supply-order:new':
case 'supply-order:updated':
refetchPending()
break
}
},
})
// Если уже есть корневой сайдбар и это не корневой экземпляр — не рендерим дубликат
if (
typeof window !== 'undefined' &&
!isRootInstance &&
(window as Window & { __SIDEBAR_ROOT_MOUNTED__?: boolean }).__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 handleExchangeClick = () => {
router.push('/exchange')
}
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/goods/new')
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 isExchangeActive = pathname.startsWith('/exchange')
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 Window & { __SIDEBAR_ROOT_MOUNTED__?: boolean }).__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={isExchangeActive ? 'secondary' : 'ghost'}
className={`w-full ${
isCollapsed ? 'justify-center px-2 h-9' : 'justify-start h-10'
} text-left transition-all duration-200 text-xs ${
isExchangeActive
? 'bg-white/20 text-white hover:bg-white/30'
: 'text-white/80 hover:bg-white/10 hover:text-white'
} cursor-pointer`}
onClick={handleExchangeClick}
title={isCollapsed ? 'Биржа' : ''}
>
<TrendingUp 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>
)
}