Carlos z commited on
Upload admin.js
Browse files- static/admin.js +158 -0
static/admin.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Sahkey Imóveis — painel administrativo de demonstração (CRUD de anúncios) */
|
| 2 |
+
|
| 3 |
+
const form = document.getElementById("form-anuncio");
|
| 4 |
+
const btnCancelar = document.getElementById("btn-cancelar");
|
| 5 |
+
const btnSalvar = document.getElementById("btn-salvar");
|
| 6 |
+
|
| 7 |
+
function lerFormulario() {
|
| 8 |
+
return {
|
| 9 |
+
tipo_negocio: document.getElementById("a-tipo-negocio").value,
|
| 10 |
+
tipo_imovel: document.getElementById("a-tipo-imovel").value,
|
| 11 |
+
titulo: document.getElementById("a-titulo").value,
|
| 12 |
+
descricao: document.getElementById("a-descricao").value,
|
| 13 |
+
endereco: document.getElementById("a-endereco").value,
|
| 14 |
+
bairro: document.getElementById("a-bairro").value,
|
| 15 |
+
cidade: document.getElementById("a-cidade").value,
|
| 16 |
+
estado: document.getElementById("a-estado").value,
|
| 17 |
+
cep: document.getElementById("a-cep").value,
|
| 18 |
+
preco: Number(document.getElementById("a-preco").value || 0),
|
| 19 |
+
condominio: Number(document.getElementById("a-condominio").value || 0),
|
| 20 |
+
iptu: Number(document.getElementById("a-iptu").value || 0),
|
| 21 |
+
area_util: Number(document.getElementById("a-area-util").value || 0),
|
| 22 |
+
area_total: Number(document.getElementById("a-area-total").value || 0),
|
| 23 |
+
quartos: Number(document.getElementById("a-quartos").value || 0),
|
| 24 |
+
suites: Number(document.getElementById("a-suites").value || 0),
|
| 25 |
+
banheiros: Number(document.getElementById("a-banheiros").value || 0),
|
| 26 |
+
vagas_garagem: Number(document.getElementById("a-vagas").value || 0),
|
| 27 |
+
status: document.getElementById("a-status").value,
|
| 28 |
+
destaque: document.getElementById("a-destaque").checked,
|
| 29 |
+
corretor_responsavel: document.getElementById("a-corretor").value,
|
| 30 |
+
telefone_contato: document.getElementById("a-telefone").value,
|
| 31 |
+
fotos: "",
|
| 32 |
+
};
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
function preencherFormulario(a) {
|
| 36 |
+
document.getElementById("a-id").value = a.id;
|
| 37 |
+
document.getElementById("a-tipo-negocio").value = a.tipo_negocio;
|
| 38 |
+
document.getElementById("a-tipo-imovel").value = a.tipo_imovel;
|
| 39 |
+
document.getElementById("a-titulo").value = a.titulo;
|
| 40 |
+
document.getElementById("a-descricao").value = a.descricao || "";
|
| 41 |
+
document.getElementById("a-endereco").value = a.endereco || "";
|
| 42 |
+
document.getElementById("a-bairro").value = a.bairro || "";
|
| 43 |
+
document.getElementById("a-cidade").value = a.cidade;
|
| 44 |
+
document.getElementById("a-estado").value = a.estado;
|
| 45 |
+
document.getElementById("a-cep").value = a.cep || "";
|
| 46 |
+
document.getElementById("a-preco").value = a.preco;
|
| 47 |
+
document.getElementById("a-condominio").value = a.condominio || 0;
|
| 48 |
+
document.getElementById("a-iptu").value = a.iptu || 0;
|
| 49 |
+
document.getElementById("a-area-util").value = a.area_util || 0;
|
| 50 |
+
document.getElementById("a-area-total").value = a.area_total || 0;
|
| 51 |
+
document.getElementById("a-quartos").value = a.quartos || 0;
|
| 52 |
+
document.getElementById("a-suites").value = a.suites || 0;
|
| 53 |
+
document.getElementById("a-banheiros").value = a.banheiros || 0;
|
| 54 |
+
document.getElementById("a-vagas").value = a.vagas_garagem || 0;
|
| 55 |
+
document.getElementById("a-status").value = a.status;
|
| 56 |
+
document.getElementById("a-destaque").checked = !!a.destaque;
|
| 57 |
+
document.getElementById("a-corretor").value = a.corretor_responsavel || "";
|
| 58 |
+
document.getElementById("a-telefone").value = a.telefone_contato || "";
|
| 59 |
+
|
| 60 |
+
btnSalvar.textContent = `Atualizar anúncio #${a.id}`;
|
| 61 |
+
btnCancelar.style.display = "";
|
| 62 |
+
form.scrollIntoView({ behavior: "smooth" });
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
function limparFormulario() {
|
| 66 |
+
form.reset();
|
| 67 |
+
document.getElementById("a-id").value = "";
|
| 68 |
+
document.getElementById("a-estado").value = "PR";
|
| 69 |
+
btnSalvar.textContent = "Salvar anúncio";
|
| 70 |
+
btnCancelar.style.display = "none";
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
async function carregarLista() {
|
| 74 |
+
const tbody = document.getElementById("admin-tbody");
|
| 75 |
+
tbody.innerHTML = `<tr><td colspan="7" class="muted">Carregando anúncios…</td></tr>`;
|
| 76 |
+
try {
|
| 77 |
+
const data = await apiGet("/", { limit: 200, ordenar_por: "mais_recentes" });
|
| 78 |
+
document.getElementById("admin-total").textContent = `${data.total} anúncio(s) na base`;
|
| 79 |
+
if (!data.resultados.length) {
|
| 80 |
+
tbody.innerHTML = `<tr><td colspan="7" class="muted">Nenhum anúncio cadastrado ainda.</td></tr>`;
|
| 81 |
+
return;
|
| 82 |
+
}
|
| 83 |
+
tbody.innerHTML = data.resultados.map((a) => `
|
| 84 |
+
<tr>
|
| 85 |
+
<td class="badge-mono">#${a.id}</td>
|
| 86 |
+
<td>${escapeHtml(a.titulo)}</td>
|
| 87 |
+
<td>${a.tipo_negocio}</td>
|
| 88 |
+
<td>${escapeHtml(a.cidade)}</td>
|
| 89 |
+
<td class="badge-mono">${formatMoney(a.preco, a.tipo_negocio).replace(/<[^>]+>/g, "")}</td>
|
| 90 |
+
<td><span class="status-pill ${statusClass(a.status)}">${a.status}</span></td>
|
| 91 |
+
<td>
|
| 92 |
+
<button class="icon-btn" data-acao="editar" data-id="${a.id}">Editar</button>
|
| 93 |
+
<button class="icon-btn" data-acao="ver" data-id="${a.id}">Ver</button>
|
| 94 |
+
<button class="icon-btn danger" data-acao="excluir" data-id="${a.id}">Excluir</button>
|
| 95 |
+
</td>
|
| 96 |
+
</tr>
|
| 97 |
+
`).join("");
|
| 98 |
+
} catch (err) {
|
| 99 |
+
tbody.innerHTML = `<tr><td colspan="7">Erro ao carregar: ${escapeHtml(err.message)}</td></tr>`;
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
document.getElementById("admin-tbody").addEventListener("click", async (e) => {
|
| 104 |
+
const btn = e.target.closest("button[data-acao]");
|
| 105 |
+
if (!btn) return;
|
| 106 |
+
const id = btn.dataset.id;
|
| 107 |
+
|
| 108 |
+
if (btn.dataset.acao === "ver") {
|
| 109 |
+
window.open(`imovel.html?id=${id}`, "_blank");
|
| 110 |
+
return;
|
| 111 |
+
}
|
| 112 |
+
if (btn.dataset.acao === "editar") {
|
| 113 |
+
try {
|
| 114 |
+
const a = await apiGet(`/${id}`);
|
| 115 |
+
preencherFormulario(a);
|
| 116 |
+
} catch (err) {
|
| 117 |
+
toast(err.message, true);
|
| 118 |
+
}
|
| 119 |
+
return;
|
| 120 |
+
}
|
| 121 |
+
if (btn.dataset.acao === "excluir") {
|
| 122 |
+
if (!confirm(`Excluir o anúncio #${id}? Essa ação não pode ser desfeita.`)) return;
|
| 123 |
+
try {
|
| 124 |
+
await apiSend("DELETE", `/${id}`);
|
| 125 |
+
toast(`Anúncio #${id} removido.`);
|
| 126 |
+
carregarLista();
|
| 127 |
+
} catch (err) {
|
| 128 |
+
toast(err.message, true);
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
});
|
| 132 |
+
|
| 133 |
+
form.addEventListener("submit", async (e) => {
|
| 134 |
+
e.preventDefault();
|
| 135 |
+
const id = document.getElementById("a-id").value;
|
| 136 |
+
const payload = lerFormulario();
|
| 137 |
+
|
| 138 |
+
btnSalvar.disabled = true;
|
| 139 |
+
try {
|
| 140 |
+
if (id) {
|
| 141 |
+
await apiSend("PUT", `/${id}`, payload);
|
| 142 |
+
toast(`Anúncio #${id} atualizado.`);
|
| 143 |
+
} else {
|
| 144 |
+
const criado = await apiSend("POST", "/", payload);
|
| 145 |
+
toast(`Anúncio #${criado.id} criado.`);
|
| 146 |
+
}
|
| 147 |
+
limparFormulario();
|
| 148 |
+
carregarLista();
|
| 149 |
+
} catch (err) {
|
| 150 |
+
toast(err.message, true);
|
| 151 |
+
} finally {
|
| 152 |
+
btnSalvar.disabled = false;
|
| 153 |
+
}
|
| 154 |
+
});
|
| 155 |
+
|
| 156 |
+
btnCancelar.addEventListener("click", limparFormulario);
|
| 157 |
+
|
| 158 |
+
document.addEventListener("DOMContentLoaded", carregarLista);
|