Files
Fluxup_PAP/app/index.tsx
2026-03-10 16:18:05 +00:00

235 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from 'react';
import {
View,
TextInput,
TouchableOpacity,
Text,
StyleSheet,
Alert,
ActivityIndicator,
SafeAreaView,
KeyboardAvoidingView,
Platform,
} from 'react-native';
import { useRouter } from 'expo-router';
import { usuariosService } from '../Fluxup/src/lib/supabase';
import { Colors } from '../Fluxup/src/constants/theme';
import { Lock, Mail, User } from 'lucide-react-native';
export default function LoginScreen() {
const router = useRouter();
const [email, setEmail] = useState('');
const [palavraPasse, setPalavraPasse] = useState('');
const [idUsuario, setIdUsuario] = useState('');
const [usuario, setUsuario] = useState('');
const [loading, setLoading] = useState(false);
const handleLogin = async () => {
// Validação dos campos
if (!email || !palavraPasse || !idUsuario || !usuario) {
Alert.alert('Erro', 'Por favor, preencha todos os campos');
return;
}
// Validação de email
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
Alert.alert('Erro', 'Email inválido');
return;
}
setLoading(true);
try {
// login no Supabase
const { data, error } = await usuariosService.login(email, palavraPasse);
if (error) {
Alert.alert('Erro', 'Email ou palavra passe incorretos');
return;
}
if (data) {
Alert.alert('Sucesso', `Bem-vindo, ${data.usuario}!`);
// quando o login é bemsucedido, vai para a página inicial
router.replace('/inicio' as any);
}
} catch (err) {
Alert.alert('Erro', 'Erro ao conectar ao servidor');
console.error(err);
} finally {
setLoading(false);
}
};
return (
<SafeAreaView style={styles.safe}>
<KeyboardAvoidingView
style={styles.container}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<Text style={styles.title}>Fluxup</Text>
<Text style={styles.subtitle}>Entre na sua conta</Text>
{/* Campo de Email */}
<View style={styles.inputContainer}>
<Mail size={20} color={Colors.light.icon} style={styles.icon} />
<TextInput
style={styles.input}
placeholder="Email"
placeholderTextColor="#999"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
editable={!loading}
/>
</View>
{/* Campo de Palavra Passe */}
<View style={styles.inputContainer}>
<Lock size={20} color={Colors.light.icon} style={styles.icon} />
<TextInput
style={styles.input}
placeholder="Palavra Passe"
placeholderTextColor="#999"
value={palavraPasse}
onChangeText={setPalavraPasse}
secureTextEntry
editable={!loading}
/>
</View>
{/* Campo de ID Usuário */}
<View style={[styles.inputContainer, { marginBottom: 8 }]}>
<TextInput
style={styles.input}
placeholder="ID Usuário"
placeholderTextColor="#999"
value={idUsuario}
onChangeText={setIdUsuario}
editable={!loading}
/>
</View>
{/* Campo de Usuário */}
<View style={[styles.inputContainer, { marginBottom: 8 }]}>
<TextInput
style={styles.input}
placeholder="Usuário"
placeholderTextColor="#999"
value={usuario}
onChangeText={setUsuario}
editable={!loading}
/>
</View>
{/* Botão de Login */}
<TouchableOpacity
style={[styles.button, loading && styles.buttonDisabled]}
onPress={handleLogin}
disabled={loading}
>
{loading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}>Entrar</Text>
)}
</TouchableOpacity>
<View style={styles.footerLinks}>
{/* Botão de Registo */}
<TouchableOpacity onPress={() => router.push('/registo')}>
<Text style={styles.linkText}>
Não tem conta? <Text style={styles.linkBold}>Registe-se</Text>
</Text>
</TouchableOpacity>
{/* Botão de Esqueci Palavra Passe */}
<TouchableOpacity
onPress={() => router.push('/esqueciPalavraPasse' as any)}
>
<Text style={styles.linkText}>Esqueci a palavrapasse</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
const primary = Colors.light.tint;
const styles = StyleSheet.create({
safe: {
flex: 1,
backgroundColor: Colors.light.background,
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: Colors.light.background,
},
title: {
fontSize: 32,
fontWeight: 'bold',
marginBottom: 8,
color: primary,
},
subtitle: {
fontSize: 16,
color: Colors.light.icon,
marginBottom: 24,
},
inputContainer: {
flexDirection: 'row',
alignItems: 'center',
width: '100%',
backgroundColor: '#fff',
borderRadius: 8,
borderWidth: 1,
borderColor: '#ddd',
marginBottom: 15,
paddingHorizontal: 10,
},
icon: {
marginRight: 10,
},
input: {
flex: 1,
height: 50,
fontSize: 16,
color: Colors.light.text,
},
button: {
width: '100%',
height: 50,
borderRadius: 8,
backgroundColor: primary,
justifyContent: 'center',
alignItems: 'center',
marginTop: 20,
marginBottom: 20,
},
buttonDisabled: {
backgroundColor: '#ccc',
},
buttonText: {
color: '#fff',
fontSize: 18,
fontWeight: 'bold',
},
linkText: {
color: primary,
fontSize: 14,
marginTop: 10,
textAlign: 'center',
},
linkBold: {
fontWeight: 'bold',
},
footerLinks: {
marginTop: 10,
},
});