mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 10:19:43 +00:00
84 lines
2.8 KiB
TypeScript
Executable File
84 lines
2.8 KiB
TypeScript
Executable File
import { useEffect, useState } from "react";
|
|
import { Redirect } from "expo-router";
|
|
import { useAuthStore } from "../src/store";
|
|
import { View, ActivityIndicator, StyleSheet } from "react-native";
|
|
import { needsOnboarding } from "../src/constants/onboarding";
|
|
import { getPendingInviteCode } from "../src/lib/pendingInviteCode";
|
|
|
|
export default function Index() {
|
|
const { isAuthenticated, isLoading, user } = useAuthStore();
|
|
const [pendingInviteCheck, setPendingInviteCheck] = useState<{ userId: string; hasInvite: boolean } | null>(null);
|
|
|
|
// Check once, after auth resolves, whether an invite code is waiting to be
|
|
// applied (e.g. the user tapped a join link before signing in).
|
|
useEffect(() => {
|
|
if (isLoading || !isAuthenticated || user?.couple_id) {
|
|
return;
|
|
}
|
|
|
|
let cancelled = false;
|
|
if (!user?.id) return;
|
|
setPendingInviteCheck(null);
|
|
getPendingInviteCode(user.id).then((code) => {
|
|
if (cancelled) return;
|
|
setPendingInviteCheck({ userId: user.id, hasInvite: !!code });
|
|
});
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [isLoading, isAuthenticated, user?.couple_id, user?.id]);
|
|
|
|
// Show loading state while auth is being determined
|
|
if (isLoading) {
|
|
return (
|
|
<View style={styles.container}>
|
|
<ActivityIndicator size="large" color="#e94560" />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
// Redirect based on auth state
|
|
if (!isAuthenticated) {
|
|
return <Redirect href="/(auth)/login" />;
|
|
}
|
|
|
|
// If user hasn't completed onboarding or needs to re-onboard, go to onboarding
|
|
if (needsOnboarding(user?.onboarding_completed, user?.onboarding_version)) {
|
|
return <Redirect href="/(app)/onboarding" />;
|
|
}
|
|
|
|
// A couple already exists for this user; no invite hand-off is relevant.
|
|
if (user?.couple_id) {
|
|
return <Redirect href="/(app)" />;
|
|
}
|
|
|
|
// Wait for the one-time pending invite code check before deciding the
|
|
// route, so a stashed code from a join link is applied without an extra
|
|
// trip through the home screen.
|
|
if (pendingInviteCheck?.userId !== user?.id) {
|
|
return (
|
|
<View style={styles.container}>
|
|
<ActivityIndicator size="large" color="#e94560" />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
if (pendingInviteCheck?.hasInvite) {
|
|
return <Redirect href="/(app)/pairing" />;
|
|
}
|
|
|
|
// Go to home/dashboard - users can pair from within the app
|
|
// No forced redirect to pairing for users without a couple
|
|
return <Redirect href="/(app)" />;
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
backgroundColor: "#1a1a2e",
|
|
},
|
|
});
|