import React, { useState, useRef, useEffect } from 'react'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { MediaModal } from '@/components/MediaModal'; import { Users, Circle, Upload, File, ImageIcon, Video, Music, FileText, Download, Play, Pause, Trash2 } from 'lucide-react'; interface ActiveUser { id: string; name: string; color: string; lastSeen: Date; isTyping?: boolean; currentLine?: number; } interface MediaFile { id: string; name: string; type: string; size: number; url: string; uploadedAt: Date; uploadedBy: string; } interface LeftPanelProps { isVisible: boolean; isConnected: boolean; className?: string; users?: ActiveUser[]; mediaFiles?: MediaFile[]; onFileUpload?: (files: FileList) => void; onFileDelete?: (fileId: string) => void; onModalStateChange?: (isOpen: boolean) => void; } export const LeftPanel: React.FC = ({ isVisible, className = '', users = [], mediaFiles = [], onFileDelete, onModalStateChange }) => { const [activeUsers, setActiveUsers] = useState(users); const [localMediaFiles, setLocalMediaFiles] = useState(mediaFiles); // Update local state when props change useEffect(() => { setActiveUsers(users); }, [users]); useEffect(() => { setLocalMediaFiles(mediaFiles); }, [mediaFiles]); const [playingAudio, setPlayingAudio] = useState(null); const [modalFile, setModalFile] = useState(null); const audioRefs = useRef<{ [key: string]: HTMLAudioElement }>({}); // Helper function to get the correct file URL using HTTP server const getFileUrl = (file: MediaFile) => { const httpUrl = process.env.NEXT_PUBLIC_HTTP_URL || 'http://localhost:8081'; return file.url.startsWith('http') ? file.url : `${httpUrl}${file.url}`; }; // Helper function to handle modal state changes const handleModalChange = (file: MediaFile | null) => { setModalFile(file); if (onModalStateChange) { onModalStateChange(file !== null); } }; // Users Panel Functions const getStatusIndicator = (user: ActiveUser) => { const timeDiff = Date.now() - user.lastSeen.getTime(); if (timeDiff < 60000) { // Less than 1 minute return { status: 'online', color: 'rgb(184, 187, 38)' }; // success color } else if (timeDiff < 300000) { // Less than 5 minutes return { status: 'away', color: 'rgb(250, 189, 47)' }; // warning color } else { return { status: 'offline', color: 'rgb(146, 131, 116)' }; // muted color } }; const formatLastSeen = (date: Date) => { const timeDiff = Date.now() - date.getTime(); if (timeDiff < 60000) { return 'Just now'; } else if (timeDiff < 3600000) { const minutes = Math.floor(timeDiff / 60000); return `${minutes}m ago`; } else { const hours = Math.floor(timeDiff / 3600000); return `${hours}h ago`; } }; // Media Panel Functions const formatFileSize = (bytes: number) => { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', '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 formatTimeAgo = (date: Date) => { const timeDiff = Date.now() - date.getTime(); if (timeDiff < 60000) { return 'Just now'; } else if (timeDiff < 3600000) { const minutes = Math.floor(timeDiff / 60000); return `${minutes}m ago`; } else { const hours = Math.floor(timeDiff / 3600000); return `${hours}h ago`; } }; const getFileIcon = (type: string) => { if (type.startsWith('image/')) return ; if (type.startsWith('video/')) return