fitaiProto/apps/mobile/src/app/(tabs)/_layout.tsx

101 lines
2.6 KiB
TypeScript

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 (
<Tabs
tabBar={(props) => <CustomTabBar {...props} />}
screenOptions={{
headerShown: false, // We'll use custom headers in screens or layout
tabBarShowLabel: false,
}}
>
<Tabs.Screen
name="index"
options={{
title: "Home",
}}
/>
<Tabs.Screen
name="goals"
options={{
title: "Goals",
}}
/>
<Tabs.Screen
name="recommendations"
options={{
title: "AI",
}}
/>
<Tabs.Screen
name="attendance"
options={{
title: "Attendance",
}}
/>
<Tabs.Screen
name="profile"
options={{
title: "Profile",
}}
/>
</Tabs>
);
}