'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 (
{logisticsCount > 99 ? '99+' : logisticsCount}
) } // Компонент для отображения поставок фулфилмента (только поставки, не заявки на партнерство) 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 (
{suppliesCount > 99 ? '99+' : suppliesCount}
) } // Компонент для отображения входящих заказов поставщика (только входящие заказы, не заявки на партнерство) 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 (
{ordersCount > 99 ? '99+' : ordersCount}
) } 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 (
{/* Основной сайдбар */}
{/* ОХУЕННАЯ кнопка сворачивания - на правом краю сайдбара */}
{/* Основная кнопка с безопасными эффектами */} {/* Убраны текстовые подсказки при наведении */}
{/* Информация о пользователе */}
{!isCollapsed ? ( // Развернутое состояние - без карточки
{user?.avatar ? ( ) : null} {getInitials()}

{getOrganizationName()}

{getCabinetType()}

) : ( // Свернутое состояние - только аватар
{user?.avatar ? ( ) : null} {getInitials()}
)}
{/* Навигация */}
{/* Кнопка Главная - первая для всех типов кабинетов */} {/* Услуги - только для фулфилмент центров */} {user?.organization?.type === 'FULFILLMENT' && ( )} {/* Сотрудники - только для фулфилмент центров */} {user?.organization?.type === 'FULFILLMENT' && ( )} {/* Мои поставки - для селлеров */} {user?.organization?.type === 'SELLER' && ( )} {/* Склад - для селлеров */} {user?.organization?.type === 'SELLER' && ( )} {/* Статистика - для селлеров */} {user?.organization?.type === 'SELLER' && ( )} {/* Входящие поставки - для фулфилмент */} {user?.organization?.type === 'FULFILLMENT' && ( )} {/* Склад - для фулфилмент */} {user?.organization?.type === 'FULFILLMENT' && ( )} {/* Статистика - для фулфилмент */} {user?.organization?.type === 'FULFILLMENT' && ( )} {/* Заявки - для поставщиков */} {user?.organization?.type === 'WHOLESALE' && ( )} {/* Перевозки - для логистов */} {user?.organization?.type === 'LOGIST' && ( )} {/* Склад - только для поставщиков */} {user?.organization?.type === 'WHOLESALE' && ( )} {/* Кнопка Экономика - для всех типов кабинетов, перед настройками */}
{/* Кнопка выхода */}
) }