Files
shopPRO/admin/templates/shop-order/order-details-custom-script.php
Jacek Pyziak 7fc8cff474 feat: copy icon for attribute values in order details
Each attribute in .atributes div gets a clipboard icon button.
Click copies the value, icon switches to checkmark for 1.5s.
Uses Clipboard API with textarea fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 20:49:01 +01:00

522 lines
14 KiB
PHP

<style type="text/css">
.attr-copy-btn {
display: inline-block;
padding: 1px 5px;
font-size: 11px;
line-height: 1.5;
background: transparent;
border: 1px solid #d0d0d0;
border-radius: 3px;
color: #999;
cursor: pointer;
vertical-align: middle;
margin-left: 4px;
transition: background .12s, color .12s, border-color .12s;
}
.attr-copy-btn:hover {
background: #f4f4f4;
border-color: #aaa;
color: #555;
}
.attr-copy-btn--copied {
background: #d4edda !important;
border-color: #28a745 !important;
color: #28a745 !important;
}
</style>
<script type="text/javascript">
(function() {
var orderId = <?= (int)($this->order_id ?? 0);?>;
var currentTrustmateState = <?= ((int)($this->trustmate_send ?? 0) === 1) ? 'true' : 'false';?>;
$(function() {
var btn = $('#integrationsDropdownBtn');
var menu = $('#integrationsDropdownMenu');
btn.wrap('<div class="dropdown d-inline-block pull-right"></div>');
menu.appendTo(btn.parent());
btn.on('click', function(e) {
e.preventDefault();
e.stopPropagation();
menu.toggleClass('show');
});
$(document).on('click', function(e) {
if (!btn.is(e.target) && !menu.is(e.target) && menu.has(e.target).length === 0) {
menu.removeClass('show');
}
});
});
$(function() {
var timer = '';
$('#notes').keyup(function() {
var textarea = $(this);
clearTimeout(timer);
timer = setTimeout(function() {
$.ajax({
type: 'POST',
cache: false,
url: '/admin/shop_order/notes_save/',
data: {
order_id: orderId,
notes: textarea.val()
}
});
}, 500);
});
$('body').on('click', '.btn-send-order-to-apilo', function(e) {
e.preventDefault();
var href = $(this).attr('href');
$.alert({
title: 'Potwierdź',
content: 'Czy na pewno chcesz wysłać zamówienie do apilo.com?',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-times',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-question',
buttons: {
confirm: {
text: 'Tak',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
document.location.href = href;
}
},
cancel: {
text: 'Nie',
btnClass: 'btn-dark',
action: function() {}
}
}
});
});
});
$('body').on('click', '.set_order_as_unpaid', function() {
var href = $(this).attr('href');
$.alert({
title: 'Pytanie',
content: 'Zmienić zamówienie na nieopłacone?',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-times',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-question',
buttons: {
confirm: {
text: 'Tak',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
document.location.href = href;
}
},
cancel: {
text: 'Nie',
btnClass: 'btn-dark',
action: function() {}
}
}
});
return false;
});
$('body').on('click', '.set_order_as_paid', function() {
var href = $(this).attr('href');
$.alert({
title: 'Pytanie',
content: 'Zmienić zamówienie na opłacone?',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-times',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-question',
buttons: {
confirm: {
text: 'Tak',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
document.location.href = href;
}
},
confirm2: {
text: 'Tak (wyślij mail)',
btnClass: 'btn-primary',
keys: ['enter'],
action: function() {
document.location.href = href + '&send_mail=1';
}
},
cancel: {
text: 'Nie',
btnClass: 'btn-dark',
action: function() {}
}
}
});
return false;
});
$('body').on('click', '.order_status_change_email', function() {
$.alert({
title: 'Pytanie',
content: 'Na pewno chcesz wysłać mail o zmianie statusu?',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-times',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-question',
buttons: {
confirm: {
text: 'Tak',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
order_status_change(orderId, $('#order-status').val(), true);
}
},
cancel: {
text: 'Nie',
btnClass: 'btn-dark',
action: function() {}
}
}
});
return false;
});
$('body').on('click', '.resend_order_confirmation_email button', function() {
$.alert({
title: 'Pytanie',
content: 'Na pewno chcesz wysłać mail o złożonym zamówieniu?',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-times',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-question',
buttons: {
confirm: {
text: 'Tak',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
$.ajax({
type: 'POST',
cache: false,
url: '/admin/shop_order/order_resend_confirmation_email/',
data: {
order_id: orderId
},
beforeSend: function() {
$('#overlay').show();
},
success: function(response) {
$('#overlay').hide();
var data = jQuery.parseJSON(response);
if (data.result === true) {
return $.alert({
title: 'Informacja',
content: 'Wiadomość została wysłana',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-close',
typeAnimated: true,
animation: 'opacity',
autoClose: 'confirm|10000',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-info',
buttons: {
confirm: {
text: 'Zamknij',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
location.reload();
}
}
}
});
}
if (data.result === false) {
return $.alert({
title: 'Błąd',
content: 'Podczas wysyłania wiadomości wystąpił błąd',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-close',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-exclamation',
buttons: {
confirm: {
text: 'Zamknij',
btnClass: 'btn-danger',
keys: ['enter'],
action: function() {
location.reload();
}
}
}
});
}
}
});
}
},
cancel: {
text: 'Nie',
btnClass: 'btn-dark',
action: function() {}
}
}
});
return false;
});
$('body').on('click', '.order_status_change', function() {
order_status_change(orderId, $('#order-status').val(), false);
return false;
});
function order_status_change(order_id, status, email) {
$.ajax({
type: 'POST',
cache: false,
url: '/admin/shop_order/order_status_change/',
data: {
order_id: order_id,
status: status,
email: email
},
beforeSend: function() {
$('#overlay').show();
},
success: function(response) {
$('#overlay').hide();
var data = jQuery.parseJSON(response);
if (data.email === true) {
return $.alert({
title: 'Informacja',
content: 'Wiadomość o zmiane statusu została wysłana',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-close',
typeAnimated: true,
animation: 'opacity',
autoClose: 'confirm|10000',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-info',
buttons: {
confirm: {
text: 'Zamknij',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
location.reload();
}
}
}
});
}
if (data.email === false) {
return $.alert({
title: 'Błąd',
content: 'Podczas wysyłania wiadomości wystąpił błąd',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-close',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-exclamation',
buttons: {
confirm: {
text: 'Zamknij',
btnClass: 'btn-danger',
keys: ['enter'],
action: function() {
location.reload();
}
}
}
});
}
if (data.result == true) {
return $.alert({
title: 'Informacja',
content: 'Status zamówienia został zmieniony',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-close',
typeAnimated: true,
animation: 'opacity',
autoClose: 'confirm|10000',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-info',
buttons: {
confirm: {
text: 'Zamknij',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
location.reload();
}
}
}
});
}
}
});
}
$(function() {
function fallbackCopy(text) {
var $tmp = $('<textarea>').css({position: 'fixed', top: 0, left: 0, opacity: 0}).val(text);
$('body').append($tmp);
$tmp[0].select();
try { document.execCommand('copy'); } catch (e) {}
$tmp.remove();
}
$('.atributes').each(function() {
var $div = $(this);
var html = $.trim($div.html());
if (!html) { return; }
var parts = html.split(/<br\s*\/?>/i);
var newParts = [];
for (var i = 0; i < parts.length; i++) {
var part = $.trim(parts[i]);
if (!part) { continue; }
var match = part.match(/^(<b>[^<]*<\/b>\s*:\s*)(.+)$/);
if (match) {
var labelHtml = match[1];
var value = $.trim(match[2]);
var escapedValue = $('<div>').text(value).html();
part = labelHtml + escapedValue
+ ' <button type="button" class="js-attr-copy-btn attr-copy-btn" data-value="'
+ escapedValue + '" title="Kopiuj: ' + escapedValue + '">'
+ '<i class="fa fa-copy"></i></button>';
}
newParts.push(part);
}
$div.html(newParts.join('<br>'));
});
$(document).on('click', '.js-attr-copy-btn', function() {
var $btn = $(this);
var value = String($btn.data('value'));
function showCopied() {
$btn.addClass('attr-copy-btn--copied');
$btn.find('i').removeClass('fa-copy').addClass('fa-check');
setTimeout(function() {
$btn.removeClass('attr-copy-btn--copied');
$btn.find('i').removeClass('fa-check').addClass('fa-copy');
}, 1500);
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(value).then(showCopied, function() {
fallbackCopy(value);
showCopied();
});
} else {
fallbackCopy(value);
showCopied();
}
});
});
$('body').on('click', '.btn-toggle-trustmate', function(e) {
e.preventDefault();
$.alert({
title: 'Potwierdź',
content: currentTrustmateState
? 'Czy na pewno chcesz odznaczyć zamówienie jako wysłane do trustmate.io?'
: 'Czy na pewno chcesz zaznaczyć zamówienie jako wysłane do trustmate.io?',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-times',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-question',
buttons: {
confirm: {
text: 'Tak',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
$.ajax({
type: 'POST',
cache: false,
url: '/admin/shop_order/toggle_trustmate_send/',
data: {
order_id: orderId
},
beforeSend: function() {
$('#overlay').show();
},
success: function(response) {
$('#overlay').hide();
var data = jQuery.parseJSON(response);
if (data.result === true) {
location.reload();
}
}
});
}
},
cancel: {
text: 'Nie',
btnClass: 'btn-dark',
action: function() {}
}
}
});
});
})();
</script>