Files
orderPRO/resources/views/products/links.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>