Update vehicle cards to show complete motor specs

Vehicle cards now display 6 motor data fields:
1. Fuel type (Gasolina/Diésel/Híbrido/Eléctrico)
2. Power (HP)
3. Torque (Nm) - NEW
4. Displacement (formatted as liters, e.g., 3.0L)
5. Cylinders
6. Engine config (V6, I4, etc. - derived from name)

Changes:
- dashboard.js: Added helper functions for formatting
  - getEngineConfig(): Extracts V6, I4, H4, etc. from engine name
  - formatDisplacement(): Converts cc to liters
  - formatFuelType(): Spanish translations
- server.py: Added torque_nm to vehicles API response

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-05 08:42:46 +00:00
parent d213ec2df0
commit 6fb2a52f86
2 changed files with 68 additions and 19 deletions

View File

@@ -587,6 +587,53 @@ class VehicleDashboard {
this.displayVehicles();
}
// Helper: Extract engine configuration from engine name
getEngineConfig(engineName) {
if (!engineName) return 'N/A';
const upper = engineName.toUpperCase();
// Match patterns like V6, V8, I4, H4, W12
const vMatch = upper.match(/V(\d+)/);
if (vMatch) return `V${vMatch[1]}`;
const iMatch = upper.match(/I(\d+)|INLINE[- ]?(\d+)/);
if (iMatch) return `I${iMatch[1] || iMatch[2]}`;
const hMatch = upper.match(/H(\d+)|FLAT[- ]?(\d+)/);
if (hMatch) return `H${hMatch[1] || hMatch[2]}`;
const wMatch = upper.match(/W(\d+)/);
if (wMatch) return `W${wMatch[1]}`;
// Try to derive from cylinder count in name
const cylMatch = upper.match(/(\d)[- ]?CYL/);
if (cylMatch) return `${cylMatch[1]} Cil`;
if (upper.includes('ELECTRIC')) return 'EV';
if (upper.includes('ROTARY')) return 'Rotary';
return 'N/A';
}
// Helper: Format displacement (cc to L)
formatDisplacement(cc) {
if (!cc || cc === 0) return 'N/A';
const liters = (cc / 1000).toFixed(1);
return `${liters}L`;
}
// Helper: Format fuel type in Spanish
formatFuelType(fuel) {
const types = {
'gasoline': 'Gasolina',
'diesel': 'Diésel',
'electric': 'Eléctrico',
'hybrid': 'Híbrido',
'other': 'Otro'
};
return types[fuel] || fuel || 'N/A';
}
displayVehicles() {
const container = document.getElementById('mainContent');
const resultCount = document.getElementById('resultCount');
@@ -595,7 +642,7 @@ class VehicleDashboard {
if (this.filteredVehicles.length === 0) {
container.innerHTML = `
<div class="empty-state">
<div class="state-container">
<i class="fas fa-car"></i>
<h4>No se encontraron vehículos</h4>
<p>Intenta ajustar los filtros</p>
@@ -615,32 +662,32 @@ class VehicleDashboard {
<div class="vehicle-specs">
<div class="spec-item">
<i class="fas fa-gas-pump"></i>
<div class="spec-value">${v.fuel_type || 'N/A'}</div>
<div class="spec-value">${this.formatFuelType(v.fuel_type)}</div>
</div>
<div class="spec-item">
<i class="fas fa-bolt"></i>
<div class="spec-value">${v.power_hp || 'N/A'} HP</div>
</div>
<div class="spec-item">
<i class="fas fa-sync-alt"></i>
<div class="spec-value">${v.torque_nm || 'N/A'} Nm</div>
</div>
<div class="spec-item">
<i class="fas fa-tachometer-alt"></i>
<div class="spec-value">${v.power_hp || 0} HP</div>
<div class="spec-value">${this.formatDisplacement(v.displacement_cc)}</div>
</div>
<div class="spec-item">
<i class="fas fa-cogs"></i>
<div class="spec-value">${v.transmission || 'N/A'}</div>
<i class="fas fa-circle-notch"></i>
<div class="spec-value">${v.cylinders || 'N/A'} Cil</div>
</div>
<div class="spec-item">
<i class="fas fa-road"></i>
<div class="spec-value">${v.drivetrain || 'N/A'}</div>
</div>
<div class="spec-item">
<i class="fas fa-cube"></i>
<div class="spec-value">${v.cylinders || 0} cil.</div>
</div>
<div class="spec-item">
<i class="fas fa-oil-can"></i>
<div class="spec-value">${v.displacement_cc || 0} cc</div>
<i class="fas fa-cog"></i>
<div class="spec-value">${this.getEngineConfig(v.engine)}</div>
</div>
</div>
${v.trim_level && v.trim_level !== 'unknown' ? `
<div class="mt-2 text-center">
<span class="badge bg-primary">${v.trim_level}</span>
<div style="text-align: center; margin-top: 0.75rem;">
<span style="background: var(--accent); color: white; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.8rem;">${v.trim_level}</span>
</div>
` : ''}
<button class="btn-parts" onclick="dashboard.goToCategories(${v.mye_id})">

View File

@@ -72,6 +72,7 @@ def search_vehicles(brand=None, model=None, year=None, engine=None):
y.year,
e.name AS engine,
e.power_hp,
e.torque_nm,
e.displacement_cc,
e.cylinders,
e.fuel_type,
@@ -115,6 +116,7 @@ def search_vehicles(brand=None, model=None, year=None, engine=None):
'year': row['year'],
'engine': row['engine'],
'power_hp': row['power_hp'] or 0,
'torque_nm': row['torque_nm'] or 0,
'displacement_cc': row['displacement_cc'] or 0,
'cylinders': row['cylinders'] or 0,
'fuel_type': row['fuel_type'] or 'unknown',