Changeset c1b757d in Klonkt for src/views/pages/admin-google.ejs


Ignore:
Timestamp:
06/21/2026 07:01:45 PM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
1ee5f65
Parents:
e25438a
Message:

feat(admin): Google setup revised — beginner-friendly explanation

The explanation was buried in a collapsed <details> with fragmented text. Now:
always-visible numbered steps (1-5) in plain language, with the redirect URI
inline at step 4 + a Copy button, a short "must match exactly" warning,
and a "no APIs needed" tip. NL/EN/DE (full sentences instead of fragments).

Co-Authored-By: Claude <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/views/pages/admin-google.ejs

    re25438a rc1b757d  
    88  <section class="set-card">
    99    <h2><%= t('agoog.card_title') %></h2>
    10     <p class="set-help"><%= t('agoog.card_help_pre') %> <strong><%= t('agoog.card_help_own') %></strong>
    11       <%= t('agoog.card_help_mid') %>
    12       <a href="https://console.cloud.google.com/apis/credentials" target="_blank" rel="noopener">console.cloud.google.com</a>
    13       <%= t('agoog.card_help_post') %>
     10    <p class="set-help"><%- t('agoog.intro') %>
    1411      <% if (google && google.configured) { %><strong><%= t('agoog.status_set') %></strong><% } else { %><%= t('agoog.status_unset') %><% } %></p>
    1512
    16     <details class="set-google-guide">
    17       <summary><%= t('agoog.guide_summary') %></summary>
    18       <ol class="set-google-steps">
    19         <li><%= t('agoog.step1_pre') %> <a href="https://console.cloud.google.com/" target="_blank" rel="noopener">Google Cloud Console</a> <%= t('agoog.step1_post') %></li>
    20         <li><strong>APIs &amp; Services → OAuth consent screen</strong>: <%= t('agoog.step2_usertype') %> <strong>External</strong>. <%= t('agoog.step2_scopes_pre') %> <code>email</code>, <code>profile</code> <%= t('agoog.step2_scopes_and') %> <code>openid</code> <%= t('agoog.step2_scopes_post') %> <%= t('agoog.step2_testmode') %></li>
    21         <li><strong>APIs &amp; Services → Credentials → Create credentials → OAuth client ID</strong>, <%= t('agoog.step3_type') %> <strong>Web application</strong>.</li>
    22         <li><%= t('agoog.step4_pre') %> <strong>Authorized redirect URIs</strong><%= t('agoog.step4_post') %></li>
    23         <li><%= t('agoog.step5_pre') %> <strong>Client ID</strong> + <strong>Client Secret</strong> <%= t('agoog.step5_post') %></li>
    24       </ol>
    25       <p class="set-help" style="margin:.5rem 0 0"><strong><%= t('agoog.note_label') %></strong> <%= t('agoog.note_pre') %> <strong><%= t('agoog.note_noapi') %></strong> <%= t('agoog.note_mid') %> <em><%= t('agoog.note_not') %></em> <%= t('agoog.note_post') %></p>
    26     </details>
    27 
    28     <% if (google && google.redirectUri) { %>
    29       <div class="set-redirect">
    30         <div class="set-redirect-label"><%= t('agoog.redirect_label') %></div>
    31         <code class="set-redirect-url" style="user-select:all"><%= google.redirectUri %></code>
    32         <ol class="set-redirect-steps">
    33           <li><%= t('agoog.rstep1_pre') %> <a href="https://console.cloud.google.com/apis/credentials" target="_blank" rel="noopener">Google Cloud Console → APIs &amp; Services → Credentials</a>.</li>
    34           <li><%= t('agoog.rstep2') %></li>
    35           <li><%= t('agoog.rstep3_pre') %> <strong>Authorized redirect URIs</strong> → <%= t('agoog.rstep3_mid') %> <strong>+ ADD URI</strong> <%= t('agoog.rstep3_post') %></li>
    36           <li><%= t('agoog.rstep4_pre') %> <strong>Save</strong> <%= t('agoog.rstep4_post') %></li>
    37         </ol>
    38         <p class="set-redirect-warn"><%= t('agoog.warn_pre') %> <strong><%= t('agoog.warn_exact') %></strong> <%= t('agoog.warn_mid1') %> <code>https://</code> (<%= t('agoog.warn_nohttp') %> <code>http</code>)<%= t('agoog.warn_mid2') %> <strong><%= t('agoog.warn_noslash') %></strong> <%= t('agoog.warn_mid3') %> <em><%= t('agoog.warn_error') %></em>.</p>
    39       </div>
    40     <% } else { %>
    41       <p class="set-help" style="color:var(--accent)"><%= t('agoog.set_baseurl_pre') %> <code>PUBLIC_BASE_URL</code> <%= t('agoog.set_baseurl_post') %></p>
    42     <% } %>
     13    <ol class="gg-steps">
     14      <li>
     15        <span class="gg-num">1</span>
     16        <div class="gg-body"><%- t('agoog.g1') %> <a href="https://console.cloud.google.com/" target="_blank" rel="noopener">Google Cloud Console ↗</a></div>
     17      </li>
     18      <li>
     19        <span class="gg-num">2</span>
     20        <div class="gg-body"><%- t('agoog.g2') %></div>
     21      </li>
     22      <li>
     23        <span class="gg-num">3</span>
     24        <div class="gg-body"><%- t('agoog.g3') %></div>
     25      </li>
     26      <li>
     27        <span class="gg-num">4</span>
     28        <div class="gg-body">
     29          <%- t('agoog.g4') %>
     30          <% if (google && google.redirectUri) { %>
     31            <div class="gg-redirect">
     32              <code class="gg-url"><%= google.redirectUri %></code>
     33              <button type="button" class="btn gg-copy" data-copy="<%= google.redirectUri %>"><%= t('agoog.copy') %></button>
     34            </div>
     35            <p class="gg-warn"><%- t('agoog.warn_short') %></p>
     36          <% } else { %>
     37            <p class="gg-warn" style="color:var(--accent)"><%- t('agoog.need_baseurl') %></p>
     38          <% } %>
     39        </div>
     40      </li>
     41      <li>
     42        <span class="gg-num">5</span>
     43        <div class="gg-body"><%- t('agoog.g5') %></div>
     44      </li>
     45    </ol>
     46    <p class="gg-tip"><%- t('agoog.no_api_note') %></p>
    4347
    4448    <form method="post" action="/admin/settings/google" class="set-form">
     
    99103.set-redirect-warn { margin: 0.85rem 0 0; font-size: 0.85rem; color: var(--ink-muted); }
    100104.set-redirect-warn code { background: var(--paper-2); padding: 0.05rem 0.35rem; border-radius: 4px; }
     105/* Genummerde, altijd-zichtbare stap-voor-stap-uitleg (beginnervriendelijk) */
     106.gg-steps { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-direction: column; gap: 0.85rem; }
     107.gg-steps > li { display: flex; gap: 0.7rem; align-items: flex-start; }
     108.gg-num { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; background: var(--accent); color: #fff; font-weight: 700; font-size: 0.85rem; display: inline-flex; align-items: center; justify-content: center; }
     109.gg-body { font-size: 0.92rem; line-height: 1.5; color: var(--ink); padding-top: 2px; min-width: 0; }
     110.gg-body code { background: var(--paper-2); padding: 0.05rem 0.35rem; border-radius: 4px; font-size: 0.88em; }
     111.gg-redirect { display: flex; gap: 0.5rem; align-items: stretch; margin: 0.5rem 0 0.3rem; flex-wrap: wrap; }
     112.gg-url { flex: 1 1 220px; min-width: 0; padding: 0.5rem 0.7rem; background: var(--paper-2); border: 1px dashed var(--accent); border-radius: 6px; font-size: 0.85rem; word-break: break-all; align-self: center; }
     113.gg-copy { flex: 0 0 auto; }
     114.gg-warn { font-size: 0.82rem; color: var(--ink-muted); margin: 0.3rem 0 0; }
     115.gg-tip { font-size: 0.85rem; color: var(--ink-muted); background: var(--paper); border: 1px solid var(--rule); border-radius: 8px; padding: 0.6rem 0.8rem; margin: 0 0 1.25rem; }
    101116</style>
     117<script>
     118  (function () {
     119    if (window.__ggCopyWired) return;
     120    window.__ggCopyWired = true;
     121    document.addEventListener('click', function (e) {
     122      var b = e.target.closest && e.target.closest('.gg-copy');
     123      if (!b) return;
     124      e.preventDefault();
     125      var txt = b.getAttribute('data-copy') || '';
     126      var done = function () { var o = b.getAttribute('data-label') || b.textContent; b.setAttribute('data-label', o); b.textContent = '<%= t('agoog.copied') %>'; setTimeout(function () { b.textContent = o; }, 1500); };
     127      if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(txt).then(done, function () {}); }
     128      else { try { var ta = document.createElement('textarea'); ta.value = txt; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); ta.remove(); done(); } catch (_) {} }
     129    });
     130  })();
     131</script>
Note: See TracChangeset for help on using the changeset viewer.