// PDF Editor - Main JavaScript Functions // Global variables let uploadedFiles = []; let sortableInstance = null; // Utility functions 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 getFileIcon(filename) { const extension = filename.toLowerCase().split('.').pop(); const iconMap = { 'pdf': 'fas fa-file-pdf text-danger', 'jpg': 'fas fa-file-image text-success', 'jpeg': 'fas fa-file-image text-success', 'png': 'fas fa-file-image text-success', 'gif': 'fas fa-file-image text-success', 'bmp': 'fas fa-file-image text-success', 'tiff': 'fas fa-file-image text-success', 'zip': 'fas fa-file-archive text-warning' }; return iconMap[extension] || 'fas fa-file text-muted'; } // Show notification function showNotification(message, type = 'info') { // Create notification element const notification = document.createElement('div'); notification.className = `alert alert-${type} alert-dismissible fade show position-fixed`; notification.style.cssText = 'top: 20px; right: 20px; z-index: 9999; max-width: 400px;'; notification.innerHTML = ` ${message} `; document.body.appendChild(notification); // Auto remove after 5 seconds setTimeout(() => { if (notification.parentNode) { notification.remove(); } }, 5000); } // Show/hide loading state function setLoadingState(element, loading = true) { if (loading) { element.disabled = true; const originalText = element.innerHTML; element.dataset.originalText = originalText; element.innerHTML = 'Verarbeitung...'; } else { element.disabled = false; element.innerHTML = element.dataset.originalText || element.innerHTML; } } // AJAX helper function async function makeRequest(url, options = {}) { try { const response = await fetch(url, { headers: { 'Content-Type': 'application/json', ...options.headers }, ...options }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error('Request failed:', error); throw error; } } // File upload with progress async function uploadFiles(files, endpoint, progressCallback) { const formData = new FormData(); if (Array.isArray(files)) { files.forEach(file => formData.append('files', file)); } else { formData.append('file', files); } return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); // Upload progress xhr.upload.addEventListener('progress', (e) => { if (e.lengthComputable && progressCallback) { const percentComplete = (e.loaded / e.total) * 100; progressCallback(percentComplete); } }); xhr.addEventListener('load', () => { if (xhr.status === 200) { try { const response = JSON.parse(xhr.responseText); resolve(response); } catch (error) { reject(new Error('Invalid JSON response')); } } else { reject(new Error(`Upload failed with status: ${xhr.status}`)); } }); xhr.addEventListener('error', () => { reject(new Error('Upload failed')); }); xhr.open('POST', endpoint); xhr.send(formData); }); } // Drag and drop functionality function setupDragAndDrop(element, callback) { ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { element.addEventListener(eventName, preventDefaults, false); }); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } ['dragenter', 'dragover'].forEach(eventName => { element.addEventListener(eventName, () => { element.classList.add('dragover'); }, false); }); ['dragleave', 'drop'].forEach(eventName => { element.addEventListener(eventName, () => { element.classList.remove('dragover'); }, false); }); element.addEventListener('drop', (e) => { const files = Array.from(e.dataTransfer.files); callback(files); }, false); } // Sortable list functionality function setupSortable(container, onUpdate) { if (typeof Sortable !== 'undefined') { return Sortable.create(container, { animation: 150, ghostClass: 'sortable-ghost', chosenClass: 'sortable-chosen', dragClass: 'sortable-drag', onUpdate: onUpdate }); } return null; } // Initialize tooltips function initializeTooltips() { const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); tooltipTriggerList.map(function (tooltipTriggerEl) { return new bootstrap.Tooltip(tooltipTriggerEl); }); } // Initialize on page load document.addEventListener('DOMContentLoaded', function() { initializeTooltips(); // Add fade-in animation to main content const mainContent = document.querySelector('main'); if (mainContent) { mainContent.classList.add('fade-in'); } });