V-US-01-02: Leistungsübersicht Packete in Json gekappselt

feature/V-US-01-02-leistungsuebersicht
Vincent Laux 2026-09-24 18:01:09 +02:00
parent fa4c5ac520
commit 312e788364
3 changed files with 144 additions and 76 deletions

View File

@ -14,72 +14,17 @@
<body> <body>
<!-- US-01-02 Leistungsübersicht --> <!-- US-01-02 Leistungsübersicht -->
<section id="leistungen" class="pakete"> <section id="leistungen" class="pakete">
<div class="pakete__intro"> <div class="pakete__intro">
<h2 class="pakete__titel">Deine Pakete</h2> <h2 class="pakete__titel"></h2>
<p class="pakete__text"> <p class="pakete__text"></p>
Drei Wege zu einer Ernährung, die zu deinem Training, deinem Alltag und
deinem Alter passt &ndash; entwickelt für Triathletinnen und Triathleten ab 50.
</p>
</div> </div>
<div class="pakete__grid"> <div class="pakete__grid"></div>
<article class="paket-karte">
<h3 class="paket-karte__name">Starter</h3>
<p class="paket-karte__preis">
<span class="paket-karte__betrag">79&nbsp;&euro;</span>
<span class="paket-karte__zeitraum">/ Monat</span>
</p>
<p class="paket-karte__beschreibung">Für den Einstieg in eine bewusste Ernährung neben dem Training.</p>
<ul class="paket-karte__leistungen">
<li>Erstgespräch &amp; Bedarfsanalyse</li>
<li>Individueller Ernährungsplan</li>
<li>Monatliches Check-in per E-Mail</li>
<li>Zugang zu Beispielplänen</li>
</ul>
<button class="paket-karte__cta" type="button" data-paket="Starter">Paket wählen</button>
</article>
<article class="paket-karte paket-karte--empfohlen">
<p class="paket-karte__badge">Beliebteste Wahl</p>
<h3 class="paket-karte__name">STANDART</h3>
<p class="paket-karte__preis">
<span class="paket-karte__betrag">149&nbsp;&euro;</span>
<span class="paket-karte__zeitraum">/ Monat</span>
</p>
<p class="paket-karte__beschreibung">Laufende Begleitung für alle, die regelmäßig für Wettkämpfe trainieren.</p>
<ul class="paket-karte__leistungen">
<li>Alles aus Starter</li>
<li>Plan-Anpassung je Trainingsphase</li>
<li>Zwei Beratungsgespräche pro Monat</li>
<li>Wettkampf-Ernährungsstrategie</li>
<li>Direkter Chat mit deiner Beraterin</li>
</ul>
<button class="paket-karte__cta" type="button" data-paket="Ausdauer">Paket wählen</button>
</article>
<article class="paket-karte">
<h3 class="paket-karte__name">Rundum Sorglos Paket</h3>
<p class="paket-karte__preis">
<span class="paket-karte__betrag">249&nbsp;&euro;</span>
<span class="paket-karte__zeitraum">/ Monat</span>
</p>
<p class="paket-karte__beschreibung">Volle Betreuung für ambitionierte Athletinnen und Athleten.</p>
<ul class="paket-karte__leistungen">
<li>Alles aus Ausdauer</li>
<li>Wöchentliche Beratungsgespräche</li>
<li>Individuelle Supplement-Empfehlung</li>
<li>Betreuung am Wettkampftag</li>
<li>Priorisierter Support</li>
</ul>
<button class="paket-karte__cta" type="button" data-paket="Wettkampf">Paket wählen</button>
</article>
</div>
</section> </section>
<script src="js/script.js"></script> <script src="js/script.js"></script>
</body> </body>
</html> </html>

View File

