From 7982f7b30024b35f3eb1eed5373d9aac8083de1e Mon Sep 17 00:00:00 2001 From: Omar Oughriss Date: Fri, 24 Oct 2025 17:07:10 +0200 Subject: [PATCH] Create FolderChat component --- components/4nk/FolderChat.tsx | 338 ++++++++++++++++++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100644 components/4nk/FolderChat.tsx diff --git a/components/4nk/FolderChat.tsx b/components/4nk/FolderChat.tsx new file mode 100644 index 0000000..ab8532a --- /dev/null +++ b/components/4nk/FolderChat.tsx @@ -0,0 +1,338 @@ +"use client" + +import { useState, useEffect } from "react" +import { Badge } from "@/components/ui/badge" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Textarea } from "@/components/ui/textarea" +import { + MessageSquare, + Search, + Send, + Paperclip, + Smile, + MoreHorizontal, + Users, + Circle, + Folder, + Clock, +} from "lucide-react" + +interface FolderMember { + id: string + name: string + avatar: string + isOnline: boolean +} + +interface FolderConversation { + id: string + folderNumber: string + folderName: string + members: FolderMember[] + lastMessage: string + lastMessageTime: string + unreadCount: number +} + +interface FolderChatProps { + heightClass?: string + folderProcesses?: any + myFolderProcesses?: string[] + folderPrivateData?: Record> +} + +export default function FolderChat({ + heightClass = "h-[calc(100vh-8rem)]", + folderProcesses, + myFolderProcesses = [], + folderPrivateData = {} +}: FolderChatProps) { + const [selectedConversation, setSelectedConversation] = useState("") + const [newMessage, setNewMessage] = useState("") + const [folderConversations, setFolderConversations] = useState([]) + const [isLoading, setIsLoading] = useState(true) + const [searchQuery, setSearchQuery] = useState("") + + // Extract folder conversations from processes + useEffect(() => { + if (folderProcesses && Object.keys(folderProcesses).length > 0) { + setIsLoading(true) + + const conversations: FolderConversation[] = [] + + Object.entries(folderProcesses).forEach(([processId, process]: [string, any]) => { + // Only include processes that belong to the user + if (!myFolderProcesses.includes(processId)) return + + const latestState = process.states?.[0] + if (!latestState) return + + // Check if this process has a folderNumber (indicates it's a folder process) + const folderNumber = latestState.pcd_commitment?.folderNumber + if (!folderNumber) return + + // Get private data for folder name + const privateData = folderPrivateData[latestState.state_id] + const folderName = privateData?.name || `Dossier ${folderNumber}` + + // Extract members from roles.owner.members + const ownerMembers = latestState.roles?.owner?.members || [] + const members: FolderMember[] = ownerMembers.map((memberId: string, index: number) => { + // Generate avatar from member ID + const avatar = memberId.slice(0, 2).toUpperCase() + + return { + id: memberId, + name: `Membre ${memberId.slice(0, 8)}`, // Could be enhanced with real names + avatar: avatar, + isOnline: Math.random() > 0.5 // Random online status for demo + } + }) + + conversations.push({ + id: processId, + folderNumber: folderNumber, + folderName: folderName, + members: members, + lastMessage: "", + lastMessageTime: "", + unreadCount: 0 + }) + }) + + setFolderConversations(conversations) + setIsLoading(false) + } else { + setIsLoading(true) + setFolderConversations([]) + } + }, [folderProcesses, myFolderProcesses, folderPrivateData]) + + // Filter conversations based on search query + const filteredConversations = folderConversations.filter(conversation => { + if (!searchQuery.trim()) return true + + const matchesNumber = conversation.folderNumber.toLowerCase().includes(searchQuery.toLowerCase()) + const matchesName = conversation.folderName.toLowerCase().includes(searchQuery.toLowerCase()) + const matchesId = conversation.id.toLowerCase().includes(searchQuery.toLowerCase()) + + return matchesNumber || matchesName || matchesId + }) + + const currentConversation = folderConversations.find((conv) => conv.id === selectedConversation) + + const handleSendMessage = () => { + if (newMessage.trim()) { + console.log("Sending message to folder:", selectedConversation, "Message:", newMessage) + // Here implement the actual message sending logic + setNewMessage("") + } + } + + return ( +
+ {/* Sidebar with folder conversations */} +
+
+
+

+ Chat Dossiers +

+
+ + setSearchQuery(e.target.value)} + className="pl-10 bg-gray-50 dark:bg-gray-700 border-gray-200 dark:border-gray-600" + /> +
+
+
+ +
+ {isLoading ? ( +
+
Chargement des dossiers...
+
+ ) : filteredConversations.length > 0 ? ( + filteredConversations.map((conversation) => ( +
setSelectedConversation(conversation.id)} + className={`p-4 border-b cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 ${ + selectedConversation === conversation.id + ? "bg-blue-50 dark:bg-blue-900 border-r-2 border-blue-500 dark:border-blue-400" + : "" + }`} + > +
+
+
+ +
+
+
+
+

+ {conversation.folderName} +

+ {conversation.members.length > 0 && ( + + + {conversation.members.length} + + )} +
+

+ #{conversation.folderNumber} +

+

+ {conversation.members.length} membre{conversation.members.length > 1 ? 's' : ''} +

+
+
+
+ )) + ) : ( +
+
+ +

Aucun dossier trouvé

+

+ Essayez de rechercher par nom ou numéro +

+
+
+ )} +
+
+ + {/* Main chat area */} +
+ {currentConversation ? ( + <> + {/* Chat header */} +
+
+
+
+ +
+
+

+ {currentConversation.folderName} +

+

+ Dossier #{currentConversation.folderNumber} • {currentConversation.members.length} membre{currentConversation.members.length > 1 ? 's' : ''} +

+
+
+
+ + +
+
+ + {/* Members list */} + {currentConversation.members.length > 0 && ( +
+
+ + + Membres du dossier + +
+
+ {currentConversation.members.map((member) => ( +
+
+
+ + {member.avatar} + +
+ {member.isOnline && ( + + )} +
+ + {member.name} + +
+ ))} +
+
+ )} +
+ + {/* Messages area */} +
+
+
+ +

+ Aucun message +

+

+ Commencez une conversation avec les membres de ce dossier +

+
+
+
+ + {/* Message input */} +
+
+ +
+