File: /home/retile.ru/public_html/admin/view/template/extension/advertise/google_campaign.twig
{{ header }}
{{ column_left }}
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<a href="{{ text_video_tutorial_url_install }}" target="_blank" class="btn btn-info" data-toggle="tooltip" title="{{ button_video_tutorial_install }}"><i class="fa fa-video-camera"></i></a>
<a href="{{ cancel }}" class="btn btn-default" data-toggle="tooltip" title="{{ button_cancel }}"><i class="fa fa-reply"></i></a>
</div>
<h1>{{ heading_title }}</h1>
<ul class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="container-fluid">
{% if not from_dashboard %}
{{ steps }}
{% endif %}
<div id="alerts">
{% if success %}
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="{{ text_close }}"><span aria-hidden="true"><i class="fa fa-close"></i></span></button>
<i class="fa fa-check-circle" aria-hidden="true"></i> {{ success }}
</div>
{% endif %}
{% if error %}
<div class="alert alert-danger alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="{{ text_close }}"><span aria-hidden="true"><i class="fa fa-close"></i></span></button>
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i> {{ error }}
</div>
{% endif %}
{% if warning %}
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="{{ text_close }}"><i class="fa fa-close"></i></button>
<i class="fa fa-info-circle"></i> {{ warning }}
</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-9">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<i class="fa fa-pencil"></i>
<span>
{% if from_dashboard %}
{{ text_panel_heading_campaign_2 }}
{% else %}
{{ text_panel_heading_campaign }}
{% endif %}
</span>
</h3>
</div>
<div class="panel-body">
<form action="{{ action }}" method="post" enctype="multipart/form-data" id="form" class="form-horizontal">
<div class="form-group required">
<label class="col-sm-2 control-label">{{ entry_campaign }}</label>
<div class="col-sm-10">
<div id="targets">
{% if targets %}
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th class="text-left">{{ entry_campaign_name }}</th>
<th class="text-center">{{ entry_country }}</th>
<th class="text-center">{{ entry_budget }}</th>
<th class="text-left">{{ entry_feed }}</th>
<th class="text-center">{{ entry_roas }}</th>
<th class="text-center">{{ entry_status }}</th>
<th class="text-right">{{ entry_action }}</th>
</tr>
</thead>
<tbody id="list">
{% for target in targets %}
<tr>
<td class="text-left">{{ target.campaign_name }}</td>
<td class="text-center">{{ target.country.name }}</td>
<td class="text-center">{{ target.budget.formatted }}</td>
<td class="text-left">
<ul>
{% for feed in target.feeds %}
<li>{{ feed.text }}</li>
{% endfor %}
</ul>
</td>
<td class="text-center">
{% if target.roas_status %}
{{ target.roas }}%
{% else %}
<span class="label label-default" data-toggle="tooltip" data-original-title="{{ target.roas_warning }}">{{ text_label_unavailable }}</span>
{% endif %}
</td>
<td class="text-center">
{% if target.status == 'paused' %}
<span class="label label-warning">{{ text_label_paused }}</span>
{% elseif target.status == 'active' %}
<span class="label label-success">{{ text_label_active }}</span>
{% endif %}
</td>
<td class="text-right">
<button class="btn btn-primary button-target-edit" data-toggle="tooltip" title="{{ button_edit }}" data-target-id="{{ target.target_id }}"><i class="fa fa-pencil"></i></button>
<button class="btn btn-danger button-target-delete" data-toggle="tooltip" title="{{ button_delete }}" data-target-id="{{ target.target_id }}"><i class="fa fa-trash"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="alert alert-warning"><i class="fa fa-warning"></i> {{ text_no_targets }}</div>
{% endif %}
</div>
<div>
<button id="button-target-add" class="btn btn-default"><i class="fa fa-plus"></i> {{ button_add_target }}</button>
</div>
</div>
</div>
<!--div class="form-group">
<label class="col-sm-2 control-label">{{ entry_auto_advertise }}</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="advertise_google_auto_advertise" value="1" {{ advertise_google_auto_advertise == '1' ? 'checked="checked"' }}>
{{ text_yes }}
</label>
<label class="radio-inline">
<input type="radio" name="advertise_google_auto_advertise" value="0" {{ advertise_google_auto_advertise == '0' ? 'checked="checked"' }}>
{{ text_no }}
</label>
</div>
</div-->
<hr />
{% if not from_dashboard %}
<div class="alert alert-info text-left">
<div class="checkbox">
<label><input type="checkbox" class="acknowledge" /> {{ text_acknowledge_add_campaign_1 }}</label>
</div>
<div class="checkbox">
<label><input type="checkbox" class="acknowledge" /> {{ text_acknowledge_add_campaign_2 }}</label>
</div>
</div>
{% endif %}
<div class="pull-right">
<button type="submit" {{ not from_dashboard ? 'disabled' }} class="btn btn-primary" id="proceed">{{ button_proceed }}</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-info-circle"></i> <span>{{ text_panel_heading_more_info }}</span></h3>
</div>
<div class="panel-body">
{{ text_campaign_more_info }}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-image"></i> <span>{{ text_panel_heading_preview }}</span></h3>
</div>
<div class="panel-body text-center">
<img id="ad-preview" src="view/image/advertise/google/ad-preview.png" />
</div>
</div>
</div>
</div>
</div>
<style type="text/css">
.feed {
position: relative;
}
.feed > .row {
padding-right: 60px;
}
.button-feed-delete {
position: absolute;
top: 9px;
right: 0;
}
#feeds > .feed:first-child > .row {
margin-top: -9px;
}
#ad-preview {
max-width: 100%;
}
</style>
<script type="text/template" id="template-targets">
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th class="text-left">{{ entry_campaign_name }}</th>
<th class="text-center">{{ entry_country }}</th>
<th class="text-center">{{ entry_budget }}</th>
<th class="text-left">{{ entry_feed }}</th>
<th class="text-center">{{ entry_roas }}</th>
<th class="text-center">{{ entry_status }}</th>
<th class="text-right">{{ entry_action }}</th>
</tr>
</thead>
<tbody id="list">
</tbody>
</table>
</div>
</script>
<script type="text/template" id="template-list-element">
<tr>
<td class="text-left">{campaign_name}</td>
<td class="text-center">{country}</td>
<td class="text-center">{budget}</td>
<td class="text-left">{feeds}</td>
<td class="text-center">{roas}</td>
<td class="text-center">{status}</td>
<td class="text-right">
<button class="btn btn-primary button-target-edit" data-toggle="tooltip" title="{{ button_edit }}" data-target-id="{target_id}"><i class="fa fa-pencil"></i></button>
<button class="btn btn-danger button-target-delete" data-toggle="tooltip" title="{{ button_delete }}" data-target-id="{target_id}"><i class="fa fa-trash"></i></button>
</td>
</tr>
</script>
<script type="text/template" id="template-modal">
<div id="target-modal" class="modal fade" tabindex="-1" role="dialog" data-backdrop="static">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><i class="fa fa-close"></i></button>
<h4 class="modal-title">{title}</h4>
</div>
<div class="modal-body form-horizontal">
<div id="target-alerts"></div>
<div class="form-group required" data-error-type="error_campaign_name">
<label for="input-campaign-name" class="col-sm-3 control-label">{{ entry_campaign_name }}</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="input-campaign-name" name="campaign_name" value="{campaign_name}" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{{ entry_status }}</label>
<div class="col-sm-9">
<select class="form-control" name="status" id="select-status" data-value="{status}">
<option value="active">{{ text_active }}</option>
<option value="paused">{{ text_paused }}</option>
</select>
</div>
</div>
<div class="form-group required" data-error-type="error_country">
<label for="select-country" class="col-sm-3 control-label">{{ entry_country }}</label>
<div class="col-sm-9">
<select class="form-control" name="country" id="select-country" data-value="{country}">
<option value="">{{ text_select_country }}</option>
</select>
</div>
</div>
<div class="form-group" data-error-type="error_roas">
<label for="input-roas" class="col-sm-3 control-label">{{ entry_roas }}</label>
<div class="col-sm-9">
<div class="alert alert-info"><i class="fa fa-info-circle"></i> {{ help_roas }}</div>
<div id="warning-roas" class="alert alert-warning" style="display: none;"><i class="fa fa-exclamation-triangle"></i> {roas_warning}</div>
<div class="input-group">
<input type="number" class="form-control" id="input-roas" name="roas" value="{roas}" min="0" />
<div class="input-group-addon"><i class="fa fa-percent"></i></div>
</div>
</div>
</div>
<div class="form-group required" data-error-type="error_budget">
<label for="input-budget" class="col-sm-3 control-label">{{ entry_budget }}</label>
<div class="col-sm-9">
<div class="alert alert-info"><i class="fa fa-info-circle"></i> {{ help_budget }}</div>
<div id="warning-budget" class="alert alert-warning" style="display: none;"><i class="fa fa-exclamation-triangle"></i> {{ warning_budget }}</div>
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-dollar"></i></div>
<input type="number" class="form-control" id="input-budget" name="budget" value="{budget}" min="5" />
<div class="input-group-addon">{{ text_usd_day }}</div>
</div>
</div>
</div>
<div class="form-group required" data-error-type="error_feed">
<label class="col-sm-3 control-label">{{ entry_feed }}</label>
<div class="col-sm-9">
<div class="alert alert-info"><i class="fa fa-info-circle"></i> {{ help_feed }}</div>
<div id="feeds">{feeds}</div>
<div>
<button id="button-feed-add" class="btn btn-success"><i class="fa fa-plus"></i> {{ button_add_feed }}</button>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><i class="fa fa-close"></i> {{ button_close }}</button>
<button type="button" class="btn btn-primary" id="button-target-save" data-text="{{ button_save }}" data-loading="{{ text_loading_please_wait }}" data-url="{url}"><i class="fa fa-save"></i> {{ button_save }}</button>
</div>
</div>
</div>
</div>
</script>
<script type="text/template" id="template-feed">
<div class="feed" data-id="{id}">
<div class="row">
<div class="col-md-6 form-control-static">
<select class="form-control" name="feed[{id}][language]" data-value="{language}">
<option value="">{{ text_select_language }}</option>
{languages}
</select>
</div>
<div class="col-md-6 form-control-static">
<select class="form-control" name="feed[{id}][currency]" data-value="{currency}">
<option value="">{{ text_select_currency }}</option>
{currencies}
</select>
</div>
</div>
<button class="button-feed-delete btn btn-default" data-toggle="tooltip" title="{{ button_delete }}"><i class="fa fa-trash"></i></button>
</div>
</script>
<script type="text/template" id="template-alert">
<div class="alert alert-{type} alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="{{ text_close }}"><span aria-hidden="true"><i class="fa fa-close"></i></span></button>
<i class="fa fa-{icon}" aria-hidden="true"></i> {message}
</div>
</script>
<script type="text/javascript">
(function($) {
var allowed_targets = {{ json_allowed_targets }};
var targets = {{ json_targets }};
var id = 0;
var selector = {
alerts: '#alerts',
acknowledge: '.acknowledge',
save: '#proceed',
form: '#form',
target: {
container: '#targets',
list: '#list',
modal: '#target-modal',
alerts: '#target-alerts',
add : '#button-target-add',
edit: '.button-target-edit',
delete: '.button-target-delete',
country : '#select-country',
status : '#select-status',
save: '#button-target-save',
budget: '#input-budget',
warning_budget: '#warning-budget',
roas: '#input-roas',
warning_roas: '#warning-roas'
},
feed: {
container: '#feeds',
error_type: '[data-error-type]',
language: 'select[name*="[language]"]',
currency: 'select[name*="[currency]"]',
add : '#button-feed-add',
delete: '.button-feed-delete',
row: '.feed'
},
template : {
alert: '#template-alert',
modal : '#template-modal',
feed : '#template-feed',
targets: '#template-targets',
list_element: '#template-list-element'
}
};
var template = function(html, data) {
$.map(data, function(text, key) {
html = html.replace(new RegExp("{" + key + "}", 'g'), text);
});
return html;
};
var makeModalHtml = function(data) {
var html = $(selector.template.modal).html();
return template(html, data);
};
var makeFeedsHtml = function(data) {
var html = $(selector.template.feed).html();
data.languages = '';
data.currencies = '';
// Set the feed countries
$(allowed_targets).each(function(index, target) {
if (target.country.code == $(selector.target.country).val()) {
$(target.languages).each(function(index, language) {
data.languages += '<option value="' + language.code + '" ' + (language.status ? '' : 'disabled') + '>' + language.name + '</option>';
});
$(target.currencies).each(function(index, currency) {
data.currencies += '<option value="' + currency.code + '" ' + (currency.status ? '' : 'disabled') + '>' + currency.name + '</option>';
});
}
});
return template(html, data);
};
var makeAlertHtml = function(data) {
var html = $(selector.template.alert).html();
return template(html, data);
};
var displayError = function(container, message) {
$(container).html(makeAlertHtml({
icon: 'exclamation-triangle',
type: 'danger',
message: message
}));
};
var makeListElementHtml = function(data) {
var html = $(selector.template.list_element).html();
return template(html, data);
}
var makeListElementRoasHtml = function(roas_status, roas_warning, roas) {
if (!roas_status) {
return '<span class="label label-default" data-toggle="tooltip" data-original-title="' + roas_warning + '">{{ text_label_unavailable }}</span>';
} else {
return roas.toString() + '%';
}
}
var makeListElementStatusHtml = function(status) {
if (status == 'paused') {
return '<span class="label label-warning">{{ text_label_paused }}</span>';
} else if (status == 'active') {
return '<span class="label label-success">{{ text_label_active }}</span>';
}
return '';
}
var makeListElementFeedsHtml = function(feeds) {
html = '<ul>';
$(feeds).each(function(index, feed) {
html += '<li>' + feed.text + '</li>';
});
html += '</ul>';
return html;
}
var displaySuccess = function(message) {
$(selector.alerts).html(makeAlertHtml({
icon: 'check-circle',
type: 'success',
message: message
}));
};
var refreshTargets = function(callback) {
$.ajax({
url: '{{ target_list }}',
type: 'GET',
dataType: 'json',
beforeSend: function() {
$(selector.target.container).html('<div class="alert alert-info text-center">{{ text_loading }}</div>');
},
complete: callback,
error: function(jqXHR, textStatus, errorThrown) {
displayError(selector.alerts, '(' + textStatus + ') ' + errorThrown);
},
success: function(data) {
if (data.error) {
displayError(selector.alerts, data.error);
} else {
if (data.targets.length) {
targets = data.targets;
$(selector.target.container).html($(selector.template.targets).html());
$(data.targets).each(function(index, target) {
$(selector.target.list).append(makeListElementHtml({
target_id: target.target_id,
campaign_name: target.campaign_name,
country: target.country.name,
budget: target.budget.formatted,
roas: makeListElementRoasHtml(target.roas_status, target.roas_warning, target.roas),
status: makeListElementStatusHtml(target.status),
feeds: makeListElementFeedsHtml(target.feeds)
}));
});
} else {
$(selector.target.container).html('<div class="alert alert-warning"><i class="fa fa-warning"></i> {{ text_no_targets }}</div>');
}
}
}
});
};
var initModal = function(modalData) {
var html = $(makeModalHtml(modalData));
$(html).modal();
$(html).on('shown.bs.modal', function() {
// Enable tooltips
$('[data-toggle="tooltip"]').tooltip({container: 'body', html: true});
// Populate countries
$(allowed_targets).each(function(index, target) {
$(selector.target.country).append('<option value="' + target.country.code + '">' + target.country.name + '</option>');
});
// Select the current country
$(selector.target.country).val($(selector.target.country).attr('data-value')).trigger('change');
$(selector.target.status).val($(selector.target.status).attr('data-value')).trigger('change');
$(selector.target.budget).trigger('change');
$(selector.target.roas).attr('disabled', !modalData.roas_status);
$(selector.target.roas).attr('data-original-disabled', !modalData.roas_status ? '1' : '0');
$(selector.target.warning_roas).toggle(!modalData.roas_status);
});
$(html).on('hidden.bs.modal', function() {
$(this).remove();
});
};
var campaignCreateTestPromise = new Promise((resolve, reject) => {
{% if can_edit_campaigns %}
resolve();
{% else %}
var doCampaignCreateTest = function() {
$.ajax({
url: '{{ url_campaign_test }}',
dataType: 'json',
success: function(data) {
if (data.status) {
resolve();
} else if (data.redirect) {
document.location = data.redirect;
} else {
setTimeout(doCampaignCreateTest, 10000);
}
}
});
};
doCampaignCreateTest();
{% endif %}
});
$(document).on('click', selector.target.add, function(e) {
e.preventDefault();
e.stopPropagation();
var modalData = {
title: '{{ text_add_target }}',
url: '{{ target_add }}',
campaign_name : '',
budget: '25.00',
roas: 0,
roas_status: false,
roas_warning: '{{ text_roas_warning }}',
country: '',
status: 'active',
feeds: makeFeedsHtml({
id: id++,
language: '',
currency: ''
})
};
initModal(modalData);
});
$(document).on('click', selector.target.edit, function(e) {
e.preventDefault();
e.stopPropagation();
var data = null;
var feeds = '';
var target_id = $(this).attr('data-target-id');
$(targets).each(function(index, target) {
if (target.target_id == target_id) {
data = target;
return;
}
});
$(data.feeds).each(function(index, feed) {
feeds += makeFeedsHtml({
id: id++,
language: feed.language,
currency: feed.currency
});
});
var modalData = {
title: '{{ text_edit_target }}'.replace(/%s/, data.campaign_name),
url: '{{ target_edit }}'.replace(/{target_id}/, target_id),
campaign_name : data.campaign_name,
budget: data.budget.value,
roas: data.roas,
roas_status: data.roas_status,
roas_warning: data.roas_warning,
country: data.country.code,
status: data.status,
feeds: feeds
};
initModal(modalData);
});
$(document).on('click', selector.target.delete, function(e) {
e.preventDefault();
e.stopPropagation();
if (confirm("{{ text_confirm }}")) {
var target_id = $(this).attr('data-target-id');
$(selector.target.container).html('<div class="alert alert-info text-center">{{ text_loading_please_wait }}</div>');
campaignCreateTestPromise.then(function() {
$.ajax({
url: '{{ target_delete }}'.replace(/{target_id}/, target_id),
type: 'GET',
dataType: 'json',
complete: function() {
refreshTargets();
},
error: function(jqXHR, textStatus, errorThrown) {
displayError(selector.alerts, '(' + textStatus + ') ' + errorThrown);
},
success: function(data) {
if (data.error) {
displayError(selector.alerts, data.error);
} else if (data.redirect) {
document.location = data.redirect;
} else {
displaySuccess(data.success);
}
}
});
});
}
});
$(document).on('click', selector.feed.add, function(e) {
$(selector.feed.container).append(
$(makeFeedsHtml({
id: id++,
language: '',
currency: ''
}))
);
});
$(document).on('click', selector.feed.delete, function(e) {
e.preventDefault();
if (confirm("{{ text_confirm }}")) {
$(this).closest(selector.feed.row).remove();
}
});
$(document).on('click', selector.target.save, function(e) {
var saveButton = this;
$(selector.target.alerts).empty();
$(selector.alerts).empty();
$(selector.target.save)
.text($(selector.target.save).attr('data-loading'))
.attr('disabled', true);
$(selector.target.modal).find('input,select').attr('disabled', true);
$(selector.target.modal).find(selector.feed.add).attr('disabled', true);
$(selector.target.modal).find(selector.feed.delete).attr('disabled', true);
$('.text-danger').remove();
$('.has-error').removeClass('has-error');
campaignCreateTestPromise.then(function() {
$.ajax({
url: $(saveButton).attr('data-url'),
type: 'POST',
dataType: 'json',
data: $(selector.target.modal).find('input,select'),
complete: function() {
$(selector.target.save)
.text($(selector.target.save).attr('data-text'))
.attr('disabled', false);
$(selector.target.modal).find('input,select').attr('disabled', false);
$(selector.target.modal).find('[data-original-disabled]').each(function(index, element) {
$(element).attr('disabled', $(element).attr('data-original-disabled') == '1');
});
$(selector.target.modal).find(selector.feed.add).attr('disabled', false);
$(selector.target.modal).find(selector.feed.delete).attr('disabled', false);
},
error: function(jqXHR, textStatus, errorThrown) {
displayError(selector.target.alerts, '(' + textStatus + ') ' + errorThrown);
},
success: function(data) {
if (data.error) {
displayError(selector.target.alerts, data.error);
$(selector.feed.error_type).each(function(index, element) {
if (typeof data[$(element).attr('data-error-type')] != 'undefined') {
$(element).find('.col-sm-9').append('<div class="text-danger">' + data[$(element).attr('data-error-type')] + '</div>');
}
});
// Highlight any found errors
$('.text-danger').each(function() {
var element = $(saveButton).parent().parent();
if (element.hasClass('form-group')) {
element.addClass('has-error');
}
});
} else if (data.redirect) {
document.location = data.redirect;
} else if (data.success) {
displaySuccess(data.success);
refreshTargets(function() {
$(selector.target.modal).modal('hide');
});
}
}
});
});
});
$(document).on('change', selector.target.country, function() {
var code = $(this).val();
// Set the feed countries
$(allowed_targets).each(function(index, target) {
if (target.country.code == code) {
$(selector.feed.container).find(selector.feed.language).find('option[value!=""]').remove();
$(target.languages).each(function(index, language) {
$(selector.feed.container).find(selector.feed.language).append('<option value="' + language.code + '" ' + (language.status ? '' : 'disabled') + '>' + language.name + '</option>');
});
$(selector.feed.container).find(selector.feed.language).val(
$(selector.feed.container).find(selector.feed.language).attr('data-value')
);
$(selector.feed.container).find(selector.feed.currency).find('option[value!=""]').remove();
$(target.currencies).each(function(index, currency) {
$(selector.feed.container).find(selector.feed.currency).append('<option value="' + currency.code + '" ' + (currency.status ? '' : 'disabled') + '>' + currency.name + '</option>');
});
$(selector.feed.container).find(selector.feed.currency).val(
$(selector.feed.container).find(selector.feed.currency).attr('data-value')
);
}
});
});
$(document).on('change', selector.acknowledge, function() {
$(selector.save).attr('disabled', $(selector.acknowledge + ':not(:checked)').length > 0);
});
$(document).on('change keyup', selector.target.budget, function() {
if (parseFloat($(this).val()) < 10) {
$(selector.target.warning_budget).show();
} else {
$(selector.target.warning_budget).hide();
}
});
$(document).on('click', selector.save, function(e) {
e.preventDefault();
e.stopPropagation();
$(selector.save).text('{{ text_loading_please_wait }}').attr('disabled', true);
$(selector.acknowledge).attr('disabled', true);
campaignCreateTestPromise.then(function() {
$(selector.form).submit();
});
});
})(jQuery);
</script>
{{ footer }}