Compare commits

..

2 commits

Author SHA1 Message Date
d7f7a7e454 Neu: AGB-Seite + Impressum/Datenschutz aktualisiert (SW by-v985)
- Neue Seite agb.js mit 11 Abschnitten (Laufzeit, Zahlung, Widerruf etc.)
- Datenschutz: 'Abonnement & Kündigung' → 'Zahlungsdaten' (DSGVO-Fokus), DDG-Hinweis ergänzt
- Impressum: ODR-Link entfernt (EU-Plattform eingestellt 2025), Telefon-Pflichthinweis nach §5 DDG, Stand Mai 2026
- AGB-Link in alle Footer (index.html, landing.html, zuechter.html, welcome.js)
- page-section #page-agb in index.html, Route 'agb' in app.js ROUTES
2026-05-15 16:21:04 +02:00
d20e63496c Feat: AGB-Link im Footer (Welt-Welt) + AGB-Checkbox im Upgrade-Modal
- worlds.js: 'Datenschutz · AGB' in der Welt-Welt-Fußzeile
- settings.js: AGB-Checkbox über Widerrufs-Checkbox; beide müssen gecheckt sein bevor 'Anfrage senden' aktiv wird
2026-05-15 16:19:46 +02:00
11 changed files with 203 additions and 36 deletions

View file

@ -296,6 +296,7 @@
<div style="display:flex;gap:var(--space-3);justify-content:center">
<span data-page="impressum" style="cursor:pointer;text-decoration:underline">Impressum</span>
<span data-page="datenschutz" style="cursor:pointer;text-decoration:underline">Datenschutz</span>
<span data-page="agb" style="cursor:pointer;text-decoration:underline">AGB</span>
</div>
<div style="display:flex;justify-content:center">
<span data-page="gruender" style="cursor:pointer;font-weight:600;font-size:var(--text-xs);
@ -487,6 +488,10 @@
<div class="page-body page-container"></div>
</section>
<section class="page" id="page-agb">
<div class="page-body page-container"></div>
</section>
<section class="page" id="page-widget">
<div class="page-body page-container"></div>
</section>

View file

