feat: Dodaj funkcjonalność usuwania kampanii i wpisów historii oraz aktualizację interfejsu użytkownika
This commit is contained in:
@@ -41,6 +41,7 @@ class Campaigns
|
||||
'',
|
||||
$row['bidding_strategy'],
|
||||
\S::number_display( $row['budget'] ),
|
||||
'<button type="button" class="btn btn-danger btn-sm delete-history-entry" data-id="' . $row['id'] . '" data-date="' . $row['date_add'] . '"><i class="fa fa-trash"></i></button>',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -102,4 +103,36 @@ class Campaigns
|
||||
] );
|
||||
exit;
|
||||
}
|
||||
|
||||
static public function delete_campaign()
|
||||
{
|
||||
$campaign_id = \S::get( 'campaign_id' );
|
||||
|
||||
if ( !$campaign_id )
|
||||
{
|
||||
echo json_encode( [ 'success' => false, 'message' => 'Nie wybrano kampanii' ] );
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = \factory\Campaigns::delete_campaign( $campaign_id );
|
||||
|
||||
echo json_encode( [ 'success' => $result ? true : false ] );
|
||||
exit;
|
||||
}
|
||||
|
||||
static public function delete_history_entry()
|
||||
{
|
||||
$history_id = \S::get( 'history_id' );
|
||||
|
||||
if ( !$history_id )
|
||||
{
|
||||
echo json_encode( [ 'success' => false, 'message' => 'Nie podano wpisu do usunięcia' ] );
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = \factory\Campaigns::delete_history_entry( $history_id );
|
||||
|
||||
echo json_encode( [ 'success' => $result ? true : false ] );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,17 @@ class Campaigns
|
||||
global $mdb;
|
||||
return $mdb -> get( 'clients', 'name', [ 'id' => $client_id ] );
|
||||
}
|
||||
|
||||
static public function delete_campaign( $campaign_id )
|
||||
{
|
||||
global $mdb;
|
||||
$mdb -> delete( 'campaigns_history', [ 'campaign_id' => $campaign_id ] );
|
||||
return $mdb -> delete( 'campaigns', [ 'id' => $campaign_id ] );
|
||||
}
|
||||
|
||||
static public function delete_history_entry( $history_id )
|
||||
{
|
||||
global $mdb;
|
||||
return $mdb -> delete( 'campaigns_history', [ 'id' => $history_id ] );
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,21 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="field select">
|
||||
<select id="campaign_id" name="campaign_id">
|
||||
<option value="">--- wybierz kampanię ---</option>
|
||||
</select>
|
||||
<i class="arrow double"></i>
|
||||
</label>
|
||||
<div class="row">
|
||||
<div class="col-md-10">
|
||||
<label class="field select">
|
||||
<select id="campaign_id" name="campaign_id">
|
||||
<option value="">--- wybierz kampanię ---</option>
|
||||
</select>
|
||||
<i class="arrow double"></i>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="button" id="delete_campaign" class="btn btn-danger btn-block" title="Usuń kampanię">
|
||||
<i class="fa fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -42,7 +51,7 @@
|
||||
<table class="table" id="products">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Data</th>
|
||||
<th scope="col">Data</th>
|
||||
<th scope="col">ROAS (30 dni)</th>
|
||||
<th scope="col">ROAS (all time)</th>
|
||||
<th scope="col">Wartość konwersji (30 dni)</th>
|
||||
@@ -50,6 +59,7 @@
|
||||
<th scope="col">Komentarz</th>
|
||||
<th scope="col">Strategia ustalania stawek</th>
|
||||
<th scope="col">Budżet</th>
|
||||
<th scope="col">Akcje</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -61,6 +71,104 @@
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var client_id = '';
|
||||
|
||||
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) {
|
||||
const parsedData = JSON.parse(response);
|
||||
|
||||
let 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: '14px'
|
||||
}
|
||||
},
|
||||
zIndex: 5
|
||||
});
|
||||
});
|
||||
|
||||
Highcharts.chart('container', {
|
||||
title: {
|
||||
text: ``,
|
||||
},
|
||||
subtitle: {
|
||||
text: ``,
|
||||
},
|
||||
yAxis: {
|
||||
title: {
|
||||
text: ''
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
categories: parsedData.dates,
|
||||
labels: {
|
||||
style: {
|
||||
fontSize: '14px'
|
||||
},
|
||||
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}`;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
plotLines: plotLines
|
||||
},
|
||||
legend: {
|
||||
layout: 'vertical',
|
||||
align: 'right',
|
||||
verticalAlign: 'middle',
|
||||
itemStyle: {
|
||||
fontSize: '14px'
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
series: {
|
||||
label: {
|
||||
connectorAllowed: false
|
||||
},
|
||||
pointStart: 0,
|
||||
},
|
||||
},
|
||||
series: parsedData.chart_data,
|
||||
tooltip: {
|
||||
style: {
|
||||
fontSize: '14px'
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
console.error('Error AJAX:', textStatus, errorThrown);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$( function()
|
||||
{
|
||||
// load campaigns from server when client is selected
|
||||
@@ -106,6 +214,120 @@
|
||||
});
|
||||
});
|
||||
|
||||
$( '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 kampanię do usunięcia.',
|
||||
type: 'orange'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
$.confirm({
|
||||
title: 'Potwierdzenie usunięcia',
|
||||
content: 'Czy na pewno chcesz usunąć kampanię <strong>' + campaign_name + '</strong>?<br><br>Ta operacja jest nieodwracalna i usunie również całą historię kampanii.',
|
||||
type: 'red',
|
||||
buttons: {
|
||||
confirm: {
|
||||
text: 'Usuń',
|
||||
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 )
|
||||
{
|
||||
$.alert({
|
||||
title: 'Sukces',
|
||||
content: 'Kampania została usunięta.',
|
||||
type: 'green',
|
||||
autoClose: 'ok|2000'
|
||||
});
|
||||
$( '#client_id' ).trigger( 'change' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$.alert({
|
||||
title: 'Błąd',
|
||||
content: data.message || 'Nie udało się usunąć 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 usunięcia',
|
||||
content: 'Czy na pewno chcesz usunąć wpis z dnia <strong>' + date + '</strong>?',
|
||||
type: 'red',
|
||||
buttons: {
|
||||
confirm: {
|
||||
text: 'Usuń',
|
||||
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 został usunięty.',
|
||||
type: 'green',
|
||||
autoClose: 'ok|2000'
|
||||
});
|
||||
$( '#products' ).DataTable().ajax.reload( null, false );
|
||||
reloadChart();
|
||||
}
|
||||
else
|
||||
{
|
||||
$.alert({
|
||||
title: 'Błąd',
|
||||
content: data.message || 'Nie udało się usunąć wpisu.',
|
||||
type: 'red'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
text: 'Anuluj'
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$( 'body' ).on( 'change', '#campaign_id', function()
|
||||
{
|
||||
var campaign_id = $( this ).val();
|
||||
@@ -128,100 +350,12 @@
|
||||
{ width: '200px', name: 'spend30', orderable: false, className: "dt-type-numeric" },
|
||||
{ width: 'auto', name: 'bidding_strategy', orderable: false },
|
||||
{ width: 'auto', name: 'comment', orderable: false },
|
||||
{ width: '150px', name: 'budget', orderable: false, className: "dt-type-numeric" }
|
||||
{ width: '150px', name: 'budget', orderable: false, className: "dt-type-numeric" },
|
||||
{ width: '80px', name: 'actions', orderable: false, className: "dt-center" }
|
||||
],
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: '/campaigns/get_campaign_history_data_table_chart/',
|
||||
method: 'POST',
|
||||
data: {
|
||||
campaign_id: campaign_id
|
||||
},
|
||||
success: function(response) {
|
||||
const parsedData = JSON.parse(response);
|
||||
|
||||
let 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: '14px'
|
||||
}
|
||||
},
|
||||
zIndex: 5
|
||||
});
|
||||
});
|
||||
|
||||
Highcharts.chart('container', {
|
||||
title: {
|
||||
text: ``,
|
||||
},
|
||||
subtitle: {
|
||||
text: ``,
|
||||
},
|
||||
yAxis: {
|
||||
title: {
|
||||
text: ''
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
categories: parsedData.dates,
|
||||
labels: {
|
||||
style: {
|
||||
fontSize: '14px'
|
||||
},
|
||||
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}`;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
plotLines: plotLines
|
||||
},
|
||||
legend: {
|
||||
layout: 'vertical',
|
||||
align: 'right',
|
||||
verticalAlign: 'middle',
|
||||
itemStyle: {
|
||||
fontSize: '14px'
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
series: {
|
||||
label: {
|
||||
connectorAllowed: false
|
||||
},
|
||||
pointStart: 0,
|
||||
},
|
||||
},
|
||||
series: parsedData.chart_data,
|
||||
tooltip: {
|
||||
style: {
|
||||
fontSize: '14px'
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
console.error('Error AJAX:', textStatus, errorThrown);
|
||||
}
|
||||
})
|
||||
reloadChart();
|
||||
})
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user