michangarrito/apps/mobile/src/navigation/AppNavigator.tsx
rckrdmrd 928eb795e6 [SIMCO-V38] feat: Actualizar a SIMCO v3.8.0 + cambios apps
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Cambios en backend y frontend

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:05 -06:00

243 lines
6.7 KiB
TypeScript

import React from 'react';
import { ActivityIndicator, View, StyleSheet, Linking } from 'react-native';
import { NavigationContainer, LinkingOptions } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Text } from 'react-native';
import { useAuth } from '../contexts/AuthContext';
import { colors, fontSize } from '../constants/theme';
// Deep linking configuration
const linking: LinkingOptions<RootStackParamList> = {
prefixes: ['michangarrito://', 'https://michangarrito.com'],
config: {
screens: {
Main: {
screens: {
Dashboard: 'dashboard',
POS: 'pos',
Reports: 'reports',
More: 'more',
},
},
Products: 'products',
Inventory: 'inventory',
Customers: 'customers',
Settings: 'settings',
BarcodeScanner: 'scan',
},
},
async getInitialURL() {
// Handle app opened from deep link
const url = await Linking.getInitialURL();
if (url != null) {
return url;
}
return null;
},
subscribe(listener) {
// Listen to incoming links while app is open
const subscription = Linking.addEventListener('url', ({ url }) => {
listener(url);
});
return () => {
subscription.remove();
};
},
};
// Screens
import LoginScreen from '../screens/LoginScreen';
import DashboardScreen from '../screens/DashboardScreen';
import POSScreen from '../screens/POSScreen';
import MoreScreen from '../screens/MoreScreen';
import ProductsScreen from '../screens/ProductsScreen';
import InventoryScreen from '../screens/InventoryScreen';
import CustomersScreen from '../screens/CustomersScreen';
import ReportsScreen from '../screens/ReportsScreen';
import SettingsScreen from '../screens/SettingsScreen';
import BarcodeScannerScreen from '../screens/BarcodeScannerScreen';
// Type definitions
export type RootStackParamList = {
Auth: undefined;
Main: undefined;
Products: undefined;
Inventory: undefined;
Customers: undefined;
Reports: undefined;
Settings: undefined;
BarcodeScanner: { onScan?: (barcode: string) => void };
};
export type MainTabParamList = {
Dashboard: undefined;
POS: undefined;
Reports: undefined;
More: undefined;
};
const Stack = createNativeStackNavigator<RootStackParamList>();
const Tab = createBottomTabNavigator<MainTabParamList>();
// Tab Icon Component
const TabIcon = ({ name, focused }: { name: string; focused: boolean }) => {
const icons: Record<string, string> = {
Dashboard: '🏠',
POS: '🛒',
Reports: '📊',
More: '☰',
};
return (
<Text style={{ fontSize: focused ? 24 : 20 }}>
{icons[name] || '•'}
</Text>
);
};
// Main Tab Navigator
function MainTabs() {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused }) => (
<TabIcon name={route.name} focused={focused} />
),
tabBarActiveTintColor: colors.primary,
tabBarInactiveTintColor: colors.textMuted,
tabBarStyle: {
backgroundColor: colors.surface,
borderTopColor: colors.border,
paddingTop: 8,
height: 60,
},
tabBarLabelStyle: {
fontSize: fontSize.xs,
fontWeight: '500',
},
headerShown: false,
})}
>
<Tab.Screen
name="Dashboard"
component={DashboardScreen}
options={{ tabBarLabel: 'Inicio' }}
/>
<Tab.Screen
name="POS"
component={POSScreen}
options={{ tabBarLabel: 'Vender' }}
/>
<Tab.Screen
name="Reports"
component={ReportsScreen}
options={{ tabBarLabel: 'Reportes' }}
/>
<Tab.Screen
name="More"
component={MoreScreen}
options={{ tabBarLabel: 'Mas' }}
/>
</Tab.Navigator>
);
}
// Loading Screen
function LoadingScreen() {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color={colors.primary} />
</View>
);
}
// Main App Navigator
export default function AppNavigator() {
const { isAuthenticated, isLoading } = useAuth();
if (isLoading) {
return <LoadingScreen />;
}
return (
<NavigationContainer linking={linking}>
<Stack.Navigator screenOptions={{ headerShown: false }}>
{isAuthenticated ? (
<>
<Stack.Screen name="Main" component={MainTabs} />
<Stack.Screen
name="Products"
component={ProductsScreen}
options={{
headerShown: true,
headerTitle: 'Productos',
headerBackTitle: 'Atras',
headerStyle: { backgroundColor: colors.surface },
headerTintColor: colors.text,
}}
/>
<Stack.Screen
name="Inventory"
component={InventoryScreen}
options={{
headerShown: true,
headerTitle: 'Inventario',
headerBackTitle: 'Atras',
headerStyle: { backgroundColor: colors.surface },
headerTintColor: colors.text,
}}
/>
<Stack.Screen
name="Customers"
component={CustomersScreen}
options={{
headerShown: true,
headerTitle: 'Clientes',
headerBackTitle: 'Atras',
headerStyle: { backgroundColor: colors.surface },
headerTintColor: colors.text,
}}
/>
<Stack.Screen
name="Settings"
component={SettingsScreen}
options={{
headerShown: true,
headerTitle: 'Ajustes',
headerBackTitle: 'Atras',
headerStyle: { backgroundColor: colors.surface },
headerTintColor: colors.text,
}}
/>
<Stack.Screen
name="BarcodeScanner"
component={BarcodeScannerScreen}
options={{
headerShown: true,
headerTitle: 'Escanear Codigo',
headerBackTitle: 'Cancelar',
headerStyle: { backgroundColor: colors.surface },
headerTintColor: colors.text,
presentation: 'modal',
}}
/>
</>
) : (
<Stack.Screen name="Auth" component={LoginScreen} />
)}
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
loadingContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: colors.background,
},
});