269 lines
13 KiB
PHP
269 lines
13 KiB
PHP
<?php $item = is_array($product ?? null) ? $product : []; ?>
|
|
<?php $links = is_array($productLinks ?? null) ? $productLinks : []; ?>
|
|
<?php $integrations = is_array($linkIntegrations ?? null) ? $linkIntegrations : []; ?>
|
|
<?php $offers = is_array($linkOffers ?? null) ? $linkOffers : []; ?>
|
|
<?php $eventsByMap = is_array($productLinkEventsByMap ?? null) ? $productLinkEventsByMap : []; ?>
|
|
<?php $selectedIntegrationId = (int) ($selectedLinksIntegrationId ?? 0); ?>
|
|
<?php $linksQueryValue = (string) ($linksQuery ?? ''); ?>
|
|
<?php $productIdValue = (int) ($productId ?? 0); ?>
|
|
|
|
<section class="card">
|
|
<h1><?= $e($t('products.links.page_title', ['id' => (string) ($productId ?? 0)])) ?></h1>
|
|
<p class="muted"><?= $e($t('products.links.description')) ?></p>
|
|
</section>
|
|
|
|
<section class="card mt-16">
|
|
<div class="product-tabs-nav">
|
|
<a class="btn btn--secondary" href="/products/<?= $e((string) $productIdValue) ?>"><?= $e($t('products.tabs.details')) ?></a>
|
|
<span class="btn btn--primary"><?= $e($t('products.tabs.links')) ?></span>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="card mt-16">
|
|
<div class="product-links-head">
|
|
<div>
|
|
<strong><?= $e($t('products.fields.name')) ?>:</strong>
|
|
<?= $e((string) ($item['name'] ?? '')) ?>
|
|
</div>
|
|
<div>
|
|
<strong>SKU:</strong>
|
|
<?= $e((string) ($item['sku'] ?? '')) ?>
|
|
</div>
|
|
<div>
|
|
<strong>EAN:</strong>
|
|
<?= $e((string) ($item['ean'] ?? '')) ?>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="card mt-16">
|
|
<h3><?= $e($t('products.links.title')) ?></h3>
|
|
|
|
<?php if (!empty($linksErrorMessage)): ?>
|
|
<div class="alert alert--danger mt-12" role="alert"><?= $e((string) $linksErrorMessage) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if (!empty($linksSuccessMessage)): ?>
|
|
<div class="alert alert--success mt-12" role="status"><?= $e((string) $linksSuccessMessage) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<h4 class="section-title mt-16"><?= $e($t('products.links.current_links')) ?></h4>
|
|
<?php if ($links === []): ?>
|
|
<p class="muted mt-12"><?= $e($t('products.links.empty_links')) ?></p>
|
|
<?php else: ?>
|
|
<div class="table-wrap mt-12">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th><?= $e($t('products.links.fields.integration')) ?></th>
|
|
<th><?= $e($t('products.links.fields.channel')) ?></th>
|
|
<th><?= $e($t('products.links.fields.external_product_id')) ?></th>
|
|
<th><?= $e($t('products.links.fields.external_variant_id')) ?></th>
|
|
<th><?= $e($t('products.links.fields.link_type')) ?></th>
|
|
<th><?= $e($t('products.links.fields.confidence')) ?></th>
|
|
<th><?= $e($t('products.links.fields.link_status')) ?></th>
|
|
<th><?= $e($t('products.links.fields.updated_at')) ?></th>
|
|
<th><?= $e($t('products.links.fields.history')) ?></th>
|
|
<th><?= $e($t('products.links.fields.actions')) ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($links as $link): ?>
|
|
<?php
|
|
$mapId = (int) ($link['id'] ?? 0);
|
|
$linkStatus = (string) ($link['link_status'] ?? '');
|
|
$isActive = $linkStatus === 'active';
|
|
$confidence = $link['confidence'] ?? null;
|
|
$hasMissingAlert = ($link['has_missing_alert'] ?? false) === true;
|
|
$missingAlertMessage = trim((string) ($link['missing_alert_message'] ?? ''));
|
|
if ($missingAlertMessage === '') {
|
|
$missingAlertMessage = (string) $t('products.links.alerts.missing_remote_link');
|
|
}
|
|
$missingAlertFirstDetectedAt = trim((string) ($link['missing_alert_first_detected_at'] ?? ''));
|
|
$missingAlertTooltip = $missingAlertMessage;
|
|
if ($missingAlertFirstDetectedAt !== '') {
|
|
$missingAlertTooltip .= ' ' . (string) $t('products.links.alerts.alert_since', [
|
|
'date' => $missingAlertFirstDetectedAt,
|
|
]);
|
|
}
|
|
$lastChangeAt = trim((string) ($link['updated_at'] ?? ''));
|
|
if ($lastChangeAt === '') {
|
|
$lastChangeAt = trim((string) ($link['linked_at'] ?? ''));
|
|
}
|
|
?>
|
|
<tr>
|
|
<td><?= $e((string) (($link['integration_name'] ?? '') !== '' ? $link['integration_name'] : ('#' . (string) ($link['integration_id'] ?? 0)))) ?></td>
|
|
<td><?= $e((string) ($link['channel_name'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($link['external_product_id'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($link['external_variant_id'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($link['link_type'] ?? '')) ?></td>
|
|
<td><?= $e($confidence === null ? '-' : ((string) $confidence . '%')) ?></td>
|
|
<td>
|
|
<div class="product-link-status-cell">
|
|
<span class="status-pill<?= $isActive ? ' is-active' : '' ?>">
|
|
<?= $e($linkStatus) ?>
|
|
</span>
|
|
<?php if ($hasMissingAlert): ?>
|
|
<span class="product-link-alert-indicator" title="<?= $e($missingAlertTooltip) ?>" aria-label="<?= $e($missingAlertTooltip) ?>">!</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
</td>
|
|
<td><?= $e($lastChangeAt === '' ? '-' : $lastChangeAt) ?></td>
|
|
<td>
|
|
<?php $events = is_array($eventsByMap[$mapId] ?? null) ? $eventsByMap[$mapId] : []; ?>
|
|
<?php if ($events === []): ?>
|
|
<span class="muted">-</span>
|
|
<?php else: ?>
|
|
<ul class="product-link-events-list">
|
|
<?php foreach ($events as $event): ?>
|
|
<li>
|
|
<span class="product-link-events-type"><?= $e((string) ($event['event_type'] ?? '')) ?></span>
|
|
<span class="product-link-events-date"><?= $e((string) ($event['created_at'] ?? '')) ?></span>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td>
|
|
<div class="product-links-actions-row">
|
|
<form action="/products/<?= $e((string) $productIdValue) ?>/links/<?= $e((string) $mapId) ?>/relink" method="post" class="product-links-inline-form product-links-relink-form">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="product_id" value="<?= $e((string) ($productId ?? 0)) ?>">
|
|
<input type="hidden" name="map_id" value="<?= $e((string) $mapId) ?>">
|
|
<input type="hidden" name="integration_id" value="<?= $e((string) ((int) ($link['integration_id'] ?? 0))) ?>">
|
|
<input class="form-control" type="text" name="external_product_id" required value="<?= $e((string) ($link['external_product_id'] ?? '')) ?>">
|
|
<input class="form-control" type="text" name="external_variant_id" value="<?= $e((string) ($link['external_variant_id'] ?? '')) ?>" placeholder="<?= $e($t('products.links.fields.external_variant_id_optional')) ?>">
|
|
<button type="submit" class="btn btn--secondary" data-links-action="relink"><?= $e($t('products.links.actions.relink')) ?></button>
|
|
</form>
|
|
|
|
<form action="/products/<?= $e((string) $productIdValue) ?>/links/<?= $e((string) $mapId) ?>/unlink" method="post" class="product-links-unlink-form">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="product_id" value="<?= $e((string) ($productId ?? 0)) ?>">
|
|
<input type="hidden" name="map_id" value="<?= $e((string) $mapId) ?>">
|
|
<button type="submit" class="btn btn--danger" data-links-action="unlink"><?= $e($t('products.links.actions.unlink')) ?></button>
|
|
</form>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<h4 class="section-title mt-16"><?= $e($t('products.links.search_title')) ?></h4>
|
|
<form class="product-links-search-form mt-12" action="/products/<?= $e((string) $productIdValue) ?>/links" method="get">
|
|
<input type="hidden" name="id" value="<?= $e((string) ($productId ?? 0)) ?>">
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('products.links.fields.integration')) ?></span>
|
|
<select class="form-control" name="links_integration_id" required>
|
|
<option value="0"><?= $e($t('products.links.integration_placeholder')) ?></option>
|
|
<?php foreach ($integrations as $integration): ?>
|
|
<?php $integrationId = (int) ($integration['id'] ?? 0); ?>
|
|
<option value="<?= $e((string) $integrationId) ?>"<?= $integrationId === $selectedIntegrationId ? ' selected' : '' ?>>
|
|
<?= $e((string) ($integration['name'] ?? '')) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</label>
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('products.links.fields.search')) ?></span>
|
|
<input class="form-control" type="text" name="links_query" value="<?= $e($linksQueryValue) ?>" placeholder="<?= $e($t('products.links.search_placeholder')) ?>">
|
|
</label>
|
|
<button type="submit" class="btn btn--primary"><?= $e($t('products.links.actions.search')) ?></button>
|
|
</form>
|
|
|
|
<?php if ($offers === []): ?>
|
|
<p class="muted mt-12"><?= $e($t('products.links.empty_offers')) ?></p>
|
|
<?php else: ?>
|
|
<div class="table-wrap mt-12">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th><?= $e($t('products.links.fields.offer_name')) ?></th>
|
|
<th>SKU</th>
|
|
<th>EAN</th>
|
|
<th><?= $e($t('products.links.fields.external_product_id')) ?></th>
|
|
<th><?= $e($t('products.links.fields.external_variant_id')) ?></th>
|
|
<th><?= $e($t('products.links.fields.match_hint')) ?></th>
|
|
<th><?= $e($t('products.links.fields.confidence')) ?></th>
|
|
<th><?= $e($t('products.links.fields.actions')) ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($offers as $offer): ?>
|
|
<tr>
|
|
<td><?= $e((string) ($offer['name'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($offer['sku'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($offer['ean'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($offer['external_product_id'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($offer['external_variant_id'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($offer['match_hint'] ?? '')) ?></td>
|
|
<td><?= $e((string) ((int) ($offer['match_confidence'] ?? 0)) . '%') ?></td>
|
|
<td>
|
|
<form action="/products/<?= $e((string) $productIdValue) ?>/links" method="post">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="product_id" value="<?= $e((string) ($productId ?? 0)) ?>">
|
|
<input type="hidden" name="integration_id" value="<?= $e((string) ($offer['integration_id'] ?? 0)) ?>">
|
|
<input type="hidden" name="external_product_id" value="<?= $e((string) ($offer['external_product_id'] ?? '')) ?>">
|
|
<input type="hidden" name="external_variant_id" value="<?= $e((string) ($offer['external_variant_id'] ?? '')) ?>">
|
|
<button type="submit" class="btn btn--primary"><?= $e($t('products.links.actions.link')) ?></button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif; ?>
|
|
</section>
|
|
|
|
<section class="card mt-16">
|
|
<a class="btn btn--secondary" href="/products"><?= $e($t('products.actions.back')) ?></a>
|
|
<a class="btn btn--secondary" href="/products/<?= $e((string) $productIdValue) ?>"><?= $e($t('products.actions.preview')) ?></a>
|
|
<a class="btn btn--primary" href="/products/edit?id=<?= $e((string) ($productId ?? 0)) ?>"><?= $e($t('products.actions.edit')) ?></a>
|
|
</section>
|
|
|
|
<script>
|
|
(function () {
|
|
var unlinkForms = document.querySelectorAll('.product-links-unlink-form');
|
|
var relinkForms = document.querySelectorAll('.product-links-relink-form');
|
|
var unlinkMessage = <?= json_encode((string) $t('products.links.confirm.unlink_message'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
var relinkMessage = <?= json_encode((string) $t('products.links.confirm.relink_message'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
var confirmTitle = <?= json_encode((string) $t('products.links.confirm.title'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
var confirmYes = <?= json_encode((string) $t('products.links.confirm.yes'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
var confirmNo = <?= json_encode((string) $t('products.links.confirm.no'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
|
|
async function handleConfirmSubmit(event, message, danger) {
|
|
if (!window.OrderProAlerts || typeof window.OrderProAlerts.confirm !== 'function') {
|
|
return;
|
|
}
|
|
|
|
event.preventDefault();
|
|
var accepted = await window.OrderProAlerts.confirm({
|
|
title: confirmTitle,
|
|
message: message,
|
|
confirmLabel: confirmYes,
|
|
cancelLabel: confirmNo,
|
|
danger: danger === true
|
|
});
|
|
if (!accepted) {
|
|
return;
|
|
}
|
|
event.target.submit();
|
|
}
|
|
|
|
unlinkForms.forEach(function (form) {
|
|
form.addEventListener('submit', function (event) {
|
|
handleConfirmSubmit(event, unlinkMessage, true);
|
|
});
|
|
});
|
|
|
|
relinkForms.forEach(function (form) {
|
|
form.addEventListener('submit', function (event) {
|
|
handleConfirmSubmit(event, relinkMessage, false);
|
|
});
|
|
});
|
|
})();
|
|
</script>
|