
- Обновлена форма создания поставок расходников фулфилмента для использования 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>
741 lines
32 KiB
TypeScript
741 lines
32 KiB
TypeScript
'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>
|
||
)
|
||
}
|