onboarding.tsx
1 import React from 'react'; 2 import { 3 View, 4 Text, 5 TouchableOpacity, 6 StyleSheet, 7 SafeAreaView, 8 ScrollView, 9 useColorScheme, 10 Alert, 11 Image, 12 } from 'react-native'; 13 import { useTheme, Theme } from '@/constants/ThemeContext'; 14 import { Ionicons } from '@expo/vector-icons'; 15 import { Colors } from '@/constants/Colors'; 16 import { setOnboardingCompleted } from '@/services/settingsService'; 17 import { useRouter } from 'expo-router'; 18 19 export default function OnboardingScreen() { 20 const router = useRouter(); 21 const { theme, setTheme } = useTheme(); 22 const systemColorScheme = useColorScheme(); 23 const colorScheme = theme === 'system' ? systemColorScheme : theme; 24 const colors = Colors[colorScheme as keyof typeof Colors] || Colors.light; 25 const styles = getStyles(colors); 26 27 const themeOptions: { label: string; value: Theme; icon: string }[] = [ 28 { label: 'Light', value: 'light', icon: 'sunny-outline' }, 29 { label: 'Dark', value: 'dark', icon: 'moon-outline' }, 30 { label: 'System', value: 'system', icon: 'phone-portrait-outline' }, 31 ]; 32 33 const completeOnboarding = async () => { 34 try { 35 await setOnboardingCompleted(true); 36 // Navigate to the main app screen 37 router.replace('/'); 38 } catch (error) { 39 console.error('Error completing onboarding:', error); 40 Alert.alert('Error', 'An error occurred while completing onboarding.'); 41 } 42 }; 43 44 return ( 45 <SafeAreaView style={styles.container}> 46 <ScrollView contentContainerStyle={styles.contentContainer}> 47 {/* Reworked Look */} 48 <View style={styles.logoContainer}> 49 <Image 50 source={require('@/assets/images/nessie.png')} 51 style={styles.logo} 52 resizeMode="contain" 53 /> 54 </View> 55 56 <Text style={styles.title}>Welcome to MangaNess</Text> 57 58 <Text style={styles.description}> 59 Explore the world of manga at your fingertips. 60 </Text> 61 62 <View style={styles.section}> 63 <Text style={styles.sectionTitle}>Choose Your Theme</Text> 64 {themeOptions.map((option) => ( 65 <TouchableOpacity 66 key={option.value} 67 style={[ 68 styles.option, 69 theme === option.value && styles.activeOption, 70 ]} 71 onPress={() => setTheme(option.value)} 72 > 73 <Ionicons 74 name={option.icon as any} 75 size={24} 76 color={theme === option.value ? colors.primary : colors.text} 77 /> 78 <Text 79 style={[ 80 styles.optionText, 81 theme === option.value && styles.activeOptionText, 82 ]} 83 > 84 {option.label} 85 </Text> 86 {theme === option.value && ( 87 <Ionicons name="checkmark" size={24} color={colors.primary} /> 88 )} 89 </TouchableOpacity> 90 ))} 91 </View> 92 <TouchableOpacity 93 style={styles.completeButton} 94 onPress={completeOnboarding} 95 > 96 <Text style={styles.completeButtonText}>Get Started</Text> 97 </TouchableOpacity> 98 </ScrollView> 99 </SafeAreaView> 100 ); 101 } 102 103 const getStyles = (colors: typeof Colors.light) => 104 StyleSheet.create({ 105 container: { 106 flex: 1, 107 backgroundColor: colors.card, 108 }, 109 contentContainer: { 110 flexGrow: 1, 111 paddingHorizontal: 20, 112 justifyContent: 'center', 113 paddingVertical: 40, 114 }, 115 logoContainer: { 116 alignItems: 'center', 117 marginBottom: 30, 118 }, 119 logo: { 120 width: 120, 121 height: 120, 122 }, 123 title: { 124 fontSize: 32, 125 fontWeight: 'bold', 126 color: colors.text, 127 textAlign: 'center', 128 marginBottom: 10, 129 }, 130 description: { 131 fontSize: 16, 132 color: colors.text, 133 textAlign: 'center', 134 marginBottom: 30, 135 }, 136 section: { 137 marginBottom: 20, 138 }, 139 sectionTitle: { 140 fontSize: 20, 141 fontWeight: '600', 142 marginBottom: 10, 143 color: colors.text, 144 }, 145 option: { 146 flexDirection: 'row', 147 alignItems: 'center', 148 paddingVertical: 15, 149 paddingHorizontal: 10, 150 borderWidth: 1, 151 borderColor: colors.border, 152 borderRadius: 8, 153 marginBottom: 10, 154 }, 155 activeOption: { 156 backgroundColor: colors.primary + '20', 157 borderColor: colors.primary, 158 }, 159 optionText: { 160 fontSize: 16, 161 marginLeft: 15, 162 flex: 1, 163 color: colors.text, 164 }, 165 activeOptionText: { 166 color: colors.primary, 167 fontWeight: '600', 168 }, 169 completeButton: { 170 backgroundColor: colors.primary, 171 padding: 15, 172 borderRadius: 10, 173 alignItems: 'center', 174 marginTop: 20, 175 }, 176 completeButtonText: { 177 color: colors.card, 178 fontSize: 18, 179 fontWeight: '600', 180 }, 181 });