add assets

This commit is contained in:
2025-08-23 21:15:12 +00:00
commit 0cf35cd494
3 changed files with 2000 additions and 0 deletions

844
assets/bankily-admin.css Normal file
View File

@@ -0,0 +1,844 @@
/**
* Styles CSS pour l'interface d'administration B-PAY Bankily
* Fichier: assets/bankily-admin.css
* Version: 1.0.0
*/
/* === VARIABLES CSS === */
:root {
--bankily-primary: #007cba;
--bankily-success: #28a745;
--bankily-warning: #ffc107;
--bankily-danger: #dc3545;
--bankily-info: #17a2b8;
--bankily-light: #f8f9fa;
--bankily-dark: #343a40;
--bankily-border: #dee2e6;
--bankily-shadow: 0 2px 4px rgba(0,0,0,0.1);
--bankily-shadow-lg: 0 4px 8px rgba(0,0,0,0.15);
--bankily-border-radius: 8px;
--bankily-transition: all 0.3s ease;
}
/* === LAYOUT GÉNÉRAL === */
.wrap .bankily-stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
margin: 20px 0 30px 0;
}
.bankily-stat-card {
background: #fff;
border: 1px solid var(--bankily-border);
border-radius: var(--bankily-border-radius);
padding: 24px;
text-align: center;
box-shadow: var(--bankily-shadow);
transition: var(--bankily-transition);
position: relative;
overflow: hidden;
}
.bankily-stat-card:hover {
transform: translateY(-2px);
box-shadow: var(--bankily-shadow-lg);
}
.bankily-stat-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: var(--bankily-primary);
}
.bankily-stat-card h3 {
font-size: 2.8em;
margin: 0 0 10px 0;
font-weight: 700;
line-height: 1;
}
.bankily-stat-card p {
margin: 0;
color: #666;
font-size: 14px;
text-transform: uppercase;
letter-spacing: 0.8px;
font-weight: 500;
}
/* Couleurs des cartes statistiques */
.bankily-stat-card.total::before { background: var(--bankily-primary); }
.bankily-stat-card.total h3 { color: var(--bankily-primary); }
.bankily-stat-card.success::before { background: var(--bankily-success); }
.bankily-stat-card.success h3 { color: var(--bankily-success); }
.bankily-stat-card.pending::before { background: var(--bankily-warning); }
.bankily-stat-card.pending h3 { color: var(--bankily-warning); }
.bankily-stat-card.failed::before { background: var(--bankily-danger); }
.bankily-stat-card.failed h3 { color: var(--bankily-danger); }
.bankily-stat-card.amount::before { background: var(--bankily-info); }
.bankily-stat-card.amount h3 { color: var(--bankily-info); }
/* === ACTIONS RAPIDES === */
.bankily-quick-actions {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border: 1px solid var(--bankily-border);
border-radius: var(--bankily-border-radius);
padding: 24px;
margin: 20px 0 30px 0;
position: relative;
}
.bankily-quick-actions::before {
content: '⚡';
position: absolute;
top: -10px;
left: 20px;
background: var(--bankily-warning);
color: white;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
.bankily-quick-actions h2 {
margin-top: 0;
color: var(--bankily-dark);
font-size: 18px;
margin-bottom: 16px;
}
.bankily-action-buttons {
display: flex;
gap: 12px;
flex-wrap: wrap;
align-items: center;
}
.bankily-action-buttons .button {
margin: 0;
font-weight: 500;
transition: var(--bankily-transition);
}
.bankily-action-buttons .button-primary {
background: var(--bankily-primary);
border-color: var(--bankily-primary);
}
.bankily-action-buttons .button-primary:hover {
background: #005a87;
border-color: #005a87;
transform: translateY(-1px);
}
/* === STATUTS DES TRANSACTIONS === */
.bankily-status {
display: inline-block;
padding: 6px 12px;
border-radius: 20px;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.8px;
border: 2px solid transparent;
transition: var(--bankily-transition);
}
.bankily-status-ts {
background: linear-gradient(135deg, #d4edda, #c3e6cb);
color: #155724;
border-color: #c3e6cb;
}
.bankily-status-tf {
background: linear-gradient(135deg, #f8d7da, #f5c6cb);
color: #721c24;
border-color: #f5c6cb;
}
.bankily-status-ta {
background: linear-gradient(135deg, #fff3cd, #ffeaa7);
color: #856404;
border-color: #ffeaa7;
animation: pulse-warning 2s infinite;
}
@keyframes pulse-warning {
0%, 100% { opacity: 1; }
50% { opacity: 0.8; }
}
/* === FILTRES ET RECHERCHE === */
.bankily-filters {
background: #fff;
border: 1px solid var(--bankily-border);
border-radius: var(--bankily-border-radius);
padding: 20px;
margin: 20px 0;
box-shadow: var(--bankily-shadow);
}
.bankily-search-box {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}
.bankily-search-box input[type="text"] {
flex: 1;
min-width: 300px;
padding: 10px 16px;
border: 2px solid var(--bankily-border);
border-radius: 6px;
font-size: 14px;
transition: var(--bankily-transition);
}
.bankily-search-box input[type="text"]:focus {
outline: none;
border-color: var(--bankily-primary);
box-shadow: 0 0 0 3px rgba(0, 124, 186, 0.1);
}
.bankily-advanced-filters {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
margin-top: 16px;
padding-top: 16px;
border-top: 1px solid var(--bankily-border);
}
.bankily-filter-group label {
display: block;
font-weight: 600;
margin-bottom: 6px;
color: var(--bankily-dark);
font-size: 13px;
}
.bankily-filter-group select,
.bankily-filter-group input {
width: 100%;
padding: 8px 12px;
border: 1px solid var(--bankily-border);
border-radius: 4px;
font-size: 13px;
transition: var(--bankily-transition);
}
.bankily-filter-group select:focus,
.bankily-filter-group input:focus {
outline: none;
border-color: var(--bankily-primary);
}
/* === ACTIONS EN LOT === */
.bankily-bulk-actions {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
border-bottom: 2px solid var(--bankily-border);
margin-bottom: 15px;
background: linear-gradient(90deg, rgba(0, 124, 186, 0.05) 0%, rgba(0, 124, 186, 0.02) 100%);
padding: 16px;
border-radius: 6px;
margin: 10px 0 20px 0;
}
.bankily-bulk-actions select {
margin-right: 8px;
padding: 6px 10px;
border-radius: 4px;
}
.bankily-bulk-actions .button.action:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.bankily-bulk-actions .displaying-num {
color: #666;
font-size: 13px;
font-weight: 500;
}
/* === TABLEAU DES TRANSACTIONS === */
.wp-list-table {
border-radius: var(--bankily-border-radius);
overflow: hidden;
box-shadow: var(--bankily-shadow);
}
.wp-list-table .transaction-row {
transition: var(--bankily-transition);
}
.wp-list-table .transaction-row:hover {
background-color: rgba(0, 124, 186, 0.05);
}
.wp-list-table .transaction-row.updated {
background-color: rgba(40, 167, 69, 0.1);
border-left: 4px solid var(--bankily-success);
}
.wp-list-table .transaction-row.bankily-checking {
background-color: rgba(0, 124, 186, 0.1);
opacity: 0.7;
}
.wp-list-table .transaction-row.bankily-success {
background-color: rgba(40, 167, 69, 0.15);
animation: flash-success 1.5s ease;
}
.wp-list-table .transaction-row.bankily-error {
background-color: rgba(220, 53, 69, 0.15);
animation: flash-error 1.5s ease;
}
@keyframes flash-success {
0%, 100% { background-color: rgba(40, 167, 69, 0.15); }
50% { background-color: rgba(40, 167, 69, 0.3); }
}
@keyframes flash-error {
0%, 100% { background-color: rgba(220, 53, 69, 0.15); }
50% { background-color: rgba(220, 53, 69, 0.3); }
}
.wp-list-table .operation-id {
font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
font-size: 12px;
font-weight: 600;
}
.wp-list-table .operation-id small {
color: #666;
font-size: 10px;
font-weight: normal;
}
.wp-list-table .actions {
white-space: nowrap;
}
.wp-list-table .actions .button {
margin: 2px;
font-size: 11px;
padding: 4px 8px;
border-radius: 4px;
font-weight: 500;
transition: var(--bankily-transition);
}
.wp-list-table .actions .button:hover {
transform: translateY(-1px);
}
.wp-list-table .actions .button.bankily-loading {
position: relative;
color: transparent !important;
}
.wp-list-table .actions .button.bankily-loading::after {
content: '';
position: absolute;
width: 12px;
height: 12px;
top: 50%;
left: 50%;
margin-left: -6px;
margin-top: -6px;
border: 2px solid #fff;
border-radius: 50%;
border-top-color: transparent;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.wp-list-table .error-message {
color: var(--bankily-danger);
font-style: italic;
cursor: help;
font-size: 11px;
}
.wp-list-table .error-message:hover {
text-decoration: underline;
}
/* Statuts des commandes */
.order-status-completed { color: var(--bankily-success); font-weight: 600; }
.order-status-processing { color: var(--bankily-info); font-weight: 600; }
.order-status-on-hold { color: var(--bankily-warning); font-weight: 600; }
.order-status-cancelled { color: var(--bankily-danger); font-weight: 600; }
.order-status-refunded { color: #6c757d; font-weight: 600; }
.order-status-failed { color: var(--bankily-danger); font-weight: 600; }
.order-status-pending { color: #fd7e14; font-weight: 600; }
/* === BARRE DE PROGRESSION === */
#bankily-progress-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 999999;
display: flex;
align-items: center;
justify-content: center;
backdrop-filter: blur(5px);
}
.bankily-progress-container {
background: #fff;
border-radius: var(--bankily-border-radius);
padding: 40px;
min-width: 450px;
max-width: 90vw;
text-align: center;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
border: 3px solid var(--bankily-primary);
}
.bankily-progress-container h3 {
margin: 0 0 24px 0;
color: var(--bankily-dark);
font-size: 20px;
}
.bankily-progress-bar {
width: 100%;
height: 24px;
background: #e9ecef;
border-radius: 12px;
overflow: hidden;
margin-bottom: 16px;
border: 2px solid var(--bankily-border);
}
.bankily-progress-fill {
height: 100%;
background: linear-gradient(45deg, var(--bankily-primary), var(--bankily-info));
transition: width 0.5s ease;
position: relative;
border-radius: 10px;
}
.bankily-progress-fill::after {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-image: linear-gradient(
45deg,
rgba(255, 255, 255, 0.3) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.3) 50%,
rgba(255, 255, 255, 0.3) 75%,
transparent 75%,
transparent
);
background-size: 24px 24px;
animation: progress-stripes 1.5s linear infinite;
}
@keyframes progress-stripes {
0% { background-position: 0 0; }
100% { background-position: 24px 0; }
}
.bankily-progress-text {
color: var(--bankily-dark);
font-weight: 600;
font-size: 16px;
margin-bottom: 16px;
}
.bankily-progress-container p {
margin-bottom: 20px;
}
.bankily-progress-container small {
color: #666;
font-style: italic;
}
/* === PAGINATION === */
.bankily-pagination {
text-align: center;
margin: 30px 0;
}
.bankily-pagination .page-numbers {
display: inline-block;
padding: 10px 14px;
margin: 0 3px;
border: 2px solid var(--bankily-border);
border-radius: 6px;
color: var(--bankily-primary);
text-decoration: none;
transition: var(--bankily-transition);
font-weight: 500;
}
.bankily-pagination .page-numbers:hover {
background: var(--bankily-primary);
color: #fff;
border-color: var(--bankily-primary);
transform: translateY(-1px);
}
.bankily-pagination .page-numbers.current {
background: var(--bankily-primary);
color: #fff;
border-color: var(--bankily-primary);
}
/* === NOTICES === */
.bankily-notice {
margin: 15px 0;
animation: slideDown 0.4s ease;
border-left: 4px solid var(--bankily-primary);
box-shadow: var(--bankily-shadow);
}
@keyframes slideDown {
from {
transform: translateY(-20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.bankily-notice.notice-success {
border-left-color: var(--bankily-success);
}
.bankily-notice.notice-error {
border-left-color: var(--bankily-danger);
}
.bankily-notice.notice-warning {
border-left-color: var(--bankily-warning);
}
.bankily-notice.notice-info {
border-left-color: var(--bankily-info);
}
/* === INDICATEUR DE CONNEXION === */
#bankily-connection-status {
position: fixed;
bottom: 20px;
right: 20px;
padding: 10px 16px;
border-radius: 25px;
font-size: 12px;
font-weight: 600;
z-index: 10000;
transition: var(--bankily-transition);
box-shadow: var(--bankily-shadow-lg);
border: 2px solid transparent;
}
#bankily-connection-status.online {
background: linear-gradient(135deg, var(--bankily-success), #20c997);
color: #fff;
border-color: var(--bankily-success);
}
#bankily-connection-status.offline {
background: linear-gradient(135deg, var(--bankily-danger), #e83e8c);
color: #fff;
border-color: var(--bankily-danger);
animation: pulse-offline 2s infinite;
}
@keyframes pulse-offline {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.8; transform: scale(1.05); }
}
/* === TOOLTIPS === */
#bankily-tooltip {
background: var(--bankily-dark);
color: #fff;
padding: 8px 12px;
border-radius: 6px;
font-size: 12px;
max-width: 300px;
word-wrap: break-word;
box-shadow: var(--bankily-shadow-lg);
z-index: 999999;
border: 1px solid rgba(255, 255, 255, 0.1);
}
/* === BADGES ET ICÔNES === */
.bankily-badge {
display: inline-block;
padding: 3px 8px;
font-size: 10px;
font-weight: 700;
border-radius: 3px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.bankily-badge.new {
background: linear-gradient(135deg, #e3f2fd, #bbdefb);
color: #1976d2;
border: 1px solid #90caf9;
}
.bankily-badge.urgent {
background: linear-gradient(135deg, #ffebee, #ffcdd2);
color: #c62828;
border: 1px solid #ef9a9a;
animation: pulse-urgent 2s infinite;
}
@keyframes pulse-urgent {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
/* === RESPONSIVE === */
@media (max-width: 1200px) {
.bankily-stats-grid {
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
}
.bankily-stat-card {
padding: 20px;
}
.bankily-stat-card h3 {
font-size: 2.4em;
}
}
@media (max-width: 782px) {
.bankily-stats-grid {
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 12px;
}
.bankily-stat-card {
padding: 16px;
}
.bankily-stat-card h3 {
font-size: 2em;
}
.bankily-search-box {
flex-direction: column;
align-items: stretch;
}
.bankily-search-box input[type="text"] {
min-width: auto;
margin-bottom: 10px;
}
.bankily-action-buttons {
flex-direction: column;
align-items: stretch;
}
.bankily-action-buttons .button {
margin-bottom: 8px;
}
.bankily-bulk-actions {
flex-direction: column;
align-items: stretch;
gap: 10px;
}
.bankily-advanced-filters {
grid-template-columns: 1fr;
}
.wp-list-table .actions {
white-space: normal;
}
.wp-list-table .actions .button {
display: block;
margin-bottom: 5px;
width: 100%;
text-align: center;
}
.bankily-progress-container {
padding: 20px;
min-width: auto;
max-width: 95vw;
}
#bankily-connection-status {
bottom: 10px;
right: 10px;
font-size: 11px;
padding: 8px 12px;
}
}
@media (max-width: 480px) {
.bankily-stats-grid {
grid-template-columns: 1fr;
}
.bankily-quick-actions {
padding: 16px;
}
.bankily-filters {
padding: 16px;
}
.wp-list-table {
font-size: 12px;
}
.wp-list-table th,
.wp-list-table td {
padding: 8px 4px;
}
}
/* === DARK MODE (optionnel) === */
@media (prefers-color-scheme: dark) {
:root {
--bankily-light: #2c3e50;
--bankily-border: #34495e;
--bankily-dark: #ecf0f1;
}
.bankily-stat-card {
background: var(--bankily-light);
border-color: var(--bankily-border);
color: var(--bankily-dark);
}
.bankily-quick-actions {
background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
border-color: var(--bankily-border);
color: var(--bankily-dark);
}
.bankily-filters {
background: var(--bankily-light);
border-color: var(--bankily-border);
color: var(--bankily-dark);
}
.bankily-progress-container {
background: var(--bankily-light);
color: var(--bankily-dark);
border-color: var(--bankily-primary);
}
}
/* === ANIMATIONS SUPPLÉMENTAIRES === */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.bankily-stats-grid .bankily-stat-card {
animation: fadeInUp 0.5s ease forwards;
}
.bankily-stats-grid .bankily-stat-card:nth-child(1) { animation-delay: 0.1s; }
.bankily-stats-grid .bankily-stat-card:nth-child(2) { animation-delay: 0.2s; }
.bankily-stats-grid .bankily-stat-card:nth-child(3) { animation-delay: 0.3s; }
.bankily-stats-grid .bankily-stat-card:nth-child(4) { animation-delay: 0.4s; }
.bankily-stats-grid .bankily-stat-card:nth-child(5) { animation-delay: 0.5s; }
/* === ACCESSIBILITÉ === */
.sr-only {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
}
/* Focus visible pour la navigation clavier */
.bankily-stat-card:focus,
.button:focus,
input:focus,
select:focus,
.bankily-status:focus {
outline: 2px solid var(--bankily-primary);
outline-offset: 2px;
}
/* === IMPRESSION === */
@media print {
.bankily-action-buttons,
.bankily-bulk-actions,
.wp-list-table .actions,
#bankily-connection-status,
.notice,
#bankily-progress-overlay {
display: none !important;
}
.bankily-stat-card {
break-inside: avoid;
box-shadow: none;
border: 1px solid #000;
}
.wp-list-table {
font-size: 10px;
}
.bankily-status {
border: 1px solid #000 !important;
background: #fff !important;
color: #000 !important;
}
}

721
assets/bankily-admin.js Normal file
View File

@@ -0,0 +1,721 @@
/**
* 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 = $('<div id="bankily-tooltip"></div>').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 = $('<div id="bankily-connection-status"></div>').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('<br><small>TXN: ' + data.transaction_id + '</small>');
}
}
// Mettre à jour le compteur de tentatives
var $attemptsCell = $row.find('td').eq(-2);
var currentAttempts = parseInt($attemptsCell.text()) || 0;
$attemptsCell.text(currentAttempts + 1);
// Mettre à jour l'heure de dernière vérification
var now = new Date();
var $lastCheckedCell = $row.find('td').eq(-3);
$lastCheckedCell.text(formatDateTime(now));
// Animation de mise à jour
$row.addClass('updated');
setTimeout(function() {
$row.removeClass('updated');
}, 2000);
}
function getStatusLabel(status) {
var labels = {
'TS': bankily_admin_ajax.strings.success,
'TF': bankily_admin_ajax.strings.failed,
'TA': bankily_admin_ajax.strings.pending
};
return labels[status] || status;
}
function formatDateTime(date) {
return date.toLocaleDateString('fr-FR', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}
function showProgressBar(total) {
var progressHtml = `
<div id="bankily-progress-overlay">
<div class="bankily-progress-container">
<h3>🔄 Vérification des transactions en cours...</h3>
<div class="bankily-progress-bar">
<div class="bankily-progress-fill" style="width: 0%"></div>
</div>
<div class="bankily-progress-text">0 / ${total}</div>
<p><small>⏱ Cette opération peut prendre plusieurs minutes. Veuillez patienter...</small></p>
<button type="button" class="button button-secondary" onclick="bankilyStopProcessing()">
Annuler
</button>
</div>
</div>
`;
$('body').append(progressHtml);
return $('#bankily-progress-overlay');
}
function updateProgressBar($progressBar, current, total) {
var percentage = (current / total) * 100;
$progressBar.find('.bankily-progress-fill').css('width', percentage + '%');
$progressBar.find('.bankily-progress-text').text(current + ' / ' + total + ' (' + Math.round(percentage) + '%)');
}
function hideProgressBar() {
$('#bankily-progress-overlay').fadeOut(function() {
$(this).remove();
});
}
window.bankilyStopProcessing = function() {
if (confirm('Êtes-vous sûr de vouloir arrêter le processus ?')) {
checking = false;
hideProgressBar();
showNotice('warning', 'Processus arrêté par l\'utilisateur.');
}
};
window.bankilyBulkAction = function() {
var action = $('#bulk-action-selector-top').val();
var selectedIds = [];
$('input[name="transaction_ids[]"]:checked').each(function() {
selectedIds.push($(this).val());
});
if (selectedIds.length === 0) {
showNotice('warning', 'Veuillez sélectionner au moins une transaction.');
return;
}
if (!confirm(bankily_admin_ajax.strings.confirm_bulk + '\n\n' + selectedIds.length + ' transactions sélectionnées.')) {
return;
}
switch (action) {
case 'check':
bankilyBulkCheck(selectedIds);
break;
case 'mark-failed':
bankilyBulkMarkFailed(selectedIds);
break;
default:
showNotice('warning', 'Veuillez sélectionner une action.');
}
};
function bankilyBulkCheck(transactionIds) {
if (checking) {
return;
}
checking = true;
var $progressBar = showProgressBar(transactionIds.length);
processBatch(transactionIds, 0, $progressBar, 3); // Taille de lot réduite pour les actions manuelles
}
function bankilyBulkMarkFailed(transactionIds) {
if (checking) {
return;
}
checking = true;
$.ajax({
url: bankily_admin_ajax.ajax_url,
type: 'POST',
data: {
action: 'bankily_bulk_mark_failed',
transaction_ids: transactionIds,
nonce: bankily_admin_ajax.nonce
},
success: function(response) {
if (response.success) {
transactionIds.forEach(function(id) {
updateTransactionRow(id, {
status: 'TF',
status_label: getStatusLabel('TF')
});
});
showNotice('success', response.data.message);
} else {
showNotice('error', 'Erreur lors du marquage des transactions.');
}
},
error: function() {
showNotice('error', bankily_admin_ajax.strings.error);
},
complete: function() {
checking = false;
}
});
}
window.bankilyMarkAsFailed = function(transactionId) {
if (!confirm('Êtes-vous sûr de vouloir marquer cette transaction comme échouée ?\n\nCette action est irréversible.')) {
return;
}
bankilyBulkMarkFailed([transactionId]);
};
window.bankilyExportTransactions = function() {
showNotice('info', 'Préparation de l\'export...');
var url = bankily_admin_ajax.ajax_url + '?action=bankily_export_transactions&nonce=' + bankily_admin_ajax.nonce;
// Créer un lien de téléchargement invisible
var $link = $('<a>').attr({
href: url,
download: 'bankily-transactions-' + new Date().toISOString().split('T')[0] + '.csv'
}).appendTo('body');
$link[0].click();
$link.remove();
showNotice('success', 'Export lancé. Le téléchargement va commencer.', 3000);
};
window.bankilyCleanOldTransactions = function() {
if (!confirm('Êtes-vous sûr de vouloir supprimer les transactions de plus de 6 mois ?\n\n⚠ Cette action est irréversible !')) {
return;
}
$.ajax({
url: bankily_admin_ajax.ajax_url,
type: 'POST',
data: {
action: 'bankily_clean_old_transactions',
nonce: bankily_admin_ajax.nonce
},
success: function(response) {
if (response.success) {
showNotice('success', response.data.message);
} else {
showNotice('error', 'Erreur lors du nettoyage.');
}
},
error: function() {
showNotice('error', bankily_admin_ajax.strings.error);
}
});
};
function showNotice(type, message, autoHide = 5000) {
// Supprimer les anciennes notices
$('.bankily-notice').remove();
var noticeClass = 'notice-' + type;
var icon = {
'success': '✅',
'error': '❌',
'warning': '⚠️',
'info': ''
}[type] || '';
var noticeHtml = `
<div class="notice ${noticeClass} is-dismissible bankily-notice" style="position: relative; z-index: 999999;">
<p><strong>${icon} ${message}</strong></p>
<button type="button" class="notice-dismiss">
<span class="screen-reader-text">Ignorer cette notice.</span>
</button>
</div>
`;
// Ajouter la nouvelle notice
$('.wrap h1').first().after(noticeHtml);
// Gestion du bouton de fermeture
$('.notice-dismiss').on('click', function() {
$(this).closest('.notice').fadeOut();
});
// Auto-fermeture
if (autoHide && autoHide > 0) {
setTimeout(function() {
$('.bankily-notice').fadeOut();
}, autoHide);
}
// Faire défiler vers la notice
$('html, body').animate({
scrollTop: $('.bankily-notice').offset().top - 100
}, 300);
}
// Amélioration UX : Confirmation avant fermeture de page si traitement en cours
window.addEventListener('beforeunload', function(e) {
if (checking) {
e.preventDefault();
e.returnValue = 'Une vérification est en cours. Êtes-vous sûr de vouloir quitter ?';
return e.returnValue;
}
});
// Nettoyage lors du déchargement de la page
$(window).on('unload', function() {
if (autoRefreshInterval) {
clearTimeout(autoRefreshInterval);
}
checking = false;
});
// Stats en temps réel (si sur le tableau de bord)
if (window.location.href.indexOf('bankily-transactions') > -1 && window.location.href.indexOf('pending') === -1) {
setInterval(function() {
if (!checking) {
updateDashboardStats();
}
}, 60000); // Mettre à jour toutes les minutes
}
function updateDashboardStats() {
$.ajax({
url: bankily_admin_ajax.ajax_url,
type: 'POST',
data: {
action: 'bankily_get_dashboard_stats',
nonce: bankily_admin_ajax.nonce
},
success: function(response) {
if (response.success) {
updateStatCards(response.data);
}
},
error: function() {
console.log('Erreur lors de la mise à jour des stats');
}
});
}
function updateStatCards(stats) {
$('.bankily-stat-card.total h3').text(stats.total || 0);
$('.bankily-stat-card.success h3').text(stats.success || 0);
$('.bankily-stat-card.pending h3').text(stats.pending || 0);
$('.bankily-stat-card.failed h3').text(stats.failed || 0);
$('.bankily-stat-card.amount h3').text((stats.total_amount || 0).toLocaleString('fr-FR') + ' MRU');
}
// Log d'initialisation
console.log('[B-PAY Admin] Interface d\'administration initialisée', {
checking: checking,
page: window.location.href,
ajax_url: bankily_admin_ajax.ajax_url
});
});

435
assets/bankily-bpay.js Normal file
View File

@@ -0,0 +1,435 @@
/**
* Script JavaScript pour le frontend B-PAY Bankily
* Fichier: assets/bankily-bpay.js
* Version: 1.0.0
*/
jQuery(document).ready(function($) {
'use strict';
// Variables globales
var bankily_form = 'form.checkout, form#order_review';
var bankily_gateway = '#payment_method_bankily_bpay';
// Initialisation
initializeBankilyCheckout();
function initializeBankilyCheckout() {
// Gestion de la sélection de la méthode de paiement
$(document).on('change', 'input[name="payment_method"]', function() {
toggleBankilyFields();
if ($(this).val() === 'bankily_bpay') {
// Focus sur le premier champ et pré-remplir en mode test
setTimeout(function() {
$('#bankily_phone').focus();
if (bankily_bpay_params.testmode === '1') {
fillTestData();
}
}, 100);
}
});
// Validation en temps réel
setupRealtimeValidation();
// Formatage des champs
setupFieldFormatting();
// Gestion de la soumission
$(bankily_form).on('checkout_place_order_bankily_bpay', function() {
return validateBankilyForm();
});
// Stylisation CSS
addBankilyStyles();
// État initial
toggleBankilyFields();
}
function setupRealtimeValidation() {
// Validation du numéro de téléphone
$(document).on('input blur', '#bankily_phone', function() {
validatePhoneField($(this));
});
// Validation du code PIN
$(document).on('input blur', '#bankily_passcode', function() {
validatePasscodeField($(this));
});
}
function validatePhoneField($field) {
var phone = $field.val().replace(/\D/g, ''); // Supprimer tous les caractères non numériques
var isValid = /^[0-9]{8}$/.test(phone);
// Mettre à jour la valeur avec uniquement les chiffres
$field.val(phone);
// Validation visuelle
updateFieldValidation($field, isValid, phone.length > 0,
'Format requis: 8 chiffres (ex: 22123456)');
// Limiter à 8 chiffres
if (phone.length > 8) {
$field.val(phone.substring(0, 8));
}
}
function validatePasscodeField($field) {
var passcode = $field.val();
var isValid = passcode.length >= 4 && passcode.length <= 6;
updateFieldValidation($field, isValid, passcode.length > 0,
'Le code PIN doit contenir entre 4 et 6 caractères');
}
function updateFieldValidation($field, isValid, hasContent, errorMessage) {
$field.removeClass('valid invalid');
$field.next('.bankily-field-error').remove();
if (hasContent) {
if (isValid) {
$field.addClass('valid');
} else {
$field.addClass('invalid');
$field.after('<span class="bankily-field-error">' + errorMessage + '</span>');
}
}
}
function setupFieldFormatting() {
// Permettre uniquement les chiffres pour le téléphone
$(document).on('keypress', '#bankily_phone', function(e) {
// Permettre uniquement les chiffres, backspace, delete, tab, escape, enter
if ($.inArray(e.keyCode, [46, 8, 9, 27, 13]) !== -1 ||
// Permettre Ctrl+A, Ctrl+C, Ctrl+V, Ctrl+X
(e.keyCode === 65 && e.ctrlKey === true) ||
(e.keyCode === 67 && e.ctrlKey === true) ||
(e.keyCode === 86 && e.ctrlKey === true) ||
(e.keyCode === 88 && e.ctrlKey === true)) {
return;
}
// S'assurer que c'est un chiffre
if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
e.preventDefault();
}
});
// Permettre uniquement les chiffres pour le code PIN
$(document).on('keypress', '#bankily_passcode', function(e) {
if ($.inArray(e.keyCode, [46, 8, 9, 27, 13]) !== -1 ||
(e.keyCode === 65 && e.ctrlKey === true) ||
(e.keyCode === 67 && e.ctrlKey === true) ||
(e.keyCode === 86 && e.ctrlKey === true) ||
(e.keyCode === 88 && e.ctrlKey === true)) {
return;
}
if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
e.preventDefault();
}
});
}
function validateBankilyForm() {
if (!$(bankily_gateway).is(':checked')) {
return true; // Pas notre méthode de paiement
}
var isValid = true;
var $phone = $('#bankily_phone');
var $passcode = $('#bankily_passcode');
// Supprimer les anciens messages d'erreur
$('.bankily-checkout-error').remove();
// Validation du téléphone
var phone = $phone.val().replace(/\D/g, '');
if (!phone || !/^[0-9]{8}$/.test(phone)) {
showCheckoutError($phone, 'Veuillez entrer un numéro de téléphone valide (8 chiffres)');
isValid = false;
}
// Validation du code PIN
var passcode = $passcode.val();
if (!passcode || passcode.length < 4 || passcode.length > 6) {
showCheckoutError($passcode, 'Veuillez entrer votre code PIN B-PAY (4 à 6 chiffres)');
isValid = false;
}
if (!isValid) {
// Faire défiler vers le premier champ avec erreur
$('html, body').animate({
scrollTop: $('.payment_method_bankily_bpay').offset().top - 100
}, 500);
// Focus sur le premier champ invalide
setTimeout(function() {
$('.payment_method_bankily_bpay .invalid').first().focus();
}, 600);
}
return isValid;
}
function showCheckoutError($field, message) {
$field.addClass('invalid');
if (!$field.next('.bankily-checkout-error').length) {
$field.after('<div class="bankily-checkout-error">' + message + '</div>');
}
}
function toggleBankilyFields() {
if ($(bankily_gateway).is(':checked')) {
$('.payment_method_bankily_bpay').slideDown(300);
} else {
$('.payment_method_bankily_bpay').slideUp(300);
}
}
function fillTestData() {
if (bankily_bpay_params.testmode === '1') {
$('#bankily_phone').val('22123456');
$('#bankily_passcode').val('1234');
}
}
function addBankilyStyles() {
var styles = `
<style id="bankily-bpay-frontend-styles">
.payment_method_bankily_bpay .form-row input.valid {
border-color: #28a745 !important;
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25) !important;
}
.payment_method_bankily_bpay .form-row input.invalid {
border-color: #dc3545 !important;
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25) !important;
}
.bankily-field-error,
.bankily-checkout-error {
color: #dc3545;
font-size: 12px;
margin-top: 5px;
display: block;
animation: slideDown 0.3s ease;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.payment_method_bankily_bpay .form-row {
margin-bottom: 15px;
}
.payment_method_bankily_bpay label {
font-weight: 600;
margin-bottom: 5px;
display: block;
}
.payment_method_bankily_bpay input[type="tel"],
.payment_method_bankily_bpay input[type="password"] {
width: 100%;
padding: 10px 12px;
border: 2px solid #ddd;
border-radius: 4px;
font-size: 14px;
transition: border-color 0.3s, box-shadow 0.3s;
font-family: monospace;
}
.payment_method_bankily_bpay input[type="tel"]:focus,
.payment_method_bankily_bpay input[type="password"]:focus {
outline: none;
border-color: #007cba;
box-shadow: 0 0 0 0.2rem rgba(0, 124, 186, 0.25);
}
.payment_method_bankily_bpay small {
color: #666;
font-size: 12px;
margin-top: 3px;
display: block;
}
.bankily-test-notice {
background: #fff3cd !important;
border: 1px solid #ffeaa7 !important;
color: #856404 !important;
padding: 10px !important;
border-radius: 4px !important;
margin-bottom: 15px !important;
border-left: 4px solid #ffc107 !important;
}
#wc-bankily_bpay-form {
background: #f9f9f9;
padding: 20px;
border-radius: 5px;
margin-top: 10px;
border: 1px solid #e1e1e1;
}
/* Animation de chargement */
.payment_method_bankily_bpay.processing::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.8);
z-index: 10;
}
.payment_method_bankily_bpay.processing::before {
content: '⏳ Traitement en cours...';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 11;
background: #007cba;
color: white;
padding: 8px 15px;
border-radius: 4px;
font-size: 14px;
}
/* Responsive */
@media (max-width: 768px) {
#wc-bankily_bpay-form {
padding: 15px;
}
.payment_method_bankily_bpay input[type="tel"],
.payment_method_bankily_bpay input[type="password"] {
padding: 12px 14px;
font-size: 16px; /* Évite le zoom sur mobile */
}
}
</style>
`;
if (!$('#bankily-bpay-frontend-styles').length) {
$('head').append(styles);
}
}
// Gestion du chargement lors de la soumission
$(document).on('submit', bankily_form, function() {
if ($(bankily_gateway).is(':checked')) {
$('.payment_method_bankily_bpay').addClass('processing');
}
});
// Nettoyer l'état de chargement si la soumission échoue
$(document).on('checkout_error', function() {
$('.payment_method_bankily_bpay').removeClass('processing');
});
// Écouter les changements de checkout (pour WooCommerce AJAX)
$(document).on('updated_checkout', function() {
toggleBankilyFields();
// Réappliquer la validation sur les champs existants
setTimeout(function() {
$('#bankily_phone').trigger('blur');
$('#bankily_passcode').trigger('blur');
}, 100);
});
// Amélioration UX: Auto-complétion du préfixe
$(document).on('focus', '#bankily_phone', function() {
var $this = $(this);
if ($this.val() === '' && bankily_bpay_params.testmode !== '1') {
// Suggestion visuelle pour le format attendu
$this.attr('placeholder', '22XXXXXX');
}
});
$(document).on('blur', '#bankily_phone', function() {
$(this).attr('placeholder', 'Exemple: 22123456');
});
// Gestion des raccourcis clavier
$(document).on('keydown', '#bankily_phone, #bankily_passcode', function(e) {
// Enter pour aller au champ suivant
if (e.keyCode === 13) {
e.preventDefault();
var $current = $(this);
var $next = $current.closest('.form-row').next('.form-row').find('input');
if ($next.length) {
$next.focus();
} else {
// Si c'est le dernier champ, déclencher la soumission
$(bankily_form).find('.place-order').click();
}
}
});
// Validation immédiate lors du collage
$(document).on('paste', '#bankily_phone', function() {
var $this = $(this);
setTimeout(function() {
validatePhoneField($this);
}, 10);
});
// Messages d'aide contextuelle
$(document).on('focus', '#bankily_phone', function() {
if (!$(this).next('.bankily-help').length) {
$(this).after('<small class="bankily-help" style="color: #007cba;">💡 Saisissez votre numéro sans l\'indicatif (+222)</small>');
}
});
$(document).on('blur', '#bankily_phone', function() {
$(this).next('.bankily-help').fadeOut(300, function() {
$(this).remove();
});
});
$(document).on('focus', '#bankily_passcode', function() {
if (!$(this).next('.bankily-help').length) {
$(this).after('<small class="bankily-help" style="color: #007cba;">🔐 Votre code PIN personnel B-PAY</small>');
}
});
$(document).on('blur', '#bankily_passcode', function() {
$(this).next('.bankily-help').fadeOut(300, function() {
$(this).remove();
});
});
// Fonctions utilitaires
function logDebug(message, data) {
if (typeof console !== 'undefined' && console.log && bankily_bpay_params.testmode === '1') {
console.log('[B-PAY Frontend] ' + message, data || '');
}
}
// Log d'initialisation
logDebug('Script B-PAY initialisé', {
testmode: bankily_bpay_params.testmode,
gateway_selector: bankily_gateway
});
// Nettoyage lors du changement de page
$(window).on('beforeunload', function() {
$('.payment_method_bankily_bpay').removeClass('processing');
$('.bankily-field-error, .bankily-checkout-error, .bankily-help').remove();
});
});