init
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { View, StyleSheet } from 'react-native';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||
import { Text } from 'react-native';
|
||||
|
||||
import SplashScreen from '../screens/SplashScreen';
|
||||
import OnboardingScreen from '../screens/OnboardingScreen';
|
||||
import LoginScreen from '../screens/LoginScreen';
|
||||
import RegisterScreen from '../screens/RegisterScreen';
|
||||
import CreateIdentityScreen from '../screens/CreateIdentityScreen';
|
||||
import IdentityStoryScreen from '../screens/IdentityStoryScreen';
|
||||
import HabitSelectionScreen from '../screens/HabitSelectionScreen';
|
||||
import HomeScreen from '../screens/HomeScreen';
|
||||
import DailyScreen from '../screens/DailyScreen';
|
||||
import StatsScreen from '../screens/StatsScreen';
|
||||
import MirrorScreen from '../screens/MirrorScreen';
|
||||
import MiniGameScreen from '../screens/MiniGameScreen';
|
||||
import CompletionScreen from '../screens/CompletionScreen';
|
||||
import ProfileScreen from '../screens/ProfileScreen';
|
||||
import DailyJournalScreen from '../screens/DailyJournalScreen';
|
||||
import JournalResultScreen from '../screens/JournalResultScreen';
|
||||
|
||||
import useAuthStore from '../store/useAuthStore';
|
||||
import * as authService from '../services/authService';
|
||||
import { colors } from '../utils/theme';
|
||||
|
||||
const Stack = createNativeStackNavigator();
|
||||
const Tab = createBottomTabNavigator();
|
||||
|
||||
function TabIcon({ label, focused }) {
|
||||
const icons = { Home: '◉', Daily: '◈', Stats: '◎', Profile: '◆' };
|
||||
return (
|
||||
<View style={tabStyles.iconContainer}>
|
||||
<Text numberOfLines={1} style={[tabStyles.label, { color: focused ? colors.primary : colors.textMuted }]}>
|
||||
{label}
|
||||
</Text>
|
||||
<Text style={[tabStyles.icon, { color: focused ? colors.primary : colors.textMuted }]}>
|
||||
{icons[label] || '●'}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const tabStyles = StyleSheet.create({
|
||||
iconContainer: { alignItems: 'center', justifyContent: 'center', paddingTop: 6, width: 70 },
|
||||
label: { fontSize: 9, fontWeight: '600', marginBottom: 3 },
|
||||
icon: { fontSize: 18 },
|
||||
});
|
||||
|
||||
function MainTabs() {
|
||||
return (
|
||||
<Tab.Navigator
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
tabBarStyle: {
|
||||
backgroundColor: colors.surface,
|
||||
borderTopColor: colors.border,
|
||||
borderTopWidth: 1,
|
||||
height: 85,
|
||||
paddingBottom: 24,
|
||||
},
|
||||
tabBarShowLabel: false,
|
||||
}}
|
||||
>
|
||||
<Tab.Screen name="Home" component={HomeScreen}
|
||||
options={{ tabBarIcon: ({ focused }) => <TabIcon label="Home" focused={focused} /> }} />
|
||||
<Tab.Screen name="Daily" component={DailyScreen}
|
||||
options={{ tabBarIcon: ({ focused }) => <TabIcon label="Daily" focused={focused} /> }} />
|
||||
<Tab.Screen name="Stats" component={StatsScreen}
|
||||
options={{ tabBarIcon: ({ focused }) => <TabIcon label="Stats" focused={focused} /> }} />
|
||||
<Tab.Screen name="Profile" component={ProfileScreen}
|
||||
options={{ tabBarIcon: ({ focused }) => <TabIcon label="Profile" focused={focused} /> }} />
|
||||
</Tab.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AppNavigator() {
|
||||
const setSession = useAuthStore((s) => s.setSession);
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
const { data: { subscription } } = authService.onAuthStateChange((_event, session) => {
|
||||
setSession(session);
|
||||
});
|
||||
return () => subscription.unsubscribe();
|
||||
} catch (_) {
|
||||
// Network unavailable — auth listener will be inactive
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<NavigationContainer>
|
||||
<Stack.Navigator
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
contentStyle: { backgroundColor: colors.background },
|
||||
animation: 'fade',
|
||||
}}
|
||||
>
|
||||
{/* Splash is always the entry point — it decides where to go */}
|
||||
<Stack.Screen name="Splash" component={SplashScreen} />
|
||||
<Stack.Screen name="Onboarding" component={OnboardingScreen} />
|
||||
<Stack.Screen name="Login" component={LoginScreen} />
|
||||
<Stack.Screen name="Register" component={RegisterScreen} />
|
||||
<Stack.Screen name="IdentityStory" component={IdentityStoryScreen} />
|
||||
<Stack.Screen name="HabitSelection" component={HabitSelectionScreen} />
|
||||
<Stack.Screen name="CreateIdentity" component={CreateIdentityScreen} />
|
||||
<Stack.Screen name="MainTabs" component={MainTabs} />
|
||||
<Stack.Screen name="MiniGame" component={MiniGameScreen} />
|
||||
<Stack.Screen name="Mirror" component={MirrorScreen} />
|
||||
<Stack.Screen name="DailyJournal" component={DailyJournalScreen} />
|
||||
<Stack.Screen name="JournalResult" component={JournalResultScreen} />
|
||||
<Stack.Screen name="Completion" component={CompletionScreen} />
|
||||
</Stack.Navigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user