1const GetServicoTemas = async () => { 2 const response = await fetch('/eficiente/sites/blumenau/ajax/servicos.tabs.php'); 3 const data = await response.json(); 4 return data; 5} 6 7const GetServicoAssuntos = async () => { 8 const response = await fetch('/eficiente/sites/blumenau/ajax/servicos.tema.php?limit=9'); 9 const data = await response.json(); 10 return data; 11} 12 13const GetNoticiasHome = async () => { 14 const response = await fetch('/eficiente/sites/blumenau/ajax/publicacoes.noticias.php?limit=15'); 15 const data = await response.json(); 16 return data; 17} 18 19const GetPublicacoesOficiais = async () => { 20 const response = await fetch('/eficiente/sites/blumenau/ajax/publicacoes.oficiais.php?limit=20'); 21 const data = await response.json(); 22 return data; 23} 24 25const GetBannersHome = async () => { 26 const response = await fetch('/eficiente/sites/blumenau/ajax/publicacoes.banners.php?limit=5'); 27 const data = await response.json(); 28 return data; 29} 30 31const GetComunicadosHome = async () => { 32 const response = await fetch('/eficiente/sites/blumenau/ajax/publicacoes.comunicados.php?limit=5'); 33 const data = await response.json(); 34 return data; 35} 36 37const GetBannerSecundarioHome = async () => { 38 const response = await fetch('/eficiente/sites/blumenau/ajax/publicacoes.bannersecundario.php?limit=5'); 39 const data = await response.json(); 40 return data; 41} 42 43const GetAcessoRapidoHome = async () => { 44 const response = await fetch('/eficiente/sites/blumenau/ajax/publicacoes.acessorapido.php?limit=4'); 45 const data = await response.json(); 46 return data; 47} 48 49const GetLocaisHome = async () => { 50 const response = await fetch('/eficiente/sites/blumenau/ajax/publicacoes.locais.php?limit=18'); 51 const data = await response.json(); 52 return data; 53} 54 55const GetSecaoHome = async () => { 56 const response = await fetch('/eficiente/sites/blumenau/ajax/secoes.home.php'); 57 const data = await response.json(); 58 return data; 59} 60 61const RenderSecaoHome = (data) => { 62 const header = document.querySelector('.tourism-header'); 63 if (!header || !data || !data.fields) return; 64 65 const fields = data.fields; 66 const title = fields["TÃtulo da seção locais"]; 67 const text = fields["Texto da seção locais"]; 68 const btnText = fields["Texto botão visitar"]; 69 const btnLink = fields["Link botão visitar"]; 70 71 if (title) { 72 const h2 = header.querySelector('h2'); 73 if (h2) h2.textContent = title; 74 } 75 76 if (text) { 77 const p = header.querySelector('p'); 78 if (p) { 79 // Replace newlines or corrupted 'rn' with <br> 80 // Note: Since I fixed funcoes.php, new saves will have real newlines. 81 // If the data is still corrupted with 'rn', we can try to fix it here too. 82 let formattedText = text.replace(/\r\n|\r|\n/g, '<br>'); 83 // If the user hasn't re-saved yet, 'rn' might be literal. 84 // But replacing all 'rn' is dangerous. We'll stick to real newlines for now. 85 p.innerHTML = formattedText; 86 } 87 } 88 89 if (btnLink) { 90 const a = header.querySelector('a'); 91 if (a) a.href = btnLink; 92 } 93 94 if (btnText) { 95 const btn = header.querySelector('.btn-tourism'); 96 if (btn) { 97 // Keep the SVG icon 98 const svg = btn.querySelector('svg'); 99 btn.innerHTML = ''; 100 if (svg) btn.appendChild(svg); 101 btn.appendChild(document.createTextNode(btnText)); 102 } 103 } 104 105 if (fields["Acesso rápido"]) { 106 RenderAcessoRapidoHome(fields["Acesso rápido"]); 107 } 108} 109 110let currentLocaisSlide = 0; 111let locaisInterval = null; 112let isLocaisPaused = false; 113 114const RenderLocaisHome = (items) => { 115 const section = document.querySelector('.tourism-section'); 116 const gallery = document.querySelector('.tourism-gallery'); 117 if (!gallery) return; 118 gallery.innerHTML = ''; 119 120 items.forEach((item, index) => { 121 const div = document.createElement('div'); 122 div.className = 'gallery-item small locais-slide-item'; 123 div.innerHTML = ` 124 <img src="${item.imagem || '/eficiente/sites/blumenau/images/tourism-card1.png'}" alt="${item.titulo}"> 125 <div class="caption">${item.titulo}</div> 126 `; 127 if (item.link) { 128 div.style.cursor = 'pointer'; 129 div.onclick = () => window.location.href = item.link; 130 } 131 gallery.appendChild(div); 132 });
133 134 const carouselContainer = section ? section.querySelector('.tourism-carousel') : null; 135 136 if (items.length > 3) { 137 if (carouselContainer) carouselContainer.style.display = 'flex'; 138 139 if (carouselContainer) { 140 const btnPrev = carouselContainer.querySelector('.btn-prev'); 141 const btnNext = carouselContainer.querySelector('.btn-next'); 142 const btnPause = carouselContainer.querySelector('.btn-pause'); 143 144 if (btnPrev) btnPrev.onclick = () => ShowLocaisSlide(currentLocaisSlide - 1); 145 if (btnNext) btnNext.onclick = () => ShowLocaisSlide(currentLocaisSlide + 1); 146 if (btnPause) btnPause.onclick = () => { 147 isLocaisPaused = !isLocaisPaused; 148 btnPause.textContent = isLocaisPaused ? 'â¶ Continuar' : 'ââ Pausar'; 149 if (isLocaisPaused) clearInterval(locaisInterval); 150 else StartLocaisTimer(); 151 }; 152 } 153 154 StartLocaisTimer(); 155 ShowLocaisSlide(0); 156 } else { 157 if (carouselContainer) carouselContainer.style.display = 'none'; 158 const allItems = gallery.querySelectorAll('.locais-slide-item'); 159 allItems.forEach(item => item.style.display = 'block'); 160 } 161} 162 163const StartLocaisTimer = () => { 164 clearInterval(locaisInterval); 165 locaisInterval = setInterval(() => { 166 if (!isLocaisPaused) ShowLocaisSlide(currentLocaisSlide + 1); 167 }, 8000); 168} 169 170const ShowLocaisSlide = (slideIndex) => { 171 const items = document.querySelectorAll('.tourism-gallery .locais-slide-item'); 172 if (items.length === 0) return; 173 174 const totalSlides = Math.ceil(items.length / 3); 175 if (slideIndex >= totalSlides) slideIndex = 0; 176 if (slideIndex < 0) slideIndex = totalSlides - 1; 177 178 const start = slideIndex * 3; 179 const end = start + 3; 180 181 items.forEach((item, i) => { 182 item.style.display = (i >= start && i < end) ? 'block' : 'none'; 183 if (item.style.display === 'block') { 184 item.style.opacity = 0; 185 setTimeout(() => item.style.opacity = 1, 10); 186 } 187 }); 188 189 currentLocaisSlide = slideIndex; 190} 191 192const RenderAcessoRapidoHome = (items) => { 193 const grid = document.querySelector('.quick-cards-grid'); 194 if (!grid || !items || !Array.isArray(items)) return; 195 grid.innerHTML = ''; 196 197 items.forEach(item => { 198 const card = document.createElement('a'); 199 card.href = item["Link"] || '#'; 200 card.className = 'quick-card'; 201 202 const bgImg = item["Imagem de fundo"] ? `${item["Imagem de fundo"]}` : '/eficiente/sites/blumenau/images/card-bg1.png'; 203 card.style.backgroundImage = `url("${bgImg}")`; 204 205 const iconImg = item["Ãcone"] ? `${item["Ãcone"]}` : '/eficiente/sites/blumenau/images/icon-megafone.png'; 206 207 card.innerHTML = ` 208 <span class="icon"><img src="${iconImg}" alt="${item["TÃtulo"]}"></span> 209 <span class="label">${item["TÃtulo"] || ''}</span> 210 <span class="description">${item["SubtÃtulo"] || ''}</span> 211 <div class="card-strip"></div> 212 <span class="acess-btn"> 213 Acessar 214 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none"> 215 <path d="M2.91675 7H11.0834" stroke="white" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/> 216 <path d="M7 2.9165L11.0833 6.99984L7 11.0832" stroke="white" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/> 217 </svg> 218 </span> 219 `; 220 grid.appendChild(card); 221 }); 222} 223 224const RenderPublicacoesOficiais = (publicacoes) => { 225 const list = document.querySelector('.pub-list'); 226 if (!list) return; 227 228 // Keep the "Mais Publicações" link 229 const viewAllLink = list.querySelector('.view-all'); 230 231 // Clear existing list items except the "view-all" one 232 list.querySelectorAll('li:not(.view-all)').forEach(item => item.remove()); 233
234 publicacoes.forEach(p => { 235 const li = document.createElement('li'); 236 const target = p.target || '_self'; 237 li.innerHTML = `<a href="${p.link}" target="${target}">${p.titulo}</a>`; 238 if (viewAllLink) { 239 list.insertBefore(li, viewAllLink); 240 } else { 241 list.appendChild(li); 242 } 243 }); 244} 245 246const RenderServices = (services) => { 247 const grid = document.querySelector('.services-grid'); 248 if (!grid) return; 249 250 // Keep the "Mais Serviços" card if it exists 251 const maisServicosCard = grid.querySelector('.card-mais'); 252 253 // Clear other cards 254 grid.querySelectorAll('.service-card-home:not(.card-mais)').forEach(card => card.remove()); 255 256 services.forEach(s => { 257 const card = document.createElement('a'); 258 card.href = '/eficiente/sites/blumenau/secao/servicos/' + s.servicoid; 259 card.className = 'service-card-home'; 260 card.innerHTML = ` 261 <div class="service-card"> 262 <div class="card-header-area"> 263 <span class="icon"><img src="${s.temaicone ? s.temaicone : '/eficiente/classes/cartaservicos/icones/outros.svg'}" alt="${s.serviconome}"></span>${s.temanome} 264 </div> 265 <div class="card-body"> 266 <div class="card-title">${s.serviconome}</div> 267 <div class="card-badges"></div> 268 </div> 269 <a href="/eficiente/sites/blumenau/secao/servicos/${s.servicoid}" class="btn-access">Acessar â</a> 270 </div> 271 `; 272 if (maisServicosCard) { 273 grid.insertBefore(card, maisServicosCard); 274 } else { 275 grid.appendChild(card); 276 } 277 }); 278} 279 280let currentNewsSlide = 0; 281let newsInterval = null; 282let isNewsPaused = false; 283let globalNoticias = []; 284 285const RenderNoticias = (noticias) => { 286 const grid = document.querySelector('.news-grid'); 287 if (!grid) return; 288 grid.innerHTML = ''; 289 globalNoticias = noticias; 290 291 noticias.forEach((n, i) => { 292 const card = document.createElement('a'); 293 card.href = n.link; 294 card.className = 'news-card news-slide-item'; 295 card.style.display = (i < 3) ? 'block' : 'none'; 296 card.innerHTML = ` 297 <div class="news-thumb" style="background-image: url('${n.imagem}');"> 298 <span class="news-category">${n.categoria || n.secao}</span> 299 </div> 300 <div class="news-body"> 301 <span class="news-date"> 302 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none"> 303 <path d="M5.33325 1.33325V3.99992" stroke="#446C8C" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/> 304 <path d="M10.6667 1.33325V3.99992" stroke="#446C8C" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/> 305 <path d="M12.6667 2.66675H3.33333C2.59695 2.66675 2 3.2637 2 4.00008V13.3334C2 14.0698 2.59695 14.6667 3.33333 14.6667H12.6667C13.403 14.6667 14 14.0698 14 13.3334V4.00008C14 3.2637 13.403 2.66675 12.6667 2.66675Z" stroke="#446C8C" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/> 306 <path d="M2 6.66675H14" stroke="#446C8C" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/> 307 </svg> 308 ${n.data}</span> 309 <h3>${n.titulo}</h3> 310 <div class="read-more">Acessar notÃcia 311 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none"> 312 <path d="M3.33325 8H12.6666" stroke="#016CB0" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/> 313 <path d="M8 3.33325L12.6667 7.99992L8 12.6666" stroke="#016CB0" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/> 314 </svg> 315 </div> 316 </div> 317 `; 318 grid.appendChild(card); 319 });
320 321 const container = document.querySelector('.news-section'); 322 const btnPrev = container.querySelector('.btn-prev'); 323 const btnNext = container.querySelector('.btn-next'); 324 const btnPause = container.querySelector('.btn-pause'); 325 326 if (btnPrev) btnPrev.onclick = () => ShowNewsSlide(currentNewsSlide - 1); 327 if (btnNext) btnNext.onclick = () => ShowNewsSlide(currentNewsSlide + 1); 328 if (btnPause) btnPause.onclick = () => { 329 isNewsPaused = !isNewsPaused; 330 btnPause.textContent = isNewsPaused ? 'â¶ Continuar' : 'ââ Pausar'; 331 if (isNewsPaused) clearInterval(newsInterval); 332 else StartNewsTimer(); 333 }; 334 335 StartNewsTimer(); 336} 337 338const StartNewsTimer = () => { 339 clearInterval(newsInterval); 340 newsInterval = setInterval(() => { 341 if (!isNewsPaused) ShowNewsSlide(currentNewsSlide + 1); 342 }, 8000); 343} 344 345const ShowNewsSlide = (slideIndex) => { 346 const items = document.querySelectorAll('.news-grid .news-slide-item'); 347 if (items.length === 0) return; 348 349 const totalSlides = Math.ceil(items.length / 3); 350 if (slideIndex >= totalSlides) slideIndex = 0; 351 if (slideIndex < 0) slideIndex = totalSlides - 1; 352 353 const start = slideIndex * 3; 354 const end = start + 3; 355 356 items.forEach((item, i) => { 357 item.style.display = (i >= start && i < end) ? 'block' : 'none'; 358 // Simple fade effect 359 if (item.style.display === 'block') { 360 item.style.opacity = 0; 361 setTimeout(() => item.style.opacity = 1, 10); 362 } 363 }); 364 365 currentNewsSlide = slideIndex; 366} 367 368let currentBannerIndex = 0; 369let bannerInterval = null; 370let isPaused = false; 371 372const RenderBannersHome = (banners) => { 373 const container = document.querySelector('.home-banner-section'); 374 if (!container) return; 375 376 // Remove existing banners 377 container.querySelectorAll('.full-banner').forEach(b => b.remove()); 378 379 const carouselContainer = container.querySelector('.carousel-container'); 380 const isMobile = window.innerWidth <= 768; 381 382 banners.forEach((b, i) => { 383 const div = document.createElement('a'); 384 div.className = 'full-banner' + (i === 0 ? ' active' : ''); 385 div.href = b.link || '#'; 386 const imgUrl = (isMobile && b.imagemMobile && b.imagemMobile.trim() !== '') 387 ? b.imagemMobile 388 : (b.imagem || '/eficiente/sites/blumenau/images/banner-1.png'); 389 div.style.backgroundImage = `url('${imgUrl}')`; 390 container.insertBefore(div, carouselContainer); 391 }); 392 393 const btnPrev = container.querySelector('.btn-prev'); 394 const btnNext = container.querySelector('.btn-next'); 395 const btnPause = container.querySelector('.btn-pause'); 396 397 if (btnPrev) btnPrev.onclick = () => ShowBanner(currentBannerIndex - 1); 398 if (btnNext) btnNext.onclick = () => ShowBanner(currentBannerIndex + 1); 399 if (btnPause) btnPause.onclick = () => { 400 isPaused = !isPaused; 401 btnPause.textContent = isPaused ? 'â¶ Continuar' : 'ââ Pausar'; 402 if (isPaused) clearInterval(bannerInterval); 403 else StartBannerTimer(); 404 }; 405 406 StartBannerTimer(); 407} 408 409const StartBannerTimer = () => { 410 clearInterval(bannerInterval); 411 bannerInterval = setInterval(() => { 412 if (!isPaused) ShowBanner(currentBannerIndex + 1); 413 }, 5000); 414} 415 416const ShowBanner = (index) => { 417 const banners = document.querySelectorAll('.home-banner-section .full-banner'); 418 if (banners.length === 0) return; 419 420 if (index >= banners.length) index = 0; 421 if (index < 0) index = banners.length - 1; 422 423 banners.forEach((b, i) => { 424 b.classList.toggle('active', i === index); 425 }); 426 427 currentBannerIndex = index; 428} 429 430let currentComunicadoIndex = 0; 431let comunicadoInterval = null; 432let isComunicadoPaused = false; 433 434const RenderComunicadosHome = (comunicados) => { 435 const container = document.querySelector('.comm-column'); 436 if (!container) return; 437 438 // Remove existing banners 439 container.querySelectorAll('.comm-banner').forEach(b => b.remove()); 440 441 const carouselContainer = container.querySelector('.carousel-container'); 442 443 comunicados.forEach((c, i) => { 444 const div = document.createElement('a'); 445 div.className = 'comm-banner' + (i === 0 ? ' active' : ''); 446 div.href = c.link; 447 div.style.display = 'block'; 448 div.innerHTML = `<img src="${c.imagem || "data:image/svg+xml,<svg width='641' height='430' viewBox='0 0 641 430' xmlns='http://www.w3.org/2000/svg'><rect width='641' height='430' fill='%23d0d0d0'/></svg>"}" alt="${c.titulo}">`; 449 container.insertBefore(div, carouselContainer); 450 });
451 452 const btnPrev = container.querySelector('.btn-prev'); 453 const btnNext = container.querySelector('.btn-next'); 454 const btnPause = container.querySelector('.btn-pause'); 455 456 if (btnPrev) btnPrev.onclick = () => ShowComunicado(currentComunicadoIndex - 1); 457 if (btnNext) btnNext.onclick = () => ShowComunicado(currentComunicadoIndex + 1); 458 if (btnPause) btnPause.onclick = () => { 459 isComunicadoPaused = !isComunicadoPaused; 460 btnPause.textContent = isComunicadoPaused ? 'â¶ Continuar' : 'ââ Pausar'; 461 if (isComunicadoPaused) clearInterval(comunicadoInterval); 462 else StartComunicadoTimer(); 463 }; 464 465 StartComunicadoTimer(); 466} 467 468const StartComunicadoTimer = () => { 469 clearInterval(comunicadoInterval); 470 comunicadoInterval = setInterval(() => { 471 if (!isComunicadoPaused) ShowComunicado(currentComunicadoIndex + 1); 472 }, 6000); // Slightly different timing for variation 473} 474 475const ShowComunicado = (index) => { 476 const banners = document.querySelectorAll('.comm-column .comm-banner'); 477 if (banners.length === 0) return; 478 479 if (index >= banners.length) index = 0; 480 if (index < 0) index = banners.length - 1; 481 482 banners.forEach((b, i) => { 483 b.classList.toggle('active', i === index); 484 }); 485 486 currentComunicadoIndex = index; 487} 488 489const RenderBannerSecundarioHome = (banners) => { 490 const container = document.querySelector('#banner-secundario'); 491 if (!container) return; 492 493 // Remove existing content 494 container.innerHTML = '<!-- Dynamic Content -->'; 495 496 if (banners && banners.length > 0) { 497 const b = banners[0]; // Just use the first one 498 const img = document.createElement('img'); 499 const isMobile = window.innerWidth <= 768; 500 const imgUrl = (isMobile && b.imagemMobile && b.imagemMobile.trim() !== '') 501 ? b.imagemMobile 502 : (b.imagem || '/eficiente/sites/blumenau/images/banner-2.png'); 503 img.src = imgUrl; 504 img.alt = b.titulo; 505 img.className = 'active'; // Just keep it active/visible 506 if (b.link) { 507 img.style.cursor = 'pointer'; 508 img.onclick = () => window.location.href = b.link; 509 } 510 container.appendChild(img); 511 } 512} 513 514window.addEventListener('load', function () { 515 const tabs = document.querySelector('#home-tabs'); 516 if (tabs) { 517 GetServicoTemas().then(data => { 518 if (data && data.length > 0) { 519 tabs.innerHTML = ''; 520 data.forEach((t, index) => { 521 const tab = document.createElement('button'); 522 tab.textContent = t.publiconome; 523 if (index === 0) { 524 tab.classList.add('active'); 525 document.querySelector('.home-btn-more-services').href = `/eficiente/sites/blumenau/secao/servicos?perfis=${t.publicoid}`; 526 RenderServices(t.servicos); 527 } 528 tab.addEventListener('click', (e) => { 529 document.querySelectorAll('#home-tabs button').forEach(b => b.classList.remove('active')); 530 e.target.classList.add('active'); 531 document.querySelector('.home-btn-more-services').href = `/eficiente/sites/blumenau/secao/servicos?perfis=${t.publicoid}`; 532 RenderServices(t.servicos); 533 }); 534 tabs.appendChild(tab); 535 }); 536 } 537 }); 538 } 539 540 const subjectsGrid = document.querySelector('.subjects-grid'); 541 if (subjectsGrid) { 542 GetServicoAssuntos().then(data => { 543 if (data && data.length > 0) { 544 subjectsGrid.innerHTML = ''; 545 data.forEach(s => { 546 if (s.id == 26) { return; } 547 const card = document.createElement('a'); 548 card.href = '/eficiente/sites/blumenau/secao/servicos?temas=' + s.id; 549 card.className = 'subject-card'; 550 card.innerHTML = ` 551 <div class="subject-icon blue">
551<img src="${s.icone ? s.icone : '/eficiente/classes/cartaservicos/icones/outros.svg'}" alt="${s.temanome}"></div> 552 <span>${s.nome}</span> 553 `; 554 subjectsGrid.appendChild(card); 555 }); 556 } 557 }); 558 } 559 560 GetNoticiasHome().then(data => { 561 if (data && data.length > 0) { 562 RenderNoticias(data); 563 } 564 }); 565 566 GetBannersHome().then(data => { 567 if (data && data.length > 0) { 568 RenderBannersHome(data); 569 } 570 }); 571 572 GetComunicadosHome().then(data => { 573 if (data && data.length > 0) { 574 RenderComunicadosHome(data); 575 } 576 }); 577 578 // Removido o carregamento via publicações, agora é via secao.home.php (home.xml) 579 /* 580 GetAcessoRapidoHome().then(data => { 581 if (data && data.length > 0) { 582 RenderAcessoRapidoHome(data); 583 } 584 }); 585 */ 586 587 GetLocaisHome().then(data => { 588 if (data && data.length > 0) { 589 RenderLocaisHome(data); 590 } 591 }); 592 593 GetSecaoHome().then(data => { 594 if (data) { 595 RenderSecaoHome(data); 596 } 597 }); 598 599 GetBannerSecundarioHome().then(data => { 600 if (data && data.length > 0) { 601 RenderBannerSecundarioHome(data); 602 } 603 }); 604 605 GetPublicacoesOficiais().then(data => { 606 if (data && data.length > 0) { 607 RenderPublicacoesOficiais(data); 608 } 609 }); 610});
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.