/**
* Settings Screen
*
* User settings and app configuration
*/
import { View, Text, StyleSheet, ScrollView, TouchableOpacity, Alert, Switch } from 'react-native';
import { useState, useEffect } from 'react';
import { Ionicons } from '@expo/vector-icons';
import { useAuthStore } from '@/stores';
import { useNotifications, useBiometrics } from '@/hooks';
import { useOfflineStore, syncManager } from '@/services/offline';
interface SettingItemProps {
icon: keyof typeof Ionicons.glyphMap;
title: string;
subtitle?: string;
onPress?: () => void;
trailing?: React.ReactNode;
danger?: boolean;
}
function SettingItem({ icon, title, subtitle, onPress, trailing, danger }: SettingItemProps) {
return (
{title}
{subtitle && {subtitle}}
{trailing || (onPress && )}
);
}
export default function SettingsScreen() {
const { user, token, logout } = useAuthStore();
const [darkMode, setDarkMode] = useState(false);
// Notifications
const {
isPermissionGranted: notificationsGranted,
requestPermission: requestNotificationPermission,
unreadCount,
} = useNotifications();
// Biometrics
const {
isAvailable: biometricsAvailable,
isEnrolled: biometricsEnrolled,
isEnabled: biometricsEnabled,
biometricTypeName,
enableBiometricLogin,
disableBiometricLogin,
isLoading: biometricsLoading,
} = useBiometrics();
// Offline
const { isOnline, syncQueue } = useOfflineStore();
const pendingSyncCount = syncQueue.filter((s) => s.status === 'pending').length;
const handleNotificationsToggle = async (value: boolean) => {
if (value && !notificationsGranted) {
const granted = await requestNotificationPermission();
if (!granted) {
Alert.alert(
'Permisos Requeridos',
'Necesitamos permiso para enviar notificaciones. Por favor, habilítalas en la configuración del dispositivo.'
);
}
}
};
const handleBiometricsToggle = async (value: boolean) => {
if (value) {
if (!biometricsAvailable) {
Alert.alert('No Disponible', 'Tu dispositivo no soporta autenticación biométrica.');
return;
}
if (!biometricsEnrolled) {
Alert.alert('No Configurado', 'No hay datos biométricos registrados en tu dispositivo.');
return;
}
if (token) {
const success = await enableBiometricLogin(token);
if (!success) {
Alert.alert('Error', 'No se pudo habilitar el inicio de sesión biométrico.');
}
}
} else {
await disableBiometricLogin();
}
};
const handleLogout = () => {
Alert.alert(
'Cerrar Sesión',
'¿Estás seguro que deseas cerrar sesión?',
[
{ text: 'Cancelar', style: 'cancel' },
{
text: 'Cerrar Sesión',
style: 'destructive',
onPress: () => logout(),
},
]
);
};
const handleChangePassword = () => {
Alert.alert('Próximamente', 'Esta función estará disponible pronto');
};
const handleHelp = () => {
Alert.alert('Ayuda', 'Contacta soporte en: soporte@erp-generic.com');
};
const handleSyncNow = () => {
if (!isOnline) {
Alert.alert('Sin Conexión', 'No hay conexión a internet para sincronizar.');
return;
}
if (pendingSyncCount === 0) {
Alert.alert('Todo Sincronizado', 'No hay cambios pendientes por sincronizar.');
return;
}
Alert.alert('Sincronizando', `Sincronizando ${pendingSyncCount} cambios...`);
};
return (
{/* Profile Section */}
{user?.fullName?.charAt(0).toUpperCase() || 'U'}
{user?.fullName || 'Usuario'}
{user?.email || 'email@ejemplo.com'}
{/* Account Section */}
Cuenta
{}}
/>
{/* Preferences Section */}
Preferencias
}
/>
}
/>
}
/>
{}}
/>
{}}
/>
{/* Sync Section */}
Sincronización
0 ? `${pendingSyncCount} por sincronizar` : 'Todo sincronizado'}
onPress={handleSyncNow}
/>
{/* Support Section */}
Soporte
{}}
/>
{}}
/>
{/* Logout Section */}
{/* Version */}
ERP Generic Mobile v0.1.0
© 2026 ERP Generic
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8fafc',
},
content: {
padding: 16,
paddingBottom: 32,
},
section: {
marginBottom: 24,
},
sectionTitle: {
fontSize: 13,
fontWeight: '600',
color: '#64748b',
textTransform: 'uppercase',
letterSpacing: 0.5,
marginBottom: 8,
marginLeft: 4,
},
sectionContent: {
backgroundColor: '#ffffff',
borderRadius: 12,
overflow: 'hidden',
},
profileCard: {
backgroundColor: '#ffffff',
borderRadius: 12,
padding: 20,
flexDirection: 'row',
alignItems: 'center',
},
profileAvatar: {
width: 64,
height: 64,
borderRadius: 32,
backgroundColor: '#1e40af',
justifyContent: 'center',
alignItems: 'center',
},
profileInitial: {
fontSize: 24,
fontWeight: '700',
color: '#ffffff',
},
profileInfo: {
marginLeft: 16,
flex: 1,
},
profileName: {
fontSize: 20,
fontWeight: '600',
color: '#1f2937',
},
profileEmail: {
fontSize: 14,
color: '#64748b',
marginTop: 2,
},
settingItem: {
flexDirection: 'row',
alignItems: 'center',
padding: 16,
borderBottomWidth: 1,
borderBottomColor: '#f1f5f9',
},
settingIcon: {
width: 36,
height: 36,
borderRadius: 8,
backgroundColor: '#eff6ff',
justifyContent: 'center',
alignItems: 'center',
marginRight: 12,
},
settingIconDanger: {
backgroundColor: '#fef2f2',
},
settingContent: {
flex: 1,
},
settingTitle: {
fontSize: 16,
color: '#1f2937',
},
settingTitleDanger: {
color: '#dc2626',
},
settingSubtitle: {
fontSize: 13,
color: '#9ca3af',
marginTop: 2,
},
footer: {
alignItems: 'center',
paddingTop: 16,
},
version: {
fontSize: 13,
color: '#9ca3af',
},
copyright: {
fontSize: 12,
color: '#d1d5db',
marginTop: 4,
},
});