import { Tabs, useRouter, useSegments } from "expo-router"; import { useAuth } from "@clerk/clerk-expo"; import { useEffect, useState } from "react"; import { CustomTabBar } from "../../components/CustomTabBar"; import { fitnessProfileApi } from "../../api/fitnessProfile"; import log from "../../utils/logger"; export default function TabLayout() { const { isSignedIn, isLoaded, getToken } = useAuth(); const router = useRouter(); const segments = useSegments(); const [onboardingChecked, setOnboardingChecked] = useState(false); useEffect(() => { if (!isLoaded) return; const inAuthGroup = segments[0] === "(auth)"; if (!isSignedIn && !inAuthGroup) { // Redirect to sign-in if not authenticated router.replace("/(auth)/sign-in"); return; } // Check if user has completed onboarding if (isSignedIn && !onboardingChecked) { checkOnboardingStatus(); } }, [isSignedIn, isLoaded, segments]); const checkOnboardingStatus = async () => { try { const token = await getToken(); if (!token) { log.warn("No token available for onboarding check"); setOnboardingChecked(true); return; } const hasProfile = await fitnessProfileApi.checkProfileExists(token); if (!hasProfile) { // User hasn't completed onboarding, redirect to onboarding screen log.info("User has not completed onboarding, redirecting"); router.replace("/(auth)/onboarding"); } else { setOnboardingChecked(true); } } catch (error) { log.error("Failed to check onboarding status", error); // On error, allow access (fail open to prevent blocking legitimate users) setOnboardingChecked(true); } }; if (!isLoaded || !isSignedIn || !onboardingChecked) { return null; } return ( } screenOptions={{ headerShown: false, // We'll use custom headers in screens or layout tabBarShowLabel: false, }} > ); }