Files
unionflow-server-impl-quarkus/unionflow-mobile-apps/src/navigation/AppNavigator.tsx
2025-08-20 21:00:35 +00:00

369 lines
11 KiB
TypeScript

import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createDrawerNavigator } from '@react-navigation/drawer';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { Platform } from 'react-native';
import { useAuth } from '../contexts/AuthContext';
import { theme } from '../theme/theme';
// Écrans d'authentification
import LoginScreen from '../screens/auth/LoginScreen';
import RegisterScreen from '../screens/auth/RegisterScreen';
import ForgotPasswordScreen from '../screens/auth/ForgotPasswordScreen';
import BiometricSetupScreen from '../screens/auth/BiometricSetupScreen';
// Écrans principaux
import HomeScreen from '../screens/home/HomeScreen';
import CotisationsScreen from '../screens/cotisations/CotisationsScreen';
import PaymentScreen from '../screens/payment/PaymentScreen';
import WavePaymentScreen from '../screens/payment/WavePaymentScreen';
import ProfileScreen from '../screens/profile/ProfileScreen';
import AssociationsScreen from '../screens/associations/AssociationsScreen';
import MembersScreen from '../screens/members/MembersScreen';
import EventsScreen from '../screens/events/EventsScreen';
import AideMutuelleScreen from '../screens/aide/AideMutuelleScreen';
import NotificationsScreen from '../screens/notifications/NotificationsScreen';
import SettingsScreen from '../screens/settings/SettingsScreen';
// Écrans de workflow
import WorkflowScreen from '../screens/workflow/WorkflowScreen';
import AdhesionWorkflowScreen from '../screens/workflow/AdhesionWorkflowScreen';
// Types de navigation
export type RootStackParamList = {
Auth: undefined;
Main: undefined;
Payment: { type: 'cotisation' | 'adhesion' | 'aide' | 'evenement'; amount?: string };
WavePayment: {
type: 'cotisation' | 'adhesion' | 'aide' | 'evenement';
amount: string;
description: string;
metadata?: any;
};
Workflow: { workflowId: string; instanceId?: string };
AdhesionWorkflow: { associationId: string };
};
export type AuthStackParamList = {
Login: undefined;
Register: undefined;
ForgotPassword: undefined;
BiometricSetup: undefined;
};
export type MainTabParamList = {
Home: undefined;
Cotisations: undefined;
Associations: undefined;
Profile: undefined;
More: undefined;
};
export type DrawerParamList = {
MainTabs: undefined;
Members: undefined;
Events: undefined;
AideMutuelle: undefined;
Notifications: undefined;
Settings: undefined;
};
const RootStack = createStackNavigator<RootStackParamList>();
const AuthStack = createStackNavigator<AuthStackParamList>();
const MainTab = createBottomTabNavigator<MainTabParamList>();
const Drawer = createDrawerNavigator<DrawerParamList>();
/**
* Navigateur d'authentification
*/
const AuthNavigator: React.FC = () => {
return (
<AuthStack.Navigator
screenOptions={{
headerShown: false,
cardStyle: { backgroundColor: theme.colors.background },
}}
>
<AuthStack.Screen name="Login" component={LoginScreen} />
<AuthStack.Screen name="Register" component={RegisterScreen} />
<AuthStack.Screen name="ForgotPassword" component={ForgotPasswordScreen} />
<AuthStack.Screen name="BiometricSetup" component={BiometricSetupScreen} />
</AuthStack.Navigator>
);
};
/**
* Navigateur à onglets principal
*/
const MainTabNavigator: React.FC = () => {
return (
<MainTab.Navigator
screenOptions={({ route }) => ({
headerShown: false,
tabBarIcon: ({ focused, color, size }) => {
let iconName: string;
switch (route.name) {
case 'Home':
iconName = focused ? 'home' : 'home-outline';
break;
case 'Cotisations':
iconName = focused ? 'credit-card' : 'credit-card-outline';
break;
case 'Associations':
iconName = focused ? 'account-group' : 'account-group-outline';
break;
case 'Profile':
iconName = focused ? 'account' : 'account-outline';
break;
case 'More':
iconName = focused ? 'menu' : 'menu';
break;
default:
iconName = 'circle';
}
return <Icon name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: theme.colors.primary,
tabBarInactiveTintColor: theme.custom.colors.textSecondary,
tabBarStyle: {
backgroundColor: theme.colors.surface,
borderTopWidth: 1,
borderTopColor: theme.custom.colors.border,
height: Platform.OS === 'ios' ? 83 : 60,
paddingBottom: Platform.OS === 'ios' ? 20 : 8,
paddingTop: 8,
},
tabBarLabelStyle: {
fontSize: theme.custom.typography.sizes.xs,
fontFamily: theme.custom.typography.families.medium,
},
})}
>
<MainTab.Screen
name="Home"
component={HomeScreen}
options={{ tabBarLabel: 'Accueil' }}
/>
<MainTab.Screen
name="Cotisations"
component={CotisationsScreen}
options={{ tabBarLabel: 'Cotisations' }}
/>
<MainTab.Screen
name="Associations"
component={AssociationsScreen}
options={{ tabBarLabel: 'Associations' }}
/>
<MainTab.Screen
name="Profile"
component={ProfileScreen}
options={{ tabBarLabel: 'Profil' }}
/>
<MainTab.Screen
name="More"
component={MoreScreen}
options={{ tabBarLabel: 'Plus' }}
/>
</MainTab.Navigator>
);
};
/**
* Écran "Plus" avec navigation vers les autres sections
*/
const MoreScreen: React.FC = ({ navigation }: any) => {
const menuItems = [
{ title: 'Membres', icon: 'account-multiple', screen: 'Members' },
{ title: 'Événements', icon: 'calendar', screen: 'Events' },
{ title: 'Aide Mutuelle', icon: 'hand-heart', screen: 'AideMutuelle' },
{ title: 'Notifications', icon: 'bell', screen: 'Notifications' },
{ title: 'Paramètres', icon: 'cog', screen: 'Settings' },
];
return (
<div style={{ flex: 1, padding: 16 }}>
{menuItems.map((item, index) => (
<div
key={index}
style={{
flexDirection: 'row',
alignItems: 'center',
padding: 16,
backgroundColor: theme.colors.surface,
marginBottom: 8,
borderRadius: 12,
}}
onClick={() => navigation.navigate(item.screen)}
>
<Icon name={item.icon} size={24} color={theme.colors.primary} />
<span style={{ marginLeft: 16, fontSize: 16 }}>{item.title}</span>
</div>
))}
</div>
);
};
/**
* Navigateur avec tiroir (drawer)
*/
const DrawerNavigator: React.FC = () => {
return (
<Drawer.Navigator
screenOptions={{
headerShown: false,
drawerStyle: {
backgroundColor: theme.colors.background,
width: 280,
},
drawerActiveTintColor: theme.colors.primary,
drawerInactiveTintColor: theme.custom.colors.textSecondary,
drawerLabelStyle: {
fontFamily: theme.custom.typography.families.medium,
fontSize: theme.custom.typography.sizes.base,
},
}}
>
<Drawer.Screen
name="MainTabs"
component={MainTabNavigator}
options={{
drawerLabel: 'Accueil',
drawerIcon: ({ color, size }) => (
<Icon name="home" size={size} color={color} />
),
}}
/>
<Drawer.Screen
name="Members"
component={MembersScreen}
options={{
drawerLabel: 'Membres',
drawerIcon: ({ color, size }) => (
<Icon name="account-multiple" size={size} color={color} />
),
}}
/>
<Drawer.Screen
name="Events"
component={EventsScreen}
options={{
drawerLabel: 'Événements',
drawerIcon: ({ color, size }) => (
<Icon name="calendar" size={size} color={color} />
),
}}
/>
<Drawer.Screen
name="AideMutuelle"
component={AideMutuelleScreen}
options={{
drawerLabel: 'Aide Mutuelle',
drawerIcon: ({ color, size }) => (
<Icon name="hand-heart" size={size} color={color} />
),
}}
/>
<Drawer.Screen
name="Notifications"
component={NotificationsScreen}
options={{
drawerLabel: 'Notifications',
drawerIcon: ({ color, size }) => (
<Icon name="bell" size={size} color={color} />
),
}}
/>
<Drawer.Screen
name="Settings"
component={SettingsScreen}
options={{
drawerLabel: 'Paramètres',
drawerIcon: ({ color, size }) => (
<Icon name="cog" size={size} color={color} />
),
}}
/>
</Drawer.Navigator>
);
};
/**
* Navigateur principal de l'application
*/
const AppNavigator: React.FC = () => {
const { isAuthenticated } = useAuth();
return (
<RootStack.Navigator
screenOptions={{
headerShown: false,
cardStyle: { backgroundColor: theme.colors.background },
}}
>
{!isAuthenticated ? (
<RootStack.Screen name="Auth" component={AuthNavigator} />
) : (
<>
<RootStack.Screen name="Main" component={DrawerNavigator} />
<RootStack.Screen
name="Payment"
component={PaymentScreen}
options={{
presentation: 'modal',
headerShown: true,
headerTitle: 'Paiement',
headerStyle: {
backgroundColor: theme.colors.primary,
},
headerTintColor: theme.custom.colors.textOnPrimary,
}}
/>
<RootStack.Screen
name="WavePayment"
component={WavePaymentScreen}
options={{
presentation: 'modal',
headerShown: true,
headerTitle: 'Paiement Wave Money',
headerStyle: {
backgroundColor: theme.custom.colors.wave,
},
headerTintColor: theme.custom.colors.textOnPrimary,
}}
/>
<RootStack.Screen
name="Workflow"
component={WorkflowScreen}
options={{
headerShown: true,
headerTitle: 'Processus',
headerStyle: {
backgroundColor: theme.colors.primary,
},
headerTintColor: theme.custom.colors.textOnPrimary,
}}
/>
<RootStack.Screen
name="AdhesionWorkflow"
component={AdhesionWorkflowScreen}
options={{
headerShown: true,
headerTitle: 'Adhésion',
headerStyle: {
backgroundColor: theme.colors.primary,
},
headerTintColor: theme.custom.colors.textOnPrimary,
}}
/>
</>
)}
</RootStack.Navigator>
);
};
export default AppNavigator;