add tab bar to separate profile and home screens
This commit is contained in:
parent
012d84b369
commit
e51b284181
74
mobile/package-lock.json
generated
74
mobile/package-lock.json
generated
@ -1,14 +1,16 @@
|
||||
{
|
||||
"name": "casadoc-mobile",
|
||||
"version": "1.0.0",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "casadoc-mobile",
|
||||
"version": "1.0.0",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@expo/vector-icons": "^15.0.3",
|
||||
"@react-native-async-storage/async-storage": "2.2.0",
|
||||
"@react-navigation/bottom-tabs": "^7.12.0",
|
||||
"@react-navigation/native": "^7.1.28",
|
||||
"@react-navigation/native-stack": "^7.12.0",
|
||||
"babel-preset-expo": "^54.0.10",
|
||||
@ -1858,6 +1860,17 @@
|
||||
"integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@expo/vector-icons": {
|
||||
"version": "15.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.3.tgz",
|
||||
"integrity": "sha512-SBUyYKphmlfUBqxSfDdJ3jAdEVSALS2VUPOUyqn48oZmb2TL/O7t7/PQm5v4NQujYEPLPMTLn9KVw6H7twwbTA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"expo-font": ">=14.0.4",
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/ws-tunnel": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz",
|
||||
@ -2404,6 +2417,24 @@
|
||||
"integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@react-navigation/bottom-tabs": {
|
||||
"version": "7.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.12.0.tgz",
|
||||
"integrity": "sha512-/GtOfVWRligHG0mvX39I1FGdUWeWl0GVF2okEziQSQj0bOTrLIt7y44C3r/aCLkEpTVltCPGM3swqGTH3UfRCw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@react-navigation/elements": "^2.9.5",
|
||||
"color": "^4.2.3",
|
||||
"sf-symbols-typescript": "^2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-navigation/native": "^7.1.28",
|
||||
"react": ">= 18.2.0",
|
||||
"react-native": "*",
|
||||
"react-native-safe-area-context": ">= 4.0.0",
|
||||
"react-native-screens": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/core": {
|
||||
"version": "7.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.14.0.tgz",
|
||||
@ -3911,6 +3942,20 @@
|
||||
"expo": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-font": {
|
||||
"version": "14.0.11",
|
||||
"resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.11.tgz",
|
||||
"integrity": "sha512-ga0q61ny4s/kr4k8JX9hVH69exVSIfcIc19+qZ7gt71Mqtm7xy2c6kwsPTCyhBW2Ro5yXTT8EaZOpuRi35rHbg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fontfaceobserver": "^2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*",
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-linking": {
|
||||
"version": "8.0.11",
|
||||
"resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-8.0.11.tgz",
|
||||
@ -4156,17 +4201,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/expo/node_modules/@expo/vector-icons": {
|
||||
"version": "15.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.3.tgz",
|
||||
"integrity": "sha512-SBUyYKphmlfUBqxSfDdJ3jAdEVSALS2VUPOUyqn48oZmb2TL/O7t7/PQm5v4NQujYEPLPMTLn9KVw6H7twwbTA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"expo-font": ">=14.0.4",
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo/node_modules/ci-info": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
|
||||
@ -4221,20 +4255,6 @@
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo/node_modules/expo-font": {
|
||||
"version": "14.0.11",
|
||||
"resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.11.tgz",
|
||||
"integrity": "sha512-ga0q61ny4s/kr4k8JX9hVH69exVSIfcIc19+qZ7gt71Mqtm7xy2c6kwsPTCyhBW2Ro5yXTT8EaZOpuRi35rHbg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fontfaceobserver": "^2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*",
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo/node_modules/expo-keep-awake": {
|
||||
"version": "15.0.8",
|
||||
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz",
|
||||
|
||||
@ -11,7 +11,9 @@
|
||||
"web": "expo start --web"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/vector-icons": "^15.0.3",
|
||||
"@react-native-async-storage/async-storage": "2.2.0",
|
||||
"@react-navigation/bottom-tabs": "^7.12.0",
|
||||
"@react-navigation/native": "^7.1.28",
|
||||
"@react-navigation/native-stack": "^7.12.0",
|
||||
"babel-preset-expo": "^54.0.10",
|
||||
|
||||
@ -3,14 +3,15 @@ import { View, ActivityIndicator } from 'react-native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import AuthScreen from '../screens/AuthScreen';
|
||||
import HomeScreen from '../screens/HomeScreen';
|
||||
import TabNavigator from './TabNavigator';
|
||||
import ForgotPasswordScreen from '../screens/ForgotPasswordScreen';
|
||||
import { useAuthStore } from '../store/useAuthStore';
|
||||
|
||||
// Define the types for your stack
|
||||
export type RootStackParamList = {
|
||||
Auth: undefined;
|
||||
ForgotPassword: undefined;
|
||||
Home: undefined;
|
||||
Home: undefined; // This is now a nested navigator
|
||||
Main: undefined; // The tab navigator 'Main'
|
||||
};
|
||||
|
||||
const Stack = createNativeStackNavigator<RootStackParamList>();
|
||||
@ -31,7 +32,7 @@ export default function AppNavigator() {
|
||||
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
||||
{user ? (
|
||||
// Screens for logged-in users
|
||||
<Stack.Screen name="Home" component={HomeScreen} />
|
||||
<Stack.Screen name="Main" component={TabNavigator} options={{ headerShown: false }} />
|
||||
) : (
|
||||
// Screens for logged-out users
|
||||
<Stack.Group>
|
||||
|
||||
59
mobile/src/navigation/TabNavigator.tsx
Normal file
59
mobile/src/navigation/TabNavigator.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||
import { useColorScheme } from 'react-native';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import HomeScreen from '../screens/HomeScreen';
|
||||
import ProfileScreen from '../screens/ProfileScreen';
|
||||
import { COLORS } from '../theme/colors';
|
||||
|
||||
const Tab = createBottomTabNavigator();
|
||||
|
||||
export default function TabNavigator() {
|
||||
const colorScheme = useColorScheme();
|
||||
const isDark = colorScheme === 'dark';
|
||||
const themeColors = isDark ? COLORS.DARK : COLORS.LIGHT;
|
||||
|
||||
return (
|
||||
<Tab.Navigator
|
||||
screenOptions={({ route }) => ({
|
||||
tabBarIcon: ({ focused, color, size }) => {
|
||||
let iconName;
|
||||
|
||||
if (route.name === 'Home') {
|
||||
iconName = focused ? 'home' : 'home-outline';
|
||||
} else if (route.name === 'Profile') {
|
||||
iconName = focused ? 'person' : 'person-outline';
|
||||
}
|
||||
|
||||
return <Ionicons name={iconName as any} size={20} color={color} />;
|
||||
},
|
||||
tabBarActiveTintColor: themeColors.brand,
|
||||
tabBarInactiveTintColor: isDark ? '#a0aec0' : 'gray',
|
||||
tabBarStyle: {
|
||||
backgroundColor: themeColors.card,
|
||||
borderTopColor: isDark ? '#2d3748' : '#e2e8f0',
|
||||
height: 60
|
||||
},
|
||||
headerStyle: {
|
||||
backgroundColor: themeColors.card,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: themeColors.text,
|
||||
fontSize: 17,
|
||||
},
|
||||
})}
|
||||
>
|
||||
<Tab.Screen name="Home" component={HomeScreen} />
|
||||
<Tab.Screen
|
||||
name="Profile"
|
||||
component={ProfileScreen}
|
||||
options={{
|
||||
tabBarItemStyle: {
|
||||
borderLeftWidth: 1.5,
|
||||
borderLeftColor: isDark ? '#4A5568' : '#E2E8F0',
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Tab.Navigator>
|
||||
);
|
||||
}
|
||||
18
mobile/src/screens/ProfileScreen.tsx
Normal file
18
mobile/src/screens/ProfileScreen.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import { View, Text, useColorScheme } from 'react-native';
|
||||
import { getThemeStyles, commonStyles } from '../theme/styles';
|
||||
|
||||
export default function ProfileScreen() {
|
||||
const colorScheme = useColorScheme();
|
||||
const isDark = colorScheme === 'dark';
|
||||
const themeStyles = getThemeStyles(isDark);
|
||||
|
||||
return (
|
||||
<View style={themeStyles.container}>
|
||||
<View style={commonStyles.centered}>
|
||||
<Text style={themeStyles.headerTitle}>Profile Screen</Text>
|
||||
<Text style={themeStyles.subtitle}>User profile details will go here.</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user