espace-paie-odentas/components/MessageCard.tsx
2025-10-12 17:05:46 +02:00

179 lines
No EOL
5.9 KiB
TypeScript

import React, { useState } from "react";
import { ChevronDown, ChevronRight, User, Settings, Paperclip } from "lucide-react";
type Message = {
id: string;
content: string;
author_type: "client" | "staff";
author_name?: string;
created_at: string;
attachments?: Array<{
filename: string;
url: string;
size?: number;
}>;
};
interface MessageCardProps {
message: Message;
isExpanded: boolean;
onToggle: () => void;
}
function formatTimeAgo(dateString: string): string {
const date = new Date(dateString);
const now = new Date();
const diffInMinutes = Math.floor((now.getTime() - date.getTime()) / (1000 * 60));
if (diffInMinutes < 1) return "À l'instant";
if (diffInMinutes < 60) return `Il y a ${diffInMinutes} min`;
const diffInHours = Math.floor(diffInMinutes / 60);
if (diffInHours < 24) return `Il y a ${diffInHours}h`;
const diffInDays = Math.floor(diffInHours / 24);
if (diffInDays < 7) return `Il y a ${diffInDays}j`;
return date.toLocaleDateString('fr-FR');
}
function formatFileSize(bytes?: number): string {
if (!bytes) return "";
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}
export default function MessageCard({ message, isExpanded, onToggle }: MessageCardProps) {
const isFromClient = message.author_type === "client";
const timeAgo = formatTimeAgo(message.created_at);
return (
<div
className={`
group border border-slate-200 rounded-xl transition-all duration-300 hover:shadow-md
${isFromClient
? "bg-blue-50/50 border-l-4 border-l-blue-500"
: "bg-emerald-50/50 border-l-4 border-l-emerald-500"
}
`}
>
{/* En-tête cliquable */}
<button
onClick={onToggle}
className="w-full p-4 flex items-center justify-between hover:bg-slate-50/50 rounded-xl transition-colors"
>
<div className="flex items-center space-x-3">
{/* Avatar */}
<div
className={`
flex items-center justify-center w-10 h-10 rounded-full border-2
${isFromClient
? "bg-blue-100 border-blue-300 text-blue-600"
: "bg-emerald-100 border-emerald-300 text-emerald-600"
}
`}
>
{isFromClient ? (
<User className="w-5 h-5" />
) : (
<Settings className="w-5 h-5" />
)}
</div>
{/* Infos */}
<div className="text-left">
<div className="flex items-center space-x-2">
<span className="font-medium text-slate-900">
{message.author_name || (isFromClient ? "Vous" : "Support Odentas")}
</span>
<span className="text-xs text-slate-500">
{timeAgo}
</span>
</div>
{/* Aperçu du message */}
{!isExpanded && (
<div className="text-sm text-slate-600 mt-1">
<div className="line-clamp-1">
{message.content.length > 100
? `${message.content.substring(0, 100)}...`
: message.content
}
</div>
</div>
)}
{/* Indicateurs */}
<div className="flex items-center space-x-3 mt-1">
{message.attachments && message.attachments.length > 0 && (
<div className="flex items-center space-x-1 text-xs text-slate-500">
<Paperclip className="w-3 h-3" />
<span>{message.attachments.length} fichier{message.attachments.length > 1 ? "s" : ""}</span>
</div>
)}
</div>
</div>
</div>
{/* Icône d'expansion */}
<div className="text-slate-400 group-hover:text-slate-600">
{isExpanded ? (
<ChevronDown className="w-5 h-5" />
) : (
<ChevronRight className="w-5 h-5" />
)}
</div>
</button>
{/* Contenu expandé */}
{isExpanded && (
<div className="px-4 pb-4">
{/* Divider */}
<div className="h-px bg-slate-200 mb-4" />
{/* Message complet */}
<div className="prose prose-sm max-w-none">
<div className="whitespace-pre-wrap text-slate-700 leading-relaxed">
{message.content}
</div>
</div>
{/* Pièces jointes */}
{message.attachments && message.attachments.length > 0 && (
<div className="mt-4 space-y-2">
<div className="text-sm font-medium text-slate-600 flex items-center space-x-2">
<Paperclip className="w-4 h-4" />
<span>Pièces jointes</span>
</div>
<div className="space-y-1">
{message.attachments.map((attachment, index) => (
<a
key={index}
href={attachment.url}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-between p-2 rounded-lg border border-slate-200 hover:bg-slate-50 transition-colors"
>
<div className="flex items-center space-x-2">
<Paperclip className="w-4 h-4 text-slate-400" />
<span className="text-sm text-slate-700">
{attachment.filename}
</span>
</div>
{attachment.size && (
<span className="text-xs text-slate-500">
{formatFileSize(attachment.size)}
</span>
)}
</a>
))}
</div>
</div>
)}
</div>
)}
</div>
);
}