PageSourceSearch

https://oliveiradosbrejinhos.ba.gov.br/organograma

html oliveiradosbrejinhos.ba.gov.br collected 2026-10-02 22:55:39 UTC 59,773 bytes, 2,430 lines download raw bytes

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                  &nbsp;
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                  &nbsp;
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">&nbsp;Mapa do Site</a> <a href="#" class="text-white">&nbsp;Acessibilidade</a> <a href="#" class="text-white">&nbsp;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">&times;</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.