first commit
This commit is contained in:
70
admininistrator/view/template/marketplace/api.twig
Normal file
70
admininistrator/view/template/marketplace/api.twig
Normal file
@ -0,0 +1,70 @@
|
||||
<div id="modal-api" class="modal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><i class="fa-solid fa-cog"></i> {{ heading_title }}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="form-api">
|
||||
<div class="alert alert-info"><i class="fa-solid fa-info-circle"></i> {{ text_signup }}</div>
|
||||
<div class="mb-3">
|
||||
<label for="input-username" class="form-label">{{ entry_username }}</label> <input type="text" name="opencart_username" value="" placeholder="{{ entry_username }}" id="input-username" class="form-control"/>
|
||||
<div id="error-username" class="invalid-feedback"></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="input-secret" class="form-label">{{ entry_secret }}</label> <textarea name="opencart_secret" placeholder="{{ entry_secret }}" rows="8" id="input-secret" class="form-control"></textarea>
|
||||
<div id="error-secret" class="invalid-feedback"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" form="form-api" id="button-save" class="btn btn-primary"><i class="fa-solid fa-floppy-disk"></i> {{ button_save }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript"><!--
|
||||
$('#form-api').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
$.ajax({
|
||||
url: 'index.php?route=marketplace/api.save&user_token={{ user_token }}',
|
||||
type: 'post',
|
||||
dataType: 'json',
|
||||
data: $('#form-api').serialize(),
|
||||
beforeSend: function() {
|
||||
$('#button-save').button('loading');
|
||||
},
|
||||
complete: function() {
|
||||
$('#button-save').button('reset');
|
||||
},
|
||||
success: function(json) {
|
||||
console.log(json);
|
||||
|
||||
$('.alert-dismissible').remove();
|
||||
$('.invalid-feedback').removeClass('d-block');
|
||||
|
||||
if (json['error']) {
|
||||
if (json['error']['warning']) {
|
||||
$('#modal-api .modal-body').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error']['warning'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
for (key in json['error']) {
|
||||
$('#input-' + key.replaceAll('_', '-')).addClass('is-invalid').find('.form-control, .form-select, .form-check-input, .form-check-label').addClass('is-invalid');
|
||||
$('#error-' + key.replaceAll('_', '-')).html(json['error'][key]).addClass('d-block');
|
||||
}
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#modal-api .modal-body').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
window.location.reload();
|
||||
}
|
||||
},
|
||||
error: function(xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
//--></script>
|
103
admininistrator/view/template/marketplace/cron.twig
Normal file
103
admininistrator/view/template/marketplace/cron.twig
Normal file
@ -0,0 +1,103 @@
|
||||
{{ header }}{{ column_left }}
|
||||
<div id="content">
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<div class="float-end">
|
||||
<button type="submit" form="form-cron" formaction="{{ delete }}" data-bs-toggle="tooltip" title="{{ button_delete }}" onclick="return confirm('{{ text_confirm }}');" class="btn btn-danger"><i class="fa-regular fa-trash-can"></i></button>
|
||||
</div>
|
||||
<h1>{{ heading_title }}</h1>
|
||||
<ol class="breadcrumb">
|
||||
{% for breadcrumb in breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header"><i class="fa-solid fa-question-circle"></i> {{ text_instruction }}</div>
|
||||
<div class="card-body">
|
||||
<p>{{ text_cron_1 }}</p>
|
||||
<p>{{ text_cron_2 }}</p>
|
||||
<div class="mb-3">
|
||||
<div class="input-group">
|
||||
<div class="input-group-text">{{ entry_cron }}</div>
|
||||
<input type="text" value="wget "{{ cron }}" --read-timeout=5400" id="input-cron" class="form-control"/>
|
||||
<button type="button" id="button-copy" data-bs-toggle="tooltip" title="{{ button_copy }}" class="btn btn-light"><i class="fa-regular fa-copy"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header"><i class="fa-solid fa-list"></i> {{ text_list }}</div>
|
||||
<div id="cron" class="card-body">{{ list }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript"><!--
|
||||
$('#cron').on('click', 'thead a, .pagination a', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
$('#cron').load(this.href);
|
||||
});
|
||||
|
||||
$('#cron').on('click', '.btn-success, .btn-warning, .btn-danger', function () {
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).val(),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
if (json['error']) {
|
||||
$('#alert').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#alert').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#cron').load($('#form-cron').attr('data-oc-load'));
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#cron').on('click', '.btn-info', function () {
|
||||
var element = this;
|
||||
|
||||
$('#modal-cron').remove();
|
||||
|
||||
html = '<div id="modal-cron" class="modal">';
|
||||
html += ' <div class="modal-dialog">';
|
||||
html += ' <div class="modal-content">';
|
||||
html += ' <div class="modal-header">';
|
||||
html += ' <h5 class="modal-title">{{ text_info|escape('js') }}</h5>';
|
||||
html += ' <button type="button" class="btn-close" data-bs-dismiss="modal"></button>';
|
||||
html += ' </div>';
|
||||
html += ' <div class="modal-body">';
|
||||
html += ' <div class="mb-3">';
|
||||
html += ' <label for="input-description" class="form-label">{{ entry_description|escape('js') }}</label>';
|
||||
html += ' <textarea placeholder="{{ entry_description|escape('js') }}" id="input-description" rows="5" class="form-control" disabled>' + $(element).attr('data-oc-description') + '</textarea>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += '</div>';
|
||||
|
||||
$('body').append(html);
|
||||
|
||||
var modal = new bootstrap.Modal(document.querySelector('#modal-cron'));
|
||||
|
||||
modal.show();
|
||||
});
|
||||
//--></script>
|
||||
{{ footer }}
|
46
admininistrator/view/template/marketplace/cron_list.twig
Normal file
46
admininistrator/view/template/marketplace/cron_list.twig
Normal file
@ -0,0 +1,46 @@
|
||||
<form id="form-cron" method="post" data-oc-toggle="ajax" data-oc-load="{{ action }}" data-oc-target="#cron">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="text-center" style="width: 1px;"><input type="checkbox" onclick="$('input[name*=\'selected\']').prop('checked', $(this).prop('checked'));" class="form-check-input"/></td>
|
||||
<td class="text-start"><a href="{{ sort_code }}"{% if sort == 'code' %} class="{{ order|lower }}"{% endif %}>{{ column_code }}</a></td>
|
||||
<td class="text-start"><a href="{{ sort_cycle }}"{% if sort == 'cycle' %} class="{{ order|lower }}"{% endif %}>{{ column_cycle }}</a></td>
|
||||
<td class="text-start"><a href="{{ sort_action }}"{% if sort == 'action' %} class="{{ order|lower }}"{% endif %}>{{ column_action }}</a></td>
|
||||
<td class="text-start d-none d-lg-table-cell"><a href="{{ sort_date_added }}"{% if sort == 'date_added' %} class="{{ order|lower }}"{% endif %}>{{ column_date_added }}</a></td>
|
||||
<td class="text-start d-none d-lg-table-cell"><a href="{{ sort_date_modified }}"{% if sort == 'date_modified' %} class="{{ order|lower }}"{% endif %}>{{ column_date_modified }}</a></td>
|
||||
<td class="text-end">{{ column_action }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if crons %}
|
||||
{% for cron in crons %}
|
||||
<tr>
|
||||
<td class="text-center"><input type="checkbox" name="selected[]" value="{{ cron.cron_id }}" class="form-check-input"/></td>
|
||||
<td class="text-start">{{ cron.code }}</td>
|
||||
<td class="text-start">{{ cron.cycle }}</td>
|
||||
<td class="text-start">{{ cron.action }}</td>
|
||||
<td class="text-start d-none d-lg-table-cell">{{ cron.date_added }}</td>
|
||||
<td class="text-start d-none d-lg-table-cell">{{ cron.date_modified }}</td>
|
||||
<td class="text-end text-nowrap"><button type="button" data-oc-description="{{ cron.description }}" data-oc-trigger="{{ cron.trigger }}" data-oc-action="{{ cron.action }}" class="btn btn-info"><i class="fa-solid fa-info-circle"></i></button>
|
||||
<button type="button" value="{{ cron.run }}" data-bs-toggle="tooltip" title="{{ button_run }}" class="btn btn-warning"><i class="fa-solid fa-play"></i></button>
|
||||
{% if not cron.status %}
|
||||
<button type="button" value="{{ cron.enable }}" data-bs-toggle="tooltip" title="{{ button_enable }}" class="btn btn-success"><i class="fa-solid fa-plus-circle"></i></button>
|
||||
{% else %}
|
||||
<button type="button" value="{{ cron.disable }}" data-bs-toggle="tooltip" title="{{ button_disable }}" class="btn btn-danger"><i class="fa-solid fa-minus-circle"></i></button>
|
||||
{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td class="text-center" colspan="7">{{ text_no_results }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 text-start">{{ pagination }}</div>
|
||||
<div class="col-sm-6 text-end">{{ results }}</div>
|
||||
</div>
|
||||
</form>
|
99
admininistrator/view/template/marketplace/event.twig
Normal file
99
admininistrator/view/template/marketplace/event.twig
Normal file
@ -0,0 +1,99 @@
|
||||
{{ header }}{{ column_left }}
|
||||
<div id="content">
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<div class="float-end">
|
||||
<button type="submit" form="form-event" formaction="{{ delete }}" data-bs-toggle="tooltip" title="{{ button_delete }}" onclick="return confirm('{{ text_confirm }}');" class="btn btn-danger"><i class="fa-regular fa-trash-can"></i></button>
|
||||
</div>
|
||||
<h1>{{ heading_title }}</h1>
|
||||
<ol class="breadcrumb">
|
||||
{% for breadcrumb in breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="alert alert-info"><i class="fa-solid fa-info-circle"></i> {{ text_event }}</div>
|
||||
<div class="card">
|
||||
<div class="card-header"><i class="fa-solid fa-list"></i> {{ text_list }}</div>
|
||||
<div id="event" class="card-body">{{ list }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript"><!--
|
||||
$('#event').on('click', 'thead a, .pagination a', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
$('#event').load(this.href);
|
||||
});
|
||||
|
||||
$('#event').on('click', '.btn-success, .btn-danger', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).val(),
|
||||
type: 'post',
|
||||
data: $('#event input[name=\'selected[]\']:checked'),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
if (json['error']) {
|
||||
$('#alert').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#alert').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#event').load($('#form-event').attr('data-oc-load'));
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#event').on('click', '.btn-info', function () {
|
||||
var element = this;
|
||||
|
||||
$('#modal-event').remove();
|
||||
|
||||
html = '<div id="modal-event" class="modal">';
|
||||
html += ' <div class="modal-dialog">';
|
||||
html += ' <div class="modal-content">';
|
||||
html += ' <div class="modal-header">';
|
||||
html += ' <h5 class="modal-title">{{ text_info|escape('js') }}</h5>';
|
||||
html += ' <button type="button" class="btn-close" data-bs-dismiss="modal"></button>';
|
||||
html += ' </div>';
|
||||
html += ' <div class="modal-body">';
|
||||
html += ' <div class="mb-3">';
|
||||
html += ' <label for="input-description" class="form-label">{{ entry_description|escape('js') }}</label> <textarea placeholder="{{ entry_description|escape('js') }}" id="input-description" rows="5" class="form-control" disabled>' + $(element).attr('data-oc-description') + '</textarea>';
|
||||
html += ' </div>';
|
||||
html += ' <div class="mb-3">';
|
||||
html += ' <label for="input-trigger" class="form-label">{{ entry_trigger|escape('js') }}</label> <textarea placeholder="{{ entry_trigger|escape('js') }}" id="input-trigger" class="form-control" disabled>' + $(element).attr('data-oc-trigger') + '</textarea>';
|
||||
html += ' </div>';
|
||||
html += ' <div class="mb-3">';
|
||||
html += ' <label for="input-action" class="form-label">{{ entry_action|escape('js') }}</label> <textarea placeholder="{{ entry_action|escape('js') }}" id="input-action" class="form-control" disabled>' + $(element).attr('data-oc-action') + '</textarea>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += '</div>';
|
||||
|
||||
$('body').append(html);
|
||||
|
||||
var modal = new bootstrap.Modal(document.querySelector('#modal-event'));
|
||||
|
||||
modal.show();
|
||||
});
|
||||
//--></script>
|
||||
{{ footer }}
|
39
admininistrator/view/template/marketplace/event_list.twig
Normal file
39
admininistrator/view/template/marketplace/event_list.twig
Normal file
@ -0,0 +1,39 @@
|
||||
<form id="form-event" method="post" data-oc-toggle="ajax" data-oc-load="{{ action }}" data-oc-target="#event">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="text-center" style="width: 1px;"><input type="checkbox" onclick="$('input[name*=\'selected\']').prop('checked', $(this).prop('checked'));" class="form-check-input"/></td>
|
||||
<td class="text-start"><a href="{{ sort_code }}"{% if sort == 'code' %} class="{{ order|lower }}"{% endif %}>{{ column_code }}</a></td>
|
||||
<td class="text-end d-none d-lg-table-cell"><a href="{{ sort_sort_order }}"{% if sort == 'sort_order' %} class="{{ order|lower }}"{% endif %}>{{ column_sort_order }}</a></td>
|
||||
<td class="text-end">{{ column_action }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if events %}
|
||||
{% for event in events %}
|
||||
<tr>
|
||||
<td class="text-center"><input type="checkbox" name="selected[]" value="{{ event.event_id }}" class="form-check-input"/></td>
|
||||
<td class="text-start">{{ event.code }}</td>
|
||||
<td class="text-end d-none d-lg-table-cell">{{ event.sort_order }}</td>
|
||||
<td class="text-end text-nowrap"><button type="button" data-oc-description="{{ event.description }}" data-oc-trigger="{{ event.trigger }}" data-oc-action="{{ event.action }}" class="btn btn-info"><i class="fa-solid fa-info-circle"></i></button>
|
||||
{% if not event.status %}
|
||||
<button type="button" value="{{ event.enable }}" data-bs-toggle="tooltip" title="{{ button_enable }}" class="btn btn-success"><i class="fa-solid fa-plus-circle"></i></button>
|
||||
{% else %}
|
||||
<button type="button" value="{{ event.disable }}" data-bs-toggle="tooltip" title="{{ button_disable }}" class="btn btn-danger"><i class="fa-solid fa-minus-circle"></i></button>
|
||||
{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td class="text-center" colspan="4">{{ text_no_results }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 text-start">{{ pagination }}</div>
|
||||
<div class="col-sm-6 text-end">{{ results }}</div>
|
||||
</div>
|
||||
</form>
|
199
admininistrator/view/template/marketplace/extension.twig
Normal file
199
admininistrator/view/template/marketplace/extension.twig
Normal file
@ -0,0 +1,199 @@
|
||||
{{ header }}{{ column_left }}
|
||||
<div id="content">
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<h1>{{ heading_title }}</h1>
|
||||
<ol class="breadcrumb">
|
||||
{% for breadcrumb in breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-header"><i class="fa-solid fa-puzzle-piece"></i> {{ text_list }}</div>
|
||||
<div class="card-body">
|
||||
<fieldset>
|
||||
<legend>{{ text_type }}</legend>
|
||||
<div class="card bg-light">
|
||||
<div class="card-body">
|
||||
<div class="input-group">
|
||||
<select name="type" id="input-type" class="form-select">
|
||||
{% for category in categories %}
|
||||
<option value="{{ category.href }}"{% if type == category.code %} selected{% endif %}>{{ category.text }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="input-group-text"><i class="fa-solid fa-filter"></i> {{ text_filter }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div id="extension">{{ extension }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript"><!--
|
||||
$('#input-type').on('change', function () {
|
||||
$.ajax({
|
||||
url: $(this).val(),
|
||||
dataType: 'html',
|
||||
beforeSend: function () {
|
||||
$('.fa-filter').addClass('fa-circle-notch fa-spin');
|
||||
$('.fa-filter').removeClass('fa-filter');
|
||||
$('#input-type').prop('disabled', true);
|
||||
},
|
||||
complete: function () {
|
||||
$('.fa-circle-notch').addClass('fa-filter');
|
||||
$('.fa-circle-notch').removeClass('fa-circle-notch fa-spin');
|
||||
$('#input-type').prop('disabled', false);
|
||||
},
|
||||
success: function (html) {
|
||||
$('#extension').html(html);
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Download promotion extension
|
||||
$('#extension').on('click', '#recommended .btn-primary', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).attr('value'),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#extension').before('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#extension').before('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
// Manually build the url so no need to refresh extensions and can trigger install
|
||||
// Once the extension is downloaded we trigger the installer
|
||||
$(element).parent().find('.dropdown-menu').html('<a href="index.php?route=marketplace/installer.install&user_token={{ user_token }}&extension_install_id=' + json['extension_install_id'] + '" class="dropdown-item"><i class="fa-solid fa-plus-circle fa-fw"></i> {{ text_install }}</a> <a href="index.php?route=marketplace/installer.delete&user_token={{ user_token }}&extension_install_id=' + json['extension_install_id'] + '" class="dropdown-item"><i class="fa-regular fa-trash-can fa-fw"></i> {{ text_delete }}</a>');
|
||||
|
||||
$(element).parent().find('.dropdown-item:first').trigger('click');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
|
||||
$(element).button('reset');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Download dropdown
|
||||
$('#extension').on('click', '.dropdown-item', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).attr('href'),
|
||||
dataType: 'json',
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#extension').before('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#extension').before('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#extension').load($('#input-type').val());
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Install
|
||||
$('#extension').on('click', '.btn-success', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).attr('href'),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#alert').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#alert').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#input-type').trigger('change');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Uninstall / Delete
|
||||
$('#extension').on('click', '.btn-danger, .btn-outline-danger', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (confirm('{{ text_confirm }}')) {
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).attr('href'),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#alert').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#alert').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#input-type').trigger('change');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
//--></script>
|
||||
{{ footer }}
|
210
admininistrator/view/template/marketplace/installer.twig
Normal file
210
admininistrator/view/template/marketplace/installer.twig
Normal file
@ -0,0 +1,210 @@
|
||||
{{ header }}{{ column_left }}
|
||||
<div id="content">
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<div class="float-end"><button type="button" id="button-upload" data-bs-toggle="tooltip" title="{{ button_upload }}" class="btn btn-primary"><i class="fa-solid fa-upload"></i></button></div>
|
||||
<h1>{{ heading_title }}</h1>
|
||||
<ol class="breadcrumb">
|
||||
{% for breadcrumb in breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-header"><i class="fa-solid fa-puzzle-piece"></i> {{ heading_title }}</div>
|
||||
<div class="card-body">
|
||||
<fieldset>
|
||||
<legend>{{ text_progress }}</legend>
|
||||
<div class="row mb-3">
|
||||
<label class="col-sm-2 col-form-label">{{ entry_progress }}</label>
|
||||
<div class="col-sm-10 mt-2">
|
||||
<div class="progress">
|
||||
<div id="progress-bar" class="progress-bar" style="width: 0%;"></div>
|
||||
</div>
|
||||
<div id="progress-text"></div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{{ text_installed }}</legend>
|
||||
<div id="extension">{{ list }}</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript"><!--
|
||||
$('#extension').on('click', 'thead a, .pagination a', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
$('#extension').load(this.href);
|
||||
});
|
||||
|
||||
// Upload
|
||||
$('#button-upload').on('click', function () {
|
||||
var element = this;
|
||||
|
||||
if (!$('#button-upload').prop('disabled')) {
|
||||
$('#form-upload').remove();
|
||||
|
||||
$('body').prepend('<form enctype="multipart/form-data" id="form-upload" style="display: none;"><input type="file" name="file"/></form>');
|
||||
|
||||
$('#form-upload input[name=\'file\']').trigger('click');
|
||||
|
||||
$('#form-upload input[name=\'file\']').on('change', function () {
|
||||
if ((this.files[0].size / 1024) > {{ config_file_max_size }}) {
|
||||
$(this).val('');
|
||||
|
||||
alert('{{ error_upload_size }}');
|
||||
}
|
||||
|
||||
if (!this.files[0].name.endsWith('.ocmod.zip')) {
|
||||
$(this).val('');
|
||||
|
||||
alert('{{ error_filetype }}');
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof timer != 'undefined') {
|
||||
clearInterval(timer);
|
||||
}
|
||||
|
||||
timer = setInterval(function () {
|
||||
if ($('#form-upload input[name=\'file\']').val() !== '') {
|
||||
clearInterval(timer);
|
||||
|
||||
$.ajax({
|
||||
url: 'index.php?route=marketplace/installer.upload&user_token={{ user_token }}',
|
||||
type: 'post',
|
||||
data: new FormData($('#form-upload')[0]),
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
if (json['error']) {
|
||||
$('#alert').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#alert').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#extension').load('index.php?route=marketplace/installer.list&user_token={{ user_token }}');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// Install
|
||||
$('#extension').on('click', '.btn-success, .btn-warning', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$(element).button('loading');
|
||||
|
||||
var next = $(element).attr('href');
|
||||
|
||||
$('#progress-bar').removeClass('bg-danger bg-success').css('width', '0%');
|
||||
$('#progress-text').html('');
|
||||
|
||||
var installer = function () {
|
||||
return $.ajax({
|
||||
url: next,
|
||||
dataType: 'json',
|
||||
success: function (json) {
|
||||
console.log(json);
|
||||
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#progress-bar').addClass('bg-danger');
|
||||
$('#progress-text').html('<div class="text-danger">' + json['error'] + '</div>');
|
||||
|
||||
$(element).button('reset');
|
||||
}
|
||||
|
||||
if (json['text']) {
|
||||
$('#progress-bar').addClass('bg-success');
|
||||
$('#progress-text').html('<div class="text-success">' + json['text'] + '</div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#progress-bar').addClass('bg-success').css('width', '100%');
|
||||
$('#progress-text').html('<div class="text-success">' + json['success'] + '</div>');
|
||||
|
||||
$(element).button('reset');
|
||||
|
||||
$('#extension').load('index.php?route=marketplace/installer.list&user_token={{ user_token }}');
|
||||
}
|
||||
|
||||
if (json['next']) {
|
||||
next = json['next'];
|
||||
|
||||
chain.attach(installer);
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
|
||||
$(element).button('reset');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
chain.attach(installer);
|
||||
});
|
||||
|
||||
// Delete
|
||||
$('#extension').on('click', '.btn-danger', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
if (confirm('{{ text_confirm }}')) {
|
||||
$.ajax({
|
||||
url: $(element).attr('href'),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
console.log(json);
|
||||
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#alert').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#alert').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#extension').load('index.php?route=marketplace/installer.list&user_token={{ user_token }}');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
//--></script>
|
||||
{{ footer }}
|
@ -0,0 +1,46 @@
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="text-start"><a href="{{ sort_name }}"{% if sort == 'name' %} class="{{ order|lower }}"{% endif %}>{{ column_name }}</a></td>
|
||||
<td class="text-start"><a href="{{ sort_version }}"{% if sort == 'version' %} class="{{ order|lower }}"{% endif %}>{{ column_version }}</a></td>
|
||||
<td class="text-start"><a href="{{ sort_date_added }}"{% if sort == 'date_added' %} class="{{ order|lower }}"{% endif %}>{{ column_date_added }}</a></td>
|
||||
<td class="text-end" style="min-width: 105px;">{{ column_action }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if extensions %}
|
||||
{% for extension in extensions %}
|
||||
<tr>
|
||||
<td class="text-start">
|
||||
{% if extension.link %}
|
||||
<a href="{{ extension.link }}" target="_blank">{{ extension.name }}</a>
|
||||
{% else %}
|
||||
{{ extension.name }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-start align-text-top">{{ extension.version }}</td>
|
||||
<td class="text-start align-text-top">{{ extension.date_added }}</td>
|
||||
<td class="text-end align-text-top text-nowrap">
|
||||
{% if not extension.status %}
|
||||
<a href="{{ extension.install }}" data-bs-toggle="tooltip" title="{{ button_install }}" class="btn btn-success"><i class="fa-solid fa-plus-circle"></i></a>
|
||||
<a href="{{ extension.delete }}" data-bs-toggle="tooltip" title="{{ button_delete }}" class="btn btn-danger"><i class="fa-regular fa-trash-can"></i></a>
|
||||
{% else %}
|
||||
<a href="{{ extension.uninstall }}" data-bs-toggle="tooltip" title="{{ button_uninstall }}" class="btn btn-warning"><i class="fa-solid fa-minus-circle"></i></a>
|
||||
<button type="button" data-bs-toggle="tooltip" title="{{ button_delete }}" class="btn btn-danger" disabled><i class="fa-regular fa-trash-can"></i></button>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td class="text-center" colspan="4">{{ text_no_results }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 text-start">{{ pagination }}</div>
|
||||
<div class="col-sm-6 text-end">{{ results }}</div>
|
||||
</div>
|
@ -0,0 +1,42 @@
|
||||
{% if comments %}
|
||||
{% for comment in comments %}
|
||||
<div id="comment-{{ comment.extension_comment_id }}" class="media">
|
||||
<img src="{{ comment.image }}" alt="{{ comment.member }}" title="{{ comment.member }}" class="me-3 rounded-circle"/>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0">{{ comment.member }} <span>{{ comment.date_added }}</span></h5>
|
||||
<p>{{ comment.comment }}</p>
|
||||
<div class="reply">
|
||||
<div> {% if comment.reply %}
|
||||
{% for reply in comment.reply %}
|
||||
<div class="media">
|
||||
<img src="{{ reply.image }}" alt="{{ reply.member }}" title="{{ reply.member }}" class="me-3 rounded-circle"/>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0">{{ reply.member }} <span>{{ reply.date_added }}</h5>
|
||||
<p>{{ reply.comment }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if comment.next %}
|
||||
<div class="text-center"><a href="{{ comment.next }}" class="btn btn-block">{{ text_more }}</a></div>
|
||||
{% endif %}
|
||||
{% endif %}<a href="{{ comment.refresh }}" class="reply-refresh hide">{{ text_refresh }}</a></div>
|
||||
</div>
|
||||
<p class="text-end">
|
||||
<button type="button" class="btn btn-link btn-sm">{{ button_reply }}</button>
|
||||
</p>
|
||||
<div class="reply-input-box" style="display: none;">
|
||||
<div class="media">
|
||||
<div class="media-body">
|
||||
<div class="mb-3">
|
||||
<label for="input-comment-{{ comment.extension_comment_id }}">{{ text_comment_add }}</label> <textarea name="comment" placeholder="{{ text_write }}" id="input-comment-{{ comment.extension_comment_id }}" class="form-control"></textarea>
|
||||
</div>
|
||||
<div class="text-end"><a href="{{ comment.add }}" class="btn btn-primary btn-sm">{{ button_comment }}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<br/>
|
||||
<div class="text-center">{{ pagination }}</div>
|
||||
{% endif %}
|
@ -0,0 +1,32 @@
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<td>{{ text_name }}</td>
|
||||
<td>{{ text_date_added }}</td>
|
||||
<td class="text-end">{{ text_action }}</td>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if downloads %}
|
||||
{% for download in downloads %}
|
||||
<tr>
|
||||
<td>{{ download.name }}</td>
|
||||
<td>{{ download.date_added }}</td>
|
||||
<td class="text-end">
|
||||
<div class="dropdown">
|
||||
<div class="btn-group">
|
||||
<button type="button" value="{{ download.download }}" class="btn btn-primary"{% if not download.download %} disabled{% endif %}><i class="fa-solid fa-download"></i> {{ button_download }}</button>
|
||||
<button type="button" data-bs-toggle="dropdown" class="btn btn-outline-dark dropdown-toggle dropdown-toggle-split"><i class="fa-solid fa-caret-down"></i></button>
|
||||
<div class="dropdown-menu dropdown-menu-end">
|
||||
<a href="{{ download.install }}" class="dropdown-item{% if not download.install %} disabled{% endif %}"><i class="fa-solid fa-plus-circle fa-fw"></i> {{ text_install }}</a> <a href="{{ download.uninstall }}" class="dropdown-item{% if not download.uninstall %} disabled{% endif %}"><i class="fa-solid fa-minus-circle fa-fw"></i> {{ text_uninstall }}</a> <a href="{{ download.delete }}" class="dropdown-item{% if not download.delete %} disabled{% endif %}"><i class="fa-regular fa-trash-can fa-fw"></i> {{ text_delete }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="3" class="text-center">{{ text_no_results }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
456
admininistrator/view/template/marketplace/marketplace_info.twig
Normal file
456
admininistrator/view/template/marketplace/marketplace_info.twig
Normal file
@ -0,0 +1,456 @@
|
||||
{{ header }}{{ column_left }}
|
||||
<div id="content">
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<div class="float-end">
|
||||
{% if signature %}
|
||||
<button type="button" id="button-api" data-bs-toggle="tooltip" title="{{ button_api }}" class="btn btn-info"><i class="fa-solid fa-cog"></i></button>
|
||||
{% else %}
|
||||
<button type="button" id="button-api" data-bs-toggle="tooltip" title="{{ button_api }}" data-placement="left" class="btn btn-danger"><i class="fa-solid fa-triangle-exclamation"></i></button>
|
||||
{% endif %}
|
||||
<a href="{{ back }}" data-bs-toggle="tooltip" title="{{ button_back }}" class="btn btn-light"><i class="fa-solid fa-reply"></i></a>
|
||||
</div>
|
||||
<h1>{{ heading_title }}</h1>
|
||||
<ol class="breadcrumb">
|
||||
{% for breadcrumb in breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div id="marketplace-extension-info" class="container-fluid">
|
||||
{% if error_warning %}
|
||||
<div class="alert alert-danger"><i class="fa-solid fa-circle-exclamation"></i> {{ error_warning }}</div>
|
||||
{% endif %}
|
||||
<div class="card">
|
||||
<div class="card-header"><i class="fa-solid fa-puzzle-piece"></i> {{ name }}</div>
|
||||
<div class="card-body">
|
||||
<div class="row extension-info">
|
||||
<div class="col-md-8 col-lg-9">
|
||||
{% if banner %}
|
||||
<div id="banner" class="text-center img-thumbnail mb-3"><img src="{{ banner }}" title="{{ name }}" alt="{{ name }}" class="img-fluid"/></div>
|
||||
{% endif %}
|
||||
<div class="row thumbnails">
|
||||
{% for image in images %}
|
||||
<div class="col-4 col-md-3 col-lg-2 mb-3"><a href="{{ image.popup }}"><img src="{{ image.thumb }}" alt="{{ image.name }}" title="{{ image.name }}" class="img-fluid img-thumbnail"/></a></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item"><a href="#tab-description" class="nav-link active" data-bs-toggle="tab">{{ tab_general }}</a></li>
|
||||
<li class="nav-item"><a href="#tab-documentation" class="nav-link" data-bs-toggle="tab">{{ tab_documentation }}</a></li>
|
||||
<li class="nav-item"><a href="#tab-download" class="nav-link" data-bs-toggle="tab">{{ tab_download }}</a></li>
|
||||
<li class="nav-item"><a href="#tab-comment" class="nav-link" data-bs-toggle="tab">{{ tab_comment }} ({{ comment_total }})</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div id="tab-description" class="tab-pane fade show active">{{ description }}</div>
|
||||
<div id="tab-documentation" class="tab-pane fade">{{ documentation }}</div>
|
||||
<div id="tab-download" class="tab-pane fade">
|
||||
<fieldset>
|
||||
<legend>{{ text_available }}</legend>
|
||||
<div id="download"></div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div id="tab-comment" class="tab-pane">
|
||||
<fieldset>
|
||||
<legend>{{ text_comment_add }}</legend>
|
||||
<div class="mb-3">
|
||||
<textarea name="comment" rows="5" placeholder="{{ text_write }}" id="input-history-comment" class="form-control"></textarea>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<button type="button" id="button-comment" class="btn btn-primary">{{ button_comment }}</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<br/>
|
||||
<fieldset>
|
||||
<legend>{{ text_comment }}</legend>
|
||||
<div id="comment"></div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 col-lg-3">
|
||||
<div id="buy" class="card mb-3">
|
||||
<div class="card-body">
|
||||
{% if license == '1' and not purchased %}
|
||||
<button type="button" id="button-buy" class="btn btn-success btn-lg btn-block">{{ button_purchase }}</button>
|
||||
{% endif %}
|
||||
<div id="price" class="row">
|
||||
<div class="col-lg-5"><strong>{{ text_price }}</strong></div>
|
||||
<div class="col-lg-7 text-end">{% if license %}
|
||||
{{ price }}
|
||||
{% else %}
|
||||
{{ text_free }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<ul class="list-check">
|
||||
<li>{{ text_partner }}</li>
|
||||
<li>{{ text_support }}</li>
|
||||
<li>{{ text_documentation }}</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-5"><strong>{{ text_rating }}</strong></div>
|
||||
<div class="col-md-7 text-end">{% for i in 1..5 %}
|
||||
{% if rating < i %}
|
||||
<i class="fa-regular fa-star"></i>
|
||||
{% else %}
|
||||
<i class="fa-solid fa-star"></i>
|
||||
{% endif %}
|
||||
{% endfor %} ({{ rating_total }})
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-5"><strong>{{ text_compatibility }}</strong></div>
|
||||
<div class="col-md-7 text-end">{{ compatibility }}</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-5"><strong>{{ text_date_modified }}</strong></div>
|
||||
<div class="col-md-7 text-end">{{ date_modified }}</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-5"><strong>{{ text_date_added }}</strong></div>
|
||||
<div class="col-md-7 text-end">{{ date_added }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="sales" class="card mb-3">
|
||||
<div class="card-body"><i class="fa-solid fa-shopping-cart"></i> <strong>{{ sales }}</strong> {{ text_sales }}</div>
|
||||
</div>
|
||||
<div id="sales" class="card mb-3">
|
||||
<div class="card-body"><i class="fa-solid fa-download"></i> <strong>{{ downloaded }}</strong> {{ text_downloaded }}</div>
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<div class="media">
|
||||
<img src="{{ member_image }}" alt="{{ member_username }}" title="{{ member_username }}" class="me-3 rounded-circle">
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><a href="{{ filter_member }}">{{ member_username }}</a></h5>
|
||||
<small>{{ text_member_since }} {{ member_date_added }}</small>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<a href="{{ filter_member }}" class="btn btn-primary btn-lg btn-block">{{ button_view_all }}</a> <a href="https://www.opencart.com/index.php?route=support/seller&extension_id={{ extension_id }}" target="_blank" class="btn btn-outline-secondary btn-lg btn-block">{{ button_support }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript"><!--
|
||||
$('#button-api').on('click', function (e) {
|
||||
$('#modal-api').remove();
|
||||
|
||||
$.ajax({
|
||||
url: 'index.php?route=marketplace/api&user_token={{ user_token }}',
|
||||
dataType: 'html',
|
||||
beforeSend: function () {
|
||||
$('#button-api').button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$('#button-api').button('reset');
|
||||
},
|
||||
success: function (html) {
|
||||
$('body').append(html);
|
||||
|
||||
$('#modal-api').modal('show');
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
//--></script>
|
||||
<script type="text/javascript"><!--
|
||||
$('#button-buy').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
$('#modal-purchase').remove();
|
||||
|
||||
html = '<div id="modal-purchase" class="modal">';
|
||||
html += ' <div class="modal-dialog">';
|
||||
html += ' <div class="modal-content">';
|
||||
html += ' <div class="modal-header">';
|
||||
html += ' <h5 class="modal-title">{{ text_purchase|escape('js') }}</h5>';
|
||||
html += ' <button type="button" class="btn-close" data-bs-dismiss="modal"></button>';
|
||||
html += ' </div>';
|
||||
html += ' <div class="modal-body">';
|
||||
html += ' <p>{{ text_pin|escape('js') }}</p>';
|
||||
html += ' <p>{{ text_secure|escape('js') }}</p>';
|
||||
html += ' <div class="mb-3">';
|
||||
html += ' <label for="input-pin">{{ entry_pin|escape('js') }}</label>';
|
||||
html += ' <input type="password" name="pin" value="" placeholder="{{ entry_pin|escape('js') }}" id="input-pin" class="form-control"/>';
|
||||
html += ' </div>';
|
||||
html += ' <div class="mb-3 text-end">';
|
||||
html += ' <div class="text-end"><a href="https://www.opencart.com/index.php?route=support/contact" class="btn btn-light btn-lg" target="_blank">{{ button_forgot_pin|escape('js') }}</a></div>';
|
||||
html += ' <button type="button" id="button-purchase" class="btn btn-primary btn-lg">{{ button_purchase|escape('js') }}</button>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += ' </div>';
|
||||
html += '</div>';
|
||||
|
||||
$('body').append(html);
|
||||
|
||||
$('#modal-purchase').modal('show');
|
||||
});
|
||||
|
||||
$('body').on('click', '#modal-purchase #button-purchase', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: 'index.php?route=marketplace/marketplace.purchase&user_token={{ user_token }}&extension_id={{ extension_id }}',
|
||||
type: 'post',
|
||||
data: $('#input-pin'),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#modal-purchase .modal-body').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#modal-purchase').modal('hide');
|
||||
|
||||
$('#alert').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#download').load('index.php?route=marketplace/marketplace.extension&user_token={{ user_token }}&extension_id={{ extension_id }}');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Download
|
||||
$('#download').load('index.php?route=marketplace/marketplace.extension&user_token={{ user_token }}&extension_id={{ extension_id }}');
|
||||
|
||||
$('#tab-download').on('click', '.btn-primary', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).val(),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#download').before('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#download').before('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#tab-download').on('click', '.dropdown-item', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).attr('href'),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#download').before('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#download').before('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#download').load('index.php?route=marketplace/marketplace.extension&user_token={{ user_token }}&extension_id={{ extension_id }}');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Comment
|
||||
$('#comment').on('click', '.pagination a', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
$('#comment').load(this.href);
|
||||
});
|
||||
|
||||
$('#comment').load('index.php?route=marketplace/marketplace.comment&user_token={{ user_token }}&extension_id={{ extension_id }}');
|
||||
|
||||
// Add comment
|
||||
$('#button-comment').on('click', function () {
|
||||
$.ajax({
|
||||
url: 'index.php?route=marketplace/marketplace.addComment&user_token={{ user_token }}&extension_id={{ extension_id }}',
|
||||
type: 'post',
|
||||
dataType: 'json',
|
||||
data: 'comment=' + encodeURIComponent($('#input-history-comment').val()),
|
||||
beforeSend: function () {
|
||||
$('#button-comment').button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$('#button-comment').button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#tab-comment').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#tab-comment').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#comment').load('index.php?route=marketplace/marketplace.comment&user_token={{ user_token }}&extension_id={{ extension_id }}');
|
||||
|
||||
$('#input-history-comment').val('');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Next replies
|
||||
$('#comment').on('click', '.btn-block', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).attr('href'),
|
||||
dataType: 'html',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (html) {
|
||||
$(element).parent().parent().parent().append(html);
|
||||
|
||||
$(element).parent().remove();
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Reply
|
||||
$('#comment').on('click', '.btn-link', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
$(this).parent().parent().find('.reply-input-box').toggle();
|
||||
});
|
||||
|
||||
// Add reply
|
||||
$('#comment').on('click', '.btn-primary', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).attr('href'),
|
||||
type: 'post',
|
||||
dataType: 'json',
|
||||
data: 'comment=' + encodeURIComponent($(element).parents('.reply-input-box').find('textarea[name=\'comment\']').val()),
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$(element).parents('.reply-input-box').before('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$(element).parents('.reply-input-box').before('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$(element).parents('.reply-input-box').parents('.media').find('.reply-refresh').last().trigger('click');
|
||||
|
||||
$(element).parents('.reply-input-box').find('textarea[name=\'comment\']').val('');
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Refresh
|
||||
$('#comment').on('click', '.reply-refresh', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).attr('href'),
|
||||
dataType: 'html',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (html) {
|
||||
$(element).parent().replaceWith(html);
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
$('.thumbnails').magnificPopup({
|
||||
type: 'image',
|
||||
delegate: 'a',
|
||||
gallery: {
|
||||
enabled: true
|
||||
}
|
||||
});
|
||||
});
|
||||
//--></script>
|
||||
{{ footer }}
|
189
admininistrator/view/template/marketplace/marketplace_list.twig
Normal file
189
admininistrator/view/template/marketplace/marketplace_list.twig
Normal file
@ -0,0 +1,189 @@
|
||||
{{ header }}{{ column_left }}
|
||||
<div id="content">
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<div class="float-end">
|
||||
|
||||
{% if signature %}
|
||||
<button type="button" id="button-api" data-bs-toggle="tooltip" title="{{ button_api }}" class="btn btn-info"><i class="fa-solid fa-cog"></i></button>
|
||||
{% else %}
|
||||
<button type="button" id="button-api" data-bs-toggle="tooltip" title="{{ button_api }}" data-placement="left" class="btn btn-danger"><i class="fa-solid fa-triangle-exclamation"></i></button>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<h1>{{ heading_title }}</h1>
|
||||
<ol class="breadcrumb">
|
||||
{% for breadcrumb in breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
|
||||
{% if error_warning %}
|
||||
<div class="alert alert-danger"><i class="fa-solid fa-triangle-exclamation"></i> {{ error_warning }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header"><i class="fa-solid fa-puzzle-piece"></i> {{ text_list }}</div>
|
||||
<div class="card-body">
|
||||
<div class="card bg-light">
|
||||
<div class="card-body">
|
||||
<div id="extension-filter" class="input-group dropdown">
|
||||
<input type="text" name="filter_search" value="{{ filter_search }}" placeholder="{{ text_search }}" id="input-search" class="form-control"/>
|
||||
{% for category in categories %}
|
||||
{% if category.value == filter_category %}
|
||||
<button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown">{{ text_category }} ({{ category.text }}) <i class="fa-solid fa-caret-down"></i></button>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<div class="dropdown-menu dropdown-menu-end">
|
||||
{% for category in categories %}
|
||||
<a href="{{ category.href }}" class="dropdown-item">{{ category.text }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<button type="button" id="button-filter" data-bs-toggle="tooltip" title="{{ button_filter }}" class="btn btn-primary"><i class="fa-solid fa-filter"></i></button>
|
||||
</div>
|
||||
<input type="hidden" name="filter_category_id" value="{{ filter_category_id }}" class="form-control"/> <input type="hidden" name="filter_download_id" value="{{ filter_download_id }}" class="form-control"/> <input type="hidden" name="filter_rating" value="{{ filter_rating }}" class="form-control"/> <input type="hidden" name="filter_license" value="{{ filter_license }}" class="form-control"/> <input type="hidden" name="filter_partner" value="{{ filter_partner }}" class="form-control"/> <input type="hidden" name="sort" value="{{ sort }}" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row mb-4">
|
||||
<div class="col-sm-auto me-sm-auto mb-2 mb-lg-0">
|
||||
<div class="btn-group">{% for license in licenses %}
|
||||
{% if license.value == filter_license %}<a href="{{ license.href }}" class="btn btn-light active">{{ license.text }}</a>{% else %}<a href="{{ license.href }}" class="btn btn-light">{{ license.text }}</a>{% endif %}
|
||||
{% endfor %}</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-5 col-sm-auto">
|
||||
<div class="input-group float-end">
|
||||
<div class="input-group-text"><i class="fa-solid fa-arrow-down-short-wide"></i></div>
|
||||
<select onchange="location = this.value;" class="form-select">
|
||||
{% for sorts in sorts %}
|
||||
<option value="{{ sorts.href }}"{% if sorts.value == sort %} selected{% endif %}>{{ sorts.text }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{% if promotions %}
|
||||
<h3>{{ text_featured }}</h3>
|
||||
<div class="row">
|
||||
{% for extension in promotions %}
|
||||
{% if extension %}
|
||||
<div class="col-lg-3 col-md-4 col-sm-6 col-12">
|
||||
<section>
|
||||
<div class="extension-preview text-center">
|
||||
<a href="{{ extension.href }}">
|
||||
<div class="extension-description">
|
||||
|
||||
</div>
|
||||
<img src="{{ extension.image }}" alt="{{ extension.name }}" title="{{ extension.name }}" class="img-fluid"/></a>
|
||||
</div>
|
||||
<div class="extension-name">
|
||||
<h4><a href="{{ extension.href }}">{{ extension.name }}</a></h4>
|
||||
{{ extension.price }}</div>
|
||||
<div class="extension-rate">
|
||||
<div class="row">
|
||||
<div class="col-6">{% for i in 1..5 %}
|
||||
{% if extension.rating < i %}<i class="fa-regular fa-star"></i>{% else %}<i class="fa-solid fa-star"></i>{% endif %}
|
||||
{% endfor %}</div>
|
||||
<div class="col-6">
|
||||
<div class="text-end">{{ extension.rating_total }} {{ text_reviews }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<hr/>
|
||||
{% endif %}
|
||||
{% if extensions %}
|
||||
<div class="row">
|
||||
{% for extension in extensions %}
|
||||
{% if extension %}
|
||||
<div class="col-lg-3 col-md-4 col-sm-6 col-12">
|
||||
<section>
|
||||
<div class="extension-preview text-center"><a href="{{ extension.href }}">
|
||||
<div class="extension-description"></div>
|
||||
<img src="{{ extension.image }}" alt="{{ extension.name }}" title="{{ extension.name }}" class="img-fluid"/></a></div>
|
||||
<div class="extension-name">
|
||||
<h4><a href="{{ extension.href }}">{{ extension.name }}</a></h4>
|
||||
{{ extension.price }}</div>
|
||||
<div class="extension-rate">
|
||||
<div class="row">
|
||||
<div class="col-6">{% for i in 1..5 %}
|
||||
{% if extension.rating < i %}<i class="fa-regular fa-star"></i>{% else %}<i class="fa-solid fa-star"></i>{% endif %}
|
||||
{% endfor %}</div>
|
||||
<div class="col-6">
|
||||
<div class="text-end">{{ extension.rating_total }} {{ text_reviews }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}</div>
|
||||
{% else %}
|
||||
<p class="text-center">{{ text_no_results }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 text-center">{{ pagination }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript"><!--
|
||||
$('#button-api').on('click', function (e) {
|
||||
$('#modal-api').remove();
|
||||
|
||||
$.ajax({
|
||||
url: 'index.php?route=marketplace/api&user_token={{ user_token }}',
|
||||
dataType: 'html',
|
||||
beforeSend: function () {
|
||||
$('#button-api').button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$('#button-api').button('reset');
|
||||
},
|
||||
success: function (html) {
|
||||
$('body').append(html);
|
||||
|
||||
$('#modal-api').modal('show');
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
//--></script>
|
||||
<script type="text/javascript"><!--
|
||||
$('#button-filter').on('click', function (e) {
|
||||
var url = 'index.php?route=marketplace/marketplace&user_token={{ user_token }}';
|
||||
|
||||
var input = $('#extension-filter :input');
|
||||
|
||||
for (i = 0; i < input.length; i++) {
|
||||
if ($(input[i]).val() !== '') {
|
||||
url += '&' + $(input[i]).attr('name') + '=' + $(input[i]).val()
|
||||
}
|
||||
}
|
||||
|
||||
download();
|
||||
|
||||
location = url;
|
||||
});
|
||||
|
||||
$('#input-search').keydown(function (e) {
|
||||
if (e.keyCode == 13) {
|
||||
e.preventDefault();
|
||||
|
||||
$('#button-filter').trigger('click');
|
||||
}
|
||||
});
|
||||
//--></script>
|
||||
{{ footer }}
|
@ -0,0 +1,17 @@
|
||||
<div>
|
||||
{% if replies %}
|
||||
{% for reply in replies %}
|
||||
<div class="media">
|
||||
<div class="media-left"><img src="{{ reply.image }}" alt="{{ reply.member }}" title="{{ reply.member }}" class="media-object"/></div>
|
||||
<div class="media-body">
|
||||
<p class="media-heading">{{ reply.member }} <span>{{ reply.date_added }}</span></p>
|
||||
<p>{{ reply.comment }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if next %}
|
||||
<div class="text-center"><a href="{{ next }}" class="btn btn-block">{{ text_more }}</a></div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<a href="{{ refresh }}" class="reply-refresh hide">{{ button_refresh }}</a>
|
||||
</div>
|
37
admininistrator/view/template/marketplace/promotion.twig
Normal file
37
admininistrator/view/template/marketplace/promotion.twig
Normal file
@ -0,0 +1,37 @@
|
||||
{% if banner %}
|
||||
<div class="text-center">{{ banner }}</div>
|
||||
<br/>
|
||||
{% endif %}
|
||||
{% if extensions %}
|
||||
<fieldset id="recommended">
|
||||
<legend>{{ text_recommended }}</legend>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="text-start">{{ column_name }}</td>
|
||||
<td class="text-end">{{ column_action }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for extension in extensions %}
|
||||
<tr>
|
||||
<td class="text-start"><a href="{{ extension.href }}">{{ extension.name }}</a></td>
|
||||
<td class="text-end">
|
||||
<div class="dropdown">
|
||||
<div class="btn-group">
|
||||
<button type="button" value="{{ extension.download }}" data-bs-toggle="tooltip" title="{{ button_download }}" class="btn btn-primary"{% if not extension.download %} disabled{% endif %}><i class="fa-solid fa-download"></i></button>
|
||||
<button type="button" data-bs-toggle="dropdown" class="btn btn-outline-dark dropdown-toggle dropdown-toggle-split"><i class="fa-solid fa-caret-down"></i></button>
|
||||
<div class="dropdown-menu dropdown-menu-end">
|
||||
<a href="{{ extension.install }}" class="dropdown-item{% if not extension.install %} disabled{% endif %}"><i class="fa-solid fa-plus-circle fa-fw"></i> {{ text_install }}</a> <a href="{{ extension.delete }}" class="dropdown-item{% if not extension.delete %} disabled{% endif %}"><i class="fa-regular fa-trash-can fa-fw"></i> {{ text_delete }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</fieldset>
|
||||
{% endif %}
|
63
admininistrator/view/template/marketplace/startup.twig
Normal file
63
admininistrator/view/template/marketplace/startup.twig
Normal file
@ -0,0 +1,63 @@
|
||||
{{ header }}{{ column_left }}
|
||||
<div id="content">
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<div class="float-end">
|
||||
<button type="submit" form="form-startup" formaction="{{ delete }}" data-bs-toggle="tooltip" title="{{ button_delete }}" onclick="return confirm('{{ text_confirm }}');" class="btn btn-danger"><i class="fa-regular fa-trash-can"></i></button>
|
||||
</div>
|
||||
<h1>{{ heading_title }}</h1>
|
||||
<ol class="breadcrumb">
|
||||
{% for breadcrumb in breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-header"><i class="fa-solid fa-list"></i> {{ text_list }}</div>
|
||||
<div id="startup" class="card-body">{{ list }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript"><!--
|
||||
$('#startup').on('click', 'thead a, .pagination a', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
$('#startup').load(this.href);
|
||||
});
|
||||
|
||||
$('#startup').on('click', '.btn-success, .btn-danger', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var element = this;
|
||||
|
||||
$.ajax({
|
||||
url: $(element).val(),
|
||||
dataType: 'json',
|
||||
beforeSend: function () {
|
||||
$(element).button('loading');
|
||||
},
|
||||
complete: function () {
|
||||
$(element).button('reset');
|
||||
},
|
||||
success: function (json) {
|
||||
$('.alert-dismissible').remove();
|
||||
|
||||
if (json['error']) {
|
||||
$('#alert').after('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
}
|
||||
|
||||
if (json['success']) {
|
||||
$('#alert').after('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>');
|
||||
|
||||
$('#startup').load($('#form-startup').attr('data-oc-load'));
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
//--></script>
|
||||
{{ footer }}
|
40
admininistrator/view/template/marketplace/startup_list.twig
Normal file
40
admininistrator/view/template/marketplace/startup_list.twig
Normal file
@ -0,0 +1,40 @@
|
||||
<form id="form-startup" method="post" data-oc-toggle="ajax" data-oc-load="{{ action }}" data-oc-target="#startup">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="text-center" style="width: 1px;"><input type="checkbox" onclick="$('input[name*=\'selected\']').prop('checked', $(this).prop('checked'));" class="form-check-input"/></td>
|
||||
<td class="text-start"><a href="{{ sort_code }}"{% if sort == 'code' %} class="{{ order|lower }}"{% endif %}>{{ column_code }}</a></td>
|
||||
<td class="text-start"><a href="{{ sort_action }}"{% if sort == 'action' %} class="{{ order|lower }}"{% endif %}>{{ column_action }}</a></td>
|
||||
<td class="text-end"><a href="{{ sort_sort_order }}"{% if sort == 'sort_order' %} class="{{ order|lower }}"{% endif %}>{{ column_sort_order }}</a></td>
|
||||
<td class="text-end">{{ column_action }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if startups %}
|
||||
{% for startup in startups %}
|
||||
<tr>
|
||||
<td class="text-center"><input type="checkbox" name="selected[]" value="{{ startup.startup_id }}" class="form-check-input"/></td>
|
||||
<td class="text-start">{{ startup.code }}</td>
|
||||
<td class="text-start">{{ startup.action }}</td>
|
||||
<td class="text-end">{{ startup.sort_order }}</td>
|
||||
<td class="text-end">{% if not startup.status %}
|
||||
<button type="button" value="{{ startup.enable }}" data-bs-toggle="tooltip" title="{{ button_enable }}" class="btn btn-success"><i class="fa-solid fa-plus-circle"></i></button>
|
||||
{% else %}
|
||||
<button type="button" value="{{ startup.disable }}" data-bs-toggle="tooltip" title="{{ button_disable }}" class="btn btn-danger"><i class="fa-solid fa-minus-circle"></i></button>
|
||||
{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td class="text-center" colspan="5">{{ text_no_results }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 text-start">{{ pagination }}</div>
|
||||
<div class="col-sm-6 text-end">{{ results }}</div>
|
||||
</div>
|
||||
</form>
|
Reference in New Issue
Block a user