feat(pos): selector de vehiculo con dropdowns — Ano > Marca > Modelo > Motor
Barra de 4 dropdowns arriba del catalogo que se habilitan en cascada. Al completar los 4, muestra categorias y partes para ese vehiculo. Boton de limpiar para resetear. Endpoint /years-all para cargar anos. Estilos con design system tokens (ambos temas). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -816,6 +816,138 @@
|
||||
}
|
||||
});
|
||||
|
||||
// ─── VEHICLE SELECTOR (dropdown bar) ───
|
||||
var vsYear = document.getElementById('vsYear');
|
||||
var vsBrand = document.getElementById('vsBrand');
|
||||
var vsModel = document.getElementById('vsModel');
|
||||
var vsEngine = document.getElementById('vsEngine');
|
||||
var vsClear = document.getElementById('vsClear');
|
||||
|
||||
// Load years on init
|
||||
function vsLoadYears() {
|
||||
apiFetch(API + '/years-all').then(function (data) {
|
||||
if (!data) return;
|
||||
var years = data.data || data;
|
||||
// If endpoint doesn't exist, generate from 1990-2026
|
||||
if (!years || !years.length) {
|
||||
years = [];
|
||||
for (var y = 2026; y >= 1990; y--) years.push({ id_year: y, year_car: y });
|
||||
}
|
||||
vsYear.innerHTML = '<option value="">Año...</option>';
|
||||
years.forEach(function (y) {
|
||||
vsYear.innerHTML += '<option value="' + y.id_year + '">' + y.year_car + '</option>';
|
||||
});
|
||||
}).catch(function () {
|
||||
// Fallback: generate years statically
|
||||
vsYear.innerHTML = '<option value="">Año...</option>';
|
||||
for (var y = 2026; y >= 1990; y--) {
|
||||
vsYear.innerHTML += '<option value="' + y + '">' + y + '</option>';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function vsYearChanged() {
|
||||
var yearId = vsYear.value;
|
||||
vsBrand.innerHTML = '<option value="">Marca...</option>';
|
||||
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
||||
vsEngine.innerHTML = '<option value="">Motor...</option>';
|
||||
vsBrand.disabled = true;
|
||||
vsModel.disabled = true;
|
||||
vsEngine.disabled = true;
|
||||
vsClear.style.display = yearId ? '' : 'none';
|
||||
|
||||
if (!yearId) return;
|
||||
|
||||
// Load brands (reuse existing endpoint)
|
||||
vsBrand.disabled = false;
|
||||
apiFetch(API + '/brands').then(function (data) {
|
||||
var brands = data.data || data;
|
||||
if (!brands) return;
|
||||
vsBrand.innerHTML = '<option value="">Marca...</option>';
|
||||
brands.forEach(function (b) {
|
||||
vsBrand.innerHTML += '<option value="' + b.id_brand + '">' + esc(b.name_brand) + '</option>';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function vsBrandChanged() {
|
||||
var brandId = vsBrand.value;
|
||||
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
||||
vsEngine.innerHTML = '<option value="">Motor...</option>';
|
||||
vsModel.disabled = true;
|
||||
vsEngine.disabled = true;
|
||||
|
||||
if (!brandId) return;
|
||||
|
||||
vsModel.disabled = false;
|
||||
apiFetch(API + '/models?brand_id=' + brandId).then(function (data) {
|
||||
var models = data.data || data;
|
||||
if (!models) return;
|
||||
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
||||
models.forEach(function (m) {
|
||||
vsModel.innerHTML += '<option value="' + m.id_model + '">' + esc(m.name_model) + '</option>';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function vsModelChanged() {
|
||||
var modelId = vsModel.value;
|
||||
var yearVal = vsYear.value;
|
||||
vsEngine.innerHTML = '<option value="">Motor...</option>';
|
||||
vsEngine.disabled = true;
|
||||
|
||||
if (!modelId || !yearVal) return;
|
||||
|
||||
vsEngine.disabled = false;
|
||||
apiFetch(API + '/engines?model_id=' + modelId + '&year_id=' + yearVal).then(function (data) {
|
||||
var engines = data.data || data;
|
||||
if (!engines) return;
|
||||
vsEngine.innerHTML = '<option value="">Motor...</option>';
|
||||
engines.forEach(function (e) {
|
||||
var label = e.name_engine + (e.trim_level ? ' (' + e.trim_level + ')' : '');
|
||||
vsEngine.innerHTML += '<option value="' + e.id_mye + '">' + esc(label) + '</option>';
|
||||
});
|
||||
// If only 1 engine, auto-select
|
||||
if (engines.length === 1) {
|
||||
vsEngine.value = engines[0].id_mye;
|
||||
vsEngineChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function vsEngineChanged() {
|
||||
var myeId = vsEngine.value;
|
||||
if (!myeId) return;
|
||||
|
||||
// Update state and load categories
|
||||
var yearText = vsYear.options[vsYear.selectedIndex].text;
|
||||
var brandText = vsBrand.options[vsBrand.selectedIndex].text;
|
||||
var modelText = vsModel.options[vsModel.selectedIndex].text;
|
||||
var engineText = vsEngine.options[vsEngine.selectedIndex].text;
|
||||
|
||||
state.brand = { id: parseInt(vsBrand.value), name: brandText };
|
||||
state.model = { id: parseInt(vsModel.value), name: modelText };
|
||||
state.year = { id: parseInt(vsYear.value), value: yearText };
|
||||
state.engine = { id_mye: parseInt(myeId), name: engineText };
|
||||
state.level = 'categories';
|
||||
|
||||
loadCategories();
|
||||
}
|
||||
|
||||
function vsClearAll() {
|
||||
vsYear.value = '';
|
||||
vsBrand.innerHTML = '<option value="">Marca...</option>';
|
||||
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
||||
vsEngine.innerHTML = '<option value="">Motor...</option>';
|
||||
vsBrand.disabled = true;
|
||||
vsModel.disabled = true;
|
||||
vsEngine.disabled = true;
|
||||
vsClear.style.display = 'none';
|
||||
|
||||
state = { level: 'brands', brand: null, model: null, year: null, engine: null, category: null, group: null, page: 1, totalPages: 1 };
|
||||
loadBrands();
|
||||
}
|
||||
|
||||
// ─── EXPOSE GLOBALS (for backward compat) ───
|
||||
window.CatalogApp = {
|
||||
toggleCart: toggleCart,
|
||||
@@ -825,10 +957,16 @@
|
||||
updateQty: updateQuantity,
|
||||
clearCart: clearCart,
|
||||
loadPage: function (p) { loadParts(p); },
|
||||
vsYearChanged: vsYearChanged,
|
||||
vsBrandChanged: vsBrandChanged,
|
||||
vsModelChanged: vsModelChanged,
|
||||
vsEngineChanged: vsEngineChanged,
|
||||
vsClear: vsClearAll,
|
||||
};
|
||||
|
||||
// ─── INIT ───
|
||||
renderCart();
|
||||
vsLoadYears();
|
||||
loadBrands();
|
||||
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user