From 404a1c34e8a4b0e343ca661fc0c36b5a9d2f6986 Mon Sep 17 00:00:00 2001 From: deploy Date: Mon, 28 Sep 2026 15:33:11 +0000 Subject: [PATCH] chore(tenants): conteudo de publico/ atualizado --- moldes/consolidado/96-publico-configmap.yaml | 80 +++++++++++++++++++- tenants/plataforma/96-publico-configmap.yaml | 80 +++++++++++++++++++- 2 files changed, 154 insertions(+), 6 deletions(-) diff --git a/moldes/consolidado/96-publico-configmap.yaml b/moldes/consolidado/96-publico-configmap.yaml index ee2a444..7bb1586 100644 --- a/moldes/consolidado/96-publico-configmap.yaml +++ b/moldes/consolidado/96-publico-configmap.yaml @@ -1554,7 +1554,7 @@ data: - + @@ -1595,7 +1595,8 @@ data: COBRANCA: "/api/cliente/cobranca", TERMO: "/api/cliente/termo-de-dados", FATURAS: "/api/cliente/faturas", - PLANO: "/api/cliente/plano" + PLANO: "/api/cliente/plano", + MODULOS: "/api/cliente/modulos" }; var CHAVE_VERIFIER = "atm.conta.verifier"; @@ -1930,7 +1931,8 @@ data: var alvo = cartaoDo(tenant); if (!alvo || alvo.querySelector(".plano-troca")) return; alvo.insertAdjacentHTML("beforeend", '
' - + '
'); + + ' ' + + ''); } function cartaoDo(tenant) { @@ -2011,6 +2013,78 @@ data: if (b) agirNoPlano(b); }); + /* ── A LOJA DE MODULOS ─────────────────────────────────────────────────────── + * + * Mesmas regras da troca de plano: comprar vale na hora e o valor entra na + * proxima cobranca; cancelar vale no fim do periodo pago. O que o plano ja + * inclui aparece como incluido, sem botao. */ + + function pedirModulo(metodo, tenant, modulo) { + return fetch(CONFIG.MODULOS + "/" + encodeURIComponent(tenant) + (modulo ? "/" + encodeURIComponent(modulo) : ""), { + method: metodo, headers: { Authorization: "Bearer " + token } + }).then(function (r) { + if (r.ok) return r.json(); + return r.json().catch(function () { return {}; }).then(function (d) { + throw new Error(d.erro || "Não consegui agora. Tente de novo em instantes."); + }); + }); + } + + function blocoDaLoja(d) { + var sufixo = d.ciclo === "ANUAL" ? "/ano" : "/mês"; + var itens = (d.modulos || []).map(function (m) { + var nome = escapar(m.nome); + if (m.incluidoNoPlano) return '
  • ' + nome + ' incluído no plano
  • '; + if (m.comprado && m.cancelamentoEm) { + return '
  • ' + nome + " " + escapar(reais(m.valor)) + sufixo + + ' (sai em ' + escapar(dataCurta(m.cancelamentoEm)) + ")
  • "; + } + if (m.comprado) { + return '
  • ' + nome + " " + escapar(reais(m.valor)) + sufixo + ' comprado ' + + '
  • '; + } + return '
  • ' + nome + " " + escapar(reais(m.valor)) + sufixo + " " + + '
  • '; + }).join(""); + return 'Módulos avulsos' + + '

    Comprar libera na hora; o valor entra na próxima cobrança. Cancelar vale no fim do período pago.

    ' + + '" + + '

    '; + } + + function agirNaLoja(botao) { + var caixa = botao.closest("[data-tenant-plano]"); + var tenant = caixa.getAttribute("data-tenant-plano"); + var acao = botao.getAttribute("data-modulo-acao"); + var modulo = botao.getAttribute("data-modulo"); + var mostrar = function (d) { caixa.innerHTML = blocoDaLoja(d); }; + var erro = function (e) { + var p = caixa.querySelector(".erro-form"); + if (p) { p.textContent = e.message; p.classList.remove("oculto"); } + botao.disabled = false; + }; + botao.disabled = true; + if (acao === "abrir") return pedirModulo("GET", tenant).then(mostrar).catch(erro); + if (acao === "comprar") { + if (typeof window.confirm === "function" && !window.confirm("Comprar " + botao.getAttribute("data-nome") + + "? Libera na hora; o valor entra na próxima cobrança.")) { botao.disabled = false; return Promise.resolve(); } + return pedirModulo("POST", tenant, modulo).then(mostrar).catch(erro); + } + if (acao === "cancelar") { + if (typeof window.confirm === "function" && !window.confirm("Cancelar este módulo? Ele continua até o fim do período pago.")) + { botao.disabled = false; return Promise.resolve(); } + return pedirModulo("DELETE", tenant, modulo).then(mostrar).catch(erro); + } + return Promise.resolve(); + } + + if (produtos) produtos.addEventListener("click", function (ev) { + var b = ev.target && ev.target.closest ? ev.target.closest("[data-modulo-acao]") : null; + if (b) agirNaLoja(b); + }); + /* ── AS FATURAS DA ASSINATURA ──────────────────────────────────────────────── * * As cobranças da Athletic Map para o cliente (não as dos alunos), com o link diff --git a/tenants/plataforma/96-publico-configmap.yaml b/tenants/plataforma/96-publico-configmap.yaml index 3694455..a016a83 100644 --- a/tenants/plataforma/96-publico-configmap.yaml +++ b/tenants/plataforma/96-publico-configmap.yaml @@ -1554,7 +1554,7 @@ data: - + @@ -1595,7 +1595,8 @@ data: COBRANCA: "/api/cliente/cobranca", TERMO: "/api/cliente/termo-de-dados", FATURAS: "/api/cliente/faturas", - PLANO: "/api/cliente/plano" + PLANO: "/api/cliente/plano", + MODULOS: "/api/cliente/modulos" }; var CHAVE_VERIFIER = "atm.conta.verifier"; @@ -1930,7 +1931,8 @@ data: var alvo = cartaoDo(tenant); if (!alvo || alvo.querySelector(".plano-troca")) return; alvo.insertAdjacentHTML("beforeend", '
    ' - + '
    '); + + ' ' + + ''); } function cartaoDo(tenant) { @@ -2011,6 +2013,78 @@ data: if (b) agirNoPlano(b); }); + /* ── A LOJA DE MODULOS ─────────────────────────────────────────────────────── + * + * Mesmas regras da troca de plano: comprar vale na hora e o valor entra na + * proxima cobranca; cancelar vale no fim do periodo pago. O que o plano ja + * inclui aparece como incluido, sem botao. */ + + function pedirModulo(metodo, tenant, modulo) { + return fetch(CONFIG.MODULOS + "/" + encodeURIComponent(tenant) + (modulo ? "/" + encodeURIComponent(modulo) : ""), { + method: metodo, headers: { Authorization: "Bearer " + token } + }).then(function (r) { + if (r.ok) return r.json(); + return r.json().catch(function () { return {}; }).then(function (d) { + throw new Error(d.erro || "Não consegui agora. Tente de novo em instantes."); + }); + }); + } + + function blocoDaLoja(d) { + var sufixo = d.ciclo === "ANUAL" ? "/ano" : "/mês"; + var itens = (d.modulos || []).map(function (m) { + var nome = escapar(m.nome); + if (m.incluidoNoPlano) return '
  • ' + nome + ' incluído no plano
  • '; + if (m.comprado && m.cancelamentoEm) { + return '
  • ' + nome + " " + escapar(reais(m.valor)) + sufixo + + ' (sai em ' + escapar(dataCurta(m.cancelamentoEm)) + ")
  • "; + } + if (m.comprado) { + return '
  • ' + nome + " " + escapar(reais(m.valor)) + sufixo + ' comprado ' + + '
  • '; + } + return '
  • ' + nome + " " + escapar(reais(m.valor)) + sufixo + " " + + '
  • '; + }).join(""); + return 'Módulos avulsos' + + '

    Comprar libera na hora; o valor entra na próxima cobrança. Cancelar vale no fim do período pago.

    ' + + '" + + '

    '; + } + + function agirNaLoja(botao) { + var caixa = botao.closest("[data-tenant-plano]"); + var tenant = caixa.getAttribute("data-tenant-plano"); + var acao = botao.getAttribute("data-modulo-acao"); + var modulo = botao.getAttribute("data-modulo"); + var mostrar = function (d) { caixa.innerHTML = blocoDaLoja(d); }; + var erro = function (e) { + var p = caixa.querySelector(".erro-form"); + if (p) { p.textContent = e.message; p.classList.remove("oculto"); } + botao.disabled = false; + }; + botao.disabled = true; + if (acao === "abrir") return pedirModulo("GET", tenant).then(mostrar).catch(erro); + if (acao === "comprar") { + if (typeof window.confirm === "function" && !window.confirm("Comprar " + botao.getAttribute("data-nome") + + "? Libera na hora; o valor entra na próxima cobrança.")) { botao.disabled = false; return Promise.resolve(); } + return pedirModulo("POST", tenant, modulo).then(mostrar).catch(erro); + } + if (acao === "cancelar") { + if (typeof window.confirm === "function" && !window.confirm("Cancelar este módulo? Ele continua até o fim do período pago.")) + { botao.disabled = false; return Promise.resolve(); } + return pedirModulo("DELETE", tenant, modulo).then(mostrar).catch(erro); + } + return Promise.resolve(); + } + + if (produtos) produtos.addEventListener("click", function (ev) { + var b = ev.target && ev.target.closest ? ev.target.closest("[data-modulo-acao]") : null; + if (b) agirNaLoja(b); + }); + /* ── AS FATURAS DA ASSINATURA ──────────────────────────────────────────────── * * As cobranças da Athletic Map para o cliente (não as dos alunos), com o link