Files
adsPRO/templates/campaigns/main_view.php
Jacek Pyziak 4635cefcbb feat: update font to Roboto across templates and add campaign/ad group filters in product views
- Changed font from Open Sans to Roboto in layout files.
- Added campaign and ad group filters in products main view.
- Enhanced product history to include campaign and ad group IDs.
- Updated migrations to support new campaign and ad group dimensions in product statistics.
- Introduced new migration files for managing campaign types and dropping obsolete columns.
2026-02-18 01:21:22 +01:00

401 lines
12 KiB
PHP

<div class="campaigns-page">
<div class="campaigns-header">
<h2><i class="fa-solid fa-chart-line"></i> Kampanie</h2>
</div>
<div class="campaigns-filters">
<div class="filter-group">
<label for="client_id"><i class="fa-solid fa-building"></i> Klient</label>
<select id="client_id" name="client_id" class="form-control">
<option value="">- wybierz klienta -</option>
<?php foreach ( $this -> clients as $client ): ?>
<option value="<?= $client['id']; ?>"><?= htmlspecialchars( $client['name'] ); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="filter-group">
<label for="campaign_id"><i class="fa-solid fa-bullhorn"></i> Kampania</label>
<div class="filter-with-action">
<select id="campaign_id" name="campaign_id" class="form-control">
<option value="">- wybierz kampanie -</option>
</select>
<button type="button" id="delete_campaign" class="btn-icon btn-icon-delete" title="Usun kampanie">
<i class="fa-solid fa-trash"></i>
</button>
</div>
</div>
</div>
<div class="campaigns-chart-wrap">
<div id="container"></div>
</div>
<div class="campaigns-table-wrap">
<table class="table" id="products">
<thead>
<tr>
<th>Data</th>
<th>ROAS (30 dni)</th>
<th>ROAS (all time)</th>
<th>Wartosc konwersji (30 dni)</th>
<th>Wydatki (30 dni)</th>
<th>Komentarz</th>
<th>Strategia ustalania stawek</th>
<th>Budzet</th>
<th style="width: 60px; text-align: center;">Akcje</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<script type="text/javascript">
var STORAGE_CLIENT_KEY = 'campaigns.last_client_id';
var STORAGE_CAMPAIGN_KEY = 'campaigns.last_campaign_id';
var restore_campaign_after_client_load = '';
function storage_set( key, value )
{
try
{
if ( value === null || value === undefined || value === '' )
localStorage.removeItem( key );
else
localStorage.setItem( key, String( value ) );
}
catch ( e ) {}
}
function storage_get( key )
{
try
{
return localStorage.getItem( key ) || '';
}
catch ( e )
{
return '';
}
}
function reloadChart()
{
var campaign_id = $( '#campaign_id' ).val();
if ( !campaign_id ) return;
$.ajax({
url: '/campaigns/get_campaign_history_data_table_chart/',
method: 'POST',
data: { campaign_id: campaign_id },
success: function( response )
{
var parsedData = JSON.parse( response );
var plotLines = [];
parsedData.comments.forEach( function( comment ) {
plotLines.push({
color: '#333333',
width: 1,
value: parsedData.dates.indexOf( comment.date_add.split(' ')[0] ),
dashStyle: 'Solid',
label: {
text: comment.comment,
align: 'left',
style: { color: '#333333', fontSize: '13px' }
},
zIndex: 5
});
});
Highcharts.chart( 'container', {
chart: {
style: { fontFamily: '"Roboto", sans-serif' },
backgroundColor: 'transparent'
},
title: { text: '' },
subtitle: { text: '' },
yAxis: {
title: { text: '' },
gridLineColor: '#E2E8F0'
},
xAxis: {
categories: parsedData.dates,
labels: {
style: { fontSize: '12px', color: '#8899A6' },
formatter: function() {
var date = new Date( Date.parse( this.value ) );
var day = date.getDate();
var month = date.getMonth() + 1;
var year = date.getFullYear();
if ( day === 1 || this.isLast ) {
return year + '-' + ( month < 10 ? '0' + month : month ) + '-' + ( day < 10 ? '0' + day : day );
}
return null;
}
},
plotLines: plotLines
},
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom',
itemStyle: { fontSize: '13px', color: '#4E5E6A' }
},
plotOptions: {
series: {
label: { connectorAllowed: false },
pointStart: 0
}
},
colors: ['#6690F4', '#57B951', '#FF8C00', '#CC0000', '#8B5CF6'],
series: parsedData.chart_data,
tooltip: { style: { fontSize: '13px' } },
credits: { enabled: false }
});
},
error: function( jqXHR, textStatus, errorThrown ) {
console.error( 'Error AJAX:', textStatus, errorThrown );
}
});
}
$( function()
{
$( 'body' ).on( 'change', '#client_id', function()
{
var client_id = $( this ).val();
storage_set( STORAGE_CLIENT_KEY, client_id );
var campaigns_select = $( '#campaign_id' );
var campaign_to_restore = restore_campaign_after_client_load;
if ( !campaign_to_restore )
storage_set( STORAGE_CAMPAIGN_KEY, '' );
campaigns_select.empty();
campaigns_select.append( '<option value="">- wybierz kampanie -</option>' );
if ( !client_id )
return;
$.ajax({
url: '/campaigns/get_campaigns_list/client_id=' + client_id,
type: 'GET',
success: function( response )
{
var data = JSON.parse( response );
var campaigns = Object.entries( data.campaigns || {} );
campaigns.sort( function( a, b ) {
var nameA = String( ( a[1] && a[1].campaign_name ) ? a[1].campaign_name : '' ).toLowerCase();
var nameB = String( ( b[1] && b[1].campaign_name ) ? b[1].campaign_name : '' ).toLowerCase();
if ( nameA === '--- konto ---' ) return -1;
if ( nameB === '--- konto ---' ) return 1;
if ( nameA > nameB ) return 1;
if ( nameA < nameB ) return -1;
return 0;
});
campaigns.forEach( function( pair ) {
var value = pair[1];
campaigns_select.append( '<option value="' + value.id + '">' + value.campaign_name + '</option>' );
});
if ( campaign_to_restore && campaigns_select.find( 'option[value="' + campaign_to_restore + '"]' ).length )
{
campaigns_select.val( campaign_to_restore ).trigger( 'change' );
}
else
{
var account_option = campaigns_select.find( 'option' ).filter( function() {
return $.trim( $( this ).text() ).toLowerCase() === '--- konto ---';
} ).first();
if ( account_option.length )
campaigns_select.val( account_option.val() ).trigger( 'change' );
}
restore_campaign_after_client_load = '';
}
});
});
$( 'body' ).on( 'click', '#delete_campaign', function()
{
var campaign_id = $( '#campaign_id' ).val();
var campaign_name = $( '#campaign_id option:selected' ).text();
if ( !campaign_id )
{
$.alert({
title: 'Uwaga',
content: 'Najpierw wybierz kampanie do usuniecia.',
type: 'orange'
});
return;
}
$.confirm({
title: 'Potwierdzenie usuniecia',
content: 'Czy na pewno chcesz usunac kampanie <strong>' + campaign_name + '</strong>?<br><br>Ta operacja jest nieodwracalna i usunie rowniez cala historie kampanii.',
type: 'red',
buttons: {
confirm: {
text: 'Usun',
btnClass: 'btn-red',
keys: ['enter'],
action: function()
{
$.ajax({
url: '/campaigns/delete_campaign/campaign_id=' + campaign_id,
type: 'POST',
success: function( response )
{
var data = JSON.parse( response );
if ( data.success )
{
if ( storage_get( STORAGE_CAMPAIGN_KEY ) === String( campaign_id ) )
storage_set( STORAGE_CAMPAIGN_KEY, '' );
$.alert({
title: 'Sukces',
content: 'Kampania zostala usunieta.',
type: 'green',
autoClose: 'ok|2000'
});
$( '#client_id' ).trigger( 'change' );
}
else
{
$.alert({
title: 'Blad',
content: data.message || 'Nie udalo sie usunac kampanii.',
type: 'red'
});
}
}
});
}
},
cancel: { text: 'Anuluj' }
}
});
});
$( 'body' ).on( 'click', '.delete-history-entry', function()
{
var btn = $( this );
var history_id = btn.data( 'id' );
var date = btn.data( 'date' );
$.confirm({
title: 'Potwierdzenie usuniecia',
content: 'Czy na pewno chcesz usunac wpis z dnia <strong>' + date + '</strong>?',
type: 'red',
buttons: {
confirm: {
text: 'Usun',
btnClass: 'btn-red',
keys: ['enter'],
action: function()
{
$.ajax({
url: '/campaigns/delete_history_entry/history_id=' + history_id,
type: 'POST',
success: function( response )
{
var data = JSON.parse( response );
if ( data.success )
{
$.alert({
title: 'Sukces',
content: 'Wpis zostal usuniety.',
type: 'green',
autoClose: 'ok|2000'
});
if ( $.fn.DataTable.isDataTable( '#products' ) )
$( '#products' ).DataTable().ajax.reload( null, false );
reloadChart();
}
else
{
$.alert({
title: 'Blad',
content: data.message || 'Nie udalo sie usunac wpisu.',
type: 'red'
});
}
}
});
}
},
cancel: { text: 'Anuluj' }
}
});
});
$( 'body' ).on( 'change', '#campaign_id', function()
{
var campaign_id = $( this ).val();
storage_set( STORAGE_CAMPAIGN_KEY, campaign_id );
if ( $.fn.DataTable.isDataTable( '#products' ) )
{
$( '#products' ).DataTable().destroy();
$( '#products tbody' ).empty();
}
if ( !campaign_id )
return;
new DataTable( '#products', {
ajax: {
type: 'POST',
url: '/campaigns/get_campaign_history_data_table/campaign_id=' + campaign_id,
},
processing: true,
serverSide: true,
searching: false,
lengthChange: false,
pageLength: 15,
columns: [
{ width: '130px', name: 'date', orderable: false, className: "nowrap" },
{ width: '120px', name: 'roas30', orderable: false, className: "dt-type-numeric" },
{ width: '120px', name: 'roas_all_time', orderable: false, className: "dt-type-numeric" },
{ width: '180px', name: 'conversion_value', orderable: false, className: "dt-type-numeric" },
{ width: '140px', name: 'spend30', orderable: false, className: "dt-type-numeric" },
{ width: 'auto', name: 'comment', orderable: false },
{ width: 'auto', name: 'bidding_strategy', orderable: false },
{ width: '100px', name: 'budget', orderable: false, className: "dt-type-numeric" },
{ width: '60px', name: 'actions', orderable: false, className: "dt-center" }
],
language: {
processing: 'Ladowanie...',
emptyTable: 'Brak danych do wyswietlenia',
info: 'Wpisy _START_ - _END_ z _TOTAL_',
infoEmpty: '',
lengthMenu: 'Pokaz _MENU_ wpisow',
paginate: {
first: 'Pierwsza',
last: 'Ostatnia',
next: 'Dalej',
previous: 'Wstecz'
}
}
});
reloadChart();
});
var saved_client_id = storage_get( STORAGE_CLIENT_KEY );
var saved_campaign_id = storage_get( STORAGE_CAMPAIGN_KEY );
if ( saved_client_id && $( '#client_id option[value="' + saved_client_id + '"]' ).length )
{
restore_campaign_after_client_load = saved_campaign_id;
$( '#client_id' ).val( saved_client_id ).trigger( 'change' );
}
});
</script>