frontend first version

This commit is contained in:
Ada
2026-01-20 21:11:04 -08:00
commit 7944b9f7ed
29 changed files with 16468 additions and 0 deletions

View File

@@ -0,0 +1,198 @@
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',
},
});