feat: Streak-Reminder – In-App-Nudge + lokale Tages-Erinnerung

- streak.js: Zustand aus last_practice_at (safe/at_risk/broken/none)
- Feed: Loss-Aversion-Bar "X-Tage-Serie – nur noch Y Std heute!" wenn die Serie heute abläuft
- Profil-Streak-Zeile zeigt Status (heute gesichert ✓ / noch X Std)
- Lokale Tages-Erinnerung via @capacitor/local-notifications (kein APNs nötig),
  geplant bei Login, abgebrochen sobald heute geübt – nativ; web no-op

Hinweis: nativ erst nach 'npx cap sync ios' + Rebuild aktiv.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 22:14:26 +02:00
parent 98543979db
commit 14fb0dcbe9
9 changed files with 140 additions and 5 deletions

View File

@@ -1,4 +1,4 @@
import { useState } from 'react'
import { useState, useEffect } from 'react'
import { AuthProvider, useAuth } from './context/AuthContext'
import AuthScreen from './components/auth/AuthScreen'
import BottomNav from './BottomNav'
@@ -6,6 +6,7 @@ import Feed from './pages/Feed'
import Game from './pages/Game'
import Pro from './pages/Pro'
import Profil from './pages/Profil'
import { scheduleStreakReminder } from './utils/streakReminder'
const PAGES = { feed: Feed, game: Game, pro: Pro, profil: Profil }
@@ -13,6 +14,11 @@ function AppContent() {
const { user, loading } = useAuth()
const [page, setPage] = useState('feed')
// Lokale Tages-Erinnerung planen, sobald ein eingeloggter Nutzer da ist (nativ; web no-op).
useEffect(() => {
if (user?.username) scheduleStreakReminder(user.streak_days || 0)
}, [user?.username, user?.streak_days])
if (loading) {
return (
<div style={{ height: '100%', overflow: 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg)' }}>