(function() {
const BrandCatalog = {
state: 'brands',
_allBrands: [],
_lastItems: [],
_offset: 0,
_limit: 50,
_total: 0,
_allowedBrands: [],
// Navigation state
nav: {
brand: null,
brandId: null,
model: null,
modelId: null,
year: null,
yearId: null,
engine: null,
myeId: null,
category: null,
categoryId: null
},
el: function(id) { return document.getElementById(id); },
_getToken: function() {
return localStorage.getItem('pos_token');
},
_headers: function() {
var token = this._getToken();
return {
'Authorization': 'Bearer ' + (token || ''),
'Content-Type': 'application/json'
};
},
_checkAuth: function(resp) {
if (resp.status === 401) {
localStorage.removeItem('pos_token');
window.location.href = '/pos/login';
return false;
}
return true;
},
show: function() {
if (!this._getToken()) {
window.location.href = '/pos/login';
return;
}
this.el('brandCatalogOverlay').style.display = 'block';
document.body.style.overflow = 'hidden';
this.loadBrands();
},
hide: function() {
this.el('brandCatalogOverlay').style.display = 'none';
document.body.style.overflow = '';
this.reset();
},
reset: function() {
this.state = 'brands';
this.nav = { brand: null, brandId: null, model: null, modelId: null, year: null, yearId: null, engine: null, myeId: null, category: null, categoryId: null };
this._allBrands = [];
this._lastItems = [];
this._offset = 0;
this._total = 0;
this.el('brandCatalogSearch').innerHTML = '';
},
loading: function(on) {
var el = this.el('brandCatalogLoading');
if (on) el.classList.add('is-visible');
else el.classList.remove('is-visible');
},
setContent: function(html) {
this.el('brandCatalogContent').innerHTML = html;
},
setSearch: function(html) {
this.el('brandCatalogSearch').innerHTML = html;
},
setBreadcrumb: function(html) {
this.el('brandCatalogBreadcrumb').innerHTML = html;
},
buildBreadcrumb: function() {
var parts = [];
parts.push('Marcas ');
if (this.nav.brand) {
parts.push('' + escapeHtml(this.nav.brand) + ' ');
}
if (this.nav.model) {
parts.push('' + escapeHtml(this.nav.model) + ' ');
}
if (this.nav.year) {
parts.push('' + this.nav.year + ' ');
}
if (this.nav.engine) {
parts.push('' + escapeHtml(this.nav.engine) + ' ');
}
if (this.nav.category) {
parts.push('' + escapeHtml(this.nav.category) + ' ');
}
this.setBreadcrumb('' + parts.join('› ') + ' ');
},
// ---------- BRANDS ----------
loadBrands: function() {
this.loading(true);
this.state = 'brands';
this.reset();
this.setBreadcrumb('Marcas de vehiculo ');
this.setSearch(
' '
);
var self = this;
fetch('/pos/api/catalog/vehicle-brands', { headers: this._headers() })
.then(function(r) {
if (!self._checkAuth(r)) return null;
return r.json();
})
.then(function(data) {
if (!data) return;
self.loading(false);
self._allBrands = data.brands || [];
if (!self._allBrands.length) {
self.setContent('
No se encontraron marcas.
');
return;
}
self.renderBrandList(self._allBrands);
})
.catch(function(err) {
self.loading(false);
self.setContent('Error al cargar marcas
' + escapeHtml(err.message) + '
');
});
},
renderBrandList: function(brands) {
var html = '';
brands.forEach(function(b) {
html += '
' +
'
' + escapeHtml(b.name) + '
' +
'
';
});
html += '
';
this.setContent(html);
},
filterBrands: function(query) {
var q = query.toLowerCase().trim();
if (!q) {
this.renderBrandList(this._allBrands);
return;
}
var filtered = this._allBrands.filter(function(b) {
return b.name.toLowerCase().indexOf(q) !== -1;
});
this.renderBrandList(filtered);
},
selectBrand: function(brandName, brandId) {
this.nav.brand = brandName;
this.nav.brandId = brandId;
this.loadModels(brandId);
},
// ---------- MODELS ----------
loadModels: function(brandId) {
this.loading(true);
this.state = 'models';
this.setSearch('');
this.buildBreadcrumb();
var self = this;
fetch('/pos/api/catalog/models?brand_id=' + encodeURIComponent(brandId), { headers: this._headers() })
.then(function(r) {
if (!self._checkAuth(r)) return null;
return r.json();
})
.then(function(data) {
if (!data) return;
self.loading(false);
var models = data.data || [];
if (!models.length) {
self.setContent('No se encontraron modelos.
');
return;
}
self.renderModelList(models);
})
.catch(function(err) {
self.loading(false);
self.setContent('Error al cargar modelos
' + escapeHtml(err.message) + '
');
});
},
renderModelList: function(models) {
var html = '';
models.forEach(function(m) {
html += '
' +
'
' + escapeHtml(m.display_name || m.name_model) + '
' +
'
';
});
html += '
';
this.setContent(html);
},
selectModel: function(modelId, modelName) {
this.nav.model = modelName;
this.nav.modelId = modelId;
this.loadYears(modelId);
},
// ---------- YEARS ----------
loadYears: function(modelId) {
this.loading(true);
this.state = 'years';
this.setSearch('');
this.buildBreadcrumb();
var self = this;
fetch('/pos/api/catalog/years?model_id=' + encodeURIComponent(modelId), { headers: this._headers() })
.then(function(r) {
if (!self._checkAuth(r)) return null;
return r.json();
})
.then(function(data) {
if (!data) return;
self.loading(false);
var years = data.data || [];
if (!years.length) {
self.setContent('');
return;
}
self.renderYearList(years);
})
.catch(function(err) {
self.loading(false);
self.setContent('Error al cargar años
' + escapeHtml(err.message) + '
');
});
},
renderYearList: function(years) {
var html = '';
years.forEach(function(y) {
html += '
' +
'
' + y.year_car + '
' +
'
';
});
html += '
';
this.setContent(html);
},
selectYear: function(yearId, yearCar) {
this.nav.year = yearCar;
this.nav.yearId = yearId;
this.loadEngines(this.nav.modelId, yearId);
},
// ---------- ENGINES ----------
loadEngines: function(modelId, yearId) {
this.loading(true);
this.state = 'engines';
this.setSearch('');
this.buildBreadcrumb();
var self = this;
fetch('/pos/api/catalog/engines?model_id=' + encodeURIComponent(modelId) + '&year_id=' + encodeURIComponent(yearId), { headers: this._headers() })
.then(function(r) {
if (!self._checkAuth(r)) return null;
return r.json();
})
.then(function(data) {
if (!data) return;
self.loading(false);
var engines = data.data || [];
if (!engines.length) {
self.setContent('No se encontraron motores.
');
return;
}
self.renderEngineList(engines);
})
.catch(function(err) {
self.loading(false);
self.setContent('Error al cargar motores
' + escapeHtml(err.message) + '
');
});
},
renderEngineList: function(engines) {
var html = '';
engines.forEach(function(e) {
html += '
' +
'
' + escapeHtml(e.name_engine) + '
' +
'
' + escapeHtml(e.trim_level || '') + '
' +
'
';
});
html += '
';
this.setContent(html);
},
selectEngine: function(myeId, engineName) {
this.nav.engine = engineName;
this.nav.myeId = myeId;
this.loadCategories(myeId);
},
// ---------- CATEGORIES ----------
loadCategories: function(myeId) {
this.loading(true);
this.state = 'categories';
this.setSearch('');
this.buildBreadcrumb();
var self = this;
fetch('/pos/api/catalog/categories?mye_id=' + encodeURIComponent(myeId) + '&mode=oem', { headers: this._headers() })
.then(function(r) {
if (!self._checkAuth(r)) return null;
return r.json();
})
.then(function(data) {
if (!data) return;
self.loading(false);
self._allowedBrands = data.allowed_brands || [];
var categories = data.data || [];
if (!categories.length) {
var msg = 'No se encontraron categorias.';
if (self._allowedBrands.length) {
msg = 'Este vehiculo no tiene cobertura de ' + self._allowedBrands.join(', ') + '.';
}
self.setContent('' + msg + '
Prueba con otro vehiculo o contacta a soporte para ampliar el catalogo.
');
return;
}
self.renderCategoryList(categories);
})
.catch(function(err) {
self.loading(false);
self.setContent('Error al cargar categorias
' + escapeHtml(err.message) + '
');
});
},
renderCategoryList: function(categories) {
var html = '';
categories.forEach(function(c) {
html += '
' +
'
' + escapeHtml(c.name) + '
' +
'
' + (c.part_count || 0) + ' refacciones
' +
'
';
});
html += '
';
this.setContent(html);
},
selectCategory: function(catId, catName) {
this.nav.category = catName;
this.nav.categoryId = catId;
this._offset = 0;
this.loadParts(this.nav.myeId, catId, '');
},
// ---------- PARTS ----------
loadParts: function(myeId, categoryId, searchTerm) {
this.loading(true);
this.state = 'parts';
this.buildBreadcrumb();
this.setSearch(
'' +
' ' +
'Buscar ' +
'Limpiar ' +
'
'
);
var url = '/pos/api/catalog/mye-parts?mye_id=' + encodeURIComponent(myeId) + '&category_id=' + encodeURIComponent(categoryId) +
'&limit=' + this._limit + '&offset=' + this._offset;
if (searchTerm) {
url += '&search=' + encodeURIComponent(searchTerm);
}
var self = this;
fetch(url, { headers: this._headers() })
.then(function(r) {
if (!self._checkAuth(r)) return null;
return r.json();
})
.then(function(data) {
if (!data) return;
self.loading(false);
self._allowedBrands = data.allowed_brands || [];
self._lastItems = data.items || [];
self._total = data.total || 0;
self._offset = data.offset || 0;
self.renderPartsList(data.items || [], searchTerm);
})
.catch(function(err) {
self.loading(false);
self.setContent('Error al cargar refacciones
' + escapeHtml(err.message) + '
');
});
},
renderPartsList: function(items, searchTerm) {
var html = '';
if (!items.length) {
var msg = 'No se encontraron refacciones.';
if (this._allowedBrands.length) {
msg = 'No hay refacciones de ' + this._allowedBrands.join(', ') + ' en esta categoria.';
}
html += '' +
'
' + msg + '
' +
'
Volver a categorias
' +
'
';
this.setContent(html);
return;
}
var startIdx = this._offset + 1;
var endIdx = this._offset + items.length;
html += '' +
'Mostrando ' + startIdx + '-' + endIdx + ' de ' + this._total + ' refacciones' +
'
';
html += '';
items.forEach(function(p) {
var hasAm = !!p.manufacturer;
var price = p.local_price
? '$' + Number(p.local_price).toFixed(2)
: (p.price_usd ? '$' + Number(p.price_usd).toFixed(2) : 'Consultar precio');
var stockBadge = p.local_stock > 0
? '
En stock '
: '
Sin stock local ';
var imgHtml = p.image_url
? '
'
: '
';
var brandLine = hasAm
? '
' + escapeHtml(p.manufacturer) + '
'
: '';
html += '
' +
'
' + imgHtml + '
' +
'
' +
brandLine +
'
' + escapeHtml(p.oem_part_number || 'N/A') + '
' +
'
' + escapeHtml(p.name || '') + '
' +
'
' +
'' +
'
Agregar ' +
'
';
});
html += '
';
html += this.renderPagination();
this.setContent(html);
},
renderPagination: function() {
var hasPrev = this._offset > 0;
var hasNext = (this._offset + this._limit) < this._total;
var pageNum = Math.floor(this._offset / this._limit) + 1;
var totalPages = Math.ceil(this._total / this._limit) || 1;
var html = '';
return html;
},
searchParts: function(term) {
this._offset = 0;
this.loadParts(this.nav.myeId, this.nav.categoryId, term);
},
clearPartsSearch: function() {
this._offset = 0;
this.loadParts(this.nav.myeId, this.nav.categoryId, '');
},
goToPage: function(newOffset) {
if (newOffset < 0) return;
this._offset = newOffset;
var searchInput = document.getElementById('partsSearchInput');
var term = searchInput ? searchInput.value : '';
this.loadParts(this.nav.myeId, this.nav.categoryId, term);
},
addToCart: function(partId, event) {
if (event) event.stopPropagation();
var part = this._lastItems.find(function(p) { return p.id === partId; });
if (!part) {
alert('Error: no se encontro la refaccion');
return;
}
if (window.CatalogApp && CatalogApp.addToCart) {
var isAftermarket = !!part.manufacturer;
CatalogApp.addToCart({
id: part.oem_id || part.id,
part_number: part.oem_part_number || 'N/A',
name: part.name || 'Refaccion',
brand: part.manufacturer || '',
price: part.local_price || part.price_usd || 0,
tax_rate: 0.16,
unit: 'PZA',
stock: part.local_stock || 0,
source: isAftermarket ? 'aftermarket' : 'oem-brand',
inventory_id: null
}, 1);
var btn = event.target;
var oldText = btn.textContent;
btn.textContent = 'Agregado!';
btn.style.background = 'var(--color-success)';
setTimeout(function() { btn.textContent = oldText; btn.style.background = ''; }, 1500);
return;
}
alert('Carrito no disponible. Asegurate de que la pagina haya cargado completamente.');
}
};
function escapeHtml(text) {
if (!text) return '';
var div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
window.BrandCatalog = BrandCatalog;
})();