portal_publico/static/js/account.js

225 lines
8.7 KiB
JavaScript

document.addEventListener("DOMContentLoaded", async () => {
const chipBtn = document.getElementById("persona-chip");
const dropdown = document.getElementById("account-dropdown");
if (!chipBtn || !dropdown) return;
const me = await pidGetMe();
if (!me) return;
const chipLabel = document.getElementById("persona-chip-label");
const nameEl = document.getElementById("account-name");
const profileEl = document.getElementById("account-profile");
const manageLink = document.getElementById("account-manage-link");
const manageAccountBtn = document.getElementById("account-manage-account-btn");
const profiles = me.perfis || [];
if (chipLabel) chipLabel.textContent = me.nome;
if (nameEl) nameEl.textContent = me.nome;
if (profileEl) {
profileEl.textContent = profiles.length ? profiles.map((p) => p.nome).join(", ") : "Sem perfil vinculado";
}
if (manageLink) manageLink.hidden = !me.gerencia_permissoes;
const themeSwatchesEl = document.getElementById("theme-swatches");
if (themeSwatchesEl) {
const renderSwatches = () => {
const active = pidGetColorTheme();
themeSwatchesEl.innerHTML = PID_COLOR_THEMES.map(
(t) => `
<button type="button" class="theme-swatch ${t.key === active ? "is-active" : ""}" data-theme-choice="${t.key}" style="background:${t.swatch}" aria-label="Tema ${t.label}" title="${t.label}">
${
t.key === active
? '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><path d="M20 6L9 17l-5-5" stroke-linecap="round" stroke-linejoin="round"/></svg>'
: ""
}
</button>`
).join("");
};
renderSwatches();
themeSwatchesEl.addEventListener("click", (event) => {
const btn = event.target.closest("[data-theme-choice]");
if (!btn) return;
pidSetColorTheme(btn.getAttribute("data-theme-choice"));
renderSwatches();
});
}
chipBtn.addEventListener("click", (event) => {
event.stopPropagation();
dropdown.hidden = !dropdown.hidden;
});
document.addEventListener("click", (event) => {
if (!dropdown.hidden && !dropdown.contains(event.target) && event.target !== chipBtn) {
dropdown.hidden = true;
}
});
const manageAccountModal = document.getElementById("manage-account-modal");
const manageAccountChangePasswordBtn = document.getElementById("manage-account-change-password-btn");
const manageAccountCloseBtn = document.getElementById("manage-account-close-btn");
const manageAccountLideradosField = document.getElementById("manage-account-liderados-field");
const manageAccountLideradosSearch = document.getElementById("manage-account-liderados-search");
const manageAccountLideradosSelectAll = document.getElementById("manage-account-liderados-select-all");
const manageAccountLideradosChecklist = document.getElementById("manage-account-liderados-checklist");
const manageAccountLideradosError = document.getElementById("manage-account-liderados-error");
const manageAccountSaveBtn = document.getElementById("manage-account-save-btn");
if (manageAccountBtn && manageAccountModal) {
let lideradosCandidatos = [];
let lideradosSelecionados = new Set();
function departamentosTexto(usuario) {
return (usuario.departamentos || []).map((d) => d.nome).join(", ");
}
function lideradosFiltrados() {
const termo = manageAccountLideradosSearch.value.trim().toLowerCase();
return lideradosCandidatos.filter(
(u) => !termo || u.nome.toLowerCase().includes(termo) || departamentosTexto(u).toLowerCase().includes(termo)
);
}
function renderManageAccountLiderados() {
const filtrados = lideradosFiltrados();
manageAccountLideradosChecklist.innerHTML = filtrados.length
? filtrados
.map(
(u) => `
<label class="checklist-item">
<input type="checkbox" value="${u.id}" ${lideradosSelecionados.has(u.id) ? "checked" : ""} />
<span class="checklist-item__info">
<span class="checklist-item__nome">${u.nome}</span>
<span class="checklist-item__departamento">${departamentosTexto(u) || "—"}</span>
</span>
</label>`
)
.join("")
: `<p class="checklist-empty">Nenhum usuário encontrado.</p>`;
const todosMarcados = filtrados.length > 0 && filtrados.every((u) => lideradosSelecionados.has(u.id));
const algumMarcado = filtrados.some((u) => lideradosSelecionados.has(u.id));
manageAccountLideradosSelectAll.disabled = filtrados.length === 0;
manageAccountLideradosSelectAll.checked = todosMarcados;
manageAccountLideradosSelectAll.indeterminate = !todosMarcados && algumMarcado;
}
manageAccountLideradosChecklist.addEventListener("change", (event) => {
const checkbox = event.target.closest('input[type="checkbox"]');
if (!checkbox) return;
const id = Number(checkbox.value);
if (checkbox.checked) lideradosSelecionados.add(id);
else lideradosSelecionados.delete(id);
renderManageAccountLiderados();
});
manageAccountLideradosSearch.addEventListener("input", renderManageAccountLiderados);
manageAccountLideradosSelectAll.addEventListener("change", () => {
const filtrados = lideradosFiltrados();
if (manageAccountLideradosSelectAll.checked) {
filtrados.forEach((u) => lideradosSelecionados.add(u.id));
} else {
filtrados.forEach((u) => lideradosSelecionados.delete(u.id));
}
renderManageAccountLiderados();
});
manageAccountBtn.addEventListener("click", async () => {
dropdown.hidden = true;
manageAccountLideradosError.textContent = "";
if (me.lideranca) {
manageAccountLideradosField.hidden = false;
manageAccountSaveBtn.hidden = false;
manageAccountLideradosSearch.value = "";
lideradosCandidatos = (await pidApiRequest("/usuarios-resumo/"))
.filter((u) => u.id !== me.id)
.slice()
.sort((a, b) => a.nome.localeCompare(b.nome));
lideradosSelecionados = new Set((me.liderados || []).map((u) => u.id));
renderManageAccountLiderados();
} else {
manageAccountLideradosField.hidden = true;
manageAccountSaveBtn.hidden = true;
}
manageAccountModal.hidden = false;
});
manageAccountCloseBtn.addEventListener("click", () => {
manageAccountModal.hidden = true;
});
manageAccountSaveBtn.addEventListener("click", async () => {
const liderados = Array.from(lideradosSelecionados);
try {
const atualizados = await pidApiRequest("/me/liderados/", { method: "PATCH", body: { liderados } });
me.liderados = atualizados;
manageAccountModal.hidden = true;
} catch (e) {
manageAccountLideradosError.textContent = e.message;
}
});
}
const passwordModal = document.getElementById("password-modal");
if (!passwordModal || !manageAccountChangePasswordBtn) return;
const currentInput = document.getElementById("pwd-current");
const newInput = document.getElementById("pwd-new");
const confirmInput = document.getElementById("pwd-confirm");
const pwdError = document.getElementById("pwd-error");
const pwdSaveBtn = document.getElementById("pwd-save-btn");
const pwdCancelBtn = document.getElementById("pwd-cancel-btn");
pidBindPasswordToggle(document.getElementById("pwd-current-toggle"), currentInput);
pidBindPasswordToggle(document.getElementById("pwd-new-toggle"), newInput);
pidBindPasswordToggle(document.getElementById("pwd-confirm-toggle"), confirmInput);
function closePasswordModal() {
passwordModal.hidden = true;
}
manageAccountChangePasswordBtn.addEventListener("click", () => {
manageAccountModal.hidden = true;
currentInput.value = "";
newInput.value = "";
confirmInput.value = "";
currentInput.type = "password";
newInput.type = "password";
confirmInput.type = "password";
pwdError.textContent = "";
passwordModal.hidden = false;
currentInput.focus();
});
pwdCancelBtn.addEventListener("click", closePasswordModal);
pwdSaveBtn.addEventListener("click", async () => {
const current = currentInput.value;
const next = newInput.value;
const confirmValue = confirmInput.value;
if (!next) {
pwdError.textContent = "Informe a nova senha.";
return;
}
if (next !== confirmValue) {
pwdError.textContent = "A confirmação não corresponde à nova senha.";
return;
}
try {
await pidApiRequest("/me/senha/", {
method: "POST",
body: { senha_atual: current, nova_senha: next },
});
closePasswordModal();
} catch (e) {
pwdError.textContent = e.message;
}
});
});