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, Colors, FontSizes, Spacing, FontWeights, } from '@/constants/theme'; import { useTheme, type ThemeMode } from '@/contexts/ThemeContext'; 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 & { colors?: typeof Colors.light }) { const { resolvedTheme } = useTheme(); const colors = Colors[resolvedTheme]; return ( {label} {badge && ( {badge} )} {rightElement || (onPress && ( ))} ); } // Theme mode selector component function ThemeModeSelector() { const { themeMode, setThemeMode, resolvedTheme } = useTheme(); const colors = Colors[resolvedTheme]; const options: { mode: ThemeMode; icon: keyof typeof Ionicons.glyphMap; label: string }[] = [ { mode: 'light', icon: 'sunny-outline', label: 'Light' }, { mode: 'dark', icon: 'moon-outline', label: 'Dark' }, { mode: 'system', icon: 'phone-portrait-outline', label: 'System' }, ]; return ( {options.map((option) => ( setThemeMode(option.mode)} activeOpacity={0.7} > {option.label} ))} ); } 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; const { resolvedTheme } = useTheme(); const colors = Colors[resolvedTheme]; React.useEffect(() => { Animated.parallel([ Animated.timing(slideAnim, { toValue: visible ? 0 : -DRAWER_WIDTH, duration: 250, useNativeDriver: true, }), Animated.timing(fadeAnim, { toValue: visible ? 1 : 0, duration: 250, useNativeDriver: true, }), ]).start(); }, [visible]); const handleNavigate = (route: string) => { onClose(); router.push(route as any); }; return ( {/* Header */} Settings {/* Appearance */} Appearance Theme {/* Preferences */} Preferences onSettingChange('pushNotifications', v)} trackColor={{ false: colors.border, true: colors.primary }} thumbColor="#FFFFFF" ios_backgroundColor={colors.border} /> } /> onSettingChange('emailNotifications', v)} trackColor={{ false: colors.border, true: colors.primary }} thumbColor="#FFFFFF" ios_backgroundColor={colors.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: 'rgba(0,0,0,0.4)', }, drawer: { position: 'absolute', left: 0, top: 0, bottom: 0, width: DRAWER_WIDTH, shadowColor: '#000', shadowOffset: { width: 2, height: 0 }, shadowOpacity: 0.15, shadowRadius: 12, elevation: 8, }, themeModeWrapper: { paddingHorizontal: Spacing.lg, paddingBottom: Spacing.md, }, themeModeContainer: { flexDirection: 'row', borderRadius: BorderRadius.lg, padding: Spacing.xs, }, themeModeButton: { flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: Spacing.sm, paddingHorizontal: Spacing.sm, borderRadius: BorderRadius.md, gap: Spacing.xs, }, themeModeButtonActive: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 2, }, themeModeLabel: { fontSize: FontSizes.sm, fontWeight: FontWeights.medium, }, themeModeLabelActive: { color: '#FFFFFF', }, drawerContent: { flex: 1, }, drawerHeader: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: Spacing.lg, paddingBottom: Spacing.lg, borderBottomWidth: 1, borderBottomColor: AppColors.border, }, drawerTitle: { fontSize: FontSizes.xl, fontWeight: FontWeights.bold, color: AppColors.textPrimary, }, closeButton: { width: 40, height: 40, borderRadius: BorderRadius.md, backgroundColor: AppColors.surfaceSecondary, justifyContent: 'center', alignItems: 'center', }, drawerScroll: { flex: 1, }, section: { paddingTop: Spacing.lg, }, sectionTitle: { fontSize: FontSizes.xs, fontWeight: FontWeights.semibold, color: AppColors.textMuted, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: Spacing.sm, marginLeft: Spacing.lg, }, drawerItem: { flexDirection: 'row', alignItems: 'center', paddingVertical: Spacing.md, paddingHorizontal: Spacing.lg, borderBottomWidth: 1, borderBottomColor: AppColors.border, }, iconContainer: { width: 40, height: 40, borderRadius: BorderRadius.md, backgroundColor: AppColors.surfaceSecondary, justifyContent: 'center', alignItems: 'center', marginRight: Spacing.md, }, iconContainerDanger: { backgroundColor: AppColors.errorLight, }, drawerItemLabel: { flex: 1, fontSize: FontSizes.base, fontWeight: FontWeights.medium, color: AppColors.textPrimary, }, dangerText: { color: AppColors.error, }, badgeText: { fontSize: FontSizes.sm, fontWeight: FontWeights.medium, color: AppColors.textMuted, marginRight: Spacing.sm, }, versionContainer: { paddingVertical: Spacing.lg, alignItems: 'center', borderTopWidth: 1, borderTopColor: AppColors.border, }, versionText: { fontSize: FontSizes.sm, color: AppColors.textMuted, }, });