update
This commit is contained in:
@@ -35,6 +35,7 @@ return [
|
||||
'company' => 'Dane firmy',
|
||||
'accounting' => 'Ksiegowosc',
|
||||
'accounting_section' => 'Ksiegowosc',
|
||||
'project_mapping' => 'Mapowanie projektow',
|
||||
],
|
||||
'marketplace' => [
|
||||
'title' => 'Marketplace',
|
||||
@@ -84,7 +85,7 @@ return [
|
||||
'title' => 'Logowanie',
|
||||
'heading' => 'Panel zarzadzania zamowieniami',
|
||||
'subtitle' => 'Zaloguj sie, aby przejsc do obslugi zamowien i wysylek.',
|
||||
'error_placeholder' => 'Miejsce na komunikat bledu logowania.',
|
||||
'remember_me' => 'Zapamietaj mnie',
|
||||
'email_label' => 'Email',
|
||||
'email_placeholder' => 'np. admin@firma.pl',
|
||||
'password_label' => 'Haslo',
|
||||
@@ -105,6 +106,18 @@ return [
|
||||
'title' => 'Zamowienia',
|
||||
'description' => 'Kompaktowa lista zamowien oparta o lokalna baze orderPRO.',
|
||||
'empty' => 'Brak zamowien do wyswietlenia.',
|
||||
'preview' => [
|
||||
'title' => 'Podglad zamowienia',
|
||||
'buyer' => 'Kupujacy',
|
||||
'order_number' => 'Nr zamowienia',
|
||||
'delivery_address' => 'Adres dostawy',
|
||||
'products' => 'Produkty',
|
||||
'summary' => 'Podsumowanie',
|
||||
'full_details' => 'Pelne szczegoly',
|
||||
'close' => 'Zamknij',
|
||||
'loading' => 'Ladowanie...',
|
||||
'notes' => 'Wiadomosc od klienta',
|
||||
],
|
||||
'fields' => [
|
||||
'order_ref' => 'Zamowienie',
|
||||
'status' => 'Status',
|
||||
@@ -1110,6 +1123,46 @@ return [
|
||||
'save_failed' => 'Nie udalo sie zapisac ustawien GS1.',
|
||||
],
|
||||
],
|
||||
'project_mapping' => [
|
||||
'title' => 'Mapowanie projektow',
|
||||
'description' => 'Mapowanie produktow na skrypty generujace projekty graficzne.',
|
||||
'add_title' => 'Dodaj mapowanie',
|
||||
'list_title' => 'Istniejace mapowania',
|
||||
'edit_title' => 'Edytuj mapowanie',
|
||||
'empty' => 'Brak zdefiniowanych mapowan.',
|
||||
'confirm_delete' => 'Czy na pewno chcesz usunac to mapowanie?',
|
||||
'fields' => [
|
||||
'pattern' => 'Wzorzec nazwy produktu',
|
||||
'script' => 'Skrypt generujacy',
|
||||
'output_dir' => 'Katalog wyjsciowy',
|
||||
'active' => 'Status',
|
||||
'actions' => 'Akcje',
|
||||
],
|
||||
'placeholders' => [
|
||||
'pattern' => 'np. %buteleczk%',
|
||||
'script' => 'Wybierz skrypt',
|
||||
'output_dir' => 'Domyslny z skryptu',
|
||||
],
|
||||
'status' => [
|
||||
'active' => 'Aktywne',
|
||||
'inactive' => 'Nieaktywne',
|
||||
],
|
||||
'actions' => [
|
||||
'add' => 'Dodaj',
|
||||
'edit' => 'Edytuj',
|
||||
'delete' => 'Usun',
|
||||
'save' => 'Zapisz',
|
||||
'cancel' => 'Anuluj',
|
||||
],
|
||||
'flash' => [
|
||||
'created' => 'Mapowanie zostalo dodane.',
|
||||
'updated' => 'Mapowanie zostalo zaktualizowane.',
|
||||
'deleted' => 'Mapowanie zostalo usuniete.',
|
||||
'toggled' => 'Status mapowania zostal zmieniony.',
|
||||
'validation_error' => 'Wypelnij wymagane pola.',
|
||||
'script_not_found' => 'Wybrany skrypt nie istnieje.',
|
||||
],
|
||||
],
|
||||
'company' => [
|
||||
'title' => 'Dane firmy',
|
||||
'description' => 'Adres nadawcy, dane bankowe i domyslne wymiary paczek.',
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
@use "modules/delivery-status";
|
||||
@use "modules/delivery-status-mappings";
|
||||
@use "modules/global-search";
|
||||
@use "modules/order-preview-modal";
|
||||
@use "modules/project-mappings";
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -101,8 +101,23 @@ h1 {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.login-alert-placeholder {
|
||||
opacity: 0.56;
|
||||
.remember-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
input[type="checkbox"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
accent-color: var(--c-primary, #4f6ef7);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form {
|
||||
|
||||
241
resources/scss/modules/_order-preview-modal.scss
Normal file
241
resources/scss/modules/_order-preview-modal.scss
Normal file
@@ -0,0 +1,241 @@
|
||||
.order-preview-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1000;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.order-preview-modal {
|
||||
background: var(--c-surface);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.18);
|
||||
width: 100%;
|
||||
max-width: 960px;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__close {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
color: var(--c-muted);
|
||||
padding: 0 4px;
|
||||
line-height: 1;
|
||||
|
||||
&:hover {
|
||||
color: var(--c-text);
|
||||
}
|
||||
}
|
||||
|
||||
&__body {
|
||||
padding: 20px 24px;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding: 12px 20px;
|
||||
border-top: 1px solid var(--c-border);
|
||||
}
|
||||
}
|
||||
|
||||
.order-preview-loading {
|
||||
text-align: center;
|
||||
padding: 32px;
|
||||
color: var(--c-muted);
|
||||
}
|
||||
|
||||
.order-preview-error {
|
||||
text-align: center;
|
||||
padding: 32px;
|
||||
color: var(--c-danger, #e53e3e);
|
||||
}
|
||||
|
||||
.order-preview-section {
|
||||
margin-bottom: 14px;
|
||||
|
||||
&__title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-muted);
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
}
|
||||
|
||||
.order-preview-kv {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 4px 14px;
|
||||
font-size: 14px;
|
||||
|
||||
dt {
|
||||
color: var(--c-muted);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.order-preview-items {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
border-collapse: collapse;
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 6px 8px;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-muted);
|
||||
}
|
||||
|
||||
tbody tr + tr {
|
||||
border-top: 1px solid var(--c-border);
|
||||
}
|
||||
}
|
||||
|
||||
.order-preview-item-cell {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.order-preview-item-thumb {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
flex-shrink: 0;
|
||||
|
||||
&--empty {
|
||||
background: var(--c-bg, #f5f5f5);
|
||||
}
|
||||
}
|
||||
|
||||
.order-preview-item-info {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.order-preview-item-name {
|
||||
font-size: 14px;
|
||||
line-height: 1.3;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.order-preview-personalization {
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
color: var(--c-muted);
|
||||
line-height: 1.4;
|
||||
|
||||
&__line {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
.order-preview-notes {
|
||||
font-size: 14px;
|
||||
|
||||
&__item {
|
||||
padding: 6px 0;
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid var(--c-border);
|
||||
}
|
||||
}
|
||||
|
||||
&__type {
|
||||
font-size: 11px;
|
||||
color: var(--c-muted);
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
&__text {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
.copy-field__btn {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--c-muted);
|
||||
padding: 0 2px;
|
||||
line-height: 1;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.15s;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
color: var(--c-primary, #4f6ef7);
|
||||
}
|
||||
|
||||
&.is-copied {
|
||||
color: #22c55e;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-icon.js-order-preview-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: var(--c-muted);
|
||||
padding: 2px 4px;
|
||||
line-height: 1;
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.15s;
|
||||
vertical-align: middle;
|
||||
margin-right: 4px;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
color: var(--c-primary, #4f6ef7);
|
||||
}
|
||||
}
|
||||
102
resources/scss/modules/_project-mappings.scss
Normal file
102
resources/scss/modules/_project-mappings.scss
Normal file
@@ -0,0 +1,102 @@
|
||||
.pm-form {
|
||||
&__row {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: flex-end;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&__field {
|
||||
flex: 1;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.pm-row {
|
||||
&--inactive {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
white-space: nowrap;
|
||||
|
||||
.btn + .btn {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.project-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
padding: 1px 4px;
|
||||
border-radius: 3px;
|
||||
vertical-align: middle;
|
||||
margin-left: 4px;
|
||||
|
||||
&--done {
|
||||
color: #16a34a;
|
||||
background: rgba(22, 163, 74, 0.1);
|
||||
}
|
||||
|
||||
&--partial {
|
||||
color: #d97706;
|
||||
background: rgba(217, 119, 6, 0.1);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&--none {
|
||||
color: #9ca3af;
|
||||
background: rgba(156, 163, 175, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.item-project-badge {
|
||||
display: inline-block;
|
||||
font-size: 10px;
|
||||
padding: 1px 6px;
|
||||
border-radius: 3px;
|
||||
margin-left: 6px;
|
||||
vertical-align: middle;
|
||||
|
||||
&--done {
|
||||
color: #16a34a;
|
||||
background: rgba(22, 163, 74, 0.1);
|
||||
}
|
||||
|
||||
&--pending {
|
||||
color: #9ca3af;
|
||||
background: rgba(156, 163, 175, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.pm-modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&__overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
&__content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,6 @@
|
||||
<div class="alert alert--danger login-alert" role="alert">
|
||||
<?= $e($errorMessage) ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert--danger login-alert login-alert-placeholder" aria-hidden="true">
|
||||
<?= $e($t('auth.login.error_placeholder')) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form class="login-form" action="/login" method="post" novalidate>
|
||||
@@ -43,6 +39,11 @@
|
||||
>
|
||||
</label>
|
||||
|
||||
<label class="form-field form-field--inline remember-field">
|
||||
<input type="checkbox" name="remember" value="1" <?= !empty($oldRemember) ? 'checked' : '' ?>>
|
||||
<span class="field-label"><?= $e($t('auth.login.remember_me')) ?></span>
|
||||
</label>
|
||||
|
||||
<button type="submit" class="btn btn--primary btn--block login-submit"><?= $e($t('actions.login')) ?></button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
@@ -84,6 +84,7 @@ $orderStatusOptions = is_array($orderStatusOptions ?? null) ? $orderStatusOption
|
||||
<option value="integration"<?= ((string) ($cond['condition_type'] ?? '')) === 'integration' ? ' selected' : '' ?>>Integracja (kanal sprzedazy)</option>
|
||||
<option value="shipment_status"<?= ((string) ($cond['condition_type'] ?? '')) === 'shipment_status' ? ' selected' : '' ?>>Status przesylki</option>
|
||||
<option value="payment_status"<?= ((string) ($cond['condition_type'] ?? '')) === 'payment_status' ? ' selected' : '' ?>>Status platnosci</option>
|
||||
<option value="payment_method"<?= ((string) ($cond['condition_type'] ?? '')) === 'payment_method' ? ' selected' : '' ?>>Metoda platnosci</option>
|
||||
<option value="order_status"<?= ((string) ($cond['condition_type'] ?? '')) === 'order_status' ? ' selected' : '' ?>>Status zamowienia</option>
|
||||
<option value="days_in_status"<?= ((string) ($cond['condition_type'] ?? '')) === 'days_in_status' ? ' selected' : '' ?>>Liczba dni w statusie</option>
|
||||
</select>
|
||||
@@ -93,6 +94,7 @@ $orderStatusOptions = is_array($orderStatusOptions ?? null) ? $orderStatusOption
|
||||
$conditionType = (string) ($cond['condition_type'] ?? 'integration');
|
||||
$selectedIds = is_array($condValue['integration_ids'] ?? null) ? $condValue['integration_ids'] : [];
|
||||
$selectedStatusKeys = is_array($condValue['status_keys'] ?? null) ? $condValue['status_keys'] : [];
|
||||
$selectedMethodKeys = is_array($condValue['method_keys'] ?? null) ? $condValue['method_keys'] : [];
|
||||
$selectedOrderStatusCodes = is_array($condValue['order_status_codes'] ?? null) ? $condValue['order_status_codes'] : [];
|
||||
?>
|
||||
<?php if ($conditionType === 'shipment_status'): ?>
|
||||
@@ -114,6 +116,15 @@ $orderStatusOptions = is_array($orderStatusOptions ?? null) ? $orderStatusOption
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php elseif ($conditionType === 'payment_method'): ?>
|
||||
<div class="checkbox-group">
|
||||
<?php foreach ($paymentMethodOptions as $methodKey => $methodLabel): ?>
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" name="conditions[<?= $idx ?>][payment_method_keys][]" value="<?= $e((string) $methodKey) ?>"<?= in_array((string) $methodKey, $selectedMethodKeys, true) ? ' checked' : '' ?>>
|
||||
<?= $e($methodLabel) ?>
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php elseif ($conditionType === 'order_status'): ?>
|
||||
<div class="checkbox-group">
|
||||
<?php foreach ($orderStatusOptions as $statusOption): ?>
|
||||
@@ -263,6 +274,7 @@ window.AutomationFormData = {
|
||||
receiptDuplicatePolicyLabels: <?= json_encode($receiptDuplicatePolicyLabels, JSON_UNESCAPED_UNICODE) ?>,
|
||||
shipmentStatusOptions: <?= json_encode($shipmentStatusOptions, JSON_UNESCAPED_UNICODE) ?>,
|
||||
paymentStatusOptions: <?= json_encode($paymentStatusOptions, JSON_UNESCAPED_UNICODE) ?>,
|
||||
paymentMethodOptions: <?= json_encode($paymentMethodOptions, JSON_UNESCAPED_UNICODE) ?>,
|
||||
orderStatusOptions: <?= json_encode(array_map(function($status) {
|
||||
return [
|
||||
'code' => (string) ($status['code'] ?? ''),
|
||||
|
||||
@@ -107,6 +107,9 @@
|
||||
<a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'delivery-status-mappings' ? ' is-active' : '' ?>" href="/settings/delivery-status-mappings">
|
||||
Mapowanie statusów dostawy
|
||||
</a>
|
||||
<a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'project-mappings' ? ' is-active' : '' ?>" href="/settings/project-mappings">
|
||||
<?= $e($t('navigation.project_mapping')) ?>
|
||||
</a>
|
||||
<a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'database' ? ' is-active' : '' ?>" href="/settings/database">
|
||||
<?= $e($t('navigation.database')) ?>
|
||||
</a>
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php require __DIR__ . '/partials/preview-modal.php'; ?>
|
||||
|
||||
<script type="application/json" id="js-inline-status-config"><?= json_encode([
|
||||
'allStatuses' => is_array($allStatuses ?? null) ? $allStatuses : [],
|
||||
'statusColorMap' => is_array($statusColorMap ?? null) ? $statusColorMap : [],
|
||||
@@ -60,4 +62,79 @@
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var overlay = document.getElementById('order-preview-overlay');
|
||||
var body = document.getElementById('order-preview-body');
|
||||
var detailsLink = document.getElementById('order-preview-details-link');
|
||||
if (!overlay || !body) return;
|
||||
|
||||
function openPreview(orderId) {
|
||||
body.innerHTML = '<div class="order-preview-loading">Ladowanie...</div>';
|
||||
detailsLink.href = '/orders/' + orderId;
|
||||
overlay.style.display = 'flex';
|
||||
|
||||
fetch('/api/orders/' + orderId + '/preview', { credentials: 'same-origin' })
|
||||
.then(function (res) {
|
||||
if (!res.ok) throw new Error('HTTP ' + res.status);
|
||||
return res.text();
|
||||
})
|
||||
.then(function (html) {
|
||||
body.innerHTML = html;
|
||||
})
|
||||
.catch(function () {
|
||||
body.innerHTML = '<div class="order-preview-loading">Nie udalo sie zaladowac podgladu.</div>';
|
||||
});
|
||||
}
|
||||
|
||||
function closePreview() {
|
||||
overlay.style.display = 'none';
|
||||
body.innerHTML = '';
|
||||
}
|
||||
|
||||
document.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest('.js-order-preview-btn');
|
||||
if (btn) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var orderId = btn.getAttribute('data-order-id');
|
||||
if (orderId) openPreview(orderId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.target.id === 'order-preview-close' || e.target.id === 'order-preview-close-btn') {
|
||||
closePreview();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.target === overlay) {
|
||||
closePreview();
|
||||
return;
|
||||
}
|
||||
|
||||
var copyBtn = e.target.closest('.copy-field__btn');
|
||||
if (copyBtn) {
|
||||
var value = copyBtn.getAttribute('data-copy-value') || '';
|
||||
if (value === '') return;
|
||||
navigator.clipboard.writeText(value).then(function () {
|
||||
var copyIc = copyBtn.querySelector('.copy-icon');
|
||||
var checkIc = copyBtn.querySelector('.check-icon');
|
||||
if (copyIc) copyIc.style.display = 'none';
|
||||
if (checkIc) checkIc.style.display = '';
|
||||
copyBtn.classList.add('is-copied');
|
||||
setTimeout(function () {
|
||||
if (copyIc) copyIc.style.display = '';
|
||||
if (checkIc) checkIc.style.display = 'none';
|
||||
copyBtn.classList.remove('is-copied');
|
||||
}, 1500);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape' && overlay.style.display !== 'none') {
|
||||
closePreview();
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
189
resources/views/orders/partials/preview-content.php
Normal file
189
resources/views/orders/partials/preview-content.php
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
$orderRow = is_array($order ?? null) ? $order : [];
|
||||
$itemsList = is_array($items ?? null) ? $items : [];
|
||||
$notesList = is_array($notes ?? null) ? $notes : [];
|
||||
$addrMap = is_array($addressByType ?? null) ? $addressByType : [];
|
||||
$customer = is_array($addrMap['customer'] ?? null) ? $addrMap['customer'] : [];
|
||||
$delivery = is_array($addrMap['delivery'] ?? null) ? $addrMap['delivery'] : [];
|
||||
|
||||
$orderNumber = trim((string) ($orderRow['internal_order_number'] ?? ''));
|
||||
if ($orderNumber === '') {
|
||||
$orderNumber = '#' . (string) ($orderRow['id'] ?? 0);
|
||||
}
|
||||
$externalId = trim((string) ($orderRow['external_order_id'] ?? ''));
|
||||
$buyerName = trim((string) ($customer['name'] ?? ''));
|
||||
$buyerEmail = trim((string) ($customer['email'] ?? ''));
|
||||
$buyerPhone = trim((string) ($customer['phone'] ?? ''));
|
||||
|
||||
$deliveryName = trim((string) ($delivery['name'] ?? ''));
|
||||
$deliveryStreet = trim((string) (($delivery['street_name'] ?? '') . ' ' . ($delivery['street_number'] ?? '')));
|
||||
$deliveryCity = trim((string) (($delivery['zip_code'] ?? '') . ' ' . ($delivery['city'] ?? '')));
|
||||
$deliveryCountry = trim((string) ($delivery['country'] ?? ''));
|
||||
$deliveryParcel = trim((string) ($delivery['parcel_name'] ?? ''));
|
||||
$deliveryParcelId = trim((string) ($delivery['parcel_external_id'] ?? ''));
|
||||
|
||||
$fullDeliveryAddress = implode(', ', array_filter([
|
||||
$deliveryName,
|
||||
$deliveryStreet,
|
||||
$deliveryCity,
|
||||
$deliveryCountry,
|
||||
$deliveryParcel !== '' ? $deliveryParcel : null,
|
||||
$deliveryParcelId !== '' ? $deliveryParcelId : null,
|
||||
]));
|
||||
|
||||
$totalWithTax = $orderRow['total_with_tax'] !== null ? number_format((float) $orderRow['total_with_tax'], 2, '.', ' ') : '-';
|
||||
$totalPaid = $orderRow['total_paid'] !== null ? number_format((float) $orderRow['total_paid'], 2, '.', ' ') : '-';
|
||||
$currency = trim((string) ($orderRow['currency'] ?? ''));
|
||||
|
||||
$copyIcon = '<svg class="copy-icon" xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>';
|
||||
$checkIcon = '<svg class="check-icon" style="display:none" xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>';
|
||||
$copyBtn = static function (string $value) use ($e, $copyIcon, $checkIcon): string {
|
||||
if ($value === '') return '';
|
||||
return ' <button type="button" class="copy-field__btn" data-copy-value="' . $e($value) . '" title="Kopiuj">' . $copyIcon . $checkIcon . '</button>';
|
||||
};
|
||||
?>
|
||||
|
||||
<div class="order-preview-section">
|
||||
<div class="order-preview-section__title"><?= $e($t('orders.preview.order_number')) ?></div>
|
||||
<div class="order-preview-kv">
|
||||
<dt>Nr:</dt>
|
||||
<dd><strong><?= $e($orderNumber) ?></strong><?= $copyBtn($orderNumber) ?></dd>
|
||||
<?php if ($externalId !== ''): ?>
|
||||
<dt>Zewn. ID:</dt>
|
||||
<dd><?= $e($externalId) ?><?= $copyBtn($externalId) ?></dd>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-preview-section">
|
||||
<div class="order-preview-section__title"><?= $e($t('orders.preview.buyer')) ?></div>
|
||||
<div class="order-preview-kv">
|
||||
<?php if ($buyerName !== ''): ?>
|
||||
<dt>Nazwa:</dt>
|
||||
<dd><?= $e($buyerName) ?><?= $copyBtn($buyerName) ?></dd>
|
||||
<?php endif; ?>
|
||||
<?php if ($buyerEmail !== ''): ?>
|
||||
<dt>Email:</dt>
|
||||
<dd><?= $e($buyerEmail) ?><?= $copyBtn($buyerEmail) ?></dd>
|
||||
<?php endif; ?>
|
||||
<?php if ($buyerPhone !== ''): ?>
|
||||
<dt>Telefon:</dt>
|
||||
<dd><?= $e($buyerPhone) ?><?= $copyBtn($buyerPhone) ?></dd>
|
||||
<?php endif; ?>
|
||||
<?php if ($buyerName === '' && $buyerEmail === ''): ?>
|
||||
<dt></dt><dd class="muted">Brak danych</dd>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-preview-section">
|
||||
<div class="order-preview-section__title"><?= $e($t('orders.preview.delivery_address')) ?></div>
|
||||
<?php if ($delivery !== []): ?>
|
||||
<div class="order-preview-kv">
|
||||
<?php if ($deliveryName !== ''): ?>
|
||||
<dt>Odbiorca:</dt>
|
||||
<dd><?= $e($deliveryName) ?><?= $copyBtn($deliveryName) ?></dd>
|
||||
<?php endif; ?>
|
||||
<?php if ($deliveryStreet !== ''): ?>
|
||||
<dt>Ulica:</dt>
|
||||
<dd><?= $e($deliveryStreet) ?></dd>
|
||||
<?php endif; ?>
|
||||
<?php if ($deliveryCity !== ''): ?>
|
||||
<dt>Miasto:</dt>
|
||||
<dd><?= $e($deliveryCity) ?></dd>
|
||||
<?php endif; ?>
|
||||
<?php if ($deliveryParcel !== ''): ?>
|
||||
<dt>Punkt:</dt>
|
||||
<dd><?= $e($deliveryParcel) ?><?= $deliveryParcelId !== '' ? ' (' . $e($deliveryParcelId) . ')' : '' ?></dd>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div style="margin-top:4px">
|
||||
<button type="button" class="copy-field__btn" data-copy-value="<?= $e($fullDeliveryAddress) ?>" title="Kopiuj caly adres" style="font-size:11px;opacity:0.7">
|
||||
<?= $copyIcon ?> Kopiuj caly adres
|
||||
</button>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="muted">Brak danych</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($itemsList !== []): ?>
|
||||
<div class="order-preview-section">
|
||||
<div class="order-preview-section__title"><?= $e($t('orders.preview.products')) ?> (<?= $e((string) count($itemsList)) ?>)</div>
|
||||
<table class="order-preview-items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Produkt</th>
|
||||
<th>Ilosc</th>
|
||||
<th>Cena</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($itemsList as $item): ?>
|
||||
<?php
|
||||
$qty = (float) ($item['quantity'] ?? 0);
|
||||
$price = $item['original_price_with_tax'] !== null ? (float) $item['original_price_with_tax'] : null;
|
||||
$media = trim((string) ($item['media_url'] ?? ''));
|
||||
$personalization = trim((string) ($item['personalization'] ?? ''));
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="order-preview-item-cell">
|
||||
<?php if ($media !== ''): ?>
|
||||
<img src="<?= $e($media) ?>" alt="" class="order-preview-item-thumb">
|
||||
<?php else: ?>
|
||||
<span class="order-preview-item-thumb order-preview-item-thumb--empty"></span>
|
||||
<?php endif; ?>
|
||||
<div class="order-preview-item-info">
|
||||
<div class="order-preview-item-name"><?= $e((string) ($item['original_name'] ?? '-')) ?></div>
|
||||
<?php if ($personalization !== ''): ?>
|
||||
<div class="order-preview-personalization">
|
||||
<?php foreach (explode("\n", $personalization) as $line): ?>
|
||||
<?php if (trim($line) !== ''): ?>
|
||||
<div class="order-preview-personalization__line"><?= $e(trim($line)) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><?= $e((string) $qty) ?></td>
|
||||
<td><?= $e($price !== null ? number_format($price, 2, '.', ' ') . ' ' . $currency : '-') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($notesList !== []): ?>
|
||||
<div class="order-preview-section">
|
||||
<div class="order-preview-section__title"><?= $e($t('orders.preview.notes')) ?></div>
|
||||
<div class="order-preview-notes">
|
||||
<?php foreach ($notesList as $note): ?>
|
||||
<div class="order-preview-notes__item">
|
||||
<div class="order-preview-notes__type"><?= $e((string) ($note['note_type'] ?? '')) ?> | <?= $e((string) ($note['created_at_external'] ?? '')) ?></div>
|
||||
<div class="order-preview-notes__text"><?= $e((string) ($note['comment'] ?? '')) ?><?= $copyBtn(trim((string) ($note['comment'] ?? ''))) ?></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="order-preview-section">
|
||||
<div class="order-preview-section__title"><?= $e($t('orders.preview.summary')) ?></div>
|
||||
<div class="order-preview-kv">
|
||||
<dt>Razem:</dt>
|
||||
<dd><strong><?= $e($totalWithTax . ' ' . $currency) ?></strong></dd>
|
||||
<dt>Oplacono:</dt>
|
||||
<dd><?= $e($totalPaid . ' ' . $currency) ?></dd>
|
||||
<?php
|
||||
$paymentType = strtoupper(trim((string) ($orderRow['external_payment_type_id'] ?? '')));
|
||||
if ($paymentType !== ''):
|
||||
?>
|
||||
<dt>Platnosc:</dt>
|
||||
<dd><?= $e($paymentType) ?></dd>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
15
resources/views/orders/partials/preview-modal.php
Normal file
15
resources/views/orders/partials/preview-modal.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<div class="order-preview-overlay" id="order-preview-overlay" style="display:none">
|
||||
<div class="order-preview-modal">
|
||||
<div class="order-preview-modal__header">
|
||||
<h3 class="order-preview-modal__title"><?= $e($t('orders.preview.title')) ?></h3>
|
||||
<button type="button" class="order-preview-modal__close" id="order-preview-close">×</button>
|
||||
</div>
|
||||
<div class="order-preview-modal__body" id="order-preview-body">
|
||||
<div class="order-preview-loading"><?= $e($t('orders.preview.loading')) ?></div>
|
||||
</div>
|
||||
<div class="order-preview-modal__footer">
|
||||
<a href="#" class="btn btn--primary btn--sm" id="order-preview-details-link"><?= $e($t('orders.preview.full_details')) ?></a>
|
||||
<button type="button" class="btn btn--secondary btn--sm" id="order-preview-close-btn"><?= $e($t('orders.preview.close')) ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -168,7 +168,14 @@ foreach ($addressesList as $address) {
|
||||
<span class="order-item-thumb order-item-thumb--empty"></span>
|
||||
<?php endif; ?>
|
||||
<div>
|
||||
<div class="order-item-name"><?= $e((string) ($item['original_name'] ?? '')) ?></div>
|
||||
<div class="order-item-name"><?= $e((string) ($item['original_name'] ?? '')) ?><?php
|
||||
$projGen = (int) ($item['project_generated'] ?? 0);
|
||||
if ($projGen === 1): ?>
|
||||
<span class="item-project-badge item-project-badge--done">Projekt</span>
|
||||
<?php else: ?>
|
||||
<span class="item-project-badge item-project-badge--pending">Brak projektu</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $personalization = trim((string) ($item['personalization'] ?? '')); ?>
|
||||
<?php if ($personalization !== ''): ?>
|
||||
<div class="item-personalization">
|
||||
|
||||
178
resources/views/settings/project-mappings.php
Normal file
178
resources/views/settings/project-mappings.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
$mappings = is_array($mappings ?? null) ? $mappings : [];
|
||||
$scripts = is_array($scripts ?? null) ? $scripts : [];
|
||||
?>
|
||||
|
||||
<section class="card">
|
||||
<h2 class="section-title"><?= $e($t('settings.project_mapping.title')) ?></h2>
|
||||
<p class="muted mt-4"><?= $e($t('settings.project_mapping.description')) ?></p>
|
||||
|
||||
<?php if (!empty($errorMessage)): ?>
|
||||
<div class="alert alert--danger mt-12" role="alert"><?= $e((string) $errorMessage) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($successMessage)): ?>
|
||||
<div class="alert alert--success mt-12" role="status"><?= $e((string) $successMessage) ?></div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<section class="card mt-12">
|
||||
<h3 class="section-title"><?= $e($t('settings.project_mapping.add_title')) ?></h3>
|
||||
<form action="/settings/project-mappings" method="post" class="pm-form mt-8" novalidate>
|
||||
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
||||
|
||||
<div class="pm-form__row">
|
||||
<label class="form-field pm-form__field">
|
||||
<span class="field-label"><?= $e($t('settings.project_mapping.fields.pattern')) ?></span>
|
||||
<input class="form-control" type="text" name="product_name_pattern" placeholder="<?= $e($t('settings.project_mapping.placeholders.pattern')) ?>" required>
|
||||
</label>
|
||||
|
||||
<label class="form-field pm-form__field">
|
||||
<span class="field-label"><?= $e($t('settings.project_mapping.fields.script')) ?></span>
|
||||
<select class="form-control" name="script_name" required>
|
||||
<option value="">-- <?= $e($t('settings.project_mapping.placeholders.script')) ?> --</option>
|
||||
<?php foreach ($scripts as $script): ?>
|
||||
<option value="<?= $e($script) ?>"><?= $e($script) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="form-field pm-form__field">
|
||||
<span class="field-label"><?= $e($t('settings.project_mapping.fields.output_dir')) ?></span>
|
||||
<input class="form-control" type="text" name="output_dir" placeholder="<?= $e($t('settings.project_mapping.placeholders.output_dir')) ?>">
|
||||
</label>
|
||||
|
||||
<div class="pm-form__actions">
|
||||
<button type="submit" class="btn btn--action"><?= $e($t('settings.project_mapping.actions.add')) ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="card mt-12">
|
||||
<h3 class="section-title"><?= $e($t('settings.project_mapping.list_title')) ?></h3>
|
||||
|
||||
<?php if (empty($mappings)): ?>
|
||||
<p class="muted mt-8"><?= $e($t('settings.project_mapping.empty')) ?></p>
|
||||
<?php else: ?>
|
||||
<table class="table mt-8">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= $e($t('settings.project_mapping.fields.pattern')) ?></th>
|
||||
<th><?= $e($t('settings.project_mapping.fields.script')) ?></th>
|
||||
<th><?= $e($t('settings.project_mapping.fields.output_dir')) ?></th>
|
||||
<th class="text-center"><?= $e($t('settings.project_mapping.fields.active')) ?></th>
|
||||
<th class="text-center"><?= $e($t('settings.project_mapping.fields.actions')) ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($mappings as $mapping): ?>
|
||||
<tr class="pm-row<?= !$mapping['is_active'] ? ' pm-row--inactive' : '' ?>" data-id="<?= (int) $mapping['id'] ?>">
|
||||
<td class="pm-row__pattern"><?= $e((string) $mapping['product_name_pattern']) ?></td>
|
||||
<td class="pm-row__script"><?= $e((string) $mapping['script_name']) ?></td>
|
||||
<td class="pm-row__dir"><?= $e((string) ($mapping['output_dir'] ?? '-')) ?></td>
|
||||
<td class="text-center">
|
||||
<form action="/settings/project-mappings/<?= (int) $mapping['id'] ?>/toggle" method="post" class="inline-form">
|
||||
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
||||
<button type="submit" class="btn btn--sm <?= $mapping['is_active'] ? 'btn--success' : 'btn--muted' ?>">
|
||||
<?= $mapping['is_active'] ? $e($t('settings.project_mapping.status.active')) : $e($t('settings.project_mapping.status.inactive')) ?>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
<td class="text-center pm-row__actions">
|
||||
<button type="button" class="btn btn--sm btn--outline js-pm-edit"
|
||||
data-id="<?= (int) $mapping['id'] ?>"
|
||||
data-pattern="<?= $e((string) $mapping['product_name_pattern']) ?>"
|
||||
data-script="<?= $e((string) $mapping['script_name']) ?>"
|
||||
data-output-dir="<?= $e((string) ($mapping['output_dir'] ?? '')) ?>">
|
||||
<?= $e($t('settings.project_mapping.actions.edit')) ?>
|
||||
</button>
|
||||
<button type="button" class="btn btn--sm btn--danger js-pm-delete"
|
||||
data-id="<?= (int) $mapping['id'] ?>"
|
||||
data-token="<?= $e($csrfToken ?? '') ?>">
|
||||
<?= $e($t('settings.project_mapping.actions.delete')) ?>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<!-- Modal edycji -->
|
||||
<div id="pm-edit-modal" class="pm-modal" style="display:none;">
|
||||
<div class="pm-modal__overlay js-pm-modal-close"></div>
|
||||
<div class="pm-modal__content card">
|
||||
<h3 class="section-title"><?= $e($t('settings.project_mapping.edit_title')) ?></h3>
|
||||
<form id="pm-edit-form" method="post" novalidate>
|
||||
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
||||
|
||||
<label class="form-field mt-8">
|
||||
<span class="field-label"><?= $e($t('settings.project_mapping.fields.pattern')) ?></span>
|
||||
<input class="form-control" type="text" name="product_name_pattern" required>
|
||||
</label>
|
||||
|
||||
<label class="form-field mt-8">
|
||||
<span class="field-label"><?= $e($t('settings.project_mapping.fields.script')) ?></span>
|
||||
<select class="form-control" name="script_name" required>
|
||||
<?php foreach ($scripts as $script): ?>
|
||||
<option value="<?= $e($script) ?>"><?= $e($script) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="form-field mt-8">
|
||||
<span class="field-label"><?= $e($t('settings.project_mapping.fields.output_dir')) ?></span>
|
||||
<input class="form-control" type="text" name="output_dir">
|
||||
</label>
|
||||
|
||||
<div class="mt-12">
|
||||
<button type="submit" class="btn btn--action"><?= $e($t('settings.project_mapping.actions.save')) ?></button>
|
||||
<button type="button" class="btn btn--outline js-pm-modal-close"><?= $e($t('settings.project_mapping.actions.cancel')) ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var modal = document.getElementById('pm-edit-modal');
|
||||
var form = document.getElementById('pm-edit-form');
|
||||
|
||||
document.querySelectorAll('.js-pm-edit').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var id = this.dataset.id;
|
||||
form.action = '/settings/project-mappings/' + id + '/update';
|
||||
form.querySelector('[name="product_name_pattern"]').value = this.dataset.pattern;
|
||||
form.querySelector('[name="script_name"]').value = this.dataset.script;
|
||||
form.querySelector('[name="output_dir"]').value = this.dataset.outputDir || '';
|
||||
modal.style.display = 'flex';
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.js-pm-modal-close').forEach(function(el) {
|
||||
el.addEventListener('click', function() {
|
||||
modal.style.display = 'none';
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.js-pm-delete').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var id = this.dataset.id;
|
||||
var token = this.dataset.token;
|
||||
if (typeof window.OrderProAlerts !== 'undefined') {
|
||||
window.OrderProAlerts.confirm('<?= $e($t('settings.project_mapping.confirm_delete')) ?>', function() {
|
||||
var f = document.createElement('form');
|
||||
f.method = 'post';
|
||||
f.action = '/settings/project-mappings/' + id + '/delete';
|
||||
var t = document.createElement('input');
|
||||
t.type = 'hidden'; t.name = '_token'; t.value = token;
|
||||
f.appendChild(t);
|
||||
document.body.appendChild(f);
|
||||
f.submit();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user