import React from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Modal,
Animated,
Dimensions,
Switch,
ScrollView,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { router } from 'expo-router';
import {
AppColors,
BorderRadius,
FontSizes,
Spacing,
FontWeights,
Shadows,
} from '@/constants/theme';
const { width: SCREEN_WIDTH } = Dimensions.get('window');
const DRAWER_WIDTH = SCREEN_WIDTH * 0.85;
interface DrawerItemProps {
icon: keyof typeof Ionicons.glyphMap;
label: string;
onPress?: () => void;
rightElement?: React.ReactNode;
danger?: boolean;
badge?: string;
}
function DrawerItem({ icon, label, onPress, rightElement, danger, badge }: DrawerItemProps) {
return (
{label}
{badge && (
{badge}
)}
{rightElement || (onPress && (
))}
);
}
interface ProfileDrawerProps {
visible: boolean;
onClose: () => void;
onLogout: () => void;
settings: {
pushNotifications: boolean;
emailNotifications: boolean;
biometricLogin: boolean;
};
onSettingChange: (key: string, value: boolean) => void;
}
export function ProfileDrawer({
visible,
onClose,
onLogout,
settings,
onSettingChange,
}: ProfileDrawerProps) {
const insets = useSafeAreaInsets();
const slideAnim = React.useRef(new Animated.Value(-DRAWER_WIDTH)).current;
const fadeAnim = React.useRef(new Animated.Value(0)).current;
React.useEffect(() => {
Animated.parallel([
Animated.timing(slideAnim, {
toValue: visible ? 0 : -DRAWER_WIDTH,
duration: 280,
useNativeDriver: true,
}),
Animated.timing(fadeAnim, {
toValue: visible ? 1 : 0,
duration: 280,
useNativeDriver: true,
}),
]).start();
}, [visible]);
const handleNavigate = (route: string) => {
onClose();
router.push(route as any);
};
return (
{/* Header */}
Settings
{/* Quick Settings */}
Preferences
onSettingChange('pushNotifications', v)}
trackColor={{ false: AppColors.border, true: AppColors.primaryLight }}
thumbColor={AppColors.white}
ios_backgroundColor={AppColors.border}
/>
}
/>
onSettingChange('emailNotifications', v)}
trackColor={{ false: AppColors.border, true: AppColors.primaryLight }}
thumbColor={AppColors.white}
ios_backgroundColor={AppColors.border}
/>
}
/>
{/* Account */}
Account
handleNavigate('/(tabs)/profile/language')}
/>
{/* Support */}
Support
handleNavigate('/(tabs)/profile/help')}
/>
handleNavigate('/(tabs)/profile/support')}
/>
handleNavigate('/(tabs)/profile/terms')}
/>
{/* About */}
About
handleNavigate('/(tabs)/profile/about')}
/>
{/* Version */}
WellNuo v1.0.0
);
}
const styles = StyleSheet.create({
overlay: {
flex: 1,
flexDirection: 'row',
},
backdrop: {
...StyleSheet.absoluteFillObject,
backgroundColor: AppColors.overlay,
},
drawer: {
position: 'absolute',
left: 0,
top: 0,
bottom: 0,
width: DRAWER_WIDTH,
backgroundColor: AppColors.background,
...Shadows.xl,
},
drawerContent: {
flex: 1,
},
drawerHeader: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: Spacing.lg,
paddingVertical: Spacing.lg,
borderBottomWidth: 1,
borderBottomColor: AppColors.border,
},
drawerHeaderContent: {
flexDirection: 'row',
alignItems: 'center',
gap: Spacing.md,
},
headerIconContainer: {
width: 40,
height: 40,
borderRadius: BorderRadius.lg,
backgroundColor: AppColors.primaryLighter,
justifyContent: 'center',
alignItems: 'center',
},
drawerTitle: {
fontSize: FontSizes.xl,
fontWeight: FontWeights.bold,
color: AppColors.textPrimary,
},
closeButton: {
width: 36,
height: 36,
borderRadius: BorderRadius.md,
backgroundColor: AppColors.surfaceSecondary,
justifyContent: 'center',
alignItems: 'center',
},
drawerScroll: {
flex: 1,
},
section: {
paddingTop: Spacing.lg,
paddingHorizontal: Spacing.lg,
},
sectionTitle: {
fontSize: FontSizes.xs,
fontWeight: FontWeights.semibold,
color: AppColors.textMuted,
textTransform: 'uppercase',
letterSpacing: 0.5,
marginBottom: Spacing.sm,
marginLeft: Spacing.xs,
},
sectionCard: {
backgroundColor: AppColors.surface,
borderRadius: BorderRadius.xl,
...Shadows.xs,
},
drawerItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: Spacing.md,
paddingHorizontal: Spacing.md,
gap: Spacing.md,
},
drawerItemIcon: {
width: 36,
height: 36,
borderRadius: BorderRadius.md,
backgroundColor: AppColors.surfaceSecondary,
justifyContent: 'center',
alignItems: 'center',
},
dangerIcon: {
backgroundColor: AppColors.errorLight,
},
drawerItemLabel: {
flex: 1,
fontSize: FontSizes.base,
fontWeight: FontWeights.medium,
color: AppColors.textPrimary,
},
dangerText: {
color: AppColors.error,
},
badge: {
backgroundColor: AppColors.primaryLighter,
paddingHorizontal: Spacing.sm,
paddingVertical: 2,
borderRadius: BorderRadius.full,
marginRight: Spacing.xs,
},
badgeText: {
fontSize: FontSizes.xs,
fontWeight: FontWeights.semibold,
color: AppColors.primary,
},
divider: {
height: 1,
backgroundColor: AppColors.borderLight,
marginLeft: 60,
},
logoutSection: {
paddingBottom: Spacing.xl,
},
logoutButton: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: Spacing.sm,
paddingVertical: Spacing.md,
backgroundColor: AppColors.errorLight,
borderRadius: BorderRadius.lg,
},
logoutText: {
fontSize: FontSizes.base,
fontWeight: FontWeights.semibold,
color: AppColors.error,
},
versionContainer: {
paddingVertical: Spacing.md,
alignItems: 'center',
borderTopWidth: 1,
borderTopColor: AppColors.border,
},
versionText: {
fontSize: FontSizes.xs,
color: AppColors.textMuted,
},
});