Files
mariani_mobile/app/login.tsx

146 lines
7.1 KiB
TypeScript

import { useAlert } from '@/components/AlertComponent';
import api from '@/utils/api';
import { AuthContext } from '@/utils/authContext';
import { Eye, EyeOff, Lock, LogIn, Mail } from 'lucide-react-native';
import React, { useContext, useState } from 'react';
import { Image, KeyboardAvoidingView, Platform, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native';
export default function LoginScreen() {
const alert = useAlert();
const authContext = useContext(AuthContext);
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [showPassword, setShowPassword] = useState(false);
const [isLoading, setIsLoading] = useState(false);
// TODO: Riscrivere funzione per migliorare leggibilità e gestione errori
const handleLogin = async () => {
// TODO: Implementa toast o messaggio di errore più user-friendly
if (!username || !password) {
alert.showAlert('error', 'Attenzione', 'Inserisci username e password');
return;
}
setIsLoading(true);
try {
username.trim();
password.trim();
// Esegui richiesta di login
const response = await api.post("/user/login", {
username: username,
password: password
});
const { token, user } = response.data;
console.log("Login successo, token ricevuto.");
console.log("Dati utente:", user);
// Passiamo token e dati utente al context che gestirà salvataggio e redirect
authContext.logIn(token, user);
} catch (error: any) {
console.error("Login Error:", error);
let message = "Si è verificato un errore durante l'accesso.";
if (error.response) {
// Errore dal server (es. 401 Credenziali errate)
if (error.response.status === 401) {
// TODO: Alert o Toast specifico per credenziali errate
message = "Credenziali non valide."
} else {
message = `Errore Server: ${error.response.data.message || error.response.status}`;
}
} else if (error.request) {
// Server non raggiungibile
message = "Impossibile contattare il server. Controlla la connessione.";
}
alert.showAlert('error', "Login Fallito", message);
} finally {
setIsLoading(false);
}
};
return (
<View className="flex-1 bg-[#099499] h-screen overflow-hidden">
{/* Header con Logo/Titolo */}
<View className="h-[35%] flex-column justify-center items-center">
<Image
source={require('@/assets/images/mariani-logo.png')}
className='h-24 w-80'
resizeMode="contain"
/>
</View>
{/* Form Container */}
<View className="flex-1 bg-white rounded-t-[2.5rem] px-8 pt-10 shadow-xl w-full">
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
className="flex-1"
>
<ScrollView showsVerticalScrollIndicator={false} className="h-full">
<View className="gap-6 flex flex-col" style={{ gap: '1.5rem' }}>
{/* Input Username / Email */}
<View>
<Text className="text-gray-700 text-lg font-bold mb-3 ml-1">Username o Email</Text>
<View className="flex-row items-center bg-gray-50 border border-gray-100 rounded-2xl h-16 px-4 flex">
<Mail size={24} color="#9ca3af" />
<TextInput
className="flex-1 ml-4 text-gray-800 text-lg font-medium h-full w-full"
placeholder="mario.rossi@esempio.com"
placeholderTextColor="#9ca3af"
value={username}
onChangeText={setUsername}
autoCapitalize="none"
keyboardType="email-address"
/>
</View>
</View>
{/* Input Password */}
<View>
<Text className="text-gray-700 text-lg font-bold mb-3 ml-1">Password</Text>
<View className="flex-row items-center bg-gray-50 border border-gray-100 rounded-2xl h-16 px-4 flex">
<Lock size={24} color="#9ca3af" />
<TextInput
className="flex-1 ml-4 text-gray-800 text-lg font-medium h-full w-full"
placeholder="••••••••"
placeholderTextColor="#9ca3af"
value={password}
onChangeText={setPassword}
secureTextEntry={!showPassword}
/>
<TouchableOpacity onPress={() => setShowPassword(!showPassword)}>
{showPassword ? (
<EyeOff size={24} color="#6b7280" />
) : (
<Eye size={24} color="#6b7280" />
)}
</TouchableOpacity>
</View>
<TouchableOpacity className="mt-3 self-end" style={{ alignSelf: 'flex-end' }}>
<Text className="text-[#099499] font-bold text-base">Password dimenticata?</Text>
</TouchableOpacity>
</View>
{/* Tasto Login */}
<TouchableOpacity
onPress={handleLogin}
activeOpacity={0.8}
className={`bg-[#099499] h-16 rounded-2xl flex-row justify-center items-center shadow-md mt-4 flex ${isLoading ? 'opacity-70' : ''}`}
disabled={isLoading}
>
<Text className="text-white text-xl font-bold mr-2">
{isLoading ? 'Accesso in corso...' : 'Accedi'}
</Text>
{!isLoading && <LogIn size={24} color="white" />}
</TouchableOpacity>
</View>
</ScrollView>
</KeyboardAvoidingView>
</View>
</View>
);
}