1<!doctype html> 2<html lang="pt-br"> 3 4<head> 5 <meta charset="utf-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <title>Prefeitura Municipal de Oliveira Dos Brejinhos - Ba</title> 8 9 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" 10 integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" 11 crossorigin="anonymous" referrerpolicy="no-referrer" /> 12 13 14 15
15<script src="https://kit.fontawesome.com/7c366fa5c4.js" crossorigin="anonymous"></script>
15 16 <link rel="icon" type="image/x-icon" href="src/View/Layout/favicon/favicon.ico"> 17 <link rel="shortcut icon" href="src/View/Layout/favicon/favicon.ico" type="image/x-icon"> 18 <link rel="apple-touch-icon" href="src/View/Layout/favicon/favicon.ico"> 19 <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> 20 <link href="public/css/app.css" rel="stylesheet"> 21 <link href="public/js/app.js"> 22 <link href="public/js/jquery.js"> 23 <link rel="stylesheet" href="node_modules/bootstrap-icons/font/bootstrap-icons.css"> 24
24<script src="node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
24 25 <link href="https://cdn.jsdelivr.net/npm/[email protected]/index.global.min.css" rel="stylesheet"> 26
26<script src="https://cdn.jsdelivr.net/npm/[email protected]/index.global.min.js"></script>
26 27 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" 28 integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous"> 29
29<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
29 30 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css"> 31 32 33
33<script src="https://code.jquery.com/ui/1.13.0/jquery-ui.js"></script>
33 34
34<script src="https://deuxhuithuit.github.io/quicksearch/r/src/jquery.quicksearch.js"></script>
34 35 36 37
37<script> 38 ! function (d, s, id) { 39 var js, fjs = d.getElementsByTagName(s)[0]; 40 if (!d.getElementById(id)) { 41 js = d.createElement(s); 42 js.id = id; 43 js.src = 'https://weatherwidget.io/js/widget.min.js'; 44 fjs.parentNode.insertBefore(js, fjs); 45 } 46 }(document, 'script', 'weatherwidget-io-js'); 47 </script>
47 48</head> 49 50 51 52<body><nav class="navbar fixed-top mb_menu container-fluid" 53 style="background-color: #0A28D2;"> 54 55 <div class="container-fluid d-flex justify-content-between align-items-center"> 56 57 <!-- Portal Transparência --> 58 <div class="d-flex align-items-center ms-5"> 59 <a href="https://transparencia.caldeiraogrande.ba.gov.br" 60 class="btn tr-button"> 61 PORTAL DA TRANSPARÃNCIA 62 </a> 63 </div> 64 65 <!-- Logo --> 66 <div class="d-flex justify-content-center flex-grow-1 ms-5"> 67 <a class="navbar-brand m-0"> 68 <img src="public/images/logo/logo.png" width="300"> 69 </a> 70 </div> 71 72 <!-- Redes Sociais --> 73 <div class="d-flex align-items-center gap-1 ms-5"> 74 75 <button id="searchBtn" class="btn btn-outline-danger glass-box"> 76 <i class="fa-solid fa-magnifying-glass"></i> 77 </button> 78 79 <input id="searchInput" 80 type="text" 81 class="form-control glass-box" 82 placeholder="Buscar" 83 style="width:130px;"> 84 85 <a href="https://www.instagram.com/pref.oliveiradosbrejinhos/" class="btn btn-outline-danger glass-box"> 86 <i class="fa-brands fa-instagram"></i> 87 </a> 88 89 <a href="https://www.facebook.com/prefeituradeoliveiradosbrejinhos" class="btn btn-outline-danger glass-box"> 90 <i class="fa-brands fa-facebook"></i> 91 </a> 92 93 <a href="https://www.youtube.com/@OliveiraDosBrejinhos" class="btn btn-outline-danger glass-box"> 94 <i class="fa-brands fa-youtube"></i> 95 </a> 96 97 <a href="https://wa.me/message/JX4V6KJNSAOUE1" 98 target="_blank" 99 class="btn btn-outline-danger glass-box"> 100 <i class="bi bi-whatsapp"></i> 101 </a> 102 103 </div> 104 105 </div> 106 107</nav> 108<nav class="navbar navbar-expand-lg fixed-top container-fluid mb_mn_config h6" style="background-color:#0a28d2; top: 130px;"><button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button> <div class="row collapse navbar-collapse" id="navbarSupportedContent"><ul class="navbar-nav text-center d-flex justify-content-center grid gap-3"><li class="nav-item grid gap-3"><a class="nav-link fw-bold menu_h white-space-nowrap" href="/">INÃCIO</a></li><li class="nav-item dropdown text-center"><a class="nav-link fw-bold dropdown-toggle menu_h" href="#" id="navbarDropdown8" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">INSTITUCIONAL</a><div class="dropdown-menu dropdown-content col" aria-labelledby="navbarDropdown8" style="background-color:#0a28d2"><a class="dropdown-item fw-bold menu_h text-center" href="/municipio"> A CIDADE</a><a class="dropdown-item fw-bold menu_h text-center" href="/gestao"> GESTÃO</a><a class="dropdown-item fw-bold menu_h text-center" href="/organograma"> ORGANOGRAMA</a></div></li><li class="nav-item dropdown text-center"><a class="nav-link fw-bold dropdown-toggle menu_h" href="#" id="navbarDropdown10" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">TRANSPARÃNCIA</a><div class="dropdown-menu dropdown-content col" aria-labelledby="navbarDropdown10" style="background-color:#0a28d2"><a class="dropdown-item fw-bold menu_h text-center" href="/diario"> DIARIO OFICIAL</a><a class="dropdown-item fw-bold menu_h text-center" href="https://transparencia.oliveiradosbrejinhos.ba.gov.br"> PORTAL DA TRANSPARÃNCIA</a><a class="dropdown-item fw-bold menu_h text-center" href="/esic"> E-SIC</a><a class="dropdown-item fw-bold menu_h text-center" href="/ouvidoria"> OUVIDORIA</a><a class="dropdown-item fw-bold menu_h text-center" href="https://transparencia.oliveiradosbrejinhos.ba.gov.br"> DOCUMENTAÃÃO NA INTEGRA</a></div></li><li class="nav-item dropdown text-center"><a class="nav-link fw-bold dropdown-toggle menu_h" href="#" id="navbarDropdown11" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">CIDADÃO</a><div class="dropdown-menu dropdown-content col" aria-labelledby="navbarDropdown11" style="background-color:#0a28d2"><a class="dropdown-item fw-bold menu_h text-center" href="https://alistamento.eb.mil.br/"> SERVIÃO MILITAR</a><a class="dropdown-item fw-bold menu_h text-center" href="https://delegaciavirtual.sinesp.gov.br/portal/"> DELEGACIA VIRTUAL</a><a class="dropdown-item fw-bold menu_h text-center" href="https://www.sac.ba.gov.br/"> SAC</a><a class="dropdown-item fw-bold menu_h text-center" href="https://www.ba.gov.br/trabalho/280/vagas-do-dia-sinebahia"> SINE BAHIA</a><a class="dropdown-item fw-bold menu_h text-center" href="https://www.gov.br/pt-br"> GOV BR</a><a class="dropdown-item fw-bold menu_h text-center" href="https://www.ba.gov.br/">
108 SERVIÃOS DO GOVERNO</a><a class="dropdown-item fw-bold menu_h text-center" href="/curriculoonline"> CURRICULO ONLINE PMOB</a></div></li><li class="nav-item dropdown text-center"><a class="nav-link fw-bold dropdown-toggle menu_h" href="#" id="navbarDropdown12" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">EMPREENDEDOR</a><div class="dropdown-menu dropdown-content col" aria-labelledby="navbarDropdown12" style="background-color:#0a28d2"><a class="dropdown-item fw-bold menu_h text-center" href="https://imcompras.org"> PORTAL DE COMPRAS</a><a class="dropdown-item fw-bold menu_h text-center" href="https://oliveiradosbrejinhos.saatri.com.br/DocumentoFiscal"> NOTA FISCAL DE SERVIÃOS</a></div></li><li class="nav-item dropdown text-center"><a class="nav-link fw-bold dropdown-toggle menu_h" href="#" id="navbarDropdown13" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">SERVIDOR</a><div class="dropdown-menu dropdown-content col" aria-labelledby="navbarDropdown13" style="background-color:#0a28d2"><a class="dropdown-item fw-bold menu_h text-center" href="https://m.fatorsistemas.com.br/login.php"> PORTAL DO SERVIDOR</a></div></li><li class="nav-item grid gap-3"><a class="nav-link fw-bold menu_h white-space-nowrap" href="/noticias">NOTÃCIAS</a></li><li class="nav-item dropdown text-center"><a class="nav-link fw-bold dropdown-toggle menu_h" href="#" id="navbarDropdown15" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">CONTATO</a><div class="dropdown-menu dropdown-content col" aria-labelledby="navbarDropdown15" style="background-color:#0a28d2"><a class="dropdown-item fw-bold menu_h text-center" href="/faleconosco"> FALE CONOSCO</a><a class="dropdown-item fw-bold menu_h text-center" href="/ouvidoria"> OUVIDORIA</a></div></li></ul></div></nav><div class="modal fade" id="modalBusca" tabindex="-1" aria-labelledby="modalBuscaLabel" aria-hidden="true"> 109 <div class="modal-dialog modal-dialog-centered"> 110 <div class="modal-content bg-dark text-light"> 111 <div class="modal-header border-0"> 112 <h5 class="modal-title" id="modalBuscaLabel">Pesquisar no Portal</h5> 113 <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Fechar"></button> 114 </div> 115 <div class="modal-body"> 116 <form id="formBusca" method="GET" action="buscar.php"> 117 <div class="input-group"> 118 <input type="text" name="q" class="form-control form-control-lg" placeholder="Digite sua busca..." required> 119 <button id="btnSearch" class="btn btn-primary btn-lg" type="submit"><i class="bi bi-search"></i></button> 120 121 122 </div> 123 </form> 124 <div id="resultadosBusca" class="mt-4"></div> 125 </div> 126 </div> 127 </div> 128</div>
129<script> 130 // Função para aumentar o tamanho da fonte de todos os elementos filhos de body 131 function increaseFontSize() { 132 const currentFontSize = parseFloat(window.getComputedStyle(document.body).fontSize); 133 document.body.style.fontSize = (currentFontSize * 1.1) + 'px'; 134 135 // Aumentar o tamanho de fonte para todos os elementos filhos de body 136 const allElements = document.querySelectorAll('body *'); 137 allElements.forEach(element => { 138 const elementFontSize = parseFloat(window.getComputedStyle(element).fontSize); 139 element.style.fontSize = (elementFontSize * 1.1) + 'px'; 140 }); 141 } 142 143 // Função para diminuir o tamanho da fonte de todos os elementos filhos de body 144 function decreaseFontSize() { 145 const currentFontSize = parseFloat(window.getComputedStyle(document.body).fontSize); 146 document.body.style.fontSize = (currentFontSize / 1.1) + 'px'; 147 148 // Diminuir o tamanho de fonte para todos os elementos filhos de body 149 const allElements = document.querySelectorAll('body *'); 150 allElements.forEach(element => { 151 const elementFontSize = parseFloat(window.getComputedStyle(element).fontSize); 152 element.style.fontSize = (elementFontSize / 1.1) + 'px'; 153 }); 154 } 155 // Função para alternar o modo de contraste 156 function toggleContrastMode() { 157 document.body.classList.toggle('high-contrast'); 158 } 159 160 const originalFontSizes = []; 161 162 window.addEventListener('load', function() { 163 const allElements = document.querySelectorAll('body *'); 164 allElements.forEach(element => { 165 const elementFontSize = parseFloat(window.getComputedStyle(element).fontSize); 166 originalFontSizes.push(elementFontSize); 167 }); 168 }); 169 170 // Restaurar configurações para o padrão 171 function resetSettings() { 172 // Redefinir o tamanho de fonte para o body 173 document.body.style.fontSize = ''; 174 175 // Restaurar tamanhos de fonte originais dos elementos filhos de body 176 const allElements = document.querySelectorAll('body *'); 177 allElements.forEach((element, index) => { 178 element.style.fontSize = originalFontSizes[index] + 'px'; 179 }); 180 181 // Remover a classe high-contrast 182 document.body.classList.remove('high-contrast'); 183 } 184 185 // Event listeners para os links de acessibilidade 186 document.getElementById('increase-font').addEventListener('click', increaseFontSize); 187 document.getElementById('decrease-font').addEventListener('click', decreaseFontSize); 188 document.getElementById('toggle-contrast').addEventListener('click', toggleContrastMode); 189 document.getElementById('reset-settings').addEventListener('click', resetSettings); 190</script>
190 191<div id="pag_config"> 192 <div class="m-5"> 193 <nav aria-label="breadcrumb"> 194 <ol class="breadcrumb"> 195 <li class="breadcrumb-item"><a href="/" class="text-decoration-none text-primary fw-bold"><i class="bi bi-house-fill"></i> InÃcio</a></li> 196 <li class="breadcrumb-item active">Organograma</li> 197 </ol> 198 </nav> 199 <hr class="hr-breadcrumb"> 200 </div> 201 <main class="content"> 202 203 <div class="container-fluid"> 204 205 206 <section class="estrutura-header mb-5 container"> 207 208 <div class="text-start"> 209 210 <h3 class="fw-bold text-uppercase" style="color:#0a28d2;"> 211 Estrutura Organizacional 212 </h3> 213 214 <p class="lead mt-3"> 215 â Apresenta como o órgão está organizado, com seus setores, unidades e responsáveis, além dos canais de contato institucionais. Ela facilita o acesso do cidadão à s informações e aos serviços públicos. 216 </p> 217 218 219 220 <div class="card shadow mb-5 norma-card"> 221 222 <div class="card-body"> 223 224 <div class="row align-items-center"> 225 <p>Norma que institui/altera a estrutura organizacional</p> 226 <div class="col-lg-9"> 227 228 <h4 class="fw-bold mb-2" style="color:#0a28d2;"> 229 230 <i data-feather="book-open"></i> 231 232 LEI N° 82/2017 DE 16 DE JUNHO DE 2017. 233 </h4> 234 235 236 <p class="mb-2 fw-normal"> 237 238 âDispõe sobre a Estruturação Administrativa da Prefeitura Municipal de Oliveira dos Brejinhos e dá outras providênciasâ. 239 </p> 240 241 242 <span class="badge bg-primary"> 243 244 N° 82/2017 245 </span> 246 247 248 <span class="badge bg-secondary ms-2"> 249 250 Publicada em 251 16/07/2017 252 </span> 253 254 255 </div> 256 257 <div class="col-lg-3 text-lg-end mt-3 mt-lg-0"> 258 259 260 <a 261 href="https://oliveiradosbrejinhos.ba.gov.br/uploads/estrutura/1784836271_1765474325_LEI DE ESTRUTURA ADMINISTRATIVA_2017_PMOB.pdf" 262 target="_blank" 263 class="btn btn-dark rounded-pill px-4"> 264 265 <i class="bi bi-box-arrow-up-right"></i> 266 Visualizar Norma 267 268 </a> 269 270 271 </div> 272 273 </div> 274 275 </div> 276 277 </div> 278 279 280 281 </div> 282 283 284 </section> 285 286 287 <div class="text-center mb-4"> 288 289 <div class="btn-group"> 290 291 <button class="btn btn-success" onclick="exportarJSON()"> 292 <i class="fa-solid fa-code"></i> JSON 293 </button> 294 295 <button class="btn btn-primary" onclick="exportarCSV()"> 296 <i class="fa-solid fa-file-csv"></i> CSV 297 </button> 298 299 <button class="btn btn-warning" onclick="exportarXLSX()"> 300 <i class="fa-solid fa-file-excel"></i> XLSX 301 </button> 302 303 <button class="btn btn-secondary" onclick="exportarTXT()"> 304 <i class="fa-solid fa-file-lines"></i> TXT 305 </button> 306 307 <button class="btn btn-danger" onclick="exportarPDF()"> 308 <i class="fa-solid fa-file-pdf"></i> PDF 309 </button> 310 311 </div> 312 313 </div> 314 <!-- PESQUISA --> 315 316 <div class="row mb-5"> 317 318 <div class="col-md-8 mx-auto"> 319 320 <div class="input-group pesquisa-box"> 321
322 <span class="input-group-text"> 323 324 <i data-feather="search"></i> 325 326 </span> 327 328 329 <input 330 type="text" 331 id="pesquisaSecretaria" 332 class="form-control" 333 placeholder="Pesquisar secretaria ou responsável..."> 334 335 336 </div> 337 338 339 </div> 340 341 342 </div> 343 344 345 346 347 348 <section class="container mb-5"> 349 350 <div class="row g-4" id="listaSecretarias"> 351 352 <div class="col-12 text-center"> 353 354 <div class="spinner-border text-primary"></div> 355 356 <p class="mt-2 text-muted"> 357 Carregando secretarias... 358 </p> 359 360 </div> 361 362 363 </div> 364 365 366 </section> 367 368 369 <section class="organograma mt-5"> 370 371 <h2 class="text-center fw-bold mb-5"> 372 Organograma 373 </h2> 374 375 <div class="text-center mb-4"> 376 377 <button class="btn btn-dark rounded-pill" 378 onclick="imprimirOrganograma()"> 379 380 <i class="fa-solid fa-print"></i> 381 Imprimir Organograma 382 383 </button> 384 385 </div> 386 387 <div class="d-flex justify-content-center gap-2 mb-4"> 388 389 <button class="btn btn-dark" 390 onclick="mostrarMapa()"> 391 392 <i class="fa-solid fa-diagram-project"></i> 393 394 Mapa 395 396 </button> 397 398 <button class="btn btn-outline-dark" 399 onclick="mostrarListaMapa()"> 400 401 <i class="bi bi-list-ul"></i> 402 403 Lista 404 405 </button> 406 407 </div> 408 409 <div id="mapaOrganograma"> 410 411 <div class="org-root"> 412 413 <div class="org-box prefeitura"> 414 <i class="fa-solid fa-building-columns me-2"></i> 415 Prefeitura Municipal de Oliveira Dos Brejinhos 416 </div> 417 418 <div class="linha-vertical"></div> 419 420 <div class="linha-horizontal"></div> 421 422 <div class="org-secretarias" id="mapaSecretarias"></div> 423 424 </div> 425 426 </div> 427 428 <div id="listaOrganograma" style="display:none;"> 429 430 </div> 431 432 433 434 </section> 435 436 </div> 437 438 439 </main> 440 441 <div class="modal fade" id="modalSecretaria" tabindex="-1"> 442 443 <div class="modal-dialog modal-xl modal-dialog-centered"> 444 445 <div class="modal-content border-0 shadow"> 446 447 <div class="modal-header text-white" style="background:#0a28d2"> 448 449 <h5 class="modal-title"> 450 451 Informações da Secretaria 452 453 </h5> 454 455 <button 456 type="button" 457 class="btn-close btn-close-white" 458 data-bs-dismiss="modal"> 459 </button> 460 461 </div> 462 463 <div class="modal-body" id="conteudoSecretaria"> 464 465 </div> 466 467 </div> 468 469 </div> 470 471 </div> 472</div> 473 474 475<style> 476 .estrutura-header { 477 478 background: #fff; 479 480 481 border-radius: 25px; 482 483 } 484 485 486 .estrutura-header h3 { 487 488 letter-spacing: 1px; 489 490 } 491 492 493 494 .norma-card { 495 496 border-left: 6px solid #0a28d2; 497 498 border-radius: 18px; 499 500 } 501 502 .norma-card .badge { 503 504 font-size: 13px; 505 506 } 507 508 .norma-card h4 { 509 510 font-size: 22px; 511 512 } 513 514 515 516 .pesquisa-box { 517 518 box-shadow: 0 5px 20px rgba(0, 0, 0, .08); 519 520 border-radius: 50px; 521 522 overflow: hidden; 523 524 } 525 526 527 .pesquisa-box input { 528 529 border: none; 530 531 height: 55px; 532 533 } 534 535 536 .pesquisa-box .input-group-text { 537 538 background: #fff; 539 540 border: none; 541 542 } 543 544 545 546 547 548 549 @media(max-width:768px) { 550 551 552 .estrutura-header { 553 554 padding: 25px; 555 556 } 557 558 559 .estrutura-header h1 { 560 561 font-size: 28px; 562 563 } 564 565 566 } 567</style> 568 569
570<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
570 571
572<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
572 573
574<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.8.2/jspdf.plugin.autotable.min.js"></script>
vendor: 1 bytes, line 574
574
575<script> 576 window.secretarias = []; 577 578 document.addEventListener("DOMContentLoaded", function() { 579 580 581 582 const lista = document.getElementById("listaSecretarias"); 583 584 const pesquisa = document.getElementById("pesquisaSecretaria"); 585 586 587 if (!lista) { 588 589 console.error("Elemento #listaSecretarias não encontrado"); 590 591 return; 592 593 } 594 595 596 597 fetch("src/Services/secretarias.php") 598 599 600 .then(response => { 601 602 603 if (!response.ok) { 604 605 throw new Error("Erro HTTP: " + response.status); 606 607 } 608 609 610 return response.json(); 611 612 613 }) 614 615 616 .then(data => { 617 618 619 console.log("Secretarias carregadas:", data); 620 621 622 window.secretarias = data; 623 624 625 renderizarSecretarias(secretarias); 626 montarOrganograma(secretarias); 627 montarListaOrganograma(secretarias); 628 629 630 }) 631 632 633 .catch(error => { 634 635 636 console.error("Erro:", error); 637 638 639 lista.innerHTML = ` 640 641 <div class="col-12"> 642 643 <div class="alert alert-danger text-center"> 644 645 Erro ao carregar secretarias. 646 647 </div> 648 649 </div> 650 651 `; 652 653 654 }); 655 656 657 658 659 function renderizarSecretarias(dados) { 660 661 662 lista.innerHTML = ""; 663 664 665 666 if (dados.length === 0) { 667 668 669 lista.innerHTML = ` 670 671 <div class="col-12"> 672 673 <div class="alert alert-warning text-center"> 674 675 Nenhuma secretaria encontrada. 676 677 </div> 678 679 </div> 680 681 `; 682 683 684 return; 685 686 } 687 688 689 690 691 692 dados.forEach((secretaria, index) => { 693 694 695 let collapseId = "secretaria_" + index; 696 697 698 699 let foto = secretaria.foto && secretaria.foto.trim() !== "" 700 701 ? 702 "uploads/secretarias/" + secretaria.foto 703 704 : 705 "uploads/secretarias/sem-imagem.jpg"; 706 707 708 709 710 711 let card = ` 712 713 <div class="col-xl-4 col-lg-6 col-md-6 mb-4"> 714 715 <div class="card card-secretaria h-100"> 716 717 <div class="card-body text-center"> 718 719 <img 720 src="uploads/secretarias/${secretaria.foto}" 721 class="foto-secretaria" 722 loading="lazy" 723 alt="${secretaria.nome}" 724 onerror="this.onerror=null;this.src='uploads/secretarias/sem-foto.png';"> 725 726 <h4 class="mt-3 fw-bold" style="color:#0a28d2;"> 727 728 ${secretaria.nome} 729 730 </h4> 731 732 733 <hr> 734 <p class="competencias"> 735 <small class="text-start d-block text-uppercase fw-bold"><i class="fa-solid fa-folder-tree" ></i> Competências</small> 736 737 ${limitarTexto(secretaria.competencias, 120)} 738 739 </p> 740 741 <div class="mt-4"> 742 743 <a 744 href="secretaria?id=${secretaria.id}" 745 class="btn btn-primary w-100 rounded-pill"> 746 747 <i class="bi bi-arrow-right"></i> 748 749 Ver informações 750 751 </a> 752 753 </div> 754 755 </div> 756 757 </div> 758 759 </div> 760 761 762 `; 763 764 765 766 lista.insertAdjacentHTML('beforeend', card); 767 768 769 770 }); 771 772 773 774 if (typeof feather !== "undefined") { 775 776 feather.replace(); 777 778 } 779 780 781 782 } 783 784 785 786 if (pesquisa) { 787 788 789 pesquisa.addEventListener("keyup", function() { 790 791 792 793 let termo = this.value.toLowerCase(); 794 795 796 797 798 let filtradas = secretarias.filter(sec => { 799 800 801 802 let nome = (sec.nome || '').toLowerCase(); 803 804 let responsavel = (sec.responsavel || '').toLowerCase(); 805 806 let telefone = (sec.telefone || '').toLowerCase(); 807 808 809 810 return ( 811 812 nome.includes(termo) 813 814 || 815 816 responsavel.includes(termo) 817 818 || 819 820 telefone.includes(termo) 821 822 ); 823 824 825 826 }); 827 828 829 830 831 renderizarSecretarias(filtradas); 832 833 834 835 }); 836 837 838 839 } 840 841 842 843 }); 844 845 function limitarTexto(texto, limite = 120) { 846 847 if (!texto) return "Não informado"; 848 849 // Remove tags HTML 850 texto = texto.replace(/<[^>]*>/g, ""); 851 852 if (texto.length <= limite) { 853 return texto; 854 } 855 856 return texto.substring(0, limite) + "..."; 857 } 858 859 860 861 function montarOrganograma(secretarias) { 862 863 let mapa = document.getElementById("mapaSecretarias"); 864 865 mapa.innerHTML = ""; 866 867 secretarias.forEach(sec => { 868 869 mapa.innerHTML += ` 870 871 <div class="secretaria-box"> 872 873 <div class="secretaria-card" 874 875 onclick="abrirSecretaria(${sec.id})" 876 877 style="cursor:pointer;"> 878 879 <i class="fa-solid fa-building me-2"></i> 880 881 <h6 class="fw-bold mb-0"> 882 883 ${sec.nome} 884 885 </h6> 886 887 </div> 888 889 </div> 890 891 `; 892 893 }); 894 895 } 896 897 function montarListaOrganograma(secretarias) { 898 899 let html = ` 900 901 <div class="org-lista container"> 902 903 <div class="prefeitura-lista"> 904 905 <i class="fa-solid fa-building-columns"></i> 906 907 Prefeitura Municipal de Oliveira Dos Brejinhos 908 909 </div> 910 911 `; 912 913 secretarias.forEach(sec => { 914 915 html += ` 916 917 <div class="secretaria-lista" onclick="abrirSecretaria(${sec.id})"> 918 919 <i class="fa-solid fa-building me-2"></i> 920 921 ${sec.nome} 922 923 </div> 924 925 `; 926 927 }); 928 929 html += "</div>"; 930 931 document.getElementById("listaOrganograma").innerHTML = html; 932 933 } 934 935 936 function mostrarMapa() { 937 938 mapaOrganograma.style.display = "block"; 939 940 listaOrganograma.style.display = "none"; 941 942 } 943 944 function mostrarListaMapa() { 945 946 mapaOrganograma.style.display = "none"; 947 948 listaOrganograma.style.display = "block"; 949 950 } 951 952 953 954 const total = secretarias.length; 955
956 let colunas = 4; 957 958 if (total <= 4) { 959 960 colunas = total; 961 962 } else if (total <= 8) { 963 964 colunas = 4; 965 966 } else if (total <= 16) { 967 968 colunas = 5; 969 970 } else { 971 972 colunas = 6; 973 974 } 975 976 document.documentElement.style.setProperty( 977 "--colunas-org", 978 colunas 979 ); 980 981 982 function abrirSecretaria(id) { 983 984 let secretaria = secretarias.find(s => s.id == id); 985 986 if (!secretaria) return; 987 988 let foto = secretaria.foto && secretaria.foto != "" ? 989 "uploads/secretarias/" + secretaria.foto : 990 "uploads/secretarias/sem-foto.png"; 991 992 document.getElementById("conteudoSecretaria").innerHTML = ` 993 994 <div class="text-center"> 995 996 <img 997 998 src="${foto}" 999 1000 class="rounded-circle shadow" 1001 1002 style="width:170px;height:170px;object-fit:cover" 1003 1004 onerror="this.src='uploads/secretarias/sem-foto.png'"> 1005 1006 <h3 class="mt-4 fw-bold"> 1007 1008 ${secretaria.nome} 1009 1010 </h3> 1011 1012 <h5 class="text-muted"> 1013 1014 ${secretaria.responsavel || "-"} 1015 1016 </h5> 1017 1018 </div> 1019 1020 <hr> 1021 1022 <div class="row"> 1023 1024 <div class="col-md-6"> 1025 1026 <p class="fw-normal"> 1027 1028 <strong>Telefone</strong><br> 1029 1030 ${secretaria.telefone || "Não informado"} 1031 1032 </p> 1033 1034 </div> 1035 1036 <div class="col-md-6"> 1037 1038 <p class="fw-normal"> 1039 1040 <strong>Email</strong><br> 1041 1042 ${secretaria.email || "Não informado"} 1043 1044 </p> 1045 1046 </div> 1047 1048 <div class="col-md-6"> 1049 1050 <p class="fw-normal"> 1051 1052 <strong>Endereço</strong><br> 1053 1054 ${secretaria.endereco || "Não informado"} 1055 1056 </p> 1057 1058 </div> 1059 1060 <div class="col-md-6"> 1061 1062 <p class="fw-normal"> 1063 1064 <strong>Horário</strong><br> 1065 1066 ${secretaria.hora || "Não informado"} 1067 1068 </p> 1069 1070 </div> 1071 1072 </div> 1073 1074 <hr> 1075 1076 <h5 class="fw-bold text-uppercase"> 1077 1078 Competências 1079 1080 </h5> 1081 1082 <div class="p-3 rounded bg-light fw-normal"> 1083 1084 ${secretaria.competencias || "Não informado"} 1085 1086 </div> 1087 1088 <div class="mt-4 text-end"> 1089 1090 <a 1091 1092 href="secretaria?id=${secretaria.id}" 1093 1094 class="btn btn-primary"> 1095 1096 Ver página completa 1097 1098 </a> 1099 1100 </div> 1101 1102 `; 1103 1104 new bootstrap.Modal( 1105 document.getElementById("modalSecretaria") 1106 ).show(); 1107 1108 } 1109 1110 1111 1112 function imprimirOrganograma() { 1113 1114 1115 let area = document.getElementById("mapaOrganograma"); 1116 1117 1118 if (!area) { 1119 1120 alert("Organograma não encontrado."); 1121 1122 return; 1123 1124 } 1125 1126 1127 let conteudo = area.innerHTML; 1128 1129 1130 1131 let janela = 1132 window.open("", "", "width=1000,height=700"); 1133 1134 1135 1136 janela.document.write(` 1137 1138<html> 1139 1140<head> 1141 1142<title>Organograma</title> 1143 1144 1145<style> 1146 1147 1148body{ 1149 1150font-family:Arial; 1151 1152text-align:center; 1153 1154} 1155 1156 1157 1158.org-root{ 1159 1160display:flex; 1161 1162flex-direction:column; 1163 1164align-items:center; 1165 1166} 1167 1168 1169 1170.org-secretarias{ 1171 1172display:flex; 1173 1174flex-wrap:wrap; 1175 1176justify-content:center; 1177 1178gap:20px; 1179 1180} 1181 1182 1183 1184.org-box, 1185.secretaria-card{ 1186 1187border:1px solid #ccc; 1188 1189padding:20px; 1190 1191margin:10px; 1192 1193border-radius:10px; 1194 1195font-weight:bold; 1196 1197} 1198 1199 1200 1201.linha-vertical{ 1202 1203height:40px; 1204 1205width:3px; 1206 1207background:#0a28d2; 1208 1209} 1210 1211 1212 1213.linha-horizontal{ 1214 1215height:3px; 1216 1217width:80%; 1218 1219background:#0a28d2; 1220 1221} 1222 1223 1224 1225</style> 1226 1227 1228</head> 1229 1230 1231<body> 1232 1233 1234<h2> 1235Organograma Administrativo 1236</h2> 1237 1238 1239<h3> 1240Prefeitura Municipal de Oliveira Dos Brejinhos 1241</h3> 1242 1243 1244${conteudo} 1245 1246 1247</body> 1248 1249 1250</html> 1251 1252`); 1253 1254 1255 1256 janela.document.close(); 1257 1258 1259 setTimeout(() => { 1260 1261 janela.print(); 1262 1263 }, 500); 1264 1265 1266 } 1267 1268 1269 function exportarJSON() { 1270 1271 1272 let arquivo = JSON.stringify( 1273 window.secretarias, 1274 null, 1275 4 1276 ); 1277 1278 1279 baixarArquivo( 1280 arquivo, 1281 "secretarias.json", 1282 "application/json" 1283 ); 1284 1285 } 1286 1287 1288 1289 function exportarCSV() { 1290 1291 1292 let linhas = []; 1293 1294 linhas.push( 1295 "Secretaria;Responsável;Telefone;Email;Endereço;Horário;Competências" 1296 ); 1297 1298 1299 window.secretarias.forEach(sec => { 1300 1301 1302 linhas.push([ 1303 1304 sec.nome, 1305 sec.responsavel, 1306 sec.telefone, 1307 sec.email, 1308 sec.endereco, 1309 sec.hora, 1310 limitarTexto(sec.competencias, 500) 1311 1312 ].join(";")); 1313 1314 1315 }); 1316 1317 1318 baixarArquivo( 1319 linhas.join("\n"), 1320 "secretarias.csv", 1321 "text/csv;charset=utf-8" 1322 ); 1323 1324 1325 } 1326 1327 1328 1329 function exportarXLSX() { 1330 1331 1332 let dados = window.secretarias.map(sec => { 1333 1334 1335 return { 1336 1337 "Secretaria": sec.nome, 1338 1339 "Responsável": sec.responsavel, 1340 1341 "Telefone": sec.telefone, 1342 1343 "Email": sec.email, 1344 1345 "Endereço": sec.endereco, 1346 1347 "Horário": sec.hora, 1348 1349 "Competências": sec.competencias 1350 1351 1352 }; 1353 1354 1355 }); 1356 1357 1358 let planilha = 1359 XLSX.utils.json_to_sheet(dados); 1360 1361 1362 let livro = 1363 XLSX.utils.book_new(); 1364 1365 1366 XLSX.utils.book_append_sheet( 1367 livro, 1368 planilha, 1369 "Secretarias" 1370 ); 1371 1372 1373 XLSX.writeFile( 1374 livro, 1375 "secretarias.xlsx" 1376 ); 1377 1378 1379 } 1380 1381 1382 1383 function exportarTXT() { 1384 1385 1386 let texto = "ESTRUTURA ORGANIZACIONAL\n\n"; 1387 1388 1389 window.secretarias.forEach((sec, index) => { 1390 1391 1392 texto += ` 1393${index+1} - ${sec.nome} 1394 1395Responsável: 1396${sec.responsavel} 1397 1398Telefone: 1399${sec.telefone} 1400
1401Email: 1402${sec.email} 1403 1404Endereço: 1405${sec.endereco} 1406 1407Horário: 1408${sec.hora} 1409 1410Competências: 1411${sec.competencias} 1412 1413 1414-------------------------------- 1415 1416`; 1417 1418 1419 }); 1420 1421 1422 baixarArquivo( 1423 texto, 1424 "secretarias.txt", 1425 "text/plain" 1426 ); 1427 1428 1429 } 1430 1431 1432 function exportarPDF() { 1433 1434 1435 const { 1436 jsPDF 1437 } = window.jspdf; 1438 1439 1440 let pdf = new jsPDF( 1441 'landscape' 1442 ); 1443 1444 1445 pdf.setFontSize(16); 1446 1447 pdf.text( 1448 "Estrutura Organizacional - Secretarias", 1449 15, 1450 15 1451 ); 1452 1453 1454 1455 let dados = []; 1456 1457 1458 window.secretarias.forEach(sec => { 1459 1460 1461 dados.push([ 1462 1463 sec.nome, 1464 1465 sec.responsavel, 1466 1467 sec.telefone, 1468 1469 sec.email, 1470 1471 sec.endereco 1472 1473 ]); 1474 1475 1476 }); 1477 1478 1479 1480 pdf.autoTable({ 1481 1482 startY: 25, 1483 1484 head: [ 1485 [ 1486 "Secretaria", 1487 "Responsável", 1488 "Telefone", 1489 "Email", 1490 "Endereço" 1491 ] 1492 ], 1493 1494 body: dados, 1495 1496 styles: { 1497 fontSize: 8 1498 } 1499 1500 }); 1501 1502 1503 1504 pdf.save( 1505 "secretarias.pdf" 1506 ); 1507 1508 1509 1510 } 1511 1512 1513 function baixarArquivo(conteudo, nome, tipo) { 1514 1515 1516 let blob = new Blob( 1517 [conteudo], { 1518 type: tipo 1519 } 1520 ); 1521 1522 1523 let url = 1524 URL.createObjectURL(blob); 1525 1526 1527 let link = 1528 document.createElement("a"); 1529 1530 1531 link.href = url; 1532 1533 link.download = nome; 1534 1535 1536 document.body.appendChild(link); 1537 1538 1539 link.click(); 1540 1541 1542 document.body.removeChild(link); 1543 1544 1545 URL.revokeObjectURL(url); 1546 1547 1548 } 1549</script>
1549 1550 1551<style> 1552 .card-secretaria { 1553 1554 1555 1556 border-radius: 22px; 1557 1558 background: #fff; 1559 1560 overflow: hidden; 1561 1562 transition: .25s ease; 1563 1564 } 1565 1566 1567 1568 .card-secretaria:hover { 1569 1570 transform: translateY(-5px); 1571 1572 box-shadow: 0 15px 35px rgba(0, 0, 0, .12) !important; 1573 1574 } 1575 1576 1577 1578 .foto-secretaria { 1579 1580 width: 140px; 1581 1582 height: 140px; 1583 1584 object-fit: cover; 1585 1586 border-radius: 50%; 1587 1588 border: 6px solid #f1f5ff; 1589 1590 margin-top: 15px; 1591 1592 } 1593 1594 1595 1596 .sem-foto { 1597 1598 width: 140px; 1599 1600 height: 140px; 1601 1602 border-radius: 50%; 1603 1604 background: #f1f3f5; 1605 1606 display: flex; 1607 1608 align-items: center; 1609 1610 justify-content: center; 1611 1612 margin: 15px auto; 1613 1614 color: #6c757d; 1615 1616 } 1617 1618 1619 1620 .sem-foto svg { 1621 1622 width: 50px; 1623 1624 height: 50px; 1625 1626 } 1627 1628 1629 1630 .competencias { 1631 text-align: justify; 1632 font-weight: normal; 1633 } 1634 1635 1636 .card-secretaria h4 { 1637 1638 font-size: 20px; 1639 1640 line-height: 1.3; 1641 1642 min-height: 55px; 1643 1644 } 1645 1646 1647 1648 .responsavel { 1649 1650 color: #555; 1651 1652 font-size: 15px; 1653 1654 font-weight: 600; 1655 1656 } 1657 1658 1659 1660 .responsavel svg { 1661 1662 width: 16px; 1663 1664 vertical-align: middle; 1665 1666 margin-right: 5px; 1667 1668 } 1669 1670 1671 .dados-resumo { 1672 1673 color: #666; 1674 1675 font-size: 14px; 1676 1677 } 1678 1679 1680 1681 .dados-resumo p { 1682 1683 margin-bottom: 8px; 1684 1685 } 1686 1687 1688 1689 .dados-resumo svg { 1690 1691 width: 15px; 1692 1693 margin-right: 5px; 1694 1695 } 1696 1697 1698 .card-secretaria .btn { 1699 1700 font-weight: 600; 1701 1702 padding: 10px 25px; 1703 1704 } 1705 1706 1707 1708 .card-secretaria .btn svg { 1709 1710 width: 16px; 1711 1712 margin-left: 5px; 1713 1714 } 1715 1716 1717 .secretaria-item { 1718 1719 animation: aparecer .3s ease; 1720 1721 } 1722 1723 1724 1725 @keyframes aparecer { 1726 1727 from { 1728 1729 opacity: 0; 1730 1731 transform: translateY(10px); 1732 1733 } 1734 1735 1736 to { 1737 1738 opacity: 1; 1739 1740 transform: translateY(0); 1741 1742 } 1743 1744 } 1745 1746 1747 @media(max-width:576px) { 1748 1749 1750 .foto-secretaria { 1751 1752 width: 110px; 1753 1754 height: 110px; 1755 1756 } 1757 1758 1759 .card-secretaria h4 { 1760 1761 font-size: 18px; 1762 1763 } 1764 1765 1766 } 1767 1768 .organograma { 1769 padding: 60px 0; 1770 } 1771 1772 .org-root { 1773 display: flex; 1774 flex-direction: column; 1775 align-items: center; 1776 } 1777 1778 .org-box { 1779 1780 background: #fff; 1781 1782 border-radius: 12px; 1783 1784 padding: 18px 25px; 1785 1786 box-shadow: 0 5px 15px rgba(0, 0, 0, .08); 1787 1788 border-top: 5px solid #0a28d2; 1789 1790 font-weight: bold; 1791 1792 text-align: center; 1793 1794 min-width: 250px; 1795 1796 } 1797 1798 .prefeitura { 1799 1800 1801 color: #000; 1802 1803 } 1804 1805 .linha-vertical { 1806 1807 width: 3px; 1808 1809 height: 40px; 1810 1811 background: #0a28d2; 1812 1813 } 1814 1815 .linha-horizontal { 1816 1817 width: 85%; 1818 1819 height: 3px; 1820 1821 background: #0a28d2; 1822 1823 margin-bottom: 40px; 1824 1825 } 1826 1827 .org-secretarias { 1828 1829 display: flex; 1830 1831 flex-wrap: wrap; 1832 1833 justify-content: center; 1834 1835 gap: 35px; 1836 1837 width: 100%; 1838 1839 } 1840 1841 .secretaria-box { 1842 1843 width: 260px; 1844 1845 position: relative; 1846 1847 text-align: center; 1848 1849 } 1850 1851 .secretaria-box::before { 1852 1853 content: ""; 1854 1855 position: absolute; 1856 1857 top: -40px; 1858 1859 left: 50%; 1860 1861 width: 3px; 1862 1863 height: 40px; 1864 1865 transform: translateX(-50%); 1866 1867 background: #0a28d2; 1868 1869 } 1870 1871 .secretaria-card { 1872 1873 background: #fff; 1874 1875 border-radius: 15px; 1876 1877 padding: 20px; 1878 1879 box-shadow: 0 5px 15px rgba(0, 0, 0, .08); 1880 1881 transition: .3s; 1882 1883 border-left: 4px solid #0a28d2; 1884 1885 } 1886 1887 .secretaria-card:hover { 1888 1889 transform: translateY(-5px); 1890 1891 } 1892 1893 1894 .prefeitura-lista { 1895 1896 font-size: 22px; 1897 1898 font-weight: bold; 1899 1900 color: #0a28d2; 1901 1902 margin-bottom: 20px; 1903 1904 } 1905 1906 .secretaria-lista { 1907 1908 padding: 14px 20px; 1909 1910 border-left: 4px solid #0a28d2; 1911 1912 margin-bottom: 12px; 1913 1914 background: #fff; 1915 1916 border-radius: 10px; 1917 1918 box-shadow: 0 3px 8px rgba(0, 0, 0, .08); 1919 1920 cursor: pointer; 1921 1922 } 1923</style><!-- Feedback Popup (cole no footer, antes de </body>) --> 1924<style> 1925/* popup base */ 1926#siteFeedbackModal { 1927 position: fixed; 1928 inset: 0; 1929 display: none; 1930 z-index: 1080;
1931 align-items: center; 1932 justify-content: center; 1933 background: rgba(15,15,15,0.45); 1934 backdrop-filter: blur(4px); 1935 animation: fadeIn .18s ease; 1936} 1937@keyframes fadeIn { from {opacity:0} to {opacity:1} } 1938 1939#siteFeedbackCard { 1940 width: 100%; 1941 max-width: 680px; 1942 border-radius: 14px; 1943 background: #fff; 1944 box-shadow: 0 10px 30px rgba(0,0,0,0.18); 1945 transform: translateY(10px); 1946 animation: popIn .25s cubic-bezier(.2,.9,.2,1); 1947} 1948@keyframes popIn { from {opacity:0; transform:translateY(20px) scale(.98)} to {opacity:1; transform:translateY(0) scale(1)} } 1949 1950.sf-header { 1951 padding: 18px 22px; 1952 border-bottom: 1px solid #f1f1f1; 1953 display:flex; align-items:center; gap:12px; 1954} 1955.sf-body { padding: 20px 22px; } 1956.sf-footer { padding: 14px 22px; border-top:1px solid #f6f6f6; display:flex; justify-content:space-between; align-items:center; gap:12px; } 1957 1958/* stars */ 1959.sf-stars { display:flex; gap:6px; align-items:center; } 1960.sf-star { 1961 font-size: 32px; 1962 cursor: pointer; 1963 transition: transform .12s ease, color .12s ease; 1964 color: #dcdcdc; 1965 user-select:none; 1966} 1967.sf-star:hover { transform: translateY(-3px) scale(1.08); } 1968 1969/* rating text */ 1970.sf-rating-text { font-size:14px; color:#666; margin-left:8px; } 1971 1972/* textarea */ 1973.sf-text { 1974 width:100%; 1975 min-height:90px; 1976 resize:vertical; 1977 padding:10px 12px; 1978 border-radius:8px; 1979 border:1px solid #e6e6e6; 1980 font-size:14px; 1981} 1982 1983/* compact checkbox */ 1984.sf-bottom-left { display:flex; align-items:center; gap:8px; font-size:13px; color:#666; } 1985 1986/* primary btn */ 1987.sf-send { 1988 background: linear-gradient(90deg,#16a34a,#10b981); /* green gradient */ 1989 color:#fff; 1990 border:0; 1991 padding:9px 18px; 1992 border-radius:10px; 1993 box-shadow: 0 6px 18px rgba(16,185,129,0.18); 1994} 1995 1996/* success */ 1997.sf-success { 1998 display:none; 1999 padding:18px; 2000 text-align:center; 2001 color:#064e3b; 2002} 2003 2004/* small responsive tweak */ 2005@media (max-width:576px){ 2006 #siteFeedbackCard { margin: 20px; } 2007 .sf-star { font-size:28px; } 2008} 2009</style> 2010 2011<!-- Modal markup --> 2012<!---<div id="siteFeedbackModal" aria-hidden="true" role="dialog" aria-labelledby="sfTitle" aria-modal="true"> 2013 <div id="siteFeedbackCard" role="document"> 2014 <div class="sf-header"> 2015 <div style="width:46px;height:46px;background:linear-gradient(135deg,#06b6d4,#7c3aed);border-radius:10px;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700">BD</div> 2016 <div> 2017 <h5 id="sfTitle" style="margin:0">O que está achando do site?</h5> 2018 <small style="color:#666">Sua opinião ajuda a melhorar â leva só 10 segundos</small> 2019 </div> 2020 <button type="button" class="btn-close ms-auto me-2" aria-label="Fechar" id="sfCloseBtn"></button> 2021 </div> 2022 2023 <div class="sf-body"> 2024 <div style="display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px"> 2025 <div class="sf-stars" id="sfStars" role="radiogroup" aria-label="Avaliação em estrelas"> 2026 </div> 2027 <div class="sf-rating-text" id="sfRatingText">Selecione uma nota</div> 2028 </div> 2029 2030 <textarea id="sfText" class="sf-text" placeholder="Deixe um comentário (opcional) â o que você gostou? o que podemos melhorar?"></textarea> 2031 </div> 2032 2033 <div class="sf-footer"> 2034 <div class="sf-bottom-left"> 2035 <input type="checkbox" id="sfDontShow" /> 2036 <label for="sfDontShow">Não mostrar novamente</label> 2037 </div> 2038 <div style="display:flex;gap:10px;align-items:center"> 2039 <button class="btn btn-outline-secondary" id="sfSkipBtn">Agora não</button> 2040 <button class="sf-send" id="sfSubmitBtn">Enviar feedback</button> 2041 </div> 2042 </div> 2043 2044 <div class="sf-success" id="sfSuccess"> 2045 <p style="margin:0;font-weight:700">Obrigado pelo feedback!</p> 2046 <p style="margin:6px 0 0;color:#065f46">Sua opinião foi enviada com sucesso.</p> 2047 </div> 2048 </div> 2049</div> 2050
2051<script> 2052(function(){ 2053 // --- Config --- 2054 const delayMs = 6000; // tempo até abrir (ms) 2055 const endpoint = 'src/Services/feedback.php'; // ajuste se necessário 2056 const storageKey = 'brejolandia_feedback_dontshow'; 2057 2058 // --- DOM refs --- 2059 const modal = document.getElementById('siteFeedbackModal'); 2060 const starsWrap = document.getElementById('sfStars'); 2061 const ratingText = document.getElementById('sfRatingText'); 2062 const textEl = document.getElementById('sfText'); 2063 const dontShowEl = document.getElementById('sfDontShow'); 2064 const closeBtn = document.getElementById('sfCloseBtn'); 2065 const skipBtn = document.getElementById('sfSkipBtn'); 2066 const submitBtn = document.getElementById('sfSubmitBtn'); 2067 const successBox = document.getElementById('sfSuccess'); 2068 2069 let currentRating = 0; 2070 2071 // star labels (you can change) 2072 const ratingLabels = { 2073 1: 'Péssimo', 2074 2: 'Ruim', 2075 3: 'Regular', 2076 4: 'Bom', 2077 5: 'Ãtimo' 2078 }; 2079 2080 // create star elements 2081 for (let i=1;i<=5;i++){ 2082 const span = document.createElement('span'); 2083 span.className = 'sf-star'; 2084 span.setAttribute('data-value', i); 2085 span.setAttribute('role','radio'); 2086 span.setAttribute('aria-checked','false'); 2087 span.setAttribute('tabindex', '0'); 2088 span.innerHTML = 'â '; // star glyph 2089 // events 2090 span.addEventListener('mouseenter', ()=> highlight(i)); 2091 span.addEventListener('mouseleave', ()=> highlight(currentRating)); 2092 span.addEventListener('click', ()=> setRating(i)); 2093 span.addEventListener('keydown', (ev)=> { 2094 if (ev.key === 'Enter' || ev.key === ' ') { ev.preventDefault(); setRating(i); } 2095 if (ev.key === 'ArrowRight' && i < 5) { document.querySelector('[data-value="'+(i+1)+'"]').focus(); } 2096 if (ev.key === 'ArrowLeft' && i > 1) { document.querySelector('[data-value="'+(i-1)+'"]').focus(); } 2097 }); 2098 starsWrap.appendChild(span); 2099 } 2100 2101 function highlight(n){ 2102 const stars = starsWrap.querySelectorAll('.sf-star'); 2103 stars.forEach(s => { 2104 const v = parseInt(s.getAttribute('data-value'),10); 2105 s.style.color = (v <= n) ? '#f59e0b' : '#dcdcdc'; 2106 }); 2107 ratingText.textContent = n ? ratingLabels[n] : 'Selecione uma nota'; 2108 } 2109 2110 function setRating(n){ 2111 currentRating = n; 2112 highlight(n); 2113 // set aria-checked 2114 starsWrap.querySelectorAll('.sf-star').forEach(s => { 2115 s.setAttribute('aria-checked', parseInt(s.getAttribute('data-value'),10) === n ? 'true' : 'false'); 2116 }); 2117 } 2118 2119 // open modal 2120 function openModal(){ 2121 // don't open if user opted out 2122 if (localStorage.getItem(storageKey) === '1') return; 2123 modal.style.display = 'flex'; 2124 modal.setAttribute('aria-hidden','false'); 2125 // focus first star 2126 const firstStar = modal.querySelector('.sf-star'); 2127 if (firstStar) firstStar.focus(); 2128 } 2129 2130 // close 2131 function closeModal(){ 2132 modal.style.display = 'none'; 2133 modal.setAttribute('aria-hidden','true'); 2134 } 2135 2136 // submit 2137 async function submitFeedback(){ 2138 if (!currentRating) { 2139 // small feedback if not rated 2140 ratingText.textContent = 'Por favor, escolha uma nota antes de enviar.'; 2141 ratingText.style.color = '#b91c1c'; 2142 setTimeout(()=> ratingText.style.color = '', 2200); 2143 return; 2144 } 2145 2146 submitBtn.disabled = true; 2147 submitBtn.textContent = 'Enviando...'; 2148 2149 const payload = { 2150 pagina: window.location.pathname, 2151 nota: currentRating, 2152 comentario: textEl.value.trim() 2153 }; 2154 2155 try { 2156 const res = await fetch(endpoint, { 2157 method: 'POST', 2158 headers: {'Content-Type':'application/json'}, 2159 body: JSON.stringify(payload) 2160 }); 2161 2162 if (!res.ok) throw new Error('Erro na rede'); 2163 2164 const data = await res.json(); 2165 if (data && data.success) { 2166 // show success and optionally store "dont show" if checked 2167 successBox.style.display = 'block'; 2168 modal.querySelector('.sf-body, .sf-footer, .sf-header').style.display = 'none'; 2169 if (dontShowEl.checked) localStorage.setItem(storageKey,'1'); 2170 setTimeout(closeModal, 2000); 2171 } else { 2172 throw new Error(data.message || 'Erro desconhecido'); 2173 } 2174 } catch (err) { 2175 alert('Erro ao enviar feedback: ' + (err.message||err));
2176 submitBtn.disabled = false; 2177 submitBtn.textContent = 'Enviar feedback'; 2178 } 2179 } 2180 2181 // events 2182 closeBtn.addEventListener('click', closeModal); 2183 skipBtn.addEventListener('click', closeModal); 2184 submitBtn.addEventListener('click', submitFeedback); 2185 2186 // close on background click 2187 modal.addEventListener('click', (e)=>{ 2188 if (e.target === modal) closeModal(); 2189 }); 2190 2191 // open after delay 2192 window.addEventListener('load', ()=>{ 2193 setTimeout(openModal, delayMs); 2194 }); 2195 2196})(); 2197</script>
2197--> 2198 2199<footer class="bg-sb text-white pt-5 pb-4"> 2200 <div class="container"> 2201 <div class="row"> 2202 2203 <!-- COLUNA ESQUERDA: LOGO + REDES + SERVIÃOS + GOVERNO --> 2204 <div class="col-md-6"> 2205 <div class="row"> 2206 2207 <!-- LOGO + REDES SOCIAIS --> 2208 <div class="col-md-6 mb-4" style="margin-left: -30px;"> 2209 <img src="public/images/logo/logofo.png" alt="Logo Prefeitura" width="130px"> 2210 <h5 class="mb-4 mt-4 mt-3">Redes sociais</h5> 2211 <a href="#" class="text-warning mr-3"><i class="fab fa-facebook fa-lg"></i></a> 2212 <a href="#" class="text-warning mr-3"><i class="fab fa-instagram fa-lg"></i></a> 2213 <a href="#" class="text-warning"><i class="fab fa-youtube fa-lg"></i></a> 2214 </div> 2215 2216 <!-- SERVIÃOS AO CIDADÃO + GOVERNO --> 2217 <div class="col-md-6 mb-4"> 2218 <h6 class="text-warning font-weight-bold">Serviços<br>ao Cidadão</h6> 2219 <ul class="list-unstyled mt-3"> 2220 <li><a href="#" class="text-white">Emissão de Certidão Negativa</a></li> 2221 <li><a href="#" class="text-white">Emissão de Nota Fiscal</a></li> 2222 <li><a href="#" class="text-white">Emissão de Guias IPTU</a></li> 2223 </ul> 2224 2225 <h6 class="text-warning font-weight-bold mt-4">Estrutura<br>de Governo</h6> 2226 <ul class="list-unstyled mt-3"> 2227 <li><a href="#" class="text-white">Gabinete do Prefeito</a></li> 2228 <li><a href="#" class="text-white">Gabinete do Vice-prefeito</a></li> 2229 <li><a href="#" class="text-white">Estrutura Organizacional</a></li> 2230 </ul> 2231 </div> 2232 2233 </div> 2234 </div> 2235 2236 <!-- COLUNA DIREITA: TRANSPARÃNCIA + OUVIDORIA + CONTATO + LOCALIZAÃÃO --> 2237 <div class="col-md-6"> 2238 <div class="row"> 2239 2240 <!-- TRANSPARÃNCIA + OUVIDORIA --> 2241 <div class="col-md-6 mb-4"> 2242 <h6 class="text-warning font-weight-bold">Portal da<br>Transparência</h6> 2243 <ul class="list-unstyled mt-3"> 2244 <li><a href="#" class="text-white">Licitações</a></li> 2245 <li><a href="https://sobradinho.ba.gov.br/integra_view/contrato.php" class="text-white">Contratos</a></li> 2246 <li><a href="#" class="text-white">Relatório de Gestão Fiscal</a></li><p> 2247 <li><a href="#" class="text-white">Despesas</a></li> 2248 </ul> 2249 2250 <h6 class="text-warning font-weight-bold mt-4">Ouvidoria e<br>Atendimento</h6> 2251 <ul class="list-unstyled mt-3"> 2252 <li><a href="/ouvidoria" class="text-white">Ouvidoria</a></li> 2253 <li><a href="/esic" class="text-white">SIC - Informação</a></li> 2254 <li><a href="/faleconosco" class="text-white">Fale Conosco</a></li> 2255 </ul> 2256 </div> 2257 2258 <!-- CONTATO + LOCALIZAÃÃO (em blocos) --> 2259 <div class="col-md-6 mb-4"> 2260 <!-- Contato --> 2261 <div class="d-flex mb-3" style="min-width: 310px; background-color: #0a28d2; color: #0f2a73; border-radius: 20px 20px 20px 20px; font-family: 'Montserrat', sans-serif; font-weight: 600;"> 2262 <div class="bg-warning d-flex align-items-center justify-content-center px-2 text-center font-weight-bold" 2263 style="writing-mode: vertical-rl; text-orientation: mixed; font-size: 14px; border-radius: 0px 20px 20px 0px; transform: rotate(180deg) !important;">FALE CONOSCO</div> 2264 <div class="p-3"> 2265 2266 <p class="mb-1 text-white ">(77) 9 9849-2915</p> 2267 <p class="mb-1 text-white" style="font-size:0.9rem; word-break: break-word;"> 2268 [email protected] </p> 2269 2270 </div> 2271 </div> 2272 2273 <!-- Localização --> 2274 <div class="d-flex" style="min-width: 310px; background-color: #0a28d2; color: #0f2a73; border-radius: 20px 20px 20px 20px;"> 2275 <div class="bg-warning d-flex align-items-center justify-content-center px-2 text-center font-weight-bold" 2276 style="writing-mode: vertical-rl; text-orientation: mixed; font-size: 14px; border-radius: 0px 20px 20px 0px; transform: rotate(180deg) !important;">LOCALIZAÃÃO</div> 2277 <div class="p-3">
2278 <p class="mb-1 text-white text-justify">Praça João Nery de Sant´ana, nº 197, centro, Oliveira dos Brejinhos - Bahia</p> 2279 <span class="mb-0 text-white text-justify" style="font-size: 0.9rem;">De Segunda a Sextadas 07h à s 13h</span> 2280 </div> 2281 </div> 2282 </div> 2283 2284 </div> 2285 </div> 2286 2287 </div> 2288 2289 <!-- COPYRIGHT --> 2290 <div class="text-center mt-4 pt-2 border-top border-white"> 2291 <small>2025 © Prefeitura Municipal de Oliveira Dos Brejinhos - Ba. Todos os direitos reservados.</small> 2292 </div> 2293 </div> 2294 </footer> 2295 </div> 2296 2297 2298 2299<footer class="font-small pt-4 text-center text-white" style="background-color: #0a28d2;"> 2300 <p><a href="#" class="text-white">Politica de Privacidade</a> <a href="#" class="text-white"> Mapa do Site</a> <a href="#" class="text-white"> Acessibilidade</a> <a href="#" class="text-white"> Glossario</a> <a href="./faleconosco" class="text-white">Contato</a> </p><br> 2301</footer> 2302</footer> 2303 2304<div class="modal fade" id="transparenciaModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> 2305 <div class="modal-dialog modal-fullscreen"> 2306 <div class="modal-content"> 2307 <div class="modal-header"> 2308 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 2309 </div> 2310 <div class="modal-body"> 2311 <!-- Loader --> 2312 <div id="iframeLoader" class="text-center py-5"> 2313 <div class="spinner-border text-primary" role="status"></div> 2314 </div> 2315 <iframe id="modalFrame" width="100%" height="600px" style="border:0; display:none;" onload="hideLoader()"></iframe> 2316 </div> 2317 <div class="modal-footer"> 2318 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fechar</button> 2319 </div> 2320 </div> 2321 </div> 2322</div> 2323 2324 2325<!-- EDITAL-YEAR --> 2326<div class="row"> 2327 <!-- Modal --> 2328 <div class="modal fade" id="editalModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> 2329 <div class="modal-dialog modal-xl" role="document"> 2330 <div class="modal-content"> 2331 <div class="modal-header"> 2332 <button type="button" class="close pr-3" data-dismiss="modal" aria-label="Close" @click="clear()"> 2333 <span aria-hidden="true">×</span> 2334 </button> 2335 </div> 2336 <div class="modal-body"> 2337 2338 Nenhum resultado encontrado. 2339 </div> 2340 <div class="modal-footer"> 2341 <button type="button" class="btn bg-padrao text-light" data-dismiss="modal" @click="getEditalAll()">TODAS</button> 2342 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">FECHAR</button> 2343 </div> 2344 </div> 2345 </div> 2346 </div> 2347</div><!-- row --> 2348<!-- EDITAL-YEAR --> 2349<style> 2350.bg-sb{ 2351 background-color: #0f2a73; 2352} 2353 2354ul{ 2355text-align: left !important; 2356} 2357li{ 2358text-align: left !important; 2359} 2360</style> 2361 2362 2363 2364
2364<script> 2365 let currentUrl = ""; 2366 2367 function hideLoader() { 2368 const loader = document.getElementById("iframeLoader"); 2369 const iframe = document.getElementById("modalFrame"); 2370 loader.style.display = "none"; 2371 iframe.style.display = "block"; 2372 } 2373 2374 function openModal(url) { 2375 const modal = document.getElementById("transparenciaModal"); 2376 const iframe = document.getElementById("modalFrame"); 2377 const loader = document.getElementById("iframeLoader"); 2378 2379 // Mostra loader e esconde iframe 2380 loader.style.display = "block"; 2381 iframe.style.display = "none"; 2382 2383 // Seta a URL apenas se for diferente da anterior 2384 if (url !== currentUrl) { 2385 iframe.src = url; 2386 currentUrl = url; 2387 } 2388 2389 // Cria e abre o modal com Bootstrap 2390 const modalBS = bootstrap.Modal.getOrCreateInstance(modal); 2391 modalBS.show(); 2392 } 2393</script>
2393 2394
2395<script> 2396 // Encontre todos os elementos de menu dropdown 2397 var dropdowns = document.querySelectorAll(".dropdown"); 2398 2399 // Adicione ouvintes de eventos para cada elemento de menu dropdown 2400 dropdowns.forEach(function(dropdown) { 2401 // Abra o dropdown quando o mouse entra 2402 dropdown.addEventListener("mouseenter", function() { 2403 var dropdownContent = this.querySelector(".dropdown-content"); 2404 if (dropdownContent) { 2405 dropdownContent.style.display = "block"; 2406 } 2407 }); 2408 2409 // Feche o dropdown quando o mouse sai 2410 dropdown.addEventListener("mouseleave", function() { 2411 var dropdownContent = this.querySelector(".dropdown-content"); 2412 if (dropdownContent) { 2413 dropdownContent.style.display = "none"; 2414 } 2415 }); 2416 }); 2417</script>
2417 2418 2419 2420<div vw class="enabled"> 2421 <div vw-access-button class="active"></div> 2422 <div vw-plugin-wrapper> 2423 <div class="vw-plugin-top-wrapper"></div> 2424 </div> 2425</div>
2426<script src="https://vlibras.gov.br/app/vlibras-plugin.js"></script>
vendor: 2 bytes, line 2426
2426
2427<script> 2428 new window.VLibras.Widget('https://vlibras.gov.br/app'); 2429</script>
2429 2430</div>
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.