"use client"
import { useState, useEffect } from 'react'
import { useQuery } from '@apollo/client'
import { GET_MESSAGES } from '@/graphql/queries'
import { useAuth } from '@/hooks/useAuth'
import { Card } from '@/components/ui/card'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Badge } from '@/components/ui/badge'
import { ImageLightbox } from '@/components/ui/image-lightbox'
import { VoicePlayer } from '@/components/ui/voice-player'
import {
FileText,
Image,
Music,
Video,
Download,
Calendar,
User,
RefreshCw
} from 'lucide-react'
interface Organization {
id: string
inn: string
name?: string
fullName?: string
type: 'FULFILLMENT' | 'SELLER' | 'LOGIST' | 'WHOLESALE'
users?: Array<{ id: string, avatar?: string, managerName?: string }>
}
interface Message {
id: string
content?: string
type?: 'TEXT' | 'VOICE' | 'IMAGE' | 'FILE'
voiceUrl?: string
voiceDuration?: number
fileUrl?: string
fileName?: string
fileSize?: number
fileType?: string
senderId: string
senderOrganization: Organization
receiverOrganization: Organization
createdAt: string
isRead: boolean
}
interface MessengerAttachmentsProps {
counterparty: Organization
onViewChange?: () => void
}
export function MessengerAttachments({ counterparty, onViewChange }: MessengerAttachmentsProps) {
const { user } = useAuth()
const [activeTab, setActiveTab] = useState('all')
const [lightboxImage, setLightboxImage] = useState<{ url: string; fileName: string; fileSize?: number } | null>(null)
// Загружаем все сообщения для получения вложений
const { data: messagesData, loading, refetch } = useQuery(GET_MESSAGES, {
variables: { counterpartyId: counterparty.id, limit: 1000 },
fetchPolicy: 'cache-and-network',
pollInterval: 5000, // Обновляем каждые 5 секунд
notifyOnNetworkStatusChange: false, // Не показываем loading при обновлениях
})
// Обновляем данные при открытии вкладки вложений
useEffect(() => {
onViewChange?.()
}, [onViewChange])
const messages: Message[] = messagesData?.messages || []
// Фильтруем только сообщения с вложениями
const attachmentMessages = messages.filter(msg =>
msg.type && ['VOICE', 'IMAGE', 'FILE'].includes(msg.type) &&
(msg.fileUrl || (msg.type === 'VOICE' && msg.voiceUrl))
)
// Группируем по типам
const imageMessages = attachmentMessages.filter(msg => msg.type === 'IMAGE')
const voiceMessages = attachmentMessages.filter(msg => msg.type === 'VOICE')
const fileMessages = attachmentMessages.filter(msg => msg.type === 'FILE')
const getOrganizationName = (org: Organization) => {
return org.name || org.fullName || 'Организация'
}
const getInitials = (org: Organization) => {
const name = getOrganizationName(org)
return name.charAt(0).toUpperCase()
}
const formatFileSize = (bytes?: number) => {
if (!bytes) return '0 B'
const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}
const formatDate = (dateString: string) => {
const date = new Date(dateString)
return date.toLocaleDateString('ru-RU', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
})
}
const formatTime = (dateString: string) => {
const date = new Date(dateString)
return date.toLocaleTimeString('ru-RU', {
hour: '2-digit',
minute: '2-digit'
})
}
const handleDownload = (fileUrl: string, fileName: string) => {
const link = document.createElement('a')
link.href = fileUrl
link.download = fileName
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
const handleImageClick = (imageUrl: string, fileName?: string, fileSize?: number) => {
setLightboxImage({
url: imageUrl,
fileName: fileName || 'Изображение',
fileSize
})
}
const renderFileIcon = (fileType?: string) => {
if (!fileType) return
{message.fileName ||
(message.type === 'IMAGE' ? 'Изображение' : 'Файл')}
Нет вложений
Файлы, изображения и голосовые сообщения будут отображаться здесь
Нет вложений
Нет изображений
Нет аудио записей
Нет файлов