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:
@@ -93,26 +93,26 @@ class VehicleDashboard {
|
||||
items.push({ label: this.selectedBrand, active: true });
|
||||
} else if (this.currentView === 'vehicles') {
|
||||
items.push({ label: '<i class="fas fa-home"></i> Marcas', action: 'dashboard.goToBrands()' });
|
||||
items.push({ label: this.selectedBrand, action: `dashboard.goToModels('${this.selectedBrand}')` });
|
||||
items.push({ label: this.selectedBrand, action: `dashboard.goToModels('${this.selectedBrand.replace(/'/g, "\\'")}')` });
|
||||
items.push({ label: this.selectedModel, active: true });
|
||||
} else if (this.currentView === 'categories') {
|
||||
items.push({ label: '<i class="fas fa-home"></i> Marcas', action: 'dashboard.goToBrands()' });
|
||||
items.push({ label: this.selectedBrand, action: `dashboard.goToModels('${this.selectedBrand}')` });
|
||||
items.push({ label: this.selectedModel, action: `dashboard.goToVehicles('${this.selectedBrand}', '${this.selectedModel}')` });
|
||||
items.push({ label: this.selectedBrand, action: `dashboard.goToModels('${this.selectedBrand.replace(/'/g, "\\'")}')` });
|
||||
items.push({ label: this.selectedModel, action: `dashboard.goToVehicles('${this.selectedBrand.replace(/'/g, "\\'")}', '${this.selectedModel.replace(/'/g, "\\'")}')` });
|
||||
if (this.selectedYear) items.push({ label: this.selectedYear });
|
||||
items.push({ label: 'Categorías', active: true });
|
||||
} else if (this.currentView === 'groups') {
|
||||
items.push({ label: '<i class="fas fa-home"></i> Marcas', action: 'dashboard.goToBrands()' });
|
||||
items.push({ label: this.selectedBrand, action: `dashboard.goToModels('${this.selectedBrand}')` });
|
||||
items.push({ label: this.selectedModel, action: `dashboard.goToVehicles('${this.selectedBrand}', '${this.selectedModel}')` });
|
||||
items.push({ label: this.selectedBrand, action: `dashboard.goToModels('${this.selectedBrand.replace(/'/g, "\\'")}')` });
|
||||
items.push({ label: this.selectedModel, action: `dashboard.goToVehicles('${this.selectedBrand.replace(/'/g, "\\'")}', '${this.selectedModel.replace(/'/g, "\\'")}')` });
|
||||
if (this.selectedYear) items.push({ label: this.selectedYear });
|
||||
items.push({ label: 'Categorías', action: `dashboard.goToCategories(${this.selectedVehicleId})` });
|
||||
items.push({ label: this.selectedCategory ? (this.selectedCategory.name_es || this.selectedCategory.name) : 'Grupos', active: true });
|
||||
} else if (this.currentView === 'parts') {
|
||||
const groupName = this.selectedGroup ? (this.selectedGroup.name_es || this.selectedGroup.name) : 'Grupo';
|
||||
items.push({ label: '<i class="fas fa-home"></i> Marcas', action: 'dashboard.goToBrands()' });
|
||||
items.push({ label: this.selectedBrand, action: `dashboard.goToModels('${this.selectedBrand}')` });
|
||||
items.push({ label: this.selectedModel, action: `dashboard.goToVehicles('${this.selectedBrand}', '${this.selectedModel}')` });
|
||||
items.push({ label: this.selectedBrand, action: `dashboard.goToModels('${this.selectedBrand.replace(/'/g, "\\'")}')` });
|
||||
items.push({ label: this.selectedModel, action: `dashboard.goToVehicles('${this.selectedBrand.replace(/'/g, "\\'")}', '${this.selectedModel.replace(/'/g, "\\'")}')` });
|
||||
if (this.selectedYear) items.push({ label: this.selectedYear });
|
||||
items.push({ label: 'Categorías', action: `dashboard.goToCategories(${this.selectedVehicleId})` });
|
||||
items.push({ label: this.selectedCategory ? (this.selectedCategory.name_es || this.selectedCategory.name) : 'Categoría', action: `dashboard.goToGroups(${this.selectedCategory ? this.selectedCategory.id : 0})` });
|
||||
@@ -980,9 +980,10 @@ class VehicleDashboard {
|
||||
|
||||
// FASE 5: Fetch group details for breadcrumb
|
||||
try {
|
||||
const response = await fetch(`/api/groups/${groupId}`);
|
||||
const response = await fetch(`/api/categories/${this.selectedCategory ? this.selectedCategory.id : 0}/groups`);
|
||||
if (response.ok) {
|
||||
this.selectedGroup = await response.json();
|
||||
const groups = await response.json();
|
||||
this.selectedGroup = groups.find(g => g.id === groupId) || { id: groupId, name: 'Grupo' };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching group details:', error);
|
||||
@@ -1354,9 +1355,9 @@ class VehicleDashboard {
|
||||
// FASE 2: Show part detail from search results (closes search modal first)
|
||||
showPartDetailFromSearch(partId) {
|
||||
// Close search results modal
|
||||
const searchModal = bootstrap.Modal.getInstance(document.getElementById('searchResultsModal'));
|
||||
if (searchModal) {
|
||||
searchModal.hide();
|
||||
const searchModalEl = document.getElementById('searchResultsModal');
|
||||
if (searchModalEl) {
|
||||
searchModalEl.classList.remove('active');
|
||||
}
|
||||
|
||||
// Small delay to allow modal transition, then show part detail
|
||||
@@ -1453,7 +1454,7 @@ class VehicleDashboard {
|
||||
async showDiagram(diagramId) {
|
||||
// FASE 5: Use focus management for modal
|
||||
const contentContainer = document.getElementById('diagramModalContent');
|
||||
const modalTitle = document.getElementById('diagramModalLabel');
|
||||
const modalTitle = document.getElementById('diagramModalTitle');
|
||||
|
||||
contentContainer.innerHTML = `
|
||||
<div class="text-center py-5">
|
||||
@@ -1567,9 +1568,9 @@ class VehicleDashboard {
|
||||
onHotspotClick(hotspot) {
|
||||
if (hotspot.part_id) {
|
||||
// Close diagram modal first
|
||||
const diagramModal = bootstrap.Modal.getInstance(document.getElementById('diagramModal'));
|
||||
if (diagramModal) {
|
||||
diagramModal.hide();
|
||||
const diagramModalEl = document.getElementById('diagramModal');
|
||||
if (diagramModalEl) {
|
||||
diagramModalEl.classList.remove('active');
|
||||
}
|
||||
|
||||
// Small delay to allow modal transition, then show part detail
|
||||
@@ -1790,9 +1791,9 @@ class VehicleDashboard {
|
||||
// FASE 4: View parts for a VIN
|
||||
async viewVinParts(vin, myeId) {
|
||||
// Close VIN modal
|
||||
const vinModal = bootstrap.Modal.getInstance(document.getElementById('vinDecoderModal'));
|
||||
if (vinModal) {
|
||||
vinModal.hide();
|
||||
const vinModalEl = document.getElementById('vinDecoderModal');
|
||||
if (vinModalEl) {
|
||||
vinModalEl.classList.remove('active');
|
||||
}
|
||||
|
||||
// FASE 5: Use focus management for modal
|
||||
|
||||
Reference in New Issue
Block a user