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>
|
<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>
|
<p className="text-sm text-gray-400 mt-1">Gérez vos dossiers 4NK</p>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
) : (
|
</div>
|
||||||
<Button variant="outline" size="sm" onClick={handleLogin}>
|
</div>
|
||||||
<Shield className="h-4 w-4 mr-2" />
|
|
||||||
Connexion 4NK
|
{/* 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>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Breadcrumb */}
|
{/* Main Content */}
|
||||||
<div className="flex items-center space-x-2 text-sm text-gray-400">
|
<div className="flex-1 flex flex-col">
|
||||||
{currentPath.map((path, index) => (
|
{/* Header */}
|
||||||
<div key={index} className="flex items-center space-x-2">
|
<div className="bg-gray-800 border-b border-gray-700 p-6">
|
||||||
{index > 0 && <ChevronRight className="h-4 w-4 text-gray-400" />}
|
<div className="flex items-center justify-between mb-4">
|
||||||
<button
|
<div className="flex items-center space-x-2">
|
||||||
className={`hover:text-gray-100 ${index === currentPath.length - 1 ? "font-medium text-gray-100" : ""}`}
|
{currentPath.map((path, index) => (
|
||||||
onClick={() => setCurrentPath(currentPath.slice(0, index + 1))}
|
<div key={index} className="flex items-center">
|
||||||
>
|
{index > 0 && <ChevronRight className="h-4 w-4 text-gray-400 mx-1" />}
|
||||||
{path}
|
<span className="text-sm text-gray-300">{path}</span>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
{/* 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">
|
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
onClick={() => handleOpenModal("autre")}
|
||||||
onClick={() => setShowFilters(!showFilters)}
|
disabled={!isConnected}
|
||||||
className={showFilters ? "bg-blue-700 text-white border-blue-600" : ""}
|
className="flex items-center space-x-2"
|
||||||
>
|
>
|
||||||
<Filter className="h-4 w-4 mr-2 text-gray-100" />
|
<FolderPlus className="h-4 w-4" />
|
||||||
Filtres
|
<span>Nouveau dossier</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
{/* Advanced Filters */}
|
{/* Search and filters */}
|
||||||
{showFilters && (
|
<div className="flex items-center space-x-4">
|
||||||
<div className="mt-4 pt-4 border-t border-gray-700">
|
<div className="flex-1 relative">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
|
||||||
<div>
|
<Input
|
||||||
<Label htmlFor="filterAccess" className="text-sm font-medium text-gray-300">
|
placeholder="Rechercher des dossiers..."
|
||||||
Accès
|
value={searchTerm}
|
||||||
</Label>
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
<Select value={filterAccess} onValueChange={setFilterAccess}>
|
className="pl-10"
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</CardContent>
|
<div className="flex items-center space-x-2">
|
||||||
</Card>
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
{/* Bulk Actions minimalistes: certificats et rôles uniquement */}
|
onClick={() => setSortOrder(sortOrder === "asc" ? "desc" : "asc")}
|
||||||
{selectedFolders.length > 0 && (
|
>
|
||||||
<Card className="bg-gray-800 border-gray-700 text-gray-100">
|
{sortOrder === "asc" ? <SortAsc className="h-4 w-4" /> : <SortDesc className="h-4 w-4" />}
|
||||||
<CardContent className="p-4">
|
</Button>
|
||||||
<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>
|
</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>
|
</div>
|
||||||
</CardContent>
|
</div>
|
||||||
</Card>
|
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
<div className="flex-1 p-6 bg-gray-900">
|
||||||
{/* Modals */}
|
{loadingFolders ? (
|
||||||
{actionModal.type && (
|
<div className="flex items-center justify-center h-64">
|
||||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
<div className="text-center">
|
||||||
<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">
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4"></div>
|
||||||
{/* Documents Certificates Modal */}
|
<p className="text-gray-400">Chargement des dossiers...</p>
|
||||||
{actionModal.type === "documents_certificates" && actionModal.folder && (
|
</div>
|
||||||
<>
|
</div>
|
||||||
<div className="flex items-center justify-between mb-4">
|
) : sortedFolders.length === 0 ? (
|
||||||
<h3 className="text-lg font-semibold text-gray-100">
|
<div className="flex items-center justify-center h-64">
|
||||||
Certificats des documents - {actionModal.folder.name}
|
<div className="text-center">
|
||||||
</h3>
|
<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
|
<Button
|
||||||
variant="ghost"
|
onClick={() => handleOpenModal("autre")}
|
||||||
size="sm"
|
disabled={!isConnected}
|
||||||
onClick={() => setActionModal({ type: null, folder: null, folders: [] })}
|
|
||||||
>
|
>
|
||||||
<X className="h-4 w-4 text-gray-100" />
|
<FolderPlus className="h-4 w-4 mr-2" />
|
||||||
|
Créer un dossier
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user