Ontwikkelen
PadelOS AppScript
Dit is precies de richting waarin ik Padelschool OS zou ontwikkelen. Je beschrijft eigenlijk geen gewone website meer, maar een SaaS-platform met rollen, rechten, administratie en planning.
Ik zou één belangrijke architectuurkeuze maken:
Gebruik Google Sheets niet als de applicatie, maar als de eerste database.
Dat lijkt een klein verschil, maar het bepaalt of je over 2 jaar nog kunt doorgroeien.
INTERNET
│
Google Apps Script
│
index.html (WebApp)
│
HTML + CSS + JavaScript (Frontend)
│
---------------------- API ------------------------
│
Code.gs
Players.gs
Trainers.gs
Lessons.gs
Planning.gs
Invoices.gs
Users.gs
Security.gs
Database.gs
Logger.gs
Router.gs
│
---------------- DATA LAYER -----------------------
│
Google Spreadsheet
De HTML weet helemaal niets van Google Sheets.
Hij praat alleen met Apps Script.
Apps Script praat met Google Sheets.
Dat is precies hoe professionele webapplicaties zijn opgebouwd.
Ik zou beginnen met één spreadsheet.
Daarin meerdere tabs.
Bijvoorbeeld:
Padelschool Database
│
├── Users
├── Players
├── Trainers
├── Groups
├── Lessons
├── LessonSeries
├── Planning
├── Bookings
├── Attendance
├── Evaluations
├── Exercises
├── Invoices
├── Payments
├── Logs
├── Settings
├── Roles
├── Permissions
├── Notifications
Later kun je daar eenvoudig tabs aan toevoegen.
Alleen de WebApp.
doGet()
doPost()
include()
Alle API-aanroepen.
Bijvoorbeeld:
getPlayers()
savePlayer()
updatePlayer()
deletePlayer()
Alle communicatie met Sheets.
Hier staat bijvoorbeeld:
readSheet()
writeSheet()
appendRow()
updateRow()
deleteRow()
Niemand anders mag rechtstreeks de Sheet benaderen.
Alles rondom spelers.
createPlayer()
updatePlayer()
getPlayer()
getPlayers()
searchPlayers()
archivePlayer()
createTrainer()
updateTrainer()
getTrainer()
createLesson()
updateLesson()
copyLesson()
lessonHistory()
createBooking()
moveBooking()
cancelBooking()
weekPlanning()
monthPlanning()
present()
absent()
late()
calculateHours()
generateInvoice()
markPaid()
Login.
login()
logout()
currentUser()
Hier komen de rechten.
Bijvoorbeeld.
Player
Trainer
Clubmanager
Administrator
Iedere wijziging wordt opgeslagen.
Wie
Wanneer
Wat gewijzigd
Oude waarde
Nieuwe waarde
Daardoor kun je altijd terugzien wie iets veranderd heeft.
De HTML bevat alleen schermen.
Bijvoorbeeld.
Dashboard
Players
Planning
Lessons
Invoices
Wanneer de speler opent:
google.script.run
.withSuccessHandler(loadPlayers)
.getPlayers();
Dus:
HTML
↓
Apps Script
↓
Google Sheet
↓
HTML
Ik zou direct beginnen met vier rollen.
Mag:
✅ Eigen profiel bekijken
✅ Eigen lessen bekijken
✅ Eigen evaluaties bekijken
✅ Eigen notities maken
✅ Eigen ontwikkeling zien
Mag NIET:
Trainer wijzigen
Facturen wijzigen
Planning wijzigen
Mag:
Eigen lessen maken
Les voorbereiden
Spelers beoordelen
Nieuwe oefeningen toevoegen
Planning bekijken
Eigen uren bekijken
Eigen facturen bekijken
Eigen agenda beheren
Mag:
Alle trainers beheren
Planning aanpassen
Groepen wijzigen
Boekingen beheren
Facturen controleren
Mag werkelijk alles.
Bijvoorbeeld.
Nieuwe trainer
Nieuwe club
Nieuwe locatie
Nieuwe database
Gebruikersrechten
Backups
Rapportages
Facturen
Instellingen
AI modules
Module
Speler
Trainer
Clubmanager
Admin
Eigen profiel bekijken
✅
✅
✅
✅
Eigen profiel wijzigen
✅
✅
✅
✅
Andere spelers bekijken
❌
✅
✅
✅
Spelers wijzigen
❌
Beperkt
✅
✅
Trainers beheren
❌
❌
✅
✅
Planning aanpassen
❌
Eigen lessen
✅
✅
Facturen bekijken
Eigen
Eigen
Club
Alles
Gebruikersrechten beheren
❌
❌
❌
✅
Iedere les krijgt een ID.
Bijvoorbeeld.
LES000154
Daarin zit.
Datum
Tijd
Trainer
Baan
Groep
Thema
Notities
Status
Status.
Gepland
Bevestigd
Geannuleerd
Afgerond
Iedere afgeronde les krijgt automatisch uren.
Bijvoorbeeld.
Trainer:
2 uur
↓
Planning
↓
Factuur
↓
Maandoverzicht
↓
Dus een trainer hoeft niet meer handmatig uren te tellen.
Ik zou ALLES loggen.
Bijvoorbeeld.
18 juli
20:34
Trainer Piet
heeft
Les 154 gewijzigd
Van
18:00
Naar
19:00
Administrator ziet alles.
Omdat deze later zonder veel aanpassingen kan doorgroeien naar een volledige database (bijvoorbeeld Cloud SQL of Firestore). De frontend blijft hetzelfde; alleen de Data Layer verandert.
In plaats van direct verder te bouwen aan schermen, zou ik eerst een Apps Script Backend v1.0 ontwerpen. Dat document beschrijft:
de volledige .gs-bestandsstructuur,
alle API-endpoints,
het Google Spreadsheet-schema (tabbladen en kolommen),
de rollen en rechten,
de logging,
de facturatieflow,
en de communicatie tussen index.html en Apps Script.
Dat vormt de technische blauwdruk waarop alle volgende 45 sprints kunnen voortbouwen. Daarmee wordt Padelschool OS niet alleen een mooie webapp, maar een schaalbaar systeem.
We gaan nu van concept → product.
De eerste versie noemen we:
Doel:
Een werkende basisapp waarin we later alle modules kunnen uitbreiden.
We starten met deze structuur:
PADELSCHOOL-OS/
│
├── index.html
│
├── css/
│ ├── style.css
│ └── components.css
│
├── js/
│ ├── app.js
│ ├── router.js
│ ├── database.js
│ ├── players.js
│ ├── trainers.js
│ ├── groups.js
│ └── planning.js
│
├── data/
│ ├── spelers.json
│ ├── trainers.json
│ ├── groepen.json
│ └── lessen.json
│
└── README.md
De eerste interface:
--------------------------------
🎾 PADELSCHOOL OS
Dashboard
Welkom Stijn
Vandaag
--------------------------------
📅 Planning
17:00
Beginners groep A
18:00
Gevorderden groep B
--------------------------------
👥 Mijn groepen
Beginners
8 spelers
Gevorderden
6 spelers
--------------------------------
⚡ Snelle acties
+ Nieuwe speler
+ Nieuwe les
+ Evaluatie
+ Oefening
--------------------------------
Versie 0.1 krijgt:
Status:
🟢 Actief
Status:
🟡 Basis
Kan:
speler toevoegen
speler bekijken
Status:
🟡 Basis
Kan:
trainer toevoegen
beschikbaarheid
Status:
🟡 Basis
Kan:
groep maken
spelers koppelen
Status:
⚪ Voorbereiding
We maken de eerste "database".
[
{
"id":1,
"naam":"Voorbeeld Speler",
"niveau":7,
"speelhand":"links",
"doel":"Techniek verbeteren"
}
]
[
{
"id":1,
"naam":"Stijn",
"niveau":"Padelleraar A",
"specialisatie":[
"Techniek",
"Tactiek"
]
}
]
We bouwen eerst:
HTML
CSS
JavaScript
Waarom?
Omdat we snel:
✅ kunnen testen
✅ kunnen aanpassen
✅ kunnen delen
✅ kunnen publiceren
Later:
Backend:
Google Sheets API
Firebase
Supabase
Eigen database
We maken direct rekening met:
ROL:
ADMIN
|
|-- Padelschool eigenaar
TRAINER
|
|-- Geeft lessen
SPELER
|
|-- Volgt ontwikkeling
CLUB
|
|-- Beheert meerdere trainers
Dag 1:
✅ Structuur maken
Dag 2:
Dashboard bouwen
Dag 3:
Navigatie bouwen
Dag 4:
Speler module
Dag 5:
Trainer module
Dag 6:
Groepen module
Dag 7:
Data opslaan
Dag 8:
Export functies
Dag 9:
Testen
Dag 10:
Alpha release
Na deze sprint hebben we:
Met:
✅ Werkende website
✅ Dashboard
✅ Navigatie
✅ Eerste database
✅ Spelersbeheer
✅ Trainersbeheer
✅ Groepenbeheer
Sprint 1.1 → De eerste index.html bouwen
Daarna:
Sprint 1.2 → CSS Design System
Daarna:
Sprint 1.3 → JavaScript Engine
Dan ontstaat de eerste echte Padelschool OS applicatie.
Ik zou nu beginnen met de complete eerste index.html van Padelschool OS Alpha 0.1.
Mooi. We gaan nu echt starten met de eerste bouwsteen.
Dit is Padelschool OS Alpha 0.1 – index.html.
Deze eerste versie bevat:
✅ Professioneel dashboard
✅ Sidebar navigatie
✅ Modulestructuur
✅ Trainer dashboard
✅ Spelersoverzicht
✅ Groepen
✅ Planning
✅ Lessen
✅ Oefeningen
✅ Evaluaties
✅ Responsive mobiele layout
✅ Eerste interacties via JavaScript
✅ Klaar om later gekoppeld te worden aan Google Sheets / Database
Maak een bestand:
PadelschoolOS/index.html
en plak onderstaande code.
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Padelschool OS Alpha 0.1</title>
<style>
:root {
--primary:#0ea5e9;
--dark:#0284c7;
--green:#22c55e;
--bg:#f8fafc;
--text:#1e293b;
--card:white;
}
*{
box-sizing:border-box;
margin:0;
padding:0;
font-family:
"Segoe UI",
Arial,
sans-serif;
}
body{
background:var(--bg);
color:var(--text);
}
/* APP */
.app{
display:flex;
min-height:100vh;
}
/* SIDEBAR */
.sidebar{
width:260px;
background:#0f172a;
color:white;
padding:25px;
}
.logo{
font-size:22px;
font-weight:bold;
margin-bottom:30px;
}
.logo span{
color:#38bdf8;
}
.menu button{
width:100%;
padding:14px;
margin-bottom:10px;
background:none;
border:none;
color:white;
text-align:left;
cursor:pointer;
border-radius:8px;
}
.menu button:hover{
background:#1e293b;
}
/* MAIN */
.main{
flex:1;
padding:30px;
}
/* HEADER */
.header{
display:flex;
justify-content:space-between;
align-items:center;
margin-bottom:30px;
}
.header h1{
font-size:28px;
}
.profile{
background:white;
padding:12px 20px;
border-radius:12px;
}
/* CARDS */
.grid{
display:grid;
grid-template-columns:
repeat(auto-fit,minmax(220px,1fr));
gap:20px;
}
.card{
background:var(--card);
padding:22px;
border-radius:18px;
box-shadow:
0 5px 15px rgba(0,0,0,.05);
}
.card h3{
margin-bottom:15px;
}
.number{
font-size:34px;
font-weight:bold;
color:var(--primary);
}
/* TABLE */
table{
width:100%;
border-collapse:collapse;
}
td,th{
padding:12px;
text-align:left;
border-bottom:1px solid #e2e8f0;
}
/* BUTTON */
.action{
background:var(--primary);
color:white;
padding:12px 18px;
border-radius:10px;
border:none;
cursor:pointer;
}
.action:hover{
background:var(--dark);
}
/* MOBILE */
@media(max-width:800px){
.sidebar{
width:80px;
}
.logo{
font-size:0;
}
.menu button{
font-size:0;
}
.main{
padding:15px;
}
}
</style>
</head>
<body>
<div class="app">
<!-- SIDEBAR -->
<aside class="sidebar">
<div class="logo">
🎾 <span>Padelschool</span> OS
</div>
<div class="menu">
<button onclick="openModule('Dashboard')">
🏠 Dashboard
</button>
<button onclick="openModule('Spelers')">
👥 Spelers
</button>
<button onclick="openModule('Trainers')">
🎓 Trainers
</button>
<button onclick="openModule('Groepen')">
👨👩👧 Groepen
</button>
<button onclick="openModule('Planning')">
📅 Planning
</button>
<button onclick="openModule('Lessen')">
🎾 Lessen
</button>
<button onclick="openModule('Oefeningen')">
📚 Oefeningen
</button>
<button onclick="openModule('Evaluaties')">
⭐ Evaluaties
</button>
</div>
</aside>
<!-- MAIN -->
<main class="main">
<div class="header">
<h1 id="title">
Dashboard
</h1>
<div class="profile">
Stijn 👋
</div>
</div>
<div id="content">
<!-- DASHBOARD -->
<div class="grid">
<div class="card">
<h3>
Spelers
</h3>
<div class="number">
48
</div>
Actieve spelers
</div>
<div class="card">
<h3>
Trainers
</h3>
<div class="number">
5
</div>
Team
</div>
<div class="card">
<h3>
Groepen
</h3>
<div class="number">
12
</div>
Trainingsgroepen
</div>
<div class="card">
<h3>
Lessen vandaag
</h3>
<div class="number">
8
</div>
Planning
</div>
</div>
<br><br>
<div class="card">
<h3>
Vandaag
</h3>
<table>
<tr>
<th>
Tijd
</th>
<th>
Groep
</th>
<th>
Thema
</th>
</tr>
<tr>
<td>
17:00
</td>
<td>
Beginners A
</td>
<td>
Forehand + positie
</td>
</tr>
<tr>
<td>
18:00
</td>
<td>
Gevorderden B
</td>
<td>
Bandeja + netspel
</td>
</tr>
<tr>
<td>
19:30
</td>
<td>
Selectie
</td>
<td>
Tactische patronen
</td>
</tr>
</table>
</div>
<br>
<button class="action"
onclick="newLesson()">
+ Nieuwe Les
</button>
</div>
</main>
</div>
<script>
function openModule(module){
document.getElementById("title").innerHTML=module;
let content=
document.getElementById("content");
content.innerHTML=`
<div class="card">
<h2>
${module}
</h2>
<p>
Deze module wordt gebouwd in volgende development sprint.
</p>
<br>
<button class="action">
Nieuwe ${module}
</button>
</div>
`;
}
function newLesson(){
alert(
"Nieuwe les wordt toegevoegd aan Padelschool OS"
);
}
</script>
</body>
</html>
Architectuur:
PADELSCHOOL OS
|
Dashboard
|
--------------------------------
Spelers Trainers Groepen
Planning Lessen Evaluaties
Oefeningen
--------------------------------
Database laag
↓
Google Sheets /
Firebase /
Supabase
Sprint 1.2 — CSS Design System uitbreiden
Daarna:
Sprint 1.3 — JavaScript Engine bouwen
Daarna:
Sprint 2 — Echt Dashboard met data-modellen
De basis staat nu. Dit is de eerste echte "app-shell" van Padelschool OS. 🎾🚀