Simplify and clean up unused UI

This commit is contained in:
omaroughriss 2025-10-23 16:44:22 +02:00
parent eaf5b653e9
commit 085713400c

View File

@ -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>