source: Klonkt/src/views/pages/guardian.ejs@ 70677e96

main
Last change on this file since 70677e96 was 70677e96, checked in by Robin Genis <roboburr@…>, 6 weeks ago

Guardian-PWA: een paneel per kind

/guardian was een platte lijst van zeven secties: de wards' berichten, de
volgverzoeken, de hulpvragen, adopteren, verzonden aanvragen, wards, meldingen.
Wie een kind wilde overzien moest tussen die secties heen en weer, en nergens
stond bij elkaar wat er over dat ene kind speelt. Een guardian denkt niet per
functie maar per kind.

Nu is de wards-lijst de ingang: elk kind is een regel die opent naar een paneel
met zijn instellingen, zijn volgverzoeken, zijn hulpvragen en zijn recente
berichten. De regel zelf draagt de tellers (hulpvragen, volgverzoeken), zodat
een dicht paneel nooit iets verbergt dat een antwoord nodig heeft; dat is
belangrijk voor de volgverzoeken, want daar zit de follow-gating in.

De hulpvragen blijven daarnaast bovenaan staan, over alle kinderen heen, want
dat is waar deze app voor bestaat en het moet opvallen zonder dat je eerst een
kind opent. Ze verschijnen dus bewust twee keer: bovenaan de recente, in het
paneel de volledige geschiedenis van dat kind.

De hulpvraag is geen alarm. Er wordt niemand automatisch gewaarschuwd; een
guardian kan hem stil oplossen. De kaart is daarom rustig gehouden.

Changed files:
src/views/pages/guardian.ejs

  • feed-section en follow-section weg als losse secties

src/assets/js/guardian.js

  • helpCard, feedCard en followCard losgetrokken zodat beide plekken ze delen
  • wardPanel: instellingen, volgverzoeken, hulpvragen, berichten, acties
  • openPanels onthoudt wat open staat, zodat verversen niet dichtklapt
  • feed en volgverzoeken vullen nu een cache en hertekenen de wards-lijst

src/assets/css/guardian.css

  • opmaak voor het paneel en de tellers op de regel

src/routes/guardian.js

  • authorUri en wardUri meegeven: de sleutels waarop gegroepeerd wordt
  • de nieuwe labels toegevoegd aan uiStrings

src/services/i18n.js

  • 39 strings voor het paneel in nl, en, de

New file:
test/guardian-panel.test.js

  • de client schrijft nergens naar een verdwenen sectie
  • elke paneelsectie heeft zijn groepeersleutel
  • elk label dat de client gebruikt wordt ook geserveerd

remarks: geverifieerd in de browser op een wegwerp-database met twee kinderen:
elk paneel toont alleen zijn eigen volgverzoek, hulpvraag en post, een geopend
paneel blijft open over een ververs-ronde heen, en op 375px loopt niets buiten
beeld. De afhandel-lifecycle (oppakken/afgehandeld, shaer-jxi) en luid publiek
als tweede gated feature (shaer-3kp) komen hierna in dit paneel.

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

  • Property mode set to 100644
File size: 3.8 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><%= t('guardian.app_name') %></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="/guardian/app.css">
11</head>
12<body>
13 <header class="g-head">
14 <span class="g-buoy">🛟</span>
15 <div class="g-head-txt">
16 <h1><%= t('guardian.app_name') %></h1>
17 <p class="g-sub"><%= t('guardian.tagline') %></p>
18 </div>
19 <% if (sites.length > 1) { %>
20 <select id="site-picker" aria-label="<%= t('guardian.acting_as') %>">
21 <% for (const s of sites) { %>
22 <option value="<%= s.slug %>" <%= s.slug === state.site ? 'selected' : '' %>>@<%= s.slug %></option>
23 <% } %>
24 </select>
25 <% } else { %>
26 <span class="g-me" title="<%= t('guardian.acting_as') %>">@<%= state.site %></span>
27 <% } %>
28 <form method="post" action="/guardian/invite" style="display:inline">
29 <button class="quiet small" type="submit">Invite a guardian</button>
30 </form>
31</header>
32
33 <main>
34 <!-- 1. Hulpverzoeken, uitgelicht over alle wards heen. Dat is waar dit voor
35 bestaat, en het moet opvallen zonder dat je eerst een kind opent.
36 De volledige geschiedenis per kind staat in dat kind zijn paneel. -->
37 <section id="help-section">
38 <div class="g-sec-head">
39 <h2><%= t('guardian.help_title') %></h2>
40 <span id="help-count" class="g-badge" hidden></span>
41 </div>
42 <p class="g-sec-sub"><%= t('guardian.help_sub') %></p>
43 <div id="help-list" class="g-list"></div>
44 <p id="help-empty" class="g-empty"><%= t('guardian.help_empty') %></p>
45 </section>
46
47 <!-- 2. Nieuwe ward adopteren. -->
48 <section id="adopt-section">
49 <div class="g-sec-head"><h2><%= t('guardian.adopt_title') %></h2></div>
50 <p class="g-sec-sub"><%= t('guardian.adopt_sub') %></p>
51 <form id="adopt-form" autocomplete="off">
52 <input id="adopt-handle" type="text" inputmode="email" autocomplete="off"
53 placeholder="@kind@server.eu" aria-label="<%= t('guardian.adopt_label') %>">
54 <button type="submit" id="adopt-btn"><%= t('guardian.adopt_btn') %></button>
55 </form>
56 <p id="adopt-msg" class="g-msg" hidden></p>
57 </section>
58
59 <!-- 3. Verzonden aanvragen (nog niet beantwoord). -->
60 <section id="pending-section" hidden>
61 <div class="g-sec-head"><h2><%= t('guardian.pending_title') %></h2></div>
62 <p class="g-sec-sub"><%= t('guardian.pending_sub') %></p>
63 <div id="pending-list" class="g-list"></div>
64 </section>
65
66 <!-- 4. Mijn wards. Elk kind is een regel die opent naar een paneel met
67 alles over dat kind: instellingen, volgverzoeken, hulpvragen en
68 recente berichten. Een guardian denkt per kind, niet per functie. -->
69 <section id="wards-section">
70 <div class="g-sec-head"><h2><%= t('guardian.wards_title') %></h2></div>
71 <div id="wards-list" class="g-list"></div>
72 <p id="wards-empty" class="g-empty"><%= t('guardian.wards_empty') %></p>
73 </section>
74
75 <!-- 5. Meldingen. -->
76 <section id="push-section">
77 <div class="g-sec-head"><h2><%= t('guardian.push_title') %></h2></div>
78 <p class="g-sec-sub"><%= t('guardian.push_sub') %></p>
79 <button id="push-toggle" class="quiet" data-on-label="<%= t('guardian.push_off') %>"
80 data-off-label="<%= t('guardian.push_on') %>"><%= t('guardian.push_on') %></button>
81 <p id="push-msg" class="g-msg" hidden></p>
82 </section>
83 </main>
84
85 <script type="application/json" id="guardian-state"><%- JSON.stringify(state) %></script>
86 <script src="/guardian/app.js" defer></script>
87</body>
88</html>
Note: See TracBrowser for help on using the repository browser.