164 lines
5.1 KiB
TypeScript
164 lines
5.1 KiB
TypeScript
import React, { useMemo, useEffect, useState } from "react";
|
|
import { StatusBar } from "expo-status-bar";
|
|
import { ActivityIndicator, View, StyleSheet } from "react-native";
|
|
import * as Updates from "expo-updates";
|
|
import { NavigationContainer } from "@react-navigation/native";
|
|
import { createNativeStackNavigator } from "@react-navigation/native-stack";
|
|
|
|
import { AuthProvider, useAuth } from "./src/auth/AuthContext";
|
|
import { ThemeProvider, useTheme } from "./src/context/ThemeContext";
|
|
import type { Colors } from "./src/theme";
|
|
import { spacing } from "./src/theme";
|
|
import { initServerBaseUrl } from "./src/api/client";
|
|
|
|
import ServerConfigScreen from "./src/screens/auth/ServerConfigScreen";
|
|
import RoleSelectScreen from "./src/screens/auth/RoleSelectScreen";
|
|
import AdminLoginScreen from "./src/screens/auth/AdminLoginScreen";
|
|
import CabineLoginScreen from "./src/screens/auth/CabineLoginScreen";
|
|
import DeliveryLoginScreen from "./src/screens/auth/DeliveryLoginScreen";
|
|
|
|
import AdminNavigator from "./src/navigation/AdminNavigator";
|
|
import CabineNavigator from "./src/navigation/CabineNavigator";
|
|
import DeliveryNavigator from "./src/navigation/DeliveryNavigator";
|
|
|
|
import type { AuthStackParamList } from "./src/navigation/types";
|
|
|
|
const Stack = createNativeStackNavigator<AuthStackParamList>();
|
|
|
|
function AuthStack() {
|
|
const { colors } = useTheme();
|
|
|
|
return (
|
|
<Stack.Navigator
|
|
initialRouteName="ServerConfig"
|
|
screenOptions={{
|
|
headerStyle: { backgroundColor: colors.bgSecondary },
|
|
headerTintColor: colors.textWhite,
|
|
}}
|
|
>
|
|
<Stack.Screen
|
|
name="ServerConfig"
|
|
component={ServerConfigScreen}
|
|
options={{ headerShown: false }}
|
|
/>
|
|
<Stack.Screen
|
|
name="RoleSelect"
|
|
component={RoleSelectScreen}
|
|
options={{ title: "Admin Panel" }}
|
|
/>
|
|
<Stack.Screen
|
|
name="AdminLogin"
|
|
component={AdminLoginScreen}
|
|
options={{ title: "Connexion Admin" }}
|
|
/>
|
|
<Stack.Screen
|
|
name="CabineLogin"
|
|
component={CabineLoginScreen}
|
|
options={{ title: "Connexion Cabine" }}
|
|
/>
|
|
<Stack.Screen
|
|
name="DeliveryLogin"
|
|
component={DeliveryLoginScreen}
|
|
options={{ title: "Connexion Livreur" }}
|
|
/>
|
|
</Stack.Navigator>
|
|
);
|
|
}
|
|
|
|
function RootNavigator() {
|
|
const { isAuthenticated, isLoading, role } = useAuth();
|
|
const { colors } = useTheme();
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<View
|
|
style={{
|
|
flex: 1,
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
backgroundColor: colors.bgPrimary,
|
|
}}
|
|
>
|
|
<ActivityIndicator size="large" color={colors.accent} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
if (isAuthenticated) {
|
|
switch (role) {
|
|
case "admin":
|
|
return <AdminNavigator />;
|
|
case "cabine":
|
|
return <CabineNavigator />;
|
|
case "livreur":
|
|
return <DeliveryNavigator />;
|
|
}
|
|
}
|
|
|
|
return <AuthStack />;
|
|
}
|
|
|
|
export default function App() {
|
|
useEffect(() => {
|
|
if (__DEV__) return;
|
|
const checkForUpdate = async () => {
|
|
try {
|
|
const update = await Updates.checkForUpdateAsync();
|
|
if (update.isAvailable) {
|
|
await Updates.fetchUpdateAsync();
|
|
await Updates.reloadAsync();
|
|
}
|
|
} catch (e) {
|
|
console.error("[OTA] Échec de la vérification/application de la mise à jour:", e);
|
|
}
|
|
};
|
|
checkForUpdate();
|
|
}, []);
|
|
|
|
return (
|
|
<ThemeProvider>
|
|
<ServerGate>
|
|
<AuthProvider>
|
|
<NavigationContainer>
|
|
<RootNavigator />
|
|
<DynamicStatusBar />
|
|
</NavigationContainer>
|
|
</AuthProvider>
|
|
</ServerGate>
|
|
</ThemeProvider>
|
|
);
|
|
}
|
|
|
|
// Restores a previously saved backend server URL before any screen
|
|
// (including the auth restore flow) can issue an API call.
|
|
function ServerGate({ children }: { children: React.ReactNode }) {
|
|
const [ready, setReady] = useState(false);
|
|
const { colors } = useTheme();
|
|
|
|
useEffect(() => {
|
|
initServerBaseUrl().finally(() => setReady(true));
|
|
}, []);
|
|
|
|
if (!ready) {
|
|
return (
|
|
<View
|
|
style={{
|
|
flex: 1,
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
backgroundColor: colors.bgPrimary,
|
|
}}
|
|
>
|
|
<ActivityIndicator size="large" color={colors.accent} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return <>{children}</>;
|
|
}
|
|
|
|
function DynamicStatusBar() {
|
|
const { isDark } = useTheme();
|
|
return <StatusBar style={isDark ? "light" : "dark"} />;
|
|
}
|