diff options
| author | Lucas Faria Mendes <lucas.fariamo08@gmail.com> | 2026-08-14 18:06:35 +0000 |
|---|---|---|
| committer | Lucas Faria Mendes <lucas.fariamo08@gmail.com> | 2026-08-14 18:06:35 +0000 |
| commit | 2c2dfba45357bbd205a59145ae55a2779c911ae0 (patch) | |
| tree | 0736b848aed56ec2da3c2489c49da0519447703d /src/app/login.tsx | |
| download | yaba-2c2dfba45357bbd205a59145ae55a2779c911ae0.tar.gz yaba-2c2dfba45357bbd205a59145ae55a2779c911ae0.zip | |
remake
Signed-off-by: Lucas Faria Mendes <lucas.fariamo08@gmail.com>
Diffstat (limited to 'src/app/login.tsx')
| -rw-r--r-- | src/app/login.tsx | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/app/login.tsx b/src/app/login.tsx new file mode 100644 index 0000000..15ec3be --- /dev/null +++ b/src/app/login.tsx @@ -0,0 +1,144 @@ +import { useAuth } from "@/contexts/AuthContext"; +import { Link, useRouter } from "expo-router"; +import { useState } from "react"; +import { + Alert, + KeyboardAvoidingView, + Platform, + StyleSheet, + Text, + View, +} from "react-native"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import * as LocalAuthentication from "expo-local-authentication"; +import Animated, { FadeInDown, FadeInUp } from "react-native-reanimated"; +import { Colors, Spacing, Typography } from "@/constants/theme"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; + +export default function LoginScreen() { + const insets = useSafeAreaInsets(); + const router = useRouter(); + const { login } = useAuth(); + + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [isLoading, setIsLoading] = useState(false); + + async function handleLogin() { + if (!email || !password) { + Alert.alert("Erro", "Por favor, preencha todos os campos."); + return; + } + + try { + setIsLoading(true); + await login({ email: email.trim(), password }); + + const hasHardware = await LocalAuthentication.hasHardwareAsync(); + const isEnrolled = await LocalAuthentication.isEnrolledAsync(); + + if (hasHardware && isEnrolled) { + router.replace("/biometrics"); + } else { + router.replace("/"); + } + } catch (error) { + Alert.alert("Erro", "Falha ao fazer login. Verifique suas credenciais e tente novamente."); + } finally { + setIsLoading(false); + } + } + + return ( + <KeyboardAvoidingView style={styles.container} behavior={Platform.OS === "ios" ? "padding" : undefined}> + <View style={[styles.content, { paddingTop: insets.top + Spacing.xxl }]}> + <Animated.View entering={FadeInUp.duration(600)} style={styles.header}> + <Text style={styles.title}>YABA</Text> + <Text style={styles.subtitle}>O seu dinheiro, no seu controle.</Text> + </Animated.View> + + <Animated.View entering={FadeInDown.delay(200).duration(600)} style={styles.form}> + <Input + id="login-email" + label="E-mail" + placeholder="seu@email.com" + value={email} + onChangeText={setEmail} + keyboardType="email-address" + autoCapitalize="none" + /> + <Input + id="login-password" + label="Senha" + placeholder="********" + value={password} + onChangeText={setPassword} + secureTextEntry + /> + + <Button + id="login-button" + label="Entrar" + fullWidth + onPress={handleLogin} + loading={isLoading} + disabled={isLoading} + /> + + <View style={styles.footer}> + <Text style={styles.footerText}>Não tem uma conta? </Text> + <Link href="/register" asChild> + <Text style={styles.linkText}>Cadastre-se</Text> + </Link> + </View> + </Animated.View> + </View> + </KeyboardAvoidingView> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: Colors.background, + }, + content: { + flex: 1, + padding: Spacing.xl, + justifyContent: "center", + }, + header: { + alignItems: "center", + marginBottom: Spacing.xl, + }, + title: { + ...Typography.h1, + fontSize: 48, + color: Colors.primaryLight, + letterSpacing: 2, + fontFamily: "DMSans_700Bold", + }, + subtitle: { + ...Typography.body, + color: Colors.textSecondary, + marginTop: Spacing.xs, + }, + form: { + gap: Spacing.lg, + }, + footer: { + flexDirection: "row", + justifyContent: "center", + marginTop: Spacing.xl, + }, + footerText: { + ...Typography.body, + color: Colors.textSecondary, + }, + linkText: { + ...Typography.body, + color: Colors.primaryLight, + fontFamily: "DMSans_700Bold", + }, +});
\ No newline at end of file |