/* ============================================================
BAN YARO — Willkommensseite
============================================================ */
window.Page_welcome = (() => {
let _container = null;
let _appState = null;
let _showInstall = false;
async function init(container, appState, params = {}) {
_container = container;
_appState = appState;
_showInstall = !!params.install;
_render();
if (_showInstall) {
setTimeout(() => {
_container.querySelector('.wc-install-card')?.scrollIntoView({ behavior: 'smooth', block: 'start' });
}, 100);
}
}
function refresh() { _render(); }
function onDogChange() {}
// ----------------------------------------------------------
// FEATURES — Icon, Titel, Beschreibung, Zielseite
// ----------------------------------------------------------
const FEATURES = [
{ icon: 'book-open', label: 'Tagebuch', page: 'diary' },
{ icon: 'first-aid', label: 'Gesundheit', page: 'health' },
{ icon: 'map-trifold', label: 'Karte', page: 'map' },
{ icon: 'path', label: 'Routen', page: 'routes' },
{ icon: 'target', label: 'Training', page: 'uebungen' },
{ icon: 'warning-octagon', label: 'Giftköder', page: 'poison' },
{ icon: 'users', label: 'Freunde', page: 'friends' },
{ icon: 'chat-circle-dots', label: 'Nachrichten', page: 'chat' },
{ icon: 'paw-print', label: 'Gassi-Treffen', page: 'walks' },
{ icon: 'house-line', label: 'Sitting', page: 'sitting' },
{ icon: 'push-pin', label: 'Forum', page: 'forum' },
{ icon: 'books', label: 'Rassen-Wiki', page: 'wiki' },
{ icon: 'calendar-dots', label: 'Events', page: 'events' },
{ icon: 'bell', label: 'Neuigkeiten', page: 'notifications' },
{ icon: 'handshake', label: 'Knigge', page: 'knigge' },
{ icon: 'magnifying-glass', label: 'Vermisste', page: 'lost' },
];
// ----------------------------------------------------------
// RENDER
// ----------------------------------------------------------
function _render() {
const isInstalled = window.matchMedia('(display-mode: standalone)').matches
|| window.navigator.standalone === true;
const user = _appState?.user;
_injectStyles();
if (user) {
_renderLoggedIn(isInstalled);
} else {
_renderLanding(isInstalled);
}
_bindEvents();
_pulseMenuBtn();
}
// ----------------------------------------------------------
// LANDING PAGE — nicht eingeloggte Besucher
// ----------------------------------------------------------
function _renderLanding(isInstalled) {
const hasPrompt = !!App.getInstallPrompt();
_container.innerHTML = `
Alles für deinen Hund.
Tagebuch, Gesundheit, Karte, Community —
auf einem Server in Deutschland. Kostenlos.
${hasPrompt ? `
App installieren
` : `
Kostenlos loslegen
`}
Schon dabei? Anmelden
Kostenlos
Kein App Store
Daten in Deutschland
Tagebuch & Erinnerungen
Halte jeden gemeinsamen Moment fest — Fotos, Einträge, Stimmungen. Nur für dich, privat und sicher.
Gesundheit im Blick
Impfungen, Gewicht, Tierarzttermine — alles an einem Ort. Du siehst immer, wann was ansteht.
Community vor Ort
Giftköder-Warnungen, Gassi-Treffen, Events — was in deiner Gegend gerade passiert.
Training & KI-Trainer
Über 100 Übungen mit Schritt-für-Schritt-Anleitungen. Mit KI-Unterstützung, die deinen Hund kennt.
Deine Daten gehören dir.
Kein Facebook. Kein Google. Keine Werbung.
Ban Yaro läuft auf einem eigenen Server in Deutschland —
dein Tagebuch, deine Routen, deine Gesundheitsdaten
bleiben privat.
Und noch viel mehr
${FEATURES.map(f => `
`).join('')}
${hasPrompt ? `
App installieren — kostenlos
` : `
Jetzt kostenlos starten
`}
Kein App Store · Direkt auf den Home-Bildschirm
${!isInstalled ? `
Installationsanleitung
` : ''}
${_showInstall ? `
` : ''}
`;
}
// ----------------------------------------------------------
// EINGELOGGTE ANSICHT — kompakter Überblick
// ----------------------------------------------------------
function _renderLoggedIn(isInstalled) {
_container.innerHTML = `
Ban Yaro
Schön, dass du wieder da bist${_appState?.user?.name ? ', ' + UI.escape(_appState.user.name) + ' ' : ''}!
Was Ban Yaro kann
${FEATURES.map(f => `
${f.label}
`).join('')}
${(!isInstalled || _showInstall) ? `
` : ''}
`;
}
// ----------------------------------------------------------
// STYLES
// ----------------------------------------------------------
function _injectStyles() {
if (document.getElementById('wc-styles')) return;
const s = document.createElement('style');
s.id = 'wc-styles';
s.textContent = `
/* ── Landing Page ──────────────────────────────────────── */
.wc-landing { display: flex; flex-direction: column; }
/* Hero */
.wc-lhero {
background: linear-gradient(160deg, var(--c-primary) 0%, color-mix(in srgb, var(--c-primary) 70%, transparent) 60%, var(--c-bg) 100%);
text-align: center;
padding: var(--space-8) var(--space-5) var(--space-8);
position: relative;
overflow: hidden;
}
.wc-lhero::before {
content: '';
position: absolute; inset: 0;
background: radial-gradient(ellipse at 50% 0%, rgba(255,255,255,0.18) 0%, transparent 65%);
pointer-events: none;
}
.wc-lhero-icon {
width: 80px; height: 80px;
border-radius: 20px;
box-shadow: 0 8px 32px rgba(0,0,0,0.25);
display: block; margin: 0 auto var(--space-5);
position: relative;
}
.wc-lhero-headline {
font-size: 2.6rem; font-weight: 800; line-height: 1.1;
color: #fff;
margin: 0 0 var(--space-4);
text-shadow: 0 2px 12px rgba(0,0,0,0.15);
letter-spacing: -0.02em;
position: relative;
}
.wc-lhero-sub {
font-size: var(--text-base); color: rgba(255,255,255,0.88);
line-height: 1.6; margin: 0 0 var(--space-6);
position: relative;
}
.wc-lhero-cta {
display: flex; flex-direction: column;
align-items: center; gap: var(--space-3);
margin-bottom: var(--space-6);
position: relative;
}
.wc-btn-hero {
background: #fff; color: var(--c-primary);
font-size: var(--text-base); font-weight: var(--weight-bold);
padding: 14px var(--space-6); border-radius: 100px;
border: none; width: 100%; max-width: 320px;
box-shadow: 0 4px 20px rgba(0,0,0,0.2);
display: flex; align-items: center; justify-content: center; gap: var(--space-2);
transition: transform 0.1s, box-shadow 0.1s;
}
.wc-btn-hero:active { transform: scale(0.97); box-shadow: 0 2px 10px rgba(0,0,0,0.15); }
.wc-btn-login {
color: rgba(255,255,255,0.9) !important;
font-size: var(--text-sm);
padding: var(--space-2) var(--space-4);
border-color: rgba(255,255,255,0.35) !important;
}
.wc-trust-strip {
display: flex; justify-content: center;
gap: var(--space-4); flex-wrap: wrap;
position: relative;
}
.wc-trust-strip span {
display: flex; align-items: center; gap: 5px;
font-size: var(--text-xs); color: rgba(255,255,255,0.8);
font-weight: var(--weight-semibold);
}
.wc-trust-strip .ph-icon { width: 13px; height: 13px; }
/* Feature Cards */
.wc-feature {
display: flex; align-items: flex-start; gap: var(--space-4);
padding: var(--space-6) var(--space-5);
border-bottom: 1px solid var(--c-border-light);
}
.wc-feature--a { background: var(--c-bg); }
.wc-feature--b { background: var(--c-surface); }
.wc-feature--c { background: var(--c-bg); }
.wc-feature--d { background: var(--c-surface); }
.wc-feature-icon {
width: 52px; height: 52px; border-radius: var(--radius-lg); flex-shrink: 0;
background: var(--c-primary-subtle);
display: flex; align-items: center; justify-content: center;
}
.wc-feature-icon .ph-icon { width: 26px; height: 26px; color: var(--c-primary); }
.wc-feature-text h2 {
font-size: var(--text-base); font-weight: var(--weight-bold);
color: var(--c-text); margin: 0 0 var(--space-1);
}
.wc-feature-text p {
font-size: var(--text-sm); color: var(--c-text-secondary);
line-height: 1.6; margin: 0;
}
/* Privacy Block */
.wc-privacy {
background: var(--c-primary);
padding: var(--space-8) var(--space-5);
text-align: center;
}
.wc-privacy-icon {
width: 56px; height: 56px; border-radius: 50%;
background: rgba(255,255,255,0.2);
display: flex; align-items: center; justify-content: center;
margin: 0 auto var(--space-4);
}
.wc-privacy-icon .ph-icon { width: 28px; height: 28px; color: #fff; }
.wc-privacy-title {
font-size: var(--text-xl); font-weight: var(--weight-bold);
color: #fff; margin: 0 0 var(--space-3);
}
.wc-privacy-sub {
font-size: var(--text-sm); color: rgba(255,255,255,0.85);
line-height: 1.7; margin: 0; max-width: 360px; margin: 0 auto;
}
/* Und noch mehr */
.wc-more {
padding: var(--space-6) var(--space-4);
background: var(--c-bg);
border-top: 1px solid var(--c-border-light);
}
.wc-more-label {
font-size: var(--text-xs); font-weight: var(--weight-semibold);
color: var(--c-text-secondary); text-transform: uppercase;
letter-spacing: 0.07em; margin: 0 0 var(--space-4); text-align: center;
}
/* Bottom CTA */
.wc-bottom-cta {
padding: var(--space-8) var(--space-5) var(--space-6);
display: flex; flex-direction: column; align-items: center;
gap: var(--space-3); background: var(--c-bg);
border-top: 1px solid var(--c-border-light);
}
.wc-bottom-hint {
font-size: var(--text-xs); color: var(--c-text-muted); margin: 0;
}
.wc-install-link {
background: none; border: none; cursor: pointer;
font-size: var(--text-xs); color: var(--c-text-secondary);
display: flex; align-items: center; gap: 4px;
padding: var(--space-2); margin-top: var(--space-1);
}
.wc-install-link .ph-icon { width: 12px; height: 12px; }
/* ── Logged-in Hero (kompakt) ──────────────────────────── */
.wc-hero {
background: linear-gradient(160deg, var(--c-primary-subtle) 0%, var(--c-bg) 70%);
text-align: center;
padding: var(--space-8) var(--space-4) var(--space-6);
border-bottom: 1px solid var(--c-border-light);
}
.wc-hero-icon {
width: 96px; height: 96px; border-radius: 22px;
box-shadow: 0 8px 28px rgba(0,0,0,0.15);
display: block; margin: 0 auto var(--space-4);
}
.wc-hero-title {
font-size: var(--text-2xl); font-weight: var(--weight-bold);
color: var(--c-text); margin: 0 0 var(--space-2);
}
.wc-hero-sub {
font-size: var(--text-base); color: var(--c-text-secondary);
margin: 0 auto; line-height: 1.6; max-width: 420px;
}
/* ── Shared ────────────────────────────────────────────── */
.wc-section-title {
font-size: var(--text-xs); font-weight: var(--weight-semibold);
color: var(--c-text-secondary); text-transform: uppercase;
letter-spacing: 0.07em; margin: 0 0 var(--space-4); text-align: center;
}
.wc-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: var(--space-3);
margin-bottom: var(--space-4);
}
.wc-tile {
display: flex; flex-direction: column; align-items: center;
gap: var(--space-2); padding: var(--space-4) var(--space-2);
background: var(--c-surface); border: 1px solid var(--c-border-light);
border-radius: var(--radius-lg); cursor: pointer;
transition: background var(--transition-fast), transform 0.1s;
}
.wc-tile:hover { background: var(--c-surface-2); }
.wc-tile:active { transform: scale(0.96); }
.wc-tile--static { cursor: default; }
.wc-tile--static:hover { background: var(--c-surface); }
.wc-tile--static:active { transform: none; }
.wc-tile-icon {
width: 40px; height: 40px; border-radius: var(--radius-md);
background: var(--c-primary-subtle);
display: flex; align-items: center; justify-content: center;
}
.wc-tile-icon .ph-icon { width: 20px; height: 20px; color: var(--c-primary); }
.wc-tile-label {
font-size: var(--text-xs); font-weight: var(--weight-semibold);
color: var(--c-text); text-align: center; line-height: 1.3;
}
.wc-install-card { margin-bottom: var(--space-5); }
.wc-install-header {
display: flex; align-items: center; gap: var(--space-2);
padding: var(--space-3) var(--space-4);
font-size: var(--text-xs); font-weight: 600;
color: var(--c-text-secondary); text-transform: uppercase;
letter-spacing: 0.05em; border-bottom: 1px solid var(--c-border);
}
.wc-install-header .ph-icon { width: 14px; height: 14px; }
.wc-footer {
text-align: center; font-size: var(--text-xs);
color: var(--c-text-muted); padding: var(--space-4);
}
@media (min-width: 640px) {
.wc-lhero-headline { font-size: 3.2rem; }
.wc-lhero-cta { flex-direction: row; justify-content: center; }
.wc-btn-hero { width: auto; }
.wc-grid { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 1024px) {
.wc-lhero { padding: var(--space-8) var(--space-4) var(--space-10); }
.wc-feature { max-width: 680px; margin: 0 auto; }
.wc-grid { grid-template-columns: repeat(8, 1fr); }
}
@keyframes wc-pulse {
0%,100% { transform: scale(1); box-shadow: none; }
50% { transform: scale(1.25); box-shadow: 0 0 0 6px var(--c-primary-subtle); }
}
.wc-pulsing { animation: wc-pulse 0.6s ease-in-out 3; border-radius: var(--radius-md); }
`;
document.head.appendChild(s);
}
// ----------------------------------------------------------
// INSTALLATIONS-ANLEITUNG
// ----------------------------------------------------------
function _installHTML() {
const ua = navigator.userAgent;
const isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;
const isSafari = /^((?!chrome|android).)*safari/i.test(ua);
const isAndroid = /android/i.test(ua);
const hasPrompt = !!App.getInstallPrompt();
if (hasPrompt) {
return `
Kein App Store nötig — direkt auf den Home-Bildschirm.
Ban Yaro installieren
`;
}
if (isIOS && isSafari) {
return `
So kommt Ban Yaro auf deinen Home-Bildschirm:
${_steps([
['share', 'Tippe unten in Safari auf das Teilen-Symbol '],
['rows-plus-top', 'Wähle „Zum Home-Bildschirm" aus der Liste'],
['check', 'Tippe oben rechts auf „Hinzufügen" '],
])}
Funktioniert nur in Safari — nicht in Chrome oder Firefox auf iOS.
`;
}
if (isIOS && !isSafari) {
return `
Auf dem iPhone geht die Installation nur über Safari .
${_steps([
['safari-logo', 'Öffne Safari auf deinem iPhone'],
['arrow-square-in','Gib banyaro.app in die Adressleiste ein'],
['share', 'Tippe auf das Teilen-Symbol und wähle „Zum Home-Bildschirm" '],
])}
Link kopieren
`;
}
if (isAndroid) {
return `
Am einfachsten geht es mit Chrome :
${_steps([
['arrow-square-in', 'Öffne banyaro.app in Chrome'],
['dots-three-circle','Tippe auf das Menü ⋮ oben rechts'],
['download-simple', 'Wähle „App installieren" oder „Zum Startbildschirm hinzufügen"'],
])}
Link kopieren
`;
}
return `
Android
iPhone / iPad
${_steps([
['arrow-square-in', 'Öffne banyaro.app in Chrome oder Edge'],
['monitor', 'Klicke auf das Installations-Symbol in der Adressleiste'],
['check', 'Bestätigen — fertig!'],
])}
${_steps([
['arrow-square-in', 'Öffne banyaro.app in Safari auf dem iPhone'],
['share', 'Tippe auf das Teilen-Symbol '],
['rows-plus-top', 'Wähle „Zum Home-Bildschirm" → „Hinzufügen" '],
])}
`;
}
function _steps(list) {
return `
${list.map(([icon, text]) => `
${text}
`).join('')}
`;
}
// ----------------------------------------------------------
// EVENTS
// ----------------------------------------------------------
function _bindEvents() {
// Install-Prompt Buttons
const installBtn = async () => {
const prompt = App.getInstallPrompt();
if (!prompt) return;
prompt.prompt();
const { outcome } = await prompt.userChoice;
if (outcome === 'accepted') { UI.toast.success('Ban Yaro wird installiert!'); _render(); }
};
_container.querySelector('#install-android-btn')?.addEventListener('click', installBtn);
_container.querySelector('#welcome-install-hero-btn')?.addEventListener('click', installBtn);
_container.querySelector('#welcome-install-hero-btn2')?.addEventListener('click', installBtn);
// Register / Login
const toSettings = () => App.navigate('settings');
_container.querySelector('#welcome-register-btn')?.addEventListener('click', toSettings);
_container.querySelector('#welcome-register-btn2')?.addEventListener('click', toSettings);
_container.querySelector('#welcome-login-btn')?.addEventListener('click', toSettings);
// Installationsanleitung Link
_container.querySelector('#welcome-install-link')?.addEventListener('click', () => {
App.navigate('welcome', true, { install: true });
});
// Link kopieren
_container.querySelector('#install-copy-btn')?.addEventListener('click', async () => {
await navigator.clipboard.writeText('https://banyaro.app');
UI.toast.success('Link kopiert!');
});
// Desktop-Tabs Android / iOS
_container.querySelector('#inst-tab-android')?.addEventListener('click', () => {
_container.querySelector('#inst-panel-android').style.display = '';
_container.querySelector('#inst-panel-ios').style.display = 'none';
_container.querySelector('#inst-tab-android').style.cssText += ';background:var(--c-primary);color:#fff;border:none';
_container.querySelector('#inst-tab-ios').className = 'btn btn-sm btn-ghost';
_container.querySelector('#inst-tab-ios').style.cssText = 'flex:1';
});
_container.querySelector('#inst-tab-ios')?.addEventListener('click', () => {
_container.querySelector('#inst-panel-android').style.display = 'none';
_container.querySelector('#inst-panel-ios').style.display = '';
_container.querySelector('#inst-tab-ios').style.cssText += ';background:var(--c-primary);color:#fff;border:none';
_container.querySelector('#inst-tab-android').className = 'btn btn-sm btn-ghost';
_container.querySelector('#inst-tab-android').style.cssText = 'flex:1';
});
// Feature-Tiles (nur eingeloggte Ansicht)
_container.querySelectorAll('[data-nav]').forEach(btn => {
btn.addEventListener('click', () => App.navigate(btn.dataset.nav));
});
}
function _pulseMenuBtn() {
const btn = document.getElementById('header-menu-btn');
if (!btn) return;
setTimeout(() => {
btn.classList.add('wc-pulsing');
btn.addEventListener('animationend', () => btn.classList.remove('wc-pulsing'), { once: true });
}, 1200);
}
return { init, refresh, onDogChange };
})();