Changeset 9a00f28 in Klonkt for src/views/pages
- Timestamp:
- 07/22/2026 08:18:39 AM (7 weeks ago)
- 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)
- Location:
- src/views/pages
- Files:
-
- 7 edited
-
admin-paid.ejs (modified) (2 diffs)
-
admin-push.ejs (modified) (7 diffs)
-
admin.ejs (modified) (3 diffs)
-
fedi-notifications.ejs (modified) (2 diffs)
-
paid-gate.ejs (modified) (6 diffs)
-
paid-passkey.ejs (modified) (4 diffs)
-
paid-result.ejs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/views/pages/admin-paid.ejs
r96c714f r9a00f28 1 1 <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> 3 3 <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') %> 7 5 </p> 8 6 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><% } %> 10 8 <% if (error) { %><p style="color:#c0392b"><%= error %></p><% } %> 11 9 <% 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> 13 11 <% } %> 14 12 15 13 <p style="margin:.2rem 0 1.2rem"> 16 Status:14 <%= t('apaid.status') %> 17 15 <% 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 %>) 19 17 <% } else if (status.configured) { %> 20 <strong> ingesteld, nog niet verbonden</strong> (vul een token in)18 <strong><%= t('apaid.configured') %></strong> 21 19 <% } else { %> 22 <strong> nog niet ingesteld</strong>20 <strong><%= t('apaid.notyet') %></strong> 23 21 <% } %> 24 22 </p> 25 23 26 24 <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> 28 26 <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') %> 31 28 </p> 32 29 <div style="display:flex;gap:.5rem;align-items:center"> 33 30 <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> 35 32 </div> 36 33 </div> 37 34 38 35 <form method="post" action="/admin/paid" style="display:flex;flex-direction:column;gap:.9rem"> 39 <label> Patreon client id36 <label><%= t('apaid.client_id') %> 40 37 <input type="text" name="client_id" value="<%= status.clientId || '' %>" autocomplete="off" style="width:100%"> 41 38 </label> 42 <label> Patreon client secret43 <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> 45 42 </label> 46 <label> Campagne-id43 <label><%= t('apaid.campaign_id') %> 47 44 <input type="text" name="campaign_id" value="<%= status.campaignId || '' %>" autocomplete="off" style="width:100%"> 48 45 </label> 49 <label> Openbare Patreon-pagina46 <label><%= t('apaid.public_page') %> 50 47 <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> 52 49 </label> 53 <label> Creator access token54 <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%"> 55 52 </label> 56 <label> Creator refresh token57 <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> 59 56 </label> 60 <label> Standaard-steunbedrag voor een betaalde post (euro)57 <label><%= t('apaid.min_eur') %> 61 58 <input type="text" name="default_min_eur" value="<%= status.defaultMinCents ? (status.defaultMinCents/100).toFixed(2) : '' %>" inputmode="decimal" style="width:120px"> 62 59 </label> 63 60 <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> 65 62 </div> 66 63 </form> 67 64 68 65 <% 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> 71 68 </form> 72 69 <% } %> 73 70 74 <p style="margin-top:1.5rem"><a href="/admin">← Terug naar Beheer</a></p>71 <p style="margin-top:1.5rem"><a href="/admin">← <%= t('admin.back') %></a></p> 75 72 </div> 76 73 … … 83 80 btn.addEventListener('click', function () { 84 81 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); }; 86 83 if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(field.value).then(done, function () { try { document.execCommand('copy'); done(); } catch (e) {} }); } 87 84 else { try { document.execCommand('copy'); done(); } catch (e) {} } -
src/views/pages/admin-push.ejs
r96c714f r9a00f28 1 1 <div class="container" style="max-width:640px;margin:1.5rem auto 3rem;padding:0 1rem"> 2 <h1 style="margin:0 0 .3rem"> Notificaties</h1>2 <h1 style="margin:0 0 .3rem"><%= t('push.t') %></h1> 3 3 <p style="color:var(--ink-soft,#888);margin:0 0 1.2rem"> 4 Krijg een melding op dit apparaat bij nieuwe volgers, reacties en berichten, 5 ook als de site niet open staat. Versleuteld tot in je browser; wij sturen zo 6 min mogelijk inhoud mee. 4 <%= t('push.intro') %> 7 5 </p> 8 6 9 7 <% if (!vapidKey) { %> 10 <p style="color:#c0392b"> Push is op deze server niet beschikbaar (sleutel kon niet worden aangemaakt of de dependency ontbreekt).</p>8 <p style="color:#c0392b"><%= t('push.unavailable') %></p> 11 9 <% } else { %> 12 10 13 11 <div id="np-unsupported" hidden style="color:#c0392b;margin:0 0 1rem"> 14 Deze browser ondersteunt geen push-notificaties.12 <%= t('push.unsupported') %> 15 13 </div> 16 14 <div id="np-ios-hint" hidden style="border:1px solid var(--border,#333);border-radius:10px;padding:.8rem 1rem;margin:0 0 1rem;font-size:.92rem;color:var(--ink-soft,#888)"> 17 Op iPhone/iPad werkt dit alleen als de site op je beginscherm staat: 18 deel-knop → <em>Zet op beginscherm</em>, en open 'm daarna vanaf daar. 15 <%= t('push.ios_hint') %> 19 16 </div> 20 17 21 18 <section style="border:1px solid var(--border,#333);border-radius:12px;padding:1rem 1.1rem;margin:0 0 1.2rem"> 22 <p style="margin:0 0 .6rem"><strong> Dit apparaat:</strong> <span id="np-state">controleren…</span></p>19 <p style="margin:0 0 .6rem"><strong><%= t('push.this_device') %></strong> <span id="np-state"><%= t('push.checking') %></span></p> 23 20 <div style="display:flex;gap:.6rem;flex-wrap:wrap"> 24 <button type="button" id="np-on" class="btn btn-primary" hidden> Zet aan op dit apparaat</button>25 <button type="button" id="np-off" class="btn" hidden> Zet uit</button>26 <button type="button" id="np-test" class="btn" hidden> Stuur testmelding</button>21 <button type="button" id="np-on" class="btn btn-primary" hidden><%= t('push.enable') %></button> 22 <button type="button" id="np-off" class="btn" hidden><%= t('push.disable') %></button> 23 <button type="button" id="np-test" class="btn" hidden><%= t('push.test') %></button> 27 24 </div> 28 25 <fieldset id="np-alerts" hidden style="border:none;padding:0;margin:1rem 0 0"> 29 <legend style="font-weight:600;margin-bottom:.4rem"> Waarvoor wil je een melding?</legend>30 <label style="display:block"><input type="checkbox" data-alert="follow"> Nieuwe volger</label>31 <label style="display:block"><input type="checkbox" data-alert="reply"> Reactie of vermelding</label>32 <label style="display:block"><input type="checkbox" data-alert="like"> Waardering (ster)</label>33 <label style="display:block"><input type="checkbox" data-alert="boost"> Boost</label>34 <label style="display:block"><input type="checkbox" data-alert="dm"> Privébericht</label>35 <p id="np-saved" hidden style="color:var(--accent);margin:.4rem 0 0"> Opgeslagen.</p>26 <legend style="font-weight:600;margin-bottom:.4rem"><%= t('push.what') %></legend> 27 <label style="display:block"><input type="checkbox" data-alert="follow"> <%= t('push.a_follow') %></label> 28 <label style="display:block"><input type="checkbox" data-alert="reply"> <%= t('push.a_reply') %></label> 29 <label style="display:block"><input type="checkbox" data-alert="like"> <%= t('push.a_like') %></label> 30 <label style="display:block"><input type="checkbox" data-alert="boost"> <%= t('push.a_boost') %></label> 31 <label style="display:block"><input type="checkbox" data-alert="dm"> <%= t('push.a_dm') %></label> 32 <p id="np-saved" hidden style="color:var(--accent);margin:.4rem 0 0"><%= t('push.saved') %></p> 36 33 </fieldset> 37 34 </section> 38 35 39 36 <% if (subscriptions.length) { %> 40 <h2 style="font-size:1.05rem;margin:0 0 .5rem"> Gekoppelde apparaten</h2>37 <h2 style="font-size:1.05rem;margin:0 0 .5rem"><%= t('push.devices') %></h2> 41 38 <ul style="list-style:none;padding:0;margin:0 0 1.2rem"> 42 39 <% subscriptions.forEach(function (s) { %> 43 40 <li data-endpoint="<%= s.endpoint %>" style="display:flex;justify-content:space-between;gap:.8rem;align-items:center;padding:.45rem 0;border-bottom:1px solid var(--border,#2a2a2a)"> 44 <span style="min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"><%= s.ua_label || 'Apparaat' %> <small style="color:var(--ink-soft,#888)">sinds<%= String(s.created_at || '').slice(0, 10) %></small></span>45 <button type="button" class="btn np-remove" data-endpoint="<%= s.endpoint %>"> Verwijder</button>41 <span style="min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"><%= s.ua_label || t('push.device') %> <small style="color:var(--ink-soft,#888)"><%= t('push.since') %> <%= String(s.created_at || '').slice(0, 10) %></small></span> 42 <button type="button" class="btn np-remove" data-endpoint="<%= s.endpoint %>"><%= t('push.remove') %></button> 46 43 </li> 47 44 <% }); %> … … 51 48 <% } %> 52 49 53 <p style="margin-top:1.5rem"><a href="/admin">← Terug naar Beheer</a></p>50 <p style="margin-top:1.5rem"><a href="/admin">← <%= t('admin.back') %></a></p> 54 51 </div> 55 52 … … 59 56 alerts: defaultAlerts, 60 57 saved: subscriptions.reduce(function (m, s) { try { m[s.endpoint] = JSON.parse(s.alert_types || '{}'); } catch (e) { m[s.endpoint] = {}; } return m; }, {}), 58 i18n: { on: t('push.state_on'), off: t('push.state_off'), denied: t('push.state_denied'), unknown: t('push.state_unknown'), unsupported: t('push.state_unsupported'), failed: t('push.enable_failed') }, 61 59 }).replace(/</g, '\\u003c') %></script> 62 60 <script> … … 74 72 if (!('serviceWorker' in navigator) || !('PushManager' in window) || !('Notification' in window)) { 75 73 document.getElementById('np-unsupported').hidden = false; 76 elState.textContent = 'niet ondersteund';74 elState.textContent = cfg.i18n.unsupported; 77 75 return; 78 76 } … … 107 105 function render(sub) { 108 106 currentEndpoint = sub ? sub.endpoint : null; 109 elState.textContent = sub ? 'meldingen staan aan' : (Notification.permission === 'denied' ? 'geblokkeerd in de browserinstellingen' : 'meldingen staan uit');107 elState.textContent = sub ? cfg.i18n.on : (Notification.permission === 'denied' ? cfg.i18n.denied : cfg.i18n.off); 110 108 btnOn.hidden = !!sub || Notification.permission === 'denied'; 111 109 btnOff.hidden = !sub; … … 120 118 setAlertBoxes((sub && cfg.saved[sub.endpoint]) ? Object.assign({}, cfg.alerts, cfg.saved[sub.endpoint]) : cfg.alerts); 121 119 render(sub); 122 }).catch(function () { elState.textContent = 'status onbekend'; });120 }).catch(function () { elState.textContent = cfg.i18n.unknown; }); 123 121 124 122 btnOn.addEventListener('click', function () { … … 131 129 return post('/push/subscribe', { subscription: sub.toJSON(), alerts: readAlertBoxes(), uaLabel: deviceLabel() }) 132 130 .then(function (r) { if (!r.ok) throw new Error('subscribe failed'); render(sub); location.reload(); }); 133 }).catch(function () { btnOn.disabled = false; elState.textContent = 'aanzetten mislukt'; });131 }).catch(function () { btnOn.disabled = false; elState.textContent = cfg.i18n.failed; }); 134 132 }); 135 133 }); -
src/views/pages/admin.ejs
r96c714f r9a00f28 19 19 <% if (tenancy === 'hub') { %> 20 20 <p class="admin-tagline"><%= t('admin.tagline_hub') %></p> 21 <% } else if (typeof circlesOn !== 'undefined' && circlesOn) { %> 22 <p class="admin-tagline"><%= t('admin.tagline_cirkels') %></p> 21 23 <% } else { %> 22 24 <p class="admin-tagline"><%= t('admin.tagline_solo') %></p> … … 46 48 <% if (typeof premiumUnlocked === 'undefined' || premiumUnlocked) { %> 47 49 <a href="/admin/stats" class="btn"><%= t('admin.b_stats') %></a> 48 <a href="/admin/paid" class="btn"> Betaalde posts</a>50 <a href="/admin/paid" class="btn"><%= t('admin.b_paid') %></a> 49 51 <a href="/admin/newsletter" class="btn"><%= t('admin.b_newsletter') %></a> 50 52 <% if (tenancy !== 'hub' && primarySite) { %><a href="/pers" class="btn" target="_blank"><%= t('admin.b_perskit') %></a><% } %> … … 55 57 <%# Fediverse pages (News / Notifications / My replies / Blocking) are reached via the 56 58 "Fediverse" nav button + the bell + the tabbed section — not duplicated here. %> 57 <a href="/admin/push" class="btn"> Notificaties</a>59 <a href="/admin/push" class="btn"><%= t('admin.b_push') %></a> 58 60 <a href="/admin/updates" class="btn"><%= t('admin.b_updates') %></a> 59 61 <a href="/admin/handleiding" class="btn"><%= t('admin.b_help') %></a> -
src/views/pages/fedi-notifications.ejs
r96c714f r9a00f28 34 34 <% if (n.type === 'mention' && n.note_url) { %><a class="nt-post" href="<%= n.note_url %>" target="_blank" rel="nofollow noopener"><%= t('tl.view_original') %></a><% } %> 35 35 </div> 36 <% if (n.type === 'report' && n.content) { %><div class="nt-content"><%= n.content %></div> 36 <% if (n.type === 'report') { %> 37 <% if (n.content) { %><div class="nt-content"><%= n.content %></div><% } else { %><div class="nt-content nt-noreason"><%= t('notif.report_noreason') %></div><% } %> 38 <% if (n.objects && n.objects.length) { %> 39 <div class="nt-report-about"> 40 <% n.objects.forEach(function (o) { %> 41 <a class="nt-post" href="/<%= o.slug %>"><%= t('notif.report_about') %>: <%= o.title %></a> 42 <% }); %> 43 </div> 44 <% } %> 37 45 <% } else if ((n.type === 'reply' || n.type === 'mention') && n.content) { %><div class="nt-content"><%- n.content %></div><% } %> 38 46 </div> … … 58 66 display: inline-flex; align-items: center; justify-content: center; } 59 67 .nt-icon svg { width: 18px; height: 18px; } 68 .nt-report-about { margin-top: .35rem; display: flex; flex-direction: column; gap: .15rem; } 69 .nt-noreason { font-style: italic; opacity: .7; } 60 70 .nt-like .nt-icon { background: color-mix(in srgb, #e8b04b 16%, transparent); color: #e8b04b; } 61 71 .nt-boost .nt-icon { background: color-mix(in srgb, #2fa85a 16%, transparent); color: #2fa85a; } -
src/views/pages/paid-gate.ejs
r96c714f r9a00f28 13 13 <section class="pg-card"> 14 14 <div class="pg-lock">💶</div> 15 <h2 class="pg-h2"> Voor supporters</h2>15 <h2 class="pg-h2"><%= t('pgate.h') %></h2> 16 16 <p class="pg-sub"> 17 Deze post is voor supporters van deze site 18 <% if (typeof pgCents !== 'undefined' && pgCents) { %>(vanaf €<%= (pgCents/100).toFixed(2) %> per maand op Patreon)<% } %>. 19 Word supporter en ontgrendel 'm daarna met een passkey. Geen account op deze site, geen cookie. 17 <% if (typeof pgCents !== 'undefined' && pgCents) { %><%= t('pgate.sub_cents', { eur: (pgCents/100).toFixed(2) }) %><% } else { %><%= t('pgate.sub') %><% } %> 20 18 </p> 21 19 22 20 <div class="pg-actions"> 23 21 <% if (_hasPatron) { %> 24 <a class="pg-btn" href="<%= pgPatronUrl %>" target="_blank" rel="noopener"> Word supporter op Patreon</a>25 <button type="button" id="pg-unlock" class="pg-btn pg-btn-ghost"> Al supporter? Ontgrendelen</button>22 <a class="pg-btn" href="<%= pgPatronUrl %>" target="_blank" rel="noopener"><%= t('pgate.join') %></a> 23 <button type="button" id="pg-unlock" class="pg-btn pg-btn-ghost"><%= t('pgate.unlock_have') %></button> 26 24 <% } else { %> 27 <button type="button" id="pg-unlock" class="pg-btn"> Ontgrendelen met Patreon</button>25 <button type="button" id="pg-unlock" class="pg-btn"><%= t('pgate.unlock') %></button> 28 26 <% } %> 29 27 </div> … … 38 36 var slug = "<%= pgSlug %>"; 39 37 var hasPatron = <%= _hasPatron ? 'true' : 'false' %>; 38 var I = { join: "<%= t('pgate.join_short') %>", confirm: "<%= t('pgate.confirm') %>", failed: "<%= t('pgate.failed') %>", error: "<%= t('pgate.error') %>" }; 40 39 var btn = document.getElementById('pg-unlock'); 41 40 var status = document.getElementById('pg-status'); … … 48 47 if (!window.SimpleWebAuthnBrowser || !window.PublicKeyCredential) { 49 48 if (hasPatron) { btn.style.display = 'none'; } 50 else { btn.textContent = 'Word supporter'; btn.addEventListener('click', toLink); }49 else { btn.textContent = I.join; btn.addEventListener('click', toLink); } 51 50 return; 52 51 } … … 54 53 btn.addEventListener('click', function () { 55 54 btn.disabled = true; 56 say( 'Bevestig met je passkey…');55 say(I.confirm); 57 56 fetch(base + '/paid/challenge?post=' + encodeURIComponent(slug)) 58 57 .then(function (r) { if (!r.ok) throw { link: true }; return r.json(); }) … … 75 74 toLink(); // no valid passkey yet (or lapsed tier): link via Patreon 76 75 } else { 77 btn.disabled = false; say( 'Ontgrendelen mislukt. Probeer opnieuw.', true);76 btn.disabled = false; say(I.failed, true); 78 77 } 79 78 }) … … 81 80 if (e && e.link) { toLink(); return; } 82 81 if (e && e.name === 'NotAllowedError') { toLink(); return; } // cancelled / no passkey -> link 83 btn.disabled = false; say( 'Er ging iets mis. Probeer opnieuw.', true);82 btn.disabled = false; say(I.error, true); 84 83 }); 85 84 }); -
src/views/pages/paid-passkey.ejs
r96c714f r9a00f28 2 2 <div class="pk-card"> 3 3 <div class="pk-ic">🔑</div> 4 <h1 class="pk-h1"> Je bent supporter, mooi.</h1>4 <h1 class="pk-h1"><%= t('ppk.h') %></h1> 5 5 <p class="pk-sub"> 6 Maak nu een passkey aan. Die wordt je sleutel voor betaalde posts, zonder 7 account en zonder cookie. We bewaren geen naam of e-mailadres. 6 <%= t('ppk.sub') %> 8 7 </p> 9 <button type="button" id="pk-go" class="pk-btn"> Maak passkey</button>8 <button type="button" id="pk-go" class="pk-btn"><%= t('ppk.make') %></button> 10 9 <p id="pk-status" class="pk-status" hidden></p> 11 10 </div> … … 17 16 var options = <%- optionsJson %>; 18 17 var blob = "<%= regBlob %>"; 18 var I = { unsupported: "<%= t('ppk.unsupported') %>", follow: "<%= t('ppk.follow') %>", done: "<%= t('ppk.done') %>", failed: "<%= t('ppk.failed') %>", cancelled: "<%= t('ppk.cancelled') %>", error: "<%= t('pgate.error') %>" }; 19 19 var postUrl = "<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase ? siteUrlBase : '') %>/<%= postSlug %>"; 20 20 var btn = document.getElementById('pk-go'); … … 24 24 if (!window.SimpleWebAuthnBrowser || !window.PublicKeyCredential) { 25 25 btn.disabled = true; 26 say( 'Passkeys worden niet ondersteund in deze browser.', true);26 say(I.unsupported, true); 27 27 return; 28 28 } 29 29 btn.addEventListener('click', function () { 30 30 btn.disabled = true; 31 say( 'Volg de vraag van je apparaat…');31 say(I.follow); 32 32 window.SimpleWebAuthnBrowser.startRegistration({ optionsJSON: options }) 33 33 .then(function (response) { … … 39 39 .then(function (r) { return r.json(); }) 40 40 .then(function (j) { 41 if (j && j.ok) { say( 'Gelukt. Je passkey is aangemaakt.'); setTimeout(function () { location.href = postUrl; }, 900); }42 else { btn.disabled = false; say( 'Aanmaken mislukt (' + ((j && j.error) || 'onbekend') + '). Probeer opnieuw.', true); }41 if (j && j.ok) { say(I.done); setTimeout(function () { location.href = postUrl; }, 900); } 42 else { btn.disabled = false; say(I.failed.replace('{err}', (j && j.error) || '?'), true); } 43 43 }) 44 .catch(function (e) { btn.disabled = false; say(e && e.name === 'NotAllowedError' ? 'Geannuleerd.' : 'Er ging iets mis. Probeer opnieuw.', true); });44 .catch(function (e) { btn.disabled = false; say(e && e.name === 'NotAllowedError' ? I.cancelled : I.error, true); }); 45 45 }); 46 46 })(); -
src/views/pages/paid-result.ejs
r96c714f r9a00f28 8 8 <div class="pr-ic">🔒</div> 9 9 <% if (reason === 'notpatron') { %> 10 <h1 class="pr-h1"> Nog geen supporter</h1>11 <p class="pr-sub"> Je bent (nog) geen actieve supporter van deze site op Patreon. Word supporter en probeer het daarna opnieuw vanaf de post.</p>10 <h1 class="pr-h1"><%= t('pres.notpatron_h') %></h1> 11 <p class="pr-sub"><%= t('pres.notpatron_p') %></p> 12 12 <% } else if (reason === 'tier') { %> 13 <h1 class="pr-h1">Een niveau hoger nodig</h1> 14 <p class="pr-sub"> 15 Deze post vraagt vanaf €<%= ((typeof neededCents !== 'undefined' ? neededCents : 0)/100).toFixed(2) %>. 16 Jouw steun is nu €<%= ((typeof haveCents !== 'undefined' ? haveCents : 0)/100).toFixed(2) %>. Verhoog je steun en probeer opnieuw. 17 </p> 13 <h1 class="pr-h1"><%= t('pres.tier_h') %></h1> 14 <p class="pr-sub"><%= t('pres.tier_p', { need: ((typeof neededCents !== 'undefined' ? neededCents : 0)/100).toFixed(2), have: ((typeof haveCents !== 'undefined' ? haveCents : 0)/100).toFixed(2) }) %></p> 18 15 <% } else if (reason === 'expired') { %> 19 <h1 class="pr-h1"> Aanvraag verlopen</h1>20 <p class="pr-sub"> Deze ontgrendel-link is verlopen of al gebruikt. Ga terug naar de post en probeer het opnieuw.</p>16 <h1 class="pr-h1"><%= t('pres.expired_h') %></h1> 17 <p class="pr-sub"><%= t('pres.expired_p') %></p> 21 18 <% } else { %> 22 <h1 class="pr-h1"> Ontgrendelen afgebroken</h1>23 <p class="pr-sub"> Er is niets gekoppeld. Je kunt het opnieuw proberen vanaf de post.</p>19 <h1 class="pr-h1"><%= t('pres.declined_h') %></h1> 20 <p class="pr-sub"><%= t('pres.declined_p') %></p> 24 21 <% } %> 25 22 26 23 <div class="pr-actions"> 27 24 <% if ((reason === 'notpatron' || reason === 'tier') && _patron) { %> 28 <a class="pr-btn" href="<%= _patron %>" target="_blank" rel="noopener"> Word supporter op Patreon</a>25 <a class="pr-btn" href="<%= _patron %>" target="_blank" rel="noopener"><%= t('pres.join') %></a> 29 26 <% } %> 30 27 <% if (_slug) { %> 31 <a class="pr-btn pr-btn-ghost" href="<%= _base %>/<%= _slug %>"> Terug naar de post</a>28 <a class="pr-btn pr-btn-ghost" href="<%= _base %>/<%= _slug %>"><%= t('pres.back_post') %></a> 32 29 <% } else { %> 33 <a class="pr-btn pr-btn-ghost" href="<%= _base %>/"> Terug naar de site</a>30 <a class="pr-btn pr-btn-ghost" href="<%= _base %>/"><%= t('pres.back_site') %></a> 34 31 <% } %> 35 32 </div>
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)