import React, { useEffect, useState } from "react"; import { Stack } from "expo-router"; import { StatusBar } from "expo-status-bar"; import { PortalHost } from "@rn-primitives/portal"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { Toast } from "@/components/Toast"; import "@/global.css"; import { SafeAreaProvider } from "react-native-safe-area-context"; import { View, ActivityIndicator } from "react-native"; import { useRestoreTheme } from "@/lib/theme"; import { SirouRouterProvider, useSirouRouter } from "@sirou/react-native"; import { routes } from "@/lib/routes"; import { authGuard, guestGuard } from "@/lib/auth-guards"; import { useAuthStore } from "@/lib/auth-store"; import { api } from "@/lib/api"; import { useSegments, router as expoRouter } from "expo-router"; function BackupGuard() { const segments = useSegments(); const isAuthed = useAuthStore((s) => s.isAuthenticated); const [isMounted, setIsMounted] = useState(false); useEffect(() => { setIsMounted(true); }, []); useEffect(() => { if (!isMounted) return; const rootSegment = segments[0]; const isPublic = rootSegment === "login" || rootSegment === "register"; if (!isAuthed && !isPublic && segments.length > 0) { console.log("[BackupGuard] Safety redirect to /login"); expoRouter.replace("/login"); } }, [segments, isAuthed, isMounted]); return null; } function SirouBridge() { const sirou = useSirouRouter(); const segments = useSegments(); const isAuthenticated = useAuthStore((s) => s.isAuthenticated); const [isMounted, setIsMounted] = useState(false); useEffect(() => { setIsMounted(true); }, []); useEffect(() => { if (!isMounted) return; const checkAuth = async () => { // Create EXACT name from segments: (tabs), index => (tabs)/index // Use "root" if segments are empty (initial layout) const routeName = segments.length > 0 ? segments.join("/") : "root"; console.log(`[SirouBridge] checking route: "${routeName}"`); try { const result = await (sirou as any).checkGuards(routeName); if (!result.allowed && result.redirect) { console.log(`[SirouBridge] REDIRECT -> ${result.redirect}`); // Use expoRouter for filesystem navigation expoRouter.replace(`/${result.redirect}`); } } catch (e: any) { console.warn( `[SirouBridge] guard crash for "${routeName}":`, e.message, ); } }; checkAuth(); }, [segments, sirou, isMounted, isAuthenticated]); return null; } export default function RootLayout() { useRestoreTheme(); const [isMounted, setIsMounted] = useState(false); const [hasHydrated, setHasHydrated] = useState(false); useEffect(() => { setIsMounted(true); const initializeAuth = async () => { if (useAuthStore.persist.hasHydrated()) { setHasHydrated(true); } else { const unsub = useAuthStore.persist.onFinishHydration(() => { setHasHydrated(true); }); return unsub; } }; initializeAuth(); }, []); if (!isMounted || !hasHydrated) { return ( ); } return ( ); }