|
| 1 | +import { Meta } from "@storybook/addon-docs/blocks"; |
| 2 | + |
| 3 | +<Meta title="Ontwerppatronen/Berichtenbox" /> |
| 4 | + |
| 5 | +# Berichtenbox |
| 6 | + |
| 7 | +De Berichtenbox is de centrale plek waar ondernemers berichten ontvangen van overheidsinstanties en gemeentes. Het ontwerp simuleert het ophalen van berichten via het Federatief Berichtenstelsel (FBS): een stelsel waarin berichten bij de bron blijven en on-demand worden opgehaald. |
| 8 | + |
| 9 | +## Ontwerpdoel |
| 10 | + |
| 11 | +Het doel is om te onderzoeken hoe een berichtenbox eruitziet en werkt wanneer berichten niet centraal worden opgeslagen, maar worden opgehaald uit honderden bronnen (magazijnen). Dit heeft consequenties voor de gebruikerservaring: berichten moeten worden opgehaald, wat tijd kost en zichtbaar moet zijn voor de gebruiker. |
| 12 | + |
| 13 | +## Ophaalanimatie |
| 14 | + |
| 15 | +Bij het eerste bezoek wordt een voortgangsanimatie getoond die het ophalen van berichten uit meerdere bronnen simuleert. De animatie: |
| 16 | + |
| 17 | +- Toont het aantal doorzochte bronnen en gevonden berichten |
| 18 | +- Gebruikt een zware-staart-verdeling zodat de meeste bronnen snel antwoorden maar enkele bronnen laat binnendruppelen |
| 19 | +- Duurt vier seconden |
| 20 | +- Verbergt de counter, het zoekveld en de berichtentabel totdat het laden is voltooid |
| 21 | + |
| 22 | +De toolbar (counter en zoekveld) is gewrapt in een `[data-berichtenbox-toolbar]` element dat als geheel verborgen en getoond wordt. |
| 23 | + |
| 24 | +## Inbox, archief en prullenbak |
| 25 | + |
| 26 | +Berichten kunnen worden gearchiveerd, verwijderd of verplaatst naar mappen. De navigatie tussen inbox, archief en prullenbak verloopt via tabs. Elke view wordt volledig door JavaScript opgebouwd op basis van de state in localStorage. |
| 27 | + |
| 28 | +De inbox-badge toont het aantal **ongelezen** berichten, niet het totaal. |
| 29 | + |
| 30 | +## Mappen |
| 31 | + |
| 32 | +Berichten kunnen worden verplaatst naar mappen via een verplaats-paneel. Er zijn twee voorgevulde mappen ("Belastingen 2025" en "Subsidies") en de gebruiker kan eigen mappen aanmaken. Bij het bekijken van een map: |
| 33 | + |
| 34 | +- Wordt de juiste tab gemarkeerd met `aria-current` en `aria-selected` |
| 35 | +- Wordt de koptekst niet aangepast (blijft "Berichtenbox") |
| 36 | +- Wordt de counter-tekst vervangen door informatie over de map |
| 37 | + |
| 38 | +## Demo-berichten (polling) |
| 39 | + |
| 40 | +Op de inbox-pagina worden periodiek nieuwe berichten gegenereerd om real-time berichtverkeer te simuleren: |
| 41 | + |
| 42 | +- **Interval**: standaard 60 seconden, configureerbaar via `?poll=5` in de URL (minimum 5 seconden) |
| 43 | +- **Limiet**: maximaal 5 demo-berichten |
| 44 | +- **Paginering**: bij elk nieuw bericht wordt het onderste bericht van de pagina verwijderd om de paginagrootte (25) te bewaren |
| 45 | +- **Detailpagina**: demo-berichten linken naar `/moza/berichtenbox/bericht-demo/` waar de inhoud uit localStorage wordt gelezen |
| 46 | + |
| 47 | +## Detailpagina |
| 48 | + |
| 49 | +Er zijn twee soorten detailpagina's: |
| 50 | + |
| 51 | +1. **Statische pagina's** (`bericht.njk`) β gegenereerd door Eleventy voor elk bericht in de dataset. Permalink: `/moza/berichtenbox/bericht/msg-0001/` |
| 52 | +2. **Generieke demo-pagina** (`bericht-demo.html`) β leest het bericht-ID uit de URL-parameter en rendert de inhoud uit de JavaScript-state. Wordt gebruikt voor dynamisch via polling toegevoegde berichten. |
| 53 | + |
| 54 | +Beide pagina's bieden dezelfde acties: archiveren, verplaatsen naar map, markeer als ongelezen en verwijderen. |
| 55 | + |
| 56 | +## Filtering |
| 57 | + |
| 58 | +Het zoekveld filtert berichten op afzender en onderwerp. De filtering werkt client-side op de zichtbare tabelrijen via tekstvergelijking. |
| 59 | + |
| 60 | +## Bijlagen |
| 61 | + |
| 62 | +Op detailpagina's wordt het laden van bijlagen gesimuleerd met een vertraging van 1,5 seconde, waarna willekeurige PDF-bestandsnamen worden getoond. In de berichtenlijst wordt een bijlage-icoon getoond voor berichten met bijlagen. |
| 63 | + |
| 64 | +## Technische opbouw |
| 65 | + |
| 66 | +| Bestand | Rol | |
| 67 | +|---|---| |
| 68 | +| `_data/berichtenboxData.js` | Genereert de dataset: magazijnen, berichten, mappen | |
| 69 | +| `_includes/berichtenbox-data.njk` | Include met `window.berichtenboxData` voor alle berichtenbox-pagina's | |
| 70 | +| `_includes/berichtenbox-row.njk` | Tabelrij-template voor statisch gerenderde berichten | |
| 71 | +| `_includes/berichtenbox-tabs.njk` | Tab-navigatie (inbox, archief, prullenbak, mappen) | |
| 72 | +| `assets/javascript/berichtenbox.js` | Client-side logica: state, polling, filtering, acties | |
| 73 | +| `moza/berichtenbox.html` | Inbox-pagina (gepagineerd, 25 per pagina) | |
| 74 | +| `moza/berichtenbox/bericht.njk` | Detailpagina (1 per statisch bericht via Eleventy-paginering) | |
| 75 | +| `moza/berichtenbox/bericht-demo.html` | Generieke detailpagina voor demo-berichten | |
| 76 | +| `moza/berichtenbox/berichtenbox-archief.html` | Archief-pagina | |
| 77 | +| `moza/berichtenbox/berichtenbox-prullenbak.html` | Prullenbak-pagina | |
| 78 | + |
| 79 | +## State en localStorage |
| 80 | + |
| 81 | +Alle berichtenbox-state wordt opgeslagen onder de localStorage-sleutel `berichtenbox` als JSON-object. De state bevat: gelezen berichten, gearchiveerde en verwijderde berichten, map-toewijzingen, eigen mappen, demo-berichten en het actuele aantal ongelezen berichten (zodat de side-nav badge ook op andere pagina's correct is). |
| 82 | + |
| 83 | +Resetten kan via de resetlink op de pagina of handmatig via `localStorage.removeItem("berichtenbox")`. |
0 commit comments