Files
MAIA/interfaces/nativeapp/src/screens/LoginScreen.tsx
2025-04-23 20:53:40 +02:00

152 lines
5.0 KiB
TypeScript

// src/screens/LoginScreen.tsx
import React, { useState } from 'react';
import { View, StyleSheet, KeyboardAvoidingView, Platform } from 'react-native';
import { TextInput, Button, Text, useTheme, HelperText, ActivityIndicator, Avatar } from 'react-native-paper';
import { useAuth } from '../contexts/AuthContext';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { AuthStackParamList } from '../types/navigation'; // Import from the new types file
type LoginScreenProps = NativeStackScreenProps<AuthStackParamList, 'Login'>;
const LoginScreen: React.FC<LoginScreenProps> = ({ navigation }) => {
const theme = useTheme();
const { login } = useAuth();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleLogin = async () => {
console.log("[LoginScreen] handleLogin: Button pressed."); // Log: Button Press
if (!username || !password) {
console.log("[LoginScreen] handleLogin: Missing username or password.");
setError('Please enter both username/email and password.');
return;
}
setError(null);
setIsLoading(true);
try {
// --- Add Log Here ---
console.log("[LoginScreen] handleLogin: Calling context login function...");
await login(username, password);
console.log("[LoginScreen] handleLogin: Context login function call finished (likely successful navigation).");
// If successful, this component might unmount before this log appears fully.
} catch (err: any) {
console.log("[LoginScreen] handleLogin: Caught error from context login."); // Log: Error caught
const errorMessage = err.response?.data?.detail ||
err.response?.data?.message ||
err.message ||
'Login failed. Please check your credentials.';
setError(errorMessage);
// **Important**: Set loading false *only in the catch block* if navigation doesn't happen
setIsLoading(false);
console.log("[LoginScreen] handleLogin: Set loading to false after error.");
}
// **Remove potential premature setIsLoading(false) if it was outside the catch block**
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
backgroundColor: theme.colors.background,
},
logoContainer: {
alignItems: 'center',
marginBottom: 40,
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 20,
color: theme.colors.primary,
},
input: {
marginBottom: 15,
},
button: {
marginTop: 10,
paddingVertical: 8, // Make button taller
},
errorText: {
// Use HelperText's styling by setting type='error'
textAlign: 'center',
marginBottom: 10,
},
loadingContainer: {
marginTop: 20,
}
});
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container}
>
<View style={styles.logoContainer}>
<Avatar.Image
size={100}
source={require('../assets/MAIA_ICON.png')}
/>
</View>
<Text style={styles.title}>MAIA Login</Text>
<TextInput
label="Username"
value={username}
onChangeText={setUsername}
mode="outlined"
style={styles.input}
autoCapitalize="none"
disabled={isLoading}
/>
<TextInput
label="Password"
value={password}
onChangeText={setPassword}
mode="outlined"
style={styles.input}
secureTextEntry // Hides password input
disabled={isLoading}
/>
{/* Display Error Message */}
<HelperText type="error" visible={!!error} style={styles.errorText}>
{error}
</HelperText>
{/* Show loading indicator inline with button or replace it */}
{isLoading ? (
<ActivityIndicator animating={true} color={theme.colors.primary} style={styles.loadingContainer}/>
) : (
<>
<Button
mode="contained"
onPress={handleLogin}
style={styles.button}
disabled={isLoading} // Disable button while loading
icon="login"
>
Login
</Button>
{/* Add Register Button */}
<Button
mode="outlined" // Use outlined for secondary action
onPress={() => navigation.navigate('Register')} // Navigate to Register screen
style={styles.button} // Reuse button style or create a new one
disabled={isLoading}
icon="account-plus-outline"
>
Register
</Button>
</>
)}
{/* TODO: Add Register here - REMOVED */}
</KeyboardAvoidingView>
);
};
export default LoginScreen;