docv/components/4nk/FolderChat.tsx

230 lines
8.1 KiB
TypeScript

"use client"
import { useState } from "react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Textarea } from "@/components/ui/textarea"
import {
Send,
Paperclip,
Smile,
MoreHorizontal,
Folder,
MessageSquare
} from "lucide-react"
import type { EnrichedFolderData } from "@/lib/contexts/FourNKContext";
import MessageBus from "@/lib/4nk/MessageBus"
import { iframeUrl } from "@/app/page"
// Interface pour les props (accepte null)
interface FolderChatProps {
folder: EnrichedFolderData | null;
}
// Message fictif pour la maquette
interface MockMessage {
id: number;
sender: 'me' | 'other';
name: string;
avatar: string;
text: string;
time: string;
type: 'owner' | 'general'; // Pour filtrer
}
export default function FolderChat({ folder }: FolderChatProps) {
const [newMessage, setNewMessage] = useState("")
const [activeTab, setActiveTab] = useState<'owner' | 'general'>('owner');
// Données fictives
const mockMessages: MockMessage[] = [
{ id: 1, sender: 'other', name: 'Membre A4B2 (Owner)', avatar: 'A4', text: "Validation Owner OK.", time: "14:30", type: 'owner' },
{ id: 2, sender: 'me', name: 'Vous', avatar: 'MO', text: "Parfait, merci.", time: "14:32", type: 'owner' },
{ id: 3, sender: 'other', name: 'Membre C8F1', avatar: 'C8', text: "Le client a une question sur ce dossier.", time: "14:33", type: 'general' },
{ id: 4, sender: 'me', name: 'Vous', avatar: 'MO', text: "Je regarde ça.", time: "14:34", type: 'general' },
];
// Filtre les messages basé sur l'onglet actif
const filteredMessages = mockMessages.filter(msg => msg.type === activeTab);
const handleProcessUpdate = async (processId: string, key: string, value: any) => {
try {
const messageBus = MessageBus.getInstance(iframeUrl);
await messageBus.isReady();
const updateData = {
[key]: value
};
// First update the process
const updatedProcess = await messageBus.updateProcess(processId, updateData, [], null);
if (!updatedProcess) {
throw new Error('No updated process found');
}
const newStateId = updatedProcess.diffs[0]?.state_id;
if (!newStateId) {
throw new Error('No new state id found');
}
// Then notify about the update
await messageBus.notifyProcessUpdate(processId, newStateId);
// Finally validate the state
await messageBus.validateState(processId, newStateId);
// Refresh the processes data
// const updatedProcesses = await messageBus.getProcesses();
console.log('Process updated successfully');
} catch (error) {
console.error('Error updating field:', error);
// You might want to show an error message to the user here
}
};
const handleSendMessage = () => {
if (newMessage.trim()) {
console.log(`Envoi message [${activeTab}] à:`, folder?.folderNumber, "Msg:", newMessage)
// TODO: Implémenter la logique d'envoi de message
if(!folder) return;
const key = activeTab === 'owner' ? 'messages_owner' : 'messages'
handleProcessUpdate(folder.processId, key, newMessage)
setNewMessage("")
}
}
// Si aucun dossier n'est sélectionné, afficher un placeholder
if (!folder) {
return (
<div className="flex h-full items-center justify-center bg-gray-800 text-gray-500 p-6">
<div className="text-center">
<MessageSquare className="h-12 w-12 mx-auto mb-4" />
<h3 className="text-lg font-medium text-gray-100 mb-2">
Chat de dossier
</h3>
<p className="text-gray-400">
Sélectionnez un dossier pour voir la conversation
</p>
</div>
</div>
)
}
// Si un dossier EST sélectionné, afficher le chat complet
return (
<div className="flex flex-col h-full bg-gray-800 text-gray-100">
{/* En-tête du chat */}
<div className="p-4 border-b border-gray-700">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-green-800 rounded-full flex items-center justify-center flex-shrink-0">
<Folder className="h-5 w-5 text-green-400" />
</div>
<div>
<h3 className="font-medium text-gray-100">
{folder.name}
</h3>
{/* ID du dossier supprimé */}
</div>
</div>
<Button variant="ghost" size="sm" className="text-gray-400 hover:text-gray-100 hover:bg-gray-700">
<MoreHorizontal className="h-4 w-4" />
</Button>
</div>
</div>
{/* Onglets "Owner" / "General" */}
<div className="p-2 flex border-b border-gray-700 bg-gray-900">
<Button
variant={activeTab === 'owner' ? "secondary" : "ghost"}
size="sm"
onClick={() => setActiveTab('owner')}
className={`flex-1 ${activeTab === 'owner' ? 'bg-gray-700 text-white' : 'text-gray-400 hover:text-white'}`}
>
Propriétaires
</Button>
<Button
variant={activeTab === 'general' ? "secondary" : "ghost"}
size="sm"
onClick={() => setActiveTab('general')}
className={`flex-1 ${activeTab === 'general' ? 'bg-gray-700 text-white' : 'text-gray-400 hover:text-white'}`}
>
Général
</Button>
</div>
{/* --- LISTE DES MEMBRES (SUPPRIMÉE) --- */}
{/* Zone des messages */}
<div className="flex-1 overflow-y-auto p-4 space-y-4 bg-gray-900">
{filteredMessages.length > 0 ? filteredMessages.map((msg) => (
<div
key={msg.id}
className={`flex items-start gap-3 ${msg.sender === 'me' ? 'justify-end' : ''}`}
>
{msg.sender === 'other' && (
<div className="w-8 h-8 bg-blue-800 rounded-full flex items-center justify-center flex-shrink-0">
<span className="text-xs text-blue-300 font-medium">{msg.avatar}</span>
</div>
)}
<div>
<div
className={`p-3 rounded-lg ${msg.sender === 'me'
? 'bg-blue-600 text-white rounded-br-none'
: 'bg-gray-700 text-gray-100 rounded-bl-none'
}`}
>
{msg.sender === 'other' && (
<p className="text-xs font-medium text-blue-300 mb-1">{msg.name}</p>
)}
<p>{msg.text}</p>
</div>
<p className={`text-xs text-gray-500 mt-1 ${msg.sender === 'me' ? 'text-right' : ''}`}>
{msg.time}
</p>
</div>
</div>
)) : (
<div className="flex h-full items-center justify-center text-center text-gray-500 p-4">
<p>Aucun message dans le chat "{activeTab}"</p>
</div>
)}
</div>
{/* Input de message */}
<div className="p-4 border-t border-gray-700">
<div className="flex items-end space-x-2">
<Button variant="ghost" size="sm" className="text-gray-400 hover:text-gray-100 hover:bg-gray-700">
<Paperclip className="h-5 w-5" />
</Button>
<Button variant="ghost" size="sm" className="text-gray-400 hover:text-gray-100 hover:bg-gray-700">
<Smile className="h-5 w-5" />
</Button>
<Textarea
placeholder={`Message (${activeTab})...`}
value={newMessage}
onChange={(e) => setNewMessage(e.target.value)}
onKeyPress={(e) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSendMessage();
}
}}
rows={1}
className="resize-none flex-1 bg-gray-700 border-gray-700 text-gray-100 placeholder-gray-400 focus:border-blue-500 focus:ring-0"
/>
<Button
onClick={handleSendMessage}
disabled={!newMessage.trim()}
className="bg-blue-600 hover:bg-blue-700 text-white"
>
<Send className="h-4 w-4" />
</Button>
</div>
</div>
</div>
)
}