183 lines
5.6 KiB
TypeScript
183 lines
5.6 KiB
TypeScript
import 'react-native-gesture-handler';
|
|
import React, { useEffect, useState } from 'react';
|
|
import { StatusBar, ActivityIndicator, View } from 'react-native';
|
|
import {
|
|
NavigationContainer,
|
|
DefaultTheme,
|
|
Theme,
|
|
} from '@react-navigation/native';
|
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
|
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { initI18n } from './src/i18n/config';
|
|
|
|
import {
|
|
WelcomeScreen,
|
|
LoginScreen,
|
|
SignupScreen,
|
|
BusinessSetupScreen,
|
|
HomeScreen,
|
|
AgentsScreen,
|
|
DocumentsScreen,
|
|
GenerateScreen,
|
|
ProfileScreen,
|
|
TasksScreen,
|
|
} from './src/screens';
|
|
import {
|
|
MainTabParamList,
|
|
MoreStackParamList,
|
|
RootStackParamList,
|
|
} from './src/types/navigation';
|
|
import { colors } from './src/theme/colors';
|
|
|
|
const RootStack = createNativeStackNavigator<RootStackParamList>();
|
|
const Tab = createBottomTabNavigator<MainTabParamList>();
|
|
const MoreStack = createNativeStackNavigator<MoreStackParamList>();
|
|
|
|
const navigationTheme: Theme = {
|
|
...DefaultTheme,
|
|
colors: {
|
|
...DefaultTheme.colors,
|
|
background: colors.background,
|
|
card: colors.surface,
|
|
primary: colors.highlight,
|
|
text: colors.textPrimary,
|
|
border: colors.border,
|
|
},
|
|
};
|
|
|
|
function MoreNavigator() {
|
|
return (
|
|
<MoreStack.Navigator screenOptions={{ headerShown: false }}>
|
|
<MoreStack.Screen name="Profile" component={ProfileScreen} />
|
|
<MoreStack.Screen name="Generate" component={GenerateScreen} />
|
|
</MoreStack.Navigator>
|
|
);
|
|
}
|
|
|
|
function MainTabs() {
|
|
const { t } = useTranslation();
|
|
|
|
return (
|
|
<Tab.Navigator
|
|
screenOptions={({ route }) => ({
|
|
headerShown: false,
|
|
tabBarActiveTintColor: colors.highlightAlt,
|
|
tabBarInactiveTintColor: colors.tabIconInactive,
|
|
tabBarStyle: {
|
|
backgroundColor: colors.surfaceAlt,
|
|
borderTopColor: colors.borderStrong,
|
|
borderTopWidth: 1.5,
|
|
height: 65,
|
|
paddingBottom: 6,
|
|
paddingTop: 6,
|
|
shadowColor: colors.shadow,
|
|
shadowOffset: { width: 0, height: -4 },
|
|
shadowOpacity: 0.2,
|
|
shadowRadius: 12,
|
|
elevation: 10,
|
|
position: 'absolute',
|
|
bottom: 10,
|
|
left: 0,
|
|
right: 0,
|
|
},
|
|
tabBarLabelStyle: {
|
|
fontSize: 11,
|
|
fontWeight: '700',
|
|
letterSpacing: 0.5,
|
|
textTransform: 'uppercase',
|
|
},
|
|
tabBarIcon: ({ color, size, focused }) => {
|
|
const iconMap: Record<keyof MainTabParamList, { filled: string; outline: string }> = {
|
|
Home: { filled: 'home', outline: 'home-variant-outline' },
|
|
Agents: { filled: 'robot', outline: 'robot-outline' },
|
|
Tasks: { filled: 'clipboard-text', outline: 'clipboard-text-outline' },
|
|
Documents: { filled: 'file-document', outline: 'file-document-outline' },
|
|
More: { filled: 'dots-horizontal-circle', outline: 'dots-horizontal-circle-outline' },
|
|
};
|
|
const icons = iconMap[route.name as keyof MainTabParamList];
|
|
const iconName = focused ? icons.filled : icons.outline;
|
|
return (
|
|
<MaterialCommunityIcons
|
|
name={iconName}
|
|
size={focused ? size + 2 : size}
|
|
color={color}
|
|
/>
|
|
);
|
|
},
|
|
})}
|
|
>
|
|
<Tab.Screen
|
|
name="Home"
|
|
component={HomeScreen}
|
|
options={{ tabBarLabel: t('home') }}
|
|
/>
|
|
<Tab.Screen
|
|
name="Agents"
|
|
component={AgentsScreen}
|
|
options={{ tabBarLabel: t('agents') }}
|
|
/>
|
|
<Tab.Screen
|
|
name="Tasks"
|
|
component={TasksScreen}
|
|
options={{ tabBarLabel: t('tasks') }}
|
|
/>
|
|
<Tab.Screen
|
|
name="Documents"
|
|
component={DocumentsScreen}
|
|
options={{ tabBarLabel: t('documents') }}
|
|
/>
|
|
<Tab.Screen
|
|
name="More"
|
|
component={MoreNavigator}
|
|
options={{ tabBarLabel: t('more') }}
|
|
/>
|
|
</Tab.Navigator>
|
|
);
|
|
}
|
|
|
|
function App(): React.JSX.Element {
|
|
const [isI18nInitialized, setIsI18nInitialized] = useState(false);
|
|
|
|
useEffect(() => {
|
|
initI18n()
|
|
.then(() => {
|
|
setIsI18nInitialized(true);
|
|
})
|
|
.catch((error) => {
|
|
console.error('Failed to initialize i18n:', error);
|
|
setIsI18nInitialized(true); // Continue anyway with default language
|
|
});
|
|
}, []);
|
|
|
|
if (!isI18nInitialized) {
|
|
return (
|
|
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: colors.background }}>
|
|
<ActivityIndicator size="large" color={colors.highlight} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
<SafeAreaProvider>
|
|
<StatusBar barStyle="light-content" backgroundColor={colors.background} />
|
|
<NavigationContainer theme={navigationTheme}>
|
|
<RootStack.Navigator screenOptions={{ headerShown: false }}>
|
|
<RootStack.Screen name="Welcome" component={WelcomeScreen} />
|
|
<RootStack.Screen name="Login" component={LoginScreen} />
|
|
<RootStack.Screen name="Signup" component={SignupScreen} />
|
|
<RootStack.Screen name="BusinessSetup" component={BusinessSetupScreen} />
|
|
<RootStack.Screen name="MainTabs" component={MainTabs} />
|
|
</RootStack.Navigator>
|
|
</NavigationContainer>
|
|
</SafeAreaProvider>
|
|
</GestureHandlerRootView>
|
|
);
|
|
}
|
|
|
|
export default App;
|