267 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ======================================================
components.js VARIANTE ROT (Dark Theme)
------------------------------------------------------
Rendert alle wiederkehrenden Elemente und die Inhalte
aus den zentralen Daten-Dateien (varianten/shared/).
Erwartet window.FFW_BASE (Pfad zum Projekt-Root).
Aktiver Navigationspunkt über <body data-page="...">.
====================================================== */
(function () {
const base = window.FFW_BASE || "";
const page = document.body.dataset.page || "";
/* ======================================================
NAVIGATION & FOOTER
====================================================== */
const NAV = `
<nav class="navbar navbar-expand-lg ff-navbar">
<div class="container">
<a class="navbar-brand" href="index.html">
<img src="${base}bilder/ffw_transp_72.gif" alt="Logo Feuerwehr Stadt Wehlen">
<span>Feuerwehr Stadt&nbsp;Wehlen</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#ffNav"
aria-controls="ffNav" aria-expanded="false" aria-label="Menü öffnen">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="ffNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" data-page="start" href="index.html">Startseite</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-page="ueber" role="button" data-bs-toggle="dropdown" aria-expanded="false">Über uns</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" data-page="geschichte" href="geschichte.html">Geschichte</a></li>
<li><a class="dropdown-item" data-page="technik" href="technik.html">Technik</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" data-page="mitglieder" href="mitglieder.html">Organigramm</a></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" data-page="dienstplan" href="dienstplan.html">Dienstplan</a></li>
<li class="nav-item"><a class="nav-link" data-page="veranstaltungen" href="#">Veranstaltungen</a></li>
<li class="nav-item"><a class="nav-link" data-page="kontakt" href="#">Kontakt / Impressum</a></li>
</ul>
</div>
</div>
</nav>`;
const FOOTER = `
<footer class="ff-footer">
<div class="container">
<div class="row g-4 align-items-start text-center text-md-start">
<div class="col-md-4">
<h6>Letzte Aktualisierung</h6>
<p>17. März 2026</p>
<small>(Version 1.2)</small>
</div>
<div class="col-md-4">
<h6>Kleine Statistik der FFw Stadt Wehlen</h6>
<p><strong>Aktive:</strong> 27 | <strong>Jugend:</strong> 23 | <strong>Passive:</strong> 9 | <strong>Förderverein:</strong> 172</p>
</div>
<div class="col-md-4">
<h6>Navigation</h6>
<ul class="footer-nav justify-content-center justify-content-md-start">
<li><a href="geschichte.html">Geschichte</a></li>
<li><a href="technik.html">Technik</a></li>
<li><a href="mitglieder.html">Organigramm</a></li>
<li><a href="dienstplan.html">Dienstplan</a></li>
</ul>
</div>
</div>
</div>
</footer>`;
const headerMount = document.getElementById("site-header");
if (headerMount) headerMount.innerHTML = NAV;
const footerMount = document.getElementById("site-footer");
if (footerMount) footerMount.innerHTML = FOOTER;
/* Aktiven Menüpunkt markieren */
document.querySelectorAll(`[data-page="${page}"]`).forEach(el => el.classList.add("active"));
/* ======================================================
HERO (Startseite)
====================================================== */
const heroMount = document.getElementById("site-hero");
if (heroMount) {
heroMount.innerHTML = `
<section class="ff-hero" style="--hero-bild: url('${base}bilder/geraetehaus.png')">
<div class="container">
<div class="ff-hero-inhalt">
<div class="ff-hero-badge"><span>Freiwillige Feuerwehr seit 1901</span></div>
<h1>Feuerwehr<br><span class="highlight">Stadt Wehlen</span></h1>
<p>Ehrenamtlich im Einsatz für Stadt Wehlen und Pötzscha bei Brand, Hilfeleistung und Wasserrettung auf der Elbe.</p>
<div class="ff-hero-cta">
<a class="btn-ff" href="technik.html">Unsere Technik</a>
<a class="btn-ff btn-ff-outline" href="dienstplan.html">Dienstplan &amp; Termine</a>
</div>
</div>
</div>
</section>`;
}
/* ======================================================
GESCHICHTE Zeitleiste mit Tabs
====================================================== */
const geschichteMount = document.getElementById("geschichte-inhalt");
if (geschichteMount && window.FFW_GESCHICHTE) {
const tabs = window.FFW_GESCHICHTE.map((epoche, i) =>
`<button class="zl-tab${i === 0 ? " active" : ""}" data-zl="${i}">${epoche.zeitraum}</button>`
).join("");
const panels = window.FFW_GESCHICHTE.map((epoche, i) => {
const inhalt = epoche.eintraege.map(e => {
const bildBtn = e.bild
? `<button type="button" class="btn-ff mt-3" data-bs-toggle="modal" data-bs-target="#modal1921">${window.FFW_GESCHICHTE_BILD.button}</button>`
: "";
return `${e.titel ? `<h2>${e.titel}</h2>` : ""}${e.html}${bildBtn}`;
}).join("");
return `<div class="zl-panel${i === 0 ? "" : " d-none"}" data-zl-panel="${i}">${inhalt}</div>`;
}).join("");
geschichteMount.innerHTML = `
<div class="zl-tabs" role="tablist" aria-label="Epochen der Wehrgeschichte">${tabs}</div>
${panels}`;
geschichteMount.querySelectorAll(".zl-tab").forEach(tab => {
tab.addEventListener("click", () => {
geschichteMount.querySelectorAll(".zl-tab").forEach(t => t.classList.remove("active"));
geschichteMount.querySelectorAll(".zl-panel").forEach(p => p.classList.add("d-none"));
tab.classList.add("active");
geschichteMount.querySelector(`[data-zl-panel="${tab.dataset.zl}"]`).classList.remove("d-none");
});
});
/* Modal für den Zeitungsartikel von 1921 */
document.body.insertAdjacentHTML("beforeend", `
<div class="modal fade" id="modal1921" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">${window.FFW_GESCHICHTE_BILD.titel}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Schließen"></button>
</div>
<div class="modal-body text-center">
<img src="${base}${window.FFW_GESCHICHTE_BILD.src}" alt="${window.FFW_GESCHICHTE_BILD.titel}" class="img-fluid">
</div>
</div>
</div>
</div>`);
}
/* ======================================================
TECHNIK Übersicht nach Kategorien gruppiert
====================================================== */
const technikMount = document.getElementById("technik-grid");
if (technikMount && window.FFW_FAHRZEUGE) {
const kategorien = [...new Set(window.FFW_FAHRZEUGE.map(f => f.kategorie))];
technikMount.innerHTML = kategorien.map(kat => {
const karten = window.FFW_FAHRZEUGE
.filter(f => f.kategorie === kat)
.map(f => {
const inner = `
<div class="bild" style="background-image: url('${base}${f.karte}')" role="img" aria-label="${f.name}"></div>
${f.inArbeit ? `<span class="bald">Demnächst</span>` : ""}
<span class="titel"><span>${f.name}</span><span class="pfeil">→</span></span>`;
return `<div class="col-md-4 col-sm-6">
${f.inArbeit
? `<div class="tech-karte">${inner}</div>`
: `<a class="tech-karte" href="fahrzeug.html?id=${f.id}">${inner}</a>`}
</div>`;
}).join("");
return `<h2 class="ff-kat-titel">${kat}</h2><div class="row g-4">${karten}</div>`;
}).join("");
}
/* ======================================================
FAHRZEUG Detailseite (datengetrieben via ?id=)
====================================================== */
const fzMount = document.getElementById("fahrzeug-detail");
if (fzMount && window.FFW_FAHRZEUGE) {
const id = new URLSearchParams(location.search).get("id");
const f = window.FFW_FAHRZEUGE.find(x => x.id === id);
if (!f || f.inArbeit) {
fzMount.innerHTML = `
<div class="ff-card">
<h3>Fahrzeug nicht gefunden</h3>
<p class="termin-beschr">Dieses Fahrzeug existiert nicht (mehr) oder die Seite befindet sich im Aufbau.</p>
<a class="btn-ff mt-3" href="technik.html">← Zurück zur Technik-Übersicht</a>
</div>`;
} else {
document.title = `${f.titel} | Feuerwehr Stadt Wehlen`;
const specs = f.daten.map(([label, wert]) =>
`<li><span class="spec-label">${label}</span><span>${wert}</span></li>`).join("");
const bereiche = (f.bereiche || []).map(b => `
<h3 class="fz-sektion">${b.titel}</h3>
<ul class="fz-punkte">${b.punkte.map(p => `<li>${p}</li>`).join("")}</ul>`).join("");
const galerie = f.bilder.length > 1
? `<div id="fahrzeugCarousel" class="carousel slide">
<div class="carousel-inner">
${f.bilder.map((b, i) => `<div class="carousel-item${i === 0 ? " active" : ""}"><img src="${base}${b.src}" class="d-block w-100" alt="${b.alt}" loading="lazy"></div>`).join("")}
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#fahrzeugCarousel" data-bs-slide="prev"><span class="carousel-control-prev-icon"></span><span class="visually-hidden">Zurück</span></button>
<button class="carousel-control-next" type="button" data-bs-target="#fahrzeugCarousel" data-bs-slide="next"><span class="carousel-control-next-icon"></span><span class="visually-hidden">Weiter</span></button>
</div>`
: `<img src="${base}${f.bilder[0].src}" class="img-fluid w-100" alt="${f.bilder[0].alt}" loading="lazy">`;
fzMount.innerHTML = `
<div class="row g-4">
<div class="col-lg-7">
<div class="ff-card">
${f.standort ? `<div class="standort-badge"><span>Standort: ${f.standort}</span></div>` : ""}
<h3>Fahrzeugdaten</h3>
<ul class="spec-list">${specs}</ul>
${bereiche}
${f.text ? `<p class="mt-4 mb-0" style="line-height:1.8">${f.text}</p>` : ""}
</div>
</div>
<div class="col-lg-5">
${galerie}
${f.hinweis ? `<div class="fz-hinweis">${f.hinweis}</div>` : ""}
</div>
</div>`;
const carouselEl = fzMount.querySelector("#fahrzeugCarousel");
if (carouselEl && window.bootstrap) new bootstrap.Carousel(carouselEl, { interval: 5000 });
}
}
/* ======================================================
MITGLIEDER Organigramm
====================================================== */
const orgMount = document.getElementById("mitglieder-inhalt");
if (orgMount && window.FFW_MITGLIEDER) {
const M = window.FFW_MITGLIEDER;
const box = (eintrag, klasse = "") => `
<div class="org-box ${klasse}">
<span class="rolle">${eintrag.rolle}</span>
<span class="name">${eintrag.namen.join("<br>")}</span>
</div>`;
const ebene = (eintraege, klasse = "") =>
`<div class="org-ebene">${eintraege.map(e => box(e, klasse)).join("")}</div>`;
const gruppen = M.gruppen.map(g => {
const inhalt = g.abschnitte
? g.abschnitte.map(a => `<span class="label">${a.label}</span><ul>${a.namen.map(n => `<li>${n}</li>`).join("")}</ul>`).join("")
: `<ul>${g.namen.map(n => `<li>${n}</li>`).join("")}</ul>`;
return `<div class="org-gruppe"><h3>${g.titel}</h3>${inhalt}</div>`;
}).join("");
orgMount.innerHTML = `
${ebene([M.fuehrung[0]], "fuehrung")}
${ebene([M.fuehrung[1]], "fuehrung")}
${ebene(M.stab)}
${ebene(M.fachwarte)}
<div class="org-gruppen">${gruppen}</div>`;
}
})();