119 lines
3.7 KiB
TypeScript
119 lines
3.7 KiB
TypeScript
// src/components/WebSidebar.tsx
|
|
import React from 'react';
|
|
import { View, StyleSheet, Pressable } from 'react-native';
|
|
import { Text, useTheme, Icon } from 'react-native-paper';
|
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
import { NavigationContainerRef } from '@react-navigation/native'; // Import ref type
|
|
import { RootStackParamList } from '../types/navigation'; // Import stack param list
|
|
|
|
// Define Props including the navigation ref
|
|
interface WebSidebarProps {
|
|
navigationRef: React.RefObject<NavigationContainerRef<RootStackParamList>>;
|
|
currentRouteName?: string; // To highlight the active item
|
|
}
|
|
|
|
// Define navigation items
|
|
const navItems = [
|
|
{ name: 'Dashboard', icon: 'view-dashboard', label: 'Dashboard' },
|
|
{ name: 'Chat', icon: 'chat', label: 'Chat' },
|
|
{ name: 'Calendar', icon: 'calendar', label: 'Calendar' },
|
|
{ name: 'Profile', icon: 'account-circle', label: 'Profile' },
|
|
] as const; // Use 'as const' for stricter typing of names
|
|
|
|
const WebSidebar = ({ navigationRef, currentRouteName }: WebSidebarProps) => {
|
|
const theme = useTheme();
|
|
|
|
const handleNavigate = (screenName: keyof RootStackParamList) => {
|
|
// Use the ref to navigate
|
|
if (navigationRef.current) {
|
|
navigationRef.current.navigate(screenName);
|
|
}
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
width: 240, // Fixed width for the sidebar
|
|
height: '100%',
|
|
backgroundColor: theme.colors.surface, // Sidebar background
|
|
paddingTop: 40, // Space from top
|
|
paddingHorizontal: 10,
|
|
borderRightWidth: 1,
|
|
borderRightColor: theme.colors.background, // Subtle border
|
|
},
|
|
logoArea: {
|
|
marginBottom: 30,
|
|
alignItems: 'center',
|
|
// Add your logo image here if desired
|
|
// <Image source={require('../assets/icon.png')} style={styles.logo} />
|
|
},
|
|
logoText: {
|
|
fontSize: 24,
|
|
fontWeight: 'bold',
|
|
color: theme.colors.primary, // Use primary color for logo text
|
|
},
|
|
navItem: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
paddingVertical: 12,
|
|
paddingHorizontal: 16,
|
|
borderRadius: theme.roundness,
|
|
marginBottom: 8,
|
|
},
|
|
activeNavItem: {
|
|
backgroundColor: theme.colors.primary, // Highlight active item background
|
|
},
|
|
icon: {
|
|
marginRight: 16,
|
|
},
|
|
label: {
|
|
fontSize: 16,
|
|
fontWeight: '500',
|
|
},
|
|
activeLabel: {
|
|
color: theme.colors.onPrimary, // Text color on primary background
|
|
},
|
|
inactiveLabel: {
|
|
color: theme.colors.textSecondary, // Text color for inactive items
|
|
},
|
|
});
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<View style={styles.logoArea}>
|
|
{/* Placeholder Logo Text */}
|
|
<Text style={styles.logoText}>MAIA</Text>
|
|
</View>
|
|
|
|
{navItems.map((item) => {
|
|
const isActive = currentRouteName === item.name;
|
|
return (
|
|
<Pressable
|
|
key={item.name}
|
|
onPress={() => handleNavigate(item.name)}
|
|
style={[
|
|
styles.navItem,
|
|
isActive && styles.activeNavItem, // Apply active style conditionally
|
|
]}
|
|
>
|
|
<MaterialCommunityIcons
|
|
name={item.icon}
|
|
size={24}
|
|
color={isActive ? theme.colors.onPrimary : theme.colors.textSecondary}
|
|
style={styles.icon}
|
|
/>
|
|
<Text
|
|
style={[
|
|
styles.label,
|
|
isActive ? styles.activeLabel : styles.inactiveLabel
|
|
]}
|
|
>
|
|
{item.label}
|
|
</Text>
|
|
</Pressable>
|
|
);
|
|
})}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default WebSidebar; |