:root {
--neabi-green: #2d955c; --neabi-red: #e31b23; --neabi-dark: #1a1a1a;
--neabi-light-green: rgba(45, 149, 92, 0.1); --bg: transparent; --card-bg: #ffffff;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
* { box-sizing: border-box; }
.grid { display: grid; grid-template-columns: 1fr 2fr; gap: 25px; margin-bottom: 30px; align-items: stretch; }
.biblioteca-container { font-family: 'Inter', sans-serif; color: var(--neabi-dark); margin: 0; padding: 20px; max-width: 1200px; margin: 0 auto; }
.biblioteca-container header { text-align: center; margin-bottom: 30px; padding: 40px 20px; background: white; border-bottom: 6px solid var(--neabi-red); border-radius: 24px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); }
.logo-container img { width: 100%; max-width: 600px; height: auto; object-fit: contain; }
.biblioteca-container header p { margin-top: 15px; color: var(--neabi-green); font-weight: 800; letter-spacing: 3px; font-size: 0.85rem; text-transform: uppercase; }
.link-header { text-decoration: none; display: block; }
.link-header header { cursor: pointer; transition: var(--transition); }
.link-header:hover header { transform: translateY(-5px); box-shadow: 0 15px 35px rgba(0,0,0,0.1); }
.grid { display: grid; grid-template-columns: 1fr 2fr; gap: 25px; margin-bottom: 25px; align-items: stretch; }
@media (max-width: 850px) { .grid { grid-template-columns: 1fr; } }
.card { background: var(--card-bg); padding: 30px; border-radius: 20px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); border: none; transition: var(--transition); }
.card h2 { font-size: 1.1rem; color: var(--neabi-dark); display: flex; align-items: center; gap: 12px; margin-top: 0; padding-bottom: 15px; border-bottom: 2px solid #f0f2f5; }
.scroll-historico { max-height: 350px; overflow-y: auto; padding-right: 5px; }
.scroll-historico::-webkit-scrollbar { width: 6px; }
.scroll-historico::-webkit-scrollbar-thumb { background: #ddd; border-radius: 10px; }
.input-group label { font-weight: 700; font-size: 0.8rem; margin-bottom: 8px; color: #666; display: block; }
.input-group input { width: 100%; padding: 14px; border: 2px solid #eee; border-radius: 12px; font-size: 1rem; box-sizing: border-box; }
.input-group input:focus { outline: none; border-color: var(--neabi-green); box-shadow: 0 0 0 4px var(--neabi-light-green); }
.biblioteca-container button { padding: 12px 20px; border: none; border-radius: 12px; cursor: pointer; font-weight: 700; transition: var(--transition); display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.btn-main { background: var(--neabi-dark); color: white; width: 100%; margin-top: 10px; }
.btn-main:hover { background: var(--neabi-green); }
.btn-return { background: white; color: var(--neabi-red); border: 2px solid var(--neabi-red); font-size: 0.75rem; padding: 6px 12px; }
.btn-return:hover { background: var(--neabi-red); color: white; }
.biblioteca-container table { width: 100%; border-collapse: separate; border-spacing: 0 8px; }
.biblioteca-container th { text-align: left; padding: 10px 15px; color: #888; font-size: 0.7rem; text-transform: uppercase; }
.biblioteca-container td { padding: 12px 15px; background: #fdfdfd; border-top: 1px solid #f1f1f1; border-bottom: 1px solid #f1f1f1; font-size: 0.85rem; }
.biblioteca-container td:first-child { border-left: 1px solid #f1f1f1; border-radius: 10px 0 0 10px; }
.biblioteca-container td:last-child { border-right: 1px solid #f1f1f1; border-radius: 0 10px 10px 0; }
.badge { padding: 4px 10px; border-radius: 6px; font-weight: 800; font-size: 0.65rem; }
.status-ativo { background: var(--neabi-light-green); color: var(--neabi-green); }
.status-finalizado { background: #eee; color: #777; }
.pagination-container { display: flex; justify-content: center; align-items: center; gap: 15px; margin-top: 20px; padding-top: 15px; border-top: 2px solid #f0f2f5; }
.page-btn { background: white; border: 1px solid #ddd; color: var(--neabi-dark); padding: 8px 16px; border-radius: 8px; }
.page-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.page-btn:not(:disabled):hover { border-color: var(--neabi-green); color: var(--neabi-green); }
#msg { margin-top: 15px; padding: 10px; border-radius: 10px; text-align: center; display: none; font-size: 0.85rem; }
.card-header-flex { display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid #f0f2f5; padding-bottom: 15px; margin-bottom: 15px; }
.card-header-flex h2 { border-bottom: none; padding-bottom: 0; margin-bottom: 0; }
.btn-export { background-color: var(--neabi-green); color: white; padding: 8px 16px; font-size: 0.8rem; border-radius: 8px; border: none; cursor: pointer; transition: var(--transition); font-weight: bold; display: flex; gap: 8px; align-items: center; }
.btn-export:hover { background-color: var(--neabi-dark); transform: translateY(-2px); }
@media (max-width: 768px) { .grid { grid-template-columns: 1fr; } .card-header-flex { flex-direction: column; align-items: flex-start; gap: 10px; } .btn-export { align-self: flex-start; } td, th { padding: 10px 8px; font-size: 0.85rem; } }
.modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.6); z-index: 9999; justify-content: center; align-items: center; }
.modal-box { background: white; padding: 25px; border-radius: 12px; max-width: 400px; width: 90%; box-shadow: 0 10px 30px rgba(0,0,0,0.3); text-align: center; }
.modal-box h3 { color: var(--neabi-dark); margin-top: 0; }
.modal-info { background: #f8f9fa; padding: 15px; border-radius: 8px; margin: 15px 0; text-align: left; font-size: 0.9rem; }
.biblioteca-container .btn-cancel { background: #ccc; color: #333; padding: 10px 15px; border: none; border-radius: 6px; cursor: pointer; }
.biblioteca-container .btn-confirm { background: var(--neabi-green); color: white; padding: 10px 15px; border: none; border-radius: 6px; cursor: pointer; margin-left: 10px; }
.admin-only { display: none; }
let isAdmin = false;
let acervoCompleto = [];
let paginaAtual = 1;
const itensPorPagina = 8;
let acervoConsultaCompleto = [];
let paginaAtualConsulta = 1;
const itensPorPaginaConsulta = 8;
function atualizarTudo() {
carregarEmprestimos();
carregarAcervo();
carregarConsultaLocal();
}
async function identificarFuncionario() {
const matricula = document.getElementById('matricula').value;
const labelNome = document.getElementById('nomeIdentificado');
if (matricula.length === 7) {
try {
const res = await fetch(`/neabi/wp-json/biblioteca/v1/funcionarios/${matricula}`);
const func = res.ok ? await res.json() : null;
if (func && func.nome) {
labelNome.innerText = `👤 ${func.nome}`;
labelNome.style.color = "var(--neabi-green)";
} else {
labelNome.innerText = "❌ Usuário não encontrado ou não cadastrado";
labelNome.style.color = "var(--neabi-red)";
}
} catch (e) { labelNome.innerText = "❌ Erro na consulta"; }
} else { labelNome.innerText = ""; }
}
async function enviarEmprestimo() {
const m = document.getElementById('matricula').value;
const l = parseInt(document.getElementById('livroId').value);
if (!m || !l) { mostrarMensagem("⚠️ Preencha os campos!", "orange"); return; }
try {
const res = await fetch('/neabi/wp-json/biblioteca/v1/emprestimos/realizar', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ matricula: m, livroId: l })
});
const texto = await res.text();
fecharModal('modalEmprestimo');
mostrarMensagem(texto, texto.includes("Erro") ? "var(--neabi-red)" : "var(--neabi-green)");
if(!texto.includes("Erro")) {
document.getElementById('matricula').value = "";
document.getElementById('livroId').value = "";
document.getElementById('nomeIdentificado').innerText = "";
}
atualizarTudo();
} catch (e) {
fecharModal('modalEmprestimo');
mostrarMensagem("❌ Erro de conexão", "red");
}
}
async function carregarEmprestimos() {
try {
const res = await fetch('/neabi/wp-json/biblioteca/v1/emprestimos/todos');
const dados = await res.json();
const corpo = document.querySelector('#tabelaEmprestimos tbody');
const cabecalho = document.querySelector('#tabelaEmprestimos thead tr');
corpo.innerHTML = "";
cabecalho.innerHTML = (isAdmin ? `Pessoa ` : ``) + `Título Status Ação `;
const dataHoje = new Date(); dataHoje.setHours(0, 0, 0, 0);
dados.reverse().forEach(emp => {
const isAtivo = emp.status === 'ATIVO';
let statusBadge = isAtivo ? `ATIVO` : `FINALIZADO`;
let estiloLinha = '';
if (isAtivo && dataHoje > new Date(emp.dataDevolucaoPrevista + "T00:00:00")) {
statusBadge = ` ATRASADO`;
estiloLinha = `style="background-color: #fff0f0;"`;
}
const colunaPessoa = isAdmin ? `${emp.funcionarioNome}
Retirado: ${emp.dataRetirada.split('-').reverse().join('/')} ` : ``;
corpo.innerHTML += `
${colunaPessoa}
${emp.livroTitulo}
Vence: ${emp.dataDevolucaoPrevista.split('-').reverse().join('/')}
${statusBadge}
${isAtivo ? `` : '---'}
`;
});
} catch (e) { console.error(e); }
}
function desbloquearAdmin() {
const senha = prompt("Digite a chave de acesso para visualizar detalhes:");
if (senha === "40028922") {
isAdmin = true;
document.getElementById('btnExportar').classList.remove('admin-only');
carregarEmprestimos();
} else {
alert("Acesso negado.");
}
}
async function carregarAcervo() {
try {
const res = await fetch('/neabi/wp-json/biblioteca/v1/livros/circulantes');
acervoCompleto = await res.json();
acervoCompleto.sort((a, b) => a.titulo.localeCompare(b.titulo));
paginaAtual = 1;
renderizarAcervo();
} catch (e) { console.error(e); }
}
async function carregarConsultaLocal() {
try {
const res = await fetch('/neabi/wp-json/biblioteca/v1/livros/consulta-local');
acervoConsultaCompleto = await res.json();
acervoConsultaCompleto.sort((a, b) => a.titulo.localeCompare(b.titulo));
paginaAtualConsulta = 1;
renderizarConsultaLocal();
} catch (e) { console.error(e); }
}
function renderizarConsultaLocal() {
const inicio = (paginaAtualConsulta - 1) * itensPorPaginaConsulta;
const fim = inicio + itensPorPaginaConsulta;
const itensPagina = acervoConsultaCompleto.slice(inicio, fim);
const corpo = document.querySelector('#tabelaConsulta tbody');
if(!corpo) return;
corpo.innerHTML = "";
itensPagina.forEach(livro => {
corpo.innerHTML += `
#${livro.id}
${livro.titulo}
${livro.autores || '-'}
${livro.categoria}
`;
});
const totalPaginas = Math.ceil(acervoConsultaCompleto.length / itensPorPaginaConsulta) || 1;
document.getElementById('pageInfoConsulta').innerText = `Página ${paginaAtualConsulta} de ${totalPaginas}`;
document.getElementById('prevBtnConsulta').disabled = paginaAtualConsulta === 1;
document.getElementById('nextBtnConsulta').disabled = paginaAtualConsulta >= totalPaginas;
}
function mudarPaginaConsulta(direcao) {
paginaAtualConsulta += direcao;
renderizarConsultaLocal();
}
async function filtrarConsultaLocal() {
const termo = document.getElementById('buscaConsulta').value;
if (termo.length a.titulo.localeCompare(b.titulo));
paginaAtualConsulta = 1;
renderizarConsultaLocal();
} catch (e) { console.error(e); }
}
function renderizarAcervo() {
const inicio = (paginaAtual - 1) * itensPorPagina;
const fim = inicio + itensPorPagina;
const itensPagina = acervoCompleto.slice(inicio, fim);
const corpo = document.querySelector('#tabelaAcervo tbody');
corpo.innerHTML = "";
itensPagina.forEach(livro => {
corpo.innerHTML += `#${livro.id}
${livro.titulo}
${livro.autores || '-'}
${livro.editora || '-'} ${livro.isbn || '-'}
0 ? 'status-ativo' : 'status-finalizado'}">${livro.quantidadeDisponivel} `;
});
document.getElementById('pageInfo').innerText = `Página ${paginaAtual} de ${Math.ceil(acervoCompleto.length / itensPorPagina)}`;
document.getElementById('prevBtn').disabled = paginaAtual === 1;
document.getElementById('nextBtn').disabled = paginaAtual >= Math.ceil(acervoCompleto.length / itensPorPagina);
}
function mudarPagina(direcao) {
paginaAtual += direcao;
renderizarAcervo();
}
async function filtrarAcervo() {
const termo = document.getElementById('buscaLivro').value;
if (termo.length a.titulo.localeCompare(b.titulo));
paginaAtual = 1;
renderizarAcervo();
} catch (e) { console.error(e); }
}
function mostrarMensagem(t, c) {
const m = document.getElementById('msg');
m.style.display = "block"; m.style.color = "white"; m.style.backgroundColor = c; m.innerText = t;
setTimeout(() => m.style.display = "none", 5000);
}
async function exportarRelatorio() {
try {
const res = await fetch('/neabi/wp-json/biblioteca/v1/emprestimos/todos');
const dados = await res.json();
if (dados.length === 0) {
alert("Não há dados para exportar.");
return;
}
let csvContent = "ID;Estudante/Servidor;Título;Data Retirada;Devolução Prevista;Status\n";
dados.forEach(emp => {
const nome = `"${emp.funcionarioNome || ''}"`;
const titulo = `"${emp.livroTitulo || ''}"`;
const dataRet = `"${emp.dataRetirada || ''}"`;
const dataDev = `"${emp.dataDevolucaoPrevista || ''}"`;
const status = `"${emp.status || ''}"`;
csvContent += `${emp.id};${nome};${titulo};${dataRet};${dataDev};${status}\n`;
});
const blob = new Blob(["\uFEFF" + csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement("a");
const url = URL.createObjectURL(blob);
const dataHoje = new Date().toISOString().slice(0, 10);
link.setAttribute("href", url);
link.setAttribute("download", `relatorio_neabi_${dataHoje}.csv`);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (e) {
console.error("Erro ao exportar:", e);
alert("Erro ao gerar o relatório. Verifique a conexão.");
}
}
function fecharModal(id) { document.getElementById(id).style.display = 'none'; }
function mostrarErro(mensagem) {
document.getElementById('textoErro').innerHTML = mensagem;
document.getElementById('modalErro').style.display = 'flex';
}
function prepararEmprestimo() {
const matricula = document.getElementById('matricula').value;
const livroId = document.getElementById('livroId').value;
const nomeStr = document.getElementById('nomeIdentificado').innerText.trim();
if (!matricula || !livroId) {
mostrarErro("Por favor, preencha a Matrícula e o Código do Livro!");
return;
}
if (!nomeStr || nomeStr.toLowerCase().includes("não encontrado") || nomeStr.toLowerCase().includes("erro")) {
mostrarErro("O RA/Matrícula digitado não pertence a um usuário cadastrado.");
return;
}
const livro = acervoCompleto.find(l => l.id == livroId) || acervoConsultaCompleto.find(l => l.id == livroId);
const tituloLivro = livro ? livro.titulo : "Livro #" + livroId;
const hoje = new Date();
const devolucao = new Date(); devolucao.setDate(hoje.getDate() + 14);
document.getElementById('resumoEmprestimo').innerHTML = `
Usuário: ${nomeStr}
Livro: ${tituloLivro}
Retirada: ${hoje.toLocaleDateString('pt-BR')}
Devolução: ${devolucao.toLocaleDateString('pt-BR')} `; document.getElementById('modalEmprestimo').style.display = 'flex'; } async function solicitarDevolucao(idEmprestimo) { const matriculaConfirmacao = prompt("Para confirmar a devolução, digite a sua Matrícula (RA):"); if (!matriculaConfirmacao) return; try { const res = await fetch(`/neabi/wp-json/biblioteca/v1/emprestimos/devolver/${idEmprestimo}?matricula=${matriculaConfirmacao}`, { method: 'POST' }); const texto = await res.text(); if (texto.startsWith("Erro")) { mostrarErro(texto); } else { alert("✅ " + texto); atualizarTudo(); } } catch (e) { mostrarErro("Erro de conexão com o servidor."); } } // Inicia o carregamento das tabelas atualizarTudo();

Sistema de Gestão Bibliográfica
Retirada
Atividades Recentes 🔒
| Pessoa | Título | Status | Ação |
|---|
Acervo Neabi Diva
| Cód | Título / Autoria | Editora | ISBN | Qtd |
|---|
Página 1
Consulta Local (Não Circulante)
*Estes exemplares são de uso exclusivo nas dependências do NEABI-CT e não podem ser retirados.
| Cód | Título / Autoria | Categoria |
|---|
Página 1
Confirmar Retirada?
Ação Bloqueada
Retirado: ${emp.dataRetirada.split('-').reverse().join('/')}
Vence: ${emp.dataDevolucaoPrevista.split('-').reverse().join('/')}
${livro.autores || '-'}
${livro.autores || '-'}
Livro: ${tituloLivro}
Retirada: ${hoje.toLocaleDateString('pt-BR')}
Devolução: ${devolucao.toLocaleDateString('pt-BR')} `; document.getElementById('modalEmprestimo').style.display = 'flex'; } async function solicitarDevolucao(idEmprestimo) { const matriculaConfirmacao = prompt("Para confirmar a devolução, digite a sua Matrícula (RA):"); if (!matriculaConfirmacao) return; try { const res = await fetch(`/neabi/wp-json/biblioteca/v1/emprestimos/devolver/${idEmprestimo}?matricula=${matriculaConfirmacao}`, { method: 'POST' }); const texto = await res.text(); if (texto.startsWith("Erro")) { mostrarErro(texto); } else { alert("✅ " + texto); atualizarTudo(); } } catch (e) { mostrarErro("Erro de conexão com o servidor."); } } // Inicia o carregamento das tabelas atualizarTudo();
