teste compre por marcas

<!doctype html> Vitrine por Faixas – Natural One (inspirado)

Vitrine por Faixa de Preço

Separação inteligente de tênis por orçamento + filtro por numeração. Visual street, clean, direto ao ponto — conversão first.

HTML + CSS + JS • Plugável
/** * ============================================================ * ONDE EDITAR / CUSTOMIZAR * ============================================================ * 1) Trocar/Adicionar produtos: * - Edite o array `products` abaixo (mock local). * * 2) Trocar/Adicionar faixas de preço: * - Edite o array `priceBands` (label, key, minExclusive, maxInclusive). * * 3) Trocar tamanhos globais: * - A UI de tamanhos usa `globalSizes`. Ajuste se necessário. * - Mesmo assim, o filtro real usa `product.sizes`. */ // ---------- MOCK DE PRODUTOS (mín. 18) ---------- const products = [ { id: "NO-001", name: "Tênis Old Skool Canvas", brand: "Vans", price: 279.90, image: "https://images.unsplash.com/photo-1525966222134-fcfa99b8ae77?auto=format&fit=crop&w=900&q=70", url: "#produto-no-001", sizes: [34,35,36,37,38,39,40,41,42], tags: ["mais_vendido"] }, { id: "NO-002", name: "Tênis Court Vision Low", brand: "Nike", price: 299.90, image: "https://images.unsplash.com/photo-1542291026-7eec264c27ff?auto=format&fit=crop&w=900&q=70", url: "#produto-no-002", sizes: [35,36,37,38,39,40,42], tags: [] }, { id: "NO-003", name: "Tênis Suede Classic", brand: "Puma", price: 289.90, image: "https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=900&q=70", url: "#produto-no-003", sizes: [34,35,36,37,38,39,40,41], tags: [] }, { id: "NO-004", name: "Tênis Chuck Taylor All Star", brand: "Converse", price: 259.90, image: "https://images.unsplash.com/photo-1528701800489-20be3c1ea6d8?auto=format&fit=crop&w=900&q=70", url: "#produto-no-004", sizes: [33,34,35,36,37,38,39,41,42], tags: ["mais_vendido"] }, { id: "NO-005", name: "Tênis Forum Low", brand: "Adidas", price: 389.90, image: "https://images.unsplash.com/photo-1600269452121-4f2416e55c28?auto=format&fit=crop&w=900&q=70", url: "#produto-no-005", sizes: [36,37,38,39,40,41,42,43], tags: ["lancamento"] }, { id: "NO-006", name: "Tênis Air Max SC", brand: "Nike", price: 399.90, image: "https://images.unsplash.com/photo-1543508282-6319a3e2621f?auto=format&fit=crop&w=900&q=70", url: "#produto-no-006", sizes: [37,38,39,40,41,42], tags: [] }, { id: "NO-007", name: "Tênis Slip-On Checkerboard", brand: "Vans", price: 349.90, image: "https://images.unsplash.com/photo-1528702748617-c64d49f918af?auto=format&fit=crop&w=900&q=70", url: "#produto-no-007", sizes: [34,35,36,38,39,40,41], tags: ["mais_vendido"] }, { id: "NO-008", name: "Tênis Suede XL", brand: "Puma", price: 429.90, image: "https://images.unsplash.com/photo-1605408499391-6368c628ef42?auto=format&fit=crop&w=900&q=70", url: "#produto-no-008", sizes: [36,37,38,40,41,42], tags: ["lancamento"] }, { id: "NO-009", name: "Tênis Rivalry Low", brand: "Adidas", price: 459.90, image: "https://images.unsplash.com/photo-1521093470119-a3acdc43374a?auto=format&fit=crop&w=900&q=70", url: "#produto-no-009", sizes: [37,38,39,40,41,43], tags: [] }, { id: "NO-010", name: "Tênis Club C 85", brand: "Reebok", price: 379.90, image: "https://images.unsplash.com/photo-1562183241-b937e95585b6?auto=format&fit=crop&w=900&q=70", url: "#produto-no-010", sizes: [35,36,37,38,39,41,42], tags: [] }, { id: "NO-011", name: "Tênis 574 Classic", brand: "New Balance", price: 499.90, image: "https://images.unsplash.com/photo-1606813907291-d86efa9b94db?auto=format&fit=crop&w=900&q=70", url: "#produto-no-011", sizes: [36,37,38,39,40,41,42,43], tags: ["mais_vendido"] }, { id: "NO-012", name: "Tênis RS-X Reinvention", brand: "Puma", price: 489.90, image: "https://images.unsplash.com/photo-1552346053-c33aa8b3d40b?auto=format&fit=crop&w=900&q=70", url: "#produto-no-012", sizes: [37,38,39,40,42,43], tags: [] }, { id: "NO-013", name: "Tênis Superstar", brand: "Adidas", price: 399.00, image: "https://images.unsplash.com/photo-1525966222134-fcfa99b8ae77?auto=format&fit=crop&w=900&q=70", url: "#produto-no-013", sizes: [34,35,36,37,38,39,40,41], tags: [] }, { id: "NO-014", name: "Tênis Blazer Low '77", brand: "Nike", price: 459.00, image: "https://images.unsplash.com/photo-1579338559194-a162d19bf842?auto=format&fit=crop&w=900&q=70", url: "#produto-no-014", sizes: [35,36,37,39,40,41,42], tags: ["lancamento"] }, { id: "NO-015", name: "Tênis Gazelle", brand: "Adidas", price: 519.90, image: "https://images.unsplash.com/photo-1595341888016-a392ef81b7de?auto=format&fit=crop&w=900&q=70", url: "#produto-no-015", sizes: [36,37,38,39,40,41,42,43], tags: [] }, { id: "NO-016", name: "Tênis Air Force 1", brand: "Nike", price: 699.90, image: "https://images.unsplash.com/photo-1600269452121-4f2416e55c28?auto=format&fit=crop&w=900&q=70", url: "#produto-no-016", sizes: [36,37,38,39,40,41,42,43,44], tags: ["mais_vendido"] }, { id: "NO-017", name: "Tênis Sk8-Hi", brand: "Vans", price: 499.00, image: "https://images.unsplash.com/photo-1605348532760-6753d2c43329?auto=format&fit=crop&w=900&q=70", url: "#produto-no-017", sizes: [36,37,38,39,41,42], tags: [] }, { id: "NO-018", name: "Tênis Run 60s", brand: "Adidas", price: 299.00, image: "https://images.unsplash.com/photo-1511556532299-8f662fc26c06?auto=format&fit=crop&w=900&q=70", url: "#produto-no-018", sizes: [34,35,36,37,38,40,41], tags: [] }, { id: "NO-019", name: "Tênis Classic Leather", brand: "Reebok", price: 469.90, image: "https://images.unsplash.com/photo-1560769629-975ec94e6a86?auto=format&fit=crop&w=900&q=70", url: "#produto-no-019", sizes: [36,37,38,39,40,41,43], tags: [] }, { id: "NO-020", name: "Tênis One Star", brand: "Converse", price: 349.00, image: "https://images.unsplash.com/photo-1460353581641-37baddab0fa2?auto=format&fit=crop&w=900&q=70", url: "#produto-no-020", sizes: [34,35,36,37,39,40,41,42], tags: [] } ]; // ---------- FAIXAS (sem repetir: <=300, (300..400], (400..500]) ---------- const priceBands = [ { key: "ate300", label: "Tênis até R$ 300", minExclusive: -Infinity, maxInclusive: 300 }, { key: "ate400", label: "Tênis até R$ 400", minExclusive: 300, maxInclusive: 400 }, { key: "ate500", label: "Tênis até R$ 500", minExclusive: 400, maxInclusive: 500 } ]; // Tamanhos globais mostrados como chips (UI). Ajuste conforme sua regra de grade. const globalSizes = [33,34,35,36,37,38,39,40,41,42,43,44]; // ---------- STATE POR FAIXA ---------- const bandState = Object.fromEntries(priceBands.map(b => [b.key, { size: null, sort: "relevancia" }])); const moneyBRL = (n) => new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(n); function inBand(product, band){ return product.price > band.minExclusive && product.price <= band.maxInclusive; } function applyFilters(bandKey){ const band = priceBands.find(b => b.key === bandKey); const state = bandState[bandKey]; let list = products.filter(p => inBand(p, band)); if (state.size !== null){ list = list.filter(p => Array.isArray(p.sizes) && p.sizes.includes(state.size)); } // Ordenação local (afeta só a faixa) if (state.sort === "menor"){ list = [...list].sort((a,b) => a.price - b.price); } else if (state.sort === "maior"){ list = [...list].sort((a,b) => b.price - a.price); } // relevancia = ordem original do array (já está) return list; } function tagLabel(tag){ if(tag === "lancamento") return "Lançamento"; if(tag === "mais_vendido") return "+Vendidos"; return tag; } function cardHTML(p){ const pills = (p.tags || []).slice(0,2).map(t => `${tagLabel(t)}`).join(""); const sizes = (p.sizes || []).slice(0,10).map(s => `${s}`).join(""); const more = (p.sizes || []).length > 10 ? `+${(p.sizes.length - 10)}` : ""; return `
${p.brand} ${p.name}
${pills}
${p.brand}