@ -2,26 +2,94 @@
// Markiert das gewählte Paket visuell und stellt die Auswahl bereit, // Markiert das gewählte Paket visuell und stellt die Auswahl bereit,
// damit US-01-03 (Pakete online buchen) später darauf aufbauen kann. // damit US-01-03 (Pakete online buchen) später darauf aufbauen kann.
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", async () => {
const karten = document.querySelectorAll(".paket-karte");
karten.forEach((karte) => { // JSON-Datei laden
const button = karte.querySelector(".paket-karte__cta"); const response = await fetch("data/pakete.json");
if (!button) return; const daten = await response.json();
button.addEventListener("click", () => { // Elemente aus dem HTML holen
karten.forEach((k) => k.classList.remove("paket-karte--ausgewaehlt")); const titel = document.querySelector(".pakete__titel");
karte.classList.add("paket-karte--ausgewaehlt"); const text = document.querySelector(".pakete__text");
const grid = document.querySelector(".pakete__grid");
const paketName = button.dataset.paket; // Intro mit Daten aus JSON füllen
titel.textContent = daten.intro.titel;
text.textContent = daten.intro.text;
// Andere Skripte (z. B. die Buchungsstrecke aus US-01-03) // Vorhandenen Inhalt entfernen
// können auf dieses Event hören, statt den DOM abzufragen. grid.innerHTML = "";
document.dispatchEvent(
new CustomEvent("paket:ausgewaehlt", { detail: { paket: paketName } })
);
console.log(`Paket "${paketName}" ausgewählt.`); // Für jedes Paket eine Karte erstellen
daten.pakete.forEach(paket => {
// Artikel erstellen
const karte = document.createElement("article");
karte.classList.add("paket-karte");
// Empfohlenes Paket bekommt zusätzliche Klasse
if (paket.empfohlen) {
karte.classList.add("paket-karte--empfohlen");
}
// Badge nur erstellen, wenn eines vorhanden ist
if (paket.badge) {
const badge = document.createElement("p");
badge.classList.add("paket-karte__badge");
badge.textContent = paket.badge;
karte.appendChild(badge);
}
// Name
const name = document.createElement("h3");
name.classList.add("paket-karte__name");
name.textContent = paket.name;
karte.appendChild(name);
// Preis
const preis = document.createElement("p");
preis.classList.add("paket-karte__preis");
const betrag = document.createElement("span");
betrag.classList.add("paket-karte__betrag");
betrag.textContent = `${paket.preis} €`;
const zeitraum = document.createElement("span");
zeitraum.classList.add("paket-karte__zeitraum");
zeitraum.textContent = `/ ${paket.zeitraum}`;
preis.appendChild(betrag);
preis.appendChild(zeitraum);
karte.appendChild(preis);
// Beschreibung
const beschreibung = document.createElement("p");
beschreibung.classList.add("paket-karte__beschreibung");
beschreibung.textContent = paket.beschreibung;
karte.appendChild(beschreibung);
// Leistungen
const liste = document.createElement("ul");
liste.classList.add("paket-karte__leistungen");
paket.leistungen.forEach(leistung => {
const punkt = document.createElement("li");
punkt.textContent = leistung;
liste.appendChild(punkt);
}); });
karte.appendChild(liste);
// Button
const button = document.createElement("button");
button.classList.add("paket-karte__cta");
button.type = "button";
button.textContent = "Paket wählen";
button.dataset.paket = paket.dataPaket;
karte.appendChild(button);
// Karte ins Grid einfügen
grid.appendChild(karte);
}); });
}); });

55
json/pakete.json 100644
View File

@ -0,0 +1,55 @@
{
"intro": {
"titel": "Deine Pakete",
"text": "Drei Wege zu einer Ernährung, die zu deinem Training, deinem Alltag und deinem Alter passt – entwickelt für Triathletinnen und Triathleten ab 50."
},
"pakete": [
{
"name": "Starter",
"preis": 79,
"zeitraum": "Monat",
"beschreibung": "Für den Einstieg in eine bewusste Ernährung neben dem Training.",
"leistungen": [
"Erstgespräch & Bedarfsanalyse",
"Individueller Ernährungsplan",
"Monatliches Check-in per E-Mail",
"Zugang zu Beispielplänen"
],
"badge": null,
"empfohlen": false,
"dataPaket": "Starter"
},
{
"name": "STANDART",
"preis": 149,
"zeitraum": "Monat",
"beschreibung": "Laufende Begleitung für alle, die regelmäßig für Wettkämpfe trainieren.",
"leistungen": [
"Alles aus Starter",
"Plan-Anpassung je Trainingsphase",
"Zwei Beratungsgespräche pro Monat",
"Wettkampf-Ernährungsstrategie",
"Direkter Chat mit deiner Beraterin"
],
"badge": "Beliebteste Wahl",
"empfohlen": true,
"dataPaket": "Ausdauer"
},
{
"name": "Rundum Sorglos Paket",
"preis": 249,
"zeitraum": "Monat",
"beschreibung": "Volle Betreuung für ambitionierte Athletinnen und Athleten.",
"leistungen": [
"Alles aus Ausdauer",
"Wöchentliche Beratungsgespräche",
"Individuelle Supplement-Empfehlung",
"Betreuung am Wettkampftag",
"Priorisierter Support"
],
"badge": null,
"empfohlen": false,
"dataPaket": "Wettkampf"
}
]
}