Files
n3wt-school/Front-End/src/components/Chat.js
2025-05-17 11:35:57 +02:00

176 lines
5.9 KiB
JavaScript

import React, { useState, useRef, useEffect } from 'react';
import { SendHorizontal, Plus } from 'lucide-react';
import Image from 'next/image';
import {
fetchConversations,
fetchMessages,
sendMessage,
markAsRead,
} from '@/app/actions/messagerieAction';
export default function Chat({
userProfileId,
establishmentId,
discussions: discussionsProp,
setDiscussions: setDiscussionsProp,
onCreateDiscussion,
onShowCreateDiscussion,
}) {
const [discussions, setDiscussions] = useState(discussionsProp || []);
const [selectedDiscussion, setSelectedDiscussion] = useState(null);
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState('');
const messagesEndRef = useRef(null);
useEffect(() => {
if (userProfileId) {
fetchConversations(userProfileId).then(setDiscussions);
}
}, [userProfileId]);
useEffect(() => {
if (selectedDiscussion) {
fetchMessages(selectedDiscussion.conversation_id).then(setMessages);
// Marquer comme lu
markAsRead(selectedDiscussion.conversation_id, userProfileId);
}
}, [selectedDiscussion, userProfileId]);
const handleSendMessage = async () => {
if (newMessage.trim() && selectedDiscussion) {
await sendMessage({
conversation_id: selectedDiscussion.conversation_id,
emetteur: userProfileId,
destinataire: selectedDiscussion.interlocuteur.id,
corpus: newMessage,
objet: '',
});
setNewMessage('');
fetchMessages(selectedDiscussion.conversation_id).then(setMessages);
fetchConversations(userProfileId).then(setDiscussions);
}
};
const handleKeyPress = (event) => {
if (event.key === 'Enter') {
handleSendMessage();
}
};
return (
<div className="flex h-full w-full">
{/* Bandeau droit : Liste des discussions */}
<div className="w-1/4 min-w-[280px] bg-gray-100 border-r border-gray-300 p-4 flex flex-col">
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-bold">Discussions</h2>
<button
className="p-2 rounded-full bg-blue-500 hover:bg-blue-600 text-white shadow"
title="Nouvelle discussion"
onClick={onShowCreateDiscussion}
>
<Plus size={20} />
</button>
</div>
<div className="flex-1 overflow-y-auto">
{discussions && discussions.length > 0 ? (
discussions.map((discussion) => (
<div
key={discussion.id}
className={`flex items-center p-2 mb-2 cursor-pointer rounded transition-colors ${
selectedDiscussion?.id === discussion.id
? 'bg-blue-100'
: 'hover:bg-gray-200'
}`}
onClick={() => setSelectedDiscussion(discussion)}
>
<Image
src={discussion.profilePic}
alt={`${discussion.name}'s profile`}
className="w-10 h-10 rounded-full mr-3"
width={40}
height={40}
/>
<div className="flex-1">
<p className="font-medium">{discussion.name}</p>
<p className="text-sm text-gray-500 truncate">
{discussion.lastMessage}
</p>
</div>
<span className="text-xs text-gray-400">
{discussion.lastMessageDate &&
new Date(discussion.lastMessageDate).toLocaleTimeString()}
</span>
</div>
))
) : (
<p className="text-gray-500">Aucune discussion disponible.</p>
)}
</div>
</div>
{/* Zone de chat */}
<div className="flex-1 flex flex-col bg-white">
{/* En-tête du chat */}
{selectedDiscussion && (
<div className="flex items-center p-4 border-b border-gray-300">
<Image
src={selectedDiscussion.profilePic}
alt={`${selectedDiscussion.name}'s profile`}
className="w-10 h-10 rounded-full mr-3"
width={40}
height={40}
/>
<h2 className="text-lg font-bold">{selectedDiscussion.name}</h2>
</div>
)}
{/* Messages */}
<div className="flex-1 overflow-y-auto p-4">
{selectedDiscussion &&
messages.map((message) => (
<div
key={message.id}
className={`flex mb-4 ${
message.isResponse ? 'justify-start' : 'justify-end'
}`}
>
<div
className={`p-3 rounded-lg max-w-xs ${
message.isResponse
? 'bg-gray-200 text-gray-800'
: 'bg-blue-500 text-white'
}`}
>
<p>{message.corpus}</p>
<span className="text-xs text-gray-500 block mt-1">
{message.date &&
new Date(message.date).toLocaleTimeString()}
</span>
</div>
</div>
))}
<div ref={messagesEndRef} />
</div>
{/* Champ de saisie */}
{selectedDiscussion && (
<div className="p-4 border-t border-gray-300 flex items-center">
<input
type="text"
value={newMessage}
onChange={(e) => setNewMessage(e.target.value)}
className="flex-1 p-2 border border-gray-300 rounded-lg mr-2"
placeholder="Écrire un message..."
onKeyDown={(e) => e.key === 'Enter' && handleSendMessage()}
/>
<button
onClick={handleSendMessage}
className="p-2 bg-blue-500 text-white rounded-lg"
>
<SendHorizontal />
</button>
</div>
)}
</div>
</div>
);
}