"use client"; import { formatDistanceToNow } from "date-fns"; import { fr } from "date-fns/locale"; import { Search, Send } from "lucide-react"; import * as React from "react"; import { toast } from "sonner"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; import { useAuth } from "@/providers/auth-provider"; import { useSocket } from "@/providers/socket-provider"; import { type Conversation, type Message, MessageService, } from "@/services/message.service"; export default function MessagesPage() { const { user } = useAuth(); const { socket } = useSocket(); const [conversations, setConversations] = React.useState([]); const [activeConv, setActiveConv] = React.useState(null); const [messages, setMessages] = React.useState([]); const [newMessage, setNewMessage] = React.useState(""); const [isLoadingConvs, setIsLoadingConvs] = React.useState(true); const [isLoadingMsgs, setIsLoadingMsgs] = React.useState(false); const scrollRef = React.useRef(null); React.useEffect(() => { const fetchConvs = async () => { try { const data = await MessageService.getConversations(); setConversations(data); } catch (_error) { toast.error("Erreur lors du chargement des conversations"); } finally { setIsLoadingConvs(false); } }; fetchConvs(); }, []); React.useEffect(() => { if (activeConv) { const fetchMsgs = async () => { setIsLoadingMsgs(true); try { const data = await MessageService.getMessages(activeConv.id); setMessages(data.reverse()); // Plus ancien au plus récent } catch (_error) { toast.error("Erreur lors du chargement des messages"); } finally { setIsLoadingMsgs(false); } }; fetchMsgs(); } }, [activeConv]); React.useEffect(() => { if (socket) { socket.on( "new_message", (data: { conversationId: string; message: Message }) => { if (activeConv?.id === data.conversationId) { setMessages((prev) => [...prev, data.message]); } // Mettre à jour la liste des conversations setConversations((prev) => { const index = prev.findIndex((c) => c.id === data.conversationId); if (index !== -1) { const updated = [...prev]; updated[index] = { ...updated[index], lastMessage: { text: data.message.text, createdAt: data.message.createdAt, }, updatedAt: data.message.createdAt, }; return updated.sort( (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(), ); } return prev; }); }, ); return () => { socket.off("new_message"); }; } }, [socket, activeConv]); React.useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }, []); const handleSendMessage = async (e: React.FormEvent) => { e.preventDefault(); if (!newMessage.trim() || !activeConv) return; const text = newMessage.trim(); setNewMessage(""); try { const msg = await MessageService.sendMessage( activeConv.recipient.uuid, text, ); setMessages((prev) => [...prev, msg]); } catch (_error) { toast.error("Erreur lors de l'envoi"); } }; return (
{/* Sidebar - Liste des conversations */}

Messages

{isLoadingConvs ? (
Chargement...
) : conversations.length === 0 ? (
Aucune conversation.
) : ( conversations.map((conv) => ( )) )}
{/* Zone de chat */}
{activeConv ? ( <> {/* Header */}
{activeConv.recipient.username[0].toUpperCase()}

{activeConv.recipient.displayName || activeConv.recipient.username}

En ligne
{/* Messages */}
{isLoadingMsgs ? (
Chargement...
) : ( messages.map((msg) => (

{msg.text}

{new Date(msg.createdAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", })}

)) )}
{/* Input */}
setNewMessage(e.target.value)} className="rounded-full px-4" />
) : (

Vos messages

Sélectionnez une conversation ou démarrez-en une nouvelle pour commencer à discuter.

)}
); }