Geen rooster-appje uit de store. Geen abonnement. Geen WhatsApp-chaos meer.
🇳🇱 Nederlands · 🇬🇧 English
Eén gratis, op maat gebouwde app die precies doet wat een kantine met vrijwilligers nodig heeft — en verder niks. Geen los WhatsApp-groepje waarin het laatste rooster ligt te verstoffen, geen Excel-bestand dat maar op één laptop staat: iedereen ziet zijn eigen diensten, geeft beschikbaarheid door en ruilt met een collega. De beheerder keurt goed, betaalt uit en heeft altijd een actueel overzicht.
- Wat kan MHVwork?
- Rollen & bevoegdheden
- Technologie
- Installeren als app
- Aan de slag
- Projectstructuur
- Beveiliging
- Dank aan
- Gebruikte bibliotheken & licenties
- Licentie
|
Een beheerder kan een dienst aanmaken zonder iemand toe te wijzen en vragen wie wil. Kies het aantal plekken en of de beheerder zelf kiest uit de aanmeldingen, of dat wie zich het eerst opgeeft er direct op staat. Medewerkers zien op hun homepage een kaart Open dienst (dag, tijd, aantal plekjes) met de knop Geef je op; de beheerder wijst toe via Dienst bewerken. Onderaan de homepage staat een klein knopje Bar-scherm dat de idle-modus opent (rooster van vandaag en wedstrijden, groot en leesbaar, met eigen uitgangscode). Het scherm blijft aan zolang de idle-modus draait. Snel inloggen met code. Onder "Inloggen" staat de knop Snelcode. Je typt alleen je persoonlijke code (6–12 letters/cijfers) en krijgt een beperkt, mooi overzicht: een aftelring voor je lopende of volgende dienst (met wie er nog meer staat), je komende diensten, de thuiswedstrijden van vandaag en de komende dagen (met een label als een wedstrijd tijdens jouw dienst valt) en een berichtenvak met snelle zinnen. Niets wordt onthouden: nieuw tabblad = opnieuw je code, en het scherm sluit na 5 minuten zonder gebruik. Na 4 foute pogingen is een toestel 15 minuten geblokkeerd. Verplichte snelcode. Elk account (medewerker, beheerder, dev) stelt er bij de eerstvolgende login één in; tot dat gebeurd is, is de app niet te gebruiken. Een knop genereert een veilige code. Tijdens de eerste login komen de popups netjes na elkaar: (installatie →) rondleiding → teamkeuze → snelcode. Persoonlijke QR. Elke medewerker heeft een eigen QR waarmee je direct in je volledige account komt. Scannen kan met de camera-app of met de knop QR scannen op de inlogpagina (die opent de camera). Opslaan in de galerij, printen als A4-kaartje, of als pinpas (bankpasformaat 85,6 × 54 mm, voor- en achterkant, als PDF of afbeelding). QR uitgelekt? De eigenaar (Profiel → Snelle toegang), een beheerder (voor medewerkers) en de dev (voor iedereen) kunnen de QR vernieuwen. De oude QR is direct ongeldig, ook op toestellen waar al mee is ingelogd, en de getroffen persoon krijgt een mail. De dev kan ook een snelcode resetten. Een geschorst account verliest direct ook zijn QR- en snelcode-toegang. De dev ziet in het Logboek wie er via QR is ingelogd en kan per account Overal uitloggen. Op een toestel kun je ook inloggen met vingerafdruk of gezicht (aan te zetten in Profiel). Alles draait op het gratis Spark-plan: anonieme Firebase-sessies plus Firestore-regels, geen Cloud Functions. Vereist wel dat Anonymous is ingeschakeld bij Authentication → Sign-in method.
|
|
|
|
|
|
|
Zwevende, glazen navigatie of de klassieke volle-breedte-balk — naar keuze per account. Licht, donker of een verborgen NASA-APOD-thema, los van de systeeminstelling. Het witte thema is in 1.5 volledig herzien: alle tekst minstens 5:1 contrast, duidelijke knoppen en invoervelden, leesbare badges. Wachtwoord-sterktemeter bij aanmaken én wijzigen. Eigen achtergrond: kies een foto uit je galerij, die alleen op dat toestel wordt bewaard (IndexedDB) en dus geen databaseruimte kost.
Tabs voor Accounts, Gasten, Wedstrijden, Berichten en Instellingen (Aankondigingen en Logboek blijven eigen tabbladen). Tijdelijke gastaccounts die een beheerder aanmaakt moeten door dev worden goedgekeurd voordat ze kunnen inloggen; dev kan ze verlengen, een datum instellen, intrekken, definitief maken (geen vervaldatum meer) of verwijderen.
Geen bereik tijdens het typen? Een bericht in de groepschat of een privébericht wordt dan lokaal vastgehouden (herkenbaar aan een lichter bolletje met een klokje) en automatisch alsnog verstuurd zodra er weer verbinding is — boven in beeld staat intussen een balkje met het aantal wachtende berichten.
| Rol | Toegang |
|---|---|
| 👤 Medewerker | Eigen rooster, beschikbaarheid, chat, profiel, agenda-export, dienst ruilen |
| 🛠️ Beheerder | Alles van medewerker + roosters beheren, medewerkers uitnodigen, uitbetalingen, aankondigingen, functies uitzetten voor één profiel — tenzij dev een specifieke bevoegdheid heeft ingetrokken |
| 💻 Dev | Eigen omgeving: accountbeheer, bevoegdheden per beheerder, functies app-breed uitzetten, aankondigingen, logboek, harde reset — géén toegang tot financiële gegevens |
Bevoegdheden zijn fijnmazig, niet alles-of-niets:
- Dev kan een beheerder-account specifieke bevoegdheden ontnemen (medewerkers toevoegen, diensten aanmaken/verwijderen/goedkeuren, uitbetalen, aankondigingen plaatsen, medewerkers beheren, functies per profiel uitzetten) zonder het hele account te schorsen — afgedwongen in zowel de app als de databaseregels zelf, en zichtbaar voor de betrokken beheerder in het eigen profiel
- Een beheerder kan nooit een aankondiging van dev verwijderen, en kan geen functie app-breed uitzetten (zoals de chat) — dat blijft voorbehouden aan dev. Een beheerder kan wel een functie uitzetten voor één profiel, bijvoorbeeld tijdens onboarding
- Harde reset (alleen dev): wist in één keer alle diensten, chat, meldingen en betaalhistorie, met dubbele bevestiging — accounts en logboek blijven altijd staan
| Onderdeel | Technologie |
|---|---|
| Hosting | GitHub Pages (gratis) |
| Database | Firebase Firestore (Spark-plan, gratis tier) |
| Authenticatie | Firebase Authentication |
EmailJS (optioneel: Gmail SMTP via Cloud Functions, zie index.js) |
|
| Push | Browser Notification API + Service Worker |
| PWA | Web App Manifest + Service Worker |
| Agenda-export | .ics-bestand (iPhone, Android, Windows, Mac) |
| Excel-export | SheetJS (client-side, geen server nodig) |
Geen build-stap, geen framework — puur HTML/CSS/JavaScript, direct leesbaar en aanpasbaar.
MHVwork is een Progressive Web App: geen appstore nodig.
🍎 iPhone / iPad
- Open MHVwork in Safari
- Tik op Deel
- Kies Zet op beginscherm
🤖 Android
- Open MHVwork in Chrome
- Open het browsermenu
- Kies App installeren of Toevoegen aan startscherm
💻 Desktop
Gebruik Chrome of Edge en klik op het installatie-icoon in de adresbalk.
Volledige installatie- en updatehandleiding: zie HANDLEIDING.md. Overzicht van alle wijzigingen per versie: zie CHANGELOG.md. Alles over versie 1.5: V1.5.md.
In het kort:
- Fork of clone deze repository
- Maak een eigen Firebase-project aan (Spark-plan volstaat)
- Vul je Firebase-configuratie in bovenaan
app.html,index.html,fast.html,register.htmlenreset-pw.html - Zet in Authentication → Sign-in method Anonymous aan (nodig voor snelcode en QR)
- Publiceer de
firestore.rulesin de Firebase Console - Zet GitHub Pages aan voor deze repository
├── index.html Inlogpagina
├── register.html Accountregistratie (via uitnodigingslink)
├── reset-pw.html Wachtwoord opnieuw instellen
├── app.html De volledige applicatie (alle rollen)
├── fast.html Snelcode-overzicht (beperkt: dienst, wedstrijden, bericht)
├── qr.js QR-generator (qrcode-generator, MIT)
├── jsqr.js QR-lezer voor de camera-scanner (jsQR, Apache-2.0)
├── voorwaarden.html Gebruiksvoorwaarden & privacyverklaring
├── promo.html Presentatie "Wat is MHVwork?"
├── firestore.rules Firestore security rules
├── manifest.json PWA-manifest
├── sw.js Service worker
├── index.js Optionele Cloud Functions (Gmail SMTP, accountbeheer)
├── icon.svg / icon-*.png App-iconen
├── HANDLEIDING.md Installatie- en updatehandleiding
├── CHANGELOG.md Overzicht van alle wijzigingen
└── V1.5.md Volledige inhoud van versie 1.5 (snelle toegang)
- Alle databasetoegang loopt via Firestore Security Rules — medewerkers kunnen alleen hun eigen gegevens aanpassen, beheerders beheren roosters/uitbetalingen binnen hun bevoegdheden, en de dev-rol heeft geen toegang tot financiële gegevens
- Installatie wordt per account én per toestel bijgehouden (Profiel → App): is de app op één apparaat geïnstalleerd, dan komt de installatie-barricade nooit meer terug — een bekend maar nog niet geïnstalleerd apparaat krijgt alleen een kleine melding met een installeerknop
- Alleen een dev-account kan de dev-rol toewijzen of intrekken, en alleen dev kan een beheerder specifieke bevoegdheden ontnemen — of een app-brede functie uitzetten — allebei afgedwongen in zowel de app als de databaseregels, niet alleen in het scherm
- Wachtwoord-reset verloopt via Firebase's eigen, beveiligde flow
- Geschorste accounts worden bij inloggen direct geweigerd (en verliezen direct hun QR-/snelcode-toegang)
- Snelcode en QR werken via anonieme Firebase-sessies die de Firestore-regels alleen als geldig zien zolang de teller van het account niet is opgehoogd; tokens zijn niet te lijsten of te zoeken, een snelcode-sessie mag alleen eigen diensten/wedstrijden lezen en berichten versturen
⚠️ Controleer altijd de actuelefirestore.rulesvoordat je naar een productieomgeving gaat.
Met dank voor het testen en meedenken:
- R. Massalt
- I. Massalt
- C. Koning
- J. v Heun (dev)
- Jou, als je meehelpt!
MHVwork is zelf geschreven zonder framework, maar leunt op de volgende diensten en bibliotheken:
| Bibliotheek / dienst | Doel | Licentie |
|---|---|---|
| Firebase (Firestore, Auth, Cloud Functions) | Database, login, optionele mailserver | Google APIs Terms of Service |
| EmailJS | E-mailverzending vanuit de browser | Eigen servicevoorwaarden (emailjs.com/legal) |
| SheetJS (xlsx) | Excel-export in de browser | Apache License 2.0 |
| qrcode-generator | QR-codes tekenen (qr.js) |
MIT License |
| jsQR | QR lezen met de camera (jsqr.js) |
Apache License 2.0 |
| Nodemailer | Gmail SMTP-verzending (optioneel, index.js) |
MIT License |
| Outfit (Google Fonts) | Lettertype | SIL Open Font License 1.1 |
Deze applicatie is gebouwd voor en het interne gebruik van MHV. De broncode mag vrij bekeken, aangepast en hergebruikt worden voor gelijksoortige vrijwilligersorganisaties; gebruik op eigen risico en zonder enige garantie. Bovenstaande externe diensten en bibliotheken vallen onder hún eigen licentievoorwaarden (zie tabel hierboven) — check die zelf even als je deze app elders wil inzetten of doorontwikkelen.