From 2c3b627aaaaa99756099600570c609d2e72b22dc Mon Sep 17 00:00:00 2001 From: omaroughriss Date: Tue, 21 Oct 2025 15:24:22 +0200 Subject: [PATCH] Retrive and render our folder list --- app/dashboard/folders/page.tsx | 136 ++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 12 deletions(-) diff --git a/app/dashboard/folders/page.tsx b/app/dashboard/folders/page.tsx index 66a6c8b..3a833b1 100644 --- a/app/dashboard/folders/page.tsx +++ b/app/dashboard/folders/page.tsx @@ -178,6 +178,9 @@ export default function FoldersPage() { const [processes, setProcesses] = useState(null) const [myProcesses, setMyProcesses] = useState([]) const [userPairingId, setUserPairingId] = useState(null) + const [folderProcesses, setFolderProcesses] = useState(null) + const [myFolderProcesses, setMyFolderProcesses] = useState([]) + const [folderPrivateData, setFolderPrivateData] = useState>>({}) // Modal states const [inviteMessage, setInviteMessage] = useState("") @@ -376,10 +379,12 @@ export default function FoldersPage() { // 2️⃣ Charger les processes const processes = await messageBus.getProcesses(); setProcesses(processes); + setFolderProcesses(processes); // Use same processes for folders // 3️⃣ Charger les myProcesses const myProcesses = await messageBus.getMyProcesses(); setMyProcesses(myProcesses); + setMyFolderProcesses(myProcesses); // Use same myProcesses for folders } catch (err) { console.error("❌ Error during pairing or process loading:", err); @@ -389,11 +394,110 @@ export default function FoldersPage() { handleConnectionFlow(); }, [isConnected, iframeUrl]); - useEffect(() => { - // Simuler le chargement des dossiers - const loadFolders = () => { - const mockFolders: FolderData[] = [] + // Notification system + const showNotification = (type: "success" | "error" | "info", message: string) => { + setNotification({ type, message }) + setTimeout(() => setNotification(null), 3000) + } + // Function to fetch folder private data + const fetchFolderPrivateData = async (processId: string, stateId: string) => { + if (!myFolderProcesses.includes(processId)) return; + try { + const messageBus = MessageBus.getInstance(iframeUrl); + await messageBus.isReady(); + const data = await messageBus.getData(processId, stateId); + setFolderPrivateData(prev => ({ ...prev, [stateId]: data })); + } catch (err) { + console.error('Error fetching folder private data:', err); + } + }; + + // Function to load folders from 4NK processes + const loadFoldersFrom4NK = useCallback(() => { + if (!folderProcesses) return; + + const folderData: FolderData[] = []; + + Object.entries(folderProcesses).forEach(([processId, process]: [string, any]) => { + // Only include processes that belong to the user (myFolderProcesses) + if (!myFolderProcesses.includes(processId)) return; + + // Check if this process has a folderNumber in pcd_commitment + const latestState = process.states[process.states.length - 2]; // -2 because last state is empty + if (!latestState) return; + + const folderNumber = latestState.pcd_commitment?.folderNumber; + if (!folderNumber) return; // Skip processes without folderNumber + + // Get private data for this state if available + const privateData = folderPrivateData[latestState.state_id] || {}; + + // Create folder data from process data + const folder: FolderData = { + id: parseInt(folderNumber) || Math.floor(Math.random() * 10000), + name: latestState.public_data?.name || privateData?.name || `Dossier ${folderNumber}`, + description: latestState.public_data?.description || privateData?.description || '', + documentsCount: latestState.public_data?.documentsCount || privateData?.documentsCount || 0, + subfoldersCount: latestState.public_data?.subfoldersCount || privateData?.subfoldersCount || 0, + size: latestState.public_data?.size || privateData?.size || '0 MB', + created: new Date(latestState.public_data?.created || privateData?.created || Date.now()), + modified: new Date(latestState.public_data?.modified || privateData?.modified || Date.now()), + owner: latestState.public_data?.owner || privateData?.owner || 'Propriétaire 4NK', + access: (latestState.public_data?.access || privateData?.access || 'private') as 'shared' | 'private', + members: latestState.public_data?.members || privateData?.members || [], + tags: latestState.public_data?.tags || privateData?.tags || [], + color: latestState.public_data?.color || privateData?.color || 'blue', + favorite: latestState.public_data?.favorite || privateData?.favorite || false, + storageType: (latestState.public_data?.storageType || privateData?.storageType || 'temporary') as 'temporary' | 'permanent', + status: (latestState.public_data?.status || privateData?.status || 'active') as 'active' | 'archived' | 'pending' | 'completed' | 'validated', + type: latestState.public_data?.type || privateData?.type || 'general', + expectedDocuments: latestState.public_data?.expectedDocuments || privateData?.expectedDocuments || [], + activity: latestState.public_data?.activity || privateData?.activity || [], + permissions: latestState.public_data?.permissions || privateData?.permissions || { + canView: true, + canEdit: true, // User owns this process + canDelete: true, // User owns this process + canInvite: true, // User owns this process + canArchive: true, // User owns this process + canAnalyze: true, + }, + temporaryStorageConfig: latestState.public_data?.temporaryStorageConfig || privateData?.temporaryStorageConfig, + documents: latestState.public_data?.documents || privateData?.documents || [], + }; + + folderData.push(folder); + + // Fetch private data if we don't have it yet (we know this is the user's process) + if (!folderPrivateData[latestState.state_id]) { + setTimeout(() => fetchFolderPrivateData(processId, latestState.state_id), 0); + } + }); + + setFolders(folderData); + + // Update stats + setStats({ + total: folderData.length, + shared: folderData.filter((folder) => folder.access === "shared").length, + private: folderData.filter((folder) => folder.access === "private").length, + thisWeek: folderData.filter((folder) => { + const weekAgo = new Date() + weekAgo.setDate(weekAgo.getDate() - 7) + return folder.modified > weekAgo + }).length, + permanent: folderData.filter((folder) => folder.storageType === "permanent").length, + temporary: folderData.filter((folder) => folder.storageType === "temporary").length, + }); + }, [folderProcesses, myFolderProcesses, folderPrivateData, iframeUrl]); + + useEffect(() => { + // Load folders from 4NK when folder processes are available + if (folderProcesses && myFolderProcesses.length >= 0) { + loadFoldersFrom4NK(); + } else { + // Fallback: load empty folders if not connected to 4NK + const mockFolders: FolderData[] = [] setFolders(mockFolders) setStats({ total: mockFolders.length, @@ -408,15 +512,14 @@ export default function FoldersPage() { temporary: mockFolders.filter((folder) => folder.storageType === "temporary").length, }) } + }, [folderProcesses, myFolderProcesses, loadFoldersFrom4NK]) - loadFolders() - }, []) - - // Notification system - const showNotification = (type: "success" | "error" | "info", message: string) => { - setNotification({ type, message }) - setTimeout(() => setNotification(null), 3000) - } + // Update folders when private data changes + useEffect(() => { + if (folderProcesses && Object.keys(folderPrivateData).length > 0) { + loadFoldersFrom4NK(); + } + }, [folderPrivateData, folderProcesses, loadFoldersFrom4NK]) // 4NK Authentication handlers const handleLogin = useCallback(() => { @@ -430,6 +533,12 @@ export default function FoldersPage() { setProcesses(null); setMyProcesses([]); setUserPairingId(null); + + // Clear folder-related states + setFolderProcesses(null); + setMyFolderProcesses([]); + setFolderPrivateData({}); + setFolders([]); // Émettre un événement pour vider les messages locaux EventBus.getInstance().emit('CLEAR_CONSOLE'); @@ -669,6 +778,7 @@ export default function FoldersPage() { .getProcesses() .then(async (processes: any) => { setProcesses(processes) + setFolderProcesses(processes) // Update folder processes as well }) ) ); @@ -1046,6 +1156,7 @@ export default function FoldersPage() { } }) + const getFolderColor = (color: string) => { const colorObj = colors.find((c) => c.id === color) return colorObj?.class || "text-gray-600 bg-gray-100" @@ -1345,6 +1456,7 @@ export default function FoldersPage() { + {/* Bulk Actions minimalistes: certificats et rôles uniquement */} {selectedFolders.length > 0 && (