diff --git a/lgbtq_connect.zip b/lgbtq_connect.zip index be068fc1..e29ffc2a 100644 Binary files a/lgbtq_connect.zip and b/lgbtq_connect.zip differ diff --git a/lgbtq_connect/includes/admin/admin_script.js b/lgbtq_connect/includes/admin/admin_script.js index cd60680e..257014c0 100644 --- a/lgbtq_connect/includes/admin/admin_script.js +++ b/lgbtq_connect/includes/admin/admin_script.js @@ -2,39 +2,21 @@ let mapAdmin; let mapEdit; let isSearching = false; +const ajaxUrl = my_ajax_object.ajax_url; + class Filtro { - static status = "Todos"; + static status = "Pendente"; static nome = ""; static servico = ""; - static realizarFiltragem(arr) { - const self = this; - return arr.filter(function (formulario) { - return (self.checarStatus(formulario) && self.checarNome(formulario) && self.checarServico(formulario)); - }); - } - static checarStatus(formulario) { - if (this.status !== "Todos") { - return (this.status == formulario.situacao); - } else { - return true; - } - } - - static checarNome(formulario) { - return (formulario.nome.toLowerCase().trim().startsWith(this.nome.toLowerCase().trim())); + static preencherQuery(dados) { + dados['status'] = this.status; + dados['nome'] = this.nome; + dados['servico'] = this.servico; } - - static checarServico(formulario) { - if (this.servico !== "") { - return (this.servico == formulario.servico); - } else { - return true; - } - } - + static reiniciarFiltro() { - this.status = "Todos"; + this.status = ""; this.nome = ""; this.servico = ""; } @@ -44,14 +26,120 @@ class Ordenador { static coluna = "nome"; static ordem = "asc"; - static realizarOrdenacao(arr) { + static preencherQuery(dados) { + dados['coluna'] = this.coluna; + dados['ordem'] = this.ordem; + } +} + +class Paginacao { + static pagina=1; + static max_paginas=20; + + static preencherQuery(dados) { + dados['pagina'] = this.pagina; + } + + static mudarMaxPaginas(n) { + this.max_paginas = n; + this.mudarPagina(1); + } + + static mudarPagina(n) { + if(n >= 1 && n <= this.max_paginas) + this.pagina = n; + } + + static gerarIndices(el) { + this.criarSeta(el, "voltar"); + let grande = this.max_paginas >= 7; + + let paginas = this.max_paginas; + if(grande) + paginas = 3; + + for(let i=1; i<=paginas; i++) { + this.criarIndice(i, el); + if(grande && this.pagina===paginas && i==this.pagina) + this.criarIndice(i+1, el); + } + + if(grande) { + this.criarReticencias(el); + + if(this.pagina > 3 && this.pagina < (this.max_paginas - 2)) { + if(this.pagina -1 > 3) + this.criarIndice(this.pagina-1, el) + + this.criarIndice(this.pagina, el); + + if(this.pagina+1 < (this.max_paginas-2)) + this.criarIndice(this.pagina+1, el) + + this.criarReticencias(el); + } + + for(let i=this.max_paginas-2; i<=this.max_paginas; i++) { + if(grande && this.pagina==(this.max_paginas-2) && i==this.pagina) + this.criarIndice(i-1, el); + this.criarIndice(i, el); + } + } + + this.criarSeta(el, "avancar"); + } + + static criarSeta(el, tipo) { const self = this; - return arr.sort(function (a, b) { - const aValue = a[self.coluna].trim().toLowerCase(); - const bValue = b[self.coluna].trim().toLowerCase(); + let liEl = document.createElement('li'); + let aEl = document.createElement('a'); + + let p; + let simbolo; + if(tipo==="voltar") { + p=-1; + simbolo = "«"; + } + else if(tipo==="avancar") { + p=1; + simbolo = "»"; + } + else + return; - return (self.ordem === 'asc') ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue); - }); + aEl.href = "#"; + aEl.onclick = function() { mudarPagina(self.pagina+p) }; + aEl.classList.add("paginacao-seta"); + aEl.innerHTML = simbolo; + + liEl.appendChild(aEl); + el.appendChild(liEl); + } + + static criarIndice(i, el) { + let liEl = document.createElement('li'); + let aEl = document.createElement('a'); + + aEl.href = "#"; + aEl.onclick = function() { mudarPagina(i) }; + aEl.id = `pagina-${i}`; + aEl.innerHTML = `${i}`; + + if(i==this.pagina) + aEl.classList.add("pagina-selecionada"); + + liEl.appendChild(aEl); + el.appendChild(liEl); + } + + static criarReticencias(el) { + let dotEl = document.createElement('li'); + dotEl.innerHTML = "..." + el.appendChild(dotEl); + } + + static excluirIndices(el) { + el.innerHTML = ""; } } @@ -163,8 +251,8 @@ class Tabela { } function destacarLinhaTabela(id) { - let tabela = document.getElementById("tabela"); - let linha = document.getElementById(("formulario-" + id)); + const tabela = document.getElementById("tabela"); + const linha = document.getElementById(("formulario-" + id)); if (linha === null) { return; @@ -446,7 +534,7 @@ function abrirModalEdicao(dados) { document.addEventListener('DOMContentLoaded', adicionarListenerFormulario); document.addEventListener('DOMContentLoaded', function() { - var btnPendente = document.getElementById('botao_inicial'); + const btnPendente = document.getElementById('botao_inicial'); if (btnPendente) { btnPendente.click(); } @@ -589,8 +677,7 @@ function filtrar(elemento) { let arr = []; const filtro_nome = document.getElementById("busca_nome"); - const filtro_servico = document.getElementById("selecao_servico"); - + const filtro_servico = document.getElementById("selecao_servico"); if (elemento) { Filtro.status = elemento.value; } @@ -602,14 +689,8 @@ function filtrar(elemento) { if (filtro_servico) { Filtro.servico = filtro_servico.value; } - arr = Filtro.realizarFiltragem(formularios_todos); - - const tabela = document.getElementById("tabela"); - const tabelaObj = new Tabela([], tabela); - tabelaObj.arr = arr; - tabelaObj.excluirLinhas(); - tabelaObj.gerarLinhas(); + realizarQuery("Filtro"); } function ordenar(elemento) { @@ -640,11 +721,67 @@ function ordenar(elemento) { Ordenador.coluna = "nome"; } - const tabelaObj = new Tabela([], tabela); - tabelaObj.arr = Ordenador.realizarOrdenacao(tabelaObj.arr); + realizarQuery("Ordenador"); +} + +function mudarPagina(n) { + Paginacao.mudarPagina(n); + + if(n < 1) + return; + + const lista = document.getElementById("admin-paginacao"); + + Paginacao.excluirIndices(lista); + Paginacao.gerarIndices(lista); + realizarQuery("Paginacao"); +} + +function realizarQuery(chamador) { + let dados = {}; + Filtro.preencherQuery(dados); + Ordenador.preencherQuery(dados); + Paginacao.preencherQuery(dados); + + const tabela = document.getElementById("tabela"); + const contador_resultados = document.getElementById("contador_resultados"); + const lista = document.getElementById("admin-paginacao"); + + if(chamador==="Filtro" || chamador==="Ordenador") + dados['pagina'] = 1; + + $.ajax({ + type: 'POST', + url: ajaxUrl, + data: { + action: 'realizarQuery', // Hook de ação para o lado do servidor + formData: dados, // Data do formulário + }, + success: function (resposta) { + // Resposta caso dê certo + + let data = resposta['data']; + const tabelaObj = new Tabela([], tabela); + tabelaObj.arr = data['resultados']; + + tabelaObj.excluirLinhas(); + tabelaObj.gerarLinhas(); + + if(chamador==="Filtro" || chamador==="Ordenador") { + Paginacao.mudarMaxPaginas(Math.ceil(data['total_items'] / 10)); + Paginacao.excluirIndices(lista); + Paginacao.gerarIndices(lista); + } - tabelaObj.excluirLinhas(); - tabelaObj.gerarLinhas(); + contador_resultados.innerHTML = ` +

${data['total_items']} resultados encontrados

+ ` + }, + error: function (xhr, status, error) { + // Resposta caso dê errado + console.error('Erro no envio do formulário:', error); + }, + }); } // Adiciona um evento de clique a todos os botões de "Ver mais/menos" diff --git a/lgbtq_connect/includes/admin/pagina_administracao.php b/lgbtq_connect/includes/admin/pagina_administracao.php index 1101f629..1f65d4b5 100644 --- a/lgbtq_connect/includes/admin/pagina_administracao.php +++ b/lgbtq_connect/includes/admin/pagina_administracao.php @@ -98,19 +98,20 @@ function mostrar_dados() { get_var($query_aprovados); + $negados = $wpdb->get_var($query_negados); + $pendentes = $wpdb->get_var($query_pendentes); - $aprovados = $wpdb->get_results($query_aprovados); - $negados = $wpdb->get_results($query_negados); - $pendentes = $wpdb->get_results($query_pendentes); echo '
'; echo '

Formulários

'; echo '
-
+

@@ -143,18 +144,19 @@ function mostrar_dados() {
- +
+
diff --git a/lgbtq_connect/includes/admin/realizar-query.php b/lgbtq_connect/includes/admin/realizar-query.php new file mode 100644 index 00000000..3c41825d --- /dev/null +++ b/lgbtq_connect/includes/admin/realizar-query.php @@ -0,0 +1,65 @@ + 'Pedido inválido']); + return; + } + + $dados = $_POST['formData']; + + // Prepara o SQL + $sql = "SELECT * FROM lc_formulario WHERE 1=1"; + $sql_contagem = "SELECT COUNT(*) FROM lc_formulario WHERE 1=1"; + + // Prepara os parâmetros do query + $params = []; + + // Filtra de acordo com o nome + $nome = '%' . str_replace(' ', '', $dados['nome']) . '%'; + $sql .= " AND REPLACE(LOWER(nome), ' ', '') LIKE LOWER(%s)"; + $sql_contagem .= " AND REPLACE(LOWER(nome), ' ', '') LIKE LOWER(%s)"; + $params[] = $nome; + + // Filtra de acordo com o status + $status = '%' . str_replace(' ', '', $dados['status']) . '%'; + $sql .= " AND REPLACE(LOWER(situacao), ' ', '') LIKE LOWER(%s)"; + $sql_contagem .= " AND REPLACE(LOWER(situacao), ' ', '') LIKE LOWER(%s)"; + $params[] = $status; + + // Filtra de acordo com o serviço + $servico = '%' . str_replace(' ', '', $dados['servico']) . '%'; + $sql .= " AND REPLACE(LOWER(servico), ' ', '') LIKE LOWER(%s)"; + $sql_contagem .= " AND REPLACE(LOWER(servico), ' ', '') LIKE LOWER(%s)"; + $params[] = $servico; + + // Ordenação + $ordem = strtoupper($dados['ordem']) === 'ASC' ? 'DESC' : 'ASC'; + $sql .= " ORDER BY {$dados['coluna']} $ordem"; + + // Paginação + $items_por_pagina = 10; + $pagina_atual = !empty($dados['pagina']) ? (int)$dados['pagina'] : 1; + $offset = ($pagina_atual - 1) * $items_por_pagina; + $sql .= $wpdb->prepare(" LIMIT %d OFFSET %d", $items_por_pagina, $offset); + + // Prepare e realiza o query de contagem + $query_contagem_preparado = $wpdb->prepare($sql_contagem, $params); + $total_items = $wpdb->get_var($query_contagem_preparado); + + // Prepara e realiza o query principal + $query_preparado = $wpdb->prepare($sql, $params); + $resultados = $wpdb->get_results($query_preparado, ARRAY_A); + + // Manda os resultados de volta para o JavaScript + wp_send_json_success([ + 'resultados' => $resultados, + 'total_items' => $total_items + ]); +} +?> diff --git a/lgbtq_connect/includes/admin/style-admin.css b/lgbtq_connect/includes/admin/style-admin.css index c1a929b2..ca1e6077 100644 --- a/lgbtq_connect/includes/admin/style-admin.css +++ b/lgbtq_connect/includes/admin/style-admin.css @@ -36,9 +36,7 @@ align-items: center; } -#busca_nome_container { - display: flex; - border: 1px solid grey; +#selecao_servico, #busca_nome{ border-radius: 10px; width: 351.51px; height: 40px; @@ -399,9 +397,9 @@ table th:last-child { display: flex; justify-content: space-between; align-items: center; - font-size: 28px; - + font-size: 28px; } + .btn-pendente{ background: rgb(238,202,16); background: linear-gradient(149deg, rgba(238,202,16,1) 14%, rgba(235,115,10,1) 65%, rgba(221,73,28,1) 99%); @@ -427,6 +425,47 @@ table th:last-child { font-size: 18px; } +#tabela tr:nth-child(odd) td { + background-color: #00000015; +} + +.paginacao { + margin: 10px; + display: inline; +} + +.paginacao li { + display: inline; +} + +.paginacao a { + font-size: large; + color: black; + float: left; + padding: 8px 16px; + text-decoration: none; + border: 1px solid #ddd; + transition: background-color .3s; +} + +.paginacao a.paginacao-seta { + border: 1.5px solid #ddd; + border-image: linear-gradient(to bottom right, red, hotpink, blue, lime, yellow) 5; +} + +.paginacao a:hover:not(.pagina-selecionada) {background-color: #ddd;} + +.wrap-paginacao { + align-items: center; + display: flex; + flex-direction: column; +} + +.pagina-selecionada { + background-color: blue; + color: white !important; +} + .lc_rotate { transform: rotate(90deg); transition: transform 0.3s ease; diff --git a/lgbtq_connect/index.php b/lgbtq_connect/index.php index 61f7770c..1df97d64 100644 --- a/lgbtq_connect/index.php +++ b/lgbtq_connect/index.php @@ -16,12 +16,16 @@ // Inclui os arquivos necessários include_once(plugin_dir_path(__FILE__) . 'includes/data/conexao_bd.php'); include_once(plugin_dir_path(__FILE__) . 'includes/data/process_form.php'); +include_once(plugin_dir_path(__FILE__) . 'includes/admin/realizar-query.php'); include_once(plugin_dir_path(__FILE__) . 'includes/admin/pagina_administracao.php'); // Adiciona um gancho para processar o formulário quando o WordPress estiver processando solicitações add_action('wp_ajax_processar_formulario', 'processar_formulario'); add_action('wp_ajax_nopriv_processar_formulario', 'processar_formulario'); +add_action('wp_ajax_realizarQuery', 'realizarQuery'); +add_action('wp_ajax_nopriv_realizarQuery', 'realizarQuery'); + // Função para carregar o conteúdo do arquivo HTML function load_meu_plugin_html() { // Obtém o caminho do arquivo HTML dentro do diretório do plugin @@ -54,11 +58,12 @@ function enfileirar_scripts_admin() { $formularios = obter_formularios($wpdb); wp_enqueue_script('admin_script.js', plugin_dir_url(__FILE__) . 'includes/admin/admin_script.js', array('jquery'), '1.0', true); + + wp_localize_script( 'admin_script.js', 'my_ajax_object', + array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) ); + // Passa os dados dos formulários aprovados para o script JavaScript wp_localize_script('admin_script.js', 'formularios_aprovados', $formularios_aprovados); - - // Passa os dados de todos os formulários para o script JavaScript - wp_localize_script('admin_script.js', 'formularios_todos', $formularios); } function enfileirar_styles_admin() diff --git a/package.json b/package.json index 96cf32fc..4c711a28 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "scripts": { "build": "webpack --mode production", "dev": "webpack --mode development", - "test:js": "jest" + "test:js": "jest --passWithNoTests" }, "devDependencies": { "@babel/core": "^7.24.6", diff --git a/tests/js/filtro_admin.test.js b/tests/js/filtro_admin.test.js deleted file mode 100644 index f2a8480d..00000000 --- a/tests/js/filtro_admin.test.js +++ /dev/null @@ -1,72 +0,0 @@ -import { Filtro } from '../../lgbtq_connect/includes/admin/admin_script.js'; - -describe("filtro (página do admin)", () => { - let arr; - let arr_filtrada; - - const formulario1 = { - nome: "Cabana", - situacao: "Aprovado", - servico: "entretenimento" - }; - const formulario2 = { - nome: "pizza", - situacao: "Negado", - servico: "bar/restaurante" - }; - const formulario3 = { - nome: "Escola", - situacao: "Pendente", - servico: "ensino" - }; - - beforeEach(() => { - // Reset the array and filters before each test - arr = [formulario1, formulario2, formulario3]; - Filtro.reiniciarFiltro(); - - // Simulate the DOM elements - document.body.innerHTML = ` -
- - - -
- `; - }); - - test('filtro por nome está funcionando', () => { - Filtro.nome = "Cabana "; - arr_filtrada = Filtro.realizarFiltragem(arr); - expect(arr_filtrada).toContain(formulario1); - expect(arr_filtrada).toHaveLength(1); - }); - - test('filtro por status está funcionando', () => { - Filtro.status = "Pendente"; - arr_filtrada = Filtro.realizarFiltragem(arr); - expect(arr_filtrada).toContain(formulario3); - expect(arr_filtrada).toHaveLength(1); - }); - - test('filtro por serviço está funcionando', () => { - Filtro.servico = "ensino"; - arr_filtrada = Filtro.realizarFiltragem(arr); - expect(arr_filtrada).toContain(formulario3); - expect(arr_filtrada).toHaveLength(1); - }); - - test('todos os filtros ao mesmo tempo estão funcionando com valores não-nulos', () => { - Filtro.nome = "Cabana "; - Filtro.status = "Aprovado"; - Filtro.servico = "entretenimento"; - arr_filtrada = Filtro.realizarFiltragem(arr); - expect(arr_filtrada).toContain(formulario1); - expect(arr_filtrada).toHaveLength(1); - }); - - test('todos os filtros ao mesmo tempo estão funcionando com valores nulos', () => { - arr_filtrada = Filtro.realizarFiltragem(arr); - expect(arr_filtrada).toHaveLength(3); - }); -}); diff --git a/tests/js/ordenacao_admin.test.js b/tests/js/ordenacao_admin.test.js deleted file mode 100644 index 73fe61a2..00000000 --- a/tests/js/ordenacao_admin.test.js +++ /dev/null @@ -1,92 +0,0 @@ -import { Ordenador } from '../../lgbtq_connect/includes/admin/admin_script.js'; - -describe("ordenador (página do admin)", () => { - let arr; - let formulario1, formulario2, formulario3; - - beforeEach(() => { - // Simulate the DOM elements - document.body.innerHTML = ` -
- - - -
- `; - - // Reset the data before each test - formulario1 = { - "id": 1, - "nome": "Cabana", - "email": "exemplo1@gmail.com", - "latitude": 50.2, - "longitude": 20.3, - "data_hora": "2024-01-01 00:00:00", - "servico": "entretenimento", - "descricao": "Bom demais", - "situacao": "Aprovado" - }; - - formulario2 = { - "id": 2, - "nome": "Pizza", - "email": "exemplo2@gmail.com", - "latitude": 50.2, - "longitude": 20.3, - "data_hora": "2024-01-02 00:00:00", - "servico": "bar/restaurante", - "descricao": "Bom demais", - "situacao": "Aprovado" - }; - - formulario3 = { - "id": 3, - "nome": "Hamburguer", - "email": "exemplo3@gmail.com", - "latitude": 50.2, - "longitude": 20.3, - "data_hora": "2024-01-01 00:00:01", - "servico": "bar/restaurante", - "descricao": "Bom demais", - "situacao": "Aprovado" - }; - - arr = [formulario1, formulario2, formulario3]; - }); - - test('ordenação por nome está funcionando', () => { - Ordenador.coluna = "nome"; - - Ordenador.ordem = "asc"; - let sortedArrAsc = Ordenador.realizarOrdenacao(arr); - expect(sortedArrAsc[0]).toBe(formulario1); - - Ordenador.ordem = "desc"; - let sortedArrDesc = Ordenador.realizarOrdenacao(arr); - expect(sortedArrDesc[0]).toBe(formulario2); - }); - - test('ordenação por email está funcionando', () => { - Ordenador.coluna = "email"; - - Ordenador.ordem = "asc"; - let sortedArrAsc = Ordenador.realizarOrdenacao(arr); - expect(sortedArrAsc[0]).toBe(formulario1); - - Ordenador.ordem = "desc"; - let sortedArrDesc = Ordenador.realizarOrdenacao(arr); - expect(sortedArrDesc[0]).toBe(formulario3); - }); - - test('ordenação por data e hora está funcionando', () => { - Ordenador.coluna = "data_hora"; - - Ordenador.ordem = "asc"; - let sortedArrAsc = Ordenador.realizarOrdenacao(arr); - expect(sortedArrAsc[0]).toBe(formulario1); - - Ordenador.ordem = "desc"; - let sortedArrDesc = Ordenador.realizarOrdenacao(arr); - expect(sortedArrDesc[0]).toBe(formulario2); - }); -}); diff --git a/tests/js/tabela_admin.test.js b/tests/js/tabela_admin.test.js deleted file mode 100644 index 5d5eb81c..00000000 --- a/tests/js/tabela_admin.test.js +++ /dev/null @@ -1,92 +0,0 @@ -import { Tabela } from '../../lgbtq_connect/includes/admin/admin_script.js'; - -describe("manipulação da tabela do admin", () => { - - let arr; - - beforeEach(() => { - // Simulate the DOM elements - document.body.innerHTML = ` -
- - - -
- - - - - - - - - - - - - - - -
Nome Email LatitudeLongitudeServiçoDescriçãoData e hora StatusAções
- `; - - // Define the test data - arr = [ - { - "id": 1, - "nome": "Cabana", - "email": "exemplo1@gmail.com", - "latitude": 50.2, - "city": "Cidade das boas", - "road": "Rua das boas", - "longitude": 20.3, - "data_hora": "2024-01-01 00:00:00", - "servico": "entretenimento", - "descricao": "Bom demais", - "situacao": "Aprovado" - } - ]; - }); - - test('a geração de linhas está funcionando', () => { - const tabela = document.getElementById('tabela'); - const tabelaObj = new Tabela(arr, tabela); - tabelaObj.gerarLinhas(); - - const tbody = document.getElementById("tabela-body"); - - // Verifica se o nome está correto - expect(tbody.querySelector("#formulario-1-nome").textContent).toBe("Cabana"); - - // Verifica se o email está correto - expect(tbody.querySelector("#formulario-1-email").textContent).toBe("exemplo1@gmail.com"); - - // Verifica se a cidade está correta - expect(tbody.querySelector("#formulario-1-cidade").textContent).toBe("Cidade das boas"); - - // Verifica se a rua está correta - expect(tbody.querySelector("#formulario-1-rua").textContent).toBe("Rua das boas"); - - // Verifica se a data e hora estão corretas - expect(tbody.querySelector("#formulario-1-data_hora").textContent).toBe("01/01/2024 00:00:00"); - - // Verifica se o serviço está correto - expect(tbody.querySelector("#formulario-1-servico").textContent).toBe("entretenimento"); - - // Verifica se a descrição está correta - expect(tbody.querySelector("#formulario-1-descricao").textContent).toBe("Bom demais"); - - // Verifica se a situação está correta - expect(tbody.querySelector("#formulario-1-situacao").textContent).toBe("Aprovado"); - }); - - test('a exclusão de linhas está funcionando', () => { - const tabela = document.getElementById('tabela'); - const tabelaObj = new Tabela(arr, tabela); - tabelaObj.gerarLinhas(); // Gera as linhas primeiro - tabelaObj.excluirLinhas(); // Em seguida, exclui as linhas - - const tbody = document.getElementById("tabela-body"); - expect(tbody.innerHTML).toBe(""); - }); -});