document.addEventListener('DOMContentLoaded', () => {
const productGrid = document.getElementById('product-grid');
const searchInput = document.getElementById('searchInput');
const brandFilterContainer = document.getElementById('filter-marcas');
const categoryFilterContainer = document.getElementById('filter-categorias');
const minPriceInput = document.getElementById('minPrice');
const maxPriceInput = document.getElementById('maxPrice');
const priceFilterBtn = document.getElementById('priceFilterBtn');
const resetFiltersBtn = document.getElementById('resetFiltersBtn');
const productCount = document.getElementById('product-count');
const navMarcas = document.getElementById('nav-marcas');
const navCategorias = document.getElementById('nav-categorias');
let allProducts = [];
let filters = {
searchTerm: '',
brands: [],
categories: [],
minPrice: null,
maxPrice: null
};
async function loadProducts() {
try {
const response = await fetch('productos.csv');
const data = await response.text();
allProducts = parseCSV(data);
displayProducts(allProducts);
populateFilters();
} catch (error) {
console.error('Error al cargar los productos:', error);
productGrid.innerHTML = '
`;
productGrid.appendChild(card);
});
}
productCount.textContent = `${products.length} de ${allProducts.length} productos mostrados.`;
}
function populateFilters() {
const brands = [...new Set(allProducts.map(p => p.marca))].sort();
const categories = [...new Set(allProducts.map(p => p.categoria))].sort();
populateFilterGroup(brandFilterContainer, brands, 'brands');
populateFilterGroup(categoryFilterContainer, categories, 'categories');
populateNavMenu(navMarcas, brands);
populateNavMenu(navCategorias, categories);
}
function populateFilterGroup(container, items, filterType) {
container.innerHTML = '';
items.forEach(item => {
const label = document.createElement('label');
label.className = 'filter-option';
label.innerHTML = ` ${item}`;
container.appendChild(label);
});
}
function populateNavMenu(container, items) {
container.innerHTML = '';
items.forEach(item => {
const link = document.createElement('a');
link.href = "#";
link.textContent = item;
link.dataset.filter = item;
link.dataset.type = (container.id === 'nav-marcas') ? 'brand' : 'category';
container.appendChild(link);
});
}
function applyFilters() {
// Recolectar filtros de checkboxes
filters.brands = getCheckedValues('brands');
filters.categories = getCheckedValues('categories');
let filteredProducts = allProducts.filter(p => {
const searchTermMatch = p.nombre.toLowerCase().includes(filters.searchTerm) ||
p.marca.toLowerCase().includes(filters.searchTerm) ||
p.descripcion.toLowerCase().includes(filters.searchTerm);
const brandMatch = filters.brands.length === 0 || filters.brands.includes(p.marca);
const categoryMatch = filters.categories.length === 0 || filters.categories.includes(p.categoria);
const minPriceMatch = filters.minPrice === null || p.precio >= filters.minPrice;
const maxPriceMatch = filters.maxPrice === null || p.precio <= filters.maxPrice;
return searchTermMatch && brandMatch && categoryMatch && minPriceMatch && maxPriceMatch;
});
displayProducts(filteredProducts);
}
function getCheckedValues(filterType) {
return Array.from(document.querySelectorAll(`input[data-filter-type="${filterType}"]:checked`)).map(input => input.value);
}
function handleFilterChange(e) {
if (e.target.matches('input[type="checkbox"]')) {
applyFilters();
}
}
function resetAllFilters() {
searchInput.value = '';
minPriceInput.value = '';
maxPriceInput.value = '';
document.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false);
filters = {
searchTerm: '',
brands: [],
categories: [],
minPrice: null,
maxPrice: null
};
applyFilters();
}
// Event Listeners
searchInput.addEventListener('input', (e) => {
filters.searchTerm = e.target.value.toLowerCase();
applyFilters();
});
brandFilterContainer.addEventListener('change', handleFilterChange);
categoryFilterContainer.addEventListener('change', handleFilterChange);
priceFilterBtn.addEventListener('click', () => {
filters.minPrice = minPriceInput.value ? parseFloat(minPriceInput.value) : null;
filters.maxPrice = maxPriceInput.value ? parseFloat(maxPriceInput.value) : null;
applyFilters();
});
resetFiltersBtn.addEventListener('click', resetAllFilters);
document.querySelector('.nav-dropdown').addEventListener('click', (e) => {
if(e.target.matches('.dropdown-content a')) {
e.preventDefault();
resetAllFilters();
const filterValue = e.target.dataset.filter;
const filterType = e.target.dataset.type;
if(filterType === 'brand') {
document.querySelector(`input[data-filter-type="brands"][value="${filterValue}"]`).checked = true;
} else if(filterType === 'category') {
document.querySelector(`input[data-filter-type="categories"][value="${filterValue}"]`).checked = true;
}
applyFilters();
// Cierra los dropdowns (opcional)
document.querySelectorAll('.dropdown-content').forEach(d => d.style.display = 'none');
setTimeout(() => document.querySelectorAll('.dropdown-content').forEach(d => d.style.display = ''), 100);
}
});
// Iniciar la aplicación
loadProducts();
});
No se pudieron cargar los productos. Por favor, intente de nuevo más tarde.
'; } } function parseCSV(data) { const rows = data.trim().split('\n').slice(1); return rows.map(row => { const [marca, categoria, nombre, descripcion, precio, imagen_url] = row.split(';'); return { marca: marca.trim(), categoria: categoria.trim(), nombre: nombre.trim(), descripcion: descripcion.trim(), precio: parseFloat(precio), imagen_url: imagen_url.trim() }; }); } function displayProducts(products) { productGrid.innerHTML = ''; if (products.length === 0) { productGrid.innerHTML = 'No se encontraron productos que coincidan con su búsqueda.
'; } else { products.forEach(product => { const card = document.createElement('div'); card.className = 'product-card'; card.innerHTML = `${product.marca}
${product.nombre}
${product.descripcion}
$${product.precio.toLocaleString('es-MX', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} MXN
Ver Ficha Técnica