feat: Implement campaign synchronization feature with dropdown UI
- Updated SCSS styles for new campaign sync buttons and dropdowns. - Refactored main_view.php to replace the single select for campaigns with a multi-select dropdown. - Added JavaScript functions to handle dropdown interactions and sync status updates. - Introduced sync status bars for clients in main_view.php. - Created new database migrations for client sync flags and cron sync status tracking.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
<th>Google Ads Customer ID</th>
|
||||
<th>Merchant Account ID</th>
|
||||
<th>Dane od</th>
|
||||
<th style="width: 160px;">Sync</th>
|
||||
<th style="width: 120px; text-align: center;">Akcje</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -45,7 +46,13 @@
|
||||
<span class="text-muted">— brak —</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="client-sync" data-sync-id="<?= $client['id']; ?>"><span class="text-muted">—</span></td>
|
||||
<td class="actions-cell">
|
||||
<?php if ( $client['google_ads_customer_id'] ): ?>
|
||||
<button type="button" class="btn-icon btn-icon-sync" onclick="syncClient(<?= $client['id']; ?>, this)" title="Pobierz dane z Google Ads">
|
||||
<i class="fa-solid fa-rotate"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="btn-icon btn-icon-edit" onclick="editClient(<?= $client['id']; ?>)" title="Edytuj">
|
||||
<i class="fa-solid fa-pen"></i>
|
||||
</button>
|
||||
@@ -57,7 +64,7 @@
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="6" class="empty-state">
|
||||
<td colspan="7" class="empty-state">
|
||||
<i class="fa-solid fa-building"></i>
|
||||
<p>Brak klientów. Dodaj pierwszego klienta.</p>
|
||||
</td>
|
||||
@@ -135,6 +142,43 @@ function editClient( id )
|
||||
} );
|
||||
}
|
||||
|
||||
function syncClient( id, btn )
|
||||
{
|
||||
var $btn = $( btn );
|
||||
var $icon = $btn.find( 'i' );
|
||||
|
||||
$btn.prop( 'disabled', true );
|
||||
$icon.removeClass( 'fa-rotate' ).addClass( 'fa-spinner fa-spin' );
|
||||
|
||||
$.post( '/clients/force_sync', { id: id }, function( response )
|
||||
{
|
||||
var data = JSON.parse( response );
|
||||
|
||||
$btn.prop( 'disabled', false );
|
||||
$icon.removeClass( 'fa-spinner fa-spin' ).addClass( 'fa-rotate' );
|
||||
|
||||
if ( data.success )
|
||||
{
|
||||
$btn.addClass( 'is-queued' );
|
||||
|
||||
$.alert({
|
||||
title: 'Zakolejkowano',
|
||||
content: 'Klient zostal oznaczony do ponownej synchronizacji. Przy najblizszym uruchomieniu CRON dane kampanii i produktow zostana pobrane od nowa dla calego okna konwersji.',
|
||||
type: 'green',
|
||||
autoClose: 'ok|3000'
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
$.alert({
|
||||
title: 'Blad',
|
||||
content: data.message || 'Nie udalo sie oznaczyc klienta.',
|
||||
type: 'red'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteClient( id, name )
|
||||
{
|
||||
$.confirm( {
|
||||
@@ -177,4 +221,50 @@ $( document ).on( 'keydown', function( e ) {
|
||||
$( '#client-modal' ).on( 'click', function( e ) {
|
||||
if ( e.target === this ) closeClientForm();
|
||||
} );
|
||||
|
||||
// --- Sync status bars ---
|
||||
function renderSyncBar( label, done, total )
|
||||
{
|
||||
var pct = total > 0 ? Math.round( done / total * 100 ) : 0;
|
||||
var cls = pct >= 100 ? 'is-done' : ( pct > 0 ? 'is-active' : '' );
|
||||
|
||||
return '<div class="client-sync-row">' +
|
||||
'<span class="client-sync-label">' + label + '</span>' +
|
||||
'<div class="client-sync-track"><div class="client-sync-fill ' + cls + '" style="width:' + pct + '%"></div></div>' +
|
||||
'<span class="client-sync-pct">' + pct + '%</span>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
function loadSyncStatus()
|
||||
{
|
||||
$.getJSON( '/clients/sync_status', function( resp )
|
||||
{
|
||||
if ( resp.status !== 'ok' ) return;
|
||||
|
||||
$( '.client-sync' ).each( function()
|
||||
{
|
||||
var $cell = $( this );
|
||||
var id = $cell.data( 'sync-id' );
|
||||
var info = resp.data[ id ];
|
||||
|
||||
if ( !info )
|
||||
{
|
||||
$cell.html( '<span class="text-muted">—</span>' );
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '<div class="client-sync-bars">';
|
||||
if ( info.campaigns ) html += renderSyncBar( 'K:', info.campaigns[0], info.campaigns[1] );
|
||||
if ( info.products ) html += renderSyncBar( 'P:', info.products[0], info.products[1] );
|
||||
html += '</div>';
|
||||
|
||||
$cell.html( html );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
$( document ).ready( function() {
|
||||
loadSyncStatus();
|
||||
setInterval( loadSyncStatus, 15000 );
|
||||
} );
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user