mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-28 23:43:22 +00:00
134 lines
4.4 KiB
JavaScript
134 lines
4.4 KiB
JavaScript
import React from 'react';
|
|
import { format, isToday, isYesterday } from 'date-fns';
|
|
import { fr } from 'date-fns/locale';
|
|
import { Check, CheckCheck } from 'lucide-react';
|
|
import FileAttachment from './FileAttachment';
|
|
import { getGravatarUrl } from '@/utils/gravatar';
|
|
|
|
const MessageBubble = ({
|
|
message,
|
|
isOwnMessage,
|
|
showAvatar = true,
|
|
isRead = false,
|
|
senderName = '',
|
|
senderEmail = '', // Nouveau prop pour l'email du sender
|
|
isFirstInGroup = true,
|
|
isLastInGroup = true,
|
|
showTime = true,
|
|
}) => {
|
|
const formatMessageTime = (dateString) => {
|
|
if (!dateString) return '';
|
|
|
|
const date = new Date(dateString);
|
|
|
|
if (isToday(date)) {
|
|
return format(date, 'HH:mm', { locale: fr });
|
|
} else if (isYesterday(date)) {
|
|
return `Hier ${format(date, 'HH:mm', { locale: fr })}`;
|
|
} else {
|
|
return format(date, 'dd/MM HH:mm', { locale: fr });
|
|
}
|
|
};
|
|
|
|
const getMessageContent = () => {
|
|
return message.content || message.corpus || '';
|
|
};
|
|
|
|
const getMessageTime = () => {
|
|
return message.created_at || message.date_envoi;
|
|
};
|
|
|
|
const hasAttachment = () => {
|
|
return (
|
|
message.attachment &&
|
|
(message.attachment.fileName || message.attachment.fileUrl)
|
|
);
|
|
};
|
|
|
|
const isFileOnlyMessage = () => {
|
|
return hasAttachment() && !getMessageContent().trim();
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={`group hover:bg-gray-50 px-4 py-1 ${isFirstInGroup ? 'mt-4' : 'mt-0.5'} message-appear`}
|
|
onMouseEnter={() => {
|
|
/* Peut ajouter des actions au hover */
|
|
}}
|
|
>
|
|
<div className="flex">
|
|
{/* Avatar - affiché seulement pour le premier message du groupe */}
|
|
{showAvatar && isFirstInGroup && (
|
|
<img
|
|
src={getGravatarUrl(senderEmail || senderName, 40)}
|
|
alt={`Avatar de ${senderName || 'Utilisateur'}`}
|
|
className="w-10 h-10 rounded-full object-cover shadow-sm mr-3 flex-shrink-0 mt-0.5"
|
|
/>
|
|
)}
|
|
|
|
{/* Espace pour aligner avec l'avatar quand il n'est pas affiché */}
|
|
{(!showAvatar || !isFirstInGroup) && (
|
|
<div className="w-10 mr-3 flex-shrink-0"></div>
|
|
)}
|
|
|
|
{/* Contenu du message */}
|
|
<div className="flex-1 min-w-0">
|
|
{/* En-tête du message (nom + heure) - seulement pour le premier message du groupe */}
|
|
{isFirstInGroup && (
|
|
<div className="flex items-baseline space-x-2 mb-1">
|
|
<span className="font-semibold text-gray-900 text-sm">
|
|
{senderName || (isOwnMessage ? 'Moi' : 'Utilisateur')}
|
|
</span>
|
|
<span className="text-xs text-gray-500">
|
|
{formatMessageTime(getMessageTime())}
|
|
</span>
|
|
</div>
|
|
)}
|
|
|
|
{/* Fichier attaché */}
|
|
{hasAttachment() && (
|
|
<div className={`${getMessageContent().trim() ? 'mb-2' : ''}`}>
|
|
<FileAttachment
|
|
fileName={message.attachment.fileName}
|
|
fileSize={message.attachment.fileSize}
|
|
fileType={message.attachment.fileType}
|
|
fileUrl={message.attachment.fileUrl}
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{/* Contenu du message */}
|
|
{getMessageContent().trim() && (
|
|
<div className="text-sm leading-relaxed whitespace-pre-wrap break-words text-gray-800">
|
|
{getMessageContent()}
|
|
</div>
|
|
)}
|
|
|
|
{/* Indicateurs de lecture et heure pour les messages non-groupés */}
|
|
<div className="flex items-center space-x-2 mt-1">
|
|
{/* Heure pour les messages qui ne sont pas le premier du groupe */}
|
|
{!isFirstInGroup && (
|
|
<span className="text-xs text-gray-400 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
{formatMessageTime(getMessageTime())}
|
|
</span>
|
|
)}
|
|
|
|
{/* Indicateurs de lecture (uniquement pour nos messages) */}
|
|
{isOwnMessage && (
|
|
<div className="flex items-center opacity-0 group-hover:opacity-100 transition-opacity">
|
|
{isRead ? (
|
|
<CheckCheck className="w-3 h-3 text-green-500" title="Lu" />
|
|
) : (
|
|
<Check className="w-3 h-3 text-gray-400" title="Envoyé" />
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MessageBubble;
|