first commit
This commit is contained in:
368
unionflow-mobile-apps/src/navigation/AppNavigator.tsx
Normal file
368
unionflow-mobile-apps/src/navigation/AppNavigator.tsx
Normal file
@@ -0,0 +1,368 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user