import React, { useState, useEffect, useRef } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { ScrollArea } from '@/components/ui/scroll-area'; // eslint-disable-next-line @typescript-eslint/no-unused-vars import { Separator } from '@/components/ui/separator'; import { useAuthStore } from '@/stores/auth'; import { websocketService } from '@/services/websocket'; // TODO: wsService should be replaced with websocketService or a proper chat service const wsService = websocketService as any; // eslint-disable-next-line @typescript-eslint/no-unused-vars import EmojiPicker, { EmojiClickData } from 'emoji-picker-react'; import { apiService } from '@/services/api'; import { toast } from '@/hooks/use-toast'; import { ChatMessage } from '@/types'; import { Send, MessageCircle, Users, Wifi, WifiOff, Loader2, // MoreVertical, Settings, Hash } from 'lucide-react'; interface ChatInterfaceProps { room?: string; onRoomChange?: (room: string) => void; } export function ChatInterface({ room = 'general', onRoomChange: _onRoomChange }: ChatInterfaceProps) { const { user } = useAuthStore(); const [messages, setMessages] = useState([]); const [newMessage, setNewMessage] = useState(''); const [isConnected, setIsConnected] = useState(false); const [isLoading, setIsLoading] = useState(false); const [isSending, setIsSending] = useState(false); // eslint-disable-next-line @typescript-eslint/no-unused-vars const [onlineUsers, setOnlineUsers] = useState([]); const [chatStats, setChatStats] = useState(null); const messagesEndRef = useRef(null); // Auto-scroll vers le bas const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }; useEffect(() => { scrollToBottom(); }, [messages]); // Gestion des événements WebSocket useEffect(() => { const handleChatConnected = () => { setIsConnected(true); toast({ title: 'Chat connecté', description: 'Vous êtes maintenant connecté au chat.', }); }; const handleChatDisconnected = () => { setIsConnected(false); toast({ title: 'Chat déconnecté', description: 'Connexion au chat perdue.', variant: 'destructive', }); }; const handleChatMessage = (message: ChatMessage) => { setMessages(prev => [...prev, message]); }; const handleChatError = (error: any) => { console.error('Erreur chat:', error); toast({ title: 'Erreur chat', description: 'Une erreur est survenue dans le chat.', variant: 'destructive', }); }; // S'abonner aux événements wsService.on('chat_connected', handleChatConnected); wsService.on('chat_disconnected', handleChatDisconnected); wsService.on('chat_message', handleChatMessage); wsService.on('chat_error', handleChatError); // Se connecter au chat wsService.connectChat(); if (room) { wsService.joinRoom(room); } // Charger les messages existants loadMessages(); loadChatStats(); return () => { wsService.off('chat_connected', handleChatConnected); wsService.off('chat_disconnected', handleChatDisconnected); wsService.off('chat_message', handleChatMessage); wsService.off('chat_error', handleChatError); }; }, [room]); const loadMessages = async () => { setIsLoading(true); try { const response = await apiService.getChatMessages({ room, limit: 50 }); if (response.success) { setMessages(response.data || []); } } catch (error) { console.error('Erreur lors du chargement des messages:', error); } finally { setIsLoading(false); } }; const loadChatStats = async () => { try { const response = await apiService.getChatStats(); if (response.success) { setChatStats(response.data); } } catch (error) { console.error('Erreur lors du chargement des statistiques:', error); } }; const handleSendMessage = async (e: React.FormEvent) => { e.preventDefault(); if (!newMessage.trim() || !user || isSending) return; const messageData = { content: newMessage.trim(), author: user.username, room, is_direct: false, }; setIsSending(true); try { // Envoyer via WebSocket wsService.sendMessage(messageData); // Aussi envoyer via API REST pour la persistance await apiService.sendChatMessage(messageData); setNewMessage(''); } catch (error) { console.error('Erreur lors de l\'envoi du message:', error); toast({ title: 'Erreur', description: 'Impossible d\'envoyer le message.', variant: 'destructive', }); } finally { setIsSending(false); } }; const formatTimestamp = (timestamp: string) => { const date = new Date(timestamp); return date.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }); }; return (
{/* En-tête du chat */}
{room}
{isConnected ? ( <> Connecté ) : ( <> Déconnecté )}
{chatStats && (
{chatStats.active_users || 0}
{chatStats.total_messages || 0}
)}
{/* Zone des messages */} {isLoading ? (
) : messages.length === 0 ? (

Aucun message dans ce salon

Soyez le premier à écrire quelque chose !

) : (
{messages.map((message, index) => (
{message.author.charAt(0).toUpperCase()}
{message.author} {formatTimestamp(message.timestamp)} {message.is_direct && ( Privé )}

{message.content}

))}
)} {/* Zone de saisie */}
setNewMessage(e.target.value)} placeholder={`Écrire dans #${room}...`} disabled={!isConnected || isSending} className="flex-1" />
); }