107 lines
3.1 KiB
TypeScript
107 lines
3.1 KiB
TypeScript
import React, { useEffect, useState } from "react";
|
|
import { View } from "react-native";
|
|
import { router } from "expo-router";
|
|
import { useAuthWithProfile } from "~/lib/hooks/useAuthWithProfile";
|
|
import { Text } from "~/components/ui/text";
|
|
import { ROUTES } from "~/lib/routes";
|
|
import { AuthService } from "~/lib/services/authServices";
|
|
|
|
interface ProtectedRouteProps {
|
|
children: React.ReactNode;
|
|
fallback?: React.ReactNode;
|
|
redirectTo?: string;
|
|
}
|
|
|
|
export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({
|
|
children,
|
|
fallback,
|
|
redirectTo = ROUTES.SIGNIN,
|
|
}) => {
|
|
const { user, loading, profile, profileLoading } = useAuthWithProfile();
|
|
const [isAgent, setIsAgent] = useState<boolean | null>(null);
|
|
const [checkingAgent, setCheckingAgent] = useState(false);
|
|
|
|
useEffect(() => {
|
|
// In dev, allow the fake emulator user through without redirecting
|
|
if (__DEV__ && user?.uid === "dev-emulator-user") {
|
|
return;
|
|
}
|
|
|
|
if (!loading && !profileLoading && !user && !fallback) {
|
|
router.replace(redirectTo);
|
|
}
|
|
}, [user, loading, profileLoading, redirectTo, fallback]);
|
|
|
|
// Check if user is an agent when profile is not available
|
|
useEffect(() => {
|
|
if (!user || profile || checkingAgent || isAgent !== null) {
|
|
return;
|
|
}
|
|
|
|
const checkAgent = async () => {
|
|
setCheckingAgent(true);
|
|
try {
|
|
const agentExists = await AuthService.checkAgentExists(user.uid);
|
|
setIsAgent(agentExists);
|
|
} catch (error) {
|
|
console.error('ProtectedRoute - error checking agent:', error);
|
|
setIsAgent(false);
|
|
} finally {
|
|
setCheckingAgent(false);
|
|
}
|
|
};
|
|
|
|
checkAgent();
|
|
}, [user, profile, checkingAgent, isAgent]);
|
|
|
|
// Show loading state while checking authentication, profile, or agent status
|
|
if (loading || profileLoading || checkingAgent) {
|
|
console.log("ProtectedRoute - showing loading state");
|
|
return (
|
|
<View className="flex-1 justify-center items-center">
|
|
<Text className="text-lg font-dmsans">Loading...</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
// If user is not authenticated, redirect or show fallback
|
|
if (!user) {
|
|
if (fallback) {
|
|
return <View className="flex-1">{fallback}</View>;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// In dev, allow fake emulator user even without profile
|
|
if (__DEV__ && user.uid === "dev-emulator-user") {
|
|
return <View className="flex-1">{children}</View>;
|
|
}
|
|
|
|
// If user has a profile, allow access
|
|
if (profile) {
|
|
return <View className="flex-1">{children}</View>;
|
|
}
|
|
|
|
// If user is an agent (even without profile), allow access
|
|
if (isAgent === true) {
|
|
return <View className="flex-1">{children}</View>;
|
|
}
|
|
|
|
// If we've checked and user is not an agent and has no profile, redirect
|
|
if (isAgent === false) {
|
|
console.log("ProtectedRoute - user has no profile and is not an agent, redirecting to signin");
|
|
router.replace(redirectTo);
|
|
return null;
|
|
}
|
|
|
|
// Still checking agent status, show loading
|
|
return (
|
|
<View className="flex-1 justify-center items-center">
|
|
<Text className="text-lg font-dmsans">Loading...</Text>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default ProtectedRoute;
|