- Implemented Gemini API service for generating optimized product titles and descriptions based on Google Merchant Center guidelines. - Added settings for Gemini API key and model selection in user settings. - Enhanced product management views to support AI-generated suggestions for titles and descriptions. - Enabled state saving for various data tables across campaign, terms, logs, and products views. - Introduced AI prompt templates for generating product descriptions and categories.
450 lines
11 KiB
PHP
450 lines
11 KiB
PHP
<div class="campaigns-page">
|
|
<div class="campaigns-header">
|
|
<h2><i class="fa-brands fa-facebook"></i> Facebook Ads</h2>
|
|
</div>
|
|
|
|
<div class="campaigns-filters">
|
|
<div class="filter-group">
|
|
<label for="fb_client_id"><i class="fa-solid fa-building"></i> Klient</label>
|
|
<select id="fb_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" style="min-width: 280px; flex: 1;">
|
|
<label for="fb_campaign_id"><i class="fa-solid fa-bullhorn"></i> Kampania</label>
|
|
<select id="fb_campaign_id" class="form-control">
|
|
<option value="">- wybierz kampanie -</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="filter-group" style="min-width: 280px; flex: 1;">
|
|
<label for="fb_ad_set_id"><i class="fa-solid fa-layer-group"></i> Zestaw reklam</label>
|
|
<select id="fb_ad_set_id" class="form-control">
|
|
<option value="">- wybierz zestaw reklam -</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="filter-group" style="min-width: 280px; flex: 1;">
|
|
<label for="fb_ad_id"><i class="fa-solid fa-rectangle-ad"></i> Reklama</label>
|
|
<select id="fb_ad_id" class="form-control">
|
|
<option value="">- wybierz reklame -</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="campaigns-chart-wrap">
|
|
<div id="fb_container"></div>
|
|
</div>
|
|
|
|
<div class="campaigns-table-wrap">
|
|
<table class="table" id="fb_history_table">
|
|
<thead>
|
|
<tr>
|
|
<th>Data</th>
|
|
<th>Spend</th>
|
|
<th>Impressions</th>
|
|
<th>Clicks</th>
|
|
<th>CTR</th>
|
|
<th>CPC</th>
|
|
<th>Wartosc konwersji</th>
|
|
<th>ROAS (30 dni)</th>
|
|
<th>ROAS (all time)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
var FB_FILTERS_KEY = 'facebook_ads_filters_v2';
|
|
|
|
function fb_save_filters_state()
|
|
{
|
|
var state = {
|
|
client_id: $( '#fb_client_id' ).val() || '',
|
|
campaign_id: $( '#fb_campaign_id' ).val() || '',
|
|
ad_set_id: $( '#fb_ad_set_id' ).val() || '',
|
|
ad_id: $( '#fb_ad_id' ).val() || ''
|
|
};
|
|
|
|
localStorage.setItem( FB_FILTERS_KEY, JSON.stringify( state ) );
|
|
}
|
|
|
|
function fb_load_filters_state()
|
|
{
|
|
try
|
|
{
|
|
var raw = localStorage.getItem( FB_FILTERS_KEY );
|
|
var parsed = JSON.parse( raw || '{}' );
|
|
|
|
return {
|
|
client_id: parsed.client_id || '',
|
|
campaign_id: parsed.campaign_id || '',
|
|
ad_set_id: parsed.ad_set_id || '',
|
|
ad_id: parsed.ad_id || ''
|
|
};
|
|
}
|
|
catch ( e )
|
|
{
|
|
return { client_id: '', campaign_id: '', ad_set_id: '', ad_id: '' };
|
|
}
|
|
}
|
|
|
|
function fb_get_filters()
|
|
{
|
|
var campaign_id = $( '#fb_campaign_id' ).val() || '';
|
|
var ad_set_id = $( '#fb_ad_set_id' ).val() || '';
|
|
var ad_id = $( '#fb_ad_id' ).val() || '';
|
|
|
|
var level = '';
|
|
var entity_id = '';
|
|
|
|
if ( ad_id )
|
|
{
|
|
level = 'ad';
|
|
entity_id = ad_id;
|
|
}
|
|
else if ( ad_set_id )
|
|
{
|
|
level = 'adset';
|
|
entity_id = ad_set_id;
|
|
}
|
|
else if ( campaign_id )
|
|
{
|
|
level = 'campaign';
|
|
entity_id = campaign_id;
|
|
}
|
|
|
|
return {
|
|
client_id: $( '#fb_client_id' ).val() || '',
|
|
campaign_id: campaign_id,
|
|
ad_set_id: ad_set_id,
|
|
ad_id: ad_id,
|
|
level: level,
|
|
entity_id: entity_id
|
|
};
|
|
}
|
|
|
|
function fb_reload_entities( level, options, done )
|
|
{
|
|
var filters = fb_get_filters();
|
|
var opts = options || {};
|
|
var selected_id = opts.selected_id || '';
|
|
var $entity = null;
|
|
var default_label = '';
|
|
|
|
if ( level === 'campaign' )
|
|
{
|
|
$entity = $( '#fb_campaign_id' );
|
|
default_label = '- wybierz kampanie -';
|
|
}
|
|
else if ( level === 'adset' )
|
|
{
|
|
$entity = $( '#fb_ad_set_id' );
|
|
default_label = '- wybierz zestaw reklam -';
|
|
}
|
|
else
|
|
{
|
|
$entity = $( '#fb_ad_id' );
|
|
default_label = '- wybierz reklame -';
|
|
}
|
|
|
|
$entity.empty().append( '<option value="">' + default_label + '</option>' );
|
|
|
|
if ( !filters.client_id )
|
|
{
|
|
if ( typeof done === 'function' )
|
|
{
|
|
done();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
var payload = { client_id: filters.client_id, level: level };
|
|
if ( level === 'adset' || level === 'ad' )
|
|
{
|
|
payload.campaign_id = filters.campaign_id;
|
|
}
|
|
if ( level === 'ad' )
|
|
{
|
|
payload.ad_set_id = filters.ad_set_id;
|
|
}
|
|
|
|
$.ajax( {
|
|
url: '/facebook_ads/get_entities',
|
|
type: 'POST',
|
|
dataType: 'json',
|
|
data: payload,
|
|
success: function( resp )
|
|
{
|
|
var rows = resp.entities || [];
|
|
|
|
rows.forEach( function( row )
|
|
{
|
|
var id = row.id;
|
|
var name = row.entity_name || ( '#' + ( row.external_id || id ) );
|
|
$entity.append( new Option( name, id ) );
|
|
} );
|
|
|
|
if ( selected_id && $entity.find( 'option[value="' + selected_id + '"]' ).length )
|
|
{
|
|
$entity.val( selected_id );
|
|
}
|
|
},
|
|
complete: function()
|
|
{
|
|
if ( typeof done === 'function' )
|
|
{
|
|
done();
|
|
}
|
|
}
|
|
} );
|
|
}
|
|
|
|
function fb_clear_chart_and_table()
|
|
{
|
|
if ( $.fn.DataTable.isDataTable( '#fb_history_table' ) )
|
|
{
|
|
$( '#fb_history_table' ).DataTable().destroy();
|
|
$( '#fb_history_table tbody' ).empty();
|
|
}
|
|
|
|
Highcharts.chart( 'fb_container', {
|
|
title: { text: '' },
|
|
series: []
|
|
} );
|
|
}
|
|
|
|
function fb_reload_table()
|
|
{
|
|
var filters = fb_get_filters();
|
|
var is_campaign = filters.level === 'campaign';
|
|
|
|
if ( $.fn.DataTable.isDataTable( '#fb_history_table' ) )
|
|
{
|
|
$( '#fb_history_table' ).DataTable().destroy();
|
|
$( '#fb_history_table tbody' ).empty();
|
|
}
|
|
|
|
if ( !filters.entity_id )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var columns = [
|
|
{ width: '130px', orderable: false, className: 'nowrap' },
|
|
{ width: '120px', orderable: false, className: 'dt-type-numeric' },
|
|
{ width: '120px', orderable: false, className: 'dt-type-numeric' },
|
|
{ width: '120px', orderable: false, className: 'dt-type-numeric' },
|
|
{ width: '120px', orderable: false, className: 'dt-type-numeric' },
|
|
{ width: '120px', orderable: false, className: 'dt-type-numeric' },
|
|
{ width: '140px', orderable: false, className: 'dt-type-numeric' },
|
|
{ width: '120px', orderable: false, className: 'dt-type-numeric' },
|
|
{ width: '140px', orderable: false, className: 'dt-type-numeric', visible: is_campaign }
|
|
];
|
|
|
|
new DataTable( '#fb_history_table', {
|
|
stateSave: true,
|
|
ajax: {
|
|
type: 'POST',
|
|
url: '/facebook_ads/get_history_data_table',
|
|
data: function( d )
|
|
{
|
|
d.level = filters.level;
|
|
d.entity_id = filters.entity_id;
|
|
}
|
|
},
|
|
processing: true,
|
|
serverSide: true,
|
|
searching: false,
|
|
lengthChange: false,
|
|
pageLength: 15,
|
|
order: [],
|
|
columns: columns,
|
|
language: {
|
|
processing: 'Ladowanie...',
|
|
emptyTable: 'Brak danych do wyswietlenia',
|
|
info: 'Wpisy _START_ - _END_ z _TOTAL_',
|
|
infoEmpty: '',
|
|
paginate: {
|
|
first: 'Pierwsza',
|
|
last: 'Ostatnia',
|
|
next: 'Dalej',
|
|
previous: 'Wstecz'
|
|
}
|
|
}
|
|
} );
|
|
}
|
|
|
|
function fb_reload_chart()
|
|
{
|
|
var filters = fb_get_filters();
|
|
|
|
Highcharts.chart( 'fb_container', {
|
|
title: { text: '' },
|
|
series: []
|
|
} );
|
|
|
|
if ( !filters.entity_id )
|
|
{
|
|
return;
|
|
}
|
|
|
|
$.ajax( {
|
|
url: '/facebook_ads/get_history_data_chart',
|
|
method: 'POST',
|
|
data: { level: filters.level, entity_id: filters.entity_id },
|
|
success: function( response )
|
|
{
|
|
var parsed = JSON.parse( response || '{}' );
|
|
var dates = parsed.dates || [];
|
|
var chart_data = parsed.chart_data || [];
|
|
|
|
Highcharts.chart( 'fb_container', {
|
|
chart: {
|
|
style: { fontFamily: '"Roboto", sans-serif' },
|
|
backgroundColor: 'transparent'
|
|
},
|
|
title: { text: '' },
|
|
xAxis: { categories: dates },
|
|
yAxis: { title: { text: '' } },
|
|
legend: {
|
|
layout: 'horizontal',
|
|
align: 'center',
|
|
verticalAlign: 'bottom'
|
|
},
|
|
colors: [ '#1877F2', '#57B951', '#FF8C00', '#8B5CF6', '#CC0000', '#1F9D8B', '#A16207', '#E91E63' ],
|
|
series: chart_data,
|
|
credits: { enabled: false }
|
|
} );
|
|
}
|
|
} );
|
|
}
|
|
|
|
function fb_reload_data()
|
|
{
|
|
fb_save_filters_state();
|
|
|
|
var filters = fb_get_filters();
|
|
if ( !filters.entity_id )
|
|
{
|
|
fb_clear_chart_and_table();
|
|
return;
|
|
}
|
|
|
|
fb_reload_table();
|
|
fb_reload_chart();
|
|
}
|
|
|
|
function fb_reload_campaigns( selected_id, done )
|
|
{
|
|
fb_reload_entities( 'campaign', { selected_id: selected_id }, done );
|
|
}
|
|
|
|
function fb_reload_ad_sets( selected_id, done )
|
|
{
|
|
fb_reload_entities( 'adset', { selected_id: selected_id }, done );
|
|
}
|
|
|
|
function fb_reload_ads( selected_id, done )
|
|
{
|
|
fb_reload_entities( 'ad', { selected_id: selected_id }, done );
|
|
}
|
|
|
|
$( function()
|
|
{
|
|
var saved = fb_load_filters_state();
|
|
|
|
if ( saved.client_id )
|
|
{
|
|
$( '#fb_client_id' ).val( saved.client_id );
|
|
}
|
|
|
|
$( 'body' ).on( 'change', '#fb_client_id', function()
|
|
{
|
|
$( '#fb_campaign_id' ).empty().append( '<option value="">- wybierz kampanie -</option>' );
|
|
$( '#fb_ad_set_id' ).empty().append( '<option value="">- wybierz zestaw reklam -</option>' );
|
|
$( '#fb_ad_id' ).empty().append( '<option value="">- wybierz reklame -</option>' );
|
|
|
|
fb_reload_campaigns( '', function()
|
|
{
|
|
fb_reload_data();
|
|
} );
|
|
} );
|
|
|
|
$( 'body' ).on( 'change', '#fb_campaign_id', function()
|
|
{
|
|
$( '#fb_ad_set_id' ).empty().append( '<option value="">- wybierz zestaw reklam -</option>' );
|
|
$( '#fb_ad_id' ).empty().append( '<option value="">- wybierz reklame -</option>' );
|
|
|
|
if ( !$( '#fb_campaign_id' ).val() )
|
|
{
|
|
fb_reload_data();
|
|
return;
|
|
}
|
|
|
|
fb_reload_ad_sets( '', function()
|
|
{
|
|
fb_reload_data();
|
|
} );
|
|
} );
|
|
|
|
$( 'body' ).on( 'change', '#fb_ad_set_id', function()
|
|
{
|
|
$( '#fb_ad_id' ).empty().append( '<option value="">- wybierz reklame -</option>' );
|
|
|
|
if ( !$( '#fb_ad_set_id' ).val() )
|
|
{
|
|
fb_reload_data();
|
|
return;
|
|
}
|
|
|
|
fb_reload_ads( '', function()
|
|
{
|
|
fb_reload_data();
|
|
} );
|
|
} );
|
|
|
|
$( 'body' ).on( 'change', '#fb_ad_id', function()
|
|
{
|
|
fb_reload_data();
|
|
} );
|
|
|
|
if ( $( '#fb_client_id' ).val() )
|
|
{
|
|
fb_reload_campaigns( saved.campaign_id, function()
|
|
{
|
|
if ( !$( '#fb_campaign_id' ).val() )
|
|
{
|
|
fb_reload_data();
|
|
return;
|
|
}
|
|
|
|
fb_reload_ad_sets( saved.ad_set_id, function()
|
|
{
|
|
if ( !$( '#fb_ad_set_id' ).val() )
|
|
{
|
|
fb_reload_data();
|
|
return;
|
|
}
|
|
|
|
fb_reload_ads( saved.ad_id, function()
|
|
{
|
|
fb_reload_data();
|
|
} );
|
|
} );
|
|
} );
|
|
}
|
|
else
|
|
{
|
|
fb_reload_data();
|
|
}
|
|
} );
|
|
</script>
|