Changeset 9a00f28 in Klonkt for src/views/pages/admin-paid.ejs


Ignore:
Timestamp:
07/22/2026 08:18:39 AM (7 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
6b5d7da
Parents:
96c714f
git-author:
Robin <roboburr@…> (07/22/2026 08:18:19 AM)
git-committer:
Robin <roboburr@…> (07/22/2026 08:18:39 AM)
Message:

Fix: test feedback round, cirkels tagline + report details + full i18n

Three findings from Bart's test pass, tied together by the new i18n keys:

  1. The admin tagline said "Solo mode" even with Cirkels (federation) on. Solo-tenancy now distinguishes: apEnabled -> "Cirkels-modus: jouw site, verbonden met de fediverse", else the solo line. New key in nl/en/de.
  1. Reports only showed who reported; now they show the reason and WHICH post. getNotifications resolves the stored objects URIs of a report: our own /ap/notes/<id> become "Over de post: <title>" links under the description; an empty reason renders "Geen reden opgegeven". Other URIs (the actor itself) are skipped, the row already names the account.
  1. Notificaties and Betaalde posts were hardcoded Dutch on an English-configured Klonkt. Everything now goes through t(): the two admin pages (including their client-side status strings, passed via the JSON data block), the admin menu buttons, and the visitor-facing paid pages (gate, passkey, result). Server-side push payloads translate too, using the SITE's content language (fallback KLONKT_DEFAULT_LANG), and the test ping uses the request language. Full nl/en/de dictionaries.

Changed files:
src/services/i18n.js

  • admin.tagline_cirkels, admin.b_paid/b_push/back, notif.report_about/ report_noreason, and the push.*, apaid.*, pgate.*, ppk.*, pres.* blocks in nl/en/de

src/routes/admin.js, src/views/pages/admin.ejs

  • circlesOn (apEnabled) -> cirkels tagline; menu buttons via t()

src/services/ActivityPubService.js

  • report objects resolved to post links; push payloads via i18nT with pushLang(slug) (site language)

src/views/pages/fedi-notifications.ejs

  • report reason fallback + "Over de post" links (+ styles)

src/routes/admin-push.js, src/views/pages/admin-push.ejs

  • pageTitleKey push.t; all copy + JS status strings via t()

src/routes/admin-paid.js, src/views/pages/admin-paid.ejs

  • pageTitleKey apaid.t; all copy via t(), copy-button label via data-attr

src/routes/paid.js

  • pageTitleKey pres.t / ppk.t

src/views/pages/paid-gate.ejs, paid-passkey.ejs, paid-result.ejs

  • visitor copy + JS strings via t()

src/routes/push.js

  • test notification via resolveLang(req)

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

File:
1 edited

Legend:

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

    r96c714f r9a00f28  
    11<div class="container" style="max-width:640px;margin:1.5rem auto 3rem;padding:0 1rem">
    2   <h1 style="margin:0 0 .3rem">Betaalde posts</h1>
     2  <h1 style="margin:0 0 .3rem"><%= t('apaid.t') %></h1>
    33  <p style="color:var(--ink-soft,#888);margin:0 0 1.2rem">
    4     Koppel je eigen Patreon-campagne. Supporters ontgrendelen betaalde posts met een passkey,
    5     zonder account en zonder cookie. Wij bewaren geen namen of e-mailadressen van supporters,
    6     alleen het versleutelde token van jouw campagne.
     4    <%= t('apaid.intro') %>
    75  </p>
    86
    9   <% if (saved) { %><p style="color:var(--accent);font-weight:600">Opgeslagen.</p><% } %>
     7  <% if (saved) { %><p style="color:var(--accent);font-weight:600"><%= t('apaid.saved') %></p><% } %>
    108  <% if (error) { %><p style="color:#c0392b"><%= error %></p><% } %>
    119  <% if (!secretReady) { %>
    12     <p style="color:#c0392b">Let op: de encryptiesleutel kon niet worden aangemaakt of gelezen (schrijfrechten op de opslagmap?). Zonder sleutel kunnen secrets niet veilig worden opgeslagen.</p>
     10    <p style="color:#c0392b"><%= t('apaid.nokey') %></p>
    1311  <% } %>
    1412
    1513  <p style="margin:.2rem 0 1.2rem">
    16     Status:
     14    <%= t('apaid.status') %>
    1715    <% if (status.connected) { %>
    18       <strong style="color:var(--accent)">verbonden</strong> (campagne <%= status.campaignId %>)
     16      <strong style="color:var(--accent)"><%= t('apaid.connected') %></strong> (<%= t('apaid.campaign') %> <%= status.campaignId %>)
    1917    <% } else if (status.configured) { %>
    20       <strong>ingesteld, nog niet verbonden</strong> (vul een token in)
     18      <strong><%= t('apaid.configured') %></strong>
    2119    <% } else { %>
    22       <strong>nog niet ingesteld</strong>
     20      <strong><%= t('apaid.notyet') %></strong>
    2321    <% } %>
    2422  </p>
    2523
    2624  <div style="border:1px solid var(--border,#333);border-radius:10px;padding:.9rem 1rem;margin:0 0 1.3rem;background:color-mix(in srgb,var(--accent,#6b8f71) 8%,transparent)">
    27     <p style="margin:0 0 .4rem;font-weight:600">Zet deze redirect-URI in je Patreon-client</p>
     25    <p style="margin:0 0 .4rem;font-weight:600"><%= t('apaid.redirect_h') %></p>
    2826    <p style="margin:0 0 .6rem;color:var(--ink-soft,#888);font-size:.9rem">
    29       Bij je Patreon API-client, onder <em>Redirect URIs</em>, moet exact deze regel staan.
    30       Klopt hij niet, dan geeft Patreon een foutmelding in plaats van je supporters terug te sturen.
     27      <%= t('apaid.redirect_p') %>
    3128    </p>
    3229    <div style="display:flex;gap:.5rem;align-items:center">
    3330      <input id="pd-redirect" type="text" readonly value="<%= redirectUri %>" style="flex:1;min-width:0;font-family:monospace;font-size:.9rem">
    34       <button type="button" id="pd-copy" class="btn">Kopieer</button>
     31      <button type="button" id="pd-copy" class="btn" data-copied="<%= t('apaid.copied') %>"><%= t('apaid.copy') %></button>
    3532    </div>
    3633  </div>
    3734
    3835  <form method="post" action="/admin/paid" style="display:flex;flex-direction:column;gap:.9rem">
    39     <label>Patreon client id
     36    <label><%= t('apaid.client_id') %>
    4037      <input type="text" name="client_id" value="<%= status.clientId || '' %>" autocomplete="off" style="width:100%">
    4138    </label>
    42     <label>Patreon client secret
    43       <input type="password" name="client_secret" placeholder="<%= status.hasSecret ? 'blijft ongewijzigd' : '' %>" autocomplete="off" style="width:100%">
    44       <small style="color:var(--ink-soft,#888)">Leeg laten = huidige waarde behouden.</small>
     39    <label><%= t('apaid.client_secret') %>
     40      <input type="password" name="client_secret" placeholder="<%= status.hasSecret ? t('apaid.unchanged') : '' %>" autocomplete="off" style="width:100%">
     41      <small style="color:var(--ink-soft,#888)"><%= t('apaid.keep') %></small>
    4542    </label>
    46     <label>Campagne-id
     43    <label><%= t('apaid.campaign_id') %>
    4744      <input type="text" name="campaign_id" value="<%= status.campaignId || '' %>" autocomplete="off" style="width:100%">
    4845    </label>
    49     <label>Openbare Patreon-pagina
     46    <label><%= t('apaid.public_page') %>
    5047      <input type="url" name="patreon_url" value="<%= status.patreonUrl || '' %>" placeholder="https://www.patreon.com/jouwnaam" autocomplete="off" style="width:100%">
    51       <small style="color:var(--ink-soft,#888)">De link waar bezoekers supporter kunnen worden. Getoond als "Word supporter" wanneer iemand nog niet doneert.</small>
     48      <small style="color:var(--ink-soft,#888)"><%= t('apaid.public_help') %></small>
    5249    </label>
    53     <label>Creator access token
    54       <input type="password" name="access_token" placeholder="blijft ongewijzigd" autocomplete="off" style="width:100%">
     50    <label><%= t('apaid.access') %>
     51      <input type="password" name="access_token" placeholder="<%= t('apaid.unchanged') %>" autocomplete="off" style="width:100%">
    5552    </label>
    56     <label>Creator refresh token
    57       <input type="password" name="refresh_token" placeholder="blijft ongewijzigd" autocomplete="off" style="width:100%">
    58       <small style="color:var(--ink-soft,#888)">De access + refresh token krijg je op je Patreon API-clientpagina. Wij versleutelen ze en verversen automatisch.</small>
     53    <label><%= t('apaid.refresh') %>
     54      <input type="password" name="refresh_token" placeholder="<%= t('apaid.unchanged') %>" autocomplete="off" style="width:100%">
     55      <small style="color:var(--ink-soft,#888)"><%= t('apaid.token_help') %></small>
    5956    </label>
    60     <label>Standaard-steunbedrag voor een betaalde post (euro)
     57    <label><%= t('apaid.min_eur') %>
    6158      <input type="text" name="default_min_eur" value="<%= status.defaultMinCents ? (status.defaultMinCents/100).toFixed(2) : '' %>" inputmode="decimal" style="width:120px">
    6259    </label>
    6360    <div style="display:flex;gap:.6rem;align-items:center">
    64       <button type="submit" class="btn btn-primary">Opslaan</button>
     61      <button type="submit" class="btn btn-primary"><%= t('apaid.save') %></button>
    6562    </div>
    6663  </form>
    6764
    6865  <% if (status.configured || status.connected) { %>
    69     <form method="post" action="/admin/paid/disconnect" data-confirm="Patreon-koppeling verwijderen?" style="margin-top:1rem">
    70       <button type="submit" class="btn btn-danger">Koppeling verwijderen</button>
     66    <form method="post" action="/admin/paid/disconnect" data-confirm="<%= t('apaid.disconnect_confirm') %>" style="margin-top:1rem">
     67      <button type="submit" class="btn btn-danger"><%= t('apaid.disconnect') %></button>
    7168    </form>
    7269  <% } %>
    7370
    74   <p style="margin-top:1.5rem"><a href="/admin">&larr; Terug naar Beheer</a></p>
     71  <p style="margin-top:1.5rem"><a href="/admin">&larr; <%= t('admin.back') %></a></p>
    7572</div>
    7673
     
    8380  btn.addEventListener('click', function () {
    8481    field.select();
    85     var done = function () { var t = btn.textContent; btn.textContent = 'Gekopieerd'; setTimeout(function () { btn.textContent = t; }, 1400); };
     82    var done = function () { var t = btn.textContent; btn.textContent = document.getElementById('pd-copy').getAttribute('data-copied'); setTimeout(function () { btn.textContent = t; }, 1400); };
    8683    if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(field.value).then(done, function () { try { document.execCommand('copy'); done(); } catch (e) {} }); }
    8784    else { try { document.execCommand('copy'); done(); } catch (e) {} }
Note: See TracChangeset for help on using the changeset viewer.