Add Chat for each Folder

This commit is contained in:
Omar Oughriss 2025-10-24 17:05:54 +02:00
parent 5c49d4eb67
commit 22a1052080

View File

@ -14,6 +14,8 @@ import {
SortAsc, SortAsc,
SortDesc, SortDesc,
X, X,
MessageSquare,
List,
} from "lucide-react" } from "lucide-react"
import { FolderData, FolderCreated, FolderPrivateFields, setDefaultFolderRoles } from "@/lib/4nk/models/FolderData" import { FolderData, FolderCreated, FolderPrivateFields, setDefaultFolderRoles } from "@/lib/4nk/models/FolderData"
import MessageBus from "@/lib/4nk/MessageBus" import MessageBus from "@/lib/4nk/MessageBus"
@ -22,6 +24,7 @@ import UserStore from "@/lib/4nk/UserStore"
import FolderModal from "@/components/4nk/FolderModal" import FolderModal from "@/components/4nk/FolderModal"
import AuthModal from "@/components/4nk/AuthModal" import AuthModal from "@/components/4nk/AuthModal"
import Iframe from "@/components/4nk/Iframe" import Iframe from "@/components/4nk/Iframe"
import FolderChat from "@/components/4nk/FolderChat"
type FolderType = 'contrat' | 'projet' | 'rapport' | 'finance' | 'rh' | 'marketing' | 'autre'; type FolderType = 'contrat' | 'projet' | 'rapport' | 'finance' | 'rh' | 'marketing' | 'autre';
@ -32,6 +35,7 @@ export default function FoldersPage() {
const [currentPath, setCurrentPath] = useState<string[]>(["Racine"]) const [currentPath, setCurrentPath] = useState<string[]>(["Racine"])
const [folderType, setFolderType] = useState<FolderType | null>(null); const [folderType, setFolderType] = useState<FolderType | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [activeTab, setActiveTab] = useState<"folders" | "chat">("folders");
// 4NK Integration states // 4NK Integration states
const [isConnected, setIsConnected] = useState(false) const [isConnected, setIsConnected] = useState(false)
@ -356,103 +360,142 @@ export default function FoldersPage() {
</div> </div>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
{activeTab === "folders" && (
<Button
onClick={() => handleOpenModal("autre")}
disabled={!isConnected}
className="flex items-center space-x-2"
>
<FolderPlus className="h-4 w-4" />
<span>Nouveau dossier</span>
</Button>
)}
</div>
</div>
{/* Tabs */}
<div className="flex items-center space-x-4 mb-4">
<div className="flex bg-gray-700 rounded-lg p-1">
<Button <Button
onClick={() => handleOpenModal("autre")} variant={activeTab === "folders" ? "default" : "ghost"}
disabled={!isConnected} size="sm"
onClick={() => setActiveTab("folders")}
className="flex items-center space-x-2" className="flex items-center space-x-2"
> >
<FolderPlus className="h-4 w-4" /> <List className="h-4 w-4" />
<span>Nouveau dossier</span> <span>Dossiers</span>
</Button>
<Button
variant={activeTab === "chat" ? "default" : "ghost"}
size="sm"
onClick={() => setActiveTab("chat")}
className="flex items-center space-x-2"
>
<MessageSquare className="h-4 w-4" />
<span>Chat</span>
</Button> </Button>
</div> </div>
</div> </div>
{/* Search and filters */} {/* Search and filters - only show for folders tab */}
<div className="flex items-center space-x-4"> {activeTab === "folders" && (
<div className="flex-1 relative"> <div className="flex items-center space-x-4">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" /> <div className="flex-1 relative">
<Input <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
placeholder="Rechercher des dossiers..." <Input
value={searchTerm} placeholder="Rechercher des dossiers..."
onChange={(e) => setSearchTerm(e.target.value)} value={searchTerm}
className="pl-10" onChange={(e) => setSearchTerm(e.target.value)}
/> className="pl-10"
/>
</div>
<div className="flex items-center space-x-2">
<Button
variant="outline"
size="sm"
onClick={() => setSortOrder(sortOrder === "asc" ? "desc" : "asc")}
>
{sortOrder === "asc" ? <SortAsc className="h-4 w-4" /> : <SortDesc className="h-4 w-4" />}
</Button>
</div>
</div> </div>
)}
<div className="flex items-center space-x-2">
<Button
variant="outline"
size="sm"
onClick={() => setSortOrder(sortOrder === "asc" ? "desc" : "asc")}
>
{sortOrder === "asc" ? <SortAsc className="h-4 w-4" /> : <SortDesc className="h-4 w-4" />}
</Button>
</div>
</div>
</div> </div>
{/* Content */} {/* Content */}
<div className="flex-1 p-6 bg-gray-900"> <div className="flex-1 bg-gray-900">
{loadingFolders ? ( {activeTab === "folders" ? (
<div className="flex items-center justify-center h-64"> <div className="p-6">
<div className="text-center"> {loadingFolders ? (
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4"></div> <div className="flex items-center justify-center h-64">
<p className="text-gray-400">Chargement des dossiers...</p> <div className="text-center">
</div> <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4"></div>
</div> <p className="text-gray-400">Chargement des dossiers...</p>
) : sortedFolders.length === 0 ? ( </div>
<div className="flex items-center justify-center h-64"> </div>
<div className="text-center"> ) : sortedFolders.length === 0 ? (
<Folder className="h-12 w-12 text-gray-400 mx-auto mb-4" /> <div className="flex items-center justify-center h-64">
<h3 className="text-lg font-medium text-gray-100 mb-2">Aucun dossier</h3> <div className="text-center">
<p className="text-gray-400 mb-4"> <Folder className="h-12 w-12 text-gray-400 mx-auto mb-4" />
{searchTerm ? "Aucun dossier ne correspond à votre recherche." : "Commencez par créer votre premier dossier."} <h3 className="text-lg font-medium text-gray-100 mb-2">Aucun dossier</h3>
</p> <p className="text-gray-400 mb-4">
{!searchTerm && ( {searchTerm ? "Aucun dossier ne correspond à votre recherche." : "Commencez par créer votre premier dossier."}
<Button </p>
onClick={() => handleOpenModal("autre")} {!searchTerm && (
disabled={!isConnected} <Button
> onClick={() => handleOpenModal("autre")}
<FolderPlus className="h-4 w-4 mr-2" /> disabled={!isConnected}
Créer un dossier >
</Button> <FolderPlus className="h-4 w-4 mr-2" />
)} Créer un dossier
</div> </Button>
</div> )}
) : ( </div>
<div className="space-y-4"> </div>
{/* Folder list */} ) : (
<div className="space-y-2"> <div className="space-y-4">
{sortedFolders.map((folder) => ( {/* Folder list */}
<Card key={folder.folderNumber} className="hover:shadow-md transition-shadow bg-gray-800 border border-gray-700"> <div className="space-y-2">
<CardContent className="p-4"> {sortedFolders.map((folder) => (
<div className="flex items-center justify-between"> <Card key={folder.folderNumber} className="hover:shadow-md transition-shadow bg-gray-800 border border-gray-700">
<div className="flex items-center space-x-3"> <CardContent className="p-4">
<Folder className="h-5 w-5 text-blue-600" /> <div className="flex items-center justify-between">
<div> <div className="flex items-center space-x-3">
<h3 className="font-medium text-gray-100">{folder.name}</h3> <Folder className="h-5 w-5 text-blue-600" />
<p className="text-sm text-gray-400">{folder.description}</p> <div>
<div className="flex items-center space-x-4 mt-1"> <h3 className="font-medium text-gray-100">{folder.name}</h3>
<span className="text-xs text-gray-400">#{folder.folderNumber}</span> <p className="text-sm text-gray-400">{folder.description}</p>
<span className="text-xs text-gray-400"> <div className="flex items-center space-x-4 mt-1">
<Clock className="h-3 w-3 inline mr-1" /> <span className="text-xs text-gray-400">#{folder.folderNumber}</span>
{new Date(folder.updated_at).toLocaleDateString()} <span className="text-xs text-gray-400">
</span> <Clock className="h-3 w-3 inline mr-1" />
{new Date(folder.updated_at).toLocaleDateString()}
</span>
</div>
</div>
</div>
<div className="flex items-center space-x-2">
{folder.notes.length > 0 && (
<Badge variant="outline">{folder.notes.length} notes</Badge>
)}
</div> </div>
</div> </div>
</div> </CardContent>
</Card>
<div className="flex items-center space-x-2"> ))}
{folder.notes.length > 0 && ( </div>
<Badge variant="outline">{folder.notes.length} notes</Badge> </div>
)} )}
</div>
</div>
</CardContent>
</Card>
))}
</div>
</div> </div>
) : (
<FolderChat
heightClass="h-full"
folderProcesses={folderProcesses}
myFolderProcesses={myFolderProcesses}
folderPrivateData={folderPrivateData}
/>
)} )}
</div> </div>
</div> </div>