erp-core/mobile/app/(auth)/forgot-password.tsx
rckrdmrd 0086695b4c
Some checks failed
ERP Core CI / Backend Lint (push) Has been cancelled
ERP Core CI / Backend Unit Tests (push) Has been cancelled
ERP Core CI / Backend Integration Tests (push) Has been cancelled
ERP Core CI / Frontend Lint (push) Has been cancelled
ERP Core CI / Frontend Unit Tests (push) Has been cancelled
ERP Core CI / Frontend E2E Tests (push) Has been cancelled
ERP Core CI / Database DDL Validation (push) Has been cancelled
ERP Core CI / Backend Build (push) Has been cancelled
ERP Core CI / Frontend Build (push) Has been cancelled
ERP Core CI / CI Success (push) Has been cancelled
Performance Tests / Lighthouse CI (push) Has been cancelled
Performance Tests / Bundle Size Analysis (push) Has been cancelled
Performance Tests / k6 Load Tests (push) Has been cancelled
Performance Tests / Performance Summary (push) Has been cancelled
[SIMCO-V38] feat: Actualizar a SIMCO v3.8.0 + cambios backend
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Actualizaciones en modulos CRM y OpenAPI

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:05 -06:00

211 lines
4.9 KiB
TypeScript

/**
* Forgot Password Screen
*
* Password recovery screen
*/
import { useState } from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
KeyboardAvoidingView,
Platform,
ActivityIndicator,
Alert,
} from 'react-native';
import { router } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
export default function ForgotPasswordScreen() {
const [email, setEmail] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
const handleSubmit = async () => {
if (!email) {
Alert.alert('Error', 'Por favor ingresa tu email');
return;
}
setIsSubmitting(true);
try {
// TODO: Implement password reset API call
// await authApi.requestPasswordReset(email);
// Simulate API call
await new Promise((resolve) => setTimeout(resolve, 1500));
setIsSubmitted(true);
} catch (error: any) {
Alert.alert('Error', error.message || 'No se pudo enviar el email de recuperación');
} finally {
setIsSubmitting(false);
}
};
if (isSubmitted) {
return (
<View style={styles.container}>
<View style={styles.content}>
<View style={styles.successIcon}>
<Ionicons name="mail-outline" size={64} color="#1e40af" />
</View>
<Text style={styles.successTitle}>Revisa tu correo</Text>
<Text style={styles.successText}>
Hemos enviado instrucciones para restablecer tu contraseña a {email}
</Text>
<TouchableOpacity
style={styles.button}
onPress={() => router.back()}
>
<Text style={styles.buttonText}>Volver al inicio de sesión</Text>
</TouchableOpacity>
</View>
</View>
);
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={styles.container}
>
<View style={styles.content}>
{/* Back button */}
<TouchableOpacity style={styles.backButton} onPress={() => router.back()}>
<Ionicons name="arrow-back" size={24} color="#1e40af" />
</TouchableOpacity>
{/* Header */}
<View style={styles.header}>
<Text style={styles.title}>¿Olvidaste tu contraseña?</Text>
<Text style={styles.subtitle}>
Ingresa tu email y te enviaremos instrucciones para restablecerla
</Text>
</View>
{/* Form */}
<View style={styles.form}>
<View style={styles.inputContainer}>
<Text style={styles.label}>Email</Text>
<TextInput
style={styles.input}
placeholder="correo@ejemplo.com"
placeholderTextColor="#9ca3af"
keyboardType="email-address"
autoCapitalize="none"
autoComplete="email"
value={email}
onChangeText={setEmail}
editable={!isSubmitting}
/>
</View>
<TouchableOpacity
style={[styles.button, isSubmitting && styles.buttonDisabled]}
onPress={handleSubmit}
disabled={isSubmitting}
>
{isSubmitting ? (
<ActivityIndicator color="#ffffff" />
) : (
<Text style={styles.buttonText}>Enviar instrucciones</Text>
)}
</TouchableOpacity>
</View>
</View>
</KeyboardAvoidingView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8fafc',
},
content: {
flex: 1,
padding: 24,
justifyContent: 'center',
},
backButton: {
position: 'absolute',
top: 60,
left: 24,
zIndex: 1,
},
header: {
marginBottom: 32,
},
title: {
fontSize: 24,
fontWeight: '700',
color: '#1f2937',
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: '#64748b',
lineHeight: 24,
},
form: {
gap: 16,
},
inputContainer: {
gap: 4,
},
label: {
fontSize: 14,
fontWeight: '500',
color: '#374151',
marginBottom: 4,
},
input: {
backgroundColor: '#ffffff',
borderWidth: 1,
borderColor: '#d1d5db',
borderRadius: 8,
paddingHorizontal: 16,
paddingVertical: 12,
fontSize: 16,
color: '#1f2937',
},
button: {
backgroundColor: '#1e40af',
borderRadius: 8,
paddingVertical: 14,
alignItems: 'center',
marginTop: 8,
},
buttonDisabled: {
backgroundColor: '#93c5fd',
},
buttonText: {
color: '#ffffff',
fontSize: 16,
fontWeight: '600',
},
successIcon: {
alignItems: 'center',
marginBottom: 24,
},
successTitle: {
fontSize: 24,
fontWeight: '700',
color: '#1f2937',
textAlign: 'center',
marginBottom: 12,
},
successText: {
fontSize: 16,
color: '#64748b',
textAlign: 'center',
lineHeight: 24,
marginBottom: 32,
},
});