eletrotupi / tcc/ frontend/app/auth/login.tsxc167b931829e73be76860df22b78f8ac0951550e
4.4 KB | 172 lines Raw
1
import React, { useState } from 'react';
2
import {
3
  View,
4
  Text,
5
  StyleSheet,
6
  ScrollView,
7
  KeyboardAvoidingView,
8
  Platform,
9
  Alert,
10
} from 'react-native';
11
import { Link, router } from 'expo-router';
12
import { SafeAreaView } from 'react-native-safe-area-context';
13
import { useThemeColor } from '@/hooks/use-theme-color';
14
import { Button, Input } from '@/components/ui';
15
import { useAuth } from '@/context/AuthContext';
16

17
export default function LoginScreen() {
18
  const [email, setEmail] = useState('');
19
  const [password, setPassword] = useState('');
20
  const [errors, setErrors] = useState<{ email?: string; password?: string }>({});
21

22
  const { login, isLoading } = useAuth();
23
  const textColor = useThemeColor({}, 'text');
24
  const backgroundColor = useThemeColor({}, 'background');
25
  const tintColor = useThemeColor({}, 'tint');
26

27
  const validateForm = () => {
28
    const newErrors: { email?: string; password?: string } = {};
29

30
    if (!email) {
31
      newErrors.email = 'Email é obrigatório';
32
    } else if (!/\S+@\S+\.\S+/.test(email)) {
33
      newErrors.email = 'Por favor, use um email válido';
34
    }
35

36
    if (!password) {
37
      newErrors.password = 'Senha é obrigatória';
38
    }
39

40
    setErrors(newErrors);
41
    return Object.keys(newErrors).length === 0;
42
  };
43

44
  const handleLogin = async () => {
45
    if (!validateForm()) return;
46

47
    try {
48
      await login(email, password);
49
      router.replace('/(tabs)');
50
    } catch (error: any) {
51
	  Alert.alert('Erro: ', error.message || 'Falha ao fazer login');
52
    }
53
  };
54

55
  return (
56
    <SafeAreaView style={[styles.container, { backgroundColor }]}>
57
      <KeyboardAvoidingView
58
        behavior='height'
59
        style={styles.keyboardView}
60
      >
61
        <ScrollView
62
          contentContainerStyle={styles.scrollContainer}
63
          showsVerticalScrollIndicator={false}
64
        >
65
          <View style={styles.header}>
66
            <Text style={[styles.title, { color: textColor }]}>Bem vindo de volta</Text>
67
            <Text style={[styles.subtitle, { color: textColor, opacity: 0.7 }]}>
68
              Logue na sua conta
69
            </Text>
70
          </View>
71

72
          <View style={styles.form}>
73
            <Input
74
              label="Email"
75
              type="email"
76
              value={email}
77
              onChangeText={setEmail}
78
              placeholder="Qual seu email?"
79
              error={errors.email}
80
              autoCapitalize="none"
81
            />
82

83
            <Input
84
              label="Senha"
85
              type="password"
86
              value={password}
87
              onChangeText={setPassword}
88
              placeholder="Qual sua senha?"
89
              error={errors.password}
90
              showPasswordToggle
91
            />
92

93
            <Button
94
              title="Entrar"
95
              onPress={handleLogin}
96
              loading={isLoading}
97
              style={styles.loginButton}
98
            />
99

100
            <Link href="/auth/forgot-password" style={[styles.link, {color: tintColor }]} asChild>
101
              <Text style={[styles.footerText, { color: textColor, opacity: 0.7 }]}>
102
                Esqueceu a senha?
103
              </Text>
104
            </Link>
105
          </View>
106

107
          <View style={styles.footer}>
108
            <Text style={[styles.footerText, { color: textColor, opacity: 0.7 }]}>
109
              Não tem uma conta ainda?{' '}
110
            </Text>
111

112
            <Link href="/auth/signup" asChild style={[styles.link, { color: tintColor }]}>
113
              <Text style={[styles.footerText, { color: textColor, opacity: 0.7 }]}>
114
                Cadastre-se
115
              </Text>
116
            </Link>
117
          </View>
118
        </ScrollView>
119
      </KeyboardAvoidingView>
120
    </SafeAreaView>
121
  );
122
}
123

124
const styles = StyleSheet.create({
125
  container: {
126
    flex: 1,
127
  },
128
  keyboardView: {
129
    flex: 1,
130
  },
131
  scrollContainer: {
132
    flexGrow: 1,
133
    paddingHorizontal: 24,
134
    justifyContent: 'center',
135
    minHeight: '100%',
136
  },
137
  header: {
138
    alignItems: 'center',
139
    marginBottom: 40,
140
  },
141
  title: {
142
    fontSize: 28,
143
    fontWeight: 'bold',
144
    marginBottom: 8,
145
  },
146
  subtitle: {
147
    fontSize: 16,
148
    textAlign: 'center',
149
  },
150
  form: {
151
    marginBottom: 32,
152
  },
153
  loginButton: {
154
    marginTop: 8,
155
    marginBottom: 16,
156
  },
157
  link: {
158
    textAlign: 'center',
159
    fontSize: 14,
160
    fontWeight: '500',
161
  },
162
  footer: {
163
    flexDirection: 'row',
164
    justifyContent: 'center',
165
    alignItems: 'center',
166
    marginTop: 'auto',
167
    paddingBottom: 20,
168
  },
169
  footerText: {
170
    fontSize: 14,
171
  },
172
});