199 lines
5.1 KiB
TypeScript
199 lines
5.1 KiB
TypeScript
import React from 'react';
|
|
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
|
import { View, Text, StyleSheet } from 'react-native';
|
|
import { Feather, MaterialCommunityIcons, FontAwesome5 } from '@expo/vector-icons';
|
|
import { colors, borderRadius, typography } from '../theme/colors';
|
|
|
|
// Screens
|
|
import FlowScreen from '../screens/FlowScreen';
|
|
import VaultScreen from '../screens/VaultScreen';
|
|
import SentinelScreen from '../screens/SentinelScreen';
|
|
import HeritageScreen from '../screens/HeritageScreen';
|
|
import MeScreen from '../screens/MeScreen';
|
|
|
|
const Tab = createBottomTabNavigator();
|
|
|
|
// Custom Tab Bar Button with icon on top and label below
|
|
const TabBarItem = ({
|
|
name,
|
|
label,
|
|
focused,
|
|
color,
|
|
isDark = false
|
|
}: {
|
|
name: string;
|
|
label: string;
|
|
focused: boolean;
|
|
color: string;
|
|
isDark?: boolean;
|
|
}) => {
|
|
const iconSize = 22;
|
|
|
|
const renderIcon = () => {
|
|
switch (name) {
|
|
case 'Flow':
|
|
return <FontAwesome5 name="scroll" size={iconSize - 2} color={color} />;
|
|
case 'Vault':
|
|
return <MaterialCommunityIcons name="treasure-chest" size={iconSize} color={color} />;
|
|
case 'Sentinel':
|
|
return <FontAwesome5 name="anchor" size={iconSize - 2} color={color} />;
|
|
case 'Heritage':
|
|
return <MaterialCommunityIcons name="compass-outline" size={iconSize} color={color} />;
|
|
case 'Me':
|
|
return <MaterialCommunityIcons name="ship-wheel" size={iconSize} color={color} />;
|
|
default:
|
|
return <Feather name="circle" size={iconSize} color={color} />;
|
|
}
|
|
};
|
|
|
|
const bgColor = focused
|
|
? (isDark ? 'rgba(184, 224, 229, 0.12)' : colors.nautical.lightMint)
|
|
: 'transparent';
|
|
|
|
return (
|
|
<View style={[styles.tabItem, { backgroundColor: bgColor }]}>
|
|
<View style={styles.iconWrapper}>
|
|
{renderIcon()}
|
|
</View>
|
|
<Text style={[
|
|
styles.tabLabel,
|
|
{ color },
|
|
focused && styles.tabLabelActive
|
|
]}>
|
|
{label}
|
|
</Text>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default function TabNavigator() {
|
|
return (
|
|
<Tab.Navigator
|
|
screenOptions={{
|
|
headerShown: false,
|
|
tabBarShowLabel: false,
|
|
tabBarStyle: styles.tabBar,
|
|
}}
|
|
>
|
|
<Tab.Screen
|
|
name="Flow"
|
|
component={FlowScreen}
|
|
options={{
|
|
tabBarIcon: ({ focused }) => (
|
|
<TabBarItem
|
|
name="Flow"
|
|
label="Flow"
|
|
focused={focused}
|
|
color={focused ? colors.flow.primary : colors.nautical.sage}
|
|
/>
|
|
),
|
|
}}
|
|
/>
|
|
<Tab.Screen
|
|
name="Vault"
|
|
component={VaultScreen}
|
|
options={{
|
|
tabBarIcon: ({ focused }) => (
|
|
<TabBarItem
|
|
name="Vault"
|
|
label="Vault"
|
|
focused={focused}
|
|
color={focused ? colors.vault.primary : colors.vault.textSecondary}
|
|
isDark
|
|
/>
|
|
),
|
|
tabBarStyle: styles.tabBarDark,
|
|
}}
|
|
/>
|
|
<Tab.Screen
|
|
name="Sentinel"
|
|
component={SentinelScreen}
|
|
options={{
|
|
tabBarIcon: ({ focused }) => (
|
|
<TabBarItem
|
|
name="Sentinel"
|
|
label="Sentinel"
|
|
focused={focused}
|
|
color={focused ? colors.sentinel.primary : colors.sentinel.textSecondary}
|
|
isDark
|
|
/>
|
|
),
|
|
tabBarStyle: styles.tabBarDark,
|
|
}}
|
|
/>
|
|
<Tab.Screen
|
|
name="Heritage"
|
|
component={HeritageScreen}
|
|
options={{
|
|
tabBarIcon: ({ focused }) => (
|
|
<TabBarItem
|
|
name="Heritage"
|
|
label="Heritage"
|
|
focused={focused}
|
|
color={focused ? colors.heritage.primary : colors.nautical.sage}
|
|
/>
|
|
),
|
|
}}
|
|
/>
|
|
<Tab.Screen
|
|
name="Me"
|
|
component={MeScreen}
|
|
options={{
|
|
tabBarIcon: ({ focused }) => (
|
|
<TabBarItem
|
|
name="Me"
|
|
label="Me"
|
|
focused={focused}
|
|
color={focused ? colors.me.primary : colors.nautical.sage}
|
|
/>
|
|
),
|
|
}}
|
|
/>
|
|
</Tab.Navigator>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
tabBar: {
|
|
backgroundColor: colors.nautical.cream,
|
|
borderTopWidth: 0,
|
|
height: 80,
|
|
paddingHorizontal: 4,
|
|
shadowColor: colors.nautical.navy,
|
|
shadowOffset: { width: 0, height: -6 },
|
|
shadowOpacity: 0.06,
|
|
shadowRadius: 16,
|
|
elevation: 12,
|
|
},
|
|
tabBarDark: {
|
|
backgroundColor: colors.nautical.navy,
|
|
borderTopWidth: 0,
|
|
height: 80,
|
|
paddingHorizontal: 4,
|
|
shadowColor: '#000',
|
|
shadowOffset: { width: 0, height: -4 },
|
|
shadowOpacity: 0.15,
|
|
shadowRadius: 12,
|
|
elevation: 12,
|
|
},
|
|
tabItem: {
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
paddingVertical: 8,
|
|
paddingHorizontal: 16,
|
|
borderRadius: borderRadius.lg,
|
|
minWidth: 64,
|
|
},
|
|
iconWrapper: {
|
|
marginBottom: 4,
|
|
},
|
|
tabLabel: {
|
|
fontSize: 10,
|
|
fontWeight: '500',
|
|
letterSpacing: 0.3,
|
|
},
|
|
tabLabelActive: {
|
|
fontWeight: '700',
|
|
},
|
|
});
|