120 lines
3.0 KiB
TypeScript
120 lines
3.0 KiB
TypeScript
import { useNavigation, useRoute } from '@react-navigation/native';
|
|
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
|
import React, { useCallback, useMemo } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import {
|
|
Dimensions,
|
|
StyleSheet,
|
|
Text,
|
|
TouchableOpacity,
|
|
View,
|
|
} from 'react-native';
|
|
|
|
import HomeIcon from 'svg/HomeIcon';
|
|
import Passport from 'svg/Passport';
|
|
import StatusIcon from 'svg/StatusIcon';
|
|
import User from 'svg/User';
|
|
import Wallet from 'svg/Wallet';
|
|
|
|
const { width } = Dimensions.get('window');
|
|
const isSmallScreen = width < 360;
|
|
|
|
type RouteName = 'Home' | 'Status' | 'Passports' | 'Wallet' | 'Profile';
|
|
|
|
const Navigation = () => {
|
|
const navigation = useNavigation<NativeStackNavigationProp<any>>();
|
|
const route = useRoute();
|
|
const { t } = useTranslation();
|
|
const links = useMemo(
|
|
() => [
|
|
{ label: 'Asosiy', icon: HomeIcon, route: 'Home' as RouteName },
|
|
{ label: 'Status', icon: StatusIcon, route: 'Status' as RouteName },
|
|
{ label: 'Passportlar', icon: Passport, route: 'Passports' as RouteName },
|
|
{ label: "To'lov", icon: Wallet, route: 'Wallet' as RouteName },
|
|
{ label: 'Profil', icon: User, route: 'Profile' as RouteName },
|
|
],
|
|
[],
|
|
);
|
|
|
|
const handleNavigation = useCallback(
|
|
(routeName: RouteName) => {
|
|
if (route.name === routeName) return;
|
|
|
|
navigation.replace(routeName);
|
|
},
|
|
[navigation, route.name],
|
|
);
|
|
|
|
const containerStyle = useMemo(() => [styles.container], []);
|
|
|
|
const renderNavItem = useCallback(
|
|
({ label, icon: Icon, route: routeName }: any) => {
|
|
const isActive = route.name === routeName;
|
|
const color = isActive ? '#28A7E8' : '#6C6C6C';
|
|
|
|
const iconSize = isSmallScreen ? 24 : 35;
|
|
const fontSize = isSmallScreen ? 10 : 10;
|
|
|
|
return (
|
|
<TouchableOpacity
|
|
key={routeName}
|
|
style={styles.links}
|
|
onPress={() => handleNavigation(routeName)}
|
|
activeOpacity={0.7}
|
|
>
|
|
<Icon color={color} width={iconSize} height={iconSize} />
|
|
<Text
|
|
style={{
|
|
color,
|
|
fontWeight: '500',
|
|
fontSize,
|
|
}}
|
|
>
|
|
{t(label)}
|
|
</Text>
|
|
</TouchableOpacity>
|
|
);
|
|
},
|
|
[route.name, handleNavigation, t],
|
|
);
|
|
|
|
const navItems = useMemo(
|
|
() => links.map(renderNavItem),
|
|
[links, renderNavItem],
|
|
);
|
|
|
|
return (
|
|
<View style={styles.wrapper}>
|
|
<View style={containerStyle}>{navItems}</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
wrapper: {
|
|
bottom: 0,
|
|
width: '100%',
|
|
height: 60,
|
|
},
|
|
container: {
|
|
height: '100%',
|
|
backgroundColor: '#fff',
|
|
borderTopLeftRadius: 30,
|
|
borderTopRightRadius: 30,
|
|
flexDirection: 'row',
|
|
shadowColor: '#000',
|
|
shadowOpacity: 0.1,
|
|
justifyContent: 'space-around',
|
|
shadowOffset: { width: 0, height: -2 },
|
|
shadowRadius: 10,
|
|
elevation: 10,
|
|
width: '100%',
|
|
},
|
|
links: {
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
});
|
|
|
|
export default Navigation;
|