import { showToast, addRippleEffect } from './utils.js';
document.addEventListener('DOMContentLoaded', function() {
const selectionGrid = document.getElementById('selection-grid');
const filterButtons = document.querySelectorAll('.filter-buttons .filter-btn');
const orientationButtons = document.querySelectorAll('.orientation-filters .filter-btn');
const resolutionFilter = document.getElementById('resolution-filter');
const selectAllBtn = document.getElementById('select-all');
const deselectAllBtn = document.getElementById('deselect-all');
const downloadSelectedBtn = document.getElementById('download-selected');
const filteredCountEl = document.getElementById('filtered-count');
// Add ripple effect to all action buttons
document.querySelectorAll('.action-btn').forEach(button => {
addRippleEffect(button);
});
const actionModal = document.getElementById('action-modal');
const closeActionModal = document.getElementById('close-action-modal');
const actionButtons = actionModal.querySelectorAll('.action-btn');
const modalPreviewImg = document.getElementById('modal-preview-img');
const modalMessage = document.getElementById('modal-message');
const resetBtn = document.getElementById('reset-db');
const resetModal = document.getElementById('reset-modal');
const confirmResetBtn = document.getElementById('confirm-reset');
const cancelResetBtn = document.getElementById('cancel-reset');
const resetMessage = document.getElementById('reset-message');
let currentFilter = 'all';
let currentOrientation = 'all';
let currentResolution = 'all';
let selectedItems = [];
let currentSelectionId = null;
let allSelections = [];
// Enhanced loading animation
function showLoading() {
selectionGrid.classList.add('loading');
selectionGrid.innerHTML = `
${selection.image_path.split('/').pop()}
Resolution: ${selection.resolution}
Date: ${formatDate(selection.timestamp)}
×
Action: ${getActionName(selection.action)}
Filename: ${selection.image_path.split('/').pop()}
`;
document.body.appendChild(modal);
// Show the modal with animation
setTimeout(() => {
modal.style.display = 'flex';
setTimeout(() => modal.classList.add('show'), 10);
}, 10);
// Add close functionality
modal.addEventListener('click', (e) => {
if (e.target === modal || e.target.classList.contains('close-modal')) {
modal.classList.remove('show');
setTimeout(() => {
modal.style.display = 'none';
modal.remove();
}, 400);
}
});
}
// Handle delete button click
else if (target.classList.contains('delete-btn') || target.closest('.delete-btn')) {
// Create a confirmation dialog
const confirmDialog = document.createElement('div');
confirmDialog.className = 'modal confirmation-modal';
confirmDialog.innerHTML = `
Confirm Deletion
Are you sure you want to delete this selection?
`;
document.body.appendChild(confirmDialog);
// Show the dialog with animation
setTimeout(() => {
confirmDialog.style.display = 'flex';
setTimeout(() => confirmDialog.classList.add('show'), 10);
}, 10);
// Add button functionality
confirmDialog.querySelector('.confirm-delete-btn').addEventListener('click', () => {
// Add animation before removing
selectionItem.classList.add('removing');
// Close the dialog
confirmDialog.classList.remove('show');
setTimeout(() => {
confirmDialog.style.display = 'none';
confirmDialog.remove();
}, 400);
// Simulate delete functionality (replace with actual API call)
setTimeout(() => {
selectionItem.remove();
showToast('Selection removed');
// Update selected items if this was selected
if (selectedItems.some(item => item.id === selectionId)) {
selectedItems = selectedItems.filter(item => item.id !== selectionId);
updateDownloadButton();
}
// Update allSelections array
allSelections = allSelections.filter(s => s.id !== selectionId);
// Update stats
const stats = calculateStats(allSelections);
updateStats(stats);
// Update filtered count
if (filteredCountEl) {
const filteredSelections = allSelections.filter(s =>
(currentFilter === 'all' || s.action === currentFilter) &&
(currentOrientation === 'all' || s.orientation === currentOrientation) &&
(currentResolution === 'all' || s.resolution === currentResolution)
);
filteredCountEl.textContent = `Showing ${filteredSelections.length} of ${allSelections.length} images`;
}
}, 300);
});
confirmDialog.querySelector('.cancel-delete-btn').addEventListener('click', () => {
confirmDialog.classList.remove('show');
setTimeout(() => {
confirmDialog.style.display = 'none';
confirmDialog.remove();
}, 400);
});
}
});
// Enhanced filter button click handlers
filterButtons.forEach(button => button.addEventListener('click', function() {
filterButtons.forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
currentFilter = this.dataset.filter;
// Apply filter animation
selectionGrid.classList.add('filtering');
setTimeout(() => {
renderSelections(allSelections);
selectionGrid.classList.remove('filtering');
}, 300);
}));
orientationButtons.forEach(button => button.addEventListener('click', function() {
orientationButtons.forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
currentOrientation = this.dataset.orientation;
// Apply filter animation
selectionGrid.classList.add('filtering');
setTimeout(() => {
renderSelections(allSelections);
selectionGrid.classList.remove('filtering');
}, 300);
}));
resolutionFilter.addEventListener('change', function() {
currentResolution = this.value;
// Apply filter animation
selectionGrid.classList.add('filtering');
setTimeout(() => {
renderSelections(allSelections);
selectionGrid.classList.remove('filtering');
}, 300);
});
// Enhanced select/deselect all functionality
selectAllBtn.addEventListener('click', () => {
const checkboxes = document.querySelectorAll('.selection-checkbox');
checkboxes.forEach(cb => cb.checked = true);
selectedItems = Array.from(document.querySelectorAll('.selection-item')).map(item => ({
id: item.dataset.id,
image_path: item.querySelector('img').src,
action: item.querySelector('.selection-action').classList[1].replace('action-', '')
}));
document.querySelectorAll('.selection-item').forEach(item => item.classList.add('selected'));
updateDownloadButton();
showToast(`Selected all ${checkboxes.length} visible images`);
});
deselectAllBtn.addEventListener('click', () => {
document.querySelectorAll('.selection-checkbox').forEach(cb => cb.checked = false);
selectedItems = [];
document.querySelectorAll('.selection-item').forEach(item => item.classList.remove('selected'));
updateDownloadButton();
showToast('Deselected all images');
});
// Enhanced download functionality
downloadSelectedBtn.addEventListener('click', () => {
if (selectedItems.length === 0) return;
// Show loading toast
showToast(`Preparing ${selectedItems.length} images for download...`);
const paths = selectedItems.map(item => item.image_path);
const query = paths.map(p => `paths=${encodeURIComponent(p)}`).join('&');
// Add a small delay to show the loading toast
setTimeout(() => {
window.location.href = `/download-selected?${query}`;
}, 800);
});
// Enhanced modal functionality
closeActionModal.addEventListener('click', () => {
actionModal.classList.remove('show');
setTimeout(() => {
actionModal.style.display = 'none';
}, 400);
});
actionButtons.forEach(button => {
// Add ripple effect
addRippleEffect(button);
button.addEventListener('click', function() {
// Remove active class from all buttons
actionButtons.forEach(btn => btn.classList.remove('active'));
// Add active class to clicked button
this.classList.add('active');
const action = this.dataset.action;
// Show feedback
modalMessage.textContent = `Updating action to ${getActionName(action)}...`;
modalMessage.style.color = '#3498db';
// Simulate API call (replace with actual implementation)
setTimeout(() => {
modalMessage.textContent = `Action updated successfully!`;
modalMessage.style.color = '#2ecc71';
// Close modal after success
setTimeout(() => {
actionModal.classList.remove('show');
setTimeout(() => {
actionModal.style.display = 'none';
modalMessage.textContent = '';
}, 400);
// Update the UI to reflect the change
const selectionItem = document.querySelector(`.selection-item[data-id="${currentSelectionId}"]`);
if (selectionItem) {
const actionEl = selectionItem.querySelector('.selection-action');
const oldAction = actionEl.classList[1].replace('action-', '');
// Update the action element
actionEl.className = `selection-action action-${action}`;
actionEl.innerHTML = `