90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
import 'react-native-gesture-handler';
|
|
import React, { useEffect } from 'react';
|
|
import { View } from 'react-native';
|
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
import { StatusBar } from 'expo-status-bar';
|
|
import { Stack, useRouter, useSegments } from 'expo-router';
|
|
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
|
|
import { AuthProvider, useAuth } from '@/auth/AuthContext';
|
|
import { I18nProvider } from '@/i18n';
|
|
import { Loading } from '@/components/ui';
|
|
import { OfflineGate } from '@/components/OfflineBanner';
|
|
import { persister, queryClient } from '@/lib/queryClient';
|
|
import { startNetworkWatcher } from '@/lib/network';
|
|
import { colors } from '@/theme';
|
|
|
|
// Before React renders, so the first queries already know the network state.
|
|
startNetworkWatcher();
|
|
|
|
/** Routes between the auth flow and the app. */
|
|
function useProtectedRoute() {
|
|
const { user, initializing } = useAuth();
|
|
const segments = useSegments();
|
|
const router = useRouter();
|
|
|
|
useEffect(() => {
|
|
if (initializing) return;
|
|
const inAuthGroup = segments[0] === '(auth)';
|
|
if (!user && !inAuthGroup) {
|
|
router.replace('/(auth)/login');
|
|
} else if (user && inAuthGroup) {
|
|
router.replace('/(tabs)');
|
|
}
|
|
}, [user, initializing, segments]);
|
|
}
|
|
|
|
function RootNavigator() {
|
|
const { initializing } = useAuth();
|
|
useProtectedRoute();
|
|
|
|
if (initializing) {
|
|
return (
|
|
<View style={{ flex: 1, backgroundColor: colors.bgApp }}>
|
|
<Loading label="CasaDoc" />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Stack screenOptions={{ headerShown: false, contentStyle: { backgroundColor: colors.bgApp } }}>
|
|
<Stack.Screen name="(auth)" />
|
|
<Stack.Screen name="(tabs)" />
|
|
<Stack.Screen name="property/[id]" />
|
|
<Stack.Screen name="property/add" />
|
|
<Stack.Screen name="documents/[propertyId]" />
|
|
<Stack.Screen name="document/[id]" />
|
|
<Stack.Screen name="profile/edit" />
|
|
<Stack.Screen name="profile/password" />
|
|
<Stack.Screen name="upload" options={{ presentation: 'modal' }} />
|
|
</Stack>
|
|
);
|
|
}
|
|
|
|
export default function RootLayout() {
|
|
return (
|
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
<SafeAreaProvider>
|
|
<PersistQueryClientProvider
|
|
client={queryClient}
|
|
persistOptions={{
|
|
persister,
|
|
maxAge: 7 * 24 * 60 * 60 * 1000,
|
|
// Reads only: a half-finished upload must not replay on launch.
|
|
dehydrateOptions: { shouldDehydrateMutation: () => false },
|
|
}}
|
|
>
|
|
<I18nProvider>
|
|
<AuthProvider>
|
|
<StatusBar style="dark" />
|
|
<OfflineGate>
|
|
<RootNavigator />
|
|
</OfflineGate>
|
|
</AuthProvider>
|
|
</I18nProvider>
|
|
</PersistQueryClientProvider>
|
|
</SafeAreaProvider>
|
|
</GestureHandlerRootView>
|
|
);
|
|
}
|