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

300 lines
7.8 KiB
TypeScript

import React, { useState } from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
Alert,
ActivityIndicator,
KeyboardAvoidingView,
Platform,
ScrollView,
SafeAreaView,
} from 'react-native';
import { useRouter, Link } from 'expo-router';
import { User, Mail, Lock, Phone, ArrowLeft, CheckCircle } from 'lucide-react-native';
import { Colors } from '../Fluxup/src/constants/theme';
// import { supabase } from '../lib/supabase';
export default function RegisterScreen() {
const router = useRouter();
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [loading, setLoading] = useState(false);
async function handleRegister() {
// 1. Validação simples antes de enviar
if (password !== confirmPassword) {
Alert.alert('Erro', 'As palavras-passe não coincidem.');
return;
}
if (username.length < 3) {
Alert.alert('Erro', 'O nome de utilizador deve ter pelo menos 3 caracteres.');
return;
}
setLoading(true);
// Simulação de registo
setTimeout(() => {
setLoading(false);
Alert.alert('Sucesso', 'Conta criada com sucesso! A entrar...');
// em vez de voltar ao login, encaminhamos directamente para a tela inicial
router.replace('/inicio' as any);
}, 1500);
/* LÓGICA REAL DO SUPABASE (Para depois):
// 1. Criar utilizador na Auth
const { data: authData, error: authError } = await supabase.auth.signUp({
email: email,
password: password,
});
if (authError) {
Alert.alert('Erro', authError.message);
setLoading(false);
return;
}
// 2. Guardar dados extra na tabela 'profiles'
if (authData.user) {
const { error: profileError } = await supabase
.from('profiles')
.insert([{
id: authData.user.id,
username: username,
phone_number: phone,
full_name: username, // Podes mudar isto depois
updated_at: new Date(),
}]);
if (profileError) {
Alert.alert('Aviso', 'Conta criada, mas houve um erro ao salvar o perfil.');
} else {
Alert.alert('Sucesso', 'Verifica o teu email para confirmar a conta!');
router.replace('/inicio');
}
}
setLoading(false);
*/
}
return (
<SafeAreaView style={styles.safe}>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={styles.container}
>
<ScrollView contentContainerStyle={styles.scrollContent}>
{/* Botão Voltar */}
<TouchableOpacity onPress={() => router.back()} style={styles.backButton}>
<ArrowLeft size={24} />
</TouchableOpacity>
<View style={styles.header}>
<Text style={styles.title}>Fluxup</Text>
<Text style={styles.subtitle}>Registar nova conta</Text>
</View>
<View style={styles.form}>
{/* Nome de Utilizador */}
<View style={styles.inputContainer}>
<User size={20} />
<TextInput
style={styles.input}
placeholder="Nome de utilizador"
placeholderTextColor="#999"
value={username}
onChangeText={setUsername}
/>
</View>
{/* Email */}
<View style={styles.inputContainer}>
<Mail size={20} />
<TextInput
style={styles.input}
placeholder="Email"
placeholderTextColor="#999"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
/>
</View>
{/* Telemóvel */}
<View style={styles.inputContainer}>
<Phone size={20} />
<TextInput
style={styles.input}
placeholder="Número de telemóvel"
placeholderTextColor="#999"
value={phone}
onChangeText={setPhone}
keyboardType="phone-pad"
/>
</View>
{/* Password */}
<View style={styles.inputContainer}>
<Lock size={20} />
<TextInput
style={styles.input}
placeholder="Palavra-passe"
placeholderTextColor="#999"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
</View>
{/* Confirmar Password */}
<View style={[
styles.inputContainer,
// Muda a cor da borda se as senhas não baterem (e se já tiver escrito algo)
confirmPassword.length > 0 && password !== confirmPassword ? { borderColor: '#EF4444' } : {}
]}>
<Lock size={20} />
<TextInput
style={styles.input}
placeholder="Confirmar palavra-passe"
placeholderTextColor="#999"
value={confirmPassword}
onChangeText={setConfirmPassword}
secureTextEntry
/>
{/* Ícone de verificação verde se as senhas baterem */}
{password.length > 0 && password === confirmPassword && (
<CheckCircle size={20} />
)}
</View>
<TouchableOpacity
style={styles.button}
onPress={handleRegister}
disabled={loading}
>
{loading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}>Registar</Text>
)}
</TouchableOpacity>
<View style={styles.footer}>
<Text style={styles.footerText}> tens conta? </Text>
<Link href="/" asChild>
<TouchableOpacity>
<Text style={styles.linkText}>Entrar</Text>
</TouchableOpacity>
</Link>
</View>
</View>
</ScrollView>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
const primary = Colors.light.tint;
const styles = StyleSheet.create({
safe: {
flex: 1,
backgroundColor: Colors.light.background,
},
container: {
flex: 1,
backgroundColor: Colors.light.background,
},
scrollContent: {
flexGrow: 1,
padding: 24,
justifyContent: 'center',
},
backButton: {
marginTop: 20,
marginBottom: 20,
},
header: {
marginBottom: 30,
alignItems: 'center',
},
title: {
fontSize: 32,
fontWeight: 'bold',
color: primary,
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: Colors.light.icon,
},
form: {
width: '100%',
},
inputContainer: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#fff',
borderRadius: 12,
paddingHorizontal: 16,
height: 56,
marginBottom: 16,
borderWidth: 1,
borderColor: '#E5E7EB',
},
inputIcon: {
marginRight: 12,
},
input: {
flex: 1,
height: '100%',
color: Colors.light.text,
fontSize: 16,
},
button: {
backgroundColor: primary,
height: 56,
borderRadius: 12,
justifyContent: 'center',
alignItems: 'center',
marginTop: 10,
shadowColor: primary,
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 4,
},
buttonText: {
color: '#fff',
fontSize: 18,
fontWeight: 'bold',
},
footer: {
flexDirection: 'row',
justifyContent: 'center',
marginTop: 24,
marginBottom: 20,
},
footerText: {
color: Colors.light.icon,
fontSize: 16,
},
linkText: {
color: primary,
fontWeight: 'bold',
fontSize: 16,
},
});