From 9f54cc1519d97526e559d9fe89436326d5c3683a Mon Sep 17 00:00:00 2001 From: Esenjin Date: Wed, 15 Jan 2025 18:02:24 +0100 Subject: [PATCH] =?UTF-8?q?am=C3=A9lioration=20de=20la=20liste=20des=20fic?= =?UTF-8?q?hiers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin.php | 257 ++++++++++++++++++++++++++++++++++---------------- core.php | 62 +++++++++++- css/style.css | 204 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 436 insertions(+), 87 deletions(-) diff --git a/admin.php b/admin.php index 3bc3e7a..0e197a2 100644 --- a/admin.php +++ b/admin.php @@ -240,103 +240,196 @@ ob_start(); ?> } -
-

Fichiers hébergés

- -

Aucun fichier hébergé

- -
- -
-
- - <?php echo Cyla::escape($file['name']); ?> - -
- -
- -
- -
-

-

- Ko - · -

-
- Voir - + + +
+

Fichiers hébergés

+ + +

Aucun fichier hébergé

+ +
+

+ +

+
+ +
+ +
+
+ + <?php echo Cyla::escape($file['name']); ?> + +
+
+ +
+ +
+

+

+ Ko + · +

+
+ Voir + +
- +
+ + + + +
+ + 1): ?> + -
+
- - -
diff --git a/core.php b/core.php index ba1ec29..3a71f22 100644 --- a/core.php +++ b/core.php @@ -131,12 +131,30 @@ class Cyla { } /** - * Liste les fichiers uploadés - * @return array + * Liste les fichiers uploadés avec pagination + * @param int $page Numéro de la page (commence à 1) + * @param int $perPage Nombre d'éléments par page + * @return array ['files' => array, 'total' => int, 'totalPages' => int] */ - public static function listFiles() { + public static function listFiles($page = 1, $perPage = 20) { $files = []; - foreach (glob(UPLOAD_DIR . '*') as $file) { + $allFiles = glob(UPLOAD_DIR . '*'); + + // Trier les fichiers par date de modification (plus récent en premier) + usort($allFiles, function($a, $b) { + return filemtime($b) - filemtime($a); + }); + + // Calculer la pagination + $total = count($allFiles); + $totalPages = ceil($total / $perPage); + $page = max(1, min($page, $totalPages)); // Garantir que la page est dans les limites + $offset = ($page - 1) * $perPage; + + // Récupérer uniquement les fichiers de la page courante + $pageFiles = array_slice($allFiles, $offset, $perPage); + + foreach ($pageFiles as $file) { $info = pathinfo($file); $files[] = [ 'name' => basename($file), @@ -146,7 +164,41 @@ class Cyla { 'preview_type' => getPreviewType($info['extension']) ]; } - return $files; + + return [ + 'files' => $files, + 'total' => $total, + 'totalPages' => $totalPages, + 'currentPage' => $page, + 'perPage' => $perPage + ]; + } + /** + * Supprime un fichier + * @param string $filename Nom du fichier à supprimer + * @return array ['success' => bool, 'error' => string|null] + */ + public static function deleteFile($filename) { + $filepath = UPLOAD_DIR . $filename; + + // Vérifier que le fichier existe et est dans le dossier d'upload + if (!file_exists($filepath) || !is_file($filepath)) { + return ['success' => false, 'error' => 'Fichier introuvable']; + } + + // Vérifier que le fichier est bien dans le dossier d'upload + $realpath = realpath($filepath); + $uploadDir = realpath(UPLOAD_DIR); + if (strpos($realpath, $uploadDir) !== 0) { + return ['success' => false, 'error' => 'Chemin de fichier non autorisé']; + } + + // Supprimer le fichier + if (unlink($filepath)) { + return ['success' => true]; + } else { + return ['success' => false, 'error' => 'Erreur lors de la suppression du fichier']; + } } } diff --git a/css/style.css b/css/style.css index 63408f3..389001f 100644 --- a/css/style.css +++ b/css/style.css @@ -386,4 +386,208 @@ footer { opacity: 1; transform: scale(1) translateY(0); } +} + +/* Styles spécifiques à la page d'administration */ +.admin-container { + display: flex; + flex-direction: column; + gap: var(--spacing-lg); +} + +.admin-container h2 { + color: var(--color-primary); + margin-bottom: var(--spacing-md); +} + +.help-text { + font-size: 0.9rem; + color: var(--color-text-muted); + margin-top: var(--spacing-xs); +} + +.preview-placeholder { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-bg); + color: var(--color-text-muted); + font-size: 2rem; + font-weight: bold; +} + +.file-name { + font-weight: bold; + word-break: break-all; +} + +.file-meta { + font-size: 0.9rem; + color: var(--color-text-muted); + margin: var(--spacing-xs) 0; +} + +.file-actions { + display: flex; + gap: var(--spacing-sm); + margin-top: var(--spacing-sm); +} + + +/* Styles pour la pagination et l'affichage des fichiers */ +.files-header { + margin-bottom: var(--spacing-md); + color: var(--color-text-muted); +} + +.files-count { + font-size: 0.9rem; +} + +.pagination { + display: flex; + justify-content: center; + align-items: center; + gap: var(--spacing-sm); + margin-top: var(--spacing-lg); + padding-top: var(--spacing-md); + border-top: 1px solid var(--color-border); +} + +.pagination-link { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 2rem; + height: 2rem; + padding: 0 var(--spacing-sm); + color: var(--color-text); + text-decoration: none; + background-color: var(--color-bg); + border: 1px solid var(--color-border); + border-radius: var(--border-radius); + transition: all 0.2s ease; +} + +.pagination-link:hover { + background-color: var(--color-border); +} + +.pagination-active { + background-color: var(--color-primary); + border-color: var(--color-primary); + color: var(--color-text); +} + +.pagination-ellipsis { + color: var(--color-text-muted); + padding: 0 var(--spacing-xs); +} + +/* Bouton de suppression */ +.btn-danger { + background-color: var(--color-accent); + width: 2.5rem; + height: 2.5rem; + padding: 0; + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + line-height: 1; +} + +.btn-danger:hover { + background-color: #a85651; +} + +/* Boîte de dialogue de confirmation */ +.confirmation-dialog { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: var(--color-bg-alt); + border: 1px solid var(--color-border); + border-radius: var(--border-radius); + padding: var(--spacing-lg); + max-width: 400px; + width: 90%; + z-index: 1000; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.confirmation-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + z-index: 999; +} + +.confirmation-dialog h3 { + color: var(--color-primary); + margin-bottom: var(--spacing-md); +} + +.confirmation-dialog p { + margin-bottom: var(--spacing-lg); +} + +.confirmation-actions { + display: flex; + gap: var(--spacing-sm); + justify-content: flex-end; +} + +.confirmation-actions .btn { + min-width: 100px; + padding: var(--spacing-sm) var(--spacing-md); +} + +/* Responsive */ +@media (max-width: 768px) { + .pagination { + flex-wrap: wrap; + } + + .file-actions { + flex-wrap: wrap; + } + + .btn-danger { + width: 100%; + } +} + +/* Styles de notification */ +.notification { + position: fixed; + bottom: var(--spacing-lg); + right: var(--spacing-lg); + background-color: var(--color-success); + color: white; + padding: var(--spacing-md) var(--spacing-lg); + border-radius: var(--border-radius); + animation: slideIn 0.3s ease-out, fadeOut 0.3s ease-in 2.7s forwards; + z-index: 1000; + pointer-events: none; +} + +.notification.error { + background-color: var(--color-error); +} + +@keyframes slideIn { + from { transform: translateY(100%); opacity: 0; } + to { transform: translateY(0); opacity: 1; } +} + +@keyframes fadeOut { + from { opacity: 1; } + to { opacity: 0; } } \ No newline at end of file