Compare commits
No commits in common. "9857a3766d03ffb7351c9899d6e32dac223214bb" and "93c927ba71ae818dd2cc9c030923069d5ea3454f" have entirely different histories.
9857a3766d
...
93c927ba71
@ -1,6 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useState, useEffect } from "react"
|
import { useState } from "react"
|
||||||
import { Badge } from "@/components/ui/badge"
|
import { Badge } from "@/components/ui/badge"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Textarea } from "@/components/ui/textarea"
|
import { Textarea } from "@/components/ui/textarea"
|
||||||
@ -12,36 +12,40 @@ import {
|
|||||||
Folder,
|
Folder,
|
||||||
MessageSquare
|
MessageSquare
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
|
import type { EnrichedFolderData } from "@/lib/contexts/FourNKContext";
|
||||||
import MessageBus from "@/lib/4nk/MessageBus"
|
import MessageBus from "@/lib/4nk/MessageBus"
|
||||||
import { iframeUrl } from "@/app/page"
|
import { iframeUrl } from "@/app/page"
|
||||||
import { FolderChatData } from "@/lib/4nk/models/FolderData"
|
|
||||||
import { use4NK, EnrichedFolderData } from "@/lib/contexts/FourNKContext"
|
|
||||||
|
|
||||||
// Interface pour les props (accepte null)
|
// Interface pour les props (accepte null)
|
||||||
interface FolderChatProps {
|
interface FolderChatProps {
|
||||||
folder: EnrichedFolderData | null;
|
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) {
|
export default function FolderChat({ folder }: FolderChatProps) {
|
||||||
const [newMessage, setNewMessage] = useState("")
|
const [newMessage, setNewMessage] = useState("")
|
||||||
const [activeTab, setActiveTab] = useState<'owner' | 'general'>('owner');
|
const [activeTab, setActiveTab] = useState<'owner' | 'general'>('owner');
|
||||||
const [ownerMessages, setOwnerMessages] = useState<FolderChatData[]>([]);
|
|
||||||
const [generalMessages, setGeneralMessages] = useState<FolderChatData[]>([]);
|
|
||||||
|
|
||||||
const {
|
// Données fictives
|
||||||
isConnected,
|
const mockMessages: MockMessage[] = [
|
||||||
userPairingId,
|
{ id: 1, sender: 'other', name: 'Membre A4B2 (Owner)', avatar: 'A4', text: "Validation Owner OK.", time: "14:30", type: 'owner' },
|
||||||
folders,
|
{ id: 2, sender: 'me', name: 'Vous', avatar: 'MO', text: "Parfait, merci.", time: "14:32", type: 'owner' },
|
||||||
members,
|
{ id: 3, sender: 'other', name: 'Membre C8F1', avatar: 'C8', text: "Le client a une question sur ce dossier.", time: "14:33", type: 'general' },
|
||||||
} = use4NK();
|
{ id: 4, sender: 'me', name: 'Vous', avatar: 'MO', text: "Je regarde ça.", time: "14:34", type: 'general' },
|
||||||
|
];
|
||||||
useEffect(() => {
|
|
||||||
setOwnerMessages(folder?.messages_owner || []);
|
|
||||||
setGeneralMessages(folder?.messages || []);
|
|
||||||
}, [folder]);
|
|
||||||
|
|
||||||
// Filtre les messages basé sur l'onglet actif
|
// Filtre les messages basé sur l'onglet actif
|
||||||
const filteredMessages = activeTab === 'owner' ? ownerMessages : generalMessages;
|
const filteredMessages = mockMessages.filter(msg => msg.type === activeTab);
|
||||||
|
|
||||||
const handleProcessUpdate = async (processId: string, key: string, value: any) => {
|
const handleProcessUpdate = async (processId: string, key: string, value: any) => {
|
||||||
try {
|
try {
|
||||||
@ -71,7 +75,7 @@ export default function FolderChat({ folder }: FolderChatProps) {
|
|||||||
await messageBus.validateState(processId, newStateId);
|
await messageBus.validateState(processId, newStateId);
|
||||||
|
|
||||||
// Refresh the processes data
|
// Refresh the processes data
|
||||||
await messageBus.getProcesses();
|
// const updatedProcesses = await messageBus.getProcesses();
|
||||||
|
|
||||||
console.log('Process updated successfully');
|
console.log('Process updated successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -81,30 +85,12 @@ export default function FolderChat({ folder }: FolderChatProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSendMessage = () => {
|
const handleSendMessage = () => {
|
||||||
if (newMessage.trim() && folder) {
|
if (newMessage.trim()) {
|
||||||
console.log(`Envoi message [${activeTab}] dans le dossier:`, folder?.name, "Msg:", newMessage)
|
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'
|
const key = activeTab === 'owner' ? 'messages_owner' : 'messages'
|
||||||
|
handleProcessUpdate(folder.processId, key, newMessage)
|
||||||
// Créez l'objet du nouveau message
|
|
||||||
const newMessageData: FolderChatData = {
|
|
||||||
timestamp: Date.now(),
|
|
||||||
sender: (userPairingId ? userPairingId : ''),
|
|
||||||
receiver: '',
|
|
||||||
fromRole: 'owner',
|
|
||||||
toRole: 'owner',
|
|
||||||
message: newMessage,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activeTab === 'owner') {
|
|
||||||
setOwnerMessages(prevMessages => [...prevMessages, newMessageData]);
|
|
||||||
} else {
|
|
||||||
setGeneralMessages(prevMessages => [...prevMessages, newMessageData]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Envoi de la mise à jour au MessageBus (en arrière-plan)
|
|
||||||
handleProcessUpdate(folder.processId, key, newMessageData)
|
|
||||||
|
|
||||||
// Vider l'input
|
|
||||||
setNewMessage("")
|
setNewMessage("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,16 +156,18 @@ export default function FolderChat({ folder }: FolderChatProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* --- LISTE DES MEMBRES (SUPPRIMÉE) --- */}
|
||||||
|
|
||||||
{/* Zone des messages */}
|
{/* Zone des messages */}
|
||||||
<div className="flex-1 overflow-y-auto p-4 space-y-4 bg-gray-900">
|
<div className="flex-1 overflow-y-auto p-4 space-y-4 bg-gray-900">
|
||||||
{filteredMessages.length > 0 ? filteredMessages.map((msg, i) => (
|
{filteredMessages.length > 0 ? filteredMessages.map((msg) => (
|
||||||
<div
|
<div
|
||||||
key={i}
|
key={msg.id}
|
||||||
className={`flex items-start gap-3 ${msg.sender === userPairingId ? 'justify-end' : ''}`}
|
className={`flex items-start gap-3 ${msg.sender === 'me' ? 'justify-end' : ''}`}
|
||||||
>
|
>
|
||||||
{msg.sender != userPairingId && (
|
{msg.sender === 'other' && (
|
||||||
<div className="w-8 h-8 bg-blue-800 rounded-full flex items-center justify-center flex-shrink-0">
|
<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.sender.slice(0, 2)}</span>
|
<span className="text-xs text-blue-300 font-medium">{msg.avatar}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div>
|
<div>
|
||||||
@ -189,16 +177,13 @@ export default function FolderChat({ folder }: FolderChatProps) {
|
|||||||
: 'bg-gray-700 text-gray-100 rounded-bl-none'
|
: 'bg-gray-700 text-gray-100 rounded-bl-none'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{msg.sender != userPairingId && (
|
{msg.sender === 'other' && (
|
||||||
<p className="text-xs font-medium text-blue-300 mb-1">KAAK</p>
|
<p className="text-xs font-medium text-blue-300 mb-1">{msg.name}</p>
|
||||||
)}
|
)}
|
||||||
<p>{msg.message}</p>
|
<p>{msg.text}</p>
|
||||||
</div>
|
</div>
|
||||||
<p className={`text-xs text-gray-500 mt-1 ${msg.sender === userPairingId ? 'text-right' : ''}`}>
|
<p className={`text-xs text-gray-500 mt-1 ${msg.sender === 'me' ? 'text-right' : ''}`}>
|
||||||
{new Date(Number(msg.timestamp)).toLocaleTimeString('fr-FR', {
|
{msg.time}
|
||||||
hour: '2-digit',
|
|
||||||
minute: '2-digit'
|
|
||||||
})}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,27 +1,5 @@
|
|||||||
import type { RoleDefinition } from "./Roles";
|
import type { RoleDefinition } from "./Roles";
|
||||||
|
|
||||||
export interface FolderChatAttachment {
|
|
||||||
ext: string;
|
|
||||||
file_name: string;
|
|
||||||
title?: string;
|
|
||||||
type?: string;
|
|
||||||
category?: string;
|
|
||||||
base64: string;
|
|
||||||
note?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FolderChatData {
|
|
||||||
timestamp: number;
|
|
||||||
sender: string;
|
|
||||||
receiver: string;
|
|
||||||
fromRole: string
|
|
||||||
toRole: string
|
|
||||||
ia?: boolean;
|
|
||||||
title?: string;
|
|
||||||
message: string;
|
|
||||||
data?: FolderChatAttachment[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttachedFile {
|
export interface AttachedFile {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@ -38,8 +16,8 @@ export interface FolderData {
|
|||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
notes: string[];
|
notes: string[];
|
||||||
messages: FolderChatData[];
|
messages: string[];
|
||||||
messages_owner: FolderChatData[];
|
messages_owner: string[];
|
||||||
attachedFiles?: AttachedFile[];
|
attachedFiles?: AttachedFile[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { createContext, useContext, useState, useEffect, useCallback, ReactNode
|
|||||||
import MessageBus from "@/lib/4nk/MessageBus";
|
import MessageBus from "@/lib/4nk/MessageBus";
|
||||||
import { iframeUrl } from "@/app/page";
|
import { iframeUrl } from "@/app/page";
|
||||||
import UserStore from "@/lib/4nk/UserStore";
|
import UserStore from "@/lib/4nk/UserStore";
|
||||||
import { FolderChatData, FolderData } from "@/lib/4nk/models/FolderData";
|
import { FolderData } from "@/lib/4nk/models/FolderData";
|
||||||
|
|
||||||
// Interface enrichie qui inclut maintenant les membres ET les fichiers
|
// Interface enrichie qui inclut maintenant les membres ET les fichiers
|
||||||
export interface EnrichedFolderData extends FolderData {
|
export interface EnrichedFolderData extends FolderData {
|
||||||
@ -82,13 +82,11 @@ export function FourNKProvider({ children }: { children: ReactNode }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let basePrivateData;
|
// console.log(validStates);
|
||||||
let mergedMessages: FolderChatData[] = [];
|
|
||||||
let mergedMessagesOwner: FolderChatData[] = [];
|
|
||||||
|
|
||||||
validStates.forEach((state: any) => {
|
// validStates.forEach(state => {
|
||||||
hasFoldersToLoad = true;
|
hasFoldersToLoad = true;
|
||||||
const stateToProcess = state;
|
const stateToProcess = referenceState;
|
||||||
|
|
||||||
const privateData = folderPrivateData[stateToProcess.state_id];
|
const privateData = folderPrivateData[stateToProcess.state_id];
|
||||||
|
|
||||||
@ -100,34 +98,30 @@ export function FourNKProvider({ children }: { children: ReactNode }) {
|
|||||||
}
|
}
|
||||||
// console.log("Données déchiffrées pour le state:", stateToProcess.state_id, privateData);
|
// console.log("Données déchiffrées pour le state:", stateToProcess.state_id, privateData);
|
||||||
|
|
||||||
if (privateData.messages_owner instanceof Map) {
|
/*
|
||||||
const messageOwnerObj = Object.fromEntries(privateData.messages_owner);
|
// 4. CONDITION B: On vérifie si cet état contient des messages.
|
||||||
mergedMessagesOwner.push(messageOwnerObj);
|
const hasMessages = (privateData.messages && privateData.messages.length > 0);
|
||||||
}
|
const hasMessagesOwner = (privateData.messages_owner && privateData.messages_owner.length > 0);
|
||||||
|
|
||||||
if (privateData.messages instanceof Map) {
|
// Si cet état n'a pas de messages, on l'ignore (return)
|
||||||
const messageObj = Object.fromEntries(privateData.messages);
|
if (!hasMessages && !hasMessagesOwner) {
|
||||||
mergedMessages.push(messageObj);
|
return; // Passe à l'état suivant
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (privateData.folderNumber) {
|
|
||||||
basePrivateData = privateData;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!basePrivateData) return;
|
|
||||||
folderData.push({
|
folderData.push({
|
||||||
processId: processId,
|
processId: processId,
|
||||||
folderNumber: mainFolderNumber,
|
folderNumber: mainFolderNumber, // La clé unique
|
||||||
name: basePrivateData.name || `Dossier ${mainFolderNumber}`,
|
name: privateData.name || `Dossier ${mainFolderNumber}`,
|
||||||
description: basePrivateData.description || '',
|
description: privateData.description || '',
|
||||||
created_at: basePrivateData.created_at || new Date().toISOString(),
|
created_at: privateData.created_at || new Date().toISOString(),
|
||||||
updated_at: basePrivateData.updated_at || new Date().toISOString(),
|
updated_at: privateData.updated_at || new Date().toISOString(),
|
||||||
notes: basePrivateData.notes || [],
|
notes: privateData.notes || [],
|
||||||
messages: mergedMessages || [],
|
messages: privateData.messages || [],
|
||||||
messages_owner: mergedMessagesOwner || [],
|
messages_owner: privateData.messages_owner || [],
|
||||||
attachedFiles: basePrivateData.attachedFiles || [],
|
attachedFiles: privateData.attachedFiles || [],
|
||||||
});
|
});
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -143,7 +137,7 @@ export function FourNKProvider({ children }: { children: ReactNode }) {
|
|||||||
setFolders(folderData);
|
setFolders(folderData);
|
||||||
setLoadingFolders(false);
|
setLoadingFolders(false);
|
||||||
}
|
}
|
||||||
}, [folderProcesses, myFolderProcesses, folderPrivateData, fetchFolderPrivateData, setFolders, setLoadingFolders]);
|
}, [folderProcesses, myFolderProcesses, folderPrivateData, fetchFolderPrivateData, setFolders, setLoadingFolders]); // J'ai ajouté setFolders et setLoadingFolders aux dépendances
|
||||||
|
|
||||||
const loadMembersFrom4NK = useCallback(() => {
|
const loadMembersFrom4NK = useCallback(() => {
|
||||||
if (!processes || !userPairingId) return;
|
if (!processes || !userPairingId) return;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user