- 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>
53 lines
1.6 KiB
JavaScript
53 lines
1.6 KiB
JavaScript
import { useState, useEffect } from 'react'
|
|
import { AuthProvider, useAuth } from './context/AuthContext'
|
|
import AuthScreen from './components/auth/AuthScreen'
|
|
import BottomNav from './BottomNav'
|
|
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 }
|
|
|
|
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)' }}>
|
|
<div className="app-spinner" />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (!user || !user.username || !user.language_native_id || !user.language_target_id) {
|
|
return <AuthScreen />
|
|
}
|
|
|
|
const PageComponent = PAGES[page] || Feed
|
|
|
|
return (
|
|
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', background: 'var(--bg)', overflow: 'hidden' }}>
|
|
<div key={page} className="page-enter" style={{ flex: 1, overflow: 'hidden', minHeight: 0 }}>
|
|
<PageComponent />
|
|
</div>
|
|
<BottomNav active={page} onNavigate={setPage} />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default function App() {
|
|
return (
|
|
<AuthProvider>
|
|
<AppContent />
|
|
</AuthProvider>
|
|
)
|
|
}
|