${p.name}

${moneyBRL(p.price)}
${sizes}${more}
`; } function renderBandShell(band){ const id = band.key; const selectedSize = bandState[id].size; return `

${band.label}

0 opções ${selectedSize ? `Nº ${selectedSize}` : "Todos tamanhos"}

Selecione o seu número

${globalSizes.map(sz => ` <button class="chip" type="button" data-band="${id}" data-size="${sz}" aria-pressed="${selectedSize === sz ? "true" : "false"}" aria-label="Selecionar número ${sz} para ${band.label}" >${sz} `).join("")}
Mais relevantes Menor preço Maior preço Limpar
`; } function renderBandProducts(bandKey){ const list = applyFilters(bandKey); const grid = document.getElementById(`grid-${bandKey}`); const empty = document.getElementById(`empty-${bandKey}`); const countEl = document.getElementById(`count-${bandKey}`); const activeEl = document.getElementById(`active-${bandKey}`); // Contadores e label de estado countEl.textContent = `${list.length} opção${list.length === 1 ? "" : "ões"}`; const sz = bandState[bandKey].size; activeEl.textContent = sz ? `Nº ${sz}` : "Todos tamanhos"; if(list.length === 0){ grid.innerHTML = ""; empty.style.display = "block"; return; } empty.style.display = "none"; grid.innerHTML = list.map(cardHTML).join(""); } function setActiveChip(bandKey, size){ const chips = document.querySelectorAll(`.chip[data-band="${bandKey}"]`); chips.forEach(btn => { const isActive = Number(btn.dataset.size) === size; btn.setAttribute("aria-pressed", isActive ? "true" : "false"); }); } function init(){ const root = document.getElementById("vitrine-faixas"); // Renderiza shells root.innerHTML = priceBands.map(renderBandShell).join(""); // Ajusta selects pro state priceBands.forEach(b => { const sel = document.querySelector(`select[data-band="${b.key}"]`); sel.value = bandState[b.key].sort; }); // Render inicial por faixa (sem re-render da página toda depois) priceBands.forEach(b => renderBandProducts(b.key)); // Eventos: Chips + teclas root.addEventListener("click", (e) => { const chip = e.target.closest(".chip"); if(chip){ const bandKey = chip.dataset.band; const size = Number(chip.dataset.size); // Toggle: se clicar no mesmo número, desmarca bandState[bandKey].size = (bandState[bandKey].size === size) ? null : size; setActiveChip(bandKey, bandState[bandKey].size); renderBandProducts(bandKey); return; } const btn = e.target.closest('button[data-action="clear"]'); if(btn){ const bandKey = btn.dataset.band; bandState[bandKey].size = null; bandState[bandKey].sort = "relevancia"; setActiveChip(bandKey, null); const sel = document.querySelector(`select[data-band="${bandKey}"]`); sel.value = "relevancia"; renderBandProducts(bandKey); return; } }); // Acessibilidade: suporte de teclado em chips (Enter/Space já ok por ser button) root.addEventListener("keydown", (e) => { const chip = e.target.closest(".chip"); if(!chip) return; // Setas para navegar horizontalmente (só ergonomia) const bandKey = chip.dataset.band; const chips = [...document.querySelectorAll(`.chip[data-band="${bandKey}"]`)]; const idx = chips.indexOf(chip); if(idx < 0) return; if(e.key === "ArrowRight"){ e.preventDefault(); (chips[idx + 1] || chips[0]).focus(); } if(e.key === "ArrowLeft"){ e.preventDefault(); (chips[idx - 1] || chips[chips.length - 1]).focus(); } }); // Eventos: select de ordenação root.addEventListener("change", (e) => { const sel = e.target.closest('select[data-band]'); if(!sel) return; const bandKey = sel.dataset.band; bandState[bandKey].sort = sel.value; renderBandProducts(bandKey); }); } init();