UX: Welcome-Seite — Anmelde-Einstieg vereinfacht, Install-Block prominent mit PWA-Erklärung (SW by-v755)
This commit is contained in:
parent
b31116abf6
commit
e5e95efaed
6 changed files with 90 additions and 88 deletions
|
|
@ -327,7 +327,7 @@ MEDIA_DIR = os.getenv("MEDIA_DIR", "/data/media")
|
||||||
os.makedirs(MEDIA_DIR, exist_ok=True)
|
os.makedirs(MEDIA_DIR, exist_ok=True)
|
||||||
app.mount("/media", StaticFiles(directory=MEDIA_DIR), name="media")
|
app.mount("/media", StaticFiles(directory=MEDIA_DIR), name="media")
|
||||||
|
|
||||||
APP_VER = "754" # muss mit APP_VER in app.js übereinstimmen
|
APP_VER = "755" # muss mit APP_VER in app.js übereinstimmen
|
||||||
|
|
||||||
@app.get("/api/version")
|
@app.get("/api/version")
|
||||||
async def app_version():
|
async def app_version():
|
||||||
|
|
|
||||||
|
|
@ -578,7 +578,7 @@
|
||||||
<script src="/js/api.js?v=94"></script>
|
<script src="/js/api.js?v=94"></script>
|
||||||
<script src="/js/ui.js?v=94"></script>
|
<script src="/js/ui.js?v=94"></script>
|
||||||
<script src="/js/app.js?v=94"></script>
|
<script src="/js/app.js?v=94"></script>
|
||||||
<script src="/js/worlds.js?v=754"></script>
|
<script src="/js/worlds.js?v=755"></script>
|
||||||
|
|
||||||
<!-- Feature-Seiten werden lazy geladen -->
|
<!-- Feature-Seiten werden lazy geladen -->
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
Router, State-Management, Navigation, Initialisierung.
|
Router, State-Management, Navigation, Initialisierung.
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
|
||||||
const APP_VER = '754'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
const APP_VER = '755'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||||
const APP_VERSION = '1.5.0'; // ← semantische Version, wird bei make release gesetzt
|
const APP_VERSION = '1.5.0'; // ← semantische Version, wird bei make release gesetzt
|
||||||
const IS_STAGING = location.hostname === 'staging.banyaro.app';
|
const IS_STAGING = location.hostname === 'staging.banyaro.app';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,12 @@ window.Page_settings = (() => {
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
// INIT / REFRESH
|
// INIT / REFRESH
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
async function init(container, appState) {
|
async function init(container, appState, params = {}) {
|
||||||
_container = container;
|
_container = container;
|
||||||
_appState = appState;
|
_appState = appState;
|
||||||
_render();
|
_render();
|
||||||
|
if (params.tab === 'login') setTimeout(() => _renderAuth('login'), 50);
|
||||||
|
if (params.tab === 'register') setTimeout(() => _renderAuth('register'), 50);
|
||||||
// Frischen User-State laden damit Badges (is_founder, is_partner) aktuell sind
|
// Frischen User-State laden damit Badges (is_founder, is_partner) aktuell sind
|
||||||
if (_appState.user) {
|
if (_appState.user) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,6 @@ window.Page_welcome = (() => {
|
||||||
// LANDING PAGE — nicht eingeloggte Besucher
|
// LANDING PAGE — nicht eingeloggte Besucher
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
function _renderLanding(isInstalled) {
|
function _renderLanding(isInstalled) {
|
||||||
// Browser-Besucher (kein PWA) ohne Login → auf /info weiterleiten
|
|
||||||
const isPWA = window.matchMedia('(display-mode: standalone)').matches
|
const isPWA = window.matchMedia('(display-mode: standalone)').matches
|
||||||
|| window.navigator.standalone === true;
|
|| window.navigator.standalone === true;
|
||||||
if (!isPWA && !sessionStorage.getItem('by_stay_in_app')) {
|
if (!isPWA && !sessionStorage.getItem('by_stay_in_app')) {
|
||||||
|
|
@ -113,17 +112,10 @@ window.Page_welcome = (() => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="wc-lhero-cta">
|
<div class="wc-lhero-cta">
|
||||||
${hasPrompt ? `
|
<button class="btn wc-btn-hero" id="welcome-register-btn">
|
||||||
<button class="btn wc-btn-hero" id="welcome-install-hero-btn">
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#paw-print"></use></svg>
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#download-simple"></use></svg>
|
Kostenlos registrieren
|
||||||
Zum Home-Bildschirm hinzufügen
|
</button>
|
||||||
</button>
|
|
||||||
` : `
|
|
||||||
<button class="btn wc-btn-hero" id="welcome-register-btn">
|
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#paw-print"></use></svg>
|
|
||||||
Kostenlos loslegen
|
|
||||||
</button>
|
|
||||||
`}
|
|
||||||
<button class="btn wc-btn-login" id="welcome-login-btn">
|
<button class="btn wc-btn-login" id="welcome-login-btn">
|
||||||
Schon dabei? Anmelden
|
Schon dabei? Anmelden
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -145,7 +137,33 @@ window.Page_welcome = (() => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Feature 1: Tagebuch ───────────────────────────── -->
|
<!-- ── Install-Block ─────────────────────────────────── -->
|
||||||
|
${!isInstalled ? `
|
||||||
|
<div class="wc-install-block">
|
||||||
|
<div class="wc-install-block-header">
|
||||||
|
<div class="wc-install-block-icon">
|
||||||
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#device-mobile"></use></svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="wc-install-block-title">Kein App Store nötig</div>
|
||||||
|
<div class="wc-install-block-sub">Füge Ban Yaro zum Home-Bildschirm hinzu — einmal, dann immer griffbereit</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="wc-install-block-why">
|
||||||
|
Ban Yaro ist eine Web-App (PWA). Das bedeutet: kein App-Store-Download, automatische Updates ohne dein Zutun, und sie verhält sich genau wie eine native App — mit Icon, Vollbild und Offline-Modus.
|
||||||
|
</p>
|
||||||
|
${hasPrompt ? `
|
||||||
|
<button class="btn btn-primary wc-install-block-btn" id="welcome-install-hero-btn">
|
||||||
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#download-simple"></use></svg>
|
||||||
|
Jetzt zum Home-Bildschirm hinzufügen
|
||||||
|
</button>
|
||||||
|
` : `
|
||||||
|
<div class="wc-install-block-steps">${_installHTML()}</div>
|
||||||
|
`}
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
|
||||||
|
<!-- ── Features ──────────────────────────────────────── -->
|
||||||
<div class="wc-feature wc-feature--a">
|
<div class="wc-feature wc-feature--a">
|
||||||
<div class="wc-feature-icon">
|
<div class="wc-feature-icon">
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#book-open"></use></svg>
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#book-open"></use></svg>
|
||||||
|
|
@ -155,8 +173,6 @@ window.Page_welcome = (() => {
|
||||||
<p>Halte jeden gemeinsamen Moment fest — Fotos, Einträge, Stimmungen. Nur für dich, privat und sicher.</p>
|
<p>Halte jeden gemeinsamen Moment fest — Fotos, Einträge, Stimmungen. Nur für dich, privat und sicher.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Feature 2: Gesundheit ─────────────────────────── -->
|
|
||||||
<div class="wc-feature wc-feature--b">
|
<div class="wc-feature wc-feature--b">
|
||||||
<div class="wc-feature-icon">
|
<div class="wc-feature-icon">
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#first-aid"></use></svg>
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#first-aid"></use></svg>
|
||||||
|
|
@ -166,26 +182,22 @@ window.Page_welcome = (() => {
|
||||||
<p>Impfungen, Gewicht, Tierarzttermine — alles an einem Ort. Du siehst immer, wann was ansteht.</p>
|
<p>Impfungen, Gewicht, Tierarzttermine — alles an einem Ort. Du siehst immer, wann was ansteht.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Feature 3: Community ──────────────────────────── -->
|
|
||||||
<div class="wc-feature wc-feature--c">
|
<div class="wc-feature wc-feature--c">
|
||||||
<div class="wc-feature-icon">
|
<div class="wc-feature-icon">
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#map-trifold"></use></svg>
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#map-trifold"></use></svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="wc-feature-text">
|
<div class="wc-feature-text">
|
||||||
<h2>Community vor Ort</h2>
|
<h2>Community vor Ort</h2>
|
||||||
<p>Giftköder-Warnungen, Gassi-Treffen, Events — was in deiner Gegend gerade passiert.</p>
|
<p>Giftköder-Warnungen, Forum, Events — was in deiner Gegend gerade passiert.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Feature 4: Training ──────────────────────────── -->
|
|
||||||
<div class="wc-feature wc-feature--d">
|
<div class="wc-feature wc-feature--d">
|
||||||
<div class="wc-feature-icon">
|
<div class="wc-feature-icon">
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#target"></use></svg>
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#target"></use></svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="wc-feature-text">
|
<div class="wc-feature-text">
|
||||||
<h2>Training & KI-Trainer</h2>
|
<h2>Training & Übungen</h2>
|
||||||
<p>Über 100 Übungen mit Schritt-für-Schritt-Anleitungen. Mit KI-Unterstützung, die deinen Hund kennt.</p>
|
<p>Über 100 Übungen mit Schritt-für-Schritt-Anleitungen. Fortschritt tracken, Streaks aufbauen.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -198,65 +210,21 @@ window.Page_welcome = (() => {
|
||||||
<p class="wc-privacy-sub">
|
<p class="wc-privacy-sub">
|
||||||
Kein Facebook. Kein Google. Keine Werbung.<br>
|
Kein Facebook. Kein Google. Keine Werbung.<br>
|
||||||
Ban Yaro läuft auf einem eigenen Server in Deutschland —
|
Ban Yaro läuft auf einem eigenen Server in Deutschland —
|
||||||
dein Tagebuch, deine Routen, deine Gesundheitsdaten
|
dein Tagebuch, deine Routen, deine Gesundheitsdaten bleiben privat.
|
||||||
bleiben privat.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Und noch mehr (einklappbar) ─────────────────────── -->
|
|
||||||
<div class="wc-more">
|
|
||||||
<button class="wc-more-toggle" id="wc-more-toggle" aria-expanded="false">
|
|
||||||
<span>Und noch viel mehr</span>
|
|
||||||
<svg class="ph-icon wc-more-chevron" aria-hidden="true"><use href="/icons/phosphor.svg#caret-down"></use></svg>
|
|
||||||
</button>
|
|
||||||
<div class="wc-grid wc-grid--collapsed" id="wc-more-grid">
|
|
||||||
${FEATURES.map(f => `
|
|
||||||
<div class="wc-tile wc-tile--static">
|
|
||||||
<div class="wc-tile-icon">
|
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#${f.icon}"></use></svg>
|
|
||||||
</div>
|
|
||||||
<span class="wc-tile-label">${f.label}</span>
|
|
||||||
</div>
|
|
||||||
`).join('')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ── Bottom CTA ────────────────────────────────────── -->
|
<!-- ── Bottom CTA ────────────────────────────────────── -->
|
||||||
<div class="wc-bottom-cta">
|
<div class="wc-bottom-cta">
|
||||||
${hasPrompt ? `
|
<button class="btn wc-btn-hero" id="welcome-register-btn2">
|
||||||
<button class="btn wc-btn-hero" id="welcome-install-hero-btn2">
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#paw-print"></use></svg>
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#download-simple"></use></svg>
|
Jetzt kostenlos starten
|
||||||
Zum Home-Bildschirm hinzufügen
|
</button>
|
||||||
</button>
|
<button class="btn wc-btn-login" id="welcome-login-btn2" style="max-width:320px;width:100%">
|
||||||
` : `
|
Schon dabei? Anmelden
|
||||||
<button class="btn wc-btn-hero" id="welcome-register-btn2">
|
</button>
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#paw-print"></use></svg>
|
|
||||||
Jetzt kostenlos starten
|
|
||||||
</button>
|
|
||||||
`}
|
|
||||||
<p class="wc-bottom-hint">Kein App Store · Direkt auf den Home-Bildschirm</p>
|
|
||||||
|
|
||||||
${!isInstalled ? `
|
|
||||||
<button class="wc-install-link" id="welcome-install-link">
|
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#download-simple"></use></svg>
|
|
||||||
Zum Home-Bildschirm hinzufügen
|
|
||||||
</button>
|
|
||||||
` : ''}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Install Card (via Einstellungen) ──────────────── -->
|
|
||||||
${_showInstall ? `
|
|
||||||
<div class="page-container" style="padding:0 var(--space-4) var(--space-6)">
|
|
||||||
<div class="card wc-install-card">
|
|
||||||
<div class="wc-install-header">
|
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#download-simple"></use></svg>
|
|
||||||
Immer griffbereit — kein App Store
|
|
||||||
</div>
|
|
||||||
<div style="padding:var(--space-4)">${_installHTML()}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
|
|
||||||
<p class="wc-footer">Ban Yaro · Deine Daten auf eigenem Server in Deutschland</p>
|
<p class="wc-footer">Ban Yaro · Deine Daten auf eigenem Server in Deutschland</p>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
@ -811,6 +779,43 @@ window.Page_welcome = (() => {
|
||||||
}
|
}
|
||||||
.wc-grid.wc-grid--collapsed { display: none; }
|
.wc-grid.wc-grid--collapsed { display: none; }
|
||||||
|
|
||||||
|
/* Install Block */
|
||||||
|
.wc-install-block {
|
||||||
|
background: var(--c-bg-card);
|
||||||
|
border-top: 3px solid var(--c-primary);
|
||||||
|
padding: var(--space-5) var(--space-5) var(--space-6);
|
||||||
|
}
|
||||||
|
.wc-install-block-header {
|
||||||
|
display: flex; align-items: flex-start; gap: var(--space-3);
|
||||||
|
margin-bottom: var(--space-3);
|
||||||
|
}
|
||||||
|
.wc-install-block-icon {
|
||||||
|
width: 44px; height: 44px; border-radius: var(--radius-md);
|
||||||
|
background: var(--c-primary-subtle); flex-shrink: 0;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
}
|
||||||
|
.wc-install-block-icon .ph-icon { width: 22px; height: 22px; color: var(--c-primary); }
|
||||||
|
.wc-install-block-title {
|
||||||
|
font-size: var(--text-base); font-weight: var(--weight-bold);
|
||||||
|
color: var(--c-text); margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
.wc-install-block-sub {
|
||||||
|
font-size: var(--text-sm); color: var(--c-text-secondary); line-height: 1.4;
|
||||||
|
}
|
||||||
|
.wc-install-block-why {
|
||||||
|
font-size: var(--text-sm); color: var(--c-text-secondary);
|
||||||
|
line-height: 1.6; margin: 0 0 var(--space-4);
|
||||||
|
padding: var(--space-3) var(--space-4);
|
||||||
|
background: var(--c-surface); border-radius: var(--radius-md);
|
||||||
|
border-left: 3px solid var(--c-primary);
|
||||||
|
}
|
||||||
|
.wc-install-block-btn {
|
||||||
|
width: 100%; font-size: var(--text-base);
|
||||||
|
padding: 14px; border-radius: var(--radius-lg);
|
||||||
|
display: flex; align-items: center; justify-content: center; gap: var(--space-2);
|
||||||
|
}
|
||||||
|
.wc-install-block-steps { margin-top: var(--space-2); }
|
||||||
|
|
||||||
/* Bottom CTA */
|
/* Bottom CTA */
|
||||||
.wc-bottom-cta {
|
.wc-bottom-cta {
|
||||||
padding: var(--space-8) var(--space-5) var(--space-6);
|
padding: var(--space-8) var(--space-5) var(--space-6);
|
||||||
|
|
@ -1194,15 +1199,10 @@ window.Page_welcome = (() => {
|
||||||
_container.querySelector('#welcome-install-hero-btn2')?.addEventListener('click', installBtn);
|
_container.querySelector('#welcome-install-hero-btn2')?.addEventListener('click', installBtn);
|
||||||
|
|
||||||
// Register / Login
|
// Register / Login
|
||||||
const toSettings = () => App.navigate('settings');
|
_container.querySelector('#welcome-register-btn')?.addEventListener('click', () => App.navigate('settings', true, { tab: 'register' }));
|
||||||
_container.querySelector('#welcome-register-btn')?.addEventListener('click', toSettings);
|
_container.querySelector('#welcome-register-btn2')?.addEventListener('click', () => App.navigate('settings', true, { tab: 'register' }));
|
||||||
_container.querySelector('#welcome-register-btn2')?.addEventListener('click', toSettings);
|
_container.querySelector('#welcome-login-btn')?.addEventListener('click', () => App.navigate('settings', true, { tab: 'login' }));
|
||||||
_container.querySelector('#welcome-login-btn')?.addEventListener('click', toSettings);
|
_container.querySelector('#welcome-login-btn2')?.addEventListener('click', () => App.navigate('settings', true, { tab: 'login' }));
|
||||||
|
|
||||||
// Installationsanleitung Link
|
|
||||||
_container.querySelector('#welcome-install-link')?.addEventListener('click', () => {
|
|
||||||
App.navigate('welcome', true, { install: true });
|
|
||||||
});
|
|
||||||
|
|
||||||
// Link kopieren
|
// Link kopieren
|
||||||
_container.querySelector('#install-copy-btn')?.addEventListener('click', async () => {
|
_container.querySelector('#install-copy-btn')?.addEventListener('click', async () => {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
Offline-Cache + Push Notifications + Tile-Cache
|
Offline-Cache + Push Notifications + Tile-Cache
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
|
||||||
const CACHE_VERSION = 'by-v754';
|
const CACHE_VERSION = 'by-v755';
|
||||||
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
||||||
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
||||||
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache
|
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue