source: Klonkt/src/views/pages/guardian.ejs@ 1a2d8ac

main
Last change on this file since 1a2d8ac was 318d0c2, checked in by Robin Genis <roboburr@…>, 7 weeks ago

De Guardian-PWA: /guardian, wards managen, berichtencentrum, eigen push

Een aparte, installeerbare hoek van Klonkt voor guardians (FEP-633c), los
van de site-PWA: eigen manifest met scope /guardian/, eigen boei-icoon,
eigen accent. Ingelogde eigenaren handelen als een van hun eigen actors
(?site=slug bij meerdere sites).

Drie secties: het berichtencentrum (inkomende hulpverzoeken uit
ap_mentions, hulpvraag-eerst), wards (adopteren via handle -> WebFinger ->
dezelfde C2S Offer-pijplijn als de Shaer-apps; pending intrekken; ward
loslaten) en meldingen (web-push-kanaal met alert-typen help + guardian,
hergebruik van de bestaande push-slices en service worker).

Geen inline scripts of styles (CSP): alle logica in
/assets/js/guardian.js, opmaak in /assets/css/guardian.css. UI-teksten
volledig via i18n (nl/en/de); de JSON-state draagt de strings voor de
client.

Changed files:
src/server.js

  • mount /guardian vóór de slug-catch-all

src/routes/posts.js

  • 'guardian' (en paid/push in admin-sites) op de reserved-slug-lijst

src/routes/admin-sites.js

  • idem voor nieuwe sites

src/services/i18n.js

  • guardian.*-teksten in nl/en/de

New file:
src/routes/guardian.js

  • pagina, /api/state, /adopt, /wards/remove, manifest, icon

src/views/pages/guardian.ejs

  • de PWA-pagina, state als application/json-blok

src/assets/js/guardian.js

  • rendering, adopt-flow, push-subscribe (help+guardian), 45s-poll

src/assets/css/guardian.css

  • donker paneel, boei-oranje accent

remarks: emancipatie/verwijdering federeren (FEP 3.2-3.4) doet de
wards/remove-knop nog niet; dat is lokaal loslaten. Volgende stap na
akkoord: beta + demo's.

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

  • Property mode set to 100644
File size: 2.3 KB
Line 
1<!DOCTYPE html>
2<html lang="<%= lang %>">
3<head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1">
6 <title>Klonkt Guardian</title>
7 <link rel="manifest" href="/guardian/manifest.webmanifest">
8 <link rel="icon" href="/guardian/icon.svg" type="image/svg+xml">
9 <meta name="theme-color" content="#ff6b35">
10 <link rel="stylesheet" href="/assets/css/guardian.css">
11</head>
12<body>
13 <header class="g-head">
14 <span class="g-buoy">🛟</span>
15 <h1>Guardian</h1>
16 <% if (sites.length > 1) { %>
17 <select id="site-picker" aria-label="Account">
18 <% for (const s of sites) { %>
19 <option value="<%= s.slug %>" <%= s.slug === state.site ? 'selected' : '' %>>@<%= s.slug %></option>
20 <% } %>
21 </select>
22 <% } else { %>
23 <span class="g-me">@<%= state.site %></span>
24 <% } %>
25 </header>
26
27 <main>
28 <!-- Berichtencentrum: hulpverzoeken eerst, dat is waar dit voor bestaat. -->
29 <section id="help-section">
30 <h2><%= t('guardian.help_title') %></h2>
31 <div id="help-list" class="g-list"></div>
32 <p id="help-empty" class="g-empty" hidden><%= t('guardian.help_empty') %></p>
33 </section>
34
35 <section id="wards-section">
36 <h2><%= t('guardian.wards_title') %></h2>
37 <form id="adopt-form" autocomplete="off">
38 <input id="adopt-handle" type="text" inputmode="email"
39 placeholder="@kind@server.eu" aria-label="<%= t('guardian.adopt_label') %>">
40 <button type="submit"><%= t('guardian.adopt_btn') %></button>
41 </form>
42 <p id="adopt-msg" class="g-msg" hidden></p>
43 <div id="wards-list" class="g-list"></div>
44 <div id="offers-list" class="g-list"></div>
45 <p id="wards-empty" class="g-empty" hidden><%= t('guardian.wards_empty') %></p>
46 </section>
47
48 <section id="push-section">
49 <h2><%= t('guardian.push_title') %></h2>
50 <p class="g-sub"><%= t('guardian.push_sub') %></p>
51 <button id="push-toggle" data-on-label="<%= t('guardian.push_off') %>"
52 data-off-label="<%= t('guardian.push_on') %>"><%= t('guardian.push_on') %></button>
53 <p id="push-msg" class="g-msg" hidden></p>
54 </section>
55 </main>
56
57 <script type="application/json" id="guardian-state"><%- JSON.stringify(state) %></script>
58 <script src="/assets/js/guardian.js" defer></script>
59</body>
60</html>
Note: See TracBrowser for help on using the repository browser.