This commit is contained in:
oliver
2026-06-09 13:51:41 -03:00
parent d0c5c1285b
commit 59871432b9
3 changed files with 376 additions and 91 deletions
+93 -13
View File
@@ -21,6 +21,8 @@ const CHAT_URL = `${API_BASE}/etc/chat`; // POST {message,sessionId,email}
const REFERRAL_URL = `${API_BASE}/etc/referral`; // POST {referrer,friend_name,friend_email,uuid}
// WIZZARD=false is written via AGENT_INFO_URL (POST { uuid, key, value })
const CREDITS_URL = `${API_BASE}/payment/credits`; // hidden form POST → 302 Stripe redirect
const INVOICES_URL = `${API_BASE}/invoices`; // GET ?email=
const INVOICE_EMAIL_URL = `${API_BASE}/account/invoice-email`; // POST {email, invoice_email}
const CONTRACT_EXTEND_URL = "https://derez.ai"; // ← replace with Stripe payment link
const CONTRACT_CANCEL_URL = "https://derez.ai"; // ← replace with Stripe cancellation link
@@ -95,9 +97,11 @@ document.addEventListener("DOMContentLoaded", () => {
if (e.target === e.currentTarget) confirmClose(false);
});
// Close user panel when clicking outside of it
// Close user panel when clicking outside of it (skip while modal is open)
document.addEventListener("click", (e) => {
const wrap = document.getElementById("user-panel-wrap");
const modal = document.getElementById("account-backdrop");
if (modal && modal.classList.contains("open")) return;
if (wrap && !wrap.contains(e.target)) closeUserPanel();
});
});
@@ -1008,25 +1012,23 @@ async function savePassword() {
ACCOUNT / USER PANEL
═══════════════════════════════════════════════════════════════ */
function toggleUserPanel() {
const panel = document.getElementById("user-panel");
if (!panel) return;
if (panel.style.display === "none" || panel.style.display === "") {
document.getElementById("user-panel-email-val").textContent =
currentEmail || "";
panel.style.display = "block";
} else {
closeUserPanel();
}
const backdrop = document.getElementById("account-backdrop");
document.getElementById("acct-email-display").textContent =
currentEmail || "";
const invInput = document.getElementById("invoice-email-input");
if (invInput) invInput.value = localStorage.getItem("al_invoice_email") || "";
backdrop.classList.add("open");
loadInvoices();
}
function closeUserPanel() {
const panel = document.getElementById("user-panel");
if (!panel) return;
panel.style.display = "none";
document.getElementById("account-backdrop").classList.remove("open");
const inp = document.getElementById("acct-pw-input");
if (inp) inp.value = "";
const btn = document.getElementById("acct-pw-save-btn");
if (btn) btn.style.display = "none";
const invBtn = document.getElementById("invoice-email-save-btn");
if (invBtn) invBtn.style.display = "none";
}
function toggleAccountPwSave(value) {
@@ -1079,6 +1081,84 @@ async function saveAccountPassword() {
}
}
function toggleInvoiceEmailSave(value) {
const btn = document.getElementById("invoice-email-save-btn");
if (btn) btn.style.display = value ? "flex" : "none";
}
async function saveInvoiceEmail() {
const input = document.getElementById("invoice-email-input");
const btn = document.getElementById("invoice-email-save-btn");
const email = input.value.trim();
if (!email || !isValidEmail(email)) {
toast("Please enter a valid email address.", "warning");
return;
}
btnLoad(btn, "");
try {
const res = await apiFetch(INVOICE_EMAIL_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email: currentEmail, invoice_email: email }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
localStorage.setItem("al_invoice_email", email);
toast("Invoice email saved.", "success");
btn.style.display = "none";
} catch (err) {
toast(err.message, "error");
} finally {
btnReset(btn);
}
}
async function loadInvoices() {
const body = document.getElementById("invoices-body");
body.innerHTML = '<div class="loading-row"><div class="spinner"></div></div>';
try {
const res = await apiFetch(
`${INVOICES_URL}?email=${encodeURIComponent(currentEmail || "")}`,
);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
renderInvoices(Array.isArray(data) ? data : []);
} catch (err) {
body.innerHTML =
'<p class="text-muted" style="font-size:13px;padding:4px 0;">Could not load invoices.</p>';
}
}
function renderInvoices(data) {
const body = document.getElementById("invoices-body");
if (!data.length) {
body.innerHTML =
'<p class="text-muted" style="font-size:13px;padding:4px 0;">No invoices yet.</p>';
return;
}
body.innerHTML = `
<div class="invoice-list">
<div class="invoice-row invoice-row--head">
<span>Date</span>
<span>Agent</span>
<span>Product</span>
<span>Price</span>
</div>
${data
.map(
(inv) => `
<div class="invoice-row">
<span class="invoice-date">${escHtml(inv.date || "—")}</span>
<span class="invoice-uuid">${escHtml(inv.uuid || "—")}</span>
<span class="invoice-product">${escHtml(inv.product || "—")}</span>
<span class="invoice-price">&euro;&thinsp;${escHtml(String(inv.price ?? "—"))}</span>
</div>`,
)
.join("")}
</div>`;
}
/* ═══════════════════════════════════════════════════════════════
RESTART
═══════════════════════════════════════════════════════════════ */