erp-transportistas-v2/mobile/App.tsx
Adrian Flores Cortes 6ed7f9e2ec [BACKUP] Pre-restructure workspace backup 2026-01-29
- Updated docs and inventory files
- Added new architecture docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 17:35:54 -06:00

173 lines
4.7 KiB
TypeScript

/**
* App Entry Point
* ERP Transportistas
* Sprint S8 - TASK-007
*
* Main application component with navigation setup.
*/
import React, { useEffect, useState } from 'react';
import { StatusBar, View, ActivityIndicator, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import { useAuthStore } from './src/store';
import { offlineStorage } from './src/services';
import {
LoginScreen,
ViajeActualScreen,
ChecklistScreen,
PODScreen,
} from './src/screens';
import type { RootStackParamList, MainTabParamList } from './src/types';
const Stack = createNativeStackNavigator<RootStackParamList>();
const Tab = createBottomTabNavigator<MainTabParamList>();
// Placeholder screens for tabs
function HistorialScreen(): JSX.Element {
return <View style={styles.placeholder} />;
}
function PerfilScreen(): JSX.Element {
return <View style={styles.placeholder} />;
}
function MainTabs(): JSX.Element {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName: keyof typeof Ionicons.glyphMap = 'car';
if (route.name === 'ViajeActual') {
iconName = focused ? 'car' : 'car-outline';
} else if (route.name === 'Historial') {
iconName = focused ? 'time' : 'time-outline';
} else if (route.name === 'Perfil') {
iconName = focused ? 'person' : 'person-outline';
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#2563eb',
tabBarInactiveTintColor: '#64748b',
headerShown: false,
})}
>
<Tab.Screen
name="ViajeActual"
component={ViajeActualScreen}
options={{ title: 'Viaje Actual' }}
/>
<Tab.Screen
name="Historial"
component={HistorialScreen}
options={{ title: 'Historial' }}
/>
<Tab.Screen
name="Perfil"
component={PerfilScreen}
options={{ title: 'Perfil' }}
/>
</Tab.Navigator>
);
}
export default function App(): JSX.Element {
const { isAuthenticated, isLoading, restoreSession } = useAuthStore();
const [isInitializing, setIsInitializing] = useState(true);
useEffect(() => {
initializeApp();
}, []);
const initializeApp = async (): Promise<void> => {
try {
// Initialize offline storage
await offlineStorage.initialize();
// Try to restore session
await restoreSession();
} catch (error) {
console.error('Error initializing app:', error);
} finally {
setIsInitializing(false);
}
};
if (isInitializing || isLoading) {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#2563eb" />
</View>
);
}
return (
<SafeAreaProvider>
<StatusBar barStyle="dark-content" backgroundColor="#ffffff" />
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerStyle: {
backgroundColor: '#ffffff',
},
headerTintColor: '#1e293b',
headerTitleStyle: {
fontWeight: '600',
},
}}
>
{isAuthenticated ? (
<>
<Stack.Screen
name="Main"
component={MainTabs}
options={{ headerShown: false }}
/>
<Stack.Screen
name="ViajeDetalle"
component={ViajeActualScreen}
options={{ title: 'Detalle del Viaje' }}
/>
<Stack.Screen
name="Checklist"
component={ChecklistScreen}
options={{ title: 'Checklist Pre-viaje' }}
/>
<Stack.Screen
name="POD"
component={PODScreen}
options={{ title: 'Prueba de Entrega' }}
/>
</>
) : (
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
)}
</Stack.Navigator>
</NavigationContainer>
</SafeAreaProvider>
);
}
const styles = StyleSheet.create({
loadingContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ffffff',
},
placeholder: {
flex: 1,
backgroundColor: '#f1f5f9',
},
});