feat: add demo catalog page with image display and part detail modal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -41,37 +41,31 @@ class VehicleDashboard {
|
||||
|
||||
async loadStats() {
|
||||
try {
|
||||
const [brandsRes, vehiclesRes, partsRes, categoriesRes] = await Promise.all([
|
||||
const [statsRes, brandsRes, categoriesRes] = await Promise.all([
|
||||
fetch('/api/catalog/stats'),
|
||||
fetch('/api/brands'),
|
||||
fetch('/api/vehicles'),
|
||||
fetch('/api/parts'),
|
||||
fetch('/api/categories')
|
||||
]);
|
||||
|
||||
if (brandsRes.ok && vehiclesRes.ok) {
|
||||
const brands = await brandsRes.json();
|
||||
const vehiclesData = await vehiclesRes.json();
|
||||
const vehicles = vehiclesData.data || vehiclesData;
|
||||
|
||||
// Contar modelos únicos
|
||||
const uniqueModels = new Set(vehicles.map(v => `${v.brand}-${v.model}`));
|
||||
|
||||
this.stats.brands = brands.length;
|
||||
this.stats.models = uniqueModels.size;
|
||||
this.stats.vehicles = vehiclesData.pagination ? vehiclesData.pagination.total : vehicles.length;
|
||||
if (statsRes.ok) {
|
||||
const s = await statsRes.json();
|
||||
this.stats.brands = s.brands;
|
||||
this.stats.models = s.models;
|
||||
this.stats.vehicles = s.vehicles;
|
||||
this.stats.parts = s.parts;
|
||||
|
||||
const fmt = n => n > 1000 ? Math.floor(n/1000) + 'K+' : n;
|
||||
const brandsEl = document.getElementById('totalBrands');
|
||||
const modelsEl = document.getElementById('totalModels');
|
||||
if (brandsEl) brandsEl.textContent = this.stats.brands;
|
||||
if (modelsEl) modelsEl.textContent = this.stats.models > 1000 ? Math.floor(this.stats.models/1000) + 'K+' : this.stats.models;
|
||||
const partsEl = document.getElementById('totalParts');
|
||||
if (brandsEl) brandsEl.textContent = fmt(this.stats.brands);
|
||||
if (modelsEl) modelsEl.textContent = fmt(this.stats.models);
|
||||
if (partsEl) partsEl.textContent = fmt(this.stats.parts);
|
||||
}
|
||||
|
||||
if (partsRes.ok) {
|
||||
const partsData = await partsRes.json();
|
||||
// Handle paginated response
|
||||
this.stats.parts = partsData.pagination ? partsData.pagination.total : (partsData.data ? partsData.data.length : partsData.length || 0);
|
||||
const partsEl = document.getElementById('totalParts');
|
||||
if (partsEl) partsEl.textContent = this.stats.parts;
|
||||
if (brandsRes.ok) {
|
||||
// Still needed for brand list rendering
|
||||
await brandsRes.json();
|
||||
}
|
||||
|
||||
if (categoriesRes.ok) {
|
||||
@@ -1144,6 +1138,11 @@ class VehicleDashboard {
|
||||
<h4 class="mb-3">${part.name_es || part.name || 'Sin nombre'}</h4>
|
||||
</div>
|
||||
</div>
|
||||
${part.image_url ? `
|
||||
<div style="text-align:center;margin-bottom:1rem;">
|
||||
<img src="${part.image_url}" alt="${part.oem_part_number || ''}" style="max-width:100%;max-height:300px;border-radius:8px;object-fit:contain;" />
|
||||
</div>
|
||||
` : ''}
|
||||
<div class="part-detail-row">
|
||||
<span class="part-detail-label">Número OEM</span>
|
||||
<span class="part-detail-value"><span class="part-oem-badge">${part.oem_part_number || 'N/A'}</span></span>
|
||||
|
||||
Reference in New Issue
Block a user