PageSourceSearch

https://www.hypera.com.br/assets/js/grid-marcas.js

js hypera.com.br collected 2026-09-25 18:39:21 UTC 11,699 bytes, 292 lines download raw bytes

1document.addEventListener("DOMContentLoaded", function() {
2  const lista = document.getElementById("lista-marcas");
3  const totalFiltro = document.getElementById("total-filtro-marcas");
4  const btnCarregar = document.getElementById("btn-carregar-marcas");
5  const letrasBtns = document.querySelectorAll(".filtro-letra");
6  const inputBusca = document.getElementById("buscar-marcas");
7  const btnSearch = document.getElementById("btn-search");
8  const btnLimpar = document.getElementById("limpar-filtros-marcas");
9
10  let letraSelecionada = "";
11  let busca = "";
12  let pagina = 0;
13  const limite = 20;
14  let totalMarcasBanco = 0;
15  let marcasCarregadas = 0;
16  let projetoRaizSelecionado = ""; // novo: armazena o projetoRaiz selecionado
17
18  // Carregar letras habilitadas
19  fetch("/core/api/carregar-marcas-letras.php")
20    .then(res => res.json())
21    .then(data => {
22      const letrasDisponiveis = Array.isArray(data.letras) ? data.letras : [];
23
24      // Normaliza para Uppercase e usa Set para lookup rápido
25      const setLetras = new Set(letrasDisponiveis.map(l => String(l).toUpperCase()));
26
27      letrasBtns.forEach(btn => {
28        const letraBtn = String(btn.dataset.letra || "").toUpperCase();
29        if (!setLetras.has(letraBtn)) {
30          btn.disabled = true;
31          btn.classList.add("desabilitado");
32        } else {
33          btn.disabled = false;
34          btn.classList.remove("desabilitado");
35        }
36      });
37    })
38    .catch(err => {
39      console.error("Erro ao carregar letras disponíveis:", err);
40    });
41
42  // Carregar marcas (aceita projetoRaizParam opcional)
43  function carregarMarcas(reset = false, projetoRaizParam = "") {
44    if (reset) {
45      pagina = 0;
46      marcasCarregadas = 0;
47      lista.innerHTML = "";
48    }
49
50    const url = `/core/api/buscar-marcas.php?letra=${encodeURIComponent(letraSelecionada)}&busca=${encodeURIComponent(busca)}&pagina=${pagina}&limite=${limite}&projetoRaiz=${encodeURIComponent(projetoRaizParam)}`;
51
52    fetch(url)
53      .then(res => res.json())
54      .then(data => {
55        totalMarcasBanco = Number(data.totalMarcasBanco) || 0;
56
57        // Guarda extra no front
58        const marcas = (data.marcas || []).filter(m => Number(m.exibicaoMarca) === 1);
59
60        if (reset && marcas.length === 0) {
61          totalFiltro.textContent = "Não existem marcas com esse filtro. Limpe os filtros ativos.";
62          btnCarregar.style.display = "none";
63          return;
64        }
65
66        // Prioriza projetosRaiz vindos do response; se não existir, usa o parâmetro passado
67        const projetosRaiz = new Set(
68          Array.isArray(data.projetosRaiz) ?
69            data.projetosRaiz.map(Number) :
70            (projetoRaizParam ? [Number(projetoRaizParam)] : [])
71        );
72
73        marcas.forEach(marca => {
74          const linkCard = document.createElement("a");
75            // calcula índice baseado no DOM atual (compatível com carregamento incremental) para cards de marcas
76            const i = lista ? lista.querySelectorAll(".card-marca").length : 0;
77
78            // aplicar variação de padding a cada grupo de 3 cards:
79            // primeiro do grupo (i % 3 === 0) => ps-md-0 pe-md-2
80            // terceiro do grupo (i % 3 === 2) => ps-md-2 pe-0
81            const paddingClass = (i % 3 === 0) ? "ps-md-0 pe-md-2" : (i % 3 === 2) ? "ps-md-2 pe-md-0" : "";
82            linkCard.className = `card-marca col-md-4 col-6 mb-3 d-flex ${paddingClass}`.trim();
83
84          const idProj = Number(marca.idProjeto);
85          // const baseHref = projetosRaiz.has(idProj) ? "/marca/" : "/produtos/marca/";
86          const baseHref = "/marca/";
87          linkCard.href = baseHref + marca.slugMarca;
88
89          let logoCaminho = marca.logoMarca ? 'https://www.hypera.com.br/assets/images/marcas/banners/' : "/assets/images/";
90          let logoMarca = marca.logoMarca && marca.logoMarca.includes("-negativo") ? marca.logoMarca.replace("-negativo", "") : marca.logoMarca;
91
92          const card = document.createElement("div");
93          card.className = "card card-marca d-flex justify-content-center align-items-center rounded border border-1 border-neutra-100 py-md-3 p-mobile-3 h-100 w-100";
94
95          if (logoMarca) {
96            const logo = document.createElement("img");
97            logo.src = `${logoCaminho}${logoMarca}`;
98            logo.className = "image object-fit-contain";
99            logo.alt = marca.nomeMarca;
100            logo.height = 48;
101            logo.width = 194;
102            card.appendChild(logo);
103          } else {
104            const nomeMarca = document.createElement("h3");
105            nomeMarca.className = "text-center mb-0";
106            nomeMarca.textContent = marca.nomeMarca;
107            card.appendChild(nomeMarca);
108          }
109
110          linkCard.appendChild(card);
111          lista.appendChild(linkCard);
112        });
113
114        marcasCarregadas += marcas.length;
115        totalFiltro.textContent = `Você visualizou ${marcasCarregadas} de ${totalMarcasBanco} marcas`;
116
117        if (marcasCarregadas >= totalMarcasBanco) {
118          // substituir botão por um texto informativo
119          if (btnCarregar) {
120            if(document.getElementById("msg-todas-marcas-carregadas")) {
121              btnCarregar.remove();
122            } else {
123              const msg = document.createElement("div");
124              msg.id = "msg-todas-marcas-carregadas";
125              msg.textContent = "Todas as marcas foram carregadas";
126              msg.className = "text-muted text-center fw-bold";
127              btnCarregar.parentNode.insertBefore(msg, btnCarregar.
127nextSibling);
128              btnCarregar.remove();
129            }
130            
131            if (btnCarregar.parentNode) {
132              btnCarregar.parentNode.insertBefore(msg, btnCarregar.nextSibling);
133              btnCarregar.remove();
134            } else {
135              const msg = document.createElement("div");
136              msg.id = "msg-todas-marcas-carregadas";
137              msg.textContent = "Todas as marcas foram carregadas";
138              msg.className = "text-muted text-center fw-bold";
139              btnCarregar.parentNode.insertBefore(msg, btnCarregar.nextSibling);
140              btnCarregar.remove();
141            }
142          }
143        } else {
144          if (btnCarregar) {
145            btnCarregar.removeAttribute("disabled");
146            btnCarregar.textContent = "Carregar mais";
147            btnCarregar.style.display = "block";
148          } else {
149            // remove o texto "Todas as marcas foram carregadas" se existir
150            const msg = document.getElementById("msg-todas-marcas-carregadas");
151            if (msg) {
152              // recriar o botão
153              const novoBtn = document.createElement("button");
154              novoBtn.id = "btn-carregar-marcas";
155              novoBtn.className = "btn btn-primary mx-auto d-block mt-3";
156              novoBtn.textContent = "Carregar mais";
157              novoBtn.addEventListener("click", () => {
158                novoBtn.setAttribute("disabled", "disabled");
159                novoBtn.textContent = "Carregando...";
160                pagina++;
161                carregarMarcas(false, projetoRaizSelecionado);
162              });
163              const parent = msg.parentNode || lista;
164              parent.insertBefore(novoBtn, msg.nextSibling);
165              // garante estado visível e habilitado do botão
166              btnCarregar.removeAttribute("disabled");
167              btnCarregar.textContent = "Carregar mais";
168              btnCarregar.style.display = "block";
169              msg.remove();
170            }
171          }
172        }
173      });
174  }
175
176  // Clique na letra
177  letrasBtns.forEach(btn => {
178    btn.addEventListener("click", () => {
179      // resetar estilo de todas
180      letrasBtns.forEach(b => {
181        b.classList.remove("btn-primary", "text-primary-50");
182        b.classList.add("btn-primary-50", "text-primary");
183      });
184
185      // aplicar estilo de ativa
186      btn.classList.remove("btn-primary-50", "text-primary");
187      btn.classList.add("btn-primary", "text-primary-50");
188
189      letraSelecionada = btn.dataset.letra;
190      // lê projetoRaiz do data-attribute da letra (por exemplo data-projetoraiz)
191      projetoRaizSelecionado = btn.dataset.projetoraiz || "";
192      carregarMarcas(true, projetoRaizSelecionado);
193
194      const offcanvasEl = document.getElementById("offcanvasResponsive");
195      if (offcanvasEl && offcanvasEl.classList.contains("show")) {
196        const offcanvasInstance = bootstrap.Offcanvas.getInstance(offcanvasEl)
197          || new bootstrap.Offcanvas(offcanvasEl);
198        offcanvasInstance.hide();
199      }
200    });
201  });
202
203  // Busca por nome
204  busca = (inputBusca?.value || "").trim();
205  if (btnSearch) {
206    btnSearch.innerHTML = busca.length > 0
207      ? `<span class="material-symbols-rounded align-middle">delete</span>`
208      : `<span class="material-symbols-rounded align-middle">search</span>`;
209  }
210
211  if (inputBusca) {
212    inputBusca.addEventListener("input", (e) => {
213      busca = e.target.value.trim();
214      if (btnSearch) {
215        btnSearch.innerHTML = busca.length > 0
216          ? `<span class="material-symbols-rounded align-middle">delete</span>`
217          : `<span class="material-symbols-rounded align-middle">search</span>`;
218      }
219      carregarMarcas(true, projetoRaizSelecionado);
220    });
221  }
222
223  if (btnSearch) {
224    btnSearch.addEventListener("click", () => {
225      if (busca.length > 0) {
226        inputBusca.value = "";
227        busca = "";
228        btnSearch.innerHTML = `<span class="material-symbols-rounded align-middle">search</span>`;
229        carregarMarcas(true, projetoRaizSelecionado);
230      }
231    });
232  }
233
234  // Limpar filtro
235  btnLimpar.addEventListener("click", e => {
236    e.preventDefault();
237    letraSelecionada = "";
238    busca = "";
239    projetoRaizSelecionado = "";
240    if (inputBusca) inputBusca.value = "";
241
242    letrasBtns.forEach(b => {
243      b.classList.remove("btn-primary", "text-primary-50");
244      b.classList.add("btn-primary-50", "text-primary");
245    });
246
247    // remover o texto "Todas as marcas foram carregadas" e restaurar o botão
248    const msg = document.getElementById("msg-todas-marcas-carregadas");
249    if (msg) {
250      const parent = msg.parentNode || lista;
251      if (btnCarregar) {
252        parent.insertBefore(btnCarregar, msg.nextSibling);
253        // garante estado visível e habilitado do botão
254        btnCarregar.removeAttribute("disabled");
255        btnCarregar.textContent = "Carregar mais";
256        btnCarregar.style.display = "block";
257      } else {
258        const novoBtn = document.createElement("button");
259        novoBtn.id = "btn-carregar-marcas";
260        novoBtn.className = "btn btn-primary mx-auto d-block mt-3";
261        novoBtn.textContent = "Carregar mais";
262        novoBtn.addEventListener("click", () => {
263          novoBtn.setAttribute("disabled", "disabled");
264          novoBtn.textContent = "Carregando...";
265          pagina++;
266          carregarMarcas(false, projetoRaizSelecionado);
267        });
268        parent.insertBefore(novoBtn, msg.nextSibling);
269      }
270      msg.remove();
271    }
272
273    carregarMarcas(true, projetoRaizSelecionado);
274
275    const offcanvasEl = document.getElementById("offcanvasResponsive");
276    if (offcanvasEl && offcanvasEl.classList.contains("show")) {
277      const offcanvasInstance = bootstrap.Offcanvas.getInstance(offcanvasEl)
278        || new bootstrap.Offcanvas(offcanvasEl);
279      offcanvasInstance.hide();
280    }
281  });
282
283  // Botão carregar mais
284  btnCarregar.addEventListener("click", () => {
285    btnCarregar.setAttribute("disabled", "disabled");
286    btnCarregar.textContent = "Carregando...";
287    pagina++;
288    carregarMarcas(false, projetoRaizSelecionado);
289  });
290
291  carregarMarcas(true, projetoRaizSelecionado); // inicial
292});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.