{"id":1397,"date":"2025-12-30T16:01:44","date_gmt":"2025-12-30T19:01:44","guid":{"rendered":"https:\/\/pensecre.org\/?page_id=1397"},"modified":"2026-04-11T14:29:25","modified_gmt":"2026-04-11T17:29:25","slug":"instrutor","status":"publish","type":"page","link":"https:\/\/pensecre.org\/en\/instrutor\/","title":{"rendered":"Instrutor"},"content":{"rendered":"<p>[et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.24.0&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.24.0&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.24.0&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_code _builder_version=&#8221;4.24.0&#8243; _module_preset=&#8221;default&#8221; hover_enabled=&#8221;0&#8243; sticky_enabled=&#8221;0&#8243;]  <script src=\"https:\/\/accounts.google.com\/gsi\/client\" async defer><\/script><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><!-- Manual GSI button container (no auto prompt) --><!-- [et_pb_line_break_holder] -->    <\/p>\n<div id=\"gSignInDiv\"><\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/p>\n<div style=\"margin-top:16px\"><!-- [et_pb_line_break_holder] -->    <strong>Token do estudante:<\/strong><!-- [et_pb_line_break_holder] -->    <\/p>\n<div id=\"studentTokenContainer\" style=\"margin-top:8px;\"><!-- [et_pb_line_break_holder] -->      <\/p>\n<pre id=\"studentToken\" style=\"white-space:pre-wrap;word-break:break-all;background:#e6f3ff;padding:8px;border-radius:4px;display:none;max-width:800px;\"><\/pre>\n<p><!-- [et_pb_line_break_holder] -->      <button id=\"copySBtn\" style=\"margin-top:8px;display:none;\">Copiar token do estudante<\/button><!-- [et_pb_line_break_holder] -->    <\/div>\n<p><!-- [et_pb_line_break_holder] -->  <\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <script><!-- [et_pb_line_break_holder] -->    \/\/ Initialize Google Identity Services and render button without auto-prompt<!-- [et_pb_line_break_holder] -->    function initGSI() {<!-- [et_pb_line_break_holder] -->      const clientId = '782008429116-vspf0ukjvbjlksks54upbrootuj9rtc1.apps.googleusercontent.com';<!-- [et_pb_line_break_holder] -->      if (!window.google || !google.accounts || !google.accounts.id) {<!-- [et_pb_line_break_holder] -->        \/\/ Wait until the library loads<!-- [et_pb_line_break_holder] -->        const t = setInterval(() => {<!-- [et_pb_line_break_holder] -->          if (window.google && google.accounts && google.accounts.id) {<!-- [et_pb_line_break_holder] -->            clearInterval(t);<!-- [et_pb_line_break_holder] -->            initGSI();<!-- [et_pb_line_break_holder] -->          }<!-- [et_pb_line_break_holder] -->        }, 100);<!-- [et_pb_line_break_holder] -->        return;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      google.accounts.id.initialize({<!-- [et_pb_line_break_holder] -->        client_id: clientId,<!-- [et_pb_line_break_holder] -->        callback: handleCredentialResponse,<!-- [et_pb_line_break_holder] -->        auto_select: false,<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      google.accounts.id.renderButton(<!-- [et_pb_line_break_holder] -->        document.getElementById('gSignInDiv'),<!-- [et_pb_line_break_holder] -->        { theme: 'outline', size: 'large' }<!-- [et_pb_line_break_holder] -->      );<!-- [et_pb_line_break_holder] -->      \/\/ Do not call google.accounts.id.prompt() \u2014 this prevents automatic popups<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    window.addEventListener('load', initGSI);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    async function handleCredentialResponse(response) {<!-- [et_pb_line_break_holder] -->      const baseUrl = window.location.hostname === 'localhost' ? 'http:\/\/localhost:8080' : 'https:\/\/auth-pense-cre-782008429116.southamerica-east1.run.app';<!-- [et_pb_line_break_holder] -->      const id_token = response.credential;<!-- [et_pb_line_break_holder] -->      const statusMsg = (m) => console.log('[auth-client]', m);<!-- [et_pb_line_break_holder] -->      try {<!-- [et_pb_line_break_holder] -->        const res = await fetch(baseUrl + '\/admin\/login\/google', {<!-- [et_pb_line_break_holder] -->          method: 'POST',<!-- [et_pb_line_break_holder] -->          headers: {'Content-Type': 'application\/json'},<!-- [et_pb_line_break_holder] -->          body: JSON.stringify({ id_token })<!-- [et_pb_line_break_holder] -->        });<!-- [et_pb_line_break_holder] -->        if (!res.ok) {<!-- [et_pb_line_break_holder] -->          let errMsg = 'Auth failed: ' + res.status;<!-- [et_pb_line_break_holder] -->          alert(errMsg);<!-- [et_pb_line_break_holder] -->          return;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        const json = await res.json();<!-- [et_pb_line_break_holder] -->        statusMsg('received tokens');<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        \/\/ Store admin token<!-- [et_pb_line_break_holder] -->        const adminToken = json.admin_token;<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        \/\/ Display student token<!-- [et_pb_line_break_holder] -->        const studentTokenEl = document.getElementById('studentToken');<!-- [et_pb_line_break_holder] -->        const copySBtn = document.getElementById('copySBtn');<!-- [et_pb_line_break_holder] -->        studentTokenEl.textContent = json.student_token || '';<!-- [et_pb_line_break_holder] -->        studentTokenEl.style.display = 'block';<!-- [et_pb_line_break_holder] -->        copySBtn.style.display = 'inline-block';<!-- [et_pb_line_break_holder] -->        copySBtn.onclick = async () => {<!-- [et_pb_line_break_holder] -->          try {<!-- [et_pb_line_break_holder] -->            await navigator.clipboard.writeText(studentTokenEl.textContent);<!-- [et_pb_line_break_holder] -->            copySBtn.textContent = 'Copied!';<!-- [et_pb_line_break_holder] -->            setTimeout(() => (copySBtn.textContent = 'Copy student token'), 1500);<!-- [et_pb_line_break_holder] -->          } catch (e) {<!-- [et_pb_line_break_holder] -->            console.error('copy failed', e);<!-- [et_pb_line_break_holder] -->          }<!-- [et_pb_line_break_holder] -->        };<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        \/\/ Fetch estacoes using admin token<!-- [et_pb_line_break_holder] -->        try {<!-- [et_pb_line_break_holder] -->          const tokensRes = await fetch(baseUrl + '\/admin\/tokens', {<!-- [et_pb_line_break_holder] -->            method: 'GET',<!-- [et_pb_line_break_holder] -->            headers: {'Authorization': 'Bearer ' + adminToken}<!-- [et_pb_line_break_holder] -->          });<!-- [et_pb_line_break_holder] -->          if (tokensRes.ok) {<!-- [et_pb_line_break_holder] -->            const tokensJson = await tokensRes.json();<!-- [et_pb_line_break_holder] -->            const estacoes = tokensJson.estacoes || [];<!-- [et_pb_line_break_holder] -->            <!-- [et_pb_line_break_holder] -->            \/\/ Populate dropdown with estacoes<!-- [et_pb_line_break_holder] -->            const dropdown = document.createElement('select');<!-- [et_pb_line_break_holder] -->            dropdown.id = 'estacaoSelect';<!-- [et_pb_line_break_holder] -->            dropdown.style.marginTop = '8px';<!-- [et_pb_line_break_holder] -->            dropdown.style.width = '178px';<!-- [et_pb_line_break_holder] -->            estacoes.forEach(name => {<!-- [et_pb_line_break_holder] -->              const option = document.createElement('option');<!-- [et_pb_line_break_holder] -->              option.value = name;<!-- [et_pb_line_break_holder] -->              option.textContent = name;<!-- [et_pb_line_break_holder] -->              dropdown.appendChild(option);<!-- [et_pb_line_break_holder] -->            });<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->            const input = document.createElement('input');<!-- [et_pb_line_break_holder] -->            input.type = 'text';<!-- [et_pb_line_break_holder] -->            input.id = 'senhaInput';<!-- [et_pb_line_break_holder] -->            input.placeholder = 'Nova senha de acesso';<!-- [et_pb_line_break_holder] -->            input.style.marginLeft = '8px';<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->            const button = document.createElement('button');<!-- [et_pb_line_break_holder] -->            button.textContent = 'Salvar senha de acesso';<!-- [et_pb_line_break_holder] -->            button.style.marginLeft = '8px';<!-- [et_pb_line_break_holder] -->            button.onclick = async () => {<!-- [et_pb_line_break_holder] -->              const name = dropdown.value;<!-- [et_pb_line_break_holder] -->              const key = input.value;<!-- [et_pb_line_break_holder] -->              if (!name || !key) return;<!-- [et_pb_line_break_holder] -->              try {<!-- [et_pb_line_break_holder] -->                const res = await fetch(baseUrl + '\/access', {<!-- [et_pb_line_break_holder] -->                  method: 'POST',<!-- [et_pb_line_break_holder] -->                  headers: {'Content-Type': 'application\/json'},<!-- [et_pb_line_break_holder] -->                  body: JSON.stringify({token: json.student_token, name, key})<!-- [et_pb_line_break_holder] -->                });<!-- [et_pb_line_break_holder] -->                if (res.ok && await res.text() === 'Success') {<!-- [et_pb_line_break_holder] -->                  button.textContent = 'Success';<!-- [et_pb_line_break_holder] -->                  setTimeout(() => button.textContent = 'Salvar senha de acesso', 2000);<!-- [et_pb_line_break_holder] -->                } else {<!-- [et_pb_line_break_holder] -->                  alert('Error');<!-- [et_pb_line_break_holder] -->                }<!-- [et_pb_line_break_holder] -->              } catch (err) {<!-- [et_pb_line_break_holder] -->                alert('Error: ' + err);<!-- [et_pb_line_break_holder] -->              }<!-- [et_pb_line_break_holder] -->            };<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->            const container = document.getElementById('studentTokenContainer');<!-- [et_pb_line_break_holder] -->            container.appendChild(document.createElement('br'));<!-- [et_pb_line_break_holder] -->            container.appendChild(dropdown);<!-- [et_pb_line_break_holder] -->            container.appendChild(input);<!-- [et_pb_line_break_holder] -->            container.appendChild(button);<!-- [et_pb_line_break_holder] -->          }<!-- [et_pb_line_break_holder] -->        } catch (err) {<!-- [et_pb_line_break_holder] -->          console.error('Error fetching estacoes', err);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      } catch (err) {<!-- [et_pb_line_break_holder] -->        console.error('Network error', err);<!-- [et_pb_line_break_holder] -->        alert('Network error: ' + err);<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ Fetch config on load to get the Google Client ID<!-- [et_pb_line_break_holder] -->    window.addEventListener('load', async () => {<!-- [et_pb_line_break_holder] -->      const baseUrl = window.location.hostname === 'localhost' ? 'http:\/\/localhost:8080' : 'https:\/\/auth-pense-cre-782008429116.southamerica-east1.run.app';<!-- [et_pb_line_break_holder] -->      try {<!-- [et_pb_line_break_holder] -->        const res = await fetch(baseUrl + '\/config');<!-- [et_pb_line_break_holder] -->        if (!res.ok) {<!-- [et_pb_line_break_holder] -->          throw new Error('Failed to fetch config: ' + res.status);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        const config = await res.json();<!-- [et_pb_line_break_holder] -->        \/\/ Initialize GSI with dynamic client ID<!-- [et_pb_line_break_holder] -->        google.accounts.id.initialize({<!-- [et_pb_line_break_holder] -->          client_id: config.google_client_id,<!-- [et_pb_line_break_holder] -->          callback: handleCredentialResponse,<!-- [et_pb_line_break_holder] -->          auto_select: false,<!-- [et_pb_line_break_holder] -->        });<!-- [et_pb_line_break_holder] -->        google.accounts.id.renderButton(<!-- [et_pb_line_break_holder] -->          document.getElementById('gSignInDiv'),<!-- [et_pb_line_break_holder] -->          { theme: 'outline', size: 'large' }<!-- [et_pb_line_break_holder] -->        );<!-- [et_pb_line_break_holder] -->      } catch (err) {<!-- [et_pb_line_break_holder] -->        console.error('Error loading config', err);<!-- [et_pb_line_break_holder] -->        alert('Error loading config: ' + err);<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    });<!-- [et_pb_line_break_holder] -->  <\/script>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","courseId":0,"footnotes":""},"class_list":["post-1397","page","type-page","status-publish","hentry"],"acf":[],"jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/pensecre.org\/en\/wp-json\/wp\/v2\/pages\/1397","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pensecre.org\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/pensecre.org\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/pensecre.org\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pensecre.org\/en\/wp-json\/wp\/v2\/comments?post=1397"}],"version-history":[{"count":14,"href":"https:\/\/pensecre.org\/en\/wp-json\/wp\/v2\/pages\/1397\/revisions"}],"predecessor-version":[{"id":1417,"href":"https:\/\/pensecre.org\/en\/wp-json\/wp\/v2\/pages\/1397\/revisions\/1417"}],"wp:attachment":[{"href":"https:\/\/pensecre.org\/en\/wp-json\/wp\/v2\/media?parent=1397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}