diff --git a/backend/main.py b/backend/main.py index 1f8dd9c..c1aee66 100644 --- a/backend/main.py +++ b/backend/main.py @@ -406,7 +406,7 @@ async def serve_media(path: str, request: _Request): raise _HE(404, "Nicht gefunden.") return _media_response(filepath) -APP_VER = "951" # muss mit APP_VER in app.js übereinstimmen +APP_VER = "948" # muss mit APP_VER in app.js übereinstimmen @app.get("/.well-known/assetlinks.json") async def assetlinks(): diff --git a/backend/routes/auth.py b/backend/routes/auth.py index 895c94c..59ad6e8 100644 --- a/backend/routes/auth.py +++ b/backend/routes/auth.py @@ -418,36 +418,20 @@ async def cancel_subscription(user=Depends(get_current_user)): try: from mailer import send_email, email_html import html as _html - tier_label = {"pro": "Ban Yaro Pro", "breeder": "Züchter"}.get(row["subscription_tier"], row["subscription_tier"]) - expires_de = None - if expires: - from datetime import date as _date - try: - d = _date.fromisoformat(expires[:10]) - monate = ["Januar","Februar","März","April","Mai","Juni", - "Juli","August","September","Oktober","November","Dezember"] - expires_de = f"{d.day}. {monate[d.month-1]} {d.year}" - except Exception: - expires_de = expires[:10] - - expiry_line = ( - f"

Dein Abo ist weiterhin aktiv bis zum {expires_de}. " - f"Ab diesem Datum wirst du automatisch auf den kostenlosen Tarif gesetzt.

" - if expires_de else - "

Dein Abo bleibt bis zum Ende des bezahlten Zeitraums aktiv.

" - ) + tier_label = {"pro": "Ban Yaro Pro", "breeder": "Züchter"}.get(row["subscription_tier"], row["subscription_tier"]) + expires_fmt = expires[:10] if expires else "—" body_html = f"""

Hallo {_html.escape(user['name'])},

deine Kündigung für {tier_label} wurde bestätigt.

- {expiry_line} +

Dein Abo ist weiterhin aktiv bis zum {expires_fmt}. + Ab diesem Datum wirst du automatisch auf den kostenlosen Tarif gesetzt.

Deine Daten (Tagebuch, Gesundheit, Notizen) bleiben vollständig erhalten. Wenn du mehrere Hunde hast, kannst du vor dem Ablauf einen als Haupthund festlegen.

Wir hoffen, dich bald wieder begrüßen zu dürfen!

Viele Grüße
René & das Ban Yaro Team

""" html = email_html(body_html, cta_url="https://banyaro.app", cta_label="Ban Yaro öffnen") plain = (f"Hallo {user['name']},\n\nKündigung bestätigt für {tier_label}.\n" - + (f"Aktiv bis: {expires_de}\n" if expires_de else "") - + "\nAlle Daten bleiben erhalten.\n\nViele Grüße\nRené") + f"Aktiv bis: {expires_fmt}\n\nAlle Daten bleiben erhalten.\n\nViele Grüße\nRené") await send_email(user["email"], f"Kündigung bestätigt — {tier_label}", html, plain) except Exception: pass diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 2282add..a2302f4 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '951'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '948'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.5.1'; // ← semantische Version, wird bei make release gesetzt const IS_STAGING = location.hostname === 'staging.banyaro.app'; // Cache-Bust-Parameter nach Update-Reload sofort entfernen diff --git a/backend/static/js/pages/settings.js b/backend/static/js/pages/settings.js index 2d23a96..89e527b 100644 --- a/backend/static/js/pages/settings.js +++ b/backend/static/js/pages/settings.js @@ -110,13 +110,7 @@ window.Page_settings = (() => { const isPaid = (isPro || isBreeder) && !tier.endsWith('_test') && !isAdmin; const _expiryInfo = () => { - if (!isPaid) return ''; - if (cancelled && !expiresDate) { - return `
- Gekündigt — läuft bis Ablauf des bezahlten Zeitraums -
`; - } - if (!expiresDate) return ''; + if (!isPaid || !expiresDate) return ''; const color = cancelled ? '#e65100' : 'var(--c-text-secondary)'; const text = cancelled ? `Gekündigt — läuft bis ${expiresDate}` @@ -428,17 +422,7 @@ window.Page_settings = (() => { const fresh = await API.auth.me(); Object.assign(_appState.user, fresh); UI.modal.close(); - const tier = fresh.subscription_tier || ''; - const label = { pro: 'Pro', breeder: 'Züchter' }[tier] || tier; - const exp = fresh.subscription_expires_at; - const expFmt = exp - ? new Date(exp).toLocaleDateString('de-DE', {day:'numeric',month:'long',year:'numeric'}) - : null; - UI.toast.success( - expFmt - ? `Kündigung bestätigt — ${label} läuft noch bis ${expFmt}.` - : 'Kündigung bestätigt. Eine Bestätigungsmail wurde gesendet.' - ); + UI.toast.success('Kündigung bestätigt. Eine Bestätigungsmail wurde gesendet.'); _render(); } catch (e) { btn.disabled = false; @@ -1314,10 +1298,10 @@ window.Page_settings = (() => { document.getElementById('settings-delete-account-btn')?.addEventListener('click', async () => { const ok = await UI.modal.confirm({ - title: 'Konto unwiderruflich löschen?', - message: 'Alle deine Daten (Tagebuch, Gesundheit, Training, Fotos) werden dauerhaft gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.', + title: 'Konto unwiderruflich löschen?', + body: 'Alle deine Daten (Tagebuch, Gesundheit, Training, Fotos) werden dauerhaft gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.', confirmText: 'Ja, Konto löschen', - danger: true, + danger: true, }); if (!ok) return; try { diff --git a/backend/static/sw.js b/backend/static/sw.js index 5be5d42..0242bac 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -3,7 +3,7 @@ Offline-Cache + Push Notifications + Tile-Cache ============================================================ */ -const CACHE_VERSION = 'by-v951'; +const CACHE_VERSION = 'by-v948'; 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