workingCopy/ecomzone/views/templates/admin/configure.tpl
2025-06-24 21:46:54 +02:00

358 lines
14 KiB
Smarty

{*
* @author EcomZone
* @copyright EcomZone
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*}
<div class="panel">
<h3><i class="icon icon-cogs"></i> {l s='EcomZone Configuration' mod='ecomzone'}</h3>
<form id="configuration_form" class="defaultForm form-horizontal" action="{$current_url}" method="post">
<input type="hidden" name="token" value="{$token}" />
<div class="panel">
<div class="form-wrapper">
<div class="form-group">
<label class="control-label col-lg-3">{l s='API URL' mod='ecomzone'}</label>
<div class="col-lg-9">
<input type="text" name="ECOMZONE_API_URL" value="{$ECOMZONE_API_URL|escape:'html':'UTF-8'}" class="form-control" required="required" />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-3">{l s='API Token' mod='ecomzone'}</label>
<div class="col-lg-9">
<input type="text" name="ECOMZONE_API_TOKEN" value="{$ECOMZONE_API_TOKEN|escape:'html':'UTF-8'}" class="form-control" required="required" />
</div>
</div>
</div>
<div class="panel-footer">
<button type="submit" name="submitEcomZoneModule" class="btn btn-default pull-right">
<i class="process-icon-save"></i> {l s='Save' mod='ecomzone'}
</button>
</div>
</div>
</form>
<div class="panel">
<h3>{l s='Product Synchronization' mod='ecomzone'}</h3>
<div class="form-wrapper">
<p>{l s='Last synchronization:' mod='ecomzone'} <strong>{if $ECOMZONE_LAST_SYNC}{$ECOMZONE_LAST_SYNC}{else}{l s='Never' mod='ecomzone'}{/if}</strong></p>
<form action="{$current_url}" method="post" class="form-horizontal" id="sync-form">
<input type="hidden" name="token" value="{$token}" />
<div class="form-group">
<div class="col-lg-9 col-lg-offset-3">
<button type="submit" name="syncProducts" class="btn btn-primary" id="sync-button">
<i class="process-icon-refresh"></i> {l s='Synchronize Products Now' mod='ecomzone'}
</button>
</div>
</div>
</form>
<div id="sync-progress" style="display: none;">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 0%;">
0%
</div>
</div>
<p class="text-center">
<span id="sync-status">{l s='Processing...' mod='ecomzone'}</span>
</p>
</div>
</div>
</div>
<div class="panel">
<h3>{l s='Product Preview' mod='ecomzone'}</h3>
<div class="form-wrapper">
<form action="{$current_url}" method="post" class="form-horizontal">
<input type="hidden" name="token" value="{$token}" />
<div class="form-group">
<div class="col-lg-9 col-lg-offset-3">
<button type="submit" name="fetchProducts" class="btn btn-default">
<i class="process-icon-preview"></i> {l s='Preview Available Products' mod='ecomzone'}
</button>
</div>
</div>
</form>
{if isset($API_PRODUCTS) && $API_PRODUCTS}
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>{l s='SKU' mod='ecomzone'}</th>
<th>{l s='Name' mod='ecomzone'}</th>
<th>{l s='Price' mod='ecomzone'}</th>
<th>{l s='Stock' mod='ecomzone'}</th>
<th>{l s='Status' mod='ecomzone'}</th>
</tr>
</thead>
<tbody>
{foreach from=$API_PRODUCTS item=product}
<tr>
<td>{$product.sku|escape:'html':'UTF-8'}</td>
<td>{$product.product_name|escape:'html':'UTF-8'}</td>
<td>{$product.product_price|escape:'html':'UTF-8'}</td>
<td>{$product.stock|escape:'html':'UTF-8'}</td>
<td>
{if isset($product.sync_status)}
<span class="badge badge-{if $product.sync_status == 'success'}success{elseif $product.sync_status == 'error'}danger{else}info{/if}">
{$product.sync_status|escape:'html':'UTF-8'}
</span>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{if isset($PAGINATION)}
<div class="text-center">
<ul class="pagination">
{for $page=1 to $PAGINATION.total_pages}
<li {if $page == $PAGINATION.current_page}class="active"{/if}>
<a href="{$current_url}&token={$token}&page={$page}">{$page}</a>
</li>
{/for}
</ul>
</div>
{/if}
{/if}
</div>
</div>
</div>
{if isset($SYNC_PROGRESS)}
<div class="panel">
<h3><i class="icon icon-refresh"></i> {l s='Sync Progress' mod='ecomzone'}</h3>
<div class="panel-body">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: {$SYNC_PROGRESS.percentage}%;">
{$SYNC_PROGRESS.percentage}%
</div>
</div>
<p class="text-center">
{l s='Processed:' mod='ecomzone'} {$SYNC_PROGRESS.processed} / {$SYNC_PROGRESS.total}
</p>
</div>
</div>
{/if}
<div class="panel">
<h3><i class="icon icon-list"></i> {l s='Recent Activity Log' mod='ecomzone'}</h3>
<div class="panel-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>{l s='Time' mod='ecomzone'}</th>
<th>{l s='Level' mod='ecomzone'}</th>
<th>{l s='Message' mod='ecomzone'}</th>
<th>{l s='Details' mod='ecomzone'}</th>
</tr>
</thead>
<tbody>
{if isset($ACTIVITY_LOG) && $ACTIVITY_LOG}
{foreach from=$ACTIVITY_LOG item=log}
<tr class="{if $log.level == 'ERROR'}danger{elseif $log.level == 'WARNING'}warning{/if}">
<td>{$log.timestamp|escape:'html':'UTF-8'}</td>
<td><span class="badge badge-{if $log.level == 'ERROR'}danger{elseif $log.level == 'WARNING'}warning{else}info{/if}">{$log.level|escape:'html':'UTF-8'}</span></td>
<td>{$log.message|escape:'html':'UTF-8'}</td>
<td>
{if $log.details}
<button type="button" class="btn btn-xs btn-default" data-toggle="popover" data-content="{$log.details|escape:'html':'UTF-8'}">
<i class="icon-info-circle"></i>
</button>
{/if}
</td>
</tr>
{/foreach}
{else}
<tr>
<td colspan="4" class="text-center">{l s='No activity logs available' mod='ecomzone'}</td>
</tr>
{/if}
</tbody>
</table>
</div>
</div>
</div>
<style type="text/css">
.progress {
margin-bottom: 10px;
}
.badge-success {
background-color: #72C279;
}
.badge-warning {
background-color: #fbbb22;
}
.badge-danger {
background-color: #E08F95;
}
.badge-info {
background-color: #25B9D7;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
$('[data-toggle="popover"]').popover({
placement: 'left',
trigger: 'click'
});
});
$(document).ready(function() {
var syncInProgress = false;
var currentRequest = null;
function showErrorMessage(message) {
if (typeof $.growl !== 'undefined') {
$.growl.error({ message: message });
} else {
alert(message);
}
}
function showSuccessMessage(message) {
if (typeof $.growl !== 'undefined') {
$.growl.notice({ message: message });
}
}
function handleAjaxError(xhr, status, error) {
var errorMessage = '{l s='Connection error' mod='ecomzone'}';
if (xhr.responseText) {
try {
var response = JSON.parse(xhr.responseText);
if (response.error) {
errorMessage = response.error;
}
} catch (e) {
console.error('Failed to parse error response:', e);
}
}
showErrorMessage(errorMessage);
syncInProgress = false;
$('#sync-button').prop('disabled', false);
$('#sync-progress').hide();
}
function updateProgress(progress) {
if (!progress) return;
$('#sync-progress').show();
$('.progress-bar').css('width', progress.percentage + '%').text(progress.percentage + '%');
$('#sync-status').text('{l s='Processed:' mod='ecomzone'} ' + progress.processed + ' / ' + progress.total);
}
function continueSyncProcess() {
if (!syncInProgress) return false;
if (currentRequest) {
currentRequest.abort();
}
currentRequest = $.ajax({
url: '{$current_url|escape:'javascript':'UTF-8'}',
type: 'POST',
dataType: 'json',
data: {
ajax: 1,
action: 'continueSyncProducts',
token: '{$token|escape:'javascript':'UTF-8'}'
},
success: function(result) {
if (!result) {
showErrorMessage('{l s='Invalid server response' mod='ecomzone'}');
syncInProgress = false;
$('#sync-button').prop('disabled', false);
$('#sync-progress').hide();
return;
}
if (result.success) {
updateProgress(result.progress);
if (!result.progress.is_complete) {
setTimeout(continueSyncProcess, 1000);
} else {
syncInProgress = false;
$('#sync-button').prop('disabled', false);
showSuccessMessage('{l s='Synchronization completed successfully' mod='ecomzone'}');
window.location.reload();
}
} else {
showErrorMessage(result.error || '{l s='Sync failed' mod='ecomzone'}');
syncInProgress = false;
$('#sync-button').prop('disabled', false);
$('#sync-progress').hide();
}
},
error: handleAjaxError
});
}
$('#sync-form').on('submit', function(e) {
e.preventDefault();
if (syncInProgress) return false;
syncInProgress = true;
$('#sync-button').prop('disabled', true);
$('#sync-progress').show();
if (currentRequest) {
currentRequest.abort();
}
currentRequest = $.ajax({
url: $(this).attr('action'),
type: 'POST',
dataType: 'json',
data: $(this).serialize() + '&ajax=1&syncProducts=1',
success: function(result) {
if (!result) {
showErrorMessage('{l s='Invalid server response' mod='ecomzone'}');
syncInProgress = false;
$('#sync-button').prop('disabled', false);
$('#sync-progress').hide();
return;
}
if (result.success) {
updateProgress(result.progress);
if (!result.progress.is_complete) {
setTimeout(continueSyncProcess, 1000);
} else {
syncInProgress = false;
$('#sync-button').prop('disabled', false);
showSuccessMessage('{l s='Synchronization completed successfully' mod='ecomzone'}');
window.location.reload();
}
} else {
showErrorMessage(result.error || '{l s='Sync failed' mod='ecomzone'}');
syncInProgress = false;
$('#sync-button').prop('disabled', false);
$('#sync-progress').hide();
}
},
error: handleAjaxError
});
return false;
});
$(window).on('beforeunload', function() {
if (currentRequest) {
currentRequest.abort();
}
});
});
</script>