Simplify and clean up unused UI
This commit is contained in:
parent
eaf5b653e9
commit
085713400c
@ -311,563 +311,110 @@ export default function FoldersPage() {
|
||||
<h1 className="text-xl font-semibold text-gray-100">Dossiers</h1>
|
||||
<p className="text-sm text-gray-400 mt-1">Gérez vos dossiers 4NK</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Header */}
|
||||
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-gray-100">Dossiers</h1>
|
||||
<p className="text-gray-400 mt-1">Organisez vos documents par dossiers</p>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3 mt-4 sm:mt-0">
|
||||
<Button variant="outline" size="sm">
|
||||
<Upload className="h-4 w-4 mr-2 text-gray-100" />
|
||||
Importer
|
||||
</Button>
|
||||
|
||||
{isConnected ? (
|
||||
<div className="flex gap-2">
|
||||
{/* Nouveau dossier avec menu */}
|
||||
<div className="relative">
|
||||
<Button size="sm" onClick={() => setMenuOpen(!menuOpen)}>
|
||||
<FolderPlus className="h-4 w-4 mr-2" />
|
||||
Nouveau dossier
|
||||
</Button>
|
||||
|
||||
{menuOpen && (
|
||||
<div className="absolute mt-1 right-0 w-48 bg-white border border-gray-200 rounded shadow-lg z-50">
|
||||
<button
|
||||
className="w-full text-left px-4 py-2 text-gray-700 hover:bg-gray-100"
|
||||
onClick={() => handleOpenModal("general")}
|
||||
>
|
||||
Nouveau dossier
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Déconnexion */}
|
||||
<Button variant="outline" size="sm" onClick={handleLogout}>
|
||||
<X className="h-4 w-4 mr-2" />
|
||||
Déconnexion 4NK
|
||||
</Button>
|
||||
|
||||
<div className="flex-1 p-4">
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<span className="text-gray-400">Total</span>
|
||||
<span className="font-medium text-gray-100">{stats.total}</span>
|
||||
</div>
|
||||
) : (
|
||||
<Button variant="outline" size="sm" onClick={handleLogin}>
|
||||
<Shield className="h-4 w-4 mr-2" />
|
||||
Connexion 4NK
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 4NK Connection Status */}
|
||||
<div className="p-4 border-t border-gray-700">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-sm font-medium text-gray-100">4NK Status</span>
|
||||
<Badge variant={isConnected ? "default" : "secondary"}>
|
||||
{isConnected ? "Connecté" : "Déconnecté"}
|
||||
</Badge>
|
||||
</div>
|
||||
{!isConnected && (
|
||||
<Button
|
||||
size="sm"
|
||||
className="w-full"
|
||||
onClick={() => setShowAuthModal(true)}
|
||||
>
|
||||
Se connecter à 4NK
|
||||
</Button>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Breadcrumb */}
|
||||
<div className="flex items-center space-x-2 text-sm text-gray-400">
|
||||
{currentPath.map((path, index) => (
|
||||
<div key={index} className="flex items-center space-x-2">
|
||||
{index > 0 && <ChevronRight className="h-4 w-4 text-gray-400" />}
|
||||
<button
|
||||
className={`hover:text-gray-100 ${index === currentPath.length - 1 ? "font-medium text-gray-100" : ""}`}
|
||||
onClick={() => setCurrentPath(currentPath.slice(0, index + 1))}
|
||||
>
|
||||
{path}
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Search and Filters */}
|
||||
<Card className="bg-gray-900 border-gray-700 text-gray-100">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex flex-col lg:flex-row lg:items-center lg:justify-between space-y-4 lg:space-y-0">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center space-y-3 sm:space-y-0 sm:space-x-4">
|
||||
{/* Main Content */}
|
||||
<div className="flex-1 flex flex-col">
|
||||
{/* Header */}
|
||||
<div className="bg-gray-800 border-b border-gray-700 p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center space-x-2">
|
||||
{currentPath.map((path, index) => (
|
||||
<div key={index} className="flex items-center">
|
||||
{index > 0 && <ChevronRight className="h-4 w-4 text-gray-400 mx-1" />}
|
||||
<span className="text-sm text-gray-300">{path}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setShowFilters(!showFilters)}
|
||||
className={showFilters ? "bg-blue-700 text-white border-blue-600" : ""}
|
||||
onClick={() => handleOpenModal("autre")}
|
||||
disabled={!isConnected}
|
||||
className="flex items-center space-x-2"
|
||||
>
|
||||
<Filter className="h-4 w-4 mr-2 text-gray-100" />
|
||||
Filtres
|
||||
<FolderPlus className="h-4 w-4" />
|
||||
<span>Nouveau dossier</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Label htmlFor="sort" className="text-sm text-gray-300">
|
||||
Trier par:
|
||||
</Label>
|
||||
<Select value={sortBy} onValueChange={setSortBy}>
|
||||
<SelectTrigger className="w-32 bg-gray-800 text-gray-100 border-gray-700">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="bg-gray-800 text-gray-100 border-gray-700">
|
||||
<SelectItem value="modified">Modifié</SelectItem>
|
||||
<SelectItem value="name">Nom</SelectItem>
|
||||
<SelectItem value="size">Taille</SelectItem>
|
||||
<SelectItem value="owner">Propriétaire</SelectItem>
|
||||
<SelectItem value="documents">Documents</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Button variant="ghost" size="sm" onClick={() => setSortOrder(sortOrder === "asc" ? "desc" : "asc")}>
|
||||
{sortOrder === "asc" ? <SortAsc className="h-4 w-4 text-gray-100" /> : <SortDesc className="h-4 w-4 text-gray-100" />}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Advanced Filters */}
|
||||
{showFilters && (
|
||||
<div className="mt-4 pt-4 border-t border-gray-700">
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="filterAccess" className="text-sm font-medium text-gray-300">
|
||||
Accès
|
||||
</Label>
|
||||
<Select value={filterAccess} onValueChange={setFilterAccess}>
|
||||
<SelectTrigger className="bg-gray-800 text-gray-100 border-gray-700">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="bg-gray-800 text-gray-100 border-gray-700">
|
||||
<SelectItem value="all">Tous les accès</SelectItem>
|
||||
<SelectItem value="shared">Partagés</SelectItem>
|
||||
<SelectItem value="private">Privés</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="filterOwner" className="text-sm font-medium text-gray-300">
|
||||
Propriétaire
|
||||
</Label>
|
||||
<Select value={filterOwner} onValueChange={setFilterOwner}>
|
||||
<SelectTrigger className="bg-gray-800 text-gray-100 border-gray-700">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="bg-gray-800 text-gray-100 border-gray-700">
|
||||
<SelectItem value="all">Tous les propriétaires</SelectItem>
|
||||
<SelectItem value="Marie Dubois">Marie Dubois</SelectItem>
|
||||
<SelectItem value="Sophie Laurent">Sophie Laurent</SelectItem>
|
||||
<SelectItem value="Jean Martin">Jean Martin</SelectItem>
|
||||
<SelectItem value="Pierre Durand">Pierre Durand</SelectItem>
|
||||
<SelectItem value="Admin Système">Admin Système</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="filterStorage" className="text-sm font-medium text-gray-300">
|
||||
Type de stockage
|
||||
</Label>
|
||||
<Select value={filterStorage} onValueChange={setFilterStorage}>
|
||||
<SelectTrigger className="bg-gray-800 text-gray-100 border-gray-700">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="bg-gray-800 text-gray-100 border-gray-700">
|
||||
<SelectItem value="all">Tous les stockages</SelectItem>
|
||||
<SelectItem value="temporary">
|
||||
<div className="flex items-center space-x-2">
|
||||
<HardDrive className="h-4 w-4 text-gray-100" />
|
||||
<span>Temporaire</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
<SelectItem value="permanent">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Cloud className="h-4 w-4 text-gray-100" />
|
||||
<span>Permanent</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="flex items-end">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
setFilterAccess("all")
|
||||
setFilterOwner("all")
|
||||
setFilterStorage("all")
|
||||
setSearchTerm("")
|
||||
}}
|
||||
>
|
||||
Réinitialiser
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{/* Search and filters */}
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="flex-1 relative">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
|
||||
<Input
|
||||
placeholder="Rechercher des dossiers..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="pl-10"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
|
||||
{/* Bulk Actions minimalistes: certificats et rôles uniquement */}
|
||||
{selectedFolders.length > 0 && (
|
||||
<Card className="bg-gray-800 border-gray-700 text-gray-100">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-3">
|
||||
<Checkbox
|
||||
checked={selectedFolders.length === filteredFolders.length}
|
||||
onCheckedChange={selectAllFolders}
|
||||
/>
|
||||
<span className="text-sm font-medium">
|
||||
{selectedFolders.length} dossier{selectedFolders.length > 1 ? "s" : ""} sélectionné
|
||||
{selectedFolders.length > 1 ? "s" : ""}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
>
|
||||
<Download className="h-4 w-4 mr-2 text-gray-100" />
|
||||
Télécharger
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const selected = folders.filter((f) => selectedFolders.includes(f.id))
|
||||
selected.forEach((folder) => {
|
||||
setActionModal({ type: "certificate", folder, folders: [] })
|
||||
})
|
||||
}}
|
||||
>
|
||||
<CheckCircle className="h-4 w-4 mr-2 text-gray-100" />
|
||||
Valider
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
showNotification("info", "Déplacement groupé de dossiers (mock)")
|
||||
}}
|
||||
>
|
||||
<FolderOpen className="h-4 w-4 mr-2 text-gray-100" />
|
||||
Déplacer
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const selected = folders.filter((f) => selectedFolders.includes(f.id))
|
||||
selected.forEach((folder) => {
|
||||
setActionModal({ type: "storage_config", folder, folders: [] })
|
||||
})
|
||||
}}
|
||||
>
|
||||
<HardDrive className="h-4 w-4 mr-2 text-gray-100" />
|
||||
Conservation
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const selected = folders.filter((f) => selectedFolders.includes(f.id))
|
||||
const withCerts = selected.filter((f) => f.documents && f.documents.some((d) => d.hasCertificate))
|
||||
if (withCerts.length === 0) {
|
||||
setNotification({ type: "info", message: "Aucun certificat à télécharger pour la sélection" })
|
||||
return
|
||||
}
|
||||
withCerts.forEach((f) => handleViewDocumentsCertificates(f))
|
||||
}}
|
||||
>
|
||||
<ShieldCheck className="h-4 w-4 mr-2 text-gray-100" />
|
||||
Certificats
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const first = folders.find((f) => selectedFolders.includes(f.id))
|
||||
if (first) {
|
||||
handleManageRoles(first)
|
||||
} else {
|
||||
setNotification({ type: "info", message: "Sélectionnez au moins un dossier" })
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Users className="h-4 w-4 mr-2 text-gray-100" />
|
||||
Rôles
|
||||
</Button>
|
||||
</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>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Folders List/Grid */}
|
||||
<Card>
|
||||
<CardContent className="p-0">
|
||||
{viewMode === "list" ? (
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full">
|
||||
<thead className="bg-gray-800">
|
||||
<tr>
|
||||
<th className="text-left py-3 px-4 w-8">
|
||||
<Checkbox
|
||||
checked={selectedFolders.length === filteredFolders.length}
|
||||
onCheckedChange={selectAllFolders}
|
||||
/>
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-100">Nom</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-100">Taille</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-100">Modifié</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-100">Propriétaire</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-100">Accès</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-100">Statut</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{filteredFolders.map((folder) => (
|
||||
<tr
|
||||
key={folder.id}
|
||||
className="border-b border-gray-700 hover:bg-gray-800"
|
||||
>
|
||||
<td className="py-3 px-4">
|
||||
<Checkbox
|
||||
checked={selectedFolders.includes(folder.id)}
|
||||
onCheckedChange={() => toggleFolderSelection(folder.id)}
|
||||
/>
|
||||
</td>
|
||||
<td className="py-3 px-4">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className={`p-2 rounded-lg ${getFolderColor(folder.color)}`}>
|
||||
<Folder className="h-5 w-5 text-black" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span
|
||||
className="font-medium text-gray-100 cursor-pointer hover:underline"
|
||||
onClick={() => handleOpenFolder(folder)}
|
||||
>
|
||||
{folder.name}
|
||||
</span>
|
||||
{isNewFolder(folder) && (
|
||||
<Badge className="bg-blue-700 text-blue-100 border-blue-600">NEW</Badge>
|
||||
)}
|
||||
{getStorageIcon(folder.storageType)}
|
||||
{folder.access === "private" && (
|
||||
<Lock className="h-4 w-4 text-gray-400" />
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm text-gray-400 truncate max-w-xs">{folder.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-3 px-4 text-gray-400">{folder.size}</td>
|
||||
<td className="py-3 px-4 text-gray-400">{formatDate(folder.modified)}</td>
|
||||
<td className="py-3 px-4 text-gray-400">{folder.owner}</td>
|
||||
<td className="py-3 px-4">
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={
|
||||
folder.access === "shared"
|
||||
? "bg-green-700 text-green-100 border-green-600"
|
||||
: "bg-orange-700 text-orange-100 border-orange-600"
|
||||
}
|
||||
>
|
||||
{folder.access === "shared" ? "Partagé" : "Privé"}
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="py-3 px-4">{getStatusBadge(folder.status)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-6">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
|
||||
{filteredFolders.map((folder) => (
|
||||
<div
|
||||
key={folder.id}
|
||||
className={`relative group border rounded-lg p-6 hover:shadow-md transition-shadow cursor-pointer ${selectedFolders.includes(folder.id)
|
||||
? "bg-blue-900 border-blue-700"
|
||||
: "bg-gray-800 border-gray-700"
|
||||
}`}
|
||||
onClick={() => handleOpenFolder(folder)}
|
||||
>
|
||||
<div className="absolute top-4 left-4" onClick={(e) => e.stopPropagation()}>
|
||||
<Checkbox
|
||||
checked={selectedFolders.includes(folder.id)}
|
||||
onCheckedChange={() => toggleFolderSelection(folder.id)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="absolute top-4 right-4 flex items-center space-x-1"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{isNewFolder(folder) && (
|
||||
<Badge className="bg-blue-700 text-blue-100 border-blue-600">NEW</Badge>
|
||||
)}
|
||||
{folder.access === "private" && <Lock className="h-4 w-4 text-gray-400" />}
|
||||
{folder.storageType === "temporary" && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleStorageConfig(folder)}
|
||||
className="h-8 w-8 p-0"
|
||||
title="Configurer le stockage temporaire"
|
||||
>
|
||||
<Timer className="h-4 w-4 text-gray-100" />
|
||||
</Button>
|
||||
)}
|
||||
{folder.status === "validated" && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleDownloadCertificate(folder)}
|
||||
className="h-8 w-8 p-0"
|
||||
title="Télécharger le certificat blockchain"
|
||||
>
|
||||
<ShieldCheck className="h-4 w-4 text-green-400" />
|
||||
</Button>
|
||||
)}
|
||||
{folder.documents && folder.documents.some((doc) => doc.hasCertificate) && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleViewDocumentsCertificates(folder)}
|
||||
className="h-8 w-8 p-0"
|
||||
title="Certificats des documents"
|
||||
>
|
||||
<FileCheck className="h-4 w-4 text-blue-400" />
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleManageRoles(folder)}
|
||||
className="h-8 w-8 p-0"
|
||||
title="Gérer les rôles"
|
||||
>
|
||||
<Users className="h-4 w-4 text-gray-100" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center space-y-4 mt-8">
|
||||
<div className={`p-4 rounded-xl ${getFolderColor(folder.color)}`}>
|
||||
<Folder className="h-12 w-12 text-gray-100" />
|
||||
</div>
|
||||
|
||||
<div className="text-center space-y-2 w-full">
|
||||
<h3
|
||||
className="font-semibold text-gray-100 text-lg truncate"
|
||||
title={folder.name}
|
||||
>
|
||||
{folder.name}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-400 line-clamp-2">{folder.description}</p>
|
||||
|
||||
<div className="text-xs text-gray-400">
|
||||
<p>{folder.size}</p>
|
||||
<p>{formatDate(folder.modified)}</p>
|
||||
<div className="flex items-center justify-center space-x-1 mt-1">
|
||||
{getStorageIcon(folder.storageType)}
|
||||
<span>{folder.storageType === "permanent" ? "Permanent" : "Temporaire"}</span>
|
||||
</div>
|
||||
{folder.temporaryStorageConfig && folder.storageType === "temporary" && (
|
||||
<div className="text-xs text-blue-400 mt-1">
|
||||
Durée: {folder.temporaryStorageConfig.duration} jours
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center">{getStatusBadge(folder.status)}</div>
|
||||
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={
|
||||
folder.access === "shared"
|
||||
? "bg-green-700 text-green-100 border-green-600"
|
||||
: "bg-orange-700 text-orange-100 border-orange-600"
|
||||
}
|
||||
>
|
||||
{folder.access === "shared" ? "Partagé" : "Privé"}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Recent Activity */}
|
||||
<div className="mt-4 pt-4 border-t border-gray-700">
|
||||
<h4 className="text-xs font-medium text-gray-300 mb-2">Activité récente</h4>
|
||||
<div className="space-y-1">
|
||||
{folder.activity.slice(0, 2).map((activity, index) => (
|
||||
<div key={index} className="text-xs text-gray-400">
|
||||
<span className="font-medium">{activity.user}</span> a {activity.action}{" "}
|
||||
<span className="font-medium">{activity.item}</span>
|
||||
<div className="text-gray-500">{activity.time}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loadingFolders && isConnected && (
|
||||
<div className="text-center py-12">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
|
||||
<h3 className="text-lg font-medium text-gray-100 mb-2">Chargement des dossiers...</h3>
|
||||
<p className="text-gray-400">Récupération des données privées depuis 4NK</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!loadingFolders && filteredFolders.length === 0 && (
|
||||
<div className="text-center py-12">
|
||||
<Folder className="h-12 w-12 mx-auto text-gray-500 mb-4" />
|
||||
<h3 className="text-lg font-medium text-gray-100 mb-2">Aucun dossier trouvé</h3>
|
||||
<p className="text-gray-400 mb-4">
|
||||
{searchTerm || filterAccess !== "all" || filterOwner !== "all" || filterStorage !== "all"
|
||||
? "Essayez de modifier vos critères de recherche"
|
||||
: "Commencez par créer votre premier dossier"}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* ProcessesViewer Card */}
|
||||
<Card className="mt-6 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700">
|
||||
<CardContent className="p-4">
|
||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">Processus Blockchain</h3>
|
||||
|
||||
{/* Intégration du ProcessesViewer */}
|
||||
<div className="w-full h-[500px]">
|
||||
<ProcessesViewer
|
||||
processes={processes}
|
||||
myProcesses={myProcesses}
|
||||
onProcessesUpdate={setProcesses}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{/* Modals */}
|
||||
{actionModal.type && (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||
<div className="bg-gray-900 text-gray-100 rounded-lg p-6 w-full max-w-4xl mx-4 max-h-[90vh] overflow-y-auto">
|
||||
{/* Documents Certificates Modal */}
|
||||
{actionModal.type === "documents_certificates" && actionModal.folder && (
|
||||
<>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-lg font-semibold text-gray-100">
|
||||
Certificats des documents - {actionModal.folder.name}
|
||||
</h3>
|
||||
{/* Content */}
|
||||
<div className="flex-1 p-6 bg-gray-900">
|
||||
{loadingFolders ? (
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4"></div>
|
||||
<p className="text-gray-400">Chargement des dossiers...</p>
|
||||
</div>
|
||||
</div>
|
||||
) : sortedFolders.length === 0 ? (
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<div className="text-center">
|
||||
<Folder className="h-12 w-12 text-gray-400 mx-auto mb-4" />
|
||||
<h3 className="text-lg font-medium text-gray-100 mb-2">Aucun dossier</h3>
|
||||
<p className="text-gray-400 mb-4">
|
||||
{searchTerm ? "Aucun dossier ne correspond à votre recherche." : "Commencez par créer votre premier dossier."}
|
||||
</p>
|
||||
{!searchTerm && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setActionModal({ type: null, folder: null, folders: [] })}
|
||||
onClick={() => handleOpenModal("autre")}
|
||||
disabled={!isConnected}
|
||||
>
|
||||
<X className="h-4 w-4 text-gray-100" />
|
||||
<FolderPlus className="h-4 w-4 mr-2" />
|
||||
Créer un dossier
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user