feat: onboarding flow (6 screens) + audio engine + design system
Onboarding: - 6-screen flow: Problem → Empathy → Solution → Wow → Personalization → Paywall - useOnboarding hook with Zustand + AsyncStorage persistence - MiniTimerDemo with live 20s timer + haptics - Auto-redirect for first-time users - Mock RevenueCat for dev testing Audio: - useAudioEngine hook with expo-av - Phase sounds (count_3/2/1, beep, bell, fanfare) - Placeholder music tracks Design System: - Typography component + constants - GlassView component - Spacing, shadows, animations, borderRadius constants - Extended color palette (phase gradients, glass, surfaces) Timer: - Fix: handle 0-duration phases (immediate advance) - Enhanced TimerDisplay with phase gradients Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
49
app/onboarding/index.tsx
Normal file
49
app/onboarding/index.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import { useRouter, Redirect } from 'expo-router'
|
||||
import { Screen1Problem } from '@/src/features/onboarding/screens/Screen1Problem'
|
||||
import { Screen2Empathy } from '@/src/features/onboarding/screens/Screen2Empathy'
|
||||
import { Screen3Solution } from '@/src/features/onboarding/screens/Screen3Solution'
|
||||
import { Screen4WowMoment } from '@/src/features/onboarding/screens/Screen4WowMoment'
|
||||
import { Screen5Personalization } from '@/src/features/onboarding/screens/Screen5Personalization'
|
||||
import { Screen6Paywall } from '@/src/features/onboarding/screens/Screen6Paywall'
|
||||
import { useOnboarding } from '@/src/features/onboarding/hooks/useOnboarding'
|
||||
|
||||
export default function OnboardingRouter() {
|
||||
const router = useRouter()
|
||||
const currentStep = useOnboarding((state) => state.currentStep)
|
||||
const isOnboardingComplete = useOnboarding((state) => state.isOnboardingComplete)
|
||||
const nextStep = useOnboarding((state) => state.nextStep)
|
||||
const completeOnboarding = useOnboarding((state) => state.completeOnboarding)
|
||||
|
||||
const handleNext = () => {
|
||||
nextStep()
|
||||
}
|
||||
|
||||
const handleComplete = () => {
|
||||
completeOnboarding()
|
||||
router.replace('/(tabs)')
|
||||
}
|
||||
|
||||
// Redirect to tabs if onboarding is already complete
|
||||
if (isOnboardingComplete) {
|
||||
return <Redirect href="/(tabs)" />
|
||||
}
|
||||
|
||||
// Render the correct screen based on current step
|
||||
switch (currentStep) {
|
||||
case 0:
|
||||
return <Screen1Problem onNext={handleNext} />
|
||||
case 1:
|
||||
return <Screen2Empathy onNext={handleNext} />
|
||||
case 2:
|
||||
return <Screen3Solution onNext={handleNext} />
|
||||
case 3:
|
||||
return <Screen4WowMoment />
|
||||
case 4:
|
||||
return <Screen5Personalization onNext={handleNext} />
|
||||
case 5:
|
||||
return <Screen6Paywall onComplete={handleComplete} />
|
||||
default:
|
||||
// Fallback to first screen if step is out of bounds
|
||||
return <Screen1Problem onNext={handleNext} />
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user