Erste Version: HCRB Spieltag-Kalender und Fahrtplaner

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
guyg1474andClaude Opus 5.5 committed 2026-10-10 13:54:33 +02:00
commit 10400eee59
30 files changed
+3771

No files matched your search

+121
View File
@@ -0,0 +1,121 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HCRB – Highcap Rasselbande</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<section class="hero">
<div>
<h1>HCRB</h1>
<div class="subtitle">Highcap Rasselbande</div>
</div>
</section>
<main>
<p class="intro">
Wir sind die Highcap Rasselbande – eine Airsoft-Gruppe aus Berlin.
Am häufigsten findet ihr uns auf der Darkzone.
</p>
<p class="notice wip">
<strong>Diese Seite ist noch in Arbeit.</strong> Es kommen noch Änderungen und neue Funktionen dazu.
</p>
<div class="tiles">
<a class="tile" href="/kalender">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="square" aria-hidden="true">
<rect x="3" y="5" width="18" height="16"/><path d="M3 10h18M8 3v4M16 3v4M7 14h3M14 14h3M7 17h3"/>
</svg>
<div>
<h2>Kalender</h2>
<p>Spieltage eintragen und zusagen.</p>
</div>
</a>
<a class="tile" href="/fahrt">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="square" aria-hidden="true">
<path d="M3 16v-4l2-5h14l2 5v4H3z"/><path d="M3 12h18"/><circle cx="7.5" cy="17.5" r="1.8"/><circle cx="16.5" cy="17.5" r="1.8"/>
</svg>
<div>
<h2>Fahrtplaner</h2>
<p>Fahrgemeinschaften einteilen.</p>
</div>
</a>
</div>
<div class="card">
<div class="card-head">
<h2>Nächste Spieltage</h2>
<a href="/kalender" class="button small">Zum Kalender</a>
</div>
<div id="upcoming"><p class="muted">Lädt …</p></div>
</div>
<div class="card">
<div class="card-head">
<h2>Pile of Shame</h2>
<a href="/statistik" class="button small">Zur Statistik</a>
</div>
<div id="shame"><p class="muted">Lädt …</p></div>
</div>
<div class="card">
<h2>Über uns</h2>
<p>
Wir sind die <strong>Highcap Rasselbande (HCRB)</strong>, eine Airsoft-Gruppe aus Berlin.
Gespielt wird bei uns vor allem auf der <strong>Darkzone</strong> – dort sind wir regelmäßig unterwegs.
</p>
<p>
Hier planen wir unsere Spieltage und Fahrgemeinschaften. Videos und Bilder von unseren Spielen
gibt es auf YouTube und Instagram:
</p>
<div class="social">
<a class="button" href="https://www.youtube.com/@highcaprasselbande" target="_blank" rel="noopener">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M23 7.2a3 3 0 0 0-2.1-2.1C19 4.6 12 4.6 12 4.6s-7 0-8.9.5A3 3 0 0 0 1 7.2 31 31 0 0 0 .5 12a31 31 0 0 0 .5 4.8 3 3 0 0 0 2.1 2.1c1.9.5 8.9.5 8.9.5s7 0 8.9-.5a3 3 0 0 0 2.1-2.1 31 31 0 0 0 .5-4.8 31 31 0 0 0-.5-4.8zM9.75 15.02V8.98L15.5 12l-5.75 3.02z"/></svg>YouTube
</a>
<a class="button" href="https://www.instagram.com/hcrb.airsoft" target="_blank" rel="noopener">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="2.5" y="2.5" width="19" height="19" rx="5"/><circle cx="12" cy="12" r="4.2"/><circle cx="17.6" cy="6.4" r="1" fill="currentColor" stroke="none"/></svg>Instagram
</a>
</div>
</div>
</main>
<script type="module">
import { renderHeader, renderFooter, api, esc, formatDate } from '/js/common.js';
renderHeader('home');
renderFooter();
const box = document.getElementById('upcoming');
try {
const events = await api('GET', '/upcoming');
box.innerHTML = events.length
? `<ul class="list">${events.map((e) => `
<li>
<span class="name"><strong>${esc(e.title)}</strong></span>
<span class="meta">${formatDate(e.date, true)}</span>
<span class="badge">${e.attendeeCount} zugesagt</span>
</li>`).join('')}</ul>`
: '<p class="muted">Noch keine Spieltage eingetragen.</p>';
} catch {
box.innerHTML = '<p class="muted">Termine konnten nicht geladen werden.</p>';
}
// Pile of Shame: wer dieses Jahr noch nicht spielen war
const shame = document.getElementById('shame');
try {
const { year, entries } = await api('GET', '/stats');
const names = entries.filter((s) => s.total === 0).map((s) => s.name).sort((a, b) => a.localeCompare(b, 'de'));
shame.innerHTML = names.length
? `<p class="muted">Waren ${year} noch kein einziges Mal spielen:</p>
<div class="chips">${names.map((n) => `<span class="chip">${esc(n)}</span>`).join('')}</div>`
: `<p class="muted">Leer – alle waren ${year} schon spielen.</p>`;
} catch {
shame.innerHTML = '<p class="muted">Konnte nicht geladen werden.</p>';
}
</script>
</body>
</html>