document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.file-size').forEach(function(element) { const size = parseInt(element.getAttribute('data-size')); element.textContent = formatFileSize(size); }); document.getElementById('searchButton').addEventListener('click', searchFiles); document.getElementById('newFolderBtn').addEventListener('click', showNewFolderModal); document.querySelectorAll('.delete-folder-button').forEach(button => { button.addEventListener('click', function() { const folderName = this.getAttribute('data-folder-name'); confirmDeleteFolder(folderName); }); }); document.querySelectorAll('.delete-file-button').forEach(button => { button.addEventListener('click', function() { const fileName = this.getAttribute('data-file-name'); confirmDelete(fileName); }); }); document.querySelectorAll('.copy-button').forEach(button => { button.addEventListener('click', function() { const fileUrl = this.getAttribute('data-file-url'); copyFileLink(fileUrl); }); }); document.querySelectorAll('.rename-file-btn').forEach(button => { button.addEventListener('click', function() { const fileName = this.getAttribute('data-file-name'); const folderName = this.getAttribute('data-folder-name'); renameFile(folderName, fileName); }); }); document.querySelectorAll('.move-file-btn').forEach(button => { button.addEventListener('click', function() { const fileName = this.getAttribute('data-file-name'); showMoveFileModal(fileName); }); }); document.getElementById('confirmMoveFile').addEventListener('click', moveFile); document.getElementById('themeSwitcher').addEventListener('click', toggleDarkMode); initTheme(); document.addEventListener('DOMContentLoaded', function () { const accountDropdownBtn = document.getElementById('accountDropdownBtn'); const accountDropdownMenu = document.getElementById('accountDropdownMenu'); accountDropdownBtn.addEventListener('click', function (e) { e.stopPropagation(); accountDropdownMenu.classList.toggle('show'); }); document.addEventListener('click', function (e) { if (!accountDropdownBtn.contains(e.target) && !accountDropdownMenu.contains(e.target)) { accountDropdownMenu.classList.remove('show'); } }); }); $('.modal').modal({ show: false }); const metadataLink = document.querySelector('a[onclick="displayMetadata()"]'); if (metadataLink) { metadataLink.addEventListener('click', function(event) { event.preventDefault(); displayMetadata(); }); } document.querySelectorAll('[onclick^="showFileInfo"]').forEach(link => { link.addEventListener('click', function(event) { event.preventDefault(); const fileName = this.getAttribute('onclick').match(/'([^']+)'/)[1]; showFileInfo(fileName); }); }); }); function formatFileSize(fileSizeInBytes) { if (fileSizeInBytes < 1024) return fileSizeInBytes + ' octets'; else if (fileSizeInBytes < 1048576) return (fileSizeInBytes / 1024).toFixed(2) + ' Ko'; else if (fileSizeInBytes < 1073741824) return (fileSizeInBytes / 1048576).toFixed(2) + ' Mo'; else return (fileSizeInBytes / 1073741824).toFixed(2) + ' Go'; } function searchFiles() { const input = document.getElementById('searchInput'); const filter = input.value.toUpperCase(); const table = document.getElementById('fileTable'); const tr = table.getElementsByTagName('tr'); for (let i = 1; i < tr.length; i++) { const td = tr[i].getElementsByTagName('td')[0]; if (td) { const txtValue = td.textContent || td.innerText; if (txtValue.toUpperCase().indexOf(filter) > -1) { tr[i].style.display = ""; } else { tr[i].style.display = "none"; } } } } function showNewFolderModal() { Swal.fire({ title: 'Nouveau dossier', input: 'text', inputPlaceholder: 'Entrer le nom du nouveau dossier', confirmButtonText: 'Créer', showCancelButton: true, cancelButtonText: 'Annuler', preConfirm: (folderName) => { if (!folderName) { Swal.showValidationMessage('Le nom du dossier ne peut pas être vide.'); } return folderName; } }).then(result => { if (result.isConfirmed) { createNewFolder(result.value); } }); } function createNewFolder(folderName) { fetch('/api/dpanel/dashboard/newfolder', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ folderName }), }) .then(response => { if (response.ok) { return response.json(); } else { return response.json().then(error => Promise.reject(error)); } }) .then(result => { Swal.fire({ position: 'top', icon: 'success', title: 'Le dossier a été créé avec succès.', showConfirmButton: false, timer: 2000, toast: true }).then(() => { location.reload(); }); }) .catch(error => { Swal.fire({ position: 'top', icon: 'error', title: 'Erreur lors de la création du dossier.', text: error.message, showConfirmButton: false, timer: 2350, toast: true }); }); } function confirmDeleteFolder(folderName) { Swal.fire({ title: 'Êtes-vous sûr?', text: `La suppression du dossier "${folderName}" est irréversible!`, icon: 'warning', showCancelButton: true, confirmButtonColor: '#d33', cancelButtonColor: '#3085d6', confirmButtonText: 'Supprimer', cancelButtonText: 'Annuler', }).then((result) => { if (result.isConfirmed) { deleteFolder(folderName); } }); } function deleteFolder(folderName) { fetch(`/api/dpanel/dashboard/deletefolder/${folderName}`, { method: 'DELETE', }) .then(response => { if (response.ok) { Swal.fire({ position: 'top', icon: 'success', title: 'Le dossier a été supprimé avec succès.', showConfirmButton: false, timer: 1800, toast: true }).then(() => { location.reload(); }); } else { throw new Error('La suppression du dossier a échoué'); } }) .catch(error => { Swal.fire({ position: 'top', icon: 'error', title: error.message, showConfirmButton: false, timer: 1800, toast: true }); }); } function confirmDelete(filename) { Swal.fire({ title: 'Êtes-vous sûr de vouloir supprimer ce fichier?', text: 'Cette action est irréversible!', icon: 'warning', showCancelButton: true, confirmButtonColor: '#d33', cancelButtonColor: '#3085d6', confirmButtonText: 'Supprimer' }).then((result) => { if (result.isConfirmed) { deleteFile(filename); } }); } function deleteFile(filename) { fetch('/api/dpanel/dashboard/delete', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ filename: filename, }), }) .then(response => { if (response.ok) { Swal.fire({ position: 'top', icon: 'success', title: 'Le fichier a été supprimé avec succès.', showConfirmButton: false, timer: 1800, toast: true }).then(() => { location.reload(); }); } else { throw new Error('La suppression du fichier a échoué'); } }) .catch(error => { Swal.fire({ position: 'top', icon: 'error', title: error.message, showConfirmButton: false, timer: 1800, toast: true }); }); } function copyFileLink(fileUrl) { navigator.clipboard.writeText(fileUrl).then(() => { Swal.fire({ position: 'top', icon: 'success', title: 'Lien copié !', showConfirmButton: false, timer: 1500, toast: true }); }, (err) => { console.error('Erreur lors de la copie: ', err); }); } function renameFile(folderName, currentName) { Swal.fire({ title: 'Entrez le nouveau nom', input: 'text', inputValue: currentName, inputPlaceholder: 'Nouveau nom', showCancelButton: true, confirmButtonText: 'Renommer', cancelButtonText: 'Annuler', inputValidator: (value) => { if (!value) { return 'Vous devez entrer un nom de fichier'; } } }).then((result) => { if (result.isConfirmed) { const newName = result.value; fetch(`/api/dpanel/dashboard/rename/${folderName}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ currentName: currentName, newName: newName }), }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { Swal.fire({ position: 'top', icon: 'success', title: 'Le fichier a été renommé avec succès.', showConfirmButton: false, timer: 1800, toast: true, }).then(() => { location.reload(); }); }) .catch((error) => { Swal.fire({ position: 'top', icon: 'error', title: 'Erreur lors du renommage du fichier.', text: error.message, showConfirmButton: false, timer: 1800, toast: true, }); }); } }); } function showMoveFileModal(fileName) { document.getElementById('moveFileName').value = fileName; $('#moveFileModal').modal('show'); } function moveFile() { const fileName = document.getElementById('moveFileName').value; const folderName = document.getElementById('moveFolderSelect').value; fetch('/api/dpanel/dashboard/movefile', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ fileName: fileName, folderName: folderName }), }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { if (data.message === "File moved successfully") { Swal.fire({ position: 'top', icon: 'success', title: 'Le fichier a été déplacé avec succès.', showConfirmButton: false, timer: 1800, toast: true, }).then(() => { location.reload(); }); } else { throw new Error(data.error || 'Une erreur est survenue'); } }) .catch((error) => { Swal.fire({ position: 'top', icon: 'error', title: 'Erreur lors du déplacement du fichier.', text: error.message, showConfirmButton: false, timer: 1800, toast: true, }); }); $('#moveFileModal').modal('hide'); } const body = document.body; const themeSwitcher = document.getElementById('themeSwitcher'); function setTheme(theme) { if (theme === 'dark') { body.classList.add('dark'); } else { body.classList.remove('dark'); } localStorage.setItem('theme', theme); } const savedTheme = localStorage.getItem('theme'); if (savedTheme) { setTheme(savedTheme); } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { setTheme('dark'); } themeSwitcher.addEventListener('click', function() { if (body.classList.contains('dark')) { setTheme('light'); } else { setTheme('dark'); } }); async function showFileInfo(fileName) { try { const response = await fetch('/api/dpanel/dashboard/getmetadatafile/file_info', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ fileLink: fileName, }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); const fileInfo = data.find(file => file.fileName === fileName); if (!fileInfo) { throw new Error(`No information found for the file ${fileName}.`); } let html = `

Nom du fichier : ${fileInfo.fileName}

`; if (fileInfo.expiryDate) { html += `

Date d'expiration : ${fileInfo.expiryDate}

`; } if (fileInfo.password) { html += `

Mot de passe : Oui

`; } if (fileInfo.userId) { html += `

Utilisateur : ${fileInfo.userId}

`; } Swal.fire({ title: 'Informations sur le fichier', html: html, confirmButtonText: 'Fermer' }); } catch (error) { console.error('Error in showFileInfo:', error); Swal.fire({ position: 'top', icon: 'error', title: 'Les informations sur le fichier ne sont pas disponibles pour le moment.', text: `Erreur : ${error.message}`, showConfirmButton: false, timer: 1800, toast: true, }); } } function displayMetadata() { fetch('/build-metadata') .then(response => response.json()) .then(metadata => { document.getElementById('buildVersion').textContent = metadata.build_version; document.getElementById('nodeVersion').textContent = metadata.node_version; document.getElementById('expressVersion').textContent = metadata.express_version; document.getElementById('buildSha').textContent = metadata.build_sha; document.getElementById('osType').textContent = metadata.os_type; document.getElementById('osRelease').textContent = metadata.os_release; $('#metadataModal').modal('show'); }) .catch(error => { console.error('Failed to fetch metadata:', error); Swal.fire({ icon: 'error', title: 'Erreur', text: 'Impossible de récupérer les métadonnées' }); }); } document.addEventListener('DOMContentLoaded', () => { // Recherche avec debounce const searchInput = document.getElementById('searchInput'); if (searchInput) { let timeout; searchInput.addEventListener('input', (e) => { clearTimeout(timeout); timeout = setTimeout(() => { const term = e.target.value.toLowerCase(); document.querySelectorAll('#fileTable tbody tr').forEach(row => { const text = row.querySelector('td:first-child').textContent.toLowerCase(); row.style.display = text.includes(term) ? '' : 'none'; }); }, 150); }); } // Gestion des modales document.querySelectorAll('[data-toggle="modal"]').forEach(trigger => { trigger.addEventListener('click', () => { const modal = document.querySelector(trigger.dataset.target); if (modal) modal.classList.add('show'); }); }); document.querySelectorAll('.modal .close, .modal .btn-secondary').forEach(btn => { btn.addEventListener('click', () => { const modal = btn.closest('.modal'); if (modal) modal.classList.remove('show'); }); }); // Dropdowns document.querySelectorAll('.dropdown-toggle').forEach(toggle => { toggle.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); const menu = toggle.nextElementSibling; if (!menu) return; // Fermer les autres dropdowns document.querySelectorAll('.dropdown-menu.show').forEach(m => { if (m !== menu) m.classList.remove('show'); }); menu.classList.toggle('show'); }); }); // Fermer les dropdowns au clic extérieur document.addEventListener('click', () => { document.querySelectorAll('.dropdown-menu.show').forEach(menu => { menu.classList.remove('show'); }); }); }); // Loading overlay window.showLoadingState = () => { const overlay = document.createElement('div'); overlay.className = 'loading-overlay animate'; overlay.innerHTML = '
'; document.body.appendChild(overlay); }; window.hideLoadingState = () => { const overlay = document.querySelector('.loading-overlay'); if (overlay) overlay.remove(); }; // Gestion améliorée de l'état de chargement window.showLoadingState = () => { const overlay = document.createElement('div'); overlay.className = 'loading-overlay'; const wrapper = document.createElement('div'); wrapper.className = 'spinner-wrapper'; const spinner = document.createElement('div'); spinner.className = 'loading-spinner'; wrapper.appendChild(spinner); overlay.appendChild(wrapper); document.body.appendChild(overlay); // Force le reflow pour démarrer l'animation overlay.offsetHeight; overlay.classList.add('show'); }; window.hideLoadingState = () => { const overlay = document.querySelector('.loading-overlay'); if (overlay) { overlay.classList.remove('show'); overlay.addEventListener('transitionend', () => overlay.remove(), { once: true }); } }; // Animation des lignes du tableau document.addEventListener('DOMContentLoaded', () => { const tableRows = document.querySelectorAll('.table tr'); tableRows.forEach((row, index) => { row.style.setProperty('--row-index', index); requestAnimationFrame(() => row.classList.add('show')); }); // Animation du conteneur principal const mainContainer = document.querySelector('.form-container'); if (mainContainer) { requestAnimationFrame(() => mainContainer.classList.add('show')); } }); // Fonction pour les transitions de page function transitionToPage(url) { document.body.classList.add('page-transition'); showLoadingState(); setTimeout(() => { window.location.href = url; }, 300); } // Amélioration des modales function showModal(modalId) { const modal = document.querySelector(modalId); if (!modal) return; modal.style.display = 'flex'; requestAnimationFrame(() => { modal.classList.add('show'); modal.querySelector('.modal-content')?.classList.add('show'); }); } function hideModal(modalId) { const modal = document.querySelector(modalId); if (!modal) return; modal.querySelector('.modal-content')?.classList.remove('show'); modal.classList.remove('show'); modal.addEventListener('transitionend', () => { modal.style.display = 'none'; }, { once: true }); } // État de chargement des boutons function setButtonLoading(button, isLoading) { if (isLoading) { button.classList.add('loading'); button.dataset.originalText = button.innerHTML; button.innerHTML = ''; } else { button.classList.remove('loading'); if (button.dataset.originalText) { button.innerHTML = button.dataset.originalText; } } } function createLoadingScreen() { const container = document.createElement('div'); container.className = 'initial-loading'; const content = `

Vous y êtes presque !

Préparation de votre espace de travail...

Chargement des données

`; container.innerHTML = content; document.body.appendChild(container); return container; } function initializeLoadingScreen() { // Vérifier si c'est la première visite de la session const hasSeenAnimation = sessionStorage.getItem('hasSeenLoadingAnimation'); if (hasSeenAnimation) { // Si l'animation a déjà été vue, initialiser directement le contenu const contentWrapper = document.querySelector('.content-wrapper'); if (contentWrapper) { contentWrapper.classList.add('loaded'); } return Promise.resolve(); } return new Promise((resolve) => { const loadingScreen = createLoadingScreen(); setTimeout(() => { loadingScreen.classList.add('fade-out'); loadingScreen.addEventListener('animationend', () => { loadingScreen.remove(); // Marquer l'animation comme vue pour cette session sessionStorage.setItem('hasSeenLoadingAnimation', 'true'); resolve(); }, { once: true }); }, 2000); }); } document.addEventListener('DOMContentLoaded', async function() { try { await initializeLoadingScreen(); const contentWrapper = document.querySelector('.content-wrapper'); if (contentWrapper) { contentWrapper.classList.add('loaded'); } } catch (error) { console.error('Erreur lors du chargement:', error); } }); fetch('/build-metadata') .then(response => response.json()) .then(data => { document.getElementById('version-number').textContent = data.build_version; }) .catch(error => { console.error('Error fetching version:', error); document.getElementById('version-number').textContent = 'Version indisponible'; });