Fix 7 frontend bugs found during audit

- Fix breadcrumb group name fetch using existing /api/categories/<id>/groups
- Fix diagramModalLabel → diagramModalTitle DOM ID mismatch
- Replace bootstrap.Modal.getInstance() with classList.remove('active') for modal close
- Escape single quotes in brand/model names in breadcrumb onclick handlers
- Implement editAftermarket() form population in admin panel
- Handle VIN decoder response wrapper in landing page
- Fetch models count from API instead of hardcoded '13K+'

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 00:59:53 +00:00
parent ad79724e8a
commit 140117a8e5
3 changed files with 52 additions and 27 deletions

View File

@@ -1277,12 +1277,13 @@
// Load stats
async function loadStats() {
try {
const [partsRes, brandsRes, categoriesRes, manufacturersRes, aftermarketRes] = await Promise.all([
const [partsRes, brandsRes, categoriesRes, manufacturersRes, aftermarketRes, modelsRes] = await Promise.all([
fetch(`${API_BASE}/api/parts?per_page=1`),
fetch(`${API_BASE}/api/brands`),
fetch(`${API_BASE}/api/categories`),
fetch(`${API_BASE}/api/manufacturers`),
fetch(`${API_BASE}/api/aftermarket?per_page=1`)
fetch(`${API_BASE}/api/aftermarket?per_page=1`),
fetch(`${API_BASE}/api/models`)
]);
const parts = await partsRes.json();
@@ -1290,11 +1291,13 @@
const categories = await categoriesRes.json();
const manufacturers = await manufacturersRes.json();
const aftermarket = await aftermarketRes.json();
const models = await modelsRes.json();
document.getElementById('stat-parts').textContent = (parts.pagination?.total || parts.length || 0) + '+';
document.getElementById('stat-brands').textContent = brands.length || 0;
document.getElementById('stat-categories').textContent = categories.length || 0;
document.getElementById('stat-models').textContent = '13K+';
const modelCount = models.length || 0;
document.getElementById('stat-models').textContent = modelCount >= 1000 ? Math.floor(modelCount / 1000) + 'K+' : modelCount;
document.getElementById('stat-manufacturers').textContent = manufacturers.length || 0;
document.getElementById('stat-aftermarket').textContent = (aftermarket.pagination?.total || aftermarket.length || 0) + '+';
} catch (e) {
@@ -1444,13 +1447,15 @@
try {
const res = await fetch(`${API_BASE}/api/vin/decode/${vin}`);
const data = await res.json();
const raw = await res.json();
const data = raw.vehicle || raw;
if (data.error) {
resultDiv.innerHTML = `<p style="color: #ef4444;">${data.error}</p>`;
return;
}
const engineInfo = data.engine_info || {};
resultDiv.innerHTML = `
<div style="background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; padding: 1.5rem; text-align: left; max-width: 500px; margin: 0 auto;">
<h3 style="color: var(--accent); margin-bottom: 1rem;">Vehículo Identificado</h3>
@@ -1459,7 +1464,7 @@
<p><strong>Año:</strong> ${data.year || 'N/A'}</p>
<p><strong>Tipo:</strong> ${data.body_class || 'N/A'}</p>
<p><strong>Tracción:</strong> ${data.drive_type || 'N/A'}</p>
${data.engine_info ? `<p><strong>Motor:</strong> ${data.engine_info.displacement_l || ''}L ${data.engine_info.cylinders || ''} cil.</p>` : ''}
${engineInfo.raw || engineInfo.displacement_l ? `<p><strong>Motor:</strong> ${engineInfo.raw || (engineInfo.displacement_l + 'L ' + (engineInfo.cylinders || '') + ' cil.')}</p>` : ''}
<a href="index.html" class="btn btn-primary" style="margin-top: 1rem; display: inline-block;">Ver partes compatibles</a>
</div>
`;