Mobile App design
Run Tests on Branches / Detect Changes (push) Successful in 10s
Run Tests on Branches / Backend Tests (push) Successful in 2m12s
Run Tests on Branches / Frontend Tests (push) Has been skipped
Run Tests on Branches / Frontend Mobile Tests (push) Successful in 1m47s

This commit is contained in:
Ichitux
2026-07-09 13:33:54 +02:00
parent 5f604b11ba
commit 2f36ef685d
32 changed files with 1793 additions and 926 deletions
+15 -26
View File
@@ -12,7 +12,8 @@ import {
import { useRouter } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
import { useAuthStore } from '../../store/authStore';
import { colors, spacing, borderRadius } from '../../constants/theme';
import { useThemeContext } from '../../components/ThemeProvider';
import { spacing, borderRadius } from '../../constants/theme';
import {
isBiometricsAvailable,
authenticateWithBiometrics,
@@ -23,6 +24,7 @@ import {
export default function LoginScreen() {
const router = useRouter();
const { login } = useAuthStore();
const { colors } = useThemeContext();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [isLoading, setIsLoading] = useState(false);
@@ -55,7 +57,6 @@ export default function LoginScreen() {
setIsLoading(true);
try {
await login(username, password);
// Save username for biometric login
if (biometricsAvailable) {
await saveBiometricCredentials(username);
}
@@ -77,8 +78,6 @@ export default function LoginScreen() {
try {
const authenticated = await authenticateWithBiometrics();
if (authenticated) {
// Use saved username with empty password for biometric login
// The backend should handle biometric authentication differently
await login(biometricUsername, '');
router.replace('/(tabs)');
} else {
@@ -93,17 +92,17 @@ export default function LoginScreen() {
return (
<KeyboardAvoidingView
style={styles.container}
style={[styles.container, { backgroundColor: colors.background }]}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<View style={styles.form}>
<Text style={styles.title}>Iniciar Sesión</Text>
<Text style={styles.subtitle}>Ingresa tus credenciales para continuar</Text>
<Text style={[styles.title, { color: colors.text }]}>Iniciar Sesión</Text>
<Text style={[styles.subtitle, { color: colors.textSecondary }]}>Ingresa tus credenciales para continuar</Text>
<View style={styles.inputContainer}>
<Text style={styles.label}>Usuario</Text>
<Text style={[styles.label, { color: colors.text }]}>Usuario</Text>
<TextInput
style={styles.input}
style={[styles.input, { backgroundColor: colors.card, color: colors.text }]}
value={username}
onChangeText={setUsername}
placeholder="Tu usuario"
@@ -114,9 +113,9 @@ export default function LoginScreen() {
</View>
<View style={styles.inputContainer}>
<Text style={styles.label}>Contraseña</Text>
<Text style={[styles.label, { color: colors.text }]}>Contraseña</Text>
<TextInput
style={styles.input}
style={[styles.input, { backgroundColor: colors.card, color: colors.text }]}
value={password}
onChangeText={setPassword}
placeholder="Tu contraseña"
@@ -137,12 +136,12 @@ export default function LoginScreen() {
{biometricsAvailable && biometricUsername && (
<TouchableOpacity
style={[styles.biometricButton, isLoading && styles.buttonDisabled]}
style={[styles.biometricButton, { backgroundColor: colors.card, borderColor: colors.primary }]}
onPress={handleBiometricLogin}
disabled={isLoading}
>
<Ionicons name="finger-print" size={24} color={colors.primary} />
<Text style={styles.biometricText}>Iniciar con biometría</Text>
<Text style={[styles.biometricText, { color: colors.primary }]}>Iniciar con biometría</Text>
</TouchableOpacity>
)}
@@ -150,7 +149,7 @@ export default function LoginScreen() {
style={styles.linkButton}
onPress={() => router.push('/auth/register')}
>
<Text style={styles.linkText}>¿No tienes cuenta? Regístrate</Text>
<Text style={[styles.linkText, { color: colors.primary }]}>¿No tienes cuenta? Regístrate</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
@@ -160,7 +159,6 @@ export default function LoginScreen() {
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.background,
},
form: {
flex: 1,
@@ -170,12 +168,10 @@ const styles = StyleSheet.create({
title: {
fontSize: 28,
fontWeight: 'bold',
color: colors.text,
marginBottom: spacing.sm,
},
subtitle: {
fontSize: 16,
color: colors.textSecondary,
marginBottom: spacing.xl,
},
inputContainer: {
@@ -184,18 +180,15 @@ const styles = StyleSheet.create({
label: {
fontSize: 14,
fontWeight: '500',
color: colors.text,
marginBottom: spacing.xs,
},
input: {
backgroundColor: colors.card,
borderRadius: borderRadius.md,
padding: spacing.md,
fontSize: 16,
color: colors.text,
},
button: {
backgroundColor: colors.primary,
backgroundColor: '#7fbf8f',
borderRadius: borderRadius.md,
padding: spacing.md,
alignItems: 'center',
@@ -205,7 +198,7 @@ const styles = StyleSheet.create({
opacity: 0.6,
},
buttonText: {
color: colors.textInverse,
color: '#ffffff',
fontSize: 16,
fontWeight: '600',
},
@@ -214,22 +207,18 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
linkText: {
color: colors.primary,
fontSize: 14,
},
biometricButton: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: colors.card,
borderRadius: borderRadius.md,
padding: spacing.md,
marginTop: spacing.md,
borderWidth: 1,
borderColor: colors.primary,
},
biometricText: {
color: colors.primary,
fontSize: 16,
fontWeight: '600',
marginLeft: spacing.sm,
+15 -20
View File
@@ -11,10 +11,12 @@ import {
} from 'react-native';
import { useRouter } from 'expo-router';
import { register } from '../../services/auth';
import { colors, spacing, borderRadius } from '../../constants/theme';
import { useThemeContext } from '../../components/ThemeProvider';
import { spacing, borderRadius } from '../../constants/theme';
export default function RegisterScreen() {
const router = useRouter();
const { colors } = useThemeContext();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
@@ -44,17 +46,17 @@ export default function RegisterScreen() {
return (
<KeyboardAvoidingView
style={styles.container}
style={[styles.container, { backgroundColor: colors.background }]}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<View style={styles.form}>
<Text style={styles.title}>Crear Cuenta</Text>
<Text style={styles.subtitle}>Regístrate para empezar</Text>
<Text style={[styles.title, { color: colors.text }]}>Crear Cuenta</Text>
<Text style={[styles.subtitle, { color: colors.textSecondary }]}>Regístrate para empezar</Text>
<View style={styles.inputContainer}>
<Text style={styles.label}>Usuario</Text>
<Text style={[styles.label, { color: colors.text }]}>Usuario</Text>
<TextInput
style={styles.input}
style={[styles.input, { backgroundColor: colors.card, color: colors.text }]}
value={username}
onChangeText={setUsername}
placeholder="Elige un usuario"
@@ -65,9 +67,9 @@ export default function RegisterScreen() {
</View>
<View style={styles.inputContainer}>
<Text style={styles.label}>Contraseña</Text>
<Text style={[styles.label, { color: colors.text }]}>Contraseña</Text>
<TextInput
style={styles.input}
style={[styles.input, { backgroundColor: colors.card, color: colors.text }]}
value={password}
onChangeText={setPassword}
placeholder="Elige una contraseña"
@@ -77,9 +79,9 @@ export default function RegisterScreen() {
</View>
<View style={styles.inputContainer}>
<Text style={styles.label}>Confirmar Contraseña</Text>
<Text style={[styles.label, { color: colors.text }]}>Confirmar Contraseña</Text>
<TextInput
style={styles.input}
style={[styles.input, { backgroundColor: colors.card, color: colors.text }]}
value={confirmPassword}
onChangeText={setConfirmPassword}
placeholder="Repite la contraseña"
@@ -102,7 +104,7 @@ export default function RegisterScreen() {
style={styles.linkButton}
onPress={() => router.back()}
>
<Text style={styles.linkText}>¿Ya tienes cuenta? Inicia sesión</Text>
<Text style={[styles.linkText, { color: colors.primary }]}>¿Ya tienes cuenta? Inicia sesión</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
@@ -112,7 +114,6 @@ export default function RegisterScreen() {
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.background,
},
form: {
flex: 1,
@@ -122,12 +123,10 @@ const styles = StyleSheet.create({
title: {
fontSize: 28,
fontWeight: 'bold',
color: colors.text,
marginBottom: spacing.sm,
},
subtitle: {
fontSize: 16,
color: colors.textSecondary,
marginBottom: spacing.xl,
},
inputContainer: {
@@ -136,18 +135,15 @@ const styles = StyleSheet.create({
label: {
fontSize: 14,
fontWeight: '500',
color: colors.text,
marginBottom: spacing.xs,
},
input: {
backgroundColor: colors.card,
borderRadius: borderRadius.md,
padding: spacing.md,
fontSize: 16,
color: colors.text,
},
button: {
backgroundColor: colors.primary,
backgroundColor: '#7fbf8f',
borderRadius: borderRadius.md,
padding: spacing.md,
alignItems: 'center',
@@ -157,7 +153,7 @@ const styles = StyleSheet.create({
opacity: 0.6,
},
buttonText: {
color: colors.textInverse,
color: '#ffffff',
fontSize: 16,
fontWeight: '600',
},
@@ -166,7 +162,6 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
linkText: {
color: colors.primary,
fontSize: 14,
},
});