/** * Script JavaScript pour l'interface d'administration B-PAY Bankily * Fichier: assets/bankily-admin.js * Version: 1.0.0 */ jQuery(document).ready(function($) { 'use strict'; // Variables globales var checking = false; var autoRefreshInterval; // Initialisation initializeAdminInterface(); function initializeAdminInterface() { // Gestion des checkboxes $('#cb-select-all').on('change', function() { $('input[name="transaction_ids[]"]').prop('checked', this.checked); updateBulkActionsState(); }); // Mise à jour de l'état des actions groupées $(document).on('change', 'input[name="transaction_ids[]"]', function() { updateBulkActionsState(); }); // Auto-refresh pour les transactions en attente if (window.location.href.indexOf('bankily-pending') > -1) { startAutoRefresh(); } // Initialiser les tooltips initializeTooltips(); // Gestion du temps réel updateTimeStamps(); setInterval(updateTimeStamps, 60000); // Mettre à jour chaque minute // Recherche en temps réel setupLiveSearch(); // Raccourcis clavier setupKeyboardShortcuts(); // Indicateur de connexion checkConnectionStatus(); setInterval(checkConnectionStatus, 30000); } function updateBulkActionsState() { var selectedCount = $('input[name="transaction_ids[]"]:checked').length; var $bulkButton = $('.button.action'); if (selectedCount > 0) { $bulkButton.prop('disabled', false).text('Appliquer (' + selectedCount + ')'); } else { $bulkButton.prop('disabled', true).text('Appliquer'); } } function initializeTooltips() { $('.error-message, [data-tooltip]').each(function() { var $this = $(this); var title = $this.attr('title') || $this.data('tooltip'); if (title) { $this.on('mouseenter', function(e) { showTooltip(e.pageX, e.pageY, title); }); $this.on('mouseleave', function() { hideTooltip(); }); $this.on('mousemove', function(e) { updateTooltipPosition(e.pageX, e.pageY); }); } }); } function showTooltip(x, y, text) { var $tooltip = $('#bankily-tooltip'); if ($tooltip.length === 0) { $tooltip = $('
').appendTo('body'); } $tooltip.text(text) .css({ position: 'absolute', left: x + 10, top: y - 30, background: '#333', color: '#fff', padding: '5px 10px', borderRadius: '4px', fontSize: '12px', zIndex: 9999, maxWidth: '300px', wordWrap: 'break-word' }) .fadeIn(200); } function hideTooltip() { $('#bankily-tooltip').fadeOut(200); } function updateTooltipPosition(x, y) { $('#bankily-tooltip').css({ left: x + 10, top: y - 30 }); } function updateTimeStamps() { $('.transaction-row').each(function() { var $row = $(this); var createdAt = $row.find('[data-timestamp]').data('timestamp'); if (createdAt) { var timeAgo = formatTimeAgo(new Date(createdAt * 1000)); $row.find('.time-ago').text(timeAgo); } }); } function formatTimeAgo(date) { var now = new Date(); var diffMs = now - date; var diffMins = Math.floor(diffMs / 60000); var diffHours = Math.floor(diffMins / 60); var diffDays = Math.floor(diffHours / 24); if (diffDays > 0) { return diffDays + ' jour' + (diffDays > 1 ? 's' : ''); } else if (diffHours > 0) { return diffHours + ' heure' + (diffHours > 1 ? 's' : ''); } else if (diffMins > 0) { return diffMins + ' minute' + (diffMins > 1 ? 's' : ''); } else { return 'À l\'instant'; } } function startAutoRefresh() { // Rafraîchir automatiquement toutes les 30 secondes si il y a des transactions en attente if ($('.bankily-status-ta').length > 0) { autoRefreshInterval = setTimeout(function() { if (!checking) { showNotice('info', 'Actualisation automatique...', 2000); setTimeout(function() { window.location.reload(); }, 1000); } }, 30000); } } function setupLiveSearch() { var searchTimeout; var $searchInput = $('input[name="search"]'); if ($searchInput.length) { $searchInput.on('input', function() { clearTimeout(searchTimeout); var query = $(this).val().toLowerCase(); searchTimeout = setTimeout(function() { filterTransactions(query); }, 300); }); } } function filterTransactions(query) { if (!query) { $('.transaction-row').show(); updateDisplayedCount(); return; } $('.transaction-row').each(function() { var $row = $(this); var text = $row.text().toLowerCase(); if (text.indexOf(query) !== -1) { $row.show(); } else { $row.hide(); } }); updateDisplayedCount(); } function updateDisplayedCount() { var visibleCount = $('.transaction-row:visible').length; $('.displaying-num').text(visibleCount + ' élément' + (visibleCount > 1 ? 's' : '')); } function setupKeyboardShortcuts() { $(document).on('keydown', function(e) { // Ctrl+R pour rafraîchir if (e.ctrlKey && e.keyCode === 82) { e.preventDefault(); window.location.reload(); } // Ctrl+A pour sélectionner tout if (e.ctrlKey && e.keyCode === 65 && $('.transaction-row').length > 0) { e.preventDefault(); $('#cb-select-all').prop('checked', true).trigger('change'); } // Échap pour désélectionner if (e.keyCode === 27) { $('#cb-select-all').prop('checked', false).trigger('change'); hideProgressBar(); } }); } function checkConnectionStatus() { $.ajax({ url: bankily_admin_ajax.ajax_url, type: 'POST', data: { action: 'bankily_ping', nonce: bankily_admin_ajax.nonce }, timeout: 5000, success: function() { updateConnectionStatus(true); }, error: function() { updateConnectionStatus(false); } }); } function updateConnectionStatus(isOnline) { var $indicator = $('#bankily-connection-status'); if ($indicator.length === 0) { $indicator = $('').appendTo('body'); } $indicator.removeClass('online offline') .addClass(isOnline ? 'online' : 'offline') .text(isOnline ? '🟢 En ligne' : '🔴 Hors ligne'); } // Fonctions globales pour les boutons (exposées au scope global) window.bankilyCheckTransaction = function(operationId, transactionId) { if (checking) { return; } checking = true; var $button = $('button[onclick*="' + transactionId + '"]').first(); var originalText = $button.text(); var $row = $('#transaction-' + transactionId); $button.prop('disabled', true).addClass('bankily-loading').text(bankily_admin_ajax.strings.checking); $row.addClass('bankily-checking'); $.ajax({ url: bankily_admin_ajax.ajax_url, type: 'POST', data: { action: 'bankily_check_transaction', operation_id: operationId, transaction_id: transactionId, nonce: bankily_admin_ajax.nonce }, success: function(response) { if (response.success) { updateTransactionRow(transactionId, response.data); showNotice('success', response.data.message); // Animation de succès $row.addClass('bankily-success'); setTimeout(function() { $row.removeClass('bankily-success'); }, 2000); } else { showNotice('error', response.data); $row.addClass('bankily-error'); setTimeout(function() { $row.removeClass('bankily-error'); }, 2000); } }, error: function(xhr, status, error) { showNotice('error', 'Erreur de connexion: ' + error); $row.addClass('bankily-error'); setTimeout(function() { $row.removeClass('bankily-error'); }, 2000); }, complete: function() { $button.prop('disabled', false) .removeClass('bankily-loading') .text(originalText); $row.removeClass('bankily-checking'); checking = false; } }); }; window.bankilyCheckAllPending = function() { if (checking) { return; } var $pendingRows = $('.bankily-status-ta').closest('tr'); if ($pendingRows.length === 0) { showNotice('info', 'Aucune transaction en attente à vérifier.'); return; } if (!confirm('Vérifier toutes les ' + $pendingRows.length + ' transactions en attente ?\n\nCela peut prendre plusieurs minutes.')) { return; } checking = true; var transactionIds = []; $pendingRows.each(function() { var $checkbox = $(this).find('input[name="transaction_ids[]"]'); if ($checkbox.length > 0) { transactionIds.push($checkbox.val()); } }); if (transactionIds.length === 0) { checking = false; showNotice('warning', 'Impossible de récupérer les IDs des transactions.'); return; } var $progressBar = showProgressBar(transactionIds.length); // Traitement par lots pour éviter de surcharger le serveur processBatch(transactionIds, 0, $progressBar, 5); // Taille de lot : 5 }; function processBatch(transactionIds, startIndex, $progressBar, batchSize) { var batch = transactionIds.slice(startIndex, startIndex + batchSize); if (batch.length === 0) { hideProgressBar(); checking = false; showNotice('success', 'Vérification terminée pour toutes les transactions.'); // Rafraîchir la page après un délai setTimeout(function() { window.location.reload(); }, 2000); return; } updateProgressBar($progressBar, startIndex, transactionIds.length); $.ajax({ url: bankily_admin_ajax.ajax_url, type: 'POST', data: { action: 'bankily_bulk_check', transaction_ids: batch, nonce: bankily_admin_ajax.nonce }, success: function(response) { if (response.success) { response.data.forEach(function(result) { if (result.status === 'success') { updateTransactionRow(result.id, { status: result.new_status, status_label: getStatusLabel(result.new_status) }); } }); } // Délai entre les lots setTimeout(function() { processBatch(transactionIds, startIndex + batchSize, $progressBar, batchSize); }, 2000); // 2 secondes entre les lots }, error: function() { hideProgressBar(); checking = false; showNotice('error', 'Erreur lors de la vérification groupée.'); } }); } function updateTransactionRow(transactionId, data) { var $row = $('#transaction-' + transactionId); if (data.status) { var $statusCell = $row.find('.bankily-status'); $statusCell.removeClass('bankily-status-ts bankily-status-tf bankily-status-ta') .addClass('bankily-status-' + data.status.toLowerCase()) .text(data.status_label || getStatusLabel(data.status)); } if (data.transaction_id) { var $operationCell = $row.find('.operation-id'); if (!$operationCell.find('small').length) { $operationCell.append('⏱ Cette opération peut prendre plusieurs minutes. Veuillez patienter...
${icon} ${message}