File: D:/HostingSpaces/TWijnstra/wijnstra.com/wwwroot/padel/index.html
<!doctype html>
<html lang="nl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Padelavond Planner</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background: #f8fafc;
color: #0f172a;
}
main {
max-width: 1100px;
margin: 0 auto;
padding: 24px;
}
.top {
display: flex;
justify-content: space-between;
gap: 16px;
align-items: flex-end;
margin-bottom: 24px;
}
h1, h2, h3, p { margin: 0; }
h1 { font-size: 34px; }
.muted { color: #64748b; margin-top: 8px; }
.card {
background: white;
border: 1px solid #e2e8f0;
border-radius: 20px;
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
padding: 24px;
margin-bottom: 24px;
}
.badge {
display: inline-block;
padding: 6px 10px;
border-radius: 999px;
background: #e2e8f0;
font-size: 14px;
font-weight: 700;
}
.badge-dark {
background: #0f172a;
color: white;
}
.active-header {
display: flex;
justify-content: space-between;
gap: 12px;
align-items: center;
margin-bottom: 24px;
}
.teams {
display: grid;
grid-template-columns: 1fr auto 1fr;
gap: 16px;
align-items: center;
}
.team {
border: 1px solid #e2e8f0;
border-radius: 18px;
padding: 20px;
background: #fff;
}
.team-name {
font-size: 24px;
font-weight: 800;
margin-top: 8px;
}
.versus {
color: #94a3b8;
font-weight: 800;
text-transform: uppercase;
font-size: 13px;
}
input {
width: 100%;
margin-top: 18px;
padding: 14px;
border: 1px solid #cbd5e1;
border-radius: 14px;
font-size: 20px;
}
.buttons {
display: flex;
justify-content: space-between;
gap: 12px;
margin-top: 20px;
}
button {
border: 0;
border-radius: 14px;
padding: 12px 16px;
font-weight: 800;
cursor: pointer;
background: #0f172a;
color: white;
font-size: 15px;
}
button.secondary {
background: white;
color: #0f172a;
border: 1px solid #cbd5e1;
}
button:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.grid {
display: grid;
grid-template-columns: 1.1fr 0.9fr;
gap: 24px;
}
.match-button {
width: 100%;
text-align: left;
margin-bottom: 10px;
background: white;
color: #0f172a;
border: 1px solid #e2e8f0;
}
.match-button.active {
background: #0f172a;
color: white;
border-color: #0f172a;
}
.match-row {
display: flex;
justify-content: space-between;
gap: 12px;
margin-bottom: 8px;
}
table {
width: 100%;
border-collapse: collapse;
overflow: hidden;
border-radius: 14px;
}
th, td {
padding: 12px;
border-bottom: 1px solid #e2e8f0;
text-align: right;
}
th:first-child, td:first-child { text-align: left; }
th { background: #f1f5f9; color: #475569; }
tr:last-child td { border-bottom: 0; }
@media (max-width: 800px) {
main { padding: 16px; }
.top, .active-header { align-items: flex-start; flex-direction: column; }
.teams, .grid { grid-template-columns: 1fr; }
.versus { text-align: center; }
h1 { font-size: 28px; }
}
</style>
</head>
<body>
<main>
<section class="top">
<div>
<h1>Padelavond Planner</h1>
<p class="muted">Tien potjes, vijf spelers, altijd één speler rust.</p>
</div>
<button class="secondary" onclick="resetEvening()">Reset avond</button>
</section>
<section class="card">
<div class="active-header">
<div>
<span class="badge" id="gameBadge"></span>
</div>
<span class="badge badge-dark" id="restBadge"></span>
</div>
<div class="teams">
<div class="team">
<p class="team-name" id="labelA">Team A</p>
<input id="scoreA" type="number" min="0" placeholder="Score" oninput="saveScore('a', this.value)" />
</div>
<div class="versus">vs</div>
<div class="team">
<p class="team-name" id="labelB">Team B</p>
<input id="scoreB" type="number" min="0" placeholder="Score" oninput="saveScore('b', this.value)" />
</div>
</div>
<div class="buttons">
<button class="secondary" id="prevButton" onclick="previousGame()">Vorig potje</button>
<button id="nextButton" onclick="nextGame()">Volgend potje</button>
</div>
</section>
<section class="grid">
<div class="card">
<h3 style="margin-bottom: 16px;">Volledig schema</h3>
<div id="scheduleList"></div>
</div>
<div class="card">
<h3 style="margin-bottom: 16px;">Tussenstand</h3>
<table>
<thead>
<tr>
<th>Speler</th>
<th>Winst</th>
<th>Saldo</th>
<th>Rust</th>
</tr>
</thead>
<tbody id="standings"></tbody>
</table>
</div>
</section>
</main>
<script>
const players = ["Erwin", "Karen", "Robert", "Tjerk", "Gerben"];
const schedule = [
{ game: 1, rest: "Gerben", teamA: ["Erwin", "Robert"], teamB: ["Karen", "Tjerk"] },
{ game: 2, rest: "Karen", teamA: ["Erwin", "Robert"], teamB: ["Tjerk", "Gerben"] },
{ game: 3, rest: "Robert", teamA: ["Erwin", "Tjerk"], teamB: ["Karen", "Gerben"] },
{ game: 4, rest: "Tjerk", teamA: ["Erwin", "Gerben"], teamB: ["Karen", "Robert"] },
{ game: 5, rest: "Erwin", teamA: ["Karen", "Tjerk"], teamB: ["Robert", "Gerben"] },
{ game: 6, rest: "Gerben", teamA: ["Erwin", "Karen"], teamB: ["Robert", "Tjerk"] },
{ game: 7, rest: "Karen", teamA: ["Erwin", "Tjerk"], teamB: ["Robert", "Gerben"] },
{ game: 8, rest: "Robert", teamA: ["Erwin", "Gerben"], teamB: ["Karen", "Tjerk"] },
{ game: 9, rest: "Tjerk", teamA: ["Erwin", "Karen"], teamB: ["Robert", "Gerben"] },
{ game: 10, rest: "Erwin", teamA: ["Karen", "Gerben"], teamB: ["Robert", "Tjerk"] }
];
let activeIndex = Number(localStorage.getItem("activeIndex") || 0);
let scores = JSON.parse(localStorage.getItem("scores") || "{}");
function getScore(game) {
return scores[game] || { a: "", b: "" };
}
function saveScore(side, value) {
const game = schedule[activeIndex].game;
scores[game] = { ...getScore(game), [side]: value };
localStorage.setItem("scores", JSON.stringify(scores));
renderStandings();
const score = getScore(game);
const scoreAIsFilled = score.a !== "";
const scoreBIsFilled = score.b !== "";
if (scoreAIsFilled && scoreBIsFilled && activeIndex < schedule.length - 1) {
setTimeout(() => {
const latestScore = getScore(game);
if (latestScore.a !== "" && latestScore.b !== "") {
setActiveGame(activeIndex + 1);
}
}, 600);
}
}
function setActiveGame(index) {
activeIndex = Math.max(0, Math.min(index, schedule.length - 1));
localStorage.setItem("activeIndex", String(activeIndex));
render();
}
function previousGame() {
setActiveGame(activeIndex - 1);
}
function nextGame() {
setActiveGame(activeIndex + 1);
}
function resetEvening() {
if (!confirm("Weet je zeker dat je de avond wilt resetten?")) return;
activeIndex = 0;
scores = {};
localStorage.removeItem("activeIndex");
localStorage.removeItem("scores");
render();
}
function renderActiveGame() {
const match = schedule[activeIndex];
const score = getScore(match.game);
document.getElementById("gameBadge").textContent = `Potje ${match.game} van ${schedule.length}`;
document.getElementById("restBadge").textContent = `Rust: ${match.rest}`;
// document.getElementById("teamA").textContent = match.teamA.join(" & ");
document.getElementById("labelA").textContent = "Team A: " + match.teamA.join(" & ");
// document.getElementById("teamB").textContent = match.teamB.join(" & ");
document.getElementById("labelB").textContent = "Team B: " + match.teamB.join(" & ");
document.getElementById("scoreA").value = score.a;
document.getElementById("scoreB").value = score.b;
document.getElementById("prevButton").disabled = activeIndex === 0;
document.getElementById("nextButton").disabled = activeIndex === schedule.length - 1;
}
function renderSchedule() {
const container = document.getElementById("scheduleList");
container.innerHTML = "";
schedule.forEach((match, index) => {
const button = document.createElement("button");
button.className = `match-button ${index === activeIndex ? "active" : ""}`;
button.onclick = () => setActiveGame(index);
button.innerHTML = `
<div class="match-row">
<strong>Potje ${match.game}</strong>
<span>Rust: ${match.rest}</span>
</div>
<div>${match.teamA.join(" & ")} vs ${match.teamB.join(" & ")}</div>
`;
container.appendChild(button);
});
}
function renderStandings() {
const stats = {};
players.forEach(player => {
stats[player] = { played: 0, rest: 0, won: 0, pointsFor: 0, pointsAgainst: 0 };
});
schedule.forEach(match => {
stats[match.rest].rest += 1;
[...match.teamA, ...match.teamB].forEach(player => {
stats[player].played += 1;
});
const score = getScore(match.game);
if (score.a === "" || score.b === "") return;
const a = Number(score.a);
const b = Number(score.b);
if (Number.isNaN(a) || Number.isNaN(b)) return;
match.teamA.forEach(player => {
stats[player].pointsFor += a;
stats[player].pointsAgainst += b;
if (a > b) stats[player].won += 1;
});
match.teamB.forEach(player => {
stats[player].pointsFor += b;
stats[player].pointsAgainst += a;
if (b > a) stats[player].won += 1;
});
});
const rows = Object.entries(stats)
.map(([player, stat]) => ({
player,
...stat,
balance: stat.pointsFor - stat.pointsAgainst
}))
.sort((a, b) => b.won - a.won || b.balance - a.balance || a.player.localeCompare(b.player));
document.getElementById("standings").innerHTML = rows.map(row => `
<tr>
<td><strong>${row.player}</strong></td>
<td>${row.won}</td>
<td>${row.balance}</td>
<td>${row.rest}</td>
</tr>
`).join("");
}
function render() {
renderActiveGame();
renderSchedule();
renderStandings();
}
render();
</script>
</body>
</html>