@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
const APP_VER = '984'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VER = '985'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
const IS_STAGING = location.hostname === 'staging.banyaro.app';
// Cache-Bust-Parameter nach Update-Reload sofort entfernen
@ -64,6 +64,7 @@ const App = (() => {
moderation: { title: 'Moderation', module: null, requiresAuth: true },
impressum: { title: 'Impressum', module: null },
datenschutz: { title: 'Datenschutz', module: null },
agb: { title: 'AGB', module: null },
widget: { title: 'Widget', module: null, requiresAuth: true },
notifications: { title: 'Aktuelles', module: null, requiresAuth: true },
breeder: { title: 'Züchter-Profil', module: null },

View file

@ -0,0 +1,150 @@
/* ============================================================
BAN YARO Allgemeine Geschäftsbedingungen
============================================================ */
window.Page_agb = (() => {
const S = {
h2: `font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)`,
p: `font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0`,
ul: `font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:var(--space-2) 0 0;padding-left:var(--space-5)`,
a: `color:var(--c-primary)`,
};
function sec(title, body) {
return `
<section style="margin-bottom:var(--space-6)">
<h2 style="${S.h2}">${title}</h2>
${body}
</section>`;
}
function init(container) {
container.innerHTML = `
<div style="max-width:640px;margin:0 auto;padding:var(--space-6) var(--space-4)">
<h1 style="font-size:var(--text-2xl);font-weight:var(--weight-bold);
color:var(--c-text);margin:0 0 var(--space-2)">Allgemeine Geschäftsbedingungen</h1>
<p style="${S.p};margin-bottom:var(--space-6)">Gültig ab Mai 2026</p>
${sec('1. Geltungsbereich', `
<p style="${S.p}">
Diese AGB gelten für die Nutzung der Plattform <strong>Ban Yaro</strong>
(<a href="https://banyaro.app" style="${S.a}">banyaro.app</a>), betrieben von:<br><br>
René Degelmann<br>
Ringstr. 26, 85560 Ebersberg<br>
E-Mail: <a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>
</p>
<p style="${S.p};margin-top:var(--space-3)">
Sie gelten ausschließlich für kostenpflichtige Abonnements. Die kostenlose Nutzung
der App setzt lediglich die Registrierung voraus.
</p>`)}
${sec('2. Leistungen', `
<p style="${S.p}">Ban Yaro bietet folgende kostenpflichtige Abonnements an:</p>
<ul style="${S.ul}">
<li>
<strong>Ban Yaro Pro 29 EUR/Jahr:</strong> Erweiterte App-Funktionen für mehrere
Hunde, KI-Features, zusätzliche Karten-Layer, Chat und Playdate-Funktion sowie
alle weiteren Pro-Funktionen laut aktuellem Funktionsumfang.
</li>
<li>
<strong>Ban Yaro Züchter 49 EUR/Jahr:</strong> Alle Pro-Funktionen plus
Zuchtkartei, Stammbaum, Wurfverwaltung und Züchterprofil.
</li>
</ul>
<p style="${S.p};margin-top:var(--space-3)">
Änderungen am Funktionsumfang werden vorab per E-Mail angekündigt. Wesentliche
Leistungsminderungen berechtigen zur außerordentlichen Kündigung.
</p>`)}
${sec('3. Preise und Zahlung', `
<p style="${S.p}">
Der Jahresbeitrag ist bei Vertragsschluss für die gesamte Laufzeit im Voraus fällig.
Die Zahlung erfolgt per Überweisung IBAN und Verwendungszweck stehen auf der
Rechnung, die per E-Mail zugestellt wird. Der Betrag ist innerhalb von
<strong>14 Tagen</strong> nach Rechnungsstellung zu überweisen.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Bei Zahlungsverzug erhalten Sie zunächst eine Zahlungserinnerung. Bleibt der Betrag
danach weiterhin ausstehend, behalten wir uns die fristlose Kündigung des Vertrags
gemäß § 314 BGB vor.
</p>`)}
${sec('4. Vertragslaufzeit und Kündigung', `
<p style="${S.p}">
Die Erstlaufzeit beträgt <strong>12 Monate</strong> ab dem Tag der Freischaltung.
Nach Ablauf verlängert sich der Vertrag auf unbestimmte Zeit kündbar jederzeit
mit einer Frist von <strong>einem Monat zum Monatsende</strong> (§ 309 Nr. 9 BGB).
</p>
<p style="${S.p};margin-top:var(--space-3)">
Die Kündigung ist jederzeit bequem in den <strong>App-Einstellungen</strong> möglich.
Der Zugang bleibt bis zum Ende der bereits bezahlten Laufzeit vollständig aktiv.
</p>`)}
${sec('5. Kein Erstattungsanspruch', `
<p style="${S.p}">
Bei vorzeitiger Kündigung durch den Nutzer erfolgt keine anteilige Rückerstattung
des Jahresbeitrags. Der Zugang bleibt bis zum Ende der Laufzeit vollständig nutzbar
du verlierst also nichts, was du bereits bezahlt hast.
</p>`)}
${sec('6. Widerrufsrecht', `
<p style="${S.p}">
Da die Nutzung sofort nach der Freischaltung beginnt und du dem beim Kauf
ausdrücklich zustimmst, erlischt das 14-tägige Widerrufsrecht gemäß
§ 356 Abs. 4 BGB mit Beginn der Nutzung. Die Zustimmung erfolgt aktiv
durch eine Checkbox beim Kaufabschluss.
</p>`)}
${sec('7. Fristlose Kündigung durch den Anbieter', `
<p style="${S.p}">
Wir sind berechtigt, den Vertrag aus wichtigem Grund fristlos zu kündigen
(§ 314 BGB). Ein wichtiger Grund liegt insbesondere vor, wenn nach einer
Zahlungserinnerung der offene Betrag weiterhin nicht beglichen wird.
In diesem Fall endet der Zugang mit Wirkung der Kündigung.
</p>`)}
${sec('8. Verfügbarkeit', `
<p style="${S.p}">
Wir streben eine hohe Verfügbarkeit von Ban Yaro an und arbeiten kontinuierlich
daran, die App stabil zu halten. Eine Garantie für ununterbrochene Verfügbarkeit
können wir jedoch nicht übernehmen. Geplante Wartungsarbeiten werden nach
Möglichkeit vorab in der App angekündigt.
</p>`)}
${sec('9. Änderungen dieser AGB', `
<p style="${S.p}">
Änderungen der AGB werden per <strong>E-Mail und in der App</strong> angekündigt
mindestens 4 Wochen vor Inkrafttreten. Widersprichst du den Änderungen nicht
innerhalb dieser Frist, gelten sie als angenommen. Dein Widerspruchsrecht und
das Recht zur außerordentlichen Kündigung bleiben unberührt.
</p>`)}
${sec('10. Anwendbares Recht', `
<p style="${S.p}">
Es gilt ausschließlich <strong>deutsches Recht</strong>. Als Verbraucher hast du
deinen allgemeinen Gerichtsstand. Die EU-Plattform zur Online-Streitbeilegung
(ec.europa.eu/consumers/odr) wurde eingestellt. Wir nehmen nicht an alternativen
Streitbeilegungsverfahren teil (§ 36 VSBG).
</p>`)}
${sec('11. Kontakt', `
<p style="${S.p}">
René Degelmann<br>
Ringstr. 26, 85560 Ebersberg<br>
E-Mail: <a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>
</p>`)}
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
Stand: Mai 2026 · Version 1
</p>
</div>
`;
}
function refresh() {}
return { init, refresh };
})();

View file

@ -70,6 +70,9 @@ window.Page_datenschutz = (() => {
Push-Benachrichtigungen. Einwilligungen können jederzeit mit Wirkung für die Zukunft
widerrufen werden (Art. 7 Abs. 3 DSGVO) einfach die entsprechende Funktion in den
Einstellungen deaktivieren oder die Browser-Freigabe entziehen.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Impressum und rechtliche Grundlage nach § 5 DDG (Digitale-Dienste-Gesetz).
</p>`)}
${sec('Datenweitergabe', `
@ -238,34 +241,19 @@ window.Page_datenschutz = (() => {
style="${S.a}">www.lda.bayern.de</a>
</p>`)}
${sec('Abonnement &amp; Kündigung', `
${sec('Zahlungsdaten', `
<p style="${S.p}">
Ban Yaro Pro und das Züchter-Paket sind Jahresabonnements mit einer Laufzeit von
12 Monaten ab Freischaltung.
Wenn du ein kostenpflichtiges Abonnement abschließt, verarbeiten wir folgende Daten:
Name, E-Mail-Adresse, Rechnungsadresse und den Zahlungseingang. Rechtsgrundlage ist
Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung). Rechnungsdaten werden gemäß
§ 147 AO <strong>10 Jahre</strong> aufbewahrt. Rechnungen werden per E-Mail mit
TLS-Verschlüsselung zugestellt.
</p>
<p style="${S.p};margin-top:var(--space-3)">
<strong>Laufzeit &amp; Verlängerung:</strong> Das Abonnement läuft 12 Monate ab dem
Tag der Freischaltung. Nach Ablauf verlängert es sich auf unbestimmte Zeit mit einer
Kündigungsfrist von einem Monat zum Monatsende, sofern nicht vorher gekündigt wird
(§&nbsp;309 Nr.&nbsp;9 BGB).
</p>
<p style="${S.p};margin-top:var(--space-3)">
<strong>Zahlung:</strong> Der Jahresbeitrag (29&nbsp;EUR für Pro, 49&nbsp;EUR für
Züchter) wird einmalig für die gesamte Laufzeit im Voraus fällig.
</p>
<p style="${S.p};margin-top:var(--space-3)">
<strong>Kündigung:</strong> Die Kündigung kann jederzeit in den Einstellungen der App
erfolgen. Der Zugang bleibt bis zum Ende der bezahlten Laufzeit erhalten.
</p>
<p style="${S.p};margin-top:var(--space-3)">
<strong>Erstattung:</strong> Bei vorzeitiger Kündigung durch den Nutzer erfolgt keine
anteilige Rückerstattung des Jahresbeitrags. Der Zugang bleibt bis zum Ende der
bezahlten Laufzeit vollständig bestehen.
</p>
<p style="${S.p};margin-top:var(--space-3)">
<strong>Widerrufsrecht:</strong> Da die Nutzung sofort nach Freischaltung beginnt und
der Nutzer dem ausdrücklich zustimmt, erlischt das 14-tägige Widerrufsrecht gemäß
§&nbsp;356 Abs.&nbsp;4 BGB mit Beginn der Nutzung.
Deine Zahlungsdaten (IBAN) werden nur für die Zuordnung des Zahlungseingangs intern
verwendet und nicht an Dritte weitergegeben. Die vertraglichen Bedingungen (Laufzeit,
Kündigung, Erstattung) findest du in unseren
<a href="#agb" style="${S.a}">AGB</a>.
</p>`)}
${sec('Speicherdauer', `

View file

@ -24,11 +24,15 @@ window.Page_impressum = (() => {
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Kontakt</h2>
<!-- TODO: Telefonnummer ergänzen (Pflicht nach §5 DDG) -->
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
E-Mail: <a href="mailto:hallo@banyaro.app"
style="color:var(--c-primary)">hallo@banyaro.app</a><br>
Kontaktformular: <a href="mailto:hallo@banyaro.app"
style="color:var(--c-primary)">Nachricht senden</a>
style="color:var(--c-primary)">Nachricht senden</a><br>
<span style="color:var(--c-warning,#f59e0b);font-size:var(--text-xs)">
Telefonnummer folgt (Pflichtangabe nach § 5 DDG)
</span>
</p>
</section>
@ -46,9 +50,6 @@ window.Page_impressum = (() => {
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Streitschlichtung</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit:
<a href="https://ec.europa.eu/consumers/odr" target="_blank" rel="noopener"
style="color:var(--c-primary)">https://ec.europa.eu/consumers/odr</a>.<br>
Wir sind nicht bereit und nicht verpflichtet, an einem Streitbeilegungsverfahren vor einer
Verbraucherschlichtungsstelle teilzunehmen (§ 36 VSBG).
</p>
@ -67,7 +68,7 @@ window.Page_impressum = (() => {
</section>
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
Stand: April 2026
Stand: Mai 2026
</p>
</div>

View file

@ -313,6 +313,18 @@ window.Page_settings = (() => {
font-size:var(--text-xs);color:#c05000;line-height:1.6;margin-top:var(--space-2)">
💡 Tipp: Trag deine <strong>Rechnungsadresse</strong> im Profil ein dann können wir die Rechnung vollständig ausstellen.
</div>` : ''}
<div style="margin-top:var(--space-3);padding:var(--space-3);border-radius:var(--radius-md);
background:var(--c-surface-raised,rgba(0,0,0,.04));">
<label style="display:flex;align-items:flex-start;gap:var(--space-2);cursor:pointer;
font-size:var(--text-xs);color:var(--c-text-secondary);line-height:1.5">
<input type="checkbox" id="agb-checkbox"
style="margin-top:2px;flex-shrink:0;accent-color:${color}">
<span>
Ich habe die <span style="color:var(--c-primary);cursor:pointer"
onclick="App.navigate('agb')">AGB</span> gelesen und stimme ihnen zu.
</span>
</label>
</div>
<div style="margin-top:var(--space-3);padding:var(--space-3);border-radius:var(--radius-md);
background:var(--c-surface-raised,rgba(0,0,0,.04));">
<label style="display:flex;align-items:flex-start;gap:var(--space-2);cursor:pointer;
@ -342,12 +354,16 @@ window.Page_settings = (() => {
</button>`
});
const agbBox = document.getElementById('agb-checkbox');
const widerrufBox = document.getElementById('widerruf-checkbox');
const sendBtn = document.getElementById('upgrade-request-send-btn');
const sendBtn = document.getElementById('upgrade-request-send-btn');
if (sendBtn) sendBtn.disabled = true;
widerrufBox?.addEventListener('change', () => {
if (sendBtn) sendBtn.disabled = !widerrufBox.checked;
});
const _checkBtns = () => {
if (sendBtn) sendBtn.disabled = !(agbBox?.checked && widerrufBox?.checked);
};
agbBox?.addEventListener('change', _checkBtns);
widerrufBox?.addEventListener('change', _checkBtns);
document.getElementById('upgrade-request-send-btn')?.addEventListener('click', async () => {
const btn = document.getElementById('upgrade-request-send-btn');

View file

@ -167,6 +167,8 @@ window.Page_welcome = (() => {
<a href="/#impressum" style="color:var(--c-text-muted)">Impressum</a>
&nbsp;·&nbsp;
<a href="/#datenschutz" style="color:var(--c-text-muted)">Datenschutz</a>
&nbsp;·&nbsp;
<a href="/#agb" style="color:var(--c-text-muted)">AGB</a>
</p>
</div>
`;

View file

@ -1658,6 +1658,8 @@ window.Worlds = (() => {
</div>
<div class="world-footer-links">
<span data-wnav="datenschutz">Datenschutz</span>
<span style="color:var(--c-border)">·</span>
<span data-wnav="agb">AGB</span>
</div>
</div>
`;

View file

@ -1533,6 +1533,7 @@
<div class="footer-links">
<a href="/#impressum">Impressum</a>
<a href="/#datenschutz">Datenschutz</a>
<a href="/#agb">AGB</a>
<a href="/presse">Presse</a>
</div>
</div>

View file

@ -3,7 +3,7 @@
Offline-Cache + Push Notifications + Tile-Cache
============================================================ */
const CACHE_VERSION = 'by-v984';
const CACHE_VERSION = 'by-v985';
const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache

View file

@ -592,6 +592,7 @@
<div class="footer-links">
<a href="/#impressum">Impressum</a>
<a href="/#datenschutz">Datenschutz</a>
<a href="/#agb">AGB</a>
<a href="/info">Über Ban Yaro</a>
<a href="/presse">Presse</a>
</div>