1import { useAuth } from "@clerk/expo";
2import { AuthView, type UserProfileCustomPage, UserProfileView } from "@clerk/expo/native";
3import { StackActions, useNavigation } from "@react-navigation/native";
4import { useCallback, useEffect, useLayoutEffect, useRef } from "react";
5import { View } from "react-native";
6import { useAtomSet } from "@effect/atom-react";
7
8import { hasCloudPublicConfig } from "../cloud/publicConfig";
9import { T3ConnectProfilePage } from "../cloud/T3ConnectProfilePage";
10import { useCloudAuthAvailable } from "../cloud/cloudAvailability";
11import { updateMobilePreferencesAtom } from "../../state/preferences";
12
13// Custom rows in Clerk's native profile. Mirrors the web UserButton pages.
14const USER_PROFILE_CUSTOM_PAGES = [
15 {
16 path: "t3-connect",
17 label: "T3 Connect",
18 icon: "globe",
19 content: <T3ConnectProfilePage />,
20 },
21] satisfies UserProfileCustomPage[];
22
23export function SettingsAuthRouteScreen() {
24 const navigation = useNavigation();
25 const cloudAvailable = useCloudAuthAvailable();
26 const savePreferences = useAtomSet(updateMobilePreferencesAtom);
27
28 useLayoutEffect(() => {
29 if (!hasCloudPublicConfig()) {
30 navigation.dispatch(StackActions.replace("SettingsContent"));
31 } else if (!cloudAvailable) {
32 savePreferences({ connectionService: "t3-connect" });
33 }
34 }, [cloudAvailable, navigation, savePreferences]);
35
36 return cloudAvailable ? <ConfiguredSettingsAuthRouteScreen /> : null;
37}
38
39function ConfiguredSettingsAuthRouteScreen() {
40 const { isLoaded, isSignedIn } = useAuth({ treatPendingAsSignedOut: false });
41 const navigation = useNavigation();
42 const handleHostBack = useCallback(
43 () => navigation.dispatch(StackActions.popTo("SettingsContent")),
44 [navigation],
45 );
46 const hasBeenSignedIn = useRef(isSignedIn);
47 if (isSignedIn) {
48 hasBeenSignedIn.current = true;
49 }
50
51 useEffect(() => {
52 if (hasBeenSignedIn.current && isLoaded && isSignedIn === false) {
53 navigation.dispatch(StackActions.popTo("SettingsContent"));
54 }
55 }, [isLoaded, isSignedIn, navigation]);
56
57 return (
58 <View collapsable={false} className="flex-1 overflow-hidden bg-sheet">
59 {isLoaded ? (
60 hasBeenSignedIn.current ? (
61 <UserProfileView
62 customPages={USER_PROFILE_CUSTOM_PAGES}
63 isDismissible={false}
64 onHostBack={handleHostBack}
65 />
66 ) : (
67 <AuthView isDismissible={false} onHostBack={handleHostBack} />
68 )
69 ) : null}
70 </View>
71 );
72}