chore: add mobile app

This commit is contained in:
2026-02-07 22:33:02 +01:00
parent db34640acc
commit e89384ad4e
29327 changed files with 3886944 additions and 12 deletions
@@ -0,0 +1,184 @@
import React from "react";
import { TouchableOpacity, View } from "react-native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { Ionicons } from "@expo/vector-icons";
import { useAuth } from "../auth/AuthContext";
import { useTheme } from "../context/ThemeContext";
import { logoutAdmin } from "../api/api_admin";
import { fontSize, spacing } from "../theme";
import type { AdminTabParamList, AdminStackParamList } from "./types";
import DashboardScreen from "../screens/admin/DashboardScreen";
import OrdersScreen from "../screens/admin/OrdersScreen";
import OrderDetailScreen from "../screens/admin/OrderDetailScreen";
import UsersScreen from "../screens/admin/UsersScreen";
import ProductsScreen from "../screens/admin/ProductsScreen";
import DeliveryScreen from "../screens/admin/DeliveryScreen";
import AlertsScreen from "../screens/admin/AlertsScreen";
const Tab = createBottomTabNavigator<AdminTabParamList>();
const Stack = createNativeStackNavigator<AdminStackParamList>();
function AdminTabs() {
const { logout } = useAuth();
const { colors, isDark, toggleTheme } = useTheme();
const handleLogout = async () => {
await logoutAdmin();
await logout();
};
return (
<Tab.Navigator
screenOptions={{
headerStyle: { backgroundColor: colors.bgSecondary },
headerTintColor: colors.textWhite,
headerRight: () => (
<View
style={{
flexDirection: "row",
alignItems: "center",
marginRight: spacing.l,
}}
>
<TouchableOpacity
onPress={toggleTheme}
style={{ marginRight: spacing.m }}
>
<Ionicons
name={isDark ? "sunny-outline" : "moon-outline"}
size={22}
color={colors.textSecondary}
/>
</TouchableOpacity>
<TouchableOpacity onPress={handleLogout}>
<Ionicons
name="log-out-outline"
size={24}
color={colors.textSecondary}
/>
</TouchableOpacity>
</View>
),
tabBarStyle: {
backgroundColor: colors.bgSecondary,
borderTopColor: colors.border,
borderTopWidth: 1,
},
tabBarActiveTintColor: colors.accent,
tabBarInactiveTintColor: colors.textMuted,
tabBarLabelStyle: { fontSize: fontSize.xs },
}}
>
<Tab.Screen
name="Dashboard"
component={DashboardScreen}
options={{
title: "Dashboard",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="grid-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Orders"
component={OrdersScreen}
options={{
title: "Commandes",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="receipt-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Users"
component={UsersScreen}
options={{
title: "Clients",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="people-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Products"
component={ProductsScreen}
options={{
title: "Produits",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="cube-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Delivery"
component={DeliveryScreen}
options={{
title: "Livreurs",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="bicycle-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Alerts"
component={AlertsScreen}
options={{
title: "Alertes",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="alert-circle-outline"
size={size}
color={color}
/>
),
}}
/>
</Tab.Navigator>
);
}
export default function AdminNavigator() {
const { colors } = useTheme();
return (
<Stack.Navigator
screenOptions={{
headerStyle: { backgroundColor: colors.bgSecondary },
headerTintColor: colors.textWhite,
}}
>
<Stack.Screen
name="AdminTabs"
component={AdminTabs}
options={{ headerShown: false }}
/>
<Stack.Screen
name="OrderDetail"
component={OrderDetailScreen}
options={{ title: "Détail commande" }}
/>
</Stack.Navigator>
);
}
@@ -0,0 +1,142 @@
import React from "react";
import { TouchableOpacity, View } from "react-native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { Ionicons } from "@expo/vector-icons";
import { useAuth } from "../auth/AuthContext";
import { useTheme } from "../context/ThemeContext";
import { logoutAdmin } from "../api/api_admin";
import { fontSize, spacing } from "../theme";
import type { CabineTabParamList } from "./types";
import DashboardScreen from "../screens/cabine/DashboardScreen";
import OrdersScreen from "../screens/cabine/OrdersScreen";
import DeliveryScreen from "../screens/cabine/DeliveryScreen";
import UsersScreen from "../screens/cabine/UsersScreen";
import AlertsScreen from "../screens/cabine/AlertsScreen";
const Tab = createBottomTabNavigator<CabineTabParamList>();
export default function CabineNavigator() {
const { logout } = useAuth();
const { colors, isDark, toggleTheme } = useTheme();
const handleLogout = async () => {
await logoutAdmin();
await logout();
};
return (
<Tab.Navigator
screenOptions={{
headerStyle: { backgroundColor: colors.bgSecondary },
headerTintColor: colors.textWhite,
headerRight: () => (
<View
style={{
flexDirection: "row",
alignItems: "center",
marginRight: spacing.l,
}}
>
<TouchableOpacity
onPress={toggleTheme}
style={{ marginRight: spacing.m }}
>
<Ionicons
name={isDark ? "sunny-outline" : "moon-outline"}
size={22}
color={colors.textSecondary}
/>
</TouchableOpacity>
<TouchableOpacity onPress={handleLogout}>
<Ionicons
name="log-out-outline"
size={24}
color={colors.textSecondary}
/>
</TouchableOpacity>
</View>
),
tabBarStyle: {
backgroundColor: colors.bgSecondary,
borderTopColor: colors.border,
borderTopWidth: 1,
},
tabBarActiveTintColor: colors.info,
tabBarInactiveTintColor: colors.textMuted,
tabBarLabelStyle: { fontSize: fontSize.xs },
}}
>
<Tab.Screen
name="Dashboard"
component={DashboardScreen}
options={{
title: "Dashboard",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="grid-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Orders"
component={OrdersScreen}
options={{
title: "Commandes",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="receipt-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Delivery"
component={DeliveryScreen}
options={{
title: "Livreurs",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="bicycle-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Users"
component={UsersScreen}
options={{
title: "Clients",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="people-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Alerts"
component={AlertsScreen}
options={{
title: "Alertes",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="alert-circle-outline"
size={size}
color={color}
/>
),
}}
/>
</Tab.Navigator>
);
}
@@ -0,0 +1,112 @@
import React from "react";
import { TouchableOpacity, View } from "react-native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { Ionicons } from "@expo/vector-icons";
import { useAuth } from "../auth/AuthContext";
import { useTheme } from "../context/ThemeContext";
import { logoutAdmin } from "../api/api_admin";
import { fontSize, spacing } from "../theme";
import type { DeliveryTabParamList } from "./types";
import DashboardScreen from "../screens/delivery/DashboardScreen";
import StatsScreen from "../screens/delivery/StatsScreen";
import AlertsScreen from "../screens/delivery/AlertsScreen";
const Tab = createBottomTabNavigator<DeliveryTabParamList>();
export default function DeliveryNavigator() {
const { logout } = useAuth();
const { colors, isDark, toggleTheme } = useTheme();
const handleLogout = async () => {
await logoutAdmin();
await logout();
};
return (
<Tab.Navigator
screenOptions={{
headerStyle: { backgroundColor: colors.bgSecondary },
headerTintColor: colors.textWhite,
headerRight: () => (
<View
style={{
flexDirection: "row",
alignItems: "center",
marginRight: spacing.l,
}}
>
<TouchableOpacity
onPress={toggleTheme}
style={{ marginRight: spacing.m }}
>
<Ionicons
name={isDark ? "sunny-outline" : "moon-outline"}
size={22}
color={colors.textSecondary}
/>
</TouchableOpacity>
<TouchableOpacity onPress={handleLogout}>
<Ionicons
name="log-out-outline"
size={24}
color={colors.textSecondary}
/>
</TouchableOpacity>
</View>
),
tabBarStyle: {
backgroundColor: colors.bgSecondary,
borderTopColor: colors.border,
borderTopWidth: 1,
},
tabBarActiveTintColor: colors.success,
tabBarInactiveTintColor: colors.textMuted,
tabBarLabelStyle: { fontSize: fontSize.xs },
}}
>
<Tab.Screen
name="Dashboard"
component={DashboardScreen}
options={{
title: "Livraisons",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="navigate-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Stats"
component={StatsScreen}
options={{
title: "Stats",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="stats-chart-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Alerts"
component={AlertsScreen}
options={{
title: "Alertes",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="alert-circle-outline"
size={size}
color={color}
/>
),
}}
/>
</Tab.Navigator>
);
}
+34
View File
@@ -0,0 +1,34 @@
export type AuthStackParamList = {
RoleSelect: undefined;
AdminLogin: undefined;
CabineLogin: undefined;
DeliveryLogin: undefined;
};
export type AdminTabParamList = {
Dashboard: undefined;
Orders: undefined;
Users: undefined;
Products: undefined;
Delivery: undefined;
Alerts: undefined;
};
export type AdminStackParamList = {
AdminTabs: undefined;
OrderDetail: { orderId: number };
};
export type CabineTabParamList = {
Dashboard: undefined;
Orders: undefined;
Delivery: undefined;
Users: undefined;
Alerts: undefined;
};
export type DeliveryTabParamList = {
Dashboard: undefined;
Stats: undefined;
Alerts: undefined;
};