feat(app): remove hard-paywall redirect — signed-in free users reach the app

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Timo Knuth
2026-07-06 13:05:25 +02:00
parent eda0ac98d9
commit 6e6041bb5b

View File

@@ -96,11 +96,8 @@ function RootLayoutInner() {
colorPalette, colorPalette,
signOut, signOut,
session, session,
billingSummary,
isActivatingEntitlement,
isInitializing, isInitializing,
isLoadingPlants, isLoadingPlants,
isLoadingBilling,
} = useApp(); } = useApp();
const colors = useColors(isDarkMode, colorPalette); const colors = useColors(isDarkMode, colorPalette);
const pathname = usePathname(); const pathname = usePathname();
@@ -118,19 +115,11 @@ function RootLayoutInner() {
}, [signOut]); }, [signOut]);
const isAppReady = installCheckDone && !isInitializing && !isLoadingPlants; const isAppReady = installCheckDone && !isInitializing && !isLoadingPlants;
const hasActiveEntitlement = isActivatingEntitlement
|| (billingSummary?.entitlement?.plan === 'pro'
&& billingSummary?.entitlement?.status === 'active');
const isAllowedWithoutSession = pathname.includes('onboarding') const isAllowedWithoutSession = pathname.includes('onboarding')
|| pathname.includes('auth/') || pathname.includes('auth/')
|| pathname.includes('scanner') || pathname.includes('scanner')
|| isShareIntentCallbackPath(pathname) || isShareIntentCallbackPath(pathname)
|| pathname.includes('profile/billing'); || pathname.includes('profile/billing');
const isAllowedWithoutEntitlement = pathname.includes('auth/')
|| pathname.includes('onboarding')
|| pathname.includes('scanner')
|| isShareIntentCallbackPath(pathname)
|| pathname.includes('profile/billing');
let content = null; let content = null;
@@ -148,10 +137,12 @@ function RootLayoutInner() {
}} }}
> >
<Stack.Screen name="onboarding" options={{ animation: 'none' }} /> <Stack.Screen name="onboarding" options={{ animation: 'none' }} />
<Stack.Screen name="onboarding/slides" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/source" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="onboarding/source" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/goal" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="onboarding/goal" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/experience" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="onboarding/experience" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/customize" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="onboarding/customize" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/personalizing" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="auth/login" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="auth/login" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="auth/signup" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="auth/signup" options={{ animation: 'slide_from_right' }} />
<Stack.Screen <Stack.Screen
@@ -166,12 +157,6 @@ function RootLayoutInner() {
</Stack> </Stack>
); );
} }
} else if (!hasActiveEntitlement && !isLoadingBilling && billingSummary && !isAllowedWithoutEntitlement) {
// Signed-in but confirmed non-pro: send to the paywall, not back to
// onboarding — bouncing a logged-in user to onboarding looks like an
// app restart. billingSummary === null means "unknown" (fetch failed),
// never redirect on unknown.
content = <Redirect href="/profile/billing" />;
} else { } else {
content = ( content = (
<> <>
@@ -182,10 +167,12 @@ function RootLayoutInner() {
}} }}
> >
<Stack.Screen name="onboarding" options={{ animation: 'none' }} /> <Stack.Screen name="onboarding" options={{ animation: 'none' }} />
<Stack.Screen name="onboarding/slides" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/source" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="onboarding/source" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/goal" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="onboarding/goal" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/experience" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="onboarding/experience" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/customize" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="onboarding/customize" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="onboarding/personalizing" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="auth/login" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="auth/login" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="auth/signup" options={{ animation: 'slide_from_right' }} /> <Stack.Screen name="auth/signup" options={{ animation: 'slide_from_right' }} />
<Stack.Screen name="(tabs)" options={{ animation: 'none' }} /> <Stack.Screen name="(tabs)" options={{ animation: 'none' }} />