'use client'; import { useEffect, useState } from 'react'; import { supabase } from '@/lib/supabase'; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { useParams, useRouter } from 'next/navigation'; import { toast } from 'sonner'; import { formatTimeDifference } from '@/lib/utils'; import Link from 'next/link'; import { Expert, Message } from '@/types'; interface Conversation { expert: Expert; lastMessage?: Message; unreadCount: number; } export default function ChatRoom() { const router = useRouter(); const { expertId } = useParams(); const [conversations, setConversations] = useState([]); const [messages, setMessages] = useState([]); const [newMessage, setNewMessage] = useState(''); const [currentExpert, setCurrentExpert] = useState(null); // Charger les conversations useEffect(() => { const loadConversations = async () => { const { data: messages, error } = await supabase .from('messages') .select('*, expert:experts(*)') .or('sender_id.eq.user_id,receiver_id.eq.user_id') .order('created_at', { ascending: false }); if (error) { toast.error("Erreur lors du chargement des conversations"); return; } // Grouper les messages par expert const conversationsMap = new Map(); messages?.forEach(message => { const expertId = message.sender_id === 'user_id' ? message.receiver_id : message.sender_id; if (!conversationsMap.has(expertId)) { conversationsMap.set(expertId, { expert: message.expert, lastMessage: message, unreadCount: message.sender_id !== 'user_id' && !message.read ? 1 : 0 }); } }); setConversations(Array.from(conversationsMap.values())); }; loadConversations(); }, []); // Charger les messages de la conversation courante useEffect(() => { if (!expertId) return; const loadMessages = async () => { const { data: expert, error: expertError } = await supabase .from('experts') .select('*') .eq('id_expert', expertId) .single(); if (expertError) { toast.error("Erreur lors du chargement de l'expert"); return; } setCurrentExpert(expert); const { data: messages, error: messagesError } = await supabase .from('messages') .select('*') .or(`sender_id.eq.${expertId},receiver_id.eq.${expertId}`) .order('created_at', { ascending: true }); if (messagesError) { toast.error("Erreur lors du chargement des messages"); return; } setMessages(messages || []); }; loadMessages(); // Souscrire aux nouveaux messages const channel = supabase.channel('public:messages') .on( 'postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages', }, (payload) => { setMessages(current => [...current, payload.new as Message]); } ) .subscribe(); return () => { channel.unsubscribe(); }; }, [expertId]); const sendMessage = async (e: React.FormEvent) => { e.preventDefault(); if (!newMessage.trim() || !expertId) return; const { error } = await supabase .from('messages') .insert({ content: newMessage, sender_id: 'user_id', receiver_id: expertId, }); if (error) { toast.error("Erreur lors de l'envoi du message"); return; } setNewMessage(''); }; const markAsRead = async (messageId: string) => { const { error } = await supabase .from('messages') .update({ read: true }) .eq('id', messageId); if (error) { toast.error("Erreur lors de la mise à jour du message"); } }; // Utilisez markAsRead quand un message est affiché useEffect(() => { if (!messages.length) return; // Marquer les messages non lus comme lus messages .filter(msg => !msg.read && msg.sender_id !== 'user_id') .forEach(msg => markAsRead(msg.id)); }, [messages]); return (
{/* Liste des conversations - cachée sur mobile si conversation active */}

Messages

{conversations.length > 0 ? ( conversations.map((conversation) => (
{(conversation.expert.avatar_url || conversation.expert.image_url) && ( {`${conversation.expert.prenom} )}

{conversation.expert.prenom} {conversation.expert.nom}

{conversation.lastMessage && (

{conversation.lastMessage.content}

)}
{conversation.unreadCount > 0 && (
{conversation.unreadCount}
)} )) ) : (
Aucune conversation
)}
{/* Zone de chat - plein écran sur mobile si conversation active */}
{expertId && currentExpert ? ( <> {/* En-tête avec bouton retour sur mobile */}
{currentExpert.avatar_url && ( // eslint-disable-next-line @next/next/no-img-element )}

{currentExpert.prenom} {currentExpert.nom}

{/* Messages avec padding ajusté */}
{messages.map((message) => (
{message.content}
{formatTimeDifference(new Date(message.created_at), new Date())}
))}
{/* Formulaire d'envoi fixé en bas sur mobile */}
setNewMessage(e.target.value)} placeholder="Écrivez votre message..." className="flex-1" />
) : (

Bienvenue dans votre messagerie

Sélectionnez une conversation ou commencez à discuter avec un expert

)}
); }