<!DOCTYPE html><html lang="fr">
<meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0">Gestionnaire de Fichiers - Client uniquement <title>Gestionnaire de Fichiers - Client uniquement</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f5f5f5; color: #333; line-height: 1.6; } .container { max-width: 1200px; margin: 0 auto; padding: 20px; } header { background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); color: white; padding: 20px 0; text-align: center; border-radius: 10px; margin-bottom: 30px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } h1 { font-size: 2.5rem; margin-bottom: 10px; } .subtitle { font-size: 1.1rem; opacity: 0.9; } .main-content { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; } @media (max-width: 768px) { .main-content { grid-template-columns: 1fr; } } .card { background: white; border-radius: 10px; padding: 25px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); transition: transform 0.3s ease; } .card:hover { transform: translateY(-5px); } .card h2 { color: #2575fc; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 2px solid #f0f0f0; } .upload-area { border: 2px dashed #6a11cb; border-radius: 8px; padding: 30px; text-align: center; margin-bottom: 20px; transition: all 0.3s ease; cursor: pointer; } .upload-area:hover { background-color: #f9f7ff; border-color: #2575fc; } .upload-area i { font-size: 48px; color: #6a11cb; margin-bottom: 15px; } .upload-area p { margin-bottom: 15px; color: #666; } .btn { display: inline-block; background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); color: white; padding: 12px 25px; border: none; border-radius: 5px; cursor: pointer; font-size: 1rem; font-weight: 600; transition: all 0.3s ease; text-decoration: none; } .btn:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); } .btn-secondary { background: #f0f0f0; color: #333; } .btn-secondary:hover { background: #e0e0e0; } .file-list { list-style: none; max-height: 400px; overflow-y: auto; } .file-item { display: flex; justify-content: space-between; align-items: center; padding: 12px 15px; border-bottom: 1px solid #f0f0f0; transition: background-color 0.2s; } .file-item:hover { background-color: #f9f9f9; } .file-info { display: flex; align-items: center; } .file-icon { margin-right: 10px; color: #6a11cb; } .file-name { font-weight: 500; } .file-size { color: #888; font-size: 0.9rem; } .file-actions { display: flex; gap: 10px; } .action-btn { background: none; border: none; cursor: pointer; color: #666; font-size: 1.1rem; transition: color 0.2s; } .action-btn:hover { color: #2575fc; } .path-info { background-color: #f0f7ff; padding: 15px; border-radius: 8px; margin-bottom: 20px; font-family: monospace; word-break: break-all; } .alert { padding: 15px; border-radius: 5px; margin-bottom: 20px; display: none; } .alert-success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; } .alert-error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; } .progress-bar { height: 6px; background-color: #e0e0e0; border-radius: 3px; margin-top: 10px; overflow: hidden; display: none; } .progress { height: 100%; background: linear-gradient(90deg, #6a11cb 0%, #2575fc 100%); width: 0%; transition: width 0.3s ease; } footer { text-align: center; margin-top: 40px; padding: 20px; color: #666; font-size: 0.9rem; } .storage-info { background-color: #f0f7ff; padding: 15px; border-radius: 8px; margin-top: 20px; text-align: center; } .storage-bar { height: 10px; background-color: #e0e0e0; border-radius: 5px; margin-top: 10px; overflow: hidden; } .storage-used { height: 100%; background: linear-gradient(90deg, #6a11cb 0%, #2575fc 100%); width: 0%; transition: width 0.5s ease; } </style> <div class="container"> <header> Gestionnaire de Fichiers <p class="subtitle">Visualisez et gérez les fichiers de votre site web (Client uniquement)</p> </header> <div class="alert alert-success" id="successAlert"> Fichier téléchargé avec succès! </div> <div class="alert alert-error" id="errorAlert"> Erreur lors du téléchargement du fichier. </div> <div class="main-content"> <div class="card"> Télécharger un fichier <div class="upload-area" id="dropArea"> <i>📁</i> <p>Glissez-déposez vos fichiers ici ou cliquez pour sélectionner</p> <button class="btn" id="browseBtn">Parcourir</button> </div> <div class="progress-bar" id="progressBar"> <div class="progress" id="progress"></div> </div> <div style="margin-top: 20px;"> <button class="btn" id="uploadBtn" disabled>Télécharger</button> <button class="btn btn-secondary" id="clearBtn">Effacer</button> </div> <div class="storage-info"> <p>Espace de stockage utilisé: <span id="storageUsed">0 KB</span> / <span id="storageTotal">5 MB</span></p> <div class="storage-bar"> <div class="storage-used" id="storageBar"></div> </div> </div> </div> <div class="card"> Fichiers du site <div class="path-info"> Répertoire actuel: <span id="currentPath">/</span> </div> <ul class="file-list" id="fileList"> <!-- Les fichiers seront affichés ici par JavaScript --> </ul> <div style="margin-top: 20px; text-align: center;"> <button class="btn btn-secondary" id="refreshBtn">Actualiser la liste</button> <button class="btn btn-secondary" id="clearStorageBtn">Vider le stockage</button> </div> </div> </div> <footer> <p>Gestionnaire de fichiers © 2023 - Fonctionne entièrement côté client</p> </footer> </div> <script> // Éléments DOM const fileInput = document.getElementById('fileInput'); const browseBtn = document.getElementById('browseBtn'); const dropArea = document.getElementById('dropArea'); const uploadBtn = document.getElementById('uploadBtn'); const clearBtn = document.getElementById('clearBtn'); const refreshBtn = document.getElementById('refreshBtn'); const clearStorageBtn = document.getElementById('clearStorageBtn'); const progressBar = document.getElementById('progressBar'); const progress = document.getElementById('progress'); const successAlert = document.getElementById('successAlert'); const errorAlert = document.getElementById('errorAlert'); const fileList = document.getElementById('fileList'); const currentPath = document.getElementById('currentPath'); const storageUsed = document.getElementById('storageUsed'); const storageTotal = document.getElementById('storageTotal'); const storageBar = document.getElementById('storageBar'); let selectedFile = null; const MAX_STORAGE = 5 * 1024 * 1024; // 5 MB en bytes // Initialisation document.addEventListener('DOMContentLoaded', function() { loadFiles(); updateStorageInfo(); }); // Événements browseBtn.addEventListener('click', () => fileInput.click()); fileInput.addEventListener('change', (e) => { selectedFile = e.target.files[0]; updateUI(); }); dropArea.addEventListener('dragover', (e) => { e.preventDefault(); dropArea.style.borderColor = '#2575fc'; dropArea.style.backgroundColor = '#f0f7ff'; }); dropArea.addEventListener('dragleave', () => { dropArea.style.borderColor = '#6a11cb'; dropArea.style.backgroundColor = ''; }); dropArea.addEventListener('drop', (e) => { e.preventDefault(); dropArea.style.borderColor = '#6a11cb'; dropArea.style.backgroundColor = ''; if (e.dataTransfer.files.length) { selectedFile = e.dataTransfer.files[0]; fileInput.files = e.dataTransfer.files; updateUI(); } }); uploadBtn.addEventListener('click', uploadFile); clearBtn.addEventListener('click', clearSelection); refreshBtn.addEventListener('click', loadFiles); clearStorageBtn.addEventListener('click', clearStorage); // Fonctions function updateUI() { if (selectedFile) { uploadBtn.disabled = false; dropArea.innerHTML = ` <i>📄</i> <p><strong>${selectedFile.name}</strong></p> <p>Taille: ${formatFileSize(selectedFile.size)}</p> `; } else { uploadBtn.disabled = true; dropArea.innerHTML = ` <i>📁</i> <p>Glissez-déposez vos fichiers ici ou cliquez pour sélectionner</p> <button class="btn" id="browseBtn">Parcourir</button> `; document.getElementById('browseBtn').addEventListener('click', () => fileInput.click()); } } function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } function uploadFile() { if (!selectedFile) return; // Vérifier la taille du fichier if (selectedFile.size > MAX_STORAGE) { errorAlert.textContent = "Le fichier est trop volumineux (max 5 MB)"; showAlert(errorAlert); return; } // Vérifier l'espace disponible const currentStorage = getUsedStorage(); if (currentStorage + selectedFile.size > MAX_STORAGE) { errorAlert.textContent = "Espace de stockage insuffisant"; showAlert(errorAlert); return; } progressBar.style.display = 'block'; progress.style.width = '0%'; // Simuler l'upload avec une progression let progressValue = 0; const progressInterval = setInterval(() => { progressValue += 5; progress.style.width = progressValue + '%'; if (progressValue >= 100) { clearInterval(progressInterval); saveFile(selectedFile); progressBar.style.display = 'none'; showAlert(successAlert); clearSelection(); loadFiles(); updateStorageInfo(); } }, 50); } function saveFile(file) { // Récupérer les fichiers existants const files = JSON.parse(localStorage.getItem('siteFiles') || '[]'); // Vérifier si le fichier existe déjà const existingFileIndex = files.findIndex(f => f.name === file.name); // Lire le fichier comme Data URL const reader = new FileReader(); reader.onload = function(e) { if (existingFileIndex !== -1) { // Remplacer le fichier existant files[existingFileIndex] = { name: file.name, size: file.size, type: file.type, data: e.target.result, lastModified: new Date().toISOString() }; } else { // Ajouter le nouveau fichier files.push({ name: file.name, size: file.size, type: file.type, data: e.target.result, lastModified: new Date().toISOString() }); } // Sauvegarder dans le localStorage localStorage.setItem('siteFiles', JSON.stringify(files)); }; reader.readAsDataURL(file); } function loadFiles() { fileList.innerHTML = '<li class="file-item">Chargement...</li>'; setTimeout(() => { const files = JSON.parse(localStorage.getItem('siteFiles') || '[]'); displayFiles(files); }, 500); } function displayFiles(files) { fileList.innerHTML = ''; if (files.length === 0) { fileList.innerHTML = '<li class="file-item">Aucun fichier trouvé</li>'; return; } files.forEach((file, index) => { const li = document.createElement('li'); li.className = 'file-item'; const icon = getFileIcon(file.type); li.innerHTML = ` <div class="file-info"> <span class="file-icon">${icon}</span> <span class="file-name">${file.name}</span> </div> <div class="file-details"> <span class="file-size">${formatFileSize(file.size)}</span> <div class="file-actions"> <button class="action-btn download-btn" title="Télécharger" data-index="${index}">⬇️</button> <button class="action-btn delete-btn" title="Supprimer" data-index="${index}">🗑️</button> </div> </div> `; fileList.appendChild(li); }); // Ajouter les événements aux boutons document.querySelectorAll('.download-btn').forEach(btn => { btn.addEventListener('click', function() { downloadFile(parseInt(this.getAttribute('data-index'))); }); }); document.querySelectorAll('.delete-btn').forEach(btn => { btn.addEventListener('click', function() { deleteFile(parseInt(this.getAttribute('data-index'))); }); }); } function downloadFile(index) { const files = JSON.parse(localStorage.getItem('siteFiles') || '[]'); if (index >= 0 && index < files.length) { const file = files[index]; // Créer un lien de téléchargement const a = document.createElement('a'); a.href = file.data; a.download = file.name; document.body.appendChild(a); a.click(); document.body.removeChild(a); } } function deleteFile(index) { const files = JSON.parse(localStorage.getItem('siteFiles') || '[]'); if (index >= 0 && index < files.length) { if (confirm(`Êtes-vous sûr de vouloir supprimer "${files[index].name}" ?`)) { files.splice(index, 1); localStorage.setItem('siteFiles', JSON.stringify(files)); loadFiles(); updateStorageInfo(); showAlert(successAlert, "Fichier supprimé avec succès"); } } } function getFileIcon(type) { const icons = { 'text/html': '🌐', 'text/css': '🎨', 'application/javascript': '⚙️', 'image/jpeg': '🖼️', 'image/png': '🖼️', 'image/gif': '🖼️', 'application/pdf': '📄', 'default': '📁' }; return icons[type] || icons.default; } function clearSelection() { selectedFile = null; fileInput.value = ''; updateUI(); } function showAlert(alertElement, message = null) { if (message) { alertElement.textContent = message; } alertElement.style.display = 'block'; setTimeout(() => { alertElement.style.display = 'none'; }, 5000); } function getUsedStorage() { const files = JSON.parse(localStorage.getItem('siteFiles') || '[]'); return files.reduce((total, file) => total + file.size, 0); } function updateStorageInfo() { const used = getUsedStorage(); storageUsed.textContent = formatFileSize(used); storageTotal.textContent = formatFileSize(MAX_STORAGE); const percentage = (used / MAX_STORAGE) * 100; storageBar.style.width = percentage + '%'; } function clearStorage() { if (confirm("Êtes-vous sûr de vouloir supprimer tous les fichiers ? Cette action est irréversible.")) { localStorage.removeItem('siteFiles'); loadFiles(); updateStorageInfo(); showAlert(successAlert, "Tous les fichiers ont été supprimés"); } } </script>