ueberpruefen
This commit is contained in:
246
src/navigation/index.tsx
Normal file
246
src/navigation/index.tsx
Normal file
@@ -0,0 +1,246 @@
|
||||
import React from 'react';
|
||||
import { Text, View, StyleSheet, TouchableOpacity, ActivityIndicator } from 'react-native';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||
import { BottomTabBarProps } from '@react-navigation/bottom-tabs';
|
||||
import { RootStackParamList, MainTabParamList } from './types';
|
||||
import {
|
||||
LoginScreen,
|
||||
SignUpScreen,
|
||||
OnboardingScreen,
|
||||
ProjectsScreen,
|
||||
ProjectDetailScreen,
|
||||
StepEditorScreen,
|
||||
NewsScreen,
|
||||
SettingsScreen,
|
||||
GlazePickerScreen,
|
||||
GlazeMixerScreen,
|
||||
} from '../screens';
|
||||
import { colors, spacing } from '../lib/theme';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
|
||||
const RootStack = createNativeStackNavigator<RootStackParamList>();
|
||||
const MainTab = createBottomTabNavigator<MainTabParamList>();
|
||||
|
||||
function CustomTabBar({ state, descriptors, navigation }: BottomTabBarProps) {
|
||||
const tabs = [
|
||||
{ name: 'Projects', label: 'Projects', icon: '🏺' },
|
||||
{ name: 'News', label: 'Tips', icon: '💡' },
|
||||
{ name: 'Settings', label: 'Settings', icon: '⚙️' },
|
||||
];
|
||||
|
||||
return (
|
||||
<View style={styles.tabBarContainer}>
|
||||
{tabs.map((tab, index) => {
|
||||
const isFocused = state.index === index;
|
||||
const isFirst = index === 0;
|
||||
const isLast = index === tabs.length - 1;
|
||||
const isMiddle = !isFirst && !isLast;
|
||||
|
||||
const onPress = () => {
|
||||
const event = navigation.emit({
|
||||
type: 'tabPress',
|
||||
target: state.routes[index].key,
|
||||
canPreventDefault: true,
|
||||
});
|
||||
|
||||
if (!isFocused && !event.defaultPrevented) {
|
||||
navigation.navigate(state.routes[index].name);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
key={tab.name}
|
||||
onPress={onPress}
|
||||
style={[
|
||||
styles.tabItem,
|
||||
isFocused && styles.tabItemActive,
|
||||
isFocused && isFirst && styles.tabItemActiveFirst,
|
||||
isFocused && isLast && styles.tabItemActiveLast,
|
||||
isFocused && isMiddle && styles.tabItemActiveMiddle,
|
||||
]}
|
||||
>
|
||||
<Text style={styles.tabIcon}>{tab.icon}</Text>
|
||||
<Text style={[
|
||||
styles.tabLabel,
|
||||
isFocused && styles.tabLabelActive
|
||||
]}>
|
||||
{tab.label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
function MainTabs() {
|
||||
return (
|
||||
<MainTab.Navigator
|
||||
tabBar={props => <CustomTabBar {...props} />}
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
}}
|
||||
>
|
||||
<MainTab.Screen
|
||||
name="Projects"
|
||||
component={ProjectsScreen}
|
||||
options={{
|
||||
tabBarLabel: 'Projects',
|
||||
}}
|
||||
/>
|
||||
<MainTab.Screen
|
||||
name="News"
|
||||
component={NewsScreen}
|
||||
options={{
|
||||
tabBarLabel: 'Tips',
|
||||
}}
|
||||
/>
|
||||
<MainTab.Screen
|
||||
name="Settings"
|
||||
component={SettingsScreen}
|
||||
options={{
|
||||
tabBarLabel: 'Settings',
|
||||
}}
|
||||
/>
|
||||
</MainTab.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
tabBarContainer: {
|
||||
flexDirection: 'row',
|
||||
backgroundColor: colors.background,
|
||||
height: 90,
|
||||
position: 'absolute',
|
||||
bottom: 20,
|
||||
left: 10,
|
||||
right: 10,
|
||||
borderRadius: 25,
|
||||
shadowColor: colors.text,
|
||||
shadowOffset: { width: 0, height: -2 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 8,
|
||||
elevation: 8,
|
||||
},
|
||||
tabItem: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingVertical: 12,
|
||||
},
|
||||
tabItemActive: {
|
||||
backgroundColor: '#E8C7A8',
|
||||
borderWidth: 2,
|
||||
borderColor: '#e6b98e',
|
||||
},
|
||||
tabItemActiveFirst: {
|
||||
borderRadius: 25,
|
||||
},
|
||||
tabItemActiveLast: {
|
||||
borderRadius: 25,
|
||||
},
|
||||
tabItemActiveMiddle: {
|
||||
borderRadius: 25,
|
||||
},
|
||||
tabIcon: {
|
||||
fontSize: 32,
|
||||
marginBottom: 4,
|
||||
},
|
||||
tabLabel: {
|
||||
fontSize: 11,
|
||||
fontWeight: '700',
|
||||
letterSpacing: 0.3,
|
||||
color: colors.textSecondary,
|
||||
},
|
||||
tabLabelActive: {
|
||||
color: colors.text,
|
||||
},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
});
|
||||
|
||||
export function AppNavigator() {
|
||||
const { user, loading, hasCompletedOnboarding } = useAuth();
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={colors.primary} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<NavigationContainer>
|
||||
<RootStack.Navigator
|
||||
initialRouteName={!user ? 'Login' : hasCompletedOnboarding ? 'MainTabs' : 'Onboarding'}
|
||||
screenOptions={{
|
||||
headerStyle: {
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
headerTintColor: colors.primary,
|
||||
headerTitleStyle: {
|
||||
fontWeight: '600',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{!user ? (
|
||||
// Auth screens - not logged in
|
||||
<>
|
||||
<RootStack.Screen
|
||||
name="Login"
|
||||
component={LoginScreen}
|
||||
options={{ headerShown: false }}
|
||||
/>
|
||||
<RootStack.Screen
|
||||
name="SignUp"
|
||||
component={SignUpScreen}
|
||||
options={{ headerShown: false }}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
// App screens - logged in (initial route determined by hasCompletedOnboarding)
|
||||
<>
|
||||
<RootStack.Screen
|
||||
name="Onboarding"
|
||||
component={OnboardingScreen}
|
||||
options={{ headerShown: false }}
|
||||
/>
|
||||
<RootStack.Screen
|
||||
name="MainTabs"
|
||||
component={MainTabs}
|
||||
options={{ headerShown: false }}
|
||||
/>
|
||||
<RootStack.Screen
|
||||
name="ProjectDetail"
|
||||
component={ProjectDetailScreen}
|
||||
options={{ title: 'Project' }}
|
||||
/>
|
||||
<RootStack.Screen
|
||||
name="StepEditor"
|
||||
component={StepEditorScreen}
|
||||
options={{ title: 'Add Step' }}
|
||||
/>
|
||||
<RootStack.Screen
|
||||
name="GlazePicker"
|
||||
component={GlazePickerScreen}
|
||||
options={{ title: 'Select Glazes' }}
|
||||
/>
|
||||
<RootStack.Screen
|
||||
name="GlazeMixer"
|
||||
component={GlazeMixerScreen}
|
||||
options={{ title: 'Mix Glazes' }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</RootStack.Navigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user