Replace KeyboardAvoidingView with KeyboardAwareScrollView, update dependencies, and handle login 401 error logging

This commit is contained in:
2026-05-13 09:44:58 +02:00
parent e8e76cdf8b
commit 26a4d0144c
4 changed files with 1356 additions and 1278 deletions

View File

@@ -3,8 +3,8 @@ import api from '@/utils/api';
import { AuthContext } from '@/utils/authContext'; import { AuthContext } from '@/utils/authContext';
import { Eye, EyeOff, Lock, LogIn, Mail } from 'lucide-react-native'; import { Eye, EyeOff, Lock, LogIn, Mail } from 'lucide-react-native';
import React, { useContext, useState } from 'react'; import React, { useContext, useState } from 'react';
import { Image, Platform, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native'; import { Image, Platform, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { KeyboardAvoidingView } from 'react-native-keyboard-controller'; import { KeyboardAwareScrollView } from 'react-native-keyboard-controller';
export default function LoginScreen() { export default function LoginScreen() {
const alert = useAlert(); const alert = useAlert();
@@ -40,19 +40,21 @@ export default function LoginScreen() {
// Pass token and user data to the context which will handle saving and redirect // Pass token and user data to the context which will handle saving and redirect
authContext.logIn(token, user); authContext.logIn(token, user);
} catch (error: any) { } catch (error: any) {
console.error("Login Error:", error);
let message = "Si è verificato un errore durante l'accesso."; let message = "Si è verificato un errore durante l'accesso.";
if (error.response) { if (error.response) {
// Server error (e.g., 401 Invalid credentials)
if (error.response.status === 401) { if (error.response.status === 401) {
message = "Credenziali non valide." message = "Credenziali non valide."
} else { } else {
console.error("Login Error:", error);
message = `Errore Server: ${error.response.data.message || error.response.status}`; message = `Errore Server: ${error.response.data.message || error.response.status}`;
} }
} else if (error.request) { } else if (error.request) {
// Server not reachable // Server not reachable
console.error("Login Error:", error);
message = "Impossibile contattare il server. Controlla la connessione."; message = "Impossibile contattare il server. Controlla la connessione.";
} else {
console.error("Login Error:", error);
} }
alert.showAlert('error', "Login Fallito", message); alert.showAlert('error', "Login Fallito", message);
@@ -74,12 +76,13 @@ export default function LoginScreen() {
{/* Form Container */} {/* Form Container */}
<View className="flex-1 bg-white rounded-t-[2.5rem] px-8 pt-10 shadow-xl w-full"> <View className="flex-1 bg-white rounded-t-[2.5rem] px-8 pt-10 shadow-xl w-full">
<KeyboardAvoidingView <KeyboardAwareScrollView
behavior={"padding"} bottomOffset={Platform.OS === 'ios' ? 50 : 80}
keyboardVerticalOffset={100} keyboardShouldPersistTaps="handled"
className='flex-1 mh-600' showsVerticalScrollIndicator={false}
contentContainerStyle={{ paddingBottom: 40, flexGrow: 1 }}
className="flex-1"
> >
<ScrollView showsVerticalScrollIndicator={false} className="h-full">
<View className="gap-6 flex flex-col" style={{ gap: '1.5rem' }}> <View className="gap-6 flex flex-col" style={{ gap: '1.5rem' }}>
{/* Input Username / Email */} {/* Input Username / Email */}
<View> <View>
@@ -138,8 +141,7 @@ export default function LoginScreen() {
{!isLoading && <LogIn size={24} color="white" pointerEvents="none" />} {!isLoading && <LogIn size={24} color="white" pointerEvents="none" />}
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</ScrollView> </KeyboardAwareScrollView>
</KeyboardAvoidingView>
</View> </View>
</View> </View>
); );

2593
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -48,6 +48,7 @@
"react-native-reanimated": "~4.1.1", "react-native-reanimated": "~4.1.1",
"react-native-safe-area-context": "~5.6.0", "react-native-safe-area-context": "~5.6.0",
"react-native-screens": "~4.16.0", "react-native-screens": "~4.16.0",
"react-native-svg": "15.12.1",
"react-native-ui-datepicker": "^3.1.2", "react-native-ui-datepicker": "^3.1.2",
"react-native-web": "~0.21.0", "react-native-web": "~0.21.0",
"react-native-worklets": "0.5.1", "react-native-worklets": "0.5.1",
@@ -59,5 +60,12 @@
"eslint-config-expo": "~10.0.0", "eslint-config-expo": "~10.0.0",
"typescript": "~5.9.2" "typescript": "~5.9.2"
}, },
"private": true "private": true,
"expo": {
"doctor": {
"reactNativeDirectoryCheck": {
"exclude": ["react-native-nfc-manager"]
}
}
}
} }

View File

@@ -44,7 +44,10 @@ api.interceptors.response.use(
const originalRequest = error.config; const originalRequest = error.config;
if (error.response) { if (error.response) {
const isLoginRequest = originalRequest?.url?.includes('/user/login');
if (!(error.response.status === 401 && isLoginRequest)) {
console.error('[API ERROR]', error.response.status, error.response.data); console.error('[API ERROR]', error.response.status, error.response.data);
}
// If we receive 401 (Unauthorized), we might want to force logout // If we receive 401 (Unauthorized), we might want to force logout
if (error.response.status === 401) { if (error.response.status === 401) {