diff --git a/.cursor/rules/my-custom-rule.mdc b/.cursor/rules/my-custom-rule.mdc deleted file mode 100644 index 75a84ca..0000000 --- a/.cursor/rules/my-custom-rule.mdc +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: -globs: ---- - -# Your rule content - -- You can @ files here -- You can use markdown but dont have to diff --git a/app/routes/dashboard.py b/app/routes/dashboard.py index 75c8d65..617aacd 100644 --- a/app/routes/dashboard.py +++ b/app/routes/dashboard.py @@ -21,9 +21,8 @@ def index(): # Get recent files recent_files = File.query.filter_by(user_id=current_user.id).order_by(File.created_at.desc()).limit(5).all() - # Add icon_class to each file - for file in recent_files: - file.icon_class = file.get_icon_class() + # We don't need to set icon_class as it's already a property + # Just pass the files to the template return render_template('dashboard/index.html', file_count=file_count, diff --git a/app/static/css/custom.css b/app/static/css/custom.css deleted file mode 100644 index c0645c8..0000000 --- a/app/static/css/custom.css +++ /dev/null @@ -1,795 +0,0 @@ -:root { - /* Dark mode colors - more modern palette */ - --bg-dark: #121418; - --card-bg-dark: #1e2029; - --text-dark: #f2f3f8; - --text-secondary-dark: #b4bcd0; - --border-dark: #2e3145; - --primary-dark: #6d5dfc; - --secondary-dark: #4839eb; - --success-dark: #22c55e; - --warning-dark: #f59e0b; - --danger-dark: #ef4444; - --info-dark: #3b82f6; - - /* Light mode colors - cleaner palette */ - --bg-light: #f7f8fc; - --card-bg-light: #ffffff; - --text-light: #1a202c; - --text-secondary-light: #64748b; - --border-light: #e2e8f0; - --primary-light: #5a47e8; - --secondary-light: #4c3fe0; - --success-light: #10b981; - --warning-light: #f59e0b; - --danger-light: #ef4444; - --info-light: #3b82f6; - - /* Shared properties */ - --border-radius: 10px; - --border-radius-sm: 6px; - --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.05); - --shadow-md: 0 4px 20px rgba(0, 0, 0, 0.08); - --shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.12); - --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); -} - -/* Apply theme variables based on data attribute */ -[data-theme="light"] { - --bg: var(--bg-light); - --card-bg: var(--card-bg-light); - --text: var(--text-light); - --text-secondary: var(--text-secondary-light); - --border-color: var(--border-light); - --primary-color: var(--primary-light); - --secondary-color: var(--secondary-light); - --success-color: var(--success-light); - --warning-color: var(--warning-light); - --danger-color: var(--danger-light); - --info-color: var(--info-light); - --shadow-color: rgba(0, 0, 0, 0.1); -} - -[data-theme="dark"] { - --bg: var(--bg-dark); - --card-bg: var(--card-bg-dark); - --text: var(--text-dark); - --text-secondary: var(--text-secondary-dark); - --border-color: var(--border-dark); - --primary-color: var(--primary-dark); - --secondary-color: var(--secondary-dark); - --success-color: var(--success-dark); - --warning-color: var(--warning-dark); - --danger-color: var(--danger-dark); - --info-color: var(--info-dark); - --shadow-color: rgba(0, 0, 0, 0.3); -} - -/* Reset and base styles */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -html, -body { - height: 100%; - font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, Oxygen-Sans, Ubuntu, Cantarell, sans-serif; -} - -body { - background-color: var(--bg); - color: var(--text); - line-height: 1.6; - font-size: 16px; - transition: background-color 0.3s ease; -} - -a { - color: var(--primary-color); - text-decoration: none; - transition: var(--transition); -} - -a:hover { - opacity: 0.85; -} - -/* Modern navbar */ -.navbar { - background-color: var(--card-bg); - padding: 1rem 2rem; - display: flex; - justify-content: space-between; - align-items: center; - box-shadow: var(--shadow-sm); - border-bottom: 1px solid var(--border-color); - position: sticky; - top: 0; - z-index: 100; -} - -.navbar-brand a { - font-size: 1.5rem; - font-weight: 700; - color: var(--primary-color); - letter-spacing: 0.5px; -} - -.navbar-menu { - display: flex; - align-items: center; - gap: 1.5rem; -} - -.nav-item { - display: flex; - align-items: center; - gap: 0.5rem; - color: var(--text); - font-weight: 500; - padding: 0.5rem 0.75rem; - border-radius: var(--border-radius-sm); - transition: var(--transition); -} - -.nav-item:hover { - background-color: rgba(var(--primary-color-rgb), 0.1); - color: var(--primary-color); -} - -.nav-item i { - font-size: 1.1rem; -} - -.theme-toggle-icon { - cursor: pointer; - padding: 0.5rem; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - transition: var(--transition); -} - -.theme-toggle-icon:hover { - background-color: rgba(var(--primary-color-rgb), 0.1); -} - -/* Container and layout */ -.container { - max-width: 1200px; - margin: 0 auto; - padding: 2rem; -} - -main { - min-height: calc(100vh - 160px); -} - -/* Card styles */ -.card { - background-color: var(--card-bg); - border-radius: var(--border-radius); - box-shadow: var(--shadow-sm); - padding: 1.5rem; - margin-bottom: 1.5rem; - border: 1px solid var(--border-color); - transition: var(--transition); -} - -.card:hover { - box-shadow: var(--shadow-md); -} - -/* Button styles - modernized and consistent */ -.btn { - display: inline-flex; - align-items: center; - justify-content: center; - gap: 0.5rem; - padding: 0.5rem 1rem; - font-size: 0.95rem; - font-weight: 500; - border-radius: var(--border-radius-sm); - border: none; - cursor: pointer; - transition: var(--transition); - background-color: var(--card-bg); - color: var(--text); - box-shadow: inset 0 0 0 1px var(--border-color); -} - -.btn:hover { - transform: translateY(-1px); - box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--border-color); -} - -.btn:active { - transform: translateY(0); -} - -.btn.primary { - background-color: var(--primary-color); - color: white; - box-shadow: 0 2px 5px rgba(var(--primary-color-rgb), 0.3); -} - -.btn.primary:hover { - box-shadow: 0 4px 10px rgba(var(--primary-color-rgb), 0.4); -} - -.btn.secondary { - background-color: var(--secondary-color); - color: white; - box-shadow: 0 2px 5px rgba(var(--secondary-color-rgb), 0.3); -} - -.btn.secondary:hover { - box-shadow: 0 4px 10px rgba(var(--secondary-color-rgb), 0.4); -} - -.btn.success { - background-color: var(--success-color); - color: white; -} - -.btn.danger { - background-color: var(--danger-color); - color: white; -} - -.btn.sm { - padding: 0.3rem 0.75rem; - font-size: 0.85rem; -} - -.btn.lg { - padding: 0.75rem 1.5rem; - font-size: 1.1rem; -} - -.btn i { - font-size: 1.1em; -} - -/* Modal styles - beautiful and animated */ -.modal { - display: none; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); - z-index: 1000; - justify-content: center; - align-items: center; - opacity: 0; - transition: opacity 0.3s ease; - overflow: auto; - backdrop-filter: blur(4px); -} - -.modal.visible { - display: flex; - opacity: 1; -} - -.modal-content { - background: var(--card-bg); - border-radius: var(--border-radius); - width: 100%; - max-width: 500px; - box-shadow: var(--shadow-lg); - transform: scale(0.9); - opacity: 0; - transition: transform 0.3s ease, opacity 0.3s ease; - overflow: hidden; - margin: 2rem; - border: 1px solid var(--border-color); -} - -.modal.visible .modal-content { - transform: scale(1); - opacity: 1; -} - -.modal-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1.25rem 1.5rem; - border-bottom: 1px solid var(--border-color); -} - -.modal-header h3 { - margin: 0; - font-size: 1.25rem; - color: var(--text); -} - -.modal-close { - background: none; - border: none; - font-size: 1.5rem; - line-height: 1; - color: var(--text-secondary); - cursor: pointer; - transition: var(--transition); - padding: 0.25rem; - border-radius: 50%; - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; -} - -.modal-close:hover { - background-color: rgba(0, 0, 0, 0.05); - color: var(--danger-color); -} - -.modal-body { - padding: 1.5rem; -} - -.modal-footer { - padding: 1rem 1.5rem; - display: flex; - justify-content: flex-end; - gap: 0.75rem; - border-top: 1px solid var(--border-color); -} - -/* Form elements */ -.form-group { - margin-bottom: 1.5rem; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 500; - color: var(--text); -} - -.form-group input, -.form-group textarea, -.form-group select { - width: 100%; - padding: 0.75rem 1rem; - border: 1px solid var(--border-color); - border-radius: var(--border-radius-sm); - background-color: var(--card-bg); - color: var(--text); - font-size: 1rem; - transition: var(--transition); -} - -.form-group input:focus, -.form-group textarea:focus, -.form-group select:focus { - outline: none; - border-color: var(--primary-color); - box-shadow: 0 0 0 3px rgba(var(--primary-color-rgb), 0.1); -} - -.form-actions { - display: flex; - justify-content: flex-end; - gap: 0.75rem; - margin-top: 1.5rem; -} - -/* File browser styles */ -.browser-container { - background: var(--card-bg); - border-radius: var(--border-radius); - padding: 1.5rem; - margin-bottom: 2rem; - box-shadow: var(--shadow-sm); - border: 1px solid var(--border-color); -} - -.browser-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 1.5rem; - flex-wrap: wrap; - gap: 1rem; -} - -.browser-title { - display: flex; - align-items: center; - gap: 0.75rem; -} - -.browser-title h2 { - margin: 0; - font-size: 1.75rem; -} - -.browser-title i { - font-size: 1.5rem; - color: var(--primary-color); -} - -.browser-actions { - display: flex; - align-items: center; - gap: 0.75rem; - flex-wrap: wrap; -} - -.search-input { - padding: 0.5rem 1rem; - border: 1px solid var(--border-color); - border-radius: var(--border-radius-sm); - background-color: var(--card-bg); - color: var(--text); - min-width: 200px; - transition: var(--transition); -} - -.search-input:focus { - outline: none; - border-color: var(--primary-color); - box-shadow: 0 0 0 3px rgba(var(--primary-color-rgb), 0.1); -} - -/* Context menu for right-click */ -.context-menu { - position: fixed; - background: var(--card-bg); - border-radius: var(--border-radius-sm); - box-shadow: var(--shadow-md); - z-index: 1000; - min-width: 180px; - border: 1px solid var(--border-color); - padding: 0.5rem 0; - animation: fadeIn 0.2s ease; -} - -.context-menu-item { - padding: 0.5rem 1rem; - display: flex; - align-items: center; - gap: 0.75rem; - cursor: pointer; - transition: var(--transition); - color: var(--text); -} - -.context-menu-item:hover { - background-color: rgba(var(--primary-color-rgb), 0.1); -} - -.context-menu-item i { - width: 1rem; - text-align: center; - color: var(--text-secondary); -} - -.context-menu-divider { - height: 1px; - background-color: var(--border-color); - margin: 0.5rem 0; -} - -/* File and folder items */ -.files-container { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); - gap: 1.5rem; -} - -.files-container.list-view { - display: table; - width: 100%; - border-collapse: separate; - border-spacing: 0 0.5rem; -} - -.file-item, -.folder-item { - background-color: var(--card-bg); - border-radius: var(--border-radius-sm); - padding: 1rem; - text-align: center; - cursor: pointer; - transition: var(--transition); - border: 1px solid var(--border-color); - position: relative; -} - -.file-item:hover, -.folder-item:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-md); -} - -.file-icon, -.folder-icon { - font-size: 2.5rem; - margin-bottom: 0.75rem; - color: var(--primary-color); -} - -.folder-icon { - color: #f9d71c; -} - -.item-name { - font-size: 0.95rem; - word-break: break-word; - margin-bottom: 0.25rem; -} - -.item-meta { - font-size: 0.75rem; - color: var(--text-secondary); -} - -/* Animations */ -@keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -@keyframes slideUp { - from { - transform: translateY(20px); - opacity: 0; - } - - to { - transform: translateY(0); - opacity: 1; - } -} - -@keyframes pulse { - 0% { - transform: scale(1); - } - - 50% { - transform: scale(1.05); - } - - 100% { - transform: scale(1); - } -} - -.fade-in { - animation: fadeIn 0.3s ease; -} - -.slide-up { - animation: slideUp 0.3s ease; -} - -/* Alerts */ -.alerts { - position: fixed; - bottom: 1.5rem; - right: 1.5rem; - z-index: 1050; - display: flex; - flex-direction: column; - gap: 0.75rem; - max-width: 350px; -} - -.alert { - background-color: var(--card-bg); - border-radius: var(--border-radius); - padding: 1rem; - display: flex; - align-items: flex-start; - box-shadow: var(--shadow-md); - border-left: 4px solid var(--info-color); - animation: slideUp 0.3s ease; -} - -.alert.success { - border-left-color: var(--success-color); -} - -.alert.error { - border-left-color: var(--danger-color); -} - -.alert.warning { - border-left-color: var(--warning-color); -} - -.alert-content { - flex: 1; - padding-right: 0.75rem; -} - -.alert .close { - background: none; - border: none; - cursor: pointer; - color: var(--text-secondary); - font-size: 1.25rem; - line-height: 1; - transition: var(--transition); -} - -.alert .close:hover { - color: var(--danger-color); -} - -.alert.fade-out { - animation: fadeOut 0.3s ease forwards; -} - -@keyframes fadeOut { - from { - opacity: 1; - transform: translateY(0); - } - - to { - opacity: 0; - transform: translateY(10px); - } -} - -/* Custom transitions and animations for Google Drive-like experience */ - -/* Folder enter animation */ -.folder-transition-enter { - opacity: 0; - transform: translateY(20px); -} - -.folder-transition-enter-active { - opacity: 1; - transform: translateY(0); - transition: all 0.3s ease-out; -} - -/* Smooth hover effects */ -.folder-item, -.file-item { - transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease; -} - -.folder-item:hover, -.file-item:hover { - transform: translateY(-3px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); - z-index: 1; -} - -/* File hover actions */ -.file-actions { - position: absolute; - right: 10px; - top: 10px; - opacity: 0; - transition: opacity 0.2s ease; -} - -.file-item:hover .file-actions, -.folder-item:hover .file-actions { - opacity: 1; -} - -/* Folder navigation transitions */ -.files-container { - transition: opacity 0.3s ease, transform 0.3s ease; -} - -.files-container.changing { - opacity: 0; - transform: translateY(10px); -} - -/* File upload animation */ -@keyframes upload-progress { - 0% { - width: 0%; - } - - 100% { - width: 100%; - } -} - -.upload-progress-bar { - animation: upload-progress 1.5s ease-in-out; -} - -/* Navigation sidebar animation */ -.sidebar { - transition: transform 0.3s ease, width 0.3s ease; -} - -.sidebar.collapsed { - transform: translateX(-100%); - width: 0; -} - -/* Scale animation for new items */ -@keyframes new-item-appear { - 0% { - transform: scale(0.8); - opacity: 0; - } - - 100% { - transform: scale(1); - opacity: 1; - } -} - -.new-item { - animation: new-item-appear 0.3s forwards; -} - -/* Custom animations and transitions */ -.folder-enter-active { - animation: folder-enter 0.4s cubic-bezier(0.2, 0.9, 0.4, 1.0); -} - -@keyframes folder-enter { - from { - opacity: 0; - transform: translateY(15px); - } - - to { - opacity: 1; - transform: translateY(0); - } -} - -/* Folder/file hover animation */ -.folder-item, -.file-item { - transition: transform 0.15s ease, box-shadow 0.15s ease; -} - -.folder-item:hover, -.file-item:hover { - transform: translateY(-3px); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); -} - -/* Upload dropzone styles */ -.dropzone { - border: 2px dashed var(--border-color); - padding: 30px; - text-align: center; - background-color: rgba(0, 0, 0, 0.05); - transition: all 0.3s ease; - cursor: pointer; -} - -.dropzone.highlight { - border-color: var(--primary-color); - background-color: rgba(74, 107, 255, 0.1); -} - -.upload-icon { - font-size: 48px; - color: var(--primary-color); - margin-bottom: 15px; - opacity: 0.8; -} \ No newline at end of file diff --git a/app/static/css/modal.css b/app/static/css/modal.css index 79d413d..b664de1 100644 --- a/app/static/css/modal.css +++ b/app/static/css/modal.css @@ -8,49 +8,45 @@ height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 1000; - justify-content: center; - align-items: center; + opacity: 0; + visibility: hidden; + transition: opacity 0.3s ease, visibility 0.3s ease; } .modal.active { display: flex; + opacity: 1; + visibility: visible; + align-items: center; + justify-content: center; } .modal-content { background-color: var(--card-bg); border-radius: 8px; - width: 450px; - max-width: 90%; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); - transform: translateY(0); - animation: modal-appear 0.3s ease; + width: 90%; + max-width: 500px; + transform: translateY(-20px); + transition: transform 0.3s ease; + overflow: hidden; } -@keyframes modal-appear { - from { - opacity: 0; - transform: translateY(-30px); - } - - to { - opacity: 1; - transform: translateY(0); - } +.modal.active .modal-content { + transform: translateY(0); } .modal-header { - padding: 1.25rem 1.5rem; - border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; align-items: center; + padding: 1rem; + border-bottom: 1px solid var(--border-color); } .modal-header h3 { margin: 0; - font-weight: 600; - color: var(--text); - font-size: 1.25rem; + color: var(--text-color); } .modal-close { @@ -58,62 +54,48 @@ border: none; font-size: 1.5rem; cursor: pointer; - color: var(--text-secondary); + color: var(--text-muted); transition: color 0.2s ease; - line-height: 1; - padding: 0; - width: 28px; - height: 28px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; } .modal-close:hover { color: var(--danger-color); - background-color: rgba(var(--danger-color-rgb), 0.1); } .modal-body { - padding: 1.5rem; + padding: 1rem; } .form-group { - margin-bottom: 1.25rem; + margin-bottom: 1rem; } .form-group label { display: block; margin-bottom: 0.5rem; - font-weight: 500; - color: var(--text); + color: var(--text-color); } -.form-group input[type="text"], -.form-group input[type="password"], -.form-group input[type="email"] { +.form-group input { width: 100%; - padding: 0.75rem 1rem; - border-radius: 8px; + padding: 0.75rem; + border-radius: 4px; border: 1px solid var(--border-color); - background-color: var(--bg); - color: var(--text); - font-size: 1rem; - transition: border-color 0.3s ease, box-shadow 0.3s ease; + background-color: var(--background-color); + color: var(--text-color); + transition: border-color 0.2s ease; } .form-group input:focus { - outline: none; border-color: var(--primary-color); - box-shadow: 0 0 0 3px rgba(var(--primary-color-rgb), 0.2); + outline: none; } .form-actions { display: flex; justify-content: flex-end; - gap: 0.75rem; - margin-top: 1.5rem; + gap: 0.5rem; + margin-top: 1rem; } .form-actions .btn { diff --git a/app/static/js/browser.js b/app/static/js/browser.js index a63525a..f0fbd21 100644 --- a/app/static/js/browser.js +++ b/app/static/js/browser.js @@ -9,7 +9,7 @@ document.addEventListener('DOMContentLoaded', function () { if (filesContainer && gridViewBtn && listViewBtn) { // Set initial view based on saved preference - const savedView = localStorage.getItem('view_preference') || 'grid'; + const savedView = localStorage.getItem('view_mode') || 'grid'; filesContainer.className = `files-container ${savedView}-view`; // Highlight the correct button @@ -26,18 +26,14 @@ document.addEventListener('DOMContentLoaded', function () { filesContainer.className = 'files-container grid-view'; gridViewBtn.classList.add('active'); listViewBtn.classList.remove('active'); - - // Save preference - localStorage.setItem('view_preference', 'grid'); + localStorage.setItem('view_mode', 'grid'); }); listViewBtn.addEventListener('click', function () { filesContainer.className = 'files-container list-view'; listViewBtn.classList.add('active'); gridViewBtn.classList.remove('active'); - - // Save preference - localStorage.setItem('view_preference', 'list'); + localStorage.setItem('view_mode', 'list'); }); } @@ -281,6 +277,71 @@ document.addEventListener('DOMContentLoaded', function () { deleteModal.classList.remove('active'); }); } + + // File/folder action buttons + const setupItemActions = () => { + // Edit/rename buttons + document.querySelectorAll('.action-btn.edit').forEach(btn => { + btn.addEventListener('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + + const itemElement = this.closest('.folder-item, .file-item'); + const itemId = itemElement.dataset.id; + const itemName = itemElement.querySelector('.item-name').textContent; + const isFolder = itemElement.classList.contains('folder-item'); + + // Set values in rename modal + const renameModal = document.getElementById('rename-modal'); + const newNameInput = document.getElementById('new-name'); + const itemIdInput = document.getElementById('item-id'); + const itemTypeInput = document.getElementById('item-type'); + + if (renameModal && newNameInput && itemIdInput && itemTypeInput) { + newNameInput.value = itemName; + itemIdInput.value = itemId; + itemTypeInput.value = isFolder ? 'folder' : 'file'; + + // Show modal + renameModal.classList.add('active'); + } + }); + }); + + // Delete buttons + document.querySelectorAll('.action-btn.delete').forEach(btn => { + btn.addEventListener('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + + const itemElement = this.closest('.folder-item, .file-item'); + const itemId = itemElement.dataset.id; + const isFolder = itemElement.classList.contains('folder-item'); + + // Set values in delete modal + const deleteModal = document.getElementById('delete-modal'); + const deleteItemIdInput = document.getElementById('delete-item-id'); + const deleteItemTypeInput = document.getElementById('delete-item-type'); + + if (deleteModal && deleteItemIdInput && deleteItemTypeInput) { + deleteItemIdInput.value = itemId; + deleteItemTypeInput.value = isFolder ? 'folder' : 'file'; + + // Update form action + const deleteForm = document.getElementById('delete-form'); + if (deleteForm) { + deleteForm.action = `/files/delete/${itemId}`; + } + + // Show modal + deleteModal.classList.add('active'); + } + }); + }); + }; + + // Initialize item actions + setupItemActions(); }); // Browser-specific functionality diff --git a/app/static/js/modal.js b/app/static/js/modal.js index 5f22380..46685b4 100644 --- a/app/static/js/modal.js +++ b/app/static/js/modal.js @@ -5,44 +5,59 @@ document.addEventListener('DOMContentLoaded', function () { }); function initializeModals() { - // Setup modal triggers - document.querySelectorAll('[data-toggle="modal"]').forEach(trigger => { - const targetId = trigger.getAttribute('data-target'); - const targetModal = document.querySelector(targetId); + // Get all modals + const modals = document.querySelectorAll('.modal'); - if (targetModal) { - trigger.addEventListener('click', function (e) { - e.preventDefault(); - openModal(targetId); + // Initialize each modal + modals.forEach(modal => { + // Get close button + const closeBtn = modal.querySelector('.modal-close'); + const cancelBtn = modal.querySelector('.modal-cancel'); + + // Close modal when close button is clicked + if (closeBtn) { + closeBtn.addEventListener('click', function () { + modal.classList.remove('active'); }); } - }); - // Setup direct modal triggers (like the new folder button) - const newFolderBtn = document.getElementById('new-folder-btn'); - if (newFolderBtn) { - newFolderBtn.addEventListener('click', function () { - openModal('#new-folder-modal'); - }); - } + // Close modal when cancel button is clicked + if (cancelBtn) { + cancelBtn.addEventListener('click', function () { + modal.classList.remove('active'); + }); + } - const emptyNewFolderBtn = document.getElementById('empty-new-folder-btn'); - if (emptyNewFolderBtn) { - emptyNewFolderBtn.addEventListener('click', function () { - openModal('#new-folder-modal'); - }); - } - - // Close buttons - document.querySelectorAll('.modal-close, .modal-cancel').forEach(closeBtn => { - closeBtn.addEventListener('click', function () { - const modal = this.closest('.modal'); - if (modal) { - closeModal('#' + modal.id); + // Close modal when clicking outside + modal.addEventListener('click', function (e) { + if (e.target === modal) { + modal.classList.remove('active'); } }); }); + // Open modal when trigger is clicked + document.querySelectorAll('[data-modal]').forEach(trigger => { + trigger.addEventListener('click', function () { + const modalId = this.dataset.modal; + const modal = document.getElementById(modalId); + if (modal) { + modal.classList.add('active'); + } + }); + }); + + // New folder button + const newFolderBtn = document.getElementById('new-folder-btn'); + if (newFolderBtn) { + newFolderBtn.addEventListener('click', function () { + const modal = document.getElementById('new-folder-modal'); + if (modal) { + modal.classList.add('active'); + } + }); + } + // Close on background click document.querySelectorAll('.modal').forEach(modal => { modal.addEventListener('click', function (e) { diff --git a/app/templates/base.html b/app/templates/base.html index cfd7427..0285b78 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -14,9 +14,9 @@ - + - + diff --git a/app/templates/dashboard/index.html b/app/templates/dashboard/index.html index 551bf38..201317c 100644 --- a/app/templates/dashboard/index.html +++ b/app/templates/dashboard/index.html @@ -47,7 +47,7 @@ {% for file in recent_files %}