eletrotupi / tcc/ frontend/app/auth/login.tsx71fdb8f591445852b09aef1f212869a412d68eb3
4.5 KB | 174 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
import { apiClient, User } from '@/lib/api';
17

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

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

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

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

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

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

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

48
    try {
49
      await login(email, password);
50
      router.replace('/');
51
    } catch (error: any) {
52
      console.log("LOGIN error: ", error)
53
      Alert.alert('Erro: ', 'Falha ao fazer login');
54
    }
55
  };
56

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

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

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

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

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

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

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

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