Files
Diarios-Oficiais-ALEMS/frontend/js/script.js

243 lines
8.8 KiB
JavaScript

document.addEventListener('alpine:init', () => {
Alpine.data('searchApp', () => ({
searchParams: {
q: '',
numero_diario: '',
data_inicio: '',
data_fim: '',
modo_busca: 'exata',
ordenar_por: 'data_asc',
page: 1,
page_size: 10
},
searchResults: null,
isLoading: false,
hasSearched: false,
error: null,
showAdvanced: false,
expandedContents: {},
suggestion: null,
ultimoTermoBuscado: '',
get shouldShowSuggestion() {
if (!this.suggestion || !this.searchParams.q) return false;
// Função para remover acentos e converter para minúsculas
const normalize = (text) => {
return text.toLowerCase()
.normalize('NFD')
.replace("/", " ")
.replace(/[^a-z0-9\s]/g, " ") // Substitui todos os outros símbolos por espaço
.replace(/[\u0300-\u036f]/g, '');
};
const normalizedQuery = normalize(this.searchParams.q);
const normalizedSuggestion = normalize(this.suggestion);
// Só mostra a sugestão se for diferente do termo buscado (ignorando acentos e caixa)
return normalizedQuery !== normalizedSuggestion;
},
// Usa a sugestão como novo termo de busca
usesuggestion() {
this.searchParams.q = this.suggestion;
this.searchParams.page = 1;
this.performSearch();
},
// Verifica se um diário tem uma melhor correspondência
hasBestMatch(diario) {
return diario.paginas && diario.paginas.length > 0;
},
// Muda a ordenação e faz uma nova busca
changeOrder(order) {
if (this.searchParams.ordenar_por !== order) {
this.searchParams.ordenar_por = order;
this.searchParams.page = 1; // Volta para a primeira página
this.performSearch();
}
},
// Obter sugestão da API
async getSuggestion(query) {
if (!query) return null;
try {
const url = new URL('http://109.199.98.226:8005/api/v1/diarios/sugestao');
url.searchParams.append('q', query);
const response = await fetch(url);
if (response.ok) {
const data = await response.json();
return data.sugestao;
}
return null;
} catch (error) {
console.error('Erro ao buscar sugestão:', error);
return null;
}
},
get totalPages() {
if (!this.searchResults) return 0;
return Math.ceil(this.searchResults.total / this.searchResults.por_pagina);
},
get paginationArray() {
const pages = [];
const currentPage = this.searchParams.page;
const totalPages = this.totalPages;
// Função auxiliar para adicionar páginas
const addPage = (page) => {
if (page >= 1 && page <= totalPages && !pages.includes(page)) {
pages.push(page);
}
};
// Sempre mostrar primeira página, página atual, última página
// e 1-2 páginas adjacentes à página atual
addPage(1);
addPage(currentPage - 2);
addPage(currentPage - 1);
addPage(currentPage);
addPage(currentPage + 1);
addPage(currentPage + 2);
addPage(totalPages);
// Ordenar e adicionar separadores
const result = pages.sort((a, b) => a - b);
return result;
},
// Retorna a melhor página (maior score) de um diário
getBestPage(paginas) {
if (!paginas || paginas.length === 0) return null;
// Ordena as páginas por score (se disponível) ou pelo número da página se não houver score
const sortedPages = [...paginas].sort((a, b) => {
if (a.score === undefined || b.score === undefined) return 0;
if (a.score === undefined) return 1;
if (b.score === undefined) return -1;
return b.score - a.score;
});
return sortedPages[0];
},
// Retorna todas as páginas exceto a melhor
getOtherPages(paginas) {
if (!paginas || paginas.length <= 1) return [];
const bestPage = this.getBestPage(paginas);
if (!bestPage) return paginas;
return paginas.filter(p => p.numero !== bestPage.numero)
.sort((a, b) => a.numero - b.numero); // Ordena por número da página
},
// Controla a exibição do conteúdo completo de uma página
toggleFullContent(diarioIndex, paginaNumero) {
const key = `${diarioIndex}-${paginaNumero}`;
this.expandedContents[key] = !this.expandedContents[key];
},
// Verifica se um conteúdo está expandido
isFullContentVisible(diarioIndex, paginaNumero) {
const key = `${diarioIndex}-${paginaNumero}`;
return this.expandedContents[key] === true;
},
async performSearch() {
this.isLoading = true;
this.error = null;
this.hasSearched = true;
this.expandedContents = {}; // Resetar estados expandidos
this.suggestion = null; // Resetar a sugestão
try {
let suggestionPromise = null;
if (this.searchParams.q) {
suggestionPromise = this.getSuggestion(this.searchParams.q);
}
if (this.searchParams.q !== this.ultimoTermoBuscado) {
this.searchParams.page = 1;
}
this.ultimoTermoBuscado = this.searchParams.q;
// Usando agora o endpoint busca
const url = new URL('http://109.199.98.226:8005/api/v1/diarios/busca');
// Adicionar parâmetros à URL
Object.entries(this.searchParams).forEach(([key, value]) => {
if (value !== '' && value !== null) {
url.searchParams.append(key, value);
}
});
const response = await fetch(url);
if (!response.ok) {
const errorData = await response.json().catch(() => null);
throw new Error(errorData?.message || `Erro HTTP: ${response.status}`);
}
this.searchResults = await response.json();
// Processar os resultados para garantir que as páginas tenham score
if (this.searchResults && this.searchResults.resultados) {
this.searchResults.resultados.forEach(diario => {
if (diario.paginas) {
// Atribuir scores padrão se não existirem
diario.paginas.forEach((pagina, index) => {
if (pagina.score === undefined || pagina.score === null) {
pagina.score = diario.paginas.length - index; // Score inversamente proporcional ao índice
}
});
}
});
}
if (suggestionPromise) {
this.suggestion = await suggestionPromise;
}
} catch (error) {
console.error('Erro na busca:', error);
this.error = `Erro ao buscar diários: ${error.message}`;
} finally {
this.isLoading = false;
}
},
formatDate(dateString) {
const options = { day: '2-digit', month: '2-digit', year: 'numeric' };
return new Date(dateString + 'T00:00:00').toLocaleDateString('pt-BR', options);
},
goToPage(page) {
if (page < 1 || page > this.totalPages) return;
this.searchParams.page = page;
this.performSearch();
window.scrollTo({ top: 0, behavior: 'smooth' });
},
resetSearch() {
this.searchParams = {
q: '',
numero_diario: '',
data_inicio: '',
data_fim: '',
modo_busca: 'exata',
ordenar_por: 'relevancia',
page: 1,
page_size: 10
};
this.searchResults = null;
this.hasSearched = false;
this.error = null;
this.expandedContents = {};
}
}));
});