252 lines
13 KiB
PHP
252 lines
13 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('content')
|
|
<!-- Single Product SKU Comparison Section -->
|
|
<div class="section">
|
|
<h2>🔍 Compare Single Product URL</h2>
|
|
<div class="info-box" style="margin-bottom: 20px;">
|
|
<h3 style="margin-bottom: 10px; color: #1976D2; font-size: 1.1em;">Compare URLs for a Specific Product</h3>
|
|
<p style="margin: 5px 0; color: #1976D2;">Enter a product SKU to compare its URLs between Magento 1 and Magento 2:</p>
|
|
</div>
|
|
|
|
<div style="margin-top: 20px; display: flex; gap: 15px; align-items: center; flex-wrap: wrap;">
|
|
<div style="display: flex; gap: 10px; align-items: center; flex: 1; min-width: 300px;">
|
|
<label for="singleSkuInput" style="font-weight: 600; color: #333; min-width: 100px;">Product SKU:</label>
|
|
<input
|
|
type="text"
|
|
id="singleSkuInput"
|
|
placeholder="Enter product SKU"
|
|
style="padding: 10px 15px; border: 2px solid #ddd; border-radius: 4px; font-size: 1em; flex: 1; min-width: 200px;"
|
|
/>
|
|
</div>
|
|
<button id="compareSingleSkuBtn" class="btn btn-primary" onclick="compareSingleSku()">
|
|
Compare Product URLs
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Single Product Comparison Results -->
|
|
<div id="singleProductComparisonSection" style="display: none; margin-top: 30px;">
|
|
<h3 style="margin-bottom: 15px; color: #333;">Comparison Results for SKU: <span id="singleSkuDisplay"></span></h3>
|
|
<div style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 20px;">
|
|
<div id="singleProductComparisonContent">
|
|
<!-- Results will be displayed here -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Fix / Migrate Product URLs Section -->
|
|
<div class="section" style="margin-top: 30px;">
|
|
<h2>🔧 Fix / Migrate Product URLs</h2>
|
|
<div class="info-box" style="margin-bottom: 20px;">
|
|
<h3 style="margin-bottom: 10px; color: #1976D2; font-size: 1.1em;">Migrate missing product URL rewrites from M1 to M2</h3>
|
|
<p style="margin: 5px 0; color: #1976D2;">For each M1 product URL whose target is <code>catalog/product/view/...</code> (canonical and category-bound URLs), this inserts the matching row into M2. Non-catalog rewrites (e.g. productquestions module URLs) are skipped, the M2 product is resolved by SKU, and category-bound URLs get <code>metadata={"category_id":"X"}</code>.</p>
|
|
<p style="margin: 5px 0; color: #1976D2;">Existing M2 rewrites with the same <code>(request_path, store_id)</code> are left untouched.</p>
|
|
</div>
|
|
|
|
<div style="margin-top: 20px; display: flex; gap: 15px; align-items: center; flex-wrap: wrap;">
|
|
<div style="display: flex; gap: 10px; align-items: center;">
|
|
<label for="fixSkuInput" style="font-weight: 600; color: #333;">SKU (optional):</label>
|
|
<input
|
|
type="text"
|
|
id="fixSkuInput"
|
|
placeholder="Leave blank to fix all"
|
|
style="padding: 8px 12px; border: 1px solid #ddd; border-radius: 4px; font-size: 1em; min-width: 200px;"
|
|
/>
|
|
</div>
|
|
<label style="display: flex; gap: 6px; align-items: center; color: #333;">
|
|
<input type="checkbox" id="fixDryRunInput" checked />
|
|
Dry run (preview only)
|
|
</label>
|
|
<button id="fixUrlsBtn" class="btn btn-primary" onclick="fixProductUrls()">
|
|
Fix URLs
|
|
</button>
|
|
</div>
|
|
|
|
<div id="fixResultsSection" style="display: none; margin-top: 30px;">
|
|
<h3 style="margin-bottom: 15px; color: #333;">Result</h3>
|
|
<div class="stats">
|
|
<div class="stat-card" style="background: #FF8C42;">
|
|
<div class="number" id="fixAdded">0</div>
|
|
<div class="label" id="fixAddedLabel">Added</div>
|
|
</div>
|
|
<div class="stat-card" style="background: #FFA366;">
|
|
<div class="number" id="fixSkippedExisting">0</div>
|
|
<div class="label">Already in M2</div>
|
|
</div>
|
|
<div class="stat-card" style="background: #FF6B35;">
|
|
<div class="number" id="fixSkippedNoProduct">0</div>
|
|
<div class="label">No M2 Product</div>
|
|
</div>
|
|
<div class="stat-card" style="background: #C43A0D;">
|
|
<div class="number" id="fixErrors">0</div>
|
|
<div class="label">Errors</div>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top: 20px; background: #1e1e1e; color: #ddd; border-radius: 6px; padding: 16px; max-height: 400px; overflow-y: auto; font-family: monospace; font-size: 0.85em; white-space: pre-wrap;" id="fixLogOutput"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bulk Comparison Section -->
|
|
<div class="section" style="margin-top: 30px;">
|
|
<h2>🔗 Bulk Product URL Comparison</h2>
|
|
<div class="info-box" style="margin-bottom: 20px;">
|
|
<h3 style="margin-bottom: 10px; color: #1976D2; font-size: 1.1em;">Compare Multiple Product URLs</h3>
|
|
<p style="margin: 5px 0; color: #1976D2;">Compare product URLs between Magento 1 and Magento 2 to identify differences:</p>
|
|
<ul style="margin: 10px 0 0 20px; color: #1976D2; line-height: 1.8;">
|
|
<li><strong>Match:</strong> URLs are identical in both systems</li>
|
|
<li><strong>Missing in M2:</strong> URL exists in Magento 1 but not in Magento 2</li>
|
|
<li><strong>Missing in M1:</strong> URL exists in Magento 2 but not in Magento 1</li>
|
|
<li><strong>Different:</strong> URLs exist in both but are different</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Search and Filter Section -->
|
|
<div style="margin-top: 20px; display: flex; gap: 15px; align-items: center; flex-wrap: wrap;">
|
|
<div style="display: flex; gap: 10px; align-items: center;">
|
|
<label for="skuFilter" style="font-weight: 600; color: #333;">Filter by SKU:</label>
|
|
<input
|
|
type="text"
|
|
id="skuFilter"
|
|
placeholder="Enter SKU (optional)"
|
|
style="padding: 8px 12px; border: 1px solid #ddd; border-radius: 4px; font-size: 1em; min-width: 200px;"
|
|
/>
|
|
</div>
|
|
<button id="compareUrlsBtn" class="btn btn-primary" onclick="compareUrls()">
|
|
Compare URLs
|
|
</button>
|
|
<button id="loadM1UrlsBtn" class="btn btn-secondary" onclick="loadM1Urls()">
|
|
Load M1 URLs
|
|
</button>
|
|
<button id="loadM2UrlsBtn" class="btn btn-secondary" onclick="loadM2Urls()">
|
|
Load M2 URLs
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Summary Statistics -->
|
|
<div id="summarySection" style="display: none; margin-top: 30px;">
|
|
<h3 style="margin-bottom: 15px; color: #333;">Summary</h3>
|
|
<div class="stats">
|
|
<div class="stat-card" style="background: #FF8C42;">
|
|
<div class="number" id="summaryMatch">0</div>
|
|
<div class="label">Matching URLs</div>
|
|
</div>
|
|
<div class="stat-card" style="background: #FF6B35;">
|
|
<div class="number" id="summaryMissingM2">0</div>
|
|
<div class="label">Missing in M2</div>
|
|
</div>
|
|
<div class="stat-card" style="background: #FFA366;">
|
|
<div class="number" id="summaryMissingM1">0</div>
|
|
<div class="label">Missing in M1</div>
|
|
</div>
|
|
<div class="stat-card" style="background: #C43A0D;">
|
|
<div class="number" id="summaryDifferent">0</div>
|
|
<div class="label">Different URLs</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Comparison Results -->
|
|
<div id="comparisonSection" style="display: none; margin-top: 30px;">
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
|
|
<h3 style="color: #333;">Comparison Results</h3>
|
|
<div style="display: flex; gap: 10px; align-items: center;">
|
|
<span id="resultsCount" style="color: #666; font-size: 0.9em;"></span>
|
|
<select id="statusFilter" onchange="filterResults()" style="padding: 6px 12px; border: 1px solid #ddd; border-radius: 4px;">
|
|
<option value="all">All Statuses</option>
|
|
<option value="match">Match</option>
|
|
<option value="missing_in_m2">Missing in M2</option>
|
|
<option value="missing_in_m1">Missing in M1</option>
|
|
<option value="different">Different</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 20px; max-height: 600px; overflow-y: auto;">
|
|
<table class="products-table" id="comparisonTable">
|
|
<thead>
|
|
<tr>
|
|
<th>SKU</th>
|
|
<th>M1 Product ID</th>
|
|
<th>M2 Product ID</th>
|
|
<th>Store ID</th>
|
|
<th>M1 URL</th>
|
|
<th>M2 URL</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="comparisonTableBody">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div id="paginationSection" style="margin-top: 15px; display: flex; justify-content: center; gap: 10px; align-items: center;">
|
|
<button id="prevPageBtn" class="btn btn-secondary" onclick="changePage(-1)" disabled>Previous</button>
|
|
<span id="pageInfo" style="color: #666;"></span>
|
|
<button id="nextPageBtn" class="btn btn-secondary" onclick="changePage(1)" disabled>Next</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- M1 URLs Section -->
|
|
<div id="m1UrlsSection" style="display: none; margin-top: 30px;">
|
|
<h3 style="margin-bottom: 15px; color: #333;">Magento 1 URLs</h3>
|
|
<div style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 20px; max-height: 600px; overflow-y: auto;">
|
|
<table class="products-table" id="m1UrlsTable">
|
|
<thead>
|
|
<tr>
|
|
<th>Product ID</th>
|
|
<th>SKU</th>
|
|
<th>Store ID</th>
|
|
<th>Request Path</th>
|
|
<th>Target Path</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="m1UrlsTableBody">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div id="m1PaginationSection" style="margin-top: 15px; display: flex; justify-content: center; gap: 10px; align-items: center;">
|
|
<button id="m1PrevPageBtn" class="btn btn-secondary" onclick="changeM1Page(-1)" disabled>Previous</button>
|
|
<span id="m1PageInfo" style="color: #666;"></span>
|
|
<button id="m1NextPageBtn" class="btn btn-secondary" onclick="changeM1Page(1)" disabled>Next</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- M2 URLs Section -->
|
|
<div id="m2UrlsSection" style="display: none; margin-top: 30px;">
|
|
<h3 style="margin-bottom: 15px; color: #333;">Magento 2 URLs</h3>
|
|
<div style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 20px; max-height: 600px; overflow-y: auto;">
|
|
<table class="products-table" id="m2UrlsTable">
|
|
<thead>
|
|
<tr>
|
|
<th>Product ID</th>
|
|
<th>SKU</th>
|
|
<th>Store ID</th>
|
|
<th>Request Path</th>
|
|
<th>Target Path</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="m2UrlsTableBody">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div id="m2PaginationSection" style="margin-top: 15px; display: flex; justify-content: center; gap: 10px; align-items: center;">
|
|
<button id="m2PrevPageBtn" class="btn btn-secondary" onclick="changeM2Page(-1)" disabled>Previous</button>
|
|
<span id="m2PageInfo" style="color: #666;"></span>
|
|
<button id="m2NextPageBtn" class="btn btn-secondary" onclick="changeM2Page(1)" disabled>Next</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
@vite(['resources/js/product-urls.js'])
|
|
<script>
|
|
window.productUrlsRoutes = {
|
|
compareUrls: '{{ route("product-urls.compare-urls") }}',
|
|
compareSingleSku: '{{ route("product-urls.compare-single-sku") }}',
|
|
getM1Urls: '{{ route("product-urls.get-m1-urls") }}',
|
|
getM2Urls: '{{ route("product-urls.get-m2-urls") }}',
|
|
fixUrls: '{{ route("product-urls.fix-urls") }}'
|
|
};
|
|
</script>
|
|
@endpush
|