native_convex_CRM/app/navigation/customDrawerContent.tsx
2026-07-24 13:15:31 +05:30

182 lines
5.6 KiB
TypeScript

import React from 'react';
import {
Text,
View,
TouchableOpacity,
ScrollView,
Image,
} from 'react-native';
import { DrawerContentComponentProps } from '@react-navigation/drawer';
import Icon from 'react-native-vector-icons/Ionicons';
import { menuItems } from '@mock-data';
import { useTheme } from '@theme';
import { DrawerItemProps } from '@interfaces';
import { route } from '@utils';
import { getStyles } from './customDrawerContent.style';
import { useAppDispatch, useAppSelector, logout, RootState } from '@store';
const DrawerItem = ({ label, iconName, focused, onPress }: DrawerItemProps) => {
const { theme: colors } = useTheme();
const styles = getStyles(colors);
return (
<TouchableOpacity
style={[styles.itemWrapper, focused && styles.itemWrapperActive]}
activeOpacity={0.7}
onPress={onPress}>
{focused && <View style={styles.activeIndicatorBar} />}
<Icon
name={iconName}
size={20}
color={focused ? colors.icon : colors.textSecondary}
style={styles.itemIcon}
/>
<Text style={[styles.itemLabel, focused && styles.itemLabelActive]}>
{label}
</Text>
</TouchableOpacity>
);
};
export const CustomDrawerContent = (props: DrawerContentComponentProps) => {
const { state, navigation } = props;
const { theme: colors } = useTheme();
const styles = getStyles(colors);
const dispatch = useAppDispatch();
const userData = useAppSelector((state: RootState) => state.auth.user_data);
const handleLogout = async () => {
try {
dispatch(logout());
} catch (e) {
console.error(e);
}
navigation.reset({
index: 0,
routes: [{ name: 'AuthStack' }],
});
};
const activeRouteName = state.routeNames[state.index];
// User details
const fullName =
userData?.full_name ||
`${userData?.firstname || ''} ${userData?.lastname || ''}`.trim() ||
'User';
const email = userData?.email || 'N/A';
const isAdmin = userData?.admin === '1';
const roleText = isAdmin ? 'Administrator' : 'Staff Member';
const isActive = userData?.active === '1';
const hasProfileImage =
userData?.profile_image && userData.profile_image.startsWith('http');
const initials =
fullName
.split(' ')
.filter(Boolean)
.map(n => n[0])
.join('')
.substring(0, 2)
.toUpperCase() || 'U';
return (
<View style={styles.container}>
{/* ── Drawer Header (User Profile) ── */}
<View style={styles.headerContainer}>
<TouchableOpacity
style={styles.userHeaderTouchable}
activeOpacity={0.8}
onPress={() => navigation.navigate('home', { screen: route.profile })}>
<View style={styles.avatarWrapper}>
{hasProfileImage ? (
<Image
source={{ uri: userData!.profile_image }}
style={styles.avatarImage}
/>
) : (
<View style={styles.avatarCircle}>
<Text style={styles.avatarInitial}>{initials}</Text>
</View>
)}
{isActive && <View style={styles.onlineDot} />}
</View>
<View style={styles.headerDetails}>
<Text style={styles.userName} numberOfLines={1}>
{fullName}
</Text>
<Text style={styles.userEmail} numberOfLines={1}>
{email}
</Text>
<View style={styles.roleBadge}>
<Text style={styles.roleBadgeText}>{roleText}</Text>
</View>
</View>
<Icon name="chevron-forward" size={18} color="#94A3B8" />
</TouchableOpacity>
</View>
{/* ── Navigation Menu List ── */}
<ScrollView contentContainerStyle={styles.scrollContent}>
<View style={styles.menuContainer}>
{menuItems.map(item => {
// Find currently active nested tab route
let activeTabName = '';
try {
let currentRoute = state.routes[state.index];
if (currentRoute.name === 'home' && currentRoute.state) {
const nestedIndex = currentRoute.state.index ?? 0;
activeTabName = currentRoute.state.routes[nestedIndex].name;
} else {
activeTabName = currentRoute.name;
}
} catch (e) {
activeTabName = '';
}
const isFocused =
(item.route === 'home' && activeTabName === route.dashboard) ||
(item.route !== 'home' && activeTabName === item.route);
return (
<DrawerItem
key={item.route}
label={item.label}
iconName={item.icon}
focused={isFocused}
onPress={() => {
if (item.route === 'home') {
navigation.navigate('home', { screen: route.dashboard });
} else {
navigation.navigate('home', { screen: item.route });
}
}}
/>
);
})}
</View>
</ScrollView>
{/* ── Drawer Footer (Logout) ── */}
<View style={styles.footer}>
<TouchableOpacity
style={styles.logoutButton}
activeOpacity={0.7}
onPress={handleLogout}>
<Icon
name="log-out-outline"
size={20}
color="#EF4444"
style={styles.logoutIcon}
/>
<Text style={styles.logoutText}>Sign Out</Text>
</TouchableOpacity>
</View>
</View>
);